@atlashub/smartstack-cli 1.9.0 → 1.10.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.
@@ -84,12 +84,383 @@ if (CURRENT === "develop") {
84
84
  })
85
85
 
86
86
  if (response === "Non, creer une feature") {
87
- console.log("→ Lancez: /gitflow:10-start feature <nom>")
87
+ // Executer le processus RESCUE TO FEATURE
88
+ // Voir section 0.1.1 ci-dessous pour les details
89
+ executeRescueToFeature()
90
+ }
91
+ }
92
+ ```
93
+
94
+ ### 0.1.1 RESCUE TO FEATURE - Sauvetage des modifications develop vers feature
95
+
96
+ > **CLAUDE INSTRUCTION:** Cette section est executee quand l'utilisateur choisit "Non, creer une feature".
97
+ > Elle analyse l'etat de develop et sauve TOUT le travail vers une feature branch.
98
+
99
+ **ETAPE R1: Analyser l'etat complet de develop**
100
+
101
+ ```bash
102
+ # Fetch pour avoir les infos a jour
103
+ git fetch origin --quiet 2>/dev/null
104
+
105
+ # Etat du working directory
106
+ STAGED=$(git diff --cached --name-only | wc -l)
107
+ MODIFIED=$(git diff --name-only | wc -l)
108
+ UNTRACKED=$(git ls-files --others --exclude-standard | wc -l)
109
+
110
+ # Determiner si dirty
111
+ if [ "$STAGED" -gt 0 ] || [ "$MODIFIED" -gt 0 ] || [ "$UNTRACKED" -gt 0 ]; then
112
+ HAS_CHANGES="true"
113
+ else
114
+ HAS_CHANGES="false"
115
+ fi
116
+
117
+ # Commits locaux non pushes
118
+ LOCAL_COMMITS=$(git rev-list --count origin/develop..HEAD 2>/dev/null || echo "0")
119
+
120
+ # Commits distants non recuperes
121
+ REMOTE_COMMITS=$(git rev-list --count HEAD..origin/develop 2>/dev/null || echo "0")
122
+
123
+ # Determiner l'etat de synchronisation
124
+ if [ "$LOCAL_COMMITS" -eq 0 ] && [ "$REMOTE_COMMITS" -eq 0 ]; then
125
+ SYNC_STATE="SYNCED"
126
+ elif [ "$LOCAL_COMMITS" -gt 0 ] && [ "$REMOTE_COMMITS" -eq 0 ]; then
127
+ SYNC_STATE="AHEAD"
128
+ elif [ "$LOCAL_COMMITS" -eq 0 ] && [ "$REMOTE_COMMITS" -gt 0 ]; then
129
+ SYNC_STATE="BEHIND"
130
+ else
131
+ SYNC_STATE="DIVERGED"
132
+ fi
133
+
134
+ echo ""
135
+ echo "=============================================================================="
136
+ echo " ANALYSE DE DEVELOP"
137
+ echo "=============================================================================="
138
+ echo ""
139
+ echo "Working directory: $HAS_CHANGES"
140
+ echo " - Fichiers stages: $STAGED"
141
+ echo " - Fichiers modifies: $MODIFIED"
142
+ echo " - Fichiers non suivis: $UNTRACKED"
143
+ echo ""
144
+ echo "Commits locaux (non pushes): $LOCAL_COMMITS"
145
+ echo "Commits distants (a recuperer): $REMOTE_COMMITS"
146
+ echo "Etat de synchronisation: $SYNC_STATE"
147
+ echo ""
148
+
149
+ # Afficher les commits locaux si present
150
+ if [ "$LOCAL_COMMITS" -gt 0 ]; then
151
+ echo "COMMITS LOCAUX:"
152
+ echo "------------------------------------------------------------------------------"
153
+ git log origin/develop..HEAD --oneline
154
+ echo "------------------------------------------------------------------------------"
155
+ fi
156
+
157
+ # Afficher les commits distants si present
158
+ if [ "$REMOTE_COMMITS" -gt 0 ]; then
159
+ echo ""
160
+ echo "COMMITS DISTANTS A RECUPERER:"
161
+ echo "------------------------------------------------------------------------------"
162
+ git log HEAD..origin/develop --oneline
163
+ echo "------------------------------------------------------------------------------"
164
+ fi
165
+
166
+ echo "=============================================================================="
167
+ ```
168
+
169
+ **ETAPE R2: Traitement selon le cas detecte**
170
+
171
+ ```javascript
172
+ // CAS 1: CLEAN - Rien a sauver
173
+ if (HAS_CHANGES === "false" && LOCAL_COMMITS === 0 && SYNC_STATE === "SYNCED") {
174
+ console.log("")
175
+ console.log("==============================================================================")
176
+ console.log(" DEVELOP EST PROPRE")
177
+ console.log("==============================================================================")
178
+ console.log("")
179
+ console.log("Aucune modification detectee sur develop.")
180
+ console.log("Vous pouvez creer une feature directement.")
181
+ console.log("")
182
+ console.log("PROCHAINE ETAPE:")
183
+ console.log(" /gitflow:10-start feature <nom>")
184
+ console.log("")
185
+ console.log("==============================================================================")
186
+ exit(0)
187
+ }
188
+
189
+ // CAS 2-9: Il y a quelque chose a sauver - Demander le nom de la feature
190
+ ```
191
+
192
+ **Generer un nom suggere depuis les commits (si applicable):**
193
+
194
+ ```bash
195
+ # ═══════════════════════════════════════════════════════════════
196
+ # FONCTION DE NORMALISATION DES NOMS
197
+ # ═══════════════════════════════════════════════════════════════
198
+ normalize_name() {
199
+ local input="$1"
200
+ local max_length="${2:-50}"
201
+
202
+ # 1. Convertir en minuscules
203
+ local result=$(echo "$input" | tr '[:upper:]' '[:lower:]')
204
+
205
+ # 2. Supprimer les accents (francais)
206
+ result=$(echo "$result" | sed 'y/àâäéèêëïîôùûüçÀÂÄÉÈÊËÏÎÔÙÛÜÇ/aaaeeeeiioouucaaaeeeeiioouuc/')
207
+
208
+ # 3. Remplacer les espaces, underscores et caracteres speciaux par des tirets
209
+ result=$(echo "$result" | sed 's/[ _:()]/-/g')
210
+
211
+ # 4. Supprimer les caracteres non autorises (garder uniquement a-z, 0-9, -)
212
+ result=$(echo "$result" | sed 's/[^a-z0-9-]//g')
213
+
214
+ # 5. Supprimer les tirets multiples
215
+ result=$(echo "$result" | sed 's/--*/-/g')
216
+
217
+ # 6. Supprimer les tirets en debut/fin
218
+ result=$(echo "$result" | sed 's/^-//;s/-$//')
219
+
220
+ # 7. Tronquer a la longueur max
221
+ result=$(echo "$result" | cut -c1-$max_length)
222
+
223
+ # 8. Supprimer le tiret final apres troncature
224
+ result=$(echo "$result" | sed 's/-$//')
225
+
226
+ echo "$result"
227
+ }
228
+
229
+ # Si des commits locaux existent, extraire un nom suggere du premier commit
230
+ if [ "$LOCAL_COMMITS" -gt 0 ]; then
231
+ FIRST_COMMIT_MSG=$(git log -1 --format='%s' origin/develop..HEAD)
232
+ # Normaliser avec la fonction
233
+ SUGGESTED_NAME=$(normalize_name "$FIRST_COMMIT_MSG" 40)
234
+ echo "Nom suggere: $SUGGESTED_NAME"
235
+ fi
236
+ ```
237
+
238
+ **Demander la description de la feature:**
239
+
240
+ > **NOTE:** Le prefix `feature/` reste TOUJOURS en anglais.
241
+ > Seule la partie descriptive utilise la langue configuree.
242
+
243
+ ```javascript
244
+ // Lire la config de langue depuis .claude/gitflow/config.json
245
+ const langConfig = readConfig()?.language || { code: "en" }
246
+ const isEnglish = langConfig.code === "en"
247
+
248
+ // Construire les options selon qu'on a un nom suggere ou non
249
+ const options = []
250
+
251
+ if (SUGGESTED_NAME && SUGGESTED_NAME.length > 0) {
252
+ options.push({ label: SUGGESTED_NAME, description: "Genere depuis vos commits (Recommande)" })
253
+ }
254
+
255
+ // Suggestions de verbes d'action selon la langue
256
+ // Le prefix de branche "feature/" ne change PAS
257
+ if (isEnglish) {
258
+ options.push({ label: "add-", description: "Add a new feature → feature/add-..." })
259
+ options.push({ label: "update-", description: "Update existing → feature/update-..." })
260
+ options.push({ label: "fix-", description: "Fix a bug → feature/fix-..." })
261
+ options.push({ label: "refactor-", description: "Refactor code → feature/refactor-..." })
262
+ } else {
263
+ options.push({ label: "ajouter-", description: "Nouvelle fonctionnalite → feature/ajouter-..." })
264
+ options.push({ label: "modifier-", description: "Modifier existant → feature/modifier-..." })
265
+ options.push({ label: "corriger-", description: "Corriger un bug → feature/corriger-..." })
266
+ options.push({ label: "refactorer-", description: "Refactorer du code → feature/refactorer-..." })
267
+ }
268
+
269
+ AskUserQuestion({
270
+ questions: [{
271
+ question: isEnglish
272
+ ? "Describe the feature (branch will be feature/your-description)"
273
+ : "Decrivez la feature (branche sera feature/votre-description)",
274
+ header: "Feature",
275
+ options: options,
276
+ multiSelect: false
277
+ }]
278
+ })
279
+
280
+ // Le nom fourni par l'utilisateur (via option ou "Other")
281
+ RAW_FEATURE_NAME = response
282
+ ```
283
+
284
+ **Normaliser le nom saisi par l'utilisateur:**
285
+
286
+ ```bash
287
+ # ═══════════════════════════════════════════════════════════════
288
+ # NORMALISATION OBLIGATOIRE DU NOM DE FEATURE
289
+ # ═══════════════════════════════════════════════════════════════
290
+ # Le nom saisi par l'utilisateur peut contenir:
291
+ # - Des accents (e, a, etc.)
292
+ # - Des espaces
293
+ # - Des majuscules
294
+ # - Des caracteres speciaux
295
+ #
296
+ # Exemples de normalisation:
297
+ # "Ajouter l'authentification" → "ajouter-lauthentification"
298
+ # "Fix bug dans le Login !!" → "fix-bug-dans-le-login"
299
+ # "Améliorer performance API" → "ameliorer-performance-api"
300
+ # ═══════════════════════════════════════════════════════════════
301
+
302
+ FEATURE_NAME=$(normalize_name "$RAW_FEATURE_NAME" 50)
303
+ FEATURE_BRANCH="feature/${FEATURE_NAME}"
304
+
305
+ # Afficher la normalisation si differente
306
+ if [ "$RAW_FEATURE_NAME" != "$FEATURE_NAME" ]; then
307
+ echo ""
308
+ echo "Nom normalise: '$RAW_FEATURE_NAME' → '$FEATURE_NAME'"
309
+ fi
310
+ ```
311
+
312
+ **ETAPE R3: Confirmer si cas complexe (divergence ou rebase necessaire)**
313
+
314
+ ```javascript
315
+ // Si divergence ou rebase necessaire, demander confirmation
316
+ if (SYNC_STATE === "DIVERGED" || (LOCAL_COMMITS > 0 && REMOTE_COMMITS > 0)) {
317
+ AskUserQuestion({
318
+ questions: [{
319
+ question: "Situation complexe detectee. Comment proceder ?",
320
+ header: "Strategy",
321
+ options: [
322
+ { label: "Rebase (Recommande)", description: "Rejouer vos commits sur origin/develop a jour" },
323
+ { label: "Sauvegarder uniquement", description: "Creer la feature sans rebase (vous devrez rebase plus tard)" },
324
+ { label: "Annuler", description: "Ne rien faire, je gere manuellement" }
325
+ ],
326
+ multiSelect: false
327
+ }]
328
+ })
329
+
330
+ if (response === "Annuler") {
331
+ console.log("Operation annulee.")
88
332
  exit(0)
89
333
  }
334
+
335
+ STRATEGY = response
90
336
  }
