@atlashub/smartstack-cli 3.35.0 → 3.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/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +111 -46
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +3 -2
- package/scripts/extract-api-endpoints.ts +325 -0
- package/scripts/extract-business-rules.ts +440 -0
- package/scripts/generate-doc-with-mock-ui.ts +811 -0
- package/scripts/health-check.sh +168 -0
- package/scripts/postinstall.js +18 -0
- package/templates/skills/apex/SKILL.md +3 -0
- package/templates/skills/apex/steps/step-00-init.md +4 -1
- package/templates/skills/apex/steps/step-03-execute.md +22 -0
- package/templates/skills/documentation/SKILL.md +175 -9
- package/templates/skills/efcore/steps/squash/step-03-create.md +6 -4
- package/templates/skills/gitflow/_shared.md +3 -1
- package/templates/skills/gitflow/steps/step-pr.md +34 -0
- package/templates/skills/ralph-loop/SKILL.md +26 -2
- package/templates/skills/ralph-loop/references/team-orchestration.md +331 -14
- package/templates/skills/ralph-loop/steps/step-00-init.md +4 -0
- package/templates/skills/ralph-loop/steps/step-02-execute.md +163 -2
|
@@ -6,7 +6,295 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Mode Selection
|
|
10
|
+
|
|
11
|
+
Ralph-loop supports TWO team orchestration modes:
|
|
12
|
+
|
|
13
|
+
### 1. **Parallel Mode** (`-p` flag) — RECOMMENDED
|
|
14
|
+
|
|
15
|
+
**Architecture:** Phase 0 (entities sequential by Ralph) + Phase 1-N (teammates parallel)
|
|
16
|
+
|
|
17
|
+
**Avantages:**
|
|
18
|
+
- ✅ Zero EF Core ModelSnapshot conflicts (entities generated once in Phase 0)
|
|
19
|
+
- ✅ True parallelization on 75-85% of code (services/controllers/frontend/tests)
|
|
20
|
+
- ✅ Teammates have isolated contexts (no saturation)
|
|
21
|
+
- ✅ 2-3x faster than sequential mode
|
|
22
|
+
- ✅ Simple coordination (no dependency graph needed)
|
|
23
|
+
|
|
24
|
+
**When to use:**
|
|
25
|
+
- 2+ applications OR 5+ modules
|
|
26
|
+
- Complex modules with many entities
|
|
27
|
+
- Need guaranteed conflict-free execution
|
|
28
|
+
|
|
29
|
+
**Workflow:**
|
|
30
|
+
1. Ralph generates ALL entities + migration (Phase 0)
|
|
31
|
+
2. Ralph spawns teammates (1 per application or module)
|
|
32
|
+
3. Teammates generate services/controllers/frontend/tests in parallel
|
|
33
|
+
4. Ralph collects results + validates
|
|
34
|
+
5. TeamDelete
|
|
35
|
+
|
|
36
|
+
See section **Parallel Mode Protocol** below.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### 2. **Dependency Layer Mode** (no `-p` flag) — LEGACY
|
|
41
|
+
|
|
42
|
+
**Architecture:** Layer-by-layer execution based on dependency graph
|
|
43
|
+
|
|
44
|
+
**Avantages:**
|
|
45
|
+
- ✅ Respects module dependencies
|
|
46
|
+
- ✅ Works without `-p` flag (backward compatible)
|
|
47
|
+
|
|
48
|
+
**Inconvénients:**
|
|
49
|
+
- ⚠️ Requires dependency graph in feature.json
|
|
50
|
+
- ⚠️ EF Core ModelSnapshot conflicts possible if modules touch same entities
|
|
51
|
+
- ⚠️ More complex coordination
|
|
52
|
+
|
|
53
|
+
**When to use:**
|
|
54
|
+
- Modules have strict dependencies
|
|
55
|
+
- No `-p` flag specified (legacy mode)
|
|
56
|
+
- Single-application projects with <5 modules
|
|
57
|
+
|
|
58
|
+
See section **Dependency Layer Mode Protocol** below.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Parallel Mode Protocol (if `-p` flag)
|
|
63
|
+
|
|
64
|
+
### Phase 0: Foundation (Ralph sequential)
|
|
65
|
+
|
|
66
|
+
Ralph generates ALL entities from ALL modules in ONE pass to avoid ModelSnapshot conflicts.
|
|
67
|
+
|
|
68
|
+
```javascript
|
|
69
|
+
// 1. Collect all entities
|
|
70
|
+
const allPrds = glob('.ralph/prd-*.json').map(f => readJSON(f));
|
|
71
|
+
const allEntities = [];
|
|
72
|
+
const allModules = [];
|
|
73
|
+
|
|
74
|
+
for (const prd of allPrds) {
|
|
75
|
+
const entities = prd.tasks
|
|
76
|
+
.filter(t => t.category === 'domain')
|
|
77
|
+
.map(t => extractEntityName(t.description));
|
|
78
|
+
|
|
79
|
+
allEntities.push(...entities);
|
|
80
|
+
allModules.push({
|
|
81
|
+
code: prd.project.module,
|
|
82
|
+
application: prd.project.application,
|
|
83
|
+
entityCount: entities.length
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
console.log(`Phase 0: Generating ${allEntities.length} entities from ${allModules.length} modules`);
|
|
88
|
+
|
|
89
|
+
// 2. Invoke apex in foundation mode
|
|
90
|
+
// /apex --foundation -d .ralph/prd.json
|
|
91
|
+
//
|
|
92
|
+
// Apex will:
|
|
93
|
+
// - Generate ALL entity classes
|
|
94
|
+
// - Generate ALL EF configurations
|
|
95
|
+
// - Register ALL DbSets in DbContext
|
|
96
|
+
// - Create ONE migration with all entities
|
|
97
|
+
// - Skip services/controllers/frontend/tests
|
|
98
|
+
|
|
99
|
+
// 3. Verify build
|
|
100
|
+
const buildResult = bash('dotnet build');
|
|
101
|
+
if (buildResult.exitCode !== 0) {
|
|
102
|
+
throw new Error('Phase 0 build failed');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 4. Commit foundation
|
|
106
|
+
bash(`git add . && git commit -m "chore(foundation): entities for all modules"`);
|
|
107
|
+
|
|
108
|
+
console.log(`Phase 0 complete. ModelSnapshot contains ${allEntities.length} entities.`);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### Phase 1-N: Spawn Teammates (parallel)
|
|
114
|
+
|
|
115
|
+
Ralph creates a team and spawns teammates (1 per application OR 1 per module if app has >3 modules).
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
// 1. Determine teammate granularity
|
|
119
|
+
const teammates = [];
|
|
120
|
+
const applicationsMap = {}; // group modules by application
|
|
121
|
+
|
|
122
|
+
for (const mod of allModules) {
|
|
123
|
+
if (!applicationsMap[mod.application]) {
|
|
124
|
+
applicationsMap[mod.application] = [];
|
|
125
|
+
}
|
|
126
|
+
applicationsMap[mod.application].push(mod);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (const [appName, modules] of Object.entries(applicationsMap)) {
|
|
130
|
+
if (modules.length <= 3) {
|
|
131
|
+
// 1 teammate per APPLICATION
|
|
132
|
+
teammates.push({
|
|
133
|
+
name: `apex-${kebabCase(appName)}`,
|
|
134
|
+
application: appName,
|
|
135
|
+
modules: modules.map(m => m.code),
|
|
136
|
+
scope: 'application'
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
// Application has >3 modules → 1 teammate per MODULE
|
|
140
|
+
for (const mod of modules) {
|
|
141
|
+
teammates.push({
|
|
142
|
+
name: `apex-${kebabCase(appName)}-${kebabCase(mod.code)}`,
|
|
143
|
+
application: appName,
|
|
144
|
+
modules: [mod.code],
|
|
145
|
+
scope: 'module'
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
console.log(`Spawning ${teammates.length} teammates:`);
|
|
152
|
+
for (const t of teammates) {
|
|
153
|
+
console.log(` - ${t.name} (${t.scope}): ${t.modules.join(', ')}`);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 2. Create team
|
|
157
|
+
const teamName = `smartstack-${kebabCase(projectName)}`;
|
|
158
|
+
TeamCreate({ team_name: teamName, description: `Parallel dev for ${teammates.length} modules` });
|
|
159
|
+
|
|
160
|
+
// 3. Spawn teammates in parallel (single message, multiple Task calls)
|
|
161
|
+
for (const teammate of teammates) {
|
|
162
|
+
const prdFiles = teammate.modules.map(m => `.ralph/prd-${m}.json`);
|
|
163
|
+
|
|
164
|
+
Task({
|
|
165
|
+
subagent_type: "apex",
|
|
166
|
+
name: teammate.name,
|
|
167
|
+
team_name: teamName,
|
|
168
|
+
mode: "bypassPermissions",
|
|
169
|
+
prompt: `
|
|
170
|
+
You are teammate ${teammate.name}.
|
|
171
|
+
|
|
172
|
+
## Context
|
|
173
|
+
- Application: ${teammate.application}
|
|
174
|
+
- Modules: ${teammate.modules.join(', ')}
|
|
175
|
+
- PRD files: ${prdFiles.join(', ')}
|
|
176
|
+
|
|
177
|
+
## Phase 0 Completed (by Ralph)
|
|
178
|
+
ALL entity classes, EF configurations, and migrations are already created.
|
|
179
|
+
The ModelSnapshot is complete and the database schema is ready.
|
|
180
|
+
|
|
181
|
+
## Your Task
|
|
182
|
+
For each module in your scope, generate:
|
|
183
|
+
- Services (Application layer)
|
|
184
|
+
- Controllers (API layer)
|
|
185
|
+
- Seed data (Navigation + Permissions + RolePermissions + Business data)
|
|
186
|
+
- Frontend (Pages + Routes + i18n for all 4 languages)
|
|
187
|
+
- Tests (Unit + Integration)
|
|
188
|
+
|
|
189
|
+
## Execution
|
|
190
|
+
For each PRD file:
|
|
191
|
+
1. INVOKE /apex -d {prdFile}
|
|
192
|
+
→ Apex will see existing entities and skip domain/infrastructure layers
|
|
193
|
+
→ Apex will generate services/controllers/seed/frontend/tests
|
|
194
|
+
→ Apex will run POST-CHECKs and commit per layer
|
|
195
|
+
2. Verify build passes
|
|
196
|
+
3. Verify tests pass
|
|
197
|
+
|
|
198
|
+
## Communication Protocol
|
|
199
|
+
When ALL your modules are complete:
|
|
200
|
+
SendMessage({
|
|
201
|
+
type: "message",
|
|
202
|
+
recipient: "team-lead",
|
|
203
|
+
content: "COMPLETE:${teammate.name}",
|
|
204
|
+
summary: "${teammate.name} completed ${teammate.modules.join(', ')}"
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
If you encounter a BLOCKING error:
|
|
208
|
+
SendMessage({
|
|
209
|
+
type: "message",
|
|
210
|
+
recipient: "team-lead",
|
|
211
|
+
content: "ERROR:${teammate.name}:{error_summary}",
|
|
212
|
+
summary: "${teammate.name} blocked"
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
## DO NOT
|
|
216
|
+
- Create new entities (already done in Phase 0)
|
|
217
|
+
- Create migrations (ModelSnapshot already complete)
|
|
218
|
+
- Modify existing entities or EF configs
|
|
219
|
+
`,
|
|
220
|
+
description: `${teammate.application} - ${teammate.modules.join(', ')}`
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### Collect Results
|
|
228
|
+
|
|
229
|
+
Ralph waits for all teammates to send completion messages.
|
|
230
|
+
|
|
231
|
+
```javascript
|
|
232
|
+
// Track completion
|
|
233
|
+
const expectedTeammates = teammates.length;
|
|
234
|
+
let completedTeammates = 0;
|
|
235
|
+
let errors = [];
|
|
236
|
+
|
|
237
|
+
// Messages arrive automatically via SendMessage
|
|
238
|
+
// When a teammate sends "COMPLETE:xxx", increment counter
|
|
239
|
+
// When a teammate sends "ERROR:xxx:yyy", record error
|
|
240
|
+
|
|
241
|
+
// Wait loop (teammates send messages when done)
|
|
242
|
+
console.log(`Waiting for ${expectedTeammates} teammates to complete...`);
|
|
243
|
+
|
|
244
|
+
// After all teammates complete (or timeout):
|
|
245
|
+
console.log(`Results:`);
|
|
246
|
+
console.log(` ✓ Completed: ${completedTeammates}/${expectedTeammates}`);
|
|
247
|
+
console.log(` ✗ Errors: ${errors.length}`);
|
|
248
|
+
|
|
249
|
+
for (const error of errors) {
|
|
250
|
+
console.log(` - ${error}`);
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Validation
|
|
257
|
+
|
|
258
|
+
After all teammates complete, Ralph runs global validation.
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Full solution build
|
|
262
|
+
dotnet build --no-restore
|
|
263
|
+
|
|
264
|
+
# Full test suite
|
|
265
|
+
dotnet test --no-build
|
|
266
|
+
|
|
267
|
+
# MCP validation
|
|
268
|
+
mcp__smartstack__validate_conventions checks=["all"]
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
### Cleanup
|
|
274
|
+
|
|
275
|
+
```javascript
|
|
276
|
+
// Shutdown teammates
|
|
277
|
+
for (const teammate of teammates) {
|
|
278
|
+
SendMessage({
|
|
279
|
+
type: "shutdown_request",
|
|
280
|
+
recipient: teammate.name,
|
|
281
|
+
content: "All modules complete, shutting down team"
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Wait for shutdown confirmations, then:
|
|
286
|
+
TeamDelete();
|
|
287
|
+
|
|
288
|
+
console.log(`Team ${teamName} deleted. All teammates shut down.`);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Dependency Layer Mode Protocol (no `-p` flag — LEGACY)
|
|
294
|
+
|
|
295
|
+
### 1. Layer Detection
|
|
296
|
+
|
|
297
|
+
**For dependency layer mode only (legacy, no `-p` flag).**
|
|
10
298
|
|
|
11
299
|
Read dependency graph from master feature.json:
|
|
12
300
|
|
|
@@ -32,7 +320,7 @@ if (!layers) {
|
|
|
32
320
|
|
|
33
321
|
---
|
|
34
322
|
|
|
35
|
-
|
|
323
|
+
### 2. Team Setup (Legacy)
|
|
36
324
|
|
|
37
325
|
```javascript
|
|
38
326
|
// Create team
|
|
@@ -49,7 +337,9 @@ const teamContext = {
|
|
|
49
337
|
|
|
50
338
|
---
|
|
51
339
|
|
|
52
|
-
|
|
340
|
+
### 3. Teammate Spawn — Per Layer (Legacy)
|
|
341
|
+
|
|
342
|
+
**For dependency layer mode only.**
|
|
53
343
|
|
|
54
344
|
For each layer, spawn teammates IN PARALLEL (single message, multiple Task calls):
|
|
55
345
|
|
|
@@ -80,7 +370,9 @@ for (const layer of layers) {
|
|
|
80
370
|
|
|
81
371
|
---
|
|
82
372
|
|
|
83
|
-
|
|
373
|
+
### 4. Teammate Prompt Template (Legacy)
|
|
374
|
+
|
|
375
|
+
**For dependency layer mode only.**
|
|
84
376
|
|
|
85
377
|
Each teammate receives a self-contained prompt that delegates to `/apex`:
|
|
86
378
|
|
|
@@ -119,7 +411,9 @@ ${prdFile}
|
|
|
119
411
|
|
|
120
412
|
---
|
|
121
413
|
|
|
122
|
-
|
|
414
|
+
### 5. Team Lead Wait Logic (Legacy)
|
|
415
|
+
|
|
416
|
+
**For dependency layer mode only.**
|
|
123
417
|
|
|
124
418
|
After spawning a layer, the team lead waits for completion:
|
|
125
419
|
|
|
@@ -144,7 +438,9 @@ let errors = [];
|
|
|
144
438
|
|
|
145
439
|
---
|
|
146
440
|
|
|
147
|
-
|
|
441
|
+
### 6. Cross-Module Verification (Legacy)
|
|
442
|
+
|
|
443
|
+
**For dependency layer mode only.**
|
|
148
444
|
|
|
149
445
|
After all layers complete, team lead runs:
|
|
150
446
|
|
|
@@ -161,7 +457,9 @@ mcp__smartstack__validate_conventions checks=["all"]
|
|
|
161
457
|
|
|
162
458
|
---
|
|
163
459
|
|
|
164
|
-
|
|
460
|
+
### 7. Cleanup (Legacy)
|
|
461
|
+
|
|
462
|
+
**For dependency layer mode only.**
|
|
165
463
|
|
|
166
464
|
After all modules done and report generated:
|
|
167
465
|
|
|
@@ -177,12 +475,31 @@ TeamDelete();
|
|
|
177
475
|
|
|
178
476
|
---
|
|
179
477
|
|
|
478
|
+
---
|
|
479
|
+
|
|
180
480
|
## Decision Matrix
|
|
181
481
|
|
|
182
|
-
| Condition | Action |
|
|
183
|
-
|
|
184
|
-
| 1 module |
|
|
185
|
-
| 2+ modules,
|
|
186
|
-
| 2+ modules, with
|
|
187
|
-
|
|
|
188
|
-
|
|
|
482
|
+
| Condition | Mode | Action |
|
|
483
|
+
|-----------|------|--------|
|
|
484
|
+
| 1 module | No team | Classic compact loop (no teams) |
|
|
485
|
+
| 2+ modules, `-p` flag | **Parallel Mode** | Phase 0 (Ralph entities) + spawn teammates per app/module |
|
|
486
|
+
| 2+ modules, no `-p`, with dependency graph | Dependency Layer Mode (legacy) | Parallel within each layer based on dependencies |
|
|
487
|
+
| 2+ modules, no `-p`, no dependency graph | Sequential (legacy) | Sequential layers (one module at a time) |
|
|
488
|
+
| Teammate error (parallel) | Continue | Log error, other teammates continue, report in step-05 |
|
|
489
|
+
| Teammate error (legacy) | Continue | Log, try to continue other modules |
|
|
490
|
+
| All modules done (parallel) | Validate + Report | Global build/test → step-05 report → TeamDelete |
|
|
491
|
+
| All modules done (legacy) | Validate + Report | Cross-module verify → step-05 → TeamDelete |
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## Recommendations
|
|
496
|
+
|
|
497
|
+
| Scenario | Recommended Mode |
|
|
498
|
+
|----------|------------------|
|
|
499
|
+
| **Multi-app project** (HR + CRM + PM) | **Parallel mode** (`-p`) — 2-3x faster, zero conflicts |
|
|
500
|
+
| **Single-app, 5+ modules** | **Parallel mode** (`-p`) — better scalability |
|
|
501
|
+
| **Single-app, 2-4 modules** | Parallel mode (`-p`) OR sequential (both OK) |
|
|
502
|
+
| **Modules with strict dependencies** | Dependency layer mode (no `-p`) OR sequential |
|
|
503
|
+
| **Single module** | No teams (compact loop) |
|
|
504
|
+
|
|
505
|
+
**Default recommendation: Use `-p` for 2+ modules.**
|
|
@@ -32,6 +32,7 @@ Defaults:
|
|
|
32
32
|
completion_promise: null
|
|
33
33
|
verbose_mode: false
|
|
34
34
|
resume_mode: false
|
|
35
|
+
parallel_mode: false
|
|
35
36
|
current_iteration: 1
|
|
36
37
|
|
|
37
38
|
Flags:
|
|
@@ -39,9 +40,12 @@ Flags:
|
|
|
39
40
|
-c TEXT / --completion-promise TEXT → {completion_promise} = TEXT
|
|
40
41
|
-v / --verbose → {verbose_mode} = true
|
|
41
42
|
-r / --resume → {resume_mode} = true
|
|
43
|
+
-p / --parallel → {parallel_mode} = true
|
|
42
44
|
Remainder → {task_description}
|
|
43
45
|
```
|
|
44
46
|
|
|
47
|
+
**If `-p` detected:** set `parallel_mode = true`. Ralph will execute Phase 0 (entities) sequentially, then spawn parallel teammates for services/controllers/frontend/tests. Requires 2+ modules to be effective.
|
|
48
|
+
|
|
45
49
|
## 2. Verify MCP (MANDATORY)
|
|
46
50
|
|
|
47
51
|
```
|
|
@@ -52,7 +52,168 @@ writeJSON('.ralph/prd.json', prd);
|
|
|
52
52
|
|
|
53
53
|
### 3. Delegate to /apex
|
|
54
54
|
|
|
55
|
-
#### 3a.
|
|
55
|
+
#### 3a. Parallel Mode (if `-p` flag)
|
|
56
|
+
|
|
57
|
+
**IF `{parallel_mode}` == true:**
|
|
58
|
+
|
|
59
|
+
##### Phase 0: Foundation (Ralph sequential)
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// Collect ALL entities from ALL modules
|
|
63
|
+
const allEntities = [];
|
|
64
|
+
const allModules = [];
|
|
65
|
+
for (const prdFile of glob('.ralph/prd-*.json')) {
|
|
66
|
+
const modulePrd = readJSON(prdFile);
|
|
67
|
+
const moduleEntities = modulePrd.tasks
|
|
68
|
+
.filter(t => t.category === 'domain')
|
|
69
|
+
.map(t => extractEntityName(t.description));
|
|
70
|
+
allEntities.push(...moduleEntities);
|
|
71
|
+
allModules.push({
|
|
72
|
+
code: modulePrd.project.module,
|
|
73
|
+
application: modulePrd.project.application,
|
|
74
|
+
prdFile: prdFile,
|
|
75
|
+
entityCount: moduleEntities.length
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log(`PARALLEL MODE: Phase 0 — Foundation`);
|
|
80
|
+
console.log(` Generating ${allEntities.length} entities from ${allModules.length} modules`);
|
|
81
|
+
console.log(` Entities: ${allEntities.join(', ')}`);
|
|
82
|
+
|
|
83
|
+
// Ralph generates ALL entities via apex foundation mode
|
|
84
|
+
// INVOKE: /apex --foundation -d .ralph/prd.json
|
|
85
|
+
//
|
|
86
|
+
// Apex will:
|
|
87
|
+
// - Generate ALL entity classes
|
|
88
|
+
// - Generate ALL EF configurations
|
|
89
|
+
// - Register ALL DbSets in DbContext
|
|
90
|
+
// - Create ONE migration with all entities
|
|
91
|
+
// - Skip services/controllers/frontend/tests
|
|
92
|
+
|
|
93
|
+
console.log(`Phase 0 completed. ModelSnapshot contains ${allEntities.length} entities.`);
|
|
94
|
+
console.log(`Committing foundation...`);
|
|
95
|
+
|
|
96
|
+
// Git commit
|
|
97
|
+
// bash: git add . && git commit -m "chore(foundation): entities for all modules"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
##### Phase 1-N: Spawn Teammates (parallel)
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// Determine granularity: 1 teammate per APPLICATION or per MODULE
|
|
104
|
+
const teammates = [];
|
|
105
|
+
const applicationsMap = {}; // group modules by application
|
|
106
|
+
|
|
107
|
+
for (const mod of allModules) {
|
|
108
|
+
if (!applicationsMap[mod.application]) {
|
|
109
|
+
applicationsMap[mod.application] = [];
|
|
110
|
+
}
|
|
111
|
+
applicationsMap[mod.application].push(mod);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
for (const [appName, modules] of Object.entries(applicationsMap)) {
|
|
115
|
+
if (modules.length <= 3) {
|
|
116
|
+
// 1 teammate per APPLICATION
|
|
117
|
+
teammates.push({
|
|
118
|
+
name: `apex-${kebabCase(appName)}`,
|
|
119
|
+
application: appName,
|
|
120
|
+
modules: modules.map(m => m.code),
|
|
121
|
+
prdFiles: modules.map(m => m.prdFile)
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
// Application has >3 modules → 1 teammate per MODULE
|
|
125
|
+
for (const mod of modules) {
|
|
126
|
+
teammates.push({
|
|
127
|
+
name: `apex-${kebabCase(appName)}-${kebabCase(mod.code)}`,
|
|
128
|
+
application: appName,
|
|
129
|
+
modules: [mod.code],
|
|
130
|
+
prdFiles: [mod.prdFile]
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
console.log(`Spawning ${teammates.length} teammates:`);
|
|
137
|
+
for (const t of teammates) {
|
|
138
|
+
console.log(` - ${t.name}: ${t.modules.join(', ')}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Create team
|
|
142
|
+
TeamCreate({
|
|
143
|
+
team_name: `smartstack-${kebabCase(prd.project.name || 'project')}`,
|
|
144
|
+
description: `Parallel development for ${teammates.length} modules`
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Spawn teammates
|
|
148
|
+
for (const teammate of teammates) {
|
|
149
|
+
Task({
|
|
150
|
+
subagent_type: "apex",
|
|
151
|
+
name: teammate.name,
|
|
152
|
+
team_name: `smartstack-${kebabCase(prd.project.name || 'project')}`,
|
|
153
|
+
prompt: `
|
|
154
|
+
You are teammate ${teammate.name}.
|
|
155
|
+
|
|
156
|
+
CONTEXT:
|
|
157
|
+
- Application: ${teammate.application}
|
|
158
|
+
- Modules: ${teammate.modules.join(', ')}
|
|
159
|
+
- PRD files: ${teammate.prdFiles.join(', ')}
|
|
160
|
+
|
|
161
|
+
ENTITIES ALREADY EXIST (Phase 0 completed by Ralph):
|
|
162
|
+
All entity classes, EF configurations, and migrations are already created.
|
|
163
|
+
The ModelSnapshot is complete and the database is ready.
|
|
164
|
+
|
|
165
|
+
YOUR TASK:
|
|
166
|
+
For each module, generate:
|
|
167
|
+
- Services (Application layer)
|
|
168
|
+
- Controllers (API layer)
|
|
169
|
+
- Seed data (Navigation + Permissions + Business data)
|
|
170
|
+
- Frontend (Pages + Routes + i18n for all 4 languages)
|
|
171
|
+
- Tests (Unit + Integration)
|
|
172
|
+
|
|
173
|
+
DO NOT:
|
|
174
|
+
- Create new entities (already done)
|
|
175
|
+
- Create migrations (ModelSnapshot already complete)
|
|
176
|
+
|
|
177
|
+
EXECUTE:
|
|
178
|
+
For each PRD file: invoke /apex -d {prdFile}
|
|
179
|
+
Apex will see existing entities and skip domain/infrastructure layers.
|
|
180
|
+
|
|
181
|
+
When done, send a message to team lead with results.
|
|
182
|
+
`
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Ralph waits for teammates to complete
|
|
187
|
+
// Each teammate will send a message when done
|
|
188
|
+
// Ralph collects results and proceeds to validation
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
##### Collect Results
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
// Wait for all teammates to send completion messages
|
|
195
|
+
// Ralph receives SendMessage from each teammate with status
|
|
196
|
+
|
|
197
|
+
const teammateResults = []; // populated from teammate messages
|
|
198
|
+
|
|
199
|
+
console.log(`All teammates completed:`);
|
|
200
|
+
for (const result of teammateResults) {
|
|
201
|
+
console.log(` - ${result.name}: ${result.status}`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Cleanup team
|
|
205
|
+
TeamDelete();
|
|
206
|
+
|
|
207
|
+
// Proceed to step-03 for global validation
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
> See `references/team-orchestration.md` for full parallel execution protocol.
|
|
211
|
+
|
|
212
|
+
**ELSE (not parallel mode):**
|
|
213
|
+
|
|
214
|
+
Continue with section-split mode or standard mode below.
|
|
215
|
+
|
|
216
|
+
#### 3b. Section-Split Mode
|
|
56
217
|
|
|
57
218
|
```javascript
|
|
58
219
|
if (prd._sectionSplit?.enabled) {
|
|
@@ -94,7 +255,7 @@ if (prd._sectionSplit?.enabled) {
|
|
|
94
255
|
|
|
95
256
|
> See `references/section-splitting.md` for full detection, mapping, PRD construction, and merge logic.
|
|
96
257
|
|
|
97
|
-
####
|
|
258
|
+
#### 3c. Standard Mode (no split, no parallel)
|
|
98
259
|
|
|
99
260
|
**INVOKE `/apex -d .ralph/prd.json`**
|
|
100
261
|
|