Files
_Assistant_Lead_Tech/scripts/post-bmad-install.sh
MaksTinyWorkshop 5650f26b08 feat: capitalise Epic 2 app-alexandrie + enrichit post-bmad-install
- Intègre 9 propositions de 95_a_capitaliser.md (Stripe, webhooks, Redis,
  entitlements, guards, catch silencieux, conventions File List)
- Ajoute core-bmad-master dans les agents patchés (orchestrateur)
- Différencie les fichiers cibles par rôle d'agent (dev/architect/qa…)
- Patch dev-story et code-review XML pour déclencher la capitalisation
  à chaque fin de story et après chaque code review

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 14:13:34 +01:00

256 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# post-bmad-install.sh
# À lancer après `npx bmad-method install` dans un projet BMAD.
# Injecte la memory de capitalisation Lead_tech dans les agents producteurs.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Résolution du chemin Lead_tech (même logique que aliases.sh)
if [ -d "$HOME/AI_RULES/_Assistant_Lead_Tech" ]; then
LEADTECH_PATH="$HOME/AI_RULES/_Assistant_Lead_Tech"
elif [ -d "/srv/projects/_Assistant_Lead_Tech" ]; then
LEADTECH_PATH="/srv/projects/_Assistant_Lead_Tech"
else
echo "Erreur : impossible de localiser le repo Lead_tech." >&2
exit 1
fi
# Projet courant
PROJECT_ROOT="$(pwd)"
PROJECT_NAME="$(basename "$PROJECT_ROOT")"
AGENTS_DIR="$PROJECT_ROOT/_bmad/_config/agents"
CLAUDE_MD="$PROJECT_ROOT/CLAUDE.md"
if [ ! -d "$AGENTS_DIR" ]; then
echo "Erreur : dossier _bmad/_config/agents/ introuvable dans $PROJECT_ROOT"
echo "Lance ce script depuis la racine d'un projet BMAD installé."
exit 1
fi
# Agents à patcher
# Tous les agents susceptibles d'identifier un pattern, anti-pattern ou décision réutilisable
PRODUCER_AGENTS=(
"bmm-dev"
"bmm-architect"
"bmm-sm"
"bmm-qa"
"bmm-quick-flow-solo-dev"
"bmm-analyst"
"bmm-pm"
"bmm-tech-writer"
"bmm-ux-designer"
"tea-tea"
"core-bmad-master"
)
CAPITALIZE_MARKER="95_a_capitaliser.md"
patch_agent() {
local agent="$1"
local file="$AGENTS_DIR/${agent}.customize.yaml"
if [ ! -f "$file" ]; then
return 0 # agent non installé dans ce projet, on skip
fi
# Idempotent : ne pas injecter si déjà présent
if grep -q "$CAPITALIZE_MARKER" "$file"; then
echo " [skip] $agent — memory déjà présente"
return 0
fi
# Injection après la ligne "memories: []"
# Si memories: [] → remplacer par le bloc memories avec la memory
if grep -q "^memories: \[\]" "$file"; then
# Construire la memory adaptée au rôle de l'agent
local memory
memory="$(build_memory "$agent")"
# Remplacer memories: [] par le bloc injecté
# Utilise awk pour éviter les conflits avec les caractères spéciaux (|, <, >) dans sed
awk -v mem="$memory" '
/^memories: \[\]/ { print "memories:"; print " - \"" mem "\""; next }
{ print }
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
echo " [ok] $agent — memory injectée"
else
echo " [warn] $agent — format memories: inattendu, patch manuel requis"
fi
}
build_memory() {
local agent="$1"
local base="When a reusable pattern, difficult bug fix, anti-pattern, or architecture decision emerges"
case "$agent" in
bmm-dev|bmm-quick-flow-solo-dev)
echo "${base} during implementation, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_backend_patterns_valides.md | 10_frontend_patterns_valides.md | 10_backend_risques_et_vigilance.md | 10_frontend_risques_et_vigilance.md | 90_debug_et_postmortem.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-architect)
echo "${base} during architecture or technical design, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <40_decisions_et_archi.md | 10_backend_patterns_valides.md | 10_backend_risques_et_vigilance.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-sm)
echo "When a process improvement, recurring friction, or architecture decision emerges during sprint work, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <target file> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-qa|tea-tea)
echo "When a reusable test pattern, tricky bug, or quality anti-pattern is identified, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <target file> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-analyst)
echo "When a reusable analysis pattern, requirements anti-pattern, or domain insight emerges, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_product_patterns_valides.md | 10_backend_patterns_valides.md | 40_decisions_et_archi.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-pm)
echo "When a product decision, prioritization pattern, or recurring friction is identified, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_product_patterns_valides.md | 40_decisions_et_archi.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-ux-designer)
echo "When a reusable UX/UI pattern, interaction anti-pattern, or UX decision emerges, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_ux_patterns_valides.md | 10_ux_risques_et_vigilance.md | 40_decisions_et_archi.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
bmm-tech-writer)
echo "When a reusable documentation pattern, writing convention, or recurring documentation friction emerges, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_conventions_redaction.md | 40_decisions_et_archi.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
core-bmad-master)
echo "As the orchestrating agent, when any cross-cutting pattern, process improvement, recurring friction, or architectural decision emerges across the project, write a proposal to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md (NUC: /srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md). Format: DATE — ${PROJECT_NAME} / FILE_UPDATE_PROPOSAL / Fichier cible: <10_backend_patterns_valides.md | 10_frontend_patterns_valides.md | 10_product_patterns_valides.md | 10_ux_patterns_valides.md | 10_backend_risques_et_vigilance.md | 10_frontend_risques_et_vigilance.md | 40_decisions_et_archi.md | 90_debug_et_postmortem.md> / Pourquoi: <reason> / Proposition: <content>. Never write directly to Lead_tech validated files."
;;
esac
}
CAPITALIZE_MARKER_XML="Capitalisation Lead_tech"
DEV_STORY_XML="$PROJECT_ROOT/_bmad/bmm/workflows/4-implementation/dev-story/instructions.xml"
CODE_REVIEW_XML="$PROJECT_ROOT/_bmad/bmm/workflows/4-implementation/code-review/instructions.xml"
patch_dev_story() {
local file="$DEV_STORY_XML"
if [ ! -f "$file" ]; then
echo " [skip] dev-story/instructions.xml — fichier absent"
return 0
fi
if grep -q "$CAPITALIZE_MARKER_XML" "$file"; then
echo " [skip] dev-story/instructions.xml — capitalisation déjà présente"
return 0
fi
# Insérer le bloc capitalisation juste avant les Final validation gates
awk '
/<!-- Final validation gates -->/ {
print " <!-- Capitalisation Lead_tech -->"
print " <action>Review implementation for reusable patterns, difficult bug fixes, anti-patterns, or architecture decisions that emerged during this story</action>"
print " <check if=\"capitalisation-worthy content identified\">"
print " <critical>Write proposals to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md ONLY \xe2\x80\x94 NEVER inside the project repo</critical>"
print " <action>For each proposal: FORMAT = \"DATE \xe2\x80\x94 '"$PROJECT_NAME"' / FILE_UPDATE_PROPOSAL / Fichier cible: &lt;target&gt; / Pourquoi: &lt;reason&gt; / Proposition: &lt;content&gt;\"</action>"
print " </check>"
print ""
}
{ print }
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
echo " [ok] dev-story/instructions.xml — capitalisation injectée"
}
patch_code_review() {
local file="$CODE_REVIEW_XML"
if [ ! -f "$file" ]; then
echo " [skip] code-review/instructions.xml — fichier absent"
return 0
fi
if grep -q "$CAPITALIZE_MARKER_XML" "$file"; then
echo " [skip] code-review/instructions.xml — capitalisation déjà présente"
return 0
fi
# Insérer le bloc capitalisation après le output "✅ Review Complete!"
awk '
/✅ Review Complete!/ { in_review_complete = 1 }
in_review_complete && /<\/output>/ {
print
print ""
print " <!-- Capitalisation Lead_tech -->"
print " <action>Review findings for patterns worth capitalizing: anti-patterns found, recurring issues, architecture decisions confirmed or invalidated</action>"
print " <check if=\"capitalisation-worthy findings identified\">"
print " <critical>Write proposals to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md ONLY \xe2\x80\x94 NEVER inside the project repo</critical>"
print " <action>For each proposal: FORMAT = \"DATE \xe2\x80\x94 '"$PROJECT_NAME"' / FILE_UPDATE_PROPOSAL / Fichier cible: &lt;target&gt; / Pourquoi: &lt;reason&gt; / Proposition: &lt;content&gt;\"</action>"
print " </check>"
in_review_complete = 0
next
}
{ print }
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
echo " [ok] code-review/instructions.xml — capitalisation injectée"
}
patch_claude_md() {
if [ ! -f "$CLAUDE_MD" ]; then
echo " [skip] CLAUDE.md — fichier absent"
return 0
fi
if grep -q "$CAPITALIZE_MARKER" "$CLAUDE_MD"; then
echo " [skip] CLAUDE.md — section capitalisation déjà présente"
return 0
fi
cat >> "$CLAUDE_MD" <<EOF
---
# Capitalisation vers Lead_tech
Quand un apprentissage émerge (bug difficile, pattern réutilisable, anti-pattern, décision d'archi),
l'écrire dans la zone tampon Lead_tech :
\`\`\`
~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md
\`\`\`
Sur le NUC : \`/srv/projects/_Assistant_Lead_Tech/95_a_capitaliser.md\`
Format :
\`\`\`
DATE — ${PROJECT_NAME}
FILE_UPDATE_PROPOSAL
Fichier cible : <10_backend_patterns_valides.md | 10_frontend_patterns_valides.md | 10_ux_patterns_valides.md | 10_backend_risques_et_vigilance.md | 10_frontend_risques_et_vigilance.md | 10_ux_risques_et_vigilance.md | 40_decisions_et_archi.md | 90_debug_et_postmortem.md>
Pourquoi :
<raison en 1-2 phrases>
Proposition :
<contenu suggéré>
\`\`\`
Règle : écrire dans \`95_a_capitaliser.md\` uniquement. Jamais directement dans les fichiers Lead_tech validés.
EOF
echo " [ok] CLAUDE.md — section capitalisation ajoutée"
}
# --- Main ---
echo ""
echo "post-bmad-install — injection Lead_tech capitalisation"
echo "Projet : $PROJECT_NAME ($PROJECT_ROOT)"
echo "Agents : $AGENTS_DIR"
echo ""
echo "Patch agents :"
for agent in "${PRODUCER_AGENTS[@]}"; do
patch_agent "$agent"
done
echo ""
echo "Patch workflows :"
patch_dev_story
patch_code_review
echo ""
echo "Patch CLAUDE.md :"
patch_claude_md
echo ""
echo "Terminé. Lance 'git diff' pour vérifier les changements."