@atlashub/smartstack-cli 3.9.0 → 3.12.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.
Files changed (48) hide show
  1. package/dist/index.js +2544 -2461
  2. package/dist/index.js.map +1 -1
  3. package/dist/mcp-entry.mjs +479 -6185
  4. package/dist/mcp-entry.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/templates/agents/ba-writer.md +178 -0
  7. package/templates/agents/db-reader.md +149 -0
  8. package/templates/skills/application/references/application-roles-template.md +227 -0
  9. package/templates/skills/application/references/provider-template.md +30 -6
  10. package/templates/skills/application/steps/step-03-roles.md +45 -7
  11. package/templates/skills/application/steps/step-03b-provider.md +13 -6
  12. package/templates/skills/business-analyse/SKILL.md +56 -4
  13. package/templates/skills/business-analyse/references/agent-pooling-best-practices.md +477 -0
  14. package/templates/skills/business-analyse/references/cache-warming-strategy.md +578 -0
  15. package/templates/skills/business-analyse/references/cadrage-vibe-coding.md +9 -19
  16. package/templates/skills/business-analyse/references/consolidation-structural-checks.md +12 -2
  17. package/templates/skills/business-analyse/references/deploy-data-build.md +36 -25
  18. package/templates/skills/business-analyse/references/detection-strategies.md +424 -0
  19. package/templates/skills/business-analyse/references/html-data-mapping.md +4 -0
  20. package/templates/skills/business-analyse/references/prd-generation.md +258 -0
  21. package/templates/skills/business-analyse/references/robustness-checks.md +538 -0
  22. package/templates/skills/business-analyse/references/validate-incremental-html.md +47 -4
  23. package/templates/skills/business-analyse/references/validation-checklist.md +281 -0
  24. package/templates/skills/business-analyse/schemas/sections/specification-schema.json +33 -1
  25. package/templates/skills/business-analyse/steps/step-00-init.md +70 -75
  26. package/templates/skills/business-analyse/steps/step-01-cadrage.md +8 -22
  27. package/templates/skills/business-analyse/steps/step-03a-data.md +20 -410
  28. package/templates/skills/business-analyse/steps/step-03a1-setup.md +356 -0
  29. package/templates/skills/business-analyse/steps/step-03a2-analysis.md +143 -0
  30. package/templates/skills/business-analyse/steps/step-03b-ui.md +3 -0
  31. package/templates/skills/business-analyse/steps/step-03c-compile.md +72 -3
  32. package/templates/skills/business-analyse/steps/step-03d-validate.md +36 -3
  33. package/templates/skills/business-analyse/steps/step-04-consolidation.md +21 -440
  34. package/templates/skills/business-analyse/steps/step-04a-collect.md +304 -0
  35. package/templates/skills/business-analyse/steps/step-04b-analyze.md +239 -0
  36. package/templates/skills/business-analyse/steps/step-04c-decide.md +186 -0
  37. package/templates/skills/business-analyse/steps/step-05a-handoff.md +44 -0
  38. package/templates/skills/business-analyse/steps/step-05b-deploy.md +42 -2
  39. package/templates/skills/business-analyse/steps/step-05c-ralph-readiness.md +518 -0
  40. package/templates/skills/controller/steps/step-03-generate.md +184 -24
  41. package/templates/skills/controller/templates.md +11 -2
  42. package/templates/skills/debug/SKILL.md +156 -53
  43. package/templates/skills/debug/references/team-protocol.md +232 -0
  44. package/templates/skills/ralph-loop/references/category-rules.md +46 -0
  45. package/templates/skills/ralph-loop/references/compact-loop.md +32 -2
  46. package/templates/skills/ralph-loop/references/core-seed-data.md +233 -21
  47. package/templates/skills/ralph-loop/steps/step-00-init.md +64 -1
  48. package/templates/skills/ralph-loop/steps/step-04-check.md +27 -2
