@atlashub/smartstack-cli 1.35.0 → 1.37.0
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/templates/skills/_shared.md +7 -7
- package/templates/skills/application/steps/step-01-navigation.md +226 -43
- package/templates/skills/application/steps/step-03-roles.md +160 -38
- package/templates/skills/application/steps/step-04-backend.md +126 -19
- package/templates/skills/application/steps/step-05-frontend.md +4 -1
- package/templates/skills/application/templates-backend.md +8 -8
- package/templates/skills/application/templates-frontend.md +8 -8
- package/templates/skills/application/templates-seed.md +200 -1
- package/templates/skills/gitflow/_shared.md +188 -53
- package/templates/skills/gitflow/phases/abort.md +28 -16
- package/templates/skills/gitflow/phases/cleanup.md +13 -9
- package/templates/skills/gitflow/phases/status.md +16 -17
- package/templates/skills/gitflow/steps/step-commit.md +11 -5
- package/templates/skills/gitflow/steps/step-finish.md +43 -33
- package/templates/skills/gitflow/steps/step-init.md +7 -2
- package/templates/skills/gitflow/steps/step-merge.md +24 -10
- package/templates/skills/gitflow/steps/step-pr.md +42 -28
- package/templates/skills/gitflow/steps/step-start.md +19 -13
- package/templates/skills/gitflow/templates/config.json +7 -4
- package/templates/skills/ralph-loop/SKILL.md +57 -11
- package/templates/skills/ralph-loop/steps/step-00-init.md +170 -30
- package/templates/skills/ralph-loop/steps/step-01-task.md +243 -40
- package/templates/skills/ralph-loop/steps/step-02-execute.md +142 -24
- package/templates/skills/ralph-loop/steps/step-03-commit.md +140 -36
- package/templates/skills/ralph-loop/steps/step-04-check.md +128 -44
- package/templates/skills/ralph-loop/steps/step-05-report.md +175 -88
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: step-04-check
|
|
3
|
-
description: Check completion criteria
|
|
3
|
+
description: Check completion criteria with status-based logic
|
|
4
4
|
next_step: steps/step-05-report.md OR steps/step-01-task.md
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ next_step: steps/step-05-report.md OR steps/step-01-task.md
|
|
|
8
8
|
|
|
9
9
|
## YOUR TASK:
|
|
10
10
|
|
|
11
|
-
Check if all tasks are complete and decide whether to output completion promise or continue to next task.
|
|
11
|
+
Check if all tasks are complete and decide whether to output completion promise or continue to next task. Uses v2 status-based checks instead of boolean `passes`.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -20,50 +20,74 @@ Check if all tasks are complete and decide whether to output completion promise
|
|
|
20
20
|
|
|
21
21
|
```javascript
|
|
22
22
|
const prd = readJSON('.ralph/prd.json');
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
const
|
|
23
|
+
|
|
24
|
+
const tasksCompleted = prd.tasks.filter(t => t.status === 'completed').length;
|
|
25
|
+
const tasksSkipped = prd.tasks.filter(t => t.status === 'skipped').length;
|
|
26
|
+
const tasksFailed = prd.tasks.filter(t => t.status === 'failed').length;
|
|
27
|
+
const tasksBlocked = prd.tasks.filter(t => t.status === 'blocked').length;
|
|
28
|
+
const tasksPending = prd.tasks.filter(t => t.status === 'pending').length;
|
|
29
|
+
const tasksTotal = prd.tasks.length;
|
|
30
|
+
|
|
31
|
+
const allDone = (tasksCompleted + tasksSkipped) === tasksTotal;
|
|
32
|
+
const hasFailures = tasksFailed > 0;
|
|
33
|
+
const hasBlocked = tasksBlocked > 0;
|
|
34
|
+
const hasPending = tasksPending > 0;
|
|
26
35
|
```
|
|
27
36
|
|
|
28
37
|
### 2. Check Iteration Limit
|
|
29
38
|
|
|
30
|
-
**If
|
|
39
|
+
**If `prd.config.current_iteration` > `prd.config.max_iterations`:**
|
|
31
40
|
|
|
32
41
|
```
|
|
33
42
|
╔══════════════════════════════════════════════════════════════════╗
|
|
34
|
-
║ ⚠️ MAX ITERATIONS REACHED
|
|
43
|
+
║ ⚠️ MAX ITERATIONS REACHED ║
|
|
35
44
|
╠══════════════════════════════════════════════════════════════════╣
|
|
36
|
-
║ Iterations: {current_iteration} / {max_iterations}
|
|
37
|
-
║ Tasks: {tasksCompleted} / {tasksTotal} complete
|
|
45
|
+
║ Iterations: {current_iteration} / {max_iterations} ║
|
|
46
|
+
║ Tasks: {tasksCompleted} / {tasksTotal} complete ║
|
|
47
|
+
║ Failed: {tasksFailed} | Blocked: {tasksBlocked} ║
|
|
38
48
|
╠══════════════════════════════════════════════════════════════════╣
|
|
39
|
-
║ Ralph loop stopped due to iteration limit.
|
|
40
|
-
║ Remaining tasks:
|
|
41
|
-
║ {list of tasks with
|
|
49
|
+
║ Ralph loop stopped due to iteration limit. ║
|
|
50
|
+
║ Remaining tasks: ║
|
|
51
|
+
║ {list of tasks with status != completed and != skipped} ║
|
|
42
52
|
╚══════════════════════════════════════════════════════════════════╝
|
|
43
53
|
|
|
44
54
|
-> Generating partial report...
|
|
45
55
|
```
|
|
46
56
|
|
|
57
|
+
**Update prd.json:**
|
|
58
|
+
```javascript
|
|
59
|
+
prd.status = 'partial';
|
|
60
|
+
prd.updated_at = new Date().toISOString();
|
|
61
|
+
writeJSON('.ralph/prd.json', prd);
|
|
62
|
+
```
|
|
63
|
+
|
|
47
64
|
**Proceed to step-05-report.md**
|
|
48
65
|
|
|
49
66
|
### 3. Check All Tasks Complete
|
|
50
67
|
|
|
51
|
-
**If
|
|
68
|
+
**If allDone = true:**
|
|
52
69
|
|
|
53
70
|
```
|
|
54
71
|
╔══════════════════════════════════════════════════════════════════╗
|
|
55
|
-
║ ✅ ALL TASKS COMPLETE
|
|
72
|
+
║ ✅ ALL TASKS COMPLETE ║
|
|
56
73
|
╠══════════════════════════════════════════════════════════════════╣
|
|
57
|
-
║ Iterations: {current_iteration}
|
|
58
|
-
║ Tasks: {
|
|
74
|
+
║ Iterations: {current_iteration - 1} ║
|
|
75
|
+
║ Tasks: {tasksCompleted} completed, {tasksSkipped} skipped ║
|
|
59
76
|
╠══════════════════════════════════════════════════════════════════╣
|
|
60
|
-
║ Output completion promise:
|
|
61
|
-
║ <promise>{completion_promise}</promise>
|
|
77
|
+
║ Output completion promise: ║
|
|
78
|
+
║ <promise>{completion_promise}</promise> ║
|
|
62
79
|
╚══════════════════════════════════════════════════════════════════╝
|
|
63
80
|
|
|
64
81
|
<promise>{completion_promise}</promise>
|
|
65
82
|
```
|
|
66
83
|
|
|
84
|
+
**Update prd.json:**
|
|
85
|
+
```javascript
|
|
86
|
+
prd.status = 'completed';
|
|
87
|
+
prd.updated_at = new Date().toISOString();
|
|
88
|
+
writeJSON('.ralph/prd.json', prd);
|
|
89
|
+
```
|
|
90
|
+
|
|
67
91
|
**CRITICAL: Output the promise tag exactly as shown:**
|
|
68
92
|
```
|
|
69
93
|
<promise>{completion_promise}</promise>
|
|
@@ -71,15 +95,48 @@ const allComplete = tasksCompleted === tasksTotal;
|
|
|
71
95
|
|
|
72
96
|
**Proceed to step-05-report.md**
|
|
73
97
|
|
|
74
|
-
### 4.
|
|
98
|
+
### 4. Check for Dead-End (all remaining are blocked/failed)
|
|
99
|
+
|
|
100
|
+
**If !hasPending AND !allDone:**
|
|
101
|
+
|
|
102
|
+
All remaining tasks are blocked or failed. No progress is possible.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
╔══════════════════════════════════════════════════════════════════╗
|
|
106
|
+
║ ⚠️ DEAD-END DETECTED ║
|
|
107
|
+
╠══════════════════════════════════════════════════════════════════╣
|
|
108
|
+
║ Tasks: {tasksCompleted} completed, {tasksFailed} failed, ║
|
|
109
|
+
║ {tasksBlocked} blocked ║
|
|
110
|
+
╠══════════════════════════════════════════════════════════════════╣
|
|
111
|
+
║ No more tasks can be executed. ║
|
|
112
|
+
║ Failed tasks: ║
|
|
113
|
+
║ {list of failed tasks with error messages} ║
|
|
114
|
+
║ ║
|
|
115
|
+
║ Blocked tasks (downstream): ║
|
|
116
|
+
║ {list of blocked tasks with dependency info} ║
|
|
117
|
+
╚══════════════════════════════════════════════════════════════════╝
|
|
118
|
+
|
|
119
|
+
-> Generating partial report...
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Update prd.json:**
|
|
123
|
+
```javascript
|
|
124
|
+
prd.status = 'failed';
|
|
125
|
+
prd.updated_at = new Date().toISOString();
|
|
126
|
+
writeJSON('.ralph/prd.json', prd);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Proceed to step-05-report.md**
|
|
130
|
+
|
|
131
|
+
### 5. More Tasks Remaining
|
|
75
132
|
|
|
76
|
-
**If
|
|
133
|
+
**If hasPending AND iteration < max_iterations:**
|
|
77
134
|
|
|
78
135
|
```
|
|
79
136
|
Progress: {tasksCompleted} / {tasksTotal} tasks
|
|
137
|
+
Failed: {tasksFailed} | Blocked: {tasksBlocked} | Pending: {tasksPending}
|
|
80
138
|
|
|
81
|
-
Next task
|
|
82
|
-
[{next_task_id}] {next_task_description}
|
|
139
|
+
Next eligible task will be determined by dependency resolution.
|
|
83
140
|
|
|
84
141
|
Continuing to next iteration...
|
|
85
142
|
```
|
|
@@ -95,20 +152,25 @@ Continuing to next iteration...
|
|
|
95
152
|
│ Check Completion │
|
|
96
153
|
└──────────┬──────────┘
|
|
97
154
|
│
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
155
|
+
┌────────────────────┼────────────────────┐
|
|
156
|
+
│ │ │
|
|
157
|
+
▼ ▼ ▼
|
|
158
|
+
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
159
|
+
│ Max Iters │ │ All Tasks │ │ Tasks │
|
|
160
|
+
│ Reached │ │ Done │ │ Remaining │
|
|
161
|
+
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
|
162
|
+
│ │ │
|
|
163
|
+
│ │ ┌────────┴────────┐
|
|
164
|
+
│ │ │ │
|
|
165
|
+
▼ ▼ ▼ ▼
|
|
166
|
+
┌──────────────┐ ┌──────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
167
|
+
│ Partial │ │ Output │ │ Dead-End │ │ Loop to │
|
|
168
|
+
│ Report │ │ Promise │ │ (all blocked│ │ step-01 │
|
|
169
|
+
│ step-05 │ │ step-05 │ │ or failed) │ │ │
|
|
170
|
+
│ status: │ │ status: │ │ step-05 │ │ │
|
|
171
|
+
│ "partial" │ │ "completed" │ │ status: │ │ │
|
|
172
|
+
└──────────────┘ └──────────────┘ │ "failed" │ └─────────────┘
|
|
173
|
+
└─────────────┘
|
|
112
174
|
```
|
|
113
175
|
|
|
114
176
|
---
|
|
@@ -122,9 +184,11 @@ Completion Check:
|
|
|
122
184
|
| Field | Value |
|
|
123
185
|
|-------|-------|
|
|
124
186
|
| Iteration | {current_iteration} / {max_iterations} |
|
|
125
|
-
|
|
|
187
|
+
| Completed | {tasksCompleted} / {tasksTotal} |
|
|
188
|
+
| Failed | {tasksFailed} |
|
|
189
|
+
| Blocked | {tasksBlocked} |
|
|
190
|
+
| Pending | {tasksPending} |
|
|
126
191
|
| Status | Continuing |
|
|
127
|
-
| Next | [{next_task_id}] {next_task_description} |
|
|
128
192
|
|
|
129
193
|
-> Loading next task...
|
|
130
194
|
```
|
|
@@ -135,8 +199,9 @@ Completion Check:
|
|
|
135
199
|
|
|
136
200
|
| Field | Value |
|
|
137
201
|
|-------|-------|
|
|
138
|
-
|
|
|
139
|
-
|
|
|
202
|
+
| Iterations Used | {current_iteration - 1} |
|
|
203
|
+
| Completed | {tasksCompleted} / {tasksTotal} |
|
|
204
|
+
| Skipped | {tasksSkipped} |
|
|
140
205
|
| Status | COMPLETE |
|
|
141
206
|
|
|
142
207
|
<promise>{completion_promise}</promise>
|
|
@@ -144,19 +209,38 @@ Completion Check:
|
|
|
144
209
|
-> Generating report...
|
|
145
210
|
```
|
|
146
211
|
|
|
212
|
+
**If partial/failed:**
|
|
213
|
+
```
|
|
214
|
+
Completion Check:
|
|
215
|
+
|
|
216
|
+
| Field | Value |
|
|
217
|
+
|-------|-------|
|
|
218
|
+
| Iterations Used | {current_iteration - 1} |
|
|
219
|
+
| Completed | {tasksCompleted} / {tasksTotal} |
|
|
220
|
+
| Failed | {tasksFailed} |
|
|
221
|
+
| Blocked | {tasksBlocked} |
|
|
222
|
+
| Status | {PARTIAL or FAILED} |
|
|
223
|
+
| Reason | {max iterations / dead-end} |
|
|
224
|
+
|
|
225
|
+
-> Generating report...
|
|
226
|
+
```
|
|
227
|
+
|
|
147
228
|
---
|
|
148
229
|
|
|
149
|
-
## CRITICAL
|
|
230
|
+
## CRITICAL RULES:
|
|
150
231
|
|
|
151
232
|
**NEVER output the completion promise unless:**
|
|
152
|
-
1. ALL tasks have `
|
|
153
|
-
2.
|
|
233
|
+
1. ALL tasks have `status: "completed"` or `status: "skipped"`
|
|
234
|
+
2. Zero tasks with `status: "blocked"` or `status: "failed"`
|
|
235
|
+
3. The statement is genuinely true
|
|
154
236
|
|
|
155
237
|
**False promises to escape the loop are FORBIDDEN.**
|
|
156
238
|
|
|
239
|
+
**Always update `prd.status` and `prd.updated_at` before proceeding.**
|
|
240
|
+
|
|
157
241
|
---
|
|
158
242
|
|
|
159
243
|
## NEXT STEP:
|
|
160
244
|
|
|
161
|
-
- If complete or max iterations: `./step-05-report.md`
|
|
245
|
+
- If complete or max iterations or dead-end: `./step-05-report.md`
|
|
162
246
|
- If tasks remaining: `./step-01-task.md`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: step-05-report
|
|
3
|
-
description: Generate final
|
|
3
|
+
description: Generate final report from prd.json v2 structured data
|
|
4
4
|
next_step: null
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,57 +8,79 @@ next_step: null
|
|
|
8
8
|
|
|
9
9
|
## YOUR TASK:
|
|
10
10
|
|
|
11
|
-
Generate a comprehensive feature report
|
|
11
|
+
Generate a comprehensive feature report using structured data from prd.json v2 (history, task metadata, file tracking).
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
15
|
## EXECUTION SEQUENCE:
|
|
16
16
|
|
|
17
|
-
### 1.
|
|
17
|
+
### 1. Load Structured Data from prd.json
|
|
18
18
|
|
|
19
|
-
**
|
|
19
|
+
**Read all data from the single source of truth:**
|
|
20
20
|
|
|
21
21
|
```javascript
|
|
22
22
|
const prd = readJSON('.ralph/prd.json');
|
|
23
|
+
|
|
23
24
|
const stats = {
|
|
24
25
|
feature: prd.feature,
|
|
26
|
+
status: prd.status,
|
|
27
|
+
schema: prd.$version,
|
|
25
28
|
started: prd.created,
|
|
26
29
|
completed: new Date().toISOString(),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
iterations_used: prd.config.current_iteration - 1,
|
|
31
|
+
max_iterations: prd.config.max_iterations,
|
|
32
|
+
tasks: {
|
|
33
|
+
total: prd.tasks.length,
|
|
34
|
+
completed: prd.tasks.filter(t => t.status === 'completed').length,
|
|
35
|
+
failed: prd.tasks.filter(t => t.status === 'failed').length,
|
|
36
|
+
blocked: prd.tasks.filter(t => t.status === 'blocked').length,
|
|
37
|
+
skipped: prd.tasks.filter(t => t.status === 'skipped').length,
|
|
38
|
+
pending: prd.tasks.filter(t => t.status === 'pending').length
|
|
39
|
+
},
|
|
40
|
+
source: prd.source ? prd.source.type : 'direct',
|
|
41
|
+
branch: prd.metadata.branch
|
|
32
42
|
};
|
|
43
|
+
|
|
44
|
+
// Aggregate files from all tasks
|
|
45
|
+
const allFilesCreated = [];
|
|
46
|
+
const allFilesModified = [];
|
|
47
|
+
for (const task of prd.tasks) {
|
|
48
|
+
if (task.files_changed) {
|
|
49
|
+
allFilesCreated.push(...task.files_changed.created);
|
|
50
|
+
allFilesModified.push(...task.files_changed.modified);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Deduplicate
|
|
55
|
+
const filesCreated = [...new Set(allFilesCreated)];
|
|
56
|
+
const filesModified = [...new Set(allFilesModified)];
|
|
57
|
+
|
|
58
|
+
// Calculate total duration from history
|
|
59
|
+
const totalDuration = prd.history.reduce((sum, h) => sum + (h.duration_seconds || 0), 0);
|
|
33
60
|
```
|
|
34
61
|
|
|
35
|
-
### 2. Collect
|
|
62
|
+
### 2. Collect MCP Usage (from logs if available)
|
|
36
63
|
|
|
37
|
-
**
|
|
64
|
+
**Parse from verbose logs:**
|
|
38
65
|
|
|
39
66
|
```bash
|
|
40
|
-
|
|
67
|
+
# Count MCP calls from log files
|
|
68
|
+
MCP_CALLS=$(grep -c "\[MCP\]" .ralph/logs/*.log 2>/dev/null || echo "0")
|
|
69
|
+
SMARTSTACK_CALLS=$(grep -c "mcp__smartstack" .ralph/logs/*.log 2>/dev/null || echo "0")
|
|
70
|
+
CONTEXT7_CALLS=$(grep -c "mcp__context7" .ralph/logs/*.log 2>/dev/null || echo "0")
|
|
41
71
|
```
|
|
42
72
|
|
|
43
|
-
**
|
|
44
|
-
- Files created (A)
|
|
45
|
-
- Files modified (M)
|
|
46
|
-
- Files deleted (D)
|
|
47
|
-
|
|
48
|
-
### 3. Collect MCP Usage
|
|
49
|
-
|
|
50
|
-
**From verbose logs (if available):**
|
|
73
|
+
**Or extract from task validations:**
|
|
51
74
|
|
|
52
75
|
```javascript
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
context7_queries: W
|
|
76
|
+
const validationStats = {
|
|
77
|
+
passed: prd.tasks.filter(t => t.validation === 'passed').length,
|
|
78
|
+
failed: prd.tasks.filter(t => t.validation && t.validation.startsWith('failed')).length,
|
|
79
|
+
skipped: prd.tasks.filter(t => t.validation === null).length
|
|
58
80
|
};
|
|
59
81
|
```
|
|
60
82
|
|
|
61
|
-
###
|
|
83
|
+
### 3. Generate Report File
|
|
62
84
|
|
|
63
85
|
**Write to `.ralph/reports/{feature-slug}.md`:**
|
|
64
86
|
|
|
@@ -66,87 +88,148 @@ const mcpStats = {
|
|
|
66
88
|
# Feature Report: {feature}
|
|
67
89
|
|
|
68
90
|
## Summary
|
|
69
|
-
- **Started**: {started}
|
|
70
|
-
- **Completed**: {completed}
|
|
71
|
-
- **Duration**: {iterations} iterations
|
|
72
|
-
- **Status**: {status}
|
|
73
|
-
|
|
74
|
-
## Task Progress
|
|
75
|
-
|
|
76
|
-
| # | Task | Status |
|
|
77
|
-
|---|------|--------|
|
|
78
|
-
| 1 | {task_1_description} | ✅ |
|
|
79
|
-
| 2 | {task_2_description} | ✅ |
|
|
80
|
-
| 3 | {task_3_description} | ❌ (if incomplete) |
|
|
81
|
-
|
|
82
|
-
## MCP Usage Statistics
|
|
83
|
-
|
|
84
|
-
| Tool | Calls | Success | Failures |
|
|
85
|
-
|------|-------|---------|----------|
|
|
86
|
-
| validate_conventions | X | X | 0 |
|
|
87
|
-
| check_migrations | Y | Y | 0 |
|
|
88
|
-
| scaffold_extension | Z | Z | 0 |
|
|
89
|
-
| context7 query-docs | W | W | 0 |
|
|
90
|
-
|
|
91
|
-
## Files Created
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
| Field | Value |
|
|
93
|
+
|-------|-------|
|
|
94
|
+
| **Status** | {status} |
|
|
95
|
+
| **Started** | {started} |
|
|
96
|
+
| **Completed** | {completed} |
|
|
97
|
+
| **Iterations** | {iterations_used} / {max_iterations} |
|
|
98
|
+
| **Branch** | {branch} |
|
|
99
|
+
| **Source** | {source} |
|
|
100
|
+
| **Schema** | {schema} |
|
|
96
101
|
|
|
97
|
-
##
|
|
102
|
+
## Task Progress
|
|
98
103
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
| # | Task | Category | Status | Iteration | Duration | Commit |
|
|
105
|
+
|---|------|----------|--------|-----------|----------|--------|
|
|
106
|
+
{for each task in prd.tasks:}
|
|
107
|
+
| {id} | {description} | {category} | {status_emoji} | {iteration || '-'} | {duration}s | {commit_hash || '-'} |
|
|
108
|
+
{end for}
|
|
109
|
+
|
|
110
|
+
**Summary: {completed}/{total} completed, {failed} failed, {blocked} blocked, {skipped} skipped**
|
|
111
|
+
|
|
112
|
+
{status_emoji mapping: completed=✅, failed=❌, blocked=🚫, skipped=⏭️, pending=⏳}
|
|
113
|
+
|
|
114
|
+
## Failed Tasks
|
|
115
|
+
|
|
116
|
+
{if any failed tasks:}
|
|
117
|
+
| # | Task | Error |
|
|
118
|
+
|---|------|-------|
|
|
119
|
+
{for each failed task:}
|
|
120
|
+
| {id} | {description} | {error} |
|
|
121
|
+
{end for}
|
|
122
|
+
{else:}
|
|
123
|
+
No failed tasks.
|
|
124
|
+
{end if}
|
|
125
|
+
|
|
126
|
+
## Blocked Tasks
|
|
127
|
+
|
|
128
|
+
{if any blocked tasks:}
|
|
129
|
+
| # | Task | Blocked By | Error |
|
|
130
|
+
|---|------|------------|-------|
|
|
131
|
+
{for each blocked task:}
|
|
132
|
+
| {id} | {description} | Tasks {dependencies} | {error} |
|
|
133
|
+
{end for}
|
|
134
|
+
{else:}
|
|
135
|
+
No blocked tasks.
|
|
136
|
+
{end if}
|
|
137
|
+
|
|
138
|
+
## Iteration History
|
|
139
|
+
|
|
140
|
+
{for each entry in prd.history:}
|
|
141
|
+
### Iteration {iteration} — Task [{task_id}]
|
|
142
|
+
- **Action**: {action}
|
|
143
|
+
- **Timestamp**: {timestamp}
|
|
144
|
+
- **Commit**: {commit_hash}
|
|
145
|
+
- **Duration**: {duration_seconds}s
|
|
146
|
+
- **Notes**: {notes}
|
|
147
|
+
|
|
148
|
+
{end for}
|
|
149
|
+
|
|
150
|
+
## MCP Validation Results
|
|
151
|
+
|
|
152
|
+
| Task | Category | Validation |
|
|
153
|
+
|------|----------|------------|
|
|
154
|
+
{for each task:}
|
|
155
|
+
| [{id}] {description} | {category} | {validation || 'N/A'} |
|
|
156
|
+
{end for}
|
|
157
|
+
|
|
158
|
+
## Files Created ({filesCreated.length})
|
|
159
|
+
|
|
160
|
+
{if filesCreated.length > 0:}
|
|
161
|
+
{for each file:}
|
|
162
|
+
- `{file}`
|
|
163
|
+
{end for}
|
|
164
|
+
{else:}
|
|
165
|
+
- (none)
|
|
166
|
+
{end if}
|
|
167
|
+
|
|
168
|
+
## Files Modified ({filesModified.length})
|
|
169
|
+
|
|
170
|
+
{if filesModified.length > 0:}
|
|
171
|
+
{for each file:}
|
|
172
|
+
- `{file}`
|
|
173
|
+
{end for}
|
|
174
|
+
{else:}
|
|
175
|
+
- (none)
|
|
176
|
+
{end if}
|
|
102
177
|
|
|
103
178
|
## Git Commits
|
|
104
179
|
|
|
105
|
-
|
|
106
|
-
{
|
|
107
|
-
{
|
|
108
|
-
```
|
|
180
|
+
{for each unique commit_hash in tasks:}
|
|
181
|
+
`{commit_hash}` {commit message from task description}
|
|
182
|
+
{end for}
|
|
109
183
|
|
|
110
|
-
##
|
|
184
|
+
## Metadata
|
|
111
185
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
186
|
+
| Field | Value |
|
|
187
|
+
|-------|-------|
|
|
188
|
+
| CLI Version | {prd.metadata.cli_version} |
|
|
189
|
+
| Branch | {prd.metadata.branch} |
|
|
190
|
+
| Project | {prd.metadata.project_path} |
|
|
191
|
+
| MCP SmartStack | {prd.metadata.mcp_servers.smartstack ? '✅' : '❌'} |
|
|
192
|
+
| MCP Context7 | {prd.metadata.mcp_servers.context7 ? '✅' : '❌'} |
|
|
193
|
+
| Total Duration | {totalDuration}s ({Math.round(totalDuration/60)} min) |
|
|
117
194
|
|
|
118
|
-
|
|
195
|
+
---
|
|
196
|
+
*Auto-generated by Ralph Loop v2 — SmartStack CLI*
|
|
197
|
+
```
|
|
119
198
|
|
|
120
|
-
|
|
199
|
+
### 4. Finalize prd.json
|
|
121
200
|
|
|
122
|
-
|
|
201
|
+
**Set final status (if not already set by step-04):**
|
|
123
202
|
|
|
124
|
-
|
|
203
|
+
```javascript
|
|
204
|
+
prd.updated_at = new Date().toISOString();
|
|
205
|
+
writeJSON('.ralph/prd.json', prd);
|
|
125
206
|
```
|
|
126
207
|
|
|
127
208
|
### 5. Display Final Summary
|
|
128
209
|
|
|
129
210
|
```
|
|
130
211
|
╔══════════════════════════════════════════════════════════════════╗
|
|
131
|
-
║ RALPH LOOP COMPLETE
|
|
212
|
+
║ RALPH LOOP COMPLETE ║
|
|
132
213
|
╠══════════════════════════════════════════════════════════════════╣
|
|
133
|
-
║ Feature:
|
|
134
|
-
║ Status:
|
|
135
|
-
║ Iterations: {
|
|
136
|
-
║ Tasks:
|
|
214
|
+
║ Feature: {feature} ║
|
|
215
|
+
║ Status: {status} ║
|
|
216
|
+
║ Iterations: {iterations_used} ║
|
|
217
|
+
║ Tasks: {completed}/{total} completed ║
|
|
218
|
+
║ {failed} failed, {blocked} blocked ║
|
|
137
219
|
╠══════════════════════════════════════════════════════════════════╣
|
|
138
|
-
║ Files Created: {
|
|
139
|
-
║ Files Modified: {
|
|
140
|
-
║ Commits: {
|
|
220
|
+
║ Files Created: {filesCreated.length} ║
|
|
221
|
+
║ Files Modified: {filesModified.length} ║
|
|
222
|
+
║ Commits: {unique_commits.length} ║
|
|
223
|
+
║ Duration: {totalDuration}s ({minutes} min) ║
|
|
141
224
|
╠══════════════════════════════════════════════════════════════════╣
|
|
142
|
-
║ Report saved to:
|
|
143
|
-
║ .ralph/reports/{feature-slug}.md
|
|
225
|
+
║ Report saved to: ║
|
|
226
|
+
║ .ralph/reports/{feature-slug}.md ║
|
|
144
227
|
╚══════════════════════════════════════════════════════════════════╝
|
|
145
228
|
```
|
|
146
229
|
|
|
147
230
|
### 6. Output Completion (if applicable)
|
|
148
231
|
|
|
149
|
-
**If
|
|
232
|
+
**If prd.status === 'completed' and not already output:**
|
|
150
233
|
|
|
151
234
|
```
|
|
152
235
|
<promise>{completion_promise}</promise>
|
|
@@ -154,7 +237,7 @@ const mcpStats = {
|
|
|
154
237
|
|
|
155
238
|
---
|
|
156
239
|
|
|
157
|
-
## CLEANUP
|
|
240
|
+
## CLEANUP SUGGESTIONS:
|
|
158
241
|
|
|
159
242
|
**Suggest to user:**
|
|
160
243
|
|
|
@@ -162,19 +245,23 @@ const mcpStats = {
|
|
|
162
245
|
Next steps:
|
|
163
246
|
1. Review report: .ralph/reports/{feature-slug}.md
|
|
164
247
|
2. Run full test suite: dotnet test
|
|
165
|
-
3. Create PR: /gitflow
|
|
166
|
-
4. Clean up Ralph files: rm -rf .ralph/
|
|
248
|
+
3. Create PR: /gitflow pr
|
|
249
|
+
4. Clean up Ralph files: rm -rf .ralph/ (optional)
|
|
167
250
|
```
|
|
168
251
|
|
|
169
252
|
---
|
|
170
253
|
|
|
171
254
|
## SUCCESS CRITERIA:
|
|
172
255
|
|
|
173
|
-
- Report generated in `.ralph/reports/`
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
256
|
+
- Report generated in `.ralph/reports/` with ALL structured data from prd.json
|
|
257
|
+
- Task progress table with categories, status, iterations, and commits
|
|
258
|
+
- Failed/blocked tasks documented with error messages
|
|
259
|
+
- Iteration history from `history[]` included
|
|
260
|
+
- File lists from task-level tracking (not git log)
|
|
261
|
+
- Metadata section with execution context
|
|
262
|
+
- Duration calculated from history entries
|
|
177
263
|
- Final summary displayed
|
|
264
|
+
- prd.json `status` and `updated_at` finalized
|
|
178
265
|
|
|
179
266
|
## COMPLETION:
|
|
180
267
|
|