@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
|
@@ -917,8 +917,10 @@ Status journey: analyze → consolidate → **handed-off**
|
|
|
917
917
|
|
|
918
918
|
### 9d. Deploy Interactive HTML Document (MANDATORY)
|
|
919
919
|
|
|
920
|
-
> **The interactive HTML document is deployed to the project
|
|
921
|
-
>
|
|
920
|
+
> **The interactive HTML document is deployed to the project PRE-POPULATED with ALL analysis data.**
|
|
921
|
+
> The client opens it in a browser and sees the complete analysis (cadrage, modules, entities, UCs, BRs, wireframes, permissions, consolidation).
|
|
922
|
+
> The client can then review, edit, enrich, and export modifications as JSON.
|
|
923
|
+
> That JSON can be re-imported via `/business-analyse -x` to update the feature.json.
|
|
922
924
|
|
|
923
925
|
**Source:** `html/ba-interactive.html` (relative to skill root = `~/.claude/skills/business-analyse/html/`)
|
|
924
926
|
|
|
@@ -926,27 +928,318 @@ Status journey: analyze → consolidate → **handed-off**
|
|
|
926
928
|
|
|
927
929
|
**Deployment steps:**
|
|
928
930
|
|
|
931
|
+
#### Step 1: Read source data
|
|
932
|
+
|
|
929
933
|
1. Read the HTML template from skill directory
|
|
930
|
-
2.
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
934
|
+
2. Read the master feature.json (application level)
|
|
935
|
+
3. Read EACH module feature.json (module level)
|
|
936
|
+
|
|
937
|
+
#### Step 2: Build FEATURE_DATA object
|
|
938
|
+
|
|
939
|
+
> **CRITICAL:** The HTML `data` object MUST be pre-populated with ALL analysis data.
|
|
940
|
+
> An empty data object is a **BUG** — the client would see a blank page.
|
|
941
|
+
|
|
942
|
+
Build a JSON object following this **exact mapping** from feature.json to the HTML data model:
|
|
943
|
+
|
|
944
|
+
```javascript
|
|
945
|
+
{
|
|
946
|
+
metadata: {
|
|
947
|
+
applicationName: master.metadata.application, // e.g. "RH"
|
|
948
|
+
applicationId: master.id, // e.g. "FEAT-001"
|
|
949
|
+
version: master.version, // e.g. "1.0"
|
|
950
|
+
createdAt: master.metadata.createdAt,
|
|
951
|
+
lastModified: master.metadata.updatedAt
|
|
952
|
+
},
|
|
953
|
+
cadrage: {
|
|
954
|
+
problem: {
|
|
955
|
+
description: master.cadrage.problem, // string → problem.description
|
|
956
|
+
trigger: master.cadrage.trigger, // string → problem.trigger
|
|
957
|
+
impactedPeople: "", // not in feature.json, client fills
|
|
958
|
+
history: "",
|
|
959
|
+
consequences: ""
|
|
960
|
+
},
|
|
961
|
+
current: {
|
|
962
|
+
tools: master.cadrage.asIs, // string → current.tools
|
|
963
|
+
steps: [], // client can add process steps
|
|
964
|
+
painPoints: master.cadrage.stakeholders
|
|
965
|
+
.flatMap(s => s.painPoints || []).join("\n"), // aggregate all painPoints
|
|
966
|
+
errors: ""
|
|
967
|
+
},
|
|
968
|
+
vision: {
|
|
969
|
+
changes: master.cadrage.toBe, // string → vision.changes
|
|
970
|
+
results: master.cadrage.acceptanceCriteria
|
|
971
|
+
.map(ac => ac.criterion).join("\n"), // AC → results (one per line)
|
|
972
|
+
successSign: ""
|
|
973
|
+
},
|
|
974
|
+
stakeholders: master.cadrage.stakeholders.map(s => ({
|
|
975
|
+
role: s.role,
|
|
976
|
+
function: s.function || "",
|
|
977
|
+
tasks: s.tasks || [],
|
|
978
|
+
frequency: mapFrequency(s.frequency), // "Quotidien"→"daily", etc.
|
|
979
|
+
access: mapAccess(s.involvement), // "decision-maker"→"admin", "end-user"→"contributor"
|
|
980
|
+
frustrations: (s.painPoints || []).join("\n")
|
|
981
|
+
})),
|
|
982
|
+
scope: {
|
|
983
|
+
vital: (master.cadrage.globalScope.mustHave || [])
|
|
984
|
+
.map(item => ({ name: item, description: "" })), // string[] → {name,description}[]
|
|
985
|
+
important: (master.cadrage.globalScope.shouldHave || [])
|
|
986
|
+
.map(item => ({ name: item, description: "" })),
|
|
987
|
+
optional: (master.cadrage.globalScope.couldHave || [])
|
|
988
|
+
.map(item => ({ name: item, description: "" })),
|
|
989
|
+
excluded: (master.cadrage.globalScope.outOfScope || [])
|
|
990
|
+
.map(item => ({ name: item, description: "" }))
|
|
991
|
+
},
|
|
992
|
+
risks: (master.cadrage.risks || []).map(r => ({
|
|
993
|
+
description: r.description,
|
|
994
|
+
probability: r.probability, // "high" | "medium" | "low"
|
|
995
|
+
impact: r.impact,
|
|
996
|
+
mitigation: r.mitigation || ""
|
|
997
|
+
})),
|
|
998
|
+
assumptions: "",
|
|
999
|
+
success: {
|
|
1000
|
+
definition: (master.cadrage.acceptanceCriteria || [])
|
|
1001
|
+
.map(ac => ac.criterion).join("\n"),
|
|
1002
|
+
metrics: "",
|
|
1003
|
+
timeline: "",
|
|
1004
|
+
minimumConditions: ""
|
|
1005
|
+
}
|
|
1006
|
+
},
|
|
1007
|
+
modules: master.modules.map(m => ({
|
|
1008
|
+
code: m.code,
|
|
1009
|
+
name: m.code, // module code as name
|
|
1010
|
+
description: m.description || "",
|
|
1011
|
+
featureType: m.featureType || "data-centric",
|
|
1012
|
+
priority: m.priority || "must",
|
|
1013
|
+
entities: m.entities || [],
|
|
1014
|
+
status: m.status || "handed-off"
|
|
1015
|
+
})),
|
|
1016
|
+
dependencies: (master.dependencyGraph?.edges || []).map(e => ({
|
|
1017
|
+
from: e.from,
|
|
1018
|
+
to: e.to,
|
|
1019
|
+
description: e.description || ""
|
|
1020
|
+
})),
|
|
1021
|
+
moduleSpecs: {
|
|
1022
|
+
// FOR EACH module: read module feature.json, then map:
|
|
1023
|
+
// [moduleCode]: { useCases, businessRules, entities, permissions, notes, mockupNotes }
|
|
1024
|
+
},
|
|
1025
|
+
consolidation: {
|
|
1026
|
+
interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
|
|
1027
|
+
from: i.fromModule,
|
|
1028
|
+
to: i.toModule,
|
|
1029
|
+
description: i.description || ""
|
|
1030
|
+
})),
|
|
1031
|
+
e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
|
|
1032
|
+
name: f.name,
|
|
1033
|
+
steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
|
|
1034
|
+
actors: (f.steps || []).map(s => s.permission).join(", ")
|
|
1035
|
+
}))
|
|
1036
|
+
},
|
|
1037
|
+
handoff: master.handoff || {}
|
|
1038
|
+
}
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
**Module specs mapping** — for EACH module in `master.modules[]`:
|
|
1042
|
+
|
|
1043
|
+
1. Read the module feature.json at `master.modules[i].featureJsonPath`
|
|
1044
|
+
2. Map to `moduleSpecs[moduleCode]`:
|
|
1045
|
+
|
|
1046
|
+
```javascript
|
|
1047
|
+
moduleSpecs[moduleCode] = {
|
|
1048
|
+
useCases: (moduleFeature.specification?.useCases || []).map(uc => ({
|
|
1049
|
+
name: uc.name,
|
|
1050
|
+
actor: uc.primaryActor,
|
|
1051
|
+
steps: (uc.mainScenario || []).join("\n"), // array → newline-separated string
|
|
1052
|
+
alternative: (uc.alternativeScenarios || [])
|
|
1053
|
+
.map(a => a.name + ": " + (a.steps || []).join(", ")).join("\n")
|
|
1054
|
+
})),
|
|
1055
|
+
businessRules: (moduleFeature.analysis?.businessRules || []).map(br => ({
|
|
1056
|
+
name: br.name,
|
|
1057
|
+
category: br.category, // "validation"|"calculation"|"workflow"|"security"|"data"
|
|
1058
|
+
statement: br.statement,
|
|
1059
|
+
example: (br.examples || []).map(e => e.input + " → " + e.expected).join("; ")
|
|
1060
|
+
})),
|
|
1061
|
+
entities: (moduleFeature.analysis?.entities || []).map(ent => ({
|
|
1062
|
+
name: ent.name,
|
|
1063
|
+
description: ent.description || "",
|
|
1064
|
+
attributes: (ent.attributes || []).map(a => ({
|
|
1065
|
+
name: a.name,
|
|
1066
|
+
description: a.description || ""
|
|
1067
|
+
})),
|
|
1068
|
+
relationships: (ent.relationships || []).map(r =>
|
|
1069
|
+
r.target + " (" + r.type + ") - " + (r.description || "")
|
|
1070
|
+
)
|
|
1071
|
+
})),
|
|
1072
|
+
permissions: buildPermissionKeys(moduleFeature), // see below
|
|
1073
|
+
notes: "",
|
|
1074
|
+
mockupNotes: "" // Deprecated: wireframes now embedded separately in EMBEDDED_ARTIFACTS
|
|
1075
|
+
}
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
**Permission keys** — the HTML uses `"Role|Action"` format (e.g. `"RH Admin|Consulter"`):
|
|
1079
|
+
|
|
1080
|
+
```javascript
|
|
1081
|
+
function buildPermissionKeys(moduleFeature) {
|
|
1082
|
+
const keys = [];
|
|
1083
|
+
const matrix = moduleFeature.specification?.permissionMatrix;
|
|
1084
|
+
if (!matrix) return keys;
|
|
1085
|
+
const actionMap = { read: "Consulter", create: "Creer", update: "Modifier",
|
|
1086
|
+
delete: "Supprimer", validate: "Valider", export: "Exporter",
|
|
1087
|
+
submit: "Valider", import: "Creer" };
|
|
1088
|
+
(matrix.roleAssignments || []).forEach(ra => {
|
|
1089
|
+
(ra.permissions || []).forEach(permPath => {
|
|
1090
|
+
const action = permPath.split(".").pop(); // last segment = action
|
|
1091
|
+
const uiAction = actionMap[action] || action;
|
|
1092
|
+
keys.push(ra.role + "|" + uiAction);
|
|
1093
|
+
});
|
|
1094
|
+
});
|
|
1095
|
+
return keys;
|
|
1096
|
+
}
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
**Frequency mapping:**
|
|
1100
|
+
```
|
|
1101
|
+
"Quotidien" → "daily", "Hebdomadaire" → "weekly", "Mensuel" → "monthly"
|
|
1102
|
+
Default: "daily"
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
**Access mapping (involvement → access):**
|
|
1106
|
+
```
|
|
1107
|
+
"decision-maker" → "admin", "end-user" with manager-like tasks → "manager"
|
|
1108
|
+
"end-user" → "contributor", "observer" → "viewer"
|
|
1109
|
+
Default: "contributor"
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
#### Step 2-bis: Build EMBEDDED_ARTIFACTS object (NEW)
|
|
1113
|
+
|
|
1114
|
+
> **NEW in v6.2:** Visual artifacts (wireframes, E2E diagrams) are now embedded as a separate JavaScript object in the HTML for client-side rendering and export.
|
|
1115
|
+
|
|
1116
|
+
Build a JSON object containing ALL visual artifacts from feature.json:
|
|
1117
|
+
|
|
1118
|
+
```javascript
|
|
1119
|
+
{
|
|
1120
|
+
wireframes: {
|
|
1121
|
+
// FOR EACH module: extract all wireframes from module feature.json
|
|
1122
|
+
// [moduleCode]: [ {screen, format, content, elements, componentMapping, layout, description} ]
|
|
1123
|
+
},
|
|
1124
|
+
e2eFlows: [
|
|
1125
|
+
// Extract from master consolidation.e2eFlows[]
|
|
1126
|
+
// { name, diagram, steps, actors }
|
|
1127
|
+
],
|
|
1128
|
+
dependencyGraph: {
|
|
1129
|
+
// Extract from master dependencyGraph
|
|
1130
|
+
// nodes: [ {id, label, type} ], edges: [ {from, to, description} ]
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
```
|
|
1134
|
+
|
|
1135
|
+
**Wireframes mapping** — for EACH module in `master.modules[]`:
|
|
1136
|
+
|
|
1137
|
+
```javascript
|
|
1138
|
+
// Read the module feature.json
|
|
1139
|
+
const moduleFeature = readModuleFeature(moduleCode);
|
|
1140
|
+
const wireframes = (moduleFeature.specification?.uiWireframes || []).map(wf => ({
|
|
1141
|
+
screen: wf.screen, // e.g. "UM-list", "UM-form"
|
|
1142
|
+
section: wf.section, // e.g. "list", "form"
|
|
1143
|
+
format: wf.mockupFormat || "ascii", // "ascii" | "svg"
|
|
1144
|
+
content: wf.mockup, // ASCII art or SVG markup
|
|
1145
|
+
description: wf.description || "",
|
|
1146
|
+
elements: wf.elements || [], // ["DataGrid", "FilterBar", ...]
|
|
1147
|
+
actions: wf.actions || [], // ["filter", "sort", "create", ...]
|
|
1148
|
+
componentMapping: wf.componentMapping || [], // [{ wireframeElement, reactComponent }]
|
|
1149
|
+
layout: wf.layout || null, // { type, regions: [...] }
|
|
1150
|
+
permissionsRequired: wf.permissionsRequired || []
|
|
1151
|
+
}));
|
|
1152
|
+
|
|
1153
|
+
// Store in artifacts object
|
|
1154
|
+
EMBEDDED_ARTIFACTS.wireframes[moduleCode] = wireframes;
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
**E2E flows mapping** — from master consolidation:
|
|
1158
|
+
|
|
1159
|
+
```javascript
|
|
1160
|
+
EMBEDDED_ARTIFACTS.e2eFlows = (master.consolidation?.e2eFlows || []).map(flow => ({
|
|
1161
|
+
name: flow.name,
|
|
1162
|
+
diagram: generateE2EDiagram(flow), // ASCII diagram from flow.steps[]
|
|
1163
|
+
steps: flow.steps || [], // [{ module, action, permission }]
|
|
1164
|
+
actors: Array.from(new Set((flow.steps || [])
|
|
1165
|
+
.map(s => s.permission?.split(".")[0]) // Extract role from permission path
|
|
1166
|
+
.filter(Boolean))).join(", "),
|
|
1167
|
+
modules: Array.from(new Set((flow.steps || [])
|
|
1168
|
+
.map(s => s.module))).join(" → ")
|
|
1169
|
+
}));
|
|
1170
|
+
|
|
1171
|
+
function generateE2EDiagram(flow) {
|
|
1172
|
+
// Generate ASCII diagram from flow.steps[]
|
|
1173
|
+
// Example output:
|
|
1174
|
+
// "Customer ──[read]──→ Order ──[create]──→ Invoice ──[send]──→"
|
|
1175
|
+
// " (Orders) (Orders) (Invoices)"
|
|
1176
|
+
// " Contributor Manager System"
|
|
1177
|
+
|
|
1178
|
+
const stepDiagrams = (flow.steps || []).map(s =>
|
|
1179
|
+
`${s.action}(${s.module})`
|
|
1180
|
+
).join(" ──→ ");
|
|
1181
|
+
|
|
1182
|
+
return stepDiagrams;
|
|
1183
|
+
}
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
**Dependency graph mapping** — from master dependencyGraph:
|
|
1187
|
+
|
|
1188
|
+
```javascript
|
|
1189
|
+
EMBEDDED_ARTIFACTS.dependencyGraph = {
|
|
1190
|
+
nodes: (master.modules || []).map(m => ({
|
|
1191
|
+
id: m.code,
|
|
1192
|
+
label: m.code,
|
|
1193
|
+
type: m.featureType || "data-centric"
|
|
1194
|
+
})),
|
|
1195
|
+
edges: (master.dependencyGraph?.edges || []).map(e => ({
|
|
1196
|
+
from: e.from,
|
|
1197
|
+
to: e.to,
|
|
1198
|
+
description: e.description || ""
|
|
1199
|
+
}))
|
|
1200
|
+
};
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
#### Step 3: Replace placeholders in template
|
|
1204
|
+
|
|
1205
|
+
1. Serialize the FEATURE_DATA object as JSON (with 2-space indentation for readability)
|
|
1206
|
+
2. Serialize the EMBEDDED_ARTIFACTS object as JSON (with 2-space indentation)
|
|
1207
|
+
3. Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
|
|
1208
|
+
4. Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
|
|
1209
|
+
5. Replace `{{APPLICATION_NAME}}` → `{application_name}` (still used in `<title>` and header)
|
|
1210
|
+
6. Replace `{{APPLICATION_ID}}` → `{feature_id}` (still used in `APP_KEY`)
|
|
1211
|
+
7. Replace `{{VERSION}}` → `{version}`
|
|
1212
|
+
8. Replace `{{CREATED_AT}}` → `{ISO timestamp}`
|
|
1213
|
+
|
|
1214
|
+
> **NOTE:** `{{APPLICATION_NAME}}`, `{{APPLICATION_ID}}`, `{{VERSION}}`, `{{CREATED_AT}}` still appear
|
|
1215
|
+
> in the HTML body (`<title>`, header, `APP_KEY`). They MUST be replaced separately from FEATURE_DATA.
|
|
1216
|
+
|
|
1217
|
+
> **NEW:** `{{EMBEDDED_ARTIFACTS}}` is a separate JavaScript variable in the HTML that stores all visual artifacts (wireframes, E2E diagrams, dependency graph) for client-side rendering and export.
|
|
1218
|
+
|
|
1219
|
+
#### Step 4: Write and confirm
|
|
1220
|
+
|
|
1221
|
+
1. Write the populated HTML to the output directory
|
|
1222
|
+
2. Display deployment confirmation:
|
|
937
1223
|
|
|
938
1224
|
```
|
|
939
1225
|
✓ Interactive HTML deployed:
|
|
940
1226
|
Path: docs/business/{app}/business-analyse/v{version}/ba-interactive.html
|
|
1227
|
+
Pre-populated with: {stakeholder_count} stakeholders, {module_count} modules,
|
|
1228
|
+
{total_uc} use cases, {total_br} business rules, {total_entity} entities
|
|
1229
|
+
Visual artifacts: {total_wireframes} wireframes, {e2e_flow_count} E2E diagrams
|
|
941
1230
|
Open in browser to review and edit the business analysis.
|
|
942
1231
|
Export JSON and re-import with: /business-analyse -x <exported-json-path>
|
|
943
1232
|
```
|
|
944
1233
|
|
|
945
|
-
**Why
|
|
946
|
-
-
|
|
947
|
-
-
|
|
1234
|
+
**Why a FINAL deployment at handoff?**
|
|
1235
|
+
- Step 03 already deploys the HTML incrementally after each module (partial data)
|
|
1236
|
+
- This final deployment adds the COMPLETE data: all modules + consolidation + handoff info
|
|
1237
|
+
- The client sees the FULL analysis pre-populated — including cross-module interactions and E2E flows
|
|
1238
|
+
- The client can review, edit, and enrich directly in the browser
|
|
948
1239
|
- Any client modifications can be re-imported via `-x` extraction mode
|
|
949
1240
|
- The HTML is standalone (no server required) with localStorage persistence
|
|
1241
|
+
- On first open: pre-populated data displays. After client edits: localStorage overrides
|
|
1242
|
+
- **NOTE:** This overwrites the incremental HTML from step-03 with the complete version
|
|
950
1243
|
|
|
951
1244
|
---
|
|
952
1245
|
|
|
@@ -1043,7 +1336,7 @@ options:
|
|
|
1043
1336
|
- label: "Feature Full (Recommandé)"
|
|
1044
1337
|
description: "Génération parallèle rapide (code + tests). Couverture 70-80%. ~{hours/3} heures."
|
|
1045
1338
|
- label: "Ralph Loop"
|
|
1046
|
-
description: "Développement task-
|
|
1339
|
+
description: "Développement itératif task-par-task avec cycle : Analyse → Dev (backend + tests unitaires + tests non-régression + frontend + tests + documentation) → Validation → Correction → Test ... jusqu'à 100% tests pass. Couverture 95-100%. ~{hours} heures."
|
|
1047
1340
|
- label: "Terminer le BA"
|
|
1048
1341
|
description: "Finir l'analyse, développement manuel par l'équipe."
|
|
1049
1342
|
```
|
|
@@ -1055,6 +1348,179 @@ options:
|
|
|
1055
1348
|
|
|
1056
1349
|
---
|
|
1057
1350
|
|
|
1351
|
+
### 10-bis. Execute User Choice (Automatic Skill Launch)
|
|
1352
|
+
|
|
1353
|
+
> **NEW in v6.1:** Automatically launch the chosen development approach for seamless transition.
|
|
1354
|
+
|
|
1355
|
+
**After receiving AskUserQuestion response:**
|
|
1356
|
+
|
|
1357
|
+
```javascript
|
|
1358
|
+
const choice = userAnswer; // "Feature Full (Recommandé)" | "Ralph Loop" | "Terminer le BA"
|
|
1359
|
+
|
|
1360
|
+
// Extract choice label (remove "(Recommandé)" suffix)
|
|
1361
|
+
const choiceLabel = choice.replace(/\s*\(.*?\)\s*$/g, '').trim();
|
|
1362
|
+
|
|
1363
|
+
if (choiceLabel === "Ralph Loop") {
|
|
1364
|
+
// Launch ralph-loop skill automatically
|
|
1365
|
+
display("");
|
|
1366
|
+
display("🚀 Lancement de Ralph Loop - Développement itératif automatique");
|
|
1367
|
+
display("");
|
|
1368
|
+
display("╔══════════════════════════════════════════════════════════════╗");
|
|
1369
|
+
display("║ CYCLE RALPH LOOP - Comment ça fonctionne ? ║");
|
|
1370
|
+
display("╠══════════════════════════════════════════════════════════════╣");
|
|
1371
|
+
display("║ ║");
|
|
1372
|
+
display("║ Ralph Loop exécute un cycle itératif jusqu'à 100% tests: ║");
|
|
1373
|
+
display("║ ║");
|
|
1374
|
+
display("║ 1️⃣ ANALYSE → Charger task suivante du prd.json ║");
|
|
1375
|
+
display("║ 2️⃣ DÉVELOPPEMENT → Générer le code demandé ║");
|
|
1376
|
+
display("║ • Backend (Entities, Services, Controllers, Repos) ║");
|
|
1377
|
+
display("║ • Tests unitaires (xUnit) + non-régression ║");
|
|
1378
|
+
display("║ • Frontend (Pages, Components, Hooks) ║");
|
|
1379
|
+
display("║ • Tests frontend (React Testing Library) ║");
|
|
1380
|
+
display("║ • SeedData (Core RBAC + business data) ║");
|
|
1381
|
+
display("║ • Documentation utilisateur (inline + tooltips) ║");
|
|
1382
|
+
display("║ 3️⃣ VALIDATION → Commit + MCP conventions check ║");
|
|
1383
|
+
display("║ 4️⃣ TEST → Exécuter dotnet test + npm test ║");
|
|
1384
|
+
display("║ 5️⃣ CORRECTION → Si échec, analyser et corriger ║");
|
|
1385
|
+
display("║ 6️⃣ BOUCLE → Répéter 4-5 jusqu'à 100% tests pass ║");
|
|
1386
|
+
display("║ 7️⃣ NEXT TASK → Passer à la task suivante (retour à 1) ║");
|
|
1387
|
+
display("║ ║");
|
|
1388
|
+
display("║ 🎯 Objectif: ZÉRO ERREUR avant de passer à la task suivante║");
|
|
1389
|
+
display("║ 📊 Couverture: 95-100% (tests générés automatiquement) ║");
|
|
1390
|
+
display("║ ║");
|
|
1391
|
+
display("╚══════════════════════════════════════════════════════════════╝");
|
|
1392
|
+
display("");
|
|
1393
|
+
display(" Configuration du projet:");
|
|
1394
|
+
display(" ┌────────────────────────────────────────────────────────────┐");
|
|
1395
|
+
display(" │ Modules: " + modules.map(m => m.code).join(", "));
|
|
1396
|
+
display(" │ Stratégie: " + implementationStrategy);
|
|
1397
|
+
display(" │ PRD: " + (modules.length > 1 ? ".ralph/prd-{module}.json (per module)" : ".ralph/prd.json"));
|
|
1398
|
+
display(" │ Progress: .ralph/progress.txt");
|
|
1399
|
+
display(" │ Ordre: " + (modules.length > 1 ? "topologique (dépendances d'abord)" : "module unique"));
|
|
1400
|
+
display(" └────────────────────────────────────────────────────────────┘");
|
|
1401
|
+
display("");
|
|
1402
|
+
display(" Modules à traiter (dans l'ordre):");
|
|
1403
|
+
for (let i = 0; i < modules.length; i++) {
|
|
1404
|
+
display(" " + (i+1) + ". " + modules[i].code + " (" + modules[i].complexity + ") - " + modules[i].tasksCount + " tasks");
|
|
1405
|
+
}
|
|
1406
|
+
display("");
|
|
1407
|
+
display(" 📂 Fichiers générés par le BA (inputs pour Ralph):");
|
|
1408
|
+
display(" ├─ feature.json (master + modules) → Spécification source");
|
|
1409
|
+
display(" ├─ prd.json (ou prd-{module}.json) → Task breakdown avec UC/FR/BR");
|
|
1410
|
+
display(" ├─ progress.txt → Tracker hiérarchique (module → layer → tasks)");
|
|
1411
|
+
display(" └─ ba-interactive.html → Revue client (mockups, wireframes)");
|
|
1412
|
+
display("");
|
|
1413
|
+
display(" 🔄 Ralph Loop va maintenant:");
|
|
1414
|
+
display(" 1. Détecter les prd-*.json par module (si multi-module)");
|
|
1415
|
+
display(" 2. Créer modules-queue.json avec l'ordre de traitement");
|
|
1416
|
+
display(" 3. Traiter module par module dans l'ordre topologique");
|
|
1417
|
+
display(" 4. Pour chaque module: parcourir les tasks (domain → seeddata → application → infrastructure → api → frontend → i18n → tests)");
|
|
1418
|
+
display(" 5. Pour chaque task: générer code → commit → tests → correction si échec → re-test → next task");
|
|
1419
|
+
display(" 6. Passer au module suivant quand 100% tasks du module actuel = completed");
|
|
1420
|
+
display(" 7. Générer rapport final avec métriques de couverture");
|
|
1421
|
+
display("");
|
|
1422
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1423
|
+
display("");
|
|
1424
|
+
display("➡️ Transition vers Ralph Loop...");
|
|
1425
|
+
display("");
|
|
1426
|
+
|
|
1427
|
+
// Call the ralph-loop skill (no arguments needed - prd.json exists)
|
|
1428
|
+
Skill({ skill: "ralph-loop" });
|
|
1429
|
+
|
|
1430
|
+
// EXIT - ralph-loop takes over
|
|
1431
|
+
// The skill does NOT return here - ralph-loop continues in a new context
|
|
1432
|
+
|
|
1433
|
+
} else if (choiceLabel === "Feature Full") {
|
|
1434
|
+
// Launch feature-full skill automatically
|
|
1435
|
+
display("");
|
|
1436
|
+
display("🚀 Lancement de Feature Full...");
|
|
1437
|
+
display("");
|
|
1438
|
+
display(" Configuration:");
|
|
1439
|
+
display(" - Mode: Parallel generation");
|
|
1440
|
+
display(" - Couverture: 70-80%");
|
|
1441
|
+
display(" - Durée estimée: ~" + Math.round(totalHours / 3) + " heures");
|
|
1442
|
+
display("");
|
|
1443
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1444
|
+
display("");
|
|
1445
|
+
|
|
1446
|
+
Skill({ skill: "feature-full" });
|
|
1447
|
+
|
|
1448
|
+
// EXIT
|
|
1449
|
+
|
|
1450
|
+
} else {
|
|
1451
|
+
// "Terminer le BA" - no skill launch, end gracefully
|
|
1452
|
+
display("");
|
|
1453
|
+
display("✅ Business Analysis terminée.");
|
|
1454
|
+
display("");
|
|
1455
|
+
display(" Les équipes peuvent commencer le développement manuel.");
|
|
1456
|
+
display(" Tous les artefacts sont prêts pour l'implémentation.");
|
|
1457
|
+
display("");
|
|
1458
|
+
display("📂 Fichiers générés:");
|
|
1459
|
+
display(" - feature.json (master + modules) - Spécification complète");
|
|
1460
|
+
display(" - .ralph/prd.json (ou prd-{module}.json) - Task breakdown");
|
|
1461
|
+
display(" - .ralph/progress.txt - Tracker de progression");
|
|
1462
|
+
display(" - ba-interactive.html - Document de revue client");
|
|
1463
|
+
display("");
|
|
1464
|
+
display("📊 Métriques:");
|
|
1465
|
+
display(" - Modules: " + modules.length);
|
|
1466
|
+
display(" - Entités: " + totalEntities);
|
|
1467
|
+
display(" - Use cases: " + totalUseCases);
|
|
1468
|
+
display(" - Business rules: " + totalBusinessRules);
|
|
1469
|
+
display(" - Fichiers à créer: " + totalFiles);
|
|
1470
|
+
display("");
|
|
1471
|
+
display("🎯 Prochaines étapes recommandées:");
|
|
1472
|
+
display(" 1. Ouvrir ba-interactive.html dans le navigateur");
|
|
1473
|
+
display(" 2. Partager avec les stakeholders pour validation finale");
|
|
1474
|
+
display(" 3. Utiliser progress.txt comme guide de développement");
|
|
1475
|
+
display(" 4. Implémenter module par module selon l'ordre topologique");
|
|
1476
|
+
display("");
|
|
1477
|
+
display("💡 Pour lancer le développement assisté plus tard:");
|
|
1478
|
+
display(" - Ralph Loop: /ralph-loop (détecte automatiquement .ralph/prd.json)");
|
|
1479
|
+
display(" - Feature Full: /feature-full");
|
|
1480
|
+
display("");
|
|
1481
|
+
display("═══════════════════════════════════════════════════════════════");
|
|
1482
|
+
|
|
1483
|
+
// EXIT gracefully - BA workflow complete
|
|
1484
|
+
}
|
|
1485
|
+
```
|
|
1486
|
+
|
|
1487
|
+
**Key behaviors:**
|
|
1488
|
+
|
|
1489
|
+
1. **Ralph Loop launch:**
|
|
1490
|
+
- No arguments needed (prd.json already exists)
|
|
1491
|
+
- Ralph automatically detects single vs multi-module
|
|
1492
|
+
- Ralph reads modules-queue.json if multi-module
|
|
1493
|
+
- Seamless transition - user sees continuous flow
|
|
1494
|
+
|
|
1495
|
+
2. **Feature Full launch:**
|
|
1496
|
+
- Passes application context
|
|
1497
|
+
- Parallel generation starts immediately
|
|
1498
|
+
|
|
1499
|
+
3. **Manual development:**
|
|
1500
|
+
- Clear summary of generated artifacts
|
|
1501
|
+
- Actionable next steps
|
|
1502
|
+
- Instructions for later skill launch
|
|
1503
|
+
|
|
1504
|
+
**Error handling:**
|
|
1505
|
+
|
|
1506
|
+
```javascript
|
|
1507
|
+
try {
|
|
1508
|
+
Skill({ skill: "ralph-loop" });
|
|
1509
|
+
} catch (error) {
|
|
1510
|
+
display("⚠️ Échec du lancement automatique de Ralph Loop");
|
|
1511
|
+
display("");
|
|
1512
|
+
display(" Veuillez lancer manuellement:");
|
|
1513
|
+
display(" /ralph-loop");
|
|
1514
|
+
display("");
|
|
1515
|
+
display(" Si le problème persiste:");
|
|
1516
|
+
display(" 1. Vérifier que la skill ralph-loop est installée");
|
|
1517
|
+
display(" 2. Vérifier les permissions Claude Code");
|
|
1518
|
+
display(" 3. Consulter les logs: .ralph/logs/");
|
|
1519
|
+
}
|
|
1520
|
+
```
|
|
1521
|
+
|
|
1522
|
+
---
|
|
1523
|
+
|
|
1058
1524
|
## MODE SUPPORT
|
|
1059
1525
|
|
|
1060
1526
|
### Standard Mode
|
|
@@ -1192,7 +1658,7 @@ Before presenting handoff to user:
|
|
|
1192
1658
|
- [ ] feature.json updated: handoff section + status "handed-off"
|
|
1193
1659
|
- [ ] All paths use project namespace from .smartstack/config.json
|
|
1194
1660
|
- [ ] No invented requirements (everything traced to feature.json)
|
|
1195
|
-
- [ ] ba-interactive.html deployed with
|
|
1661
|
+
- [ ] ba-interactive.html deployed PRE-POPULATED with all analysis data (not empty)
|
|
1196
1662
|
- [ ] BA manifest (docs/business/index.json) updated with current analysis entries
|
|
1197
1663
|
- [ ] User ready for next agent selection
|
|
1198
1664
|
|