#!/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: / Proposition: . 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: / Proposition: . 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: / Pourquoi: / Proposition: . 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: / Pourquoi: / Proposition: . 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: / Proposition: . 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: / Proposition: . 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: / Proposition: . 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: / Proposition: . 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: / Proposition: . 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 ' // { print " " print " Review implementation for reusable patterns, difficult bug fixes, anti-patterns, or architecture decisions that emerged during this story" print " " print " Write proposals to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md ONLY \xe2\x80\x94 NEVER inside the project repo" print " For each proposal: FORMAT = \"DATE \xe2\x80\x94 '"$PROJECT_NAME"' / FILE_UPDATE_PROPOSAL / Fichier cible: <target> / Pourquoi: <reason> / Proposition: <content>\"" print " " 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 " " print " Review findings for patterns worth capitalizing: anti-patterns found, recurring issues, architecture decisions confirmed or invalidated" print " " print " Write proposals to ~/AI_RULES/_Assistant_Lead_Tech/95_a_capitaliser.md ONLY \xe2\x80\x94 NEVER inside the project repo" print " For each proposal: FORMAT = \"DATE \xe2\x80\x94 '"$PROJECT_NAME"' / FILE_UPDATE_PROPOSAL / Fichier cible: <target> / Pourquoi: <reason> / Proposition: <content>\"" print " " 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" < Pourquoi : Proposition : \`\`\` 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."