@atlashub/smartstack-cli 3.0.0 → 3.2.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/.documentation/agents.html +1 -371
- package/.documentation/cli-commands.html +1 -1
- package/.documentation/commands.html +1 -1
- package/.documentation/efcore.html +1 -1
- package/.documentation/gitflow.html +1 -1
- package/.documentation/hooks.html +27 -66
- package/.documentation/index.html +166 -166
- package/.documentation/init.html +6 -7
- package/.documentation/installation.html +1 -1
- package/.documentation/prd-json-v2.0.0.md +396 -0
- package/.documentation/ralph-loop.html +1 -9
- package/.documentation/test-web.html +15 -39
- package/.documentation/testing-ba-e2e.md +462 -0
- package/dist/index.js +23 -16
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/templates/agents/gitflow/merge.md +56 -6
- package/templates/agents/gitflow/pr.md +70 -9
- package/templates/project/appsettings.json.template +8 -2
- package/templates/skills/business-analyse/SKILL.md +34 -17
- package/templates/skills/business-analyse/html/ba-interactive.html +147 -84
- package/templates/skills/business-analyse/questionnaire.md +20 -15
- package/templates/skills/business-analyse/steps/step-00-init.md +80 -57
- package/templates/skills/business-analyse/steps/step-03-specify.md +57 -0
- package/templates/skills/business-analyse/steps/step-05-handoff.md +480 -14
- package/templates/skills/business-analyse/steps/step-06-extract.md +131 -3
- package/templates/skills/gitflow/steps/step-pr.md +17 -5
- package/templates/skills/ralph-loop/SKILL.md +158 -33
- package/templates/skills/ralph-loop/steps/step-01-task.md +160 -18
- package/templates/skills/ralph-loop/steps/step-02-execute.md +408 -23
- package/templates/skills/ralph-loop/steps/step-03-commit.md +82 -0
- package/templates/skills/ralph-loop/steps/step-04-check.md +305 -9
- package/templates/skills/ralph-loop/steps/step-05-report.md +115 -0
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: step-02-execute
|
|
3
|
-
description: Execute
|
|
3
|
+
description: Execute task(s) with dependency checks and rich tracking
|
|
4
4
|
next_step: steps/step-03-commit.md
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Step 2: Execute Task
|
|
8
8
|
|
|
9
|
+
> **CONTEXT OPTIMIZATION:** This file is only read ONCE (first iteration).
|
|
10
|
+
> After the first full iteration, ALL subsequent iterations use the COMPACT LOOP
|
|
11
|
+
> in step-04-check.md section 5 which includes inline execution.
|
|
12
|
+
> **DO NOT re-read this file for iterations > 1.**
|
|
13
|
+
|
|
9
14
|
## YOUR TASK:
|
|
10
15
|
|
|
11
|
-
Execute
|
|
16
|
+
Execute the current task(s) from prd.json. For the first iteration, execute ONE task. After the first iteration, the compact loop in step-04 handles batch execution.
|
|
12
17
|
|
|
13
18
|
**ULTRA THINK about the implementation.**
|
|
14
19
|
|
|
@@ -16,12 +21,11 @@ Execute exactly ONE task from prd.json. Do NOT batch multiple tasks.
|
|
|
16
21
|
|
|
17
22
|
## EXECUTION RULES:
|
|
18
23
|
|
|
19
|
-
1. **
|
|
20
|
-
2. **
|
|
21
|
-
3. **
|
|
22
|
-
4. **
|
|
23
|
-
5. **
|
|
24
|
-
6. **TRACK FILES** - Record every file created or modified
|
|
24
|
+
1. **ATOMIC CHANGES** - Changes should be complete and working
|
|
25
|
+
2. **USE MCP** - Validate with SmartStack MCP (once per batch, not per task)
|
|
26
|
+
3. **TRACK FILES** - Record every file created or modified
|
|
27
|
+
4. **CHECK DEPENDENCIES** - Verify all dependencies are met before starting
|
|
28
|
+
5. **BATCH ALLOWED** - Multiple tasks of the same category can be batched (max 5)
|
|
25
29
|
|
|
26
30
|
---
|
|
27
31
|
|
|
@@ -81,6 +85,352 @@ writeJSON('.ralph/prd.json', prd);
|
|
|
81
85
|
| `test` | `scaffold_tests`, `analyze_test_coverage` | xUnit, test naming conventions |
|
|
82
86
|
| `validation` | `validate_conventions` | Build, test, lint checks |
|
|
83
87
|
|
|
88
|
+
**Test task guidance — TDD CYCLE (MANDATORY):**
|
|
89
|
+
|
|
90
|
+
> **CRITICAL:** Tests are NOT optional. Every feature MUST have tests that pass.
|
|
91
|
+
> The cycle is: Generate Code → Generate Tests → Run Tests → Fix Code → Re-run Tests → Pass.
|
|
92
|
+
|
|
93
|
+
When executing `test` category tasks, follow this EXACT sequence:
|
|
94
|
+
|
|
95
|
+
**1. ENSURE TEST PROJECT EXISTS (BLOCKING)**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Detect project name from solution
|
|
99
|
+
PROJECT_NAME=$(basename $(pwd))
|
|
100
|
+
TEST_PROJECT="tests/${PROJECT_NAME}.Tests.Unit"
|
|
101
|
+
|
|
102
|
+
if [ ! -d "$TEST_PROJECT" ]; then
|
|
103
|
+
echo "⚠️ Test project missing. Scaffolding now..."
|
|
104
|
+
|
|
105
|
+
# Create test project
|
|
106
|
+
dotnet new xunit -n "${PROJECT_NAME}.Tests.Unit" -o "$TEST_PROJECT"
|
|
107
|
+
|
|
108
|
+
# Add required packages
|
|
109
|
+
cd "$TEST_PROJECT"
|
|
110
|
+
dotnet add package Moq --version 4.20.72
|
|
111
|
+
dotnet add package FluentAssertions --version 8.3.0
|
|
112
|
+
dotnet add package Microsoft.Extensions.DependencyInjection --version 10.0.2
|
|
113
|
+
cd ../..
|
|
114
|
+
|
|
115
|
+
# Add project references to all src/ projects
|
|
116
|
+
for proj in src/*/*.csproj; do
|
|
117
|
+
dotnet add "$TEST_PROJECT" reference "$proj"
|
|
118
|
+
done
|
|
119
|
+
|
|
120
|
+
# Add test project to solution
|
|
121
|
+
dotnet sln add "$TEST_PROJECT/${PROJECT_NAME}.Tests.Unit.csproj"
|
|
122
|
+
|
|
123
|
+
echo "✅ Test project scaffolded at $TEST_PROJECT"
|
|
124
|
+
fi
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**2. GENERATE TESTS USING MCP (DO NOT WRITE MANUALLY)**
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
// Identify what to test based on task description
|
|
131
|
+
const task = prd.tasks.find(t => t.id === {current_task_id});
|
|
132
|
+
const testType = detectTestType(task.description); // "unit" | "integration" | "security"
|
|
133
|
+
|
|
134
|
+
// For domain tests
|
|
135
|
+
if (task.description.includes("domain entity") || task.description.includes("value object")) {
|
|
136
|
+
// Call MCP to scaffold domain tests
|
|
137
|
+
mcp__smartstack__scaffold_tests({
|
|
138
|
+
module: extractModuleName(task.description),
|
|
139
|
+
test_type: "unit",
|
|
140
|
+
target_layer: "domain",
|
|
141
|
+
target_file: identifyEntityFile(task.description)
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// For service tests
|
|
146
|
+
if (task.description.includes("service")) {
|
|
147
|
+
mcp__smartstack__scaffold_tests({
|
|
148
|
+
module: extractModuleName(task.description),
|
|
149
|
+
test_type: "unit",
|
|
150
|
+
target_layer: "application",
|
|
151
|
+
target_file: identifyServiceFile(task.description)
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// For controller tests
|
|
156
|
+
if (task.description.includes("controller") || task.description.includes("API")) {
|
|
157
|
+
mcp__smartstack__scaffold_tests({
|
|
158
|
+
module: extractModuleName(task.description),
|
|
159
|
+
test_type: "integration",
|
|
160
|
+
target_layer: "api",
|
|
161
|
+
target_file: identifyControllerFile(task.description)
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// For security/permissions tests
|
|
166
|
+
if (task.description.includes("permission") || task.description.includes("security")) {
|
|
167
|
+
mcp__smartstack__scaffold_tests({
|
|
168
|
+
module: extractModuleName(task.description),
|
|
169
|
+
test_type: "security",
|
|
170
|
+
target_layer: "api",
|
|
171
|
+
target_file: identifyControllerFile(task.description)
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**3. RUN TESTS IMMEDIATELY (BLOCKING)**
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Build test project first
|
|
180
|
+
dotnet build "$TEST_PROJECT" --no-restore
|
|
181
|
+
|
|
182
|
+
# Run tests with detailed output
|
|
183
|
+
dotnet test "$TEST_PROJECT" --no-build --verbosity normal
|
|
184
|
+
|
|
185
|
+
# Capture exit code
|
|
186
|
+
TEST_EXIT_CODE=$?
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**4. ANALYZE RESULTS AND IMPROVE (LOOP UNTIL GREEN)**
|
|
190
|
+
|
|
191
|
+
```javascript
|
|
192
|
+
if (TEST_EXIT_CODE !== 0) {
|
|
193
|
+
echo "❌ Tests failed. Analyzing failures...";
|
|
194
|
+
|
|
195
|
+
// Parse test output to identify failures
|
|
196
|
+
const failures = parseTestFailures(testOutput);
|
|
197
|
+
|
|
198
|
+
// CRITICAL: DO NOT PROCEED. Fix the code.
|
|
199
|
+
for (const failure of failures) {
|
|
200
|
+
echo ` - ${failure.testName}: ${failure.reason}`;
|
|
201
|
+
|
|
202
|
+
// Identify what needs fixing
|
|
203
|
+
if (failure.reason.includes("NullReferenceException")) {
|
|
204
|
+
// Fix null handling in implementation
|
|
205
|
+
} else if (failure.reason.includes("Expected") && failure.reason.includes("Actual")) {
|
|
206
|
+
// Fix logic to match expected behavior
|
|
207
|
+
} else if (failure.reason.includes("NotImplementedException")) {
|
|
208
|
+
// Implement missing method
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// After fixes, RE-RUN TESTS (step 3)
|
|
213
|
+
// LOOP until TEST_EXIT_CODE === 0
|
|
214
|
+
|
|
215
|
+
// If cannot fix after 3 attempts:
|
|
216
|
+
task.status = 'failed';
|
|
217
|
+
task.error = `Tests failed after 3 fix attempts: ${failures.map(f => f.testName).join(', ')}`;
|
|
218
|
+
// STOP - do not proceed to commit
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (TEST_EXIT_CODE === 0) {
|
|
222
|
+
echo "✅ All tests passed!";
|
|
223
|
+
{validation_result} = "passed";
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**5. VERIFY TEST COVERAGE (MANDATORY ≥80%)**
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
// Use MCP to analyze coverage
|
|
231
|
+
const coverage = mcp__smartstack__analyze_test_coverage({
|
|
232
|
+
project_path: process.cwd(),
|
|
233
|
+
module: extractModuleName(task.description)
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
if (coverage.percentage < 80) {
|
|
237
|
+
echo `⚠️ Test coverage ${coverage.percentage}% < 80% minimum`;
|
|
238
|
+
echo `Missing coverage for: ${coverage.uncovered_files.join(', ')}`;
|
|
239
|
+
|
|
240
|
+
// Generate additional tests for uncovered code
|
|
241
|
+
for (const file of coverage.uncovered_files) {
|
|
242
|
+
mcp__smartstack__scaffold_tests({
|
|
243
|
+
module: extractModuleName(task.description),
|
|
244
|
+
test_type: "unit",
|
|
245
|
+
target_file: file
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Re-run tests (go back to step 3)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
echo `✅ Test coverage: ${coverage.percentage}% (${coverage.lines_covered}/${coverage.lines_total} lines)`;
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**6. TEST TASK COMPLETION CRITERIA**
|
|
256
|
+
|
|
257
|
+
A test task is ONLY complete when:
|
|
258
|
+
- ✅ Test project exists
|
|
259
|
+
- ✅ Tests generated via MCP (NOT manually written)
|
|
260
|
+
- ✅ `dotnet test` exits with code 0 (all tests pass)
|
|
261
|
+
- ✅ Test coverage ≥ 80%
|
|
262
|
+
- ✅ No `[Fact(Skip = "...")]` present (no skipped tests)
|
|
263
|
+
|
|
264
|
+
**If ANY criterion fails, task.status = 'failed' and DO NOT commit.**
|
|
265
|
+
|
|
266
|
+
**Validation task guidance — FINAL VERIFICATION (BLOCKING):**
|
|
267
|
+
|
|
268
|
+
> **CRITICAL:** The validation task is the LAST task in each module. It verifies the module is production-ready.
|
|
269
|
+
|
|
270
|
+
When executing `validation` category tasks, follow this EXACT sequence:
|
|
271
|
+
|
|
272
|
+
**1. CLEAN BUILD (MANDATORY)**
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
echo "🔨 Running clean build..."
|
|
276
|
+
|
|
277
|
+
# Clean previous builds
|
|
278
|
+
dotnet clean --verbosity quiet
|
|
279
|
+
|
|
280
|
+
# Restore dependencies
|
|
281
|
+
dotnet restore --verbosity quiet
|
|
282
|
+
|
|
283
|
+
# Build entire solution
|
|
284
|
+
dotnet build --no-restore --verbosity normal
|
|
285
|
+
|
|
286
|
+
BUILD_EXIT_CODE=$?
|
|
287
|
+
|
|
288
|
+
if [ $BUILD_EXIT_CODE -ne 0 ]; then
|
|
289
|
+
echo "╔════════════════════════════════════════════════════════════╗"
|
|
290
|
+
echo "║ ❌ BUILD FAILED ║"
|
|
291
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
292
|
+
echo "║ The solution does not compile. ║"
|
|
293
|
+
echo "║ This indicates a critical error in the code. ║"
|
|
294
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
295
|
+
echo "║ CORRECTIVE ACTION: ║"
|
|
296
|
+
echo "║ 1. Review build errors above ║"
|
|
297
|
+
echo "║ 2. Fix compilation errors ║"
|
|
298
|
+
echo "║ 3. Re-run: dotnet build ║"
|
|
299
|
+
echo "║ 4. Once build succeeds, Ralph will continue ║"
|
|
300
|
+
echo "╚════════════════════════════════════════════════════════════╝"
|
|
301
|
+
|
|
302
|
+
task.status = 'failed';
|
|
303
|
+
task.error = 'Build failed. See build output for details.';
|
|
304
|
+
exit 1;
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
echo "✅ Build succeeded";
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**2. RUN FULL TEST SUITE (MANDATORY)**
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
echo "🧪 Running full test suite..."
|
|
314
|
+
|
|
315
|
+
PROJECT_NAME=$(basename $(pwd))
|
|
316
|
+
TEST_PROJECT="tests/${PROJECT_NAME}.Tests.Unit"
|
|
317
|
+
|
|
318
|
+
if [ ! -d "$TEST_PROJECT" ]; then
|
|
319
|
+
echo "⚠️ WARNING: No test project found at $TEST_PROJECT";
|
|
320
|
+
echo "This module has NO tests. This is NOT recommended.";
|
|
321
|
+
task.validation = "warning: no tests";
|
|
322
|
+
else
|
|
323
|
+
# Run ALL tests with detailed output
|
|
324
|
+
dotnet test "$TEST_PROJECT" --no-build --verbosity normal --logger "console;verbosity=detailed"
|
|
325
|
+
|
|
326
|
+
TEST_EXIT_CODE=$?
|
|
327
|
+
|
|
328
|
+
if [ $TEST_EXIT_CODE -ne 0 ]; then
|
|
329
|
+
echo "╔════════════════════════════════════════════════════════════╗"
|
|
330
|
+
echo "║ ❌ TESTS FAILED ║"
|
|
331
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
332
|
+
echo "║ One or more tests are failing. ║"
|
|
333
|
+
echo "║ The module is NOT production-ready. ║"
|
|
334
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
335
|
+
echo "║ CORRECTIVE ACTION: ║"
|
|
336
|
+
echo "║ 1. Review test failures above ║"
|
|
337
|
+
echo "║ 2. Fix the failing code or tests ║"
|
|
338
|
+
echo "║ 3. Re-run: dotnet test ║"
|
|
339
|
+
echo "║ 4. Once all tests pass, Ralph will continue ║"
|
|
340
|
+
echo "╚════════════════════════════════════════════════════════════╝"
|
|
341
|
+
|
|
342
|
+
task.status = 'failed';
|
|
343
|
+
task.error = 'Test suite failed. Module not production-ready.';
|
|
344
|
+
exit 1;
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
echo "✅ All tests passed";
|
|
348
|
+
fi
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**3. MCP VALIDATION (MANDATORY)**
|
|
352
|
+
|
|
353
|
+
```javascript
|
|
354
|
+
echo "🔍 Running MCP validation...";
|
|
355
|
+
|
|
356
|
+
// Validate SmartStack conventions
|
|
357
|
+
const validation = mcp__smartstack__validate_conventions({
|
|
358
|
+
checks: ["all"]
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
if (validation.status === "error" || validation.errors.length > 0) {
|
|
362
|
+
echo "❌ MCP validation failed:";
|
|
363
|
+
for (const error of validation.errors) {
|
|
364
|
+
echo ` - ${error.file}: ${error.message}`;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
task.status = 'failed';
|
|
368
|
+
task.error = `MCP validation failed: ${validation.errors.length} error(s)`;
|
|
369
|
+
exit 1;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (validation.warnings.length > 0) {
|
|
373
|
+
echo "⚠️ MCP validation warnings:";
|
|
374
|
+
for (const warning of validation.warnings) {
|
|
375
|
+
echo ` - ${warning.file}: ${warning.message}`;
|
|
376
|
+
}
|
|
377
|
+
task.validation = `passed with ${validation.warnings.length} warning(s)`;
|
|
378
|
+
} else {
|
|
379
|
+
task.validation = "passed";
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
echo "✅ MCP validation passed";
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**4. GENERATE VALIDATION REPORT**
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
const report = {
|
|
389
|
+
module: {current_module},
|
|
390
|
+
build: { status: "success", duration: buildDuration },
|
|
391
|
+
tests: {
|
|
392
|
+
status: TEST_EXIT_CODE === 0 ? "success" : "failed",
|
|
393
|
+
total: testStats.total,
|
|
394
|
+
passed: testStats.passed,
|
|
395
|
+
failed: testStats.failed,
|
|
396
|
+
skipped: testStats.skipped,
|
|
397
|
+
duration: testStats.duration,
|
|
398
|
+
coverage: coverage.percentage
|
|
399
|
+
},
|
|
400
|
+
mcp: {
|
|
401
|
+
status: validation.status,
|
|
402
|
+
errors: validation.errors.length,
|
|
403
|
+
warnings: validation.warnings.length
|
|
404
|
+
},
|
|
405
|
+
production_ready: (BUILD_EXIT_CODE === 0 && TEST_EXIT_CODE === 0 && validation.errors.length === 0)
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// Append to progress.txt
|
|
409
|
+
const progressEntry = `
|
|
410
|
+
╔═══════════════════════════════════════════════════════════════╗
|
|
411
|
+
║ MODULE VALIDATION REPORT - ${current_module}
|
|
412
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
413
|
+
║ Build: ${report.build.status.toUpperCase()}
|
|
414
|
+
║ Tests: ${report.tests.passed}/${report.tests.total} passed (${report.tests.coverage}% coverage)
|
|
415
|
+
║ MCP: ${report.mcp.status.toUpperCase()} (${report.mcp.errors} errors, ${report.mcp.warnings} warnings)
|
|
416
|
+
║ Production Ready: ${report.production_ready ? "YES ✅" : "NO ❌"}
|
|
417
|
+
╚═══════════════════════════════════════════════════════════════╝
|
|
418
|
+
`;
|
|
419
|
+
appendToFile('.ralph/progress.txt', progressEntry);
|
|
420
|
+
|
|
421
|
+
echo progressEntry;
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**5. VALIDATION TASK COMPLETION CRITERIA**
|
|
425
|
+
|
|
426
|
+
A validation task is ONLY complete when:
|
|
427
|
+
- ✅ `dotnet build` exits with code 0
|
|
428
|
+
- ✅ `dotnet test` exits with code 0 (or no test project + warning logged)
|
|
429
|
+
- ✅ MCP `validate_conventions` has 0 errors
|
|
430
|
+
- ✅ Production ready = true
|
|
431
|
+
|
|
432
|
+
**If ANY criterion fails, task.status = 'failed', module is NOT production-ready, and Ralph STOPS.**
|
|
433
|
+
|
|
84
434
|
**Infrastructure task guidance (MANDATORY directory conventions):**
|
|
85
435
|
|
|
86
436
|
When executing `infrastructure` category tasks, follow these rules strictly:
|
|
@@ -108,26 +458,61 @@ When executing `infrastructure` category tasks, follow these rules strictly:
|
|
|
108
458
|
- Use `SqlObjectHelper.cs` for embedded resource loading
|
|
109
459
|
- Use `CREATE OR ALTER` in SQL files for idempotency
|
|
110
460
|
|
|
111
|
-
**Frontend task guidance (MANDATORY
|
|
461
|
+
**Frontend task guidance — MCP-FIRST PROTOCOL (MANDATORY):**
|
|
462
|
+
|
|
463
|
+
> **CRITICAL:** Frontend code is generated via MCP tools, NOT written from scratch.
|
|
464
|
+
> Writing plain HTML tables, custom div cards, or hardcoded Tailwind is FORBIDDEN.
|
|
465
|
+
> The MCP tools produce SmartStack-compliant code automatically.
|
|
112
466
|
|
|
113
|
-
|
|
467
|
+
**Execution sequence for frontend tasks (follow IN ORDER):**
|
|
114
468
|
|
|
115
|
-
1. **
|
|
116
|
-
-
|
|
117
|
-
- `
|
|
118
|
-
- `
|
|
119
|
-
- `personal.*` → `<Route path="/personal/myspace" element={<UserLayout />}>` children
|
|
120
|
-
- **If routes are placed OUTSIDE the layout wrapper: header, sidebar, and AvatarMenu will NOT render**
|
|
121
|
-
- NEVER create flat routes at the top level of `<Routes>`
|
|
469
|
+
1. **Call `mcp__smartstack__scaffold_api_client`** FIRST
|
|
470
|
+
- Generates: `{entity}Api.ts` with type-safe CRUD methods + React Query hook
|
|
471
|
+
- Uses `apiClient` (NOT axios), NavRoute integration, permission checking
|
|
472
|
+
- Output: `src/services/api/{module}Api.ts`
|
|
122
473
|
|
|
123
|
-
2. **
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
474
|
+
2. **Call `mcp__smartstack__scaffold_routes`** (source: "controllers", scope: "all")
|
|
475
|
+
- Updates: `navRoutes.generated.ts` + route config in App.tsx
|
|
476
|
+
- Generates: Nested routes INSIDE correct Layout wrapper
|
|
477
|
+
- Context mapping: `business.*` → `BusinessLayout`, `platform.*` → `AdminLayout`
|
|
127
478
|
|
|
128
|
-
3. **
|
|
479
|
+
3. **Create pages using SmartStack components** (reference: `templates-frontend.md`)
|
|
480
|
+
- **List pages**: Use `SmartTable` (NOT HTML `<table>`), `SmartFilter`, `EntityCard` for grid view
|
|
481
|
+
- **Detail pages**: Use `EntityDetailCard`, `StatusBadge`, tab layout
|
|
482
|
+
- **Create/Edit pages**: Use `SmartForm` with `FluentValidation`-backed fields, tab layout
|
|
483
|
+
- **Dashboard pages**: Use `StatCard`, Recharts components
|
|
484
|
+
- Match wireframes from feature.json `specification.uiWireframes[]`
|
|
485
|
+
|
|
486
|
+
4. **Create preferences hook**: `use{Module}Preferences.ts`
|
|
487
|
+
- pageSize, sortColumn, sortDirection, visibleColumns, viewMode, filters
|
|
488
|
+
|
|
489
|
+
5. **Generate i18n** (4 languages: fr, en, it, de)
|
|
490
|
+
- All UI labels, validation messages, button text, empty states
|
|
491
|
+
|
|
492
|
+
6. **Post-generation validation (BLOCKING)**:
|
|
493
|
+
- `npm run typecheck` MUST pass
|
|
494
|
+
- NO hardcoded colors (scan for `bg-blue-`, `text-gray-`, etc.)
|
|
495
|
+
- CSS variables ONLY: `bg-[var(--bg-card)]`, `text-[var(--text-primary)]`
|
|
496
|
+
- Routes are NESTED and INSIDE Layout wrapper
|
|
497
|
+
- All pages have loading/error/empty states
|
|
498
|
+
- API client uses `@/services/api/apiClient` (NOT `import axios`)
|
|
499
|
+
- `EntityCard` for grid views (NOT custom `<div>` cards)
|
|
500
|
+
|
|
501
|
+
**FORBIDDEN patterns (any of these = FAIL the task):**
|
|
502
|
+
```
|
|
503
|
+
import axios from 'axios' → use @/services/api/apiClient
|
|
504
|
+
<table>...</table> → use SmartTable component
|
|
505
|
+
<div className="bg-blue-600"> → use bg-[var(--color-accent-600)]
|
|
506
|
+
<Route path="/business/app/mod" /> → MUST be nested inside BusinessLayout
|
|
507
|
+
Only fr/en translations → MUST have 4 languages (fr, en, it, de)
|
|
508
|
+
```
|
|
129
509
|
|
|
130
|
-
|
|
510
|
+
**Layout wrapper mapping:**
|
|
511
|
+
| Context | Layout | Route path |
|
|
512
|
+
|---------|--------|------------|
|
|
513
|
+
| `platform.*` | `AdminLayout` | `/platform` |
|
|
514
|
+
| `business.*` | `BusinessLayout` | `/business` |
|
|
515
|
+
| `personal.*` | `UserLayout` | `/personal/myspace` |
|
|
131
516
|
|
|
132
517
|
**API/Controller task guidance (MANDATORY folder hierarchy):**
|
|
133
518
|
|
|
@@ -6,6 +6,11 @@ next_step: steps/step-04-check.md
|
|
|
6
6
|
|
|
7
7
|
# Step 3: Commit Changes
|
|
8
8
|
|
|
9
|
+
> **CONTEXT OPTIMIZATION:** This file is only read ONCE (first iteration).
|
|
10
|
+
> After the first full iteration, ALL subsequent iterations use the COMPACT LOOP
|
|
11
|
+
> in step-04-check.md section 5 which includes inline commit logic.
|
|
12
|
+
> **DO NOT re-read this file for iterations > 1.**
|
|
13
|
+
|
|
9
14
|
## YOUR TASK:
|
|
10
15
|
|
|
11
16
|
Commit the changes from the executed task, finalize task tracking in prd.json, and append to history.
|
|
@@ -14,6 +19,83 @@ Commit the changes from the executed task, finalize task tracking in prd.json, a
|
|
|
14
19
|
|
|
15
20
|
## EXECUTION SEQUENCE:
|
|
16
21
|
|
|
22
|
+
### 0. PRE-COMMIT VALIDATION (BLOCKING)
|
|
23
|
+
|
|
24
|
+
**CRITICAL: Before ANY commit, verify all tests pass.**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Check if test project exists
|
|
28
|
+
PROJECT_NAME=$(basename $(pwd))
|
|
29
|
+
TEST_PROJECT="tests/${PROJECT_NAME}.Tests.Unit"
|
|
30
|
+
|
|
31
|
+
if [ -d "$TEST_PROJECT" ]; then
|
|
32
|
+
echo "Running full test suite before commit..."
|
|
33
|
+
|
|
34
|
+
# Run ALL tests (not just current task's tests)
|
|
35
|
+
dotnet test "$TEST_PROJECT" --no-build --verbosity minimal
|
|
36
|
+
|
|
37
|
+
TEST_EXIT_CODE=$?
|
|
38
|
+
|
|
39
|
+
if [ $TEST_EXIT_CODE -ne 0 ]; then
|
|
40
|
+
echo "╔════════════════════════════════════════════════════════════╗"
|
|
41
|
+
echo "║ ❌ COMMIT BLOCKED: TESTS FAILED ║"
|
|
42
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
43
|
+
echo "║ Cannot commit code when tests are failing. ║"
|
|
44
|
+
echo "║ This prevents broken code from entering the repository. ║"
|
|
45
|
+
echo "╠════════════════════════════════════════════════════════════╣"
|
|
46
|
+
echo "║ ACTION REQUIRED: ║"
|
|
47
|
+
echo "║ 1. Review test failures above ║"
|
|
48
|
+
echo "║ 2. Fix the failing code ║"
|
|
49
|
+
echo "║ 3. Re-run: dotnet test ║"
|
|
50
|
+
echo "║ 4. Once tests pass, Ralph will commit automatically ║"
|
|
51
|
+
echo "╚════════════════════════════════════════════════════════════╝"
|
|
52
|
+
|
|
53
|
+
# Mark task as failed (do not complete)
|
|
54
|
+
# Update prd.json
|
|
55
|
+
const prd = readJSON('.ralph/prd.json');
|
|
56
|
+
const task = prd.tasks.find(t => t.id === {current_task_id});
|
|
57
|
+
task.status = 'failed';
|
|
58
|
+
task.error = 'Pre-commit test suite failed. Cannot commit broken code.';
|
|
59
|
+
writeJSON('.ralph/prd.json', prd);
|
|
60
|
+
|
|
61
|
+
# STOP - return to step-02 to fix
|
|
62
|
+
exit 1;
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo "✅ All tests passed. Proceeding with commit..."
|
|
66
|
+
fi
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Additional validation for specific categories:**
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
const task = prd.tasks.find(t => t.id === {current_task_id});
|
|
73
|
+
|
|
74
|
+
// For backend changes: ensure build succeeds
|
|
75
|
+
if (['domain', 'application', 'infrastructure', 'api'].includes(task.category)) {
|
|
76
|
+
dotnet build --no-restore --verbosity quiet
|
|
77
|
+
if ($? !== 0) {
|
|
78
|
+
echo "❌ Build failed. Cannot commit broken code.";
|
|
79
|
+
task.status = 'failed';
|
|
80
|
+
task.error = 'Build failed';
|
|
81
|
+
exit 1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// For frontend changes: ensure typecheck passes
|
|
86
|
+
if (task.category === 'frontend') {
|
|
87
|
+
npm run typecheck
|
|
88
|
+
if ($? !== 0) {
|
|
89
|
+
echo "❌ TypeScript errors. Cannot commit broken code.";
|
|
90
|
+
task.status = 'failed';
|
|
91
|
+
task.error = 'TypeScript compilation failed';
|
|
92
|
+
exit 1;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**If ALL validations pass, proceed to staging.**
|
|
98
|
+
|
|
17
99
|
### 1. Stage Changes
|
|
18
100
|
|
|
19
101
|
**Add modified files:**
|