91
337
  ```
92
338
 
339
+ **ETAPE R4: Executer le rescue**
340
+
341
+ ```bash
342
+ echo ""
343
+ echo "=== RESCUE EN COURS ==="
344
+ echo ""
345
+
346
+ # Point de restauration (toujours creer un backup)
347
+ RESCUE_TAG="rescue/develop-$(date +%Y%m%d-%H%M%S)"
348
+ git tag "${RESCUE_TAG}" HEAD
349
+ echo "[1/N] Point de restauration cree: ${RESCUE_TAG}"
350
+
351
+ # ═══════════════════════════════════════════════════════════════
352
+ # EXECUTION SELON LE CAS
353
+ # ═══════════════════════════════════════════════════════════════
354
+
355
+ STEP=2
356
+
357
+ # Si modifications non committees: stash
358
+ if [ "$HAS_CHANGES" = "true" ]; then
359
+ git stash push -m "gitflow-rescue: WIP pour ${FEATURE_BRANCH}" --include-untracked
360
+ echo "[$STEP/N] Modifications sauvegardees (stash)"
361
+ STASHED="true"
362
+ STEP=$((STEP + 1))
363
+ fi
364
+
365
+ # Si commits locaux: creer branche puis reset develop
366
+ if [ "$LOCAL_COMMITS" -gt 0 ]; then
367
+ # Creer la feature branch a partir de HEAD actuel (avec les commits)
368
+ git branch "${FEATURE_BRANCH}"
369
+ echo "[$STEP/N] Branche ${FEATURE_BRANCH} creee avec ${LOCAL_COMMITS} commits"
370
+ STEP=$((STEP + 1))
371
+
372
+ # Reset develop a origin/develop
373
+ git reset --hard origin/develop
374
+ echo "[$STEP/N] develop reset a origin/develop"
375
+ STEP=$((STEP + 1))
376
+
377
+ # Checkout la feature
378
+ git checkout "${FEATURE_BRANCH}"
379
+ echo "[$STEP/N] Bascule sur ${FEATURE_BRANCH}"
380
+ STEP=$((STEP + 1))
381
+
382
+ # Si behind ET strategie rebase: rebaser sur develop a jour
383
+ if [ "$REMOTE_COMMITS" -gt 0 ] && [ "$STRATEGY" = "Rebase (Recommande)" ]; then
384
+ echo "[$STEP/N] Rebase en cours..."
385
+ if git rebase origin/develop; then
386
+ echo " Rebase reussi"
387
+ else
388
+ echo ""
389
+ echo "=============================================================================="
390
+ echo " CONFLITS DE REBASE DETECTES"
391
+ echo "=============================================================================="
392
+ echo ""
393
+ echo "Des conflits ont ete detectes lors du rebase."
394
+ echo ""
395
+ echo "RESOLUTION:"
396
+ echo " 1. Resolvez les conflits dans les fichiers marques"
397
+ echo " 2. git add <fichiers resolus>"
398
+ echo " 3. git rebase --continue"
399
+ echo ""
400
+ echo "OU pour annuler:"
401
+ echo " git rebase --abort"
402
+ echo ""
403
+ echo "Point de restauration: ${RESCUE_TAG}"
404
+ echo " Restaurer: git checkout develop && git reset --hard ${RESCUE_TAG}"
405
+ echo ""
406
+ echo "=============================================================================="
407
+ exit 1
408
+ fi
409
+ STEP=$((STEP + 1))
410
+ fi
411
+
412
+ else
413
+ # Pas de commits locaux: simple checkout -b
414
+ # Si behind: pull d'abord
415
+ if [ "$REMOTE_COMMITS" -gt 0 ]; then
416
+ git pull origin develop --ff-only
417
+ echo "[$STEP/N] develop synchronise avec origin"
418
+ STEP=$((STEP + 1))
419
+ fi
420
+
421
+ git checkout -b "${FEATURE_BRANCH}"
422
+ echo "[$STEP/N] Branche ${FEATURE_BRANCH} creee"
423
+ STEP=$((STEP + 1))
424
+ fi
425
+
426
+ # Restaurer le stash si applicable
427
+ if [ "$STASHED" = "true" ]; then
428
+ git stash pop
429
+ echo "[$STEP/N] Modifications restaurees"
430
+ fi
431
+
432
+ # ═══════════════════════════════════════════════════════════════
433
+ # AFFICHER LE RESULTAT
434
+ # ═══════════════════════════════════════════════════════════════
435
+
436
+ echo ""
437
+ echo "=============================================================================="
438
+ echo " RESCUE REUSSI"
439
+ echo "=============================================================================="
440
+ echo ""
441
+ echo "Feature creee: ${FEATURE_BRANCH}"
442
+ if [ "$LOCAL_COMMITS" -gt 0 ]; then
443
+ echo "Commits deplaces: ${LOCAL_COMMITS}"
444
+ fi
445
+ if [ "$STASHED" = "true" ]; then
446
+ echo "Modifications restaurees: $(git status --short | wc -l) fichiers"
447
+ fi
448
+ echo ""
449
+ echo "develop: Propre et synchronise avec origin"
450
+ echo "${FEATURE_BRANCH}: Contient tout votre travail"
451
+ echo ""
452
+ echo "PROCHAINES ETAPES:"
453
+ echo " /gitflow:3-commit -> Committer vos modifications"
454
+ echo " /gitflow:7-pull-request -> Creer une PR quand pret"
455
+ echo ""
456
+ echo "Point de restauration: ${RESCUE_TAG}"
457
+ echo " En cas de probleme: git checkout develop && git reset --hard ${RESCUE_TAG}"
458
+ echo ""
459
+ echo "=============================================================================="
460
+ ```
461
+
462
+ ---
463
+
93
464
  ### 0.2 Verification synchronisation
94
465
 
95
466
  ```bash