@@ -75,40 +75,51 @@ const FEATURE_DATA = {
75
75
 
76
76
  ## EMBEDDED_ARTIFACTS Object
77
77
 
78
+ > **CRITICAL:** The wireframes object is keyed by moduleCode (NOT a flat array).
79
+ > Field names MUST be renamed from feature.json: `mockupFormat` → `format`, `mockup` → `content`.
80
+ > The HTML renderer reads `wf.format` and `wf.content` — using feature.json names will produce EMPTY mockups.
81
+
78
82
  ```javascript
79
83
  const EMBEDDED_ARTIFACTS = {
80
- wireframes: [
81
- // Extract from each module's specification.uiWireframes
82
- {
83
- moduleCode: "{moduleCode}",
84
- screen: wireframe.screen,
85
- description: wireframe.description,
86
- layout: wireframe.layout || "responsive",
87
- components: wireframe.components || []
88
- }
89
- ],
90
- e2eFlows: [
91
- // Extract from master consolidation.e2eFlows
92
- {
93
- flowName: flow.name,
94
- description: flow.description,
95
- sequence: flow.sequence || [],
96
- modules: flow.modules || []
97
- }
98
- ],
84
+ wireframes: {
85
+ // PER-MODULE keyed object (NOT a flat array)
86
+ // FOR EACH module: extract from specification.uiWireframes[]
87
+ [moduleCode]: moduleFeature.specification.uiWireframes.map(wf => ({
88
+ screen: wf.screen, // e.g. "employees-list"
89
+ section: wf.section, // e.g. "list"
90
+ format: wf.mockupFormat || "ascii", // RENAME: mockupFormat → format
91
+ content: wf.mockup, // RENAME: mockup → content (ASCII art string)
92
+ description: wf.description || "",
93
+ elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
94
+ actions: wf.actions || [], // ["filter", "sort", "create", ...]
95
+ componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
96
+ layout: wf.layout || null, // { type, regions: [...] }
97
+ permissionsRequired: wf.permissionsRequired || []
98
+ }))
99
+ },
100
+ e2eFlows: (master.consolidation?.e2eFlows || []).map(flow => ({
101
+ name: flow.name,
102
+ diagram: flow.steps.map(s => `${s.action}(${s.module})`).join(" ──→ "),
103
+ steps: flow.steps || [],
104
+ actors: [...new Set(flow.steps.map(s => s.permission?.split(".")[0]).filter(Boolean))].join(", "),
105
+ modules: [...new Set(flow.steps.map(s => s.module))].join(" → ")
106
+ })),
99
107
  dependencyGraph: {
100
- // From master consolidation.dependencyGraph
101
- nodes: master.consolidation.dependencyGraph?.nodes || [],
102
- edges: master.consolidation.dependencyGraph?.edges || []
108
+ nodes: (master.modules || []).map(m => ({
109
+ id: m.code, label: m.code, type: m.featureType || "data-centric"
110
+ })),
111
+ edges: (master.dependencyGraph?.edges || []).map(e => ({
112
+ from: e.from, to: e.to, description: e.description || ""
113
+ }))
103
114
  }
104
115
  };
105
116
  ```
106
117
 
107
118
  ### Artifact Gathering
108
119
 
109
- 1. Read each module's `specification.uiWireframes[]` and add to wireframes array
110
- 2. Read master's `consolidation.e2eFlows[]` and add to e2eFlows array
111
- 3. Read master's `consolidation.dependencyGraph` and include as-is
120
+ 1. For EACH module: read `specification.uiWireframes[]`, **rename fields** (`mockupFormat`→`format`, `mockup`→`content`), store under `wireframes[moduleCode]`
121
+ 2. Read master's `consolidation.e2eFlows[]` and build e2eFlows array with diagram generation
122
+ 3. Read master's `dependencyGraph` and build nodes/edges
112
123
  4. Serialize as JSON with 2-space indentation
113
124
 
114
125
  ## Placeholder Replacement
@@ -0,0 +1,424 @@
1
+ # Detection Strategies - New vs Update vs Review
2
+
3
+ Source: business-analyse step-00-init.md
4
+
5
+ This document describes the algorithms used in step-00-init.md to automatically detect the workflow type (new application, update, or review mode) and match user intent against existing business analyses.
6
+
7
+ ---
8
+
9
+ ## 1. Review Mode Detection
10
+
11
+ **Trigger:** `{feature_description}` starts with `-review` (with or without extra text)
12
+
13
+ ### Algorithm
14
+
15
+ ```javascript
16
+ function detectReviewMode(feature_description) {
17
+ const isReviewMode = feature_description.trim().startsWith('-review');
18
+
19
+ if (!isReviewMode) {
20
+ return { mode: null };
21
+ }
22
+
23
+ // Scan docs/business/ for most recent application
24
+ const applications = glob('docs/business/*/business-analyse/*/feature.json')
25
+ .map(path => ({
26
+ path,
27
+ metadata: readJSON(path).metadata,
28
+ updatedAt: readJSON(path).metadata.updatedAt
29
+ }))
30
+ .sort((a, b) => b.updatedAt - a.updatedAt);
31
+
32
+ if (applications.length === 0) {
33
+ return {
34
+ mode: 'review',
35
+ error: 'NO_APPLICATIONS_FOUND',
36
+ fix: 'Create an application first using /business-analyse'
37
+ };
38
+ }
39
+
40
+ const latestApp = applications[0];
41
+ const versionDir = path.dirname(latestApp.path);
42
+ const reviewFilePath = path.join(versionDir, 'ba-review.json');
43
+
44
+ if (!fs.existsSync(reviewFilePath)) {
45
+ return {
46
+ mode: 'review',
47
+ error: 'NO_REVIEW_FILE',
48
+ applicationName: latestApp.metadata.application,
49
+ expectedPath: reviewFilePath,
50
+ fix: `
51
+ To create ba-review.json:
52
+ 1. Open ba-interactive.html in your browser
53
+ 2. Make your corrections
54
+ 3. Click "Sauvegarder corrections" button
55
+ 4. Save the downloaded ba-review.json in: ${versionDir}/
56
+ 5. Run /business-analyse -review again
57
+ `
58
+ };
59
+ }
60
+
61
+ return {
62
+ mode: 'review',
63
+ reviewJsonPath: reviewFilePath,
64
+ applicationName: latestApp.metadata.application,
65
+ docsDir: versionDir,
66
+ nextStep: 'step-06-review.md'
67
+ };
68
+ }
69
+ ```
70
+
71
+ ### Decision Matrix
72
+
73
+ | Condition | Action |
74
+ |-----------|--------|
75
+ | `{feature_description}` starts with `-review` | Activate review mode detection |
76
+ | ba-review.json found | Skip to step-06-review.md |
77
+ | ba-review.json NOT found | Display error with fix instructions, STOP |
78
+ | No applications exist | Display error, STOP |
79
+
80
+ ### Error Messages
81
+
82
+ **Error 1: No Applications Found**
83
+ ```
84
+ ERROR: No existing applications found in docs/business/
85
+
86
+ You must create an application first using:
87
+ /business-analyse
88
+
89
+ Then generate ba-interactive.html, make corrections, and export ba-review.json.
90
+ ```
91
+
92
+ **Error 2: No Review File**
93
+ ```
94
+ ERROR: No ba-review.json found in docs/business/{app}/business-analyse/v{version}/
95
+
96
+ To create one:
97
+ 1. Open the ba-interactive.html in your browser
98
+ 2. Make your corrections
99
+ 3. Click "Sauvegarder corrections" button
100
+ 4. Save the downloaded ba-review.json in the version folder
101
+ 5. Run /business-analyse -review again
102
+
103
+ Expected path: {expectedPath}
104
+ ```
105
+
106
+ ---
107
+
108
+ ## 2. Existing Applications Scanner
109
+
110
+ **Objective:** Build a catalog of existing business analyses for comparison.
111
+
112
+ ### Scan Algorithm
113
+
114
+ ```javascript
115
+ function scanExistingApplications() {
116
+ const featureFiles = glob('docs/business/*/business-analyse/*/feature.json');
117
+
118
+ const existingApps = featureFiles.map(path => {
119
+ const feature = readJSON(path);
120
+ return {
121
+ app: feature.metadata.application,
122
+ featureId: feature.id,
123
+ description: feature.metadata.featureDescription,
124
+ version: extractVersion(path), // e.g., "1.0" from "v1.0"
125
+ path: path,
126
+ updatedAt: feature.metadata.updatedAt,
127
+ modules: feature.modules?.map(m => m.code) || [],
128
+ status: feature.status
129
+ };
130
+ });
131
+
132
+ // Sort by most recent first
133
+ existingApps.sort((a, b) => b.updatedAt - a.updatedAt);
134
+
135
+ return existingApps;
136
+ }
137
+ ```
138
+
139
+ ### Output Schema
140
+
141
+ ```typescript
142
+ interface ExistingApp {
143
+ app: string; // "HumanResources"
144
+ featureId: string; // "FEAT-001"
145
+ description: string; // "Gestion des projets et absences"
146
+ version: string; // "1.0", "1.1", "2.0"
147
+ path: string; // "docs/business/HumanResources/..."
148
+ updatedAt: string; // ISO timestamp
149
+ modules: string[]; // ["Projects", "TimeTracking", "Reporting"]
150
+ status: string; // "draft", "consolidated", "handed-off"
151
+ }
152
+ ```
153
+
154
+ ### Edge Cases
155
+
156
+ | Case | Handling |
157
+ |------|----------|
158
+ | No feature.json files found | Return empty array → triggers "new application" mode |
159
+ | Corrupted feature.json | Skip file, log warning, continue scan |
160
+ | Multiple versions of same app | Include all, sorted by updatedAt |
161
+ | Incomplete applications (status="draft") | Include but flag in description |
162
+
163
+ ---
164
+
165
+ ## 3. New vs Update Detection
166
+
167
+ **Objective:** Determine if user wants to create a new application or update an existing one.
168
+
169
+ ### Similarity Analysis Algorithm
170
+
171
+ ```javascript
172
+ function analyzeSimilarity(feature_description, existingApps) {
173
+ const scores = existingApps.map(app => ({
174
+ app,
175
+ score: calculateSimilarityScore(feature_description, app)
176
+ }));
177
+
178
+ // Sort by highest score first
179
+ scores.sort((a, b) => b.score - a.score);
180
+
181
+ return scores;
182
+ }
183
+
184
+ function calculateSimilarityScore(description, existingApp) {
185
+ let score = 0;
186
+
187
+ // 1. Application name match (50 points)
188
+ if (description.toLowerCase().includes(existingApp.app.toLowerCase())) {
189
+ score += 50;
190
+ }
191
+
192
+ // 2. Module name match (30 points)
193
+ for (const module of existingApp.modules) {
194
+ if (description.toLowerCase().includes(module.toLowerCase())) {
195
+ score += 30;
196
+ break;
197
+ }
198
+ }
199
+
200
+ // 3. Update keywords (40 points)
201
+ const updateKeywords = [
202
+ 'ajouter', 'modifier', 'changer', 'enrichir', 'mettre à jour',
203
+ 'add', 'modify', 'change', 'update', 'extend'
204
+ ];
205
+ for (const keyword of updateKeywords) {
206
+ if (description.toLowerCase().includes(keyword)) {
207
+ score += 40;
208
+ break;
209
+ }
210
+ }
211
+
212
+ // 4. Domain overlap (20 points)
213
+ // Check if description and existing app share domain terms
214
+ const domainTerms = extractDomainTerms(existingApp.description);
215
+ for (const term of domainTerms) {
216
+ if (description.toLowerCase().includes(term.toLowerCase())) {
217
+ score += 5; // Up to 20 points (4 terms)
218
+ }
219
+ }
220
+
221
+ return score;
222
+ }
223
+
224
+ function extractDomainTerms(text) {
225
+ // Extract nouns/domain entities (simplified)
226
+ const words = text.toLowerCase().split(/\s+/);
227
+ return words.filter(w => w.length > 4); // Filter short words
228
+ }
229
+ ```
230
+
231
+ ### Decision Tree
232
+
233
+ ```
234
+ ┌─────────────────────────────────────┐
235
+ │ existing_apps.length === 0? │
236
+ └──┬─────────────────────────┬────────┘
237
+ │ YES │ NO
238
+ │ │
239
+ v v
240
+ ┌──────────────┐ ┌──────────────────────┐
241
+ │ workflow_type │ │ Calculate similarity │
242
+ │ = "new" │ │ scores for all apps │
243
+ └──────────────┘ └──────┬───────────────┘
244
+
245
+ v
246
+ ┌─────────────────────┐
247
+ │ Top score >= 80? │
248
+ └──┬─────────────┬────┘
249
+ │ YES │ NO
250
+ │ │
251
+ v v
252
+ ┌──────────────┐ ┌──────────────┐
253
+ │ Suggest │ │ Show all │
254
+ │ update to │ │ options with │
255
+ │ matched app │ │ "New app" as │
256
+ │ as first │ │ first option │
257
+ │ option │ │ │
258
+ └───────────────┘ └──────────────┘
259
+ │ │
260
+ v v
261
+ ┌────────────────────────┐
262
+ │ Ask via │
263
+ │ AskUserQuestion │
264
+ └─────────┬──────────────┘
265
+
266
+ ┌──────────────┴──────────────┐
267
+ │ │
268
+ v v
269
+ ┌──────────────────┐ ┌──────────────────┐
270
+ │ User selects │ │ User selects │
271
+ │ "Update {app}" │ │ "New app" │
272
+ └────────┬─────────┘ └────────┬─────────┘
273
+ │ │
274
+ v v
275
+ ┌──────────────────┐ ┌──────────────────┐
276
+ │ workflow_type = │ │ workflow_type = │
277
+ │ "update" │ │ "new" │
278
+ │ existing_feature │ │ │
279
+ │ = app.featureId │ │ │
280
+ └──────────────────┘ └──────────────────┘
281
+ ```
282
+
283
+ ### AskUserQuestion Format
284
+
285
+ **When similarity score >= 80 (strong match):**
286
+ ```javascript
287
+ AskUserQuestion({
288
+ question: "J'ai trouvé une analyse existante similaire. Que souhaitez-vous faire ?",
289
+ header: "Mode",
290
+ options: [
291
+ {
292
+ label: `Mise à jour de ${matchedApp.app} (${matchedApp.featureId})`,
293
+ description: `Enrichir ou modifier l'application existante (crée v${nextVersion})`
294
+ },
295
+ {
296
+ label: "Nouvelle application",
297
+ description: "Créer une nouvelle analyse complète"
298
+ }
299
+ ]
300
+ });
301
+ ```
302
+
303
+ **When multiple apps but no strong match:**
304
+ ```javascript
305
+ AskUserQuestion({
306
+ question: "J'ai trouvé des analyses existantes. Que souhaitez-vous faire ?",
307
+ header: "Mode",
308
+ options: [
309
+ {
310
+ label: "Nouvelle application",
311
+ description: "Créer une nouvelle analyse complète"
312
+ },
313
+ ...existingApps.slice(0, 3).map(app => ({
314
+ label: `Mise à jour de ${app.app} (${app.featureId})`,
315
+ description: `Enrichir ${app.app} — modules: ${app.modules.join(', ')}`
316
+ }))
317
+ ]
318
+ });
319
+ ```
320
+
321
+ ### Update Mode Flow
322
+
323
+ When user selects an existing app for update:
324
+
325
+ ```javascript
326
+ function initiateUpdateMode(existingApp) {
327
+ // 1. Call ba-writer to create new version
328
+ const newVersion = ba_writer.createVersion(
329
+ existingApp.featureId,
330
+ feature_description
331
+ );
332
+
333
+ // 2. Copy previous version data as baseline
334
+ const previousFeature = readJSON(existingApp.path);
335
+ const newFeature = {
336
+ ...previousFeature,
337
+ id: existingApp.featureId, // Keep same feature ID
338
+ version: newVersion.version, // Increment version (e.g., "1.0" → "1.1")
339
+ status: "draft",
340
+ metadata: {
341
+ ...previousFeature.metadata,
342
+ featureDescription: feature_description, // New description
343
+ workflowType: "update",
344
+ previousVersion: extractVersion(existingApp.path),
345
+ updatedAt: new Date().toISOString()
346
+ }
347
+ };
348
+
349
+ // 3. Write new version feature.json
350
+ const newPath = `docs/business/${existingApp.app}/business-analyse/v${newVersion.version}/feature.json`;
351
+ writeJSON(newPath, newFeature);
352
+
353
+ return {
354
+ workflow_type: "update",
355
+ existing_feature_id: existingApp.featureId,
356
+ version: newVersion.version,
357
+ application_name: existingApp.app,
358
+ docs_dir: path.dirname(newPath)
359
+ };
360
+ }
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Similarity Scoring Reference
366
+
367
+ | Match Type | Score | Example |
368
+ |-----------|-------|---------|
369
+ | **Application name exact** | 50 | "HumanResources" in description → matches HumanResources app |
370
+ | **Module name exact** | 30 | "Projects" in description → matches app with Projects module |
371
+ | **Update keyword** | 40 | "ajouter", "modifier", "mettre à jour" |
372
+ | **Domain term overlap** | 5 per term (max 20) | "project", "absence", "employee" |
373
+
374
+ **Total possible:** 140 points
375
+
376
+ **Thresholds:**
377
+ - **>= 80:** Strong match → suggest update as first option
378
+ - **50-79:** Moderate match → show as option but list "New app" first
379
+ - **< 50:** Weak match → show in list but deprioritize
380
+
381
+ ---
382
+
383
+ ## State Variables After Detection
384
+
385
+ After detection completes, these variables are set:
386
+
387
+ ```typescript
388
+ interface DetectionResult {
389
+ workflow_type: "new" | "update" | "review";
390
+ existing_feature_id: string | null; // Set only if workflow_type = "update"
391
+ version: string; // "1.0" (new) or "1.1"+ (update)
392
+ application_name: string;
393
+ review_json_path?: string; // Set only if workflow_type = "review"
394
+ docs_dir: string;
395
+ }
396
+ ```
397
+
398
+ ---
399
+
400
+ ## Testing Detection Logic
401
+
402
+ **Test Case 1: New Application (No Existing Apps)**
403
+ - Input: `"Créer une application de gestion des congés"`
404
+ - Expected: `workflow_type = "new"`, no prompt shown
405
+
406
+ **Test Case 2: Strong Match for Update**
407
+ - Input: `"Ajouter module de reporting à HumanResources"`
408
+ - Existing: `HumanResources (FEAT-001)` with modules `[Projects, TimeTracking]`
409
+ - Expected: Prompt with "Update HumanResources" as first option, score ~120
410
+
411
+ **Test Case 3: Ambiguous (Multiple Matches)**
412
+ - Input: `"Gérer les projets"`
413
+ - Existing: `HumanResources (FEAT-001)` with Projects module, `ProjectManagement (FEAT-002)`
414
+ - Expected: Prompt with "New app" first, both existing apps listed
415
+
416
+ **Test Case 4: Review Mode**
417
+ - Input: `"-review"`
418
+ - Existing: `HumanResources` with ba-review.json present
419
+ - Expected: Load ba-review.json, skip to step-06-review.md
420
+
421
+ **Test Case 5: Review Mode - File Missing**
422
+ - Input: `"-review"`
423
+ - Existing: `HumanResources` but no ba-review.json
424
+ - Expected: Display error with fix instructions, STOP
@@ -196,6 +196,10 @@ Default: "contributor"
196
196
 
197
197
  ## EMBEDDED_ARTIFACTS Mapping
198
198
 
199
+ > **FIELD RENAME WARNING:** feature.json stores wireframes with `mockupFormat` and `mockup` fields.
200
+ > The HTML renderer reads `format` and `content`. You MUST rename: `mockupFormat` → `format`, `mockup` → `content`.
201
+ > Failure to rename = empty mockup display in the browser.
202
+
199
203
  Build a JSON object containing ALL visual artifacts from feature.json:
200
204
 
201
205
  ```javascript