@atlashub/smartstack-cli 1.14.3 → 1.17.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 +74897 -1477
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
- package/templates/agents/efcore/migration.md +37 -25
- package/templates/agents/efcore/rebase-snapshot.md +32 -12
- package/templates/agents/efcore/squash.md +14 -4
- package/templates/agents/mcp-healthcheck.md +161 -0
- package/templates/commands/efcore/_shared.md +117 -0
- package/templates/commands/efcore/db-deploy.md +32 -4
- package/templates/commands/efcore/db-reset.md +38 -2
- package/templates/commands/efcore/db-status.md +24 -6
- package/templates/commands/efcore/migration.md +57 -9
- package/templates/commands/efcore/rebase-snapshot.md +56 -3
- package/templates/commands/efcore/squash.md +72 -17
- package/templates/hooks/mcp-check.md +64 -0
- package/templates/skills/application/SKILL.md +50 -4
- package/templates/skills/application/steps/step-00-init.md +153 -0
- package/templates/skills/application/steps/step-01-navigation.md +144 -0
- package/templates/skills/application/steps/step-02-permissions.md +159 -0
- package/templates/skills/application/steps/step-03-roles.md +158 -0
- package/templates/skills/application/steps/step-04-backend.md +202 -0
- package/templates/skills/application/steps/step-05-frontend.md +218 -0
- package/templates/skills/application/steps/step-06-migration.md +190 -0
- package/templates/skills/gitflow/steps/step-commit.md +25 -20
- package/templates/skills/gitflow/steps/step-start.md +9 -0
- package/templates/skills/mcp/SKILL.md +246 -0
- package/templates/skills/review-code/SKILL.md +77 -0
- package/templates/skills/review-code/references/smartstack-conventions.md +302 -0
|
@@ -12,13 +12,18 @@ model: haiku
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
## STEP 1: Détecter Configuration
|
|
15
|
+
## STEP 1: Détecter Configuration et DbContext
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
detect_efcore_project
|
|
18
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
19
19
|
detect_environment
|
|
20
|
+
|
|
21
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
22
|
+
echo "Schema: $SCHEMA"
|
|
20
23
|
```
|
|
21
24
|
|
|
25
|
+
**Si DbContext non détecté :** Afficher le status des DEUX contextes.
|
|
26
|
+
|
|
22
27
|
---
|
|
23
28
|
|
|
24
29
|
## STEP 2: Invoquer MCP
|
|
@@ -26,7 +31,10 @@ detect_environment
|
|
|
26
31
|
```json
|
|
27
32
|
{
|
|
28
33
|
"tool": "mcp__smartstack__check_migrations",
|
|
29
|
-
"parameters": {
|
|
34
|
+
"parameters": {
|
|
35
|
+
"branch": "<current_branch>",
|
|
36
|
+
"projectPath": "<auto-detect>"
|
|
37
|
+
}
|
|
30
38
|
}
|
|
31
39
|
```
|
|
32
40
|
|
|
@@ -37,7 +45,10 @@ Extraire: `migrations[]`, `conflicts[]`
|
|
|
37
45
|
## STEP 3: Tester Connexion
|
|
38
46
|
|
|
39
47
|
```bash
|
|
40
|
-
CONNECTION_OK=$(dotnet ef database list
|
|
48
|
+
CONNECTION_OK=$(dotnet ef database list \
|
|
49
|
+
--context "$DBCONTEXT" \
|
|
50
|
+
--project "$INFRA_PROJECT" \
|
|
51
|
+
--startup-project "$STARTUP_PROJECT" 2>&1)
|
|
41
52
|
```
|
|
42
53
|
|
|
43
54
|
---
|
|
@@ -45,8 +56,15 @@ CONNECTION_OK=$(dotnet ef database list 2>&1)
|
|
|
45
56
|
## STEP 4: Compter Migrations
|
|
46
57
|
|
|
47
58
|
```bash
|
|
48
|
-
APPLIED=$(dotnet ef migrations list
|
|
49
|
-
|
|
59
|
+
APPLIED=$(dotnet ef migrations list \
|
|
60
|
+
--context "$DBCONTEXT" \
|
|
61
|
+
--project "$INFRA_PROJECT" \
|
|
62
|
+
--startup-project "$STARTUP_PROJECT" | grep -v "(Pending)" | wc -l)
|
|
63
|
+
|
|
64
|
+
PENDING=$(dotnet ef migrations list \
|
|
65
|
+
--context "$DBCONTEXT" \
|
|
66
|
+
--project "$INFRA_PROJECT" \
|
|
67
|
+
--startup-project "$STARTUP_PROJECT" | grep "(Pending)" | wc -l)
|
|
50
68
|
```
|
|
51
69
|
|
|
52
70
|
---
|
|
@@ -29,12 +29,31 @@ Options: `--force`, `--no-cross-check`, `--rebase-first`
|
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
-
## STEP 1: Contexte Git
|
|
32
|
+
## STEP 1: Contexte Git et DbContext
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
CURRENT_BRANCH=$(git branch --show-current)
|
|
36
36
|
# Extraire type (feature/hotfix/release) et nom
|
|
37
|
-
detect_efcore_project
|
|
37
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
38
|
+
|
|
39
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
40
|
+
echo "Schema: $SCHEMA"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Si DbContext non détecté automatiquement :**
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
AskUserQuestion({
|
|
47
|
+
questions: [{
|
|
48
|
+
question: "Quel DbContext utiliser pour cette migration ?",
|
|
49
|
+
header: "DbContext",
|
|
50
|
+
options: [
|
|
51
|
+
{ label: "CoreDbContext", description: "Entités SmartStack (User, Role, Navigation...)" },
|
|
52
|
+
{ label: "ExtensionsDbContext", description: "Entités client spécifiques" }
|
|
53
|
+
],
|
|
54
|
+
multiSelect: false
|
|
55
|
+
}]
|
|
56
|
+
})
|
|
38
57
|
```
|
|
39
58
|
|
|
40
59
|
---
|
|
@@ -68,32 +87,61 @@ AskUserQuestion({
|
|
|
68
87
|
|
|
69
88
|
---
|
|
70
89
|
|
|
71
|
-
## STEP 4: Nom Migration
|
|
90
|
+
## STEP 4: Nom Migration (via MCP)
|
|
91
|
+
|
|
92
|
+
**OBLIGATOIRE : Utiliser le MCP pour le nommage conforme**
|
|
72
93
|
|
|
73
94
|
Pattern: `{context}_v{version}_{sequence}_{Description}`
|
|
74
95
|
|
|
96
|
+
**4.1 Demander la description à l'utilisateur :**
|
|
97
|
+
|
|
75
98
|
```javascript
|
|
76
99
|
AskUserQuestion({
|
|
77
100
|
questions: [{
|
|
78
|
-
question: "Description courte (ex:
|
|
101
|
+
question: "Description courte de la migration (ex: Add User Roles)",
|
|
79
102
|
header: "Description",
|
|
80
103
|
options: [
|
|
81
|
-
{ label: "Add", description: "Ajout tables/colonnes" },
|
|
82
|
-
{ label: "Update", description: "Modification structure" },
|
|
83
|
-
{ label: "Fix", description: "Correction schéma" },
|
|
84
|
-
{ label: "Remove", description: "Suppression éléments" }
|
|
104
|
+
{ label: "Add...", description: "Ajout tables/colonnes" },
|
|
105
|
+
{ label: "Update...", description: "Modification structure" },
|
|
106
|
+
{ label: "Fix...", description: "Correction schéma" },
|
|
107
|
+
{ label: "Remove...", description: "Suppression éléments" }
|
|
85
108
|
],
|
|
86
109
|
multiSelect: false
|
|
87
110
|
}]
|
|
88
111
|
})
|
|
112
|
+
// L'utilisateur peut aussi saisir un texte libre
|
|
89
113
|
```
|
|
90
114
|
|
|
115
|
+
**4.2 Appeler le MCP pour obtenir le nom conforme :**
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
// $DESCRIPTION = réponse de l'utilisateur (ex: "Add User Roles")
|
|
119
|
+
// $DBCONTEXT_TYPE = "core" ou "extensions" (de detect_dbcontext)
|
|
120
|
+
|
|
121
|
+
mcp__smartstack__suggest_migration({
|
|
122
|
+
description: DESCRIPTION,
|
|
123
|
+
context: DBCONTEXT_TYPE
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
// Résultat: core_v1.8.0_001_AddUserRoles
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
> **INTERDIT :** Calculer le nom manuellement. Toujours déléguer au MCP.
|
|
130
|
+
|
|
91
131
|
---
|
|
92
132
|
|
|
93
133
|
## STEP 5: Création
|
|
94
134
|
|
|
95
135
|
```bash
|
|
96
|
-
|
|
136
|
+
# $MIGRATION_NAME = résultat du MCP
|
|
137
|
+
# $DBCONTEXT = CoreDbContext ou ExtensionsDbContext (de detect_dbcontext)
|
|
138
|
+
|
|
139
|
+
dotnet ef migrations add "$MIGRATION_NAME" \
|
|
140
|
+
--context "$DBCONTEXT" \
|
|
141
|
+
--project "$INFRA_PROJECT" \
|
|
142
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
143
|
+
-o Persistence/Migrations \
|
|
144
|
+
--verbose
|
|
97
145
|
```
|
|
98
146
|
|
|
99
147
|
---
|
|
@@ -18,7 +18,29 @@ model: sonnet
|
|
|
18
18
|
CURRENT_BRANCH=$(git branch --show-current)
|
|
19
19
|
[[ ! $CURRENT_BRANCH =~ ^(feature|release|hotfix)/ ]] && exit 1
|
|
20
20
|
[ -n "$(git status --porcelain)" ] && { echo "Working directory non clean"; exit 1; }
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
# Détecte projet ET DbContext (core vs extensions)
|
|
23
|
+
detect_efcore_project # Appelle detect_dbcontext() automatiquement
|
|
24
|
+
determine_base_branch # Détermine la branche parente
|
|
25
|
+
|
|
26
|
+
echo "DbContext: $DBCONTEXT ($DBCONTEXT_TYPE)"
|
|
27
|
+
echo "Branche parente: $BASE_BRANCH"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Si DbContext non détecté automatiquement :**
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
AskUserQuestion({
|
|
34
|
+
questions: [{
|
|
35
|
+
question: "Quel DbContext utiliser ?",
|
|
36
|
+
header: "DbContext",
|
|
37
|
+
options: [
|
|
38
|
+
{ label: "CoreDbContext", description: "Entités SmartStack" },
|
|
39
|
+
{ label: "ExtensionsDbContext", description: "Entités client" }
|
|
40
|
+
],
|
|
41
|
+
multiSelect: false
|
|
42
|
+
}]
|
|
43
|
+
})
|
|
22
44
|
```
|
|
23
45
|
|
|
24
46
|
---
|
|
@@ -69,11 +91,42 @@ done
|
|
|
69
91
|
|
|
70
92
|
## STEP 6: Régénérer Migration Consolidée
|
|
71
93
|
|
|
94
|
+
**OBLIGATOIRE : Utiliser le MCP pour le nommage conforme**
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Construire la description
|
|
98
|
+
BRANCH_NAME_CLEAN=$(echo "$CURRENT_BRANCH" | sed 's|.*/||' | sed 's/-/ /g')
|
|
99
|
+
DESCRIPTION="${BRANCH_NAME_CLEAN} Consolidated"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Appel MCP OBLIGATOIRE :**
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
// Obtenir le nom conforme via MCP
|
|
106
|
+
mcp__smartstack__suggest_migration({
|
|
107
|
+
description: DESCRIPTION, // Ex: "user auth Consolidated"
|
|
108
|
+
context: DBCONTEXT_TYPE // "core" ou "extensions" (de detect_dbcontext)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
// Résultat: core_v1.7.0_001_UserAuthConsolidated
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Puis créer la migration :**
|
|
115
|
+
|
|
72
116
|
```bash
|
|
73
|
-
MIGRATION_NAME=
|
|
74
|
-
|
|
117
|
+
# $MIGRATION_NAME = résultat du MCP
|
|
118
|
+
# $DBCONTEXT = CoreDbContext ou ExtensionsDbContext
|
|
119
|
+
|
|
120
|
+
dotnet ef migrations add "$MIGRATION_NAME" \
|
|
121
|
+
--context "$DBCONTEXT" \
|
|
122
|
+
--project "$INFRA_PROJECT" \
|
|
123
|
+
--startup-project "$STARTUP_PROJECT" \
|
|
124
|
+
-o Persistence/Migrations \
|
|
125
|
+
--verbose
|
|
75
126
|
```
|
|
76
127
|
|
|
128
|
+
> **Convention :** `{context}_v{version}_{sequence}_{Description}` - Jamais de nom hardcodé
|
|
129
|
+
|
|
77
130
|
---
|
|
78
131
|
|
|
79
132
|
## STEP 7: Validation
|
|
@@ -103,24 +103,50 @@ echo "Backup: $BACKUP_DIR"
|
|
|
103
103
|
|
|
104
104
|
---
|
|
105
105
|
|
|
106
|
-
## STEP 4: Récupérer
|
|
106
|
+
## STEP 4: Récupérer Migrations ET Snapshot de la Branche Parente (CRUCIAL)
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
109
|
# Sauvegarder snapshot actuel
|
|
110
110
|
cp "$MIGRATIONS_DIR"/*ModelSnapshot.cs "$BACKUP_DIR/"
|
|
111
111
|
|
|
112
|
-
# Récupérer
|
|
112
|
+
# Récupérer TOUTES les migrations de la branche parente
|
|
113
113
|
git fetch origin "$BASE_BRANCH" --quiet
|
|
114
|
+
|
|
115
|
+
# 1. Récupérer le ModelSnapshot
|
|
114
116
|
git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR"/*ModelSnapshot.cs
|
|
115
117
|
|
|
116
|
-
|
|
118
|
+
# 2. Récupérer les fichiers de migration de la branche parente
|
|
119
|
+
# (pour ne pas perdre les migrations déjà présentes sur develop/main)
|
|
120
|
+
for base_mig in $BASE_MIGRATIONS; do
|
|
121
|
+
base_file=$(basename "$base_mig")
|
|
122
|
+
base_name="${base_file%.cs}"
|
|
123
|
+
|
|
124
|
+
# Récupérer le fichier migration ET son Designer
|
|
125
|
+
git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR/${base_name}.cs" 2>/dev/null || true
|
|
126
|
+
git checkout "origin/$BASE_BRANCH" -- "$MIGRATIONS_DIR/${base_name}.Designer.cs" 2>/dev/null || true
|
|
127
|
+
done
|
|
128
|
+
|
|
129
|
+
echo "Récupéré depuis origin/$BASE_BRANCH:"
|
|
130
|
+
echo " - ModelSnapshot"
|
|
131
|
+
echo " - $(echo "$BASE_MIGRATIONS" | wc -l) migrations"
|
|
117
132
|
```
|
|
118
133
|
|
|
119
134
|
**Pourquoi c'est crucial:**
|
|
120
135
|
- Le snapshot de `$BASE_BRANCH` contient l'état VALIDÉ et COMPLET
|
|
136
|
+
- Les **migrations existantes** de `$BASE_BRANCH` doivent être conservées
|
|
121
137
|
- Les migrations parallèles sur d'autres branches sont incluses
|
|
122
138
|
- Évite la perte d'information de schéma (cf. [Bokio best practices](https://www.bokio.se/engineering-blog/how-to-squash-ef-core-migrations/))
|
|
123
139
|
|
|
140
|
+
**Résultat attendu:**
|
|
141
|
+
```
|
|
142
|
+
feature/* après squash:
|
|
143
|
+
├── Core_v1_9_0_001_InitialSchema.cs ← De develop (conservé)
|
|
144
|
+
├── Core_v1_9_0_001_InitialSchema.Designer.cs
|
|
145
|
+
├── core_v1.0.0_001_FeatureConsolidated.cs ← Squash de la feature
|
|
146
|
+
├── core_v1.0.0_001_FeatureConsolidated.Designer.cs
|
|
147
|
+
└── CoreDbContextModelSnapshot.cs ← De develop
|
|
148
|
+
```
|
|
149
|
+
|
|
124
150
|
---
|
|
125
151
|
|
|
126
152
|
## STEP 5: Supprimer Migrations de la Branche (pas celles héritées)
|
|
@@ -139,29 +165,48 @@ echo "Supprimé: ${#BRANCH_ONLY_MIGRATIONS[@]} migrations"
|
|
|
139
165
|
|
|
140
166
|
## STEP 6: Créer Migration Consolidée
|
|
141
167
|
|
|
168
|
+
**OBLIGATOIRE: Utiliser le MCP pour le nommage conforme**
|
|
169
|
+
|
|
142
170
|
```bash
|
|
143
|
-
#
|
|
171
|
+
# Construire la description selon le contexte
|
|
144
172
|
case "$BRANCH_TYPE" in
|
|
145
173
|
feature)
|
|
146
|
-
BRANCH_NAME=$(echo "$CURRENT_BRANCH" | sed 's|feature/||')
|
|
147
|
-
|
|
174
|
+
BRANCH_NAME=$(echo "$CURRENT_BRANCH" | sed 's|feature/||' | sed 's/-/ /g')
|
|
175
|
+
DESCRIPTION="${BRANCH_NAME} Consolidated"
|
|
148
176
|
;;
|
|
149
177
|
release)
|
|
150
|
-
VERSION=$(echo "$CURRENT_BRANCH" | sed 's|release/||'
|
|
151
|
-
|
|
178
|
+
VERSION=$(echo "$CURRENT_BRANCH" | sed 's|release/||')
|
|
179
|
+
DESCRIPTION="Release ${VERSION} Initial"
|
|
152
180
|
;;
|
|
153
181
|
hotfix)
|
|
154
|
-
VERSION=$(echo "$CURRENT_BRANCH" | sed 's|hotfix/||'
|
|
155
|
-
|
|
182
|
+
VERSION=$(echo "$CURRENT_BRANCH" | sed 's|hotfix/||')
|
|
183
|
+
DESCRIPTION="Hotfix ${VERSION} Fix"
|
|
156
184
|
;;
|
|
157
185
|
develop)
|
|
158
|
-
|
|
186
|
+
DESCRIPTION="Develop Consolidated"
|
|
159
187
|
;;
|
|
160
188
|
*)
|
|
161
|
-
|
|
189
|
+
DESCRIPTION="Consolidated"
|
|
162
190
|
;;
|
|
163
191
|
esac
|
|
192
|
+
```
|
|
164
193
|
|
|
194
|
+
**Appel MCP OBLIGATOIRE:**
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
// Utiliser le MCP pour obtenir le nom conforme
|
|
198
|
+
mcp__smartstack__suggest_migration({
|
|
199
|
+
description: DESCRIPTION, // Ex: "multitenant Consolidated"
|
|
200
|
+
context: "core" // ou "extensions" selon le projet
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
// Résultat: core_v1.0.0_001_MultitenantConsolidated
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Puis créer la migration:**
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# MIGRATION_NAME = résultat du MCP (ex: core_v1.0.0_001_MultitenantConsolidated)
|
|
165
210
|
dotnet ef migrations add "$MIGRATION_NAME" \
|
|
166
211
|
--project "$INFRA_PROJECT" \
|
|
167
212
|
--startup-project "$STARTUP_PROJECT" \
|
|
@@ -169,6 +214,8 @@ dotnet ef migrations add "$MIGRATION_NAME" \
|
|
|
169
214
|
--verbose
|
|
170
215
|
```
|
|
171
216
|
|
|
217
|
+
> **Convention:** `{context}_v{version}_{sequence}_{Description}` - Jamais de nom hardcodé
|
|
218
|
+
|
|
172
219
|
---
|
|
173
220
|
|
|
174
221
|
## STEP 7: Validation
|
|
@@ -192,11 +239,19 @@ dotnet ef migrations script --no-build --idempotent > /dev/null
|
|
|
192
239
|
|
|
193
240
|
```
|
|
194
241
|
SQUASH - {CURRENT_BRANCH}
|
|
195
|
-
Base:
|
|
196
|
-
Backup:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
242
|
+
Base: {BASE_BRANCH}
|
|
243
|
+
Backup: {BACKUP_DIR}
|
|
244
|
+
|
|
245
|
+
Récupéré de {BASE_BRANCH}:
|
|
246
|
+
- ModelSnapshot
|
|
247
|
+
- {BASE_MIGRATION_COUNT} migrations (conservées)
|
|
248
|
+
|
|
249
|
+
Consolidé:
|
|
250
|
+
- Avant: {MIGRATION_COUNT} migrations (propres à la branche)
|
|
251
|
+
- Après: 1 migration ({MIGRATION_NAME})
|
|
252
|
+
|
|
253
|
+
Total final: {BASE_MIGRATION_COUNT + 1} migrations
|
|
254
|
+
Conformité: MCP suggest_migration, EF Core CLI, Snapshot parent
|
|
200
255
|
|
|
201
256
|
Prochains: /efcore:db-reset, /efcore:db-deploy, /gitflow:3-commit
|
|
202
257
|
```
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Quick MCP availability check before MCP tool calls
|
|
3
|
+
trigger: tool-use
|
|
4
|
+
match: mcp__smartstack__*
|
|
5
|
+
blocking: false
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# MCP Quick Check (Low Token)
|
|
9
|
+
|
|
10
|
+
Lightweight pre-check before MCP calls. Reads cache only, no LLM processing.
|
|
11
|
+
|
|
12
|
+
## Script
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
#!/bin/bash
|
|
16
|
+
STATUS_FILE=".claude/mcp-status.json"
|
|
17
|
+
MAX_AGE_DAYS=7
|
|
18
|
+
|
|
19
|
+
# Create .claude if missing
|
|
20
|
+
mkdir -p .claude
|
|
21
|
+
|
|
22
|
+
# Check if status file exists
|
|
23
|
+
if [ ! -f "$STATUS_FILE" ]; then
|
|
24
|
+
echo "⚠️ MCP: First use - run /mcp:healthcheck"
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Check file age (cross-platform)
|
|
29
|
+
if command -v stat &> /dev/null; then
|
|
30
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
31
|
+
FILE_AGE=$(( ($(date +%s) - $(stat -f %m "$STATUS_FILE")) / 86400 ))
|
|
32
|
+
else
|
|
33
|
+
FILE_AGE=$(( ($(date +%s) - $(stat -c %Y "$STATUS_FILE")) / 86400 ))
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ "$FILE_AGE" -gt "$MAX_AGE_DAYS" ]; then
|
|
37
|
+
echo "⚠️ MCP: Cache expired ($FILE_AGE days) - run /mcp:healthcheck"
|
|
38
|
+
fi
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Check last status
|
|
42
|
+
STATUS=$(grep -o '"status":\s*"[^"]*"' "$STATUS_FILE" 2>/dev/null | cut -d'"' -f4)
|
|
43
|
+
if [ "$STATUS" = "error" ]; then
|
|
44
|
+
echo "❌ MCP: Last check failed - run /mcp:healthcheck"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
exit 0
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Behavior
|
|
52
|
+
|
|
53
|
+
| Condition | Output | Blocks? |
|
|
54
|
+
|-----------|--------|---------|
|
|
55
|
+
| No cache file | Warning message | No |
|
|
56
|
+
| Cache > 7 days | Warning message | No |
|
|
57
|
+
| Last status = error | Error message | Yes |
|
|
58
|
+
| All OK | Silent (no output) | No |
|
|
59
|
+
|
|
60
|
+
## Token Cost
|
|
61
|
+
|
|
62
|
+
- **Normal case (cache valid):** 0 tokens (pure bash, no LLM)
|
|
63
|
+
- **Warning case:** ~10 tokens (displays message)
|
|
64
|
+
- **Full healthcheck:** ~100-200 tokens (only when explicitly called)
|
|
@@ -13,6 +13,39 @@ description: |
|
|
|
13
13
|
|
|
14
14
|
**Reference:** [_shared.md](../_shared.md) for architecture, permissions, i18n
|
|
15
15
|
|
|
16
|
+
## ENTRY POINT
|
|
17
|
+
|
|
18
|
+
> **FIRST ACTION:** Load `steps/step-00-init.md`
|
|
19
|
+
|
|
20
|
+
This skill uses progressive step loading. Each step calls MCP tools for generation.
|
|
21
|
+
|
|
22
|
+
## STEP FILES
|
|
23
|
+
|
|
24
|
+
| Step | File | MCP Tool Called |
|
|
25
|
+
|------|------|-----------------|
|
|
26
|
+
| 00 | `steps/step-00-init.md` | `validate_conventions` (MCP check) |
|
|
27
|
+
| 01 | `steps/step-01-navigation.md` | `scaffold_navigation` |
|
|
28
|
+
| 02 | `steps/step-02-permissions.md` | `generate_permissions` |
|
|
29
|
+
| 03 | `steps/step-03-roles.md` | `scaffold_role_permissions` |
|
|
30
|
+
| 04 | `steps/step-04-backend.md` | `scaffold_extension` |
|
|
31
|
+
| 05 | `steps/step-05-frontend.md` | `scaffold_api_client`, `scaffold_routes` |
|
|
32
|
+
| 06 | `steps/step-06-migration.md` | `suggest_migration` |
|
|
33
|
+
|
|
34
|
+
## MCP INTEGRATION
|
|
35
|
+
|
|
36
|
+
> **CRITICAL:** This skill MUST use MCP tools for all generation.
|
|
37
|
+
> Templates in this folder are for REFERENCE ONLY - never use them directly.
|
|
38
|
+
|
|
39
|
+
| MCP Tool | Purpose |
|
|
40
|
+
|----------|---------|
|
|
41
|
+
| `mcp__smartstack__scaffold_navigation` | Navigation entity + translations |
|
|
42
|
+
| `mcp__smartstack__generate_permissions` | Permissions.cs + HasData |
|
|
43
|
+
| `mcp__smartstack__scaffold_role_permissions` | Role-permission mappings |
|
|
44
|
+
| `mcp__smartstack__scaffold_extension` | Entity, Service, Controller, DTOs |
|
|
45
|
+
| `mcp__smartstack__scaffold_api_client` | TypeScript API client |
|
|
46
|
+
| `mcp__smartstack__scaffold_routes` | React Router configuration |
|
|
47
|
+
| `mcp__smartstack__suggest_migration` | Migration name suggestion |
|
|
48
|
+
|
|
16
49
|
## WHEN THIS SKILL ACTIVATES
|
|
17
50
|
|
|
18
51
|
| Trigger | Example |
|
|
@@ -134,7 +167,20 @@ await _workflowService.TriggerAsync("{entity}.created", new Dictionary<string, o
|
|
|
134
167
|
|
|
135
168
|
## ASSOCIATED FILES
|
|
136
169
|
|
|
137
|
-
|
|
138
|
-
- [
|
|
139
|
-
- [
|
|
140
|
-
- [
|
|
170
|
+
### Step Files (ACTIVE - Use These)
|
|
171
|
+
- [steps/step-00-init.md](steps/step-00-init.md) - Initialize parameters
|
|
172
|
+
- [steps/step-01-navigation.md](steps/step-01-navigation.md) - Generate navigation
|
|
173
|
+
- [steps/step-02-permissions.md](steps/step-02-permissions.md) - Generate permissions
|
|
174
|
+
- [steps/step-03-roles.md](steps/step-03-roles.md) - Assign roles
|
|
175
|
+
- [steps/step-04-backend.md](steps/step-04-backend.md) - Generate backend
|
|
176
|
+
- [steps/step-05-frontend.md](steps/step-05-frontend.md) - Generate frontend
|
|
177
|
+
- [steps/step-06-migration.md](steps/step-06-migration.md) - Create migration
|
|
178
|
+
|
|
179
|
+
### Templates (REFERENCE ONLY - Do Not Use Directly)
|
|
180
|
+
> These templates are kept for documentation purposes.
|
|
181
|
+
> All generation is done via MCP tools in step files.
|
|
182
|
+
|
|
183
|
+
- [templates-backend.md](templates-backend.md) - Backend patterns reference
|
|
184
|
+
- [templates-frontend.md](templates-frontend.md) - Frontend patterns reference
|
|
185
|
+
- [templates-i18n.md](templates-i18n.md) - i18n structure reference
|
|
186
|
+
- [templates-seed.md](templates-seed.md) - Seed data patterns reference
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: step-00-init
|
|
3
|
+
description: Initialize application/module creation - parse parameters and validate context
|
|
4
|
+
next_step: steps/step-01-navigation.md
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Step 0: Initialization
|
|
8
|
+
|
|
9
|
+
## MANDATORY EXECUTION RULES
|
|
10
|
+
|
|
11
|
+
- NEVER skip parameter validation
|
|
12
|
+
- ALWAYS detect the navigation level from user request
|
|
13
|
+
- ALWAYS validate MCP availability before proceeding
|
|
14
|
+
- YOU ARE AN INITIALIZER, not an executor
|
|
15
|
+
- FORBIDDEN to call MCP tools until init is complete
|
|
16
|
+
|
|
17
|
+
## YOUR TASK
|
|
18
|
+
|
|
19
|
+
Initialize the application/module creation by parsing parameters, detecting level, and validating the SmartStack context.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## EXECUTION SEQUENCE
|
|
24
|
+
|
|
25
|
+
### 1. Detect Navigation Level
|
|
26
|
+
|
|
27
|
+
From user request, identify the level:
|
|
28
|
+
|
|
29
|
+
| Hint in Request | → Level | Parent Required |
|
|
30
|
+
|-----------------|---------|-----------------|
|
|
31
|
+
| "context", "workspace", "nouveau contexte" | context | No |
|
|
32
|
+
| "application", "app", "nouvelle application" | application | Yes (context) |
|
|
33
|
+
| "module", "feature", "nouveau module" | module | Yes (context.application) |
|
|
34
|
+
| "section", "tab", "nouvelle section" | section | Yes (context.app.module) |
|
|
35
|
+
|
|
36
|
+
### 2. Extract Parameters
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
# Required
|
|
40
|
+
level: context | application | module | section
|
|
41
|
+
code: kebab-case (e.g., "products", "order-management")
|
|
42
|
+
labels:
|
|
43
|
+
fr: "Label français"
|
|
44
|
+
en: "English label"
|
|
45
|
+
it: "Etichetta italiana"
|
|
46
|
+
de: "Deutsche Bezeichnung"
|
|
47
|
+
icon: Lucide icon name (e.g., "Package", "ShoppingCart")
|
|
48
|
+
displayOrder: number
|
|
49
|
+
|
|
50
|
+
# Conditional (required for non-context levels)
|
|
51
|
+
parentPath: "context.application.module" (dot-separated)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Validate MCP Availability
|
|
55
|
+
|
|
56
|
+
**CRITICAL:** Before proceeding, verify SmartStack MCP is available:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Call: mcp__smartstack__validate_conventions
|
|
60
|
+
Args: { checks: ["all"] }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If MCP call fails:
|
|
64
|
+
- Display warning: "SmartStack MCP not available"
|
|
65
|
+
- Provide manual instructions instead of automated generation
|
|
66
|
+
- Do NOT proceed with step files
|
|
67
|
+
|
|
68
|
+
### 4. Build Full Path
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
{full_path} = {parentPath}.{code} (if parentPath exists)
|
|
72
|
+
{full_path} = {code} (if context level)
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
level: module
|
|
76
|
+
parentPath: erp.sales
|
|
77
|
+
code: products
|
|
78
|
+
→ full_path: erp.sales.products
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 5. Infer Descriptions (if not provided)
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
descriptions:
|
|
85
|
+
fr: "Gestion de {labels.fr}"
|
|
86
|
+
en: "{labels.en} management"
|
|
87
|
+
it: "Gestione di {labels.it}"
|
|
88
|
+
de: "Verwaltung von {labels.de}"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 6. Show Summary
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
## Application Skill: {level} - {code}
|
|
95
|
+
|
|
96
|
+
| Parameter | Value |
|
|
97
|
+
|-----------|-------|
|
|
98
|
+
| Level | {level} |
|
|
99
|
+
| Code | {code} |
|
|
100
|
+
| Full Path | {full_path} |
|
|
101
|
+
| Parent | {parentPath} |
|
|
102
|
+
| Icon | {icon} |
|
|
103
|
+
| Display Order | {displayOrder} |
|
|
104
|
+
|
|
105
|
+
### Labels
|
|
106
|
+
| Language | Label |
|
|
107
|
+
|----------|-------|
|
|
108
|
+
| FR | {labels.fr} |
|
|
109
|
+
| EN | {labels.en} |
|
|
110
|
+
| IT | {labels.it} |
|
|
111
|
+
| DE | {labels.de} |
|
|
112
|
+
|
|
113
|
+
→ Proceeding to navigation generation...
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## STATE VARIABLES TO PERSIST
|
|
119
|
+
|
|
120
|
+
| Variable | Description |
|
|
121
|
+
|----------|-------------|
|
|
122
|
+
| `{level}` | context, application, module, or section |
|
|
123
|
+
| `{code}` | kebab-case identifier |
|
|
124
|
+
| `{full_path}` | Complete navigation path |
|
|
125
|
+
| `{parent_path}` | Parent path (null for context) |
|
|
126
|
+
| `{labels}` | Object with fr, en, it, de |
|
|
127
|
+
| `{descriptions}` | Object with fr, en, it, de |
|
|
128
|
+
| `{icon}` | Lucide icon name |
|
|
129
|
+
| `{display_order}` | Numeric display order |
|
|
130
|
+
| `{mcp_available}` | Boolean - MCP connectivity status |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## SUCCESS METRICS
|
|
135
|
+
|
|
136
|
+
- Level correctly detected
|
|
137
|
+
- All required parameters extracted
|
|
138
|
+
- MCP availability verified
|
|
139
|
+
- Full path computed correctly
|
|
140
|
+
- Summary displayed
|
|
141
|
+
- Proceeded to step-01-navigation.md
|
|
142
|
+
|
|
143
|
+
## FAILURE MODES
|
|
144
|
+
|
|
145
|
+
- Missing required parameters (ask user)
|
|
146
|
+
- Invalid level detection (clarify with user)
|
|
147
|
+
- MCP not available (provide manual instructions)
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## NEXT STEP
|
|
152
|
+
|
|
153
|
+
After showing initialization summary, proceed to `./step-01-navigation.md`
|