@@ -243,21 +614,115 @@ grep -n "migrationBuilder.Sql" {migration}.cs | grep -i "DELETE\|DROP\|TRUNCATE"
243
614
 
244
615
  ### 5. Generate message (if absent)
245
616
 
617
+ > **CLAUDE INSTRUCTION - REDACTION EXPERTE DES COMMITS**
618
+ >
619
+ > Chaque message de commit doit etre **auto-explicatif** et repondre a 3 questions:
620
+ > 1. **Quel probleme existait?** (justifie le changement)
621
+ > 2. **Quelle solution?** (explique l'approche technique)
622
+ > 3. **Quel gain?** (motive l'adoption)
623
+
624
+ #### 5.1 Format standard - Commit simple
625
+
626
+ ```
627
+ {type}({scope}): {resume impact en 50 chars max}
628
+
629
+ {Pour chaque modification significative, UN PARAGRAPHE structure:}
630
+
631
+ **{NOM_CHANGEMENT}**
632
+ Resout le probleme ou {description situation problematique}.
633
+ Implemente {solution technique} qui permet desormais de {capacite gagnee}.
634
+ ```
635
+
636
+ #### 5.2 Format expert - Commit multi-changements
637
+
638
+ ```
639
+ {type}({scope}): {verbe d'impact} {objet} pour {objectif}
640
+
641
+ **{CHANGEMENT_1}**
642
+ PROBLEME: {Quel dysfonctionnement/manque existait?}
643
+ SOLUTION: {Quelle approche technique adoptee?}
644
+ IMPACT: {Qu'est-ce que l'utilisateur/developpeur gagne?}
645
+
646
+ **{CHANGEMENT_2}**
647
+ Avant: {etat problematique}.
648
+ Apres: {nouvel etat ameliore}.
649
+ Technique: {approche utilisee}.
650
+
651
+ Fichiers: {liste fichiers principaux avec leur role}
652
+
653
+ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
654
+ ```
655
+
656
+ #### 5.3 Regles de redaction
657
+
658
+ | Principe | Application |
659
+ |----------|-------------|
660
+ | **Atomicite** | 1 commit = 1 intention logique |
661
+ | **Contexte** | Le "pourquoi" AVANT le "quoi" |
662
+ | **Impact** | Toujours mentionner le benefice utilisateur |
663
+ | **Autonomie** | Chaque paragraphe comprehensible seul |
664
+ | **Concision** | Maximum d'info, minimum de mots |
665
+
666
+ #### 5.4 Verbes d'impact (preferer)
667
+
668
+ | Eviter | Utiliser |
669
+ |--------|----------|
670
+ | "Ajout de..." | "Implemente X pour Y" |
671
+ | "Modification de..." | "Optimise X qui permet Y" |
672
+ | "Correction de..." | "Resout X cause par Y" |
673
+ | "Mise a jour..." | "Ameliore X en Y" |
674
+
675
+ #### 5.5 Templates par type
676
+
246
677
  **Migration:**
247
678
  ```
248
679
  db(migrations): {action} {description}
249
680
 
250
- Migration: {MigrationName}
681
+ **MIGRATION: {MigrationName}**
682
+ PROBLEME: {Pourquoi cette migration est necessaire}
683
+ SOLUTION: {Tables/colonnes ajoutees/modifiees}
684
+ IMPACT: {Nouvelles capacites pour l'application}
685
+
251
686
  Tables: {CREATE|ALTER|DROP} {tables}
252
687
  Context: {DbContext}
253
688
  ```
254
689
 
255
- **Mixed:**
690
+ **Feature:**
691
+ ```
692
+ feat({scope}): {description impact}
693
+
694
+ **{NOM_FEATURE}**
695
+ PROBLEME: {Manque ou limitation actuelle}
696
+ SOLUTION: {Implementation technique choisie}
697
+ IMPACT: {Benefice utilisateur concret}
698
+
699
+ Fichiers cles:
700
+ - {path/file1.ext}: {role en 5 mots}
701
+ - {path/file2.ext}: {role en 5 mots}
702
+ ```
703
+
704
+ **Fix:**
705
+ ```
706
+ fix({scope}): resout {symptome} dans {contexte}
707
+
708
+ **{NOM_BUG}**
709
+ SYMPTOME: {Ce que l'utilisateur observait}
710
+ CAUSE: {Origine technique du probleme}
711
+ CORRECTION: {Comment le fix resout le probleme}
712
+ VERIFICATION: {Comment confirmer que c'est corrige}
713
+ ```
714
+
715
+ **Mixed (code + migrations):**
256
716
  ```
257
717
  feat({scope}): {description}
258
718
 
259
- - {changes}
260
- Migrations: {list}
719
+ **{FEATURE}**
720
+ {Paragraphe explicatif}
721
+
722
+ **MIGRATIONS INCLUSES**
723
+ - {MigrationName}: {ce qu'elle apporte}
724
+
725
+ Fichiers: {liste}
261
726
  ```
262
727
 
263
728
  ### 6. Execute commit