From c1f96fae9647dd511ef962a2b1ca62b3f4f7fd6d Mon Sep 17 00:00:00 2001 From: MaksTinyWorkshop Date: Sun, 8 Mar 2026 17:48:48 +0100 Subject: [PATCH] feat: automate project bootstrap and registry --- CLAUDE.md | 25 ++++++----- _AI_INSTRUCTIONS.md | 23 ++++++---- _projects.conf | 59 ++++++++++++++++++++++--- scripts/mkproj.sh | 76 ++++++++++++++++++++++++++++++-- scripts/resolve-project-path.sh | 77 +++++++++++++++++++++++++++++++++ scripts/sync-ai-instructions.sh | 34 +-------------- 6 files changed, 233 insertions(+), 61 deletions(-) create mode 100755 scripts/resolve-project-path.sh diff --git a/CLAUDE.md b/CLAUDE.md index 916a133..1bae953 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,14 +16,14 @@ Langue de travail : **français**. Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de proposer une solution dans leur domaine respectif. -| Fichier | Contenu | -|---|---| -| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles | -| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés | -| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend | -| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend | -| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) | -| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés | +| Fichier | Contenu | +| ------------------------------------- | ---------------------------------------------- | +| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles | +| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés | +| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend | +| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend | +| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) | +| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés | ## Règles de mise à jour @@ -39,9 +39,11 @@ Puis propose le contenu à ajouter dans le format du fichier cible. ## Projets actifs -| Projet | Stack | Localisation | État | -|---|---|---|---| -| app-alexandrie | NestJS + Expo (React Native) + Prisma + pnpm monorepo | `/Volumes/TeraSSD/Projets_Dev/__Mindleaf/app-alexandrie` | Epic 2 en préparation | +La liste des projets actifs est maintenue dans `_projects.conf`. + +Ce fichier constitue le registre central des projets (stack, scope, état). +Les scripts de l’environnement Lead_tech l’utilisent pour résoudre +automatiquement les chemins selon la machine (Mac / NUC). ## Patterns clés à appliquer systématiquement @@ -54,6 +56,7 @@ Puis propose le contenu à ajouter dans le format du fichier cible. ## Infrastructure NUC Convention de structure Docker sur le NUC (Proxmox) : + - `/srv/projects` — code applicatif - `/srv/docker-data` — données persistantes (bind mounts explicites) - `/srv/backups` — dumps et archives diff --git a/_AI_INSTRUCTIONS.md b/_AI_INSTRUCTIONS.md index d809de6..c8e60c7 100644 --- a/_AI_INSTRUCTIONS.md +++ b/_AI_INSTRUCTIONS.md @@ -11,14 +11,14 @@ Langue de travail : **français**. Ces fichiers sont la mémoire durable inter-projets. Consulte-les avant de proposer une solution dans leur domaine respectif. -| Fichier | Contenu | -|---|---| -| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles | -| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés | -| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend | -| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend | -| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) | -| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés | +| Fichier | Contenu | +| ------------------------------------- | ---------------------------------------------- | +| `10_backend_patterns_valides.md` | Patterns backend validés en conditions réelles | +| `10_frontend_patterns_valides.md` | Patterns frontend/mobile validés | +| `10_backend_risques_et_vigilance.md` | Risques et anti-patterns backend | +| `10_frontend_risques_et_vigilance.md` | Risques et anti-patterns frontend | +| `40_decisions_et_archi.md` | Décisions techniques (mini-ADR) | +| `90_debug_et_postmortem.md` | Post-mortems et bugs capitalisés | ## Règles de mise à jour @@ -34,7 +34,11 @@ Puis propose le contenu à ajouter dans le format du fichier cible. ## Projets actifs -{{PROJECTS_TABLE}} +La liste des projets actifs est maintenue dans `_projects.conf`. + +Ce fichier constitue le registre central des projets (stack, scope, état). +Les scripts de l’environnement Lead_tech l’utilisent pour résoudre +automatiquement les chemins selon la machine (Mac / NUC). ## Patterns clés à appliquer systématiquement @@ -47,6 +51,7 @@ Puis propose le contenu à ajouter dans le format du fichier cible. ## Infrastructure NUC Convention de structure Docker sur le NUC (Proxmox) : + - `/srv/projects` — code applicatif - `/srv/docker-data` — données persistantes (bind mounts explicites) - `/srv/backups` — dumps et archives diff --git a/_projects.conf b/_projects.conf index f943738..9c00491 100644 --- a/_projects.conf +++ b/_projects.conf @@ -1,6 +1,53 @@ -# Configuration des projets actifs -# Format : nom|stack|path_nuc|path_mac|etat -# Laisser path_nuc ou path_mac vide si le projet n'existe pas sur cette machine -# Exemple NUC seulement : mon-projet|Stack|/srv/projects/mon-projet||En cours - -app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|/srv/projects/app-alexandrie|/Volumes/TeraSSD/Projets_Dev/__Mindleaf/app-alexandrie|Epic 2 en préparation +# Registre des projets (source de vérité) +# +# Format principal : +# nom|stack|scope|etat +# +# Ce fichier sert de registre central pour les projets de développement. +# Il est utilisé par les scripts du repo Lead_tech et peut être lu par les agents +# (Claude, Codex, BMAD) pour comprendre l’architecture globale. +# +# Signification des champs : +# +# nom : nom du repository / dossier projet +# stack : stack principale (utile pour les agents et les audits techniques) +# scope : localisation logique du projet +# etat : statut actuel du projet +# +# Résolution automatique des chemins : +# +# Le champ `scope` représente d'abord une **catégorie logique de projet** +# (perso, mindleaf, lab, archive), utile pour le classement et les agents. +# +# Sur Mac, le `scope` détermine aussi la base du chemin : +# - perso → /Volumes/TeraSSD/Projets_Dev/ +# - mindleaf → /Volumes/TeraSSD/Projets_Dev/__Mindleaf/ +# - lab → /Volumes/TeraSSD/Labs/ +# - archive → /Volumes/TeraSSD/Archives_Projets/ +# +# Sur le NUC, le `scope` ne change pas le chemin physique : +# - tous les projets vivent dans /srv/projects/ +# +# Le `scope` reste néanmoins utile sur le NUC comme information logique +# (catégorie, contexte métier, filtres futurs, audits inter-projets, etc.). +# +# Valeurs recommandées pour scope : +# - perso +# - mindleaf +# - lab +# - archive +# +# Valeurs typiques pour etat : +# - dev +# - active +# - maintenance +# - archived +# +# Les scripts peuvent utiliser ce fichier pour : +# - résoudre le chemin d’un projet +# - lister les projets actifs +# - analyser les stacks +# - automatiser certains audits inter-projets +# +# Les lignes commençant par # sont ignorées. +app-alexandrie|NestJS + Expo (React Native) + Prisma + pnpm monorepo|mindleaf|Epic 2 en préparation \ No newline at end of file diff --git a/scripts/mkproj.sh b/scripts/mkproj.sh index 50c4384..c110138 100755 --- a/scripts/mkproj.sh +++ b/scripts/mkproj.sh @@ -1,11 +1,19 @@ #!/usr/bin/env bash set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +PROJECTS_CONF="$REPO_ROOT/_projects.conf" + PROJECT_NAME="${1:-}" OS="$(uname -s)" TARGET_BASE="" PROJECT_PATH="" +PROJECT_SCOPE="" +PROJECT_STACK="" +PROJECT_STATE="dev" + if [ -z "$PROJECT_NAME" ]; then echo "Usage: mkproj " exit 1 @@ -14,18 +22,30 @@ fi choose_mac_target_base() { echo "Environnement détecté : Mac" echo "Choisir le type de projet :" - echo " 1) Projet perso -> /Volumes/TeraSSD/Projets_Dev" - echo " 2) Projet Mindleaf -> /Volumes/TeraSSD/Projets_Dev/__Mindleaf" - printf "Votre choix [1/2] : " + echo " 1) Projet perso -> /Volumes/TeraSSD/Projets_Dev" + echo " 2) Projet Mindleaf -> /Volumes/TeraSSD/Projets_Dev/__Mindleaf" + echo " 3) Projet lab -> /Volumes/TeraSSD/Labs" + echo " 4) Projet archive -> /Volumes/TeraSSD/Archives_Projets" + printf "Votre choix [1/2/3/4] : " read -r choice case "$choice" in 1) + PROJECT_SCOPE="perso" TARGET_BASE="/Volumes/TeraSSD/Projets_Dev" ;; 2) + PROJECT_SCOPE="mindleaf" TARGET_BASE="/Volumes/TeraSSD/Projets_Dev/__Mindleaf" ;; + 3) + PROJECT_SCOPE="lab" + TARGET_BASE="/Volumes/TeraSSD/Labs" + ;; + 4) + PROJECT_SCOPE="archive" + TARGET_BASE="/Volumes/TeraSSD/Archives_Projets" + ;; *) echo "Choix invalide." exit 1 @@ -38,6 +58,24 @@ choose_target_base() { Linux) echo "Environnement détecté : NUC/Linux" TARGET_BASE="/srv/projects" + echo "Choisir le scope logique du projet :" + echo " 1) perso" + echo " 2) mindleaf" + echo " 3) lab" + echo " 4) archive" + printf "Votre choix [1/2/3/4] : " + read -r choice + + case "$choice" in + 1) PROJECT_SCOPE="perso" ;; + 2) PROJECT_SCOPE="mindleaf" ;; + 3) PROJECT_SCOPE="lab" ;; + 4) PROJECT_SCOPE="archive" ;; + *) + echo "Choix invalide." + exit 1 + ;; + esac ;; Darwin) choose_mac_target_base @@ -49,6 +87,30 @@ choose_target_base() { esac } +prompt_project_metadata() { + printf "Stack principale [à préciser] : " + read -r PROJECT_STACK + PROJECT_STACK="${PROJECT_STACK:-à préciser}" + + printf "État du projet [dev] : " + read -r PROJECT_STATE + PROJECT_STATE="${PROJECT_STATE:-dev}" +} + +register_project_in_conf() { + if [ ! -f "$PROJECTS_CONF" ]; then + echo "Erreur : fichier introuvable : $PROJECTS_CONF" >&2 + exit 1 + fi + + if grep -Eq "^${PROJECT_NAME}\|" "$PROJECTS_CONF"; then + echo "Erreur : le projet $PROJECT_NAME existe déjà dans _projects.conf" >&2 + exit 1 + fi + + printf "%s|%s|%s|%s\n" "$PROJECT_NAME" "$PROJECT_STACK" "$PROJECT_SCOPE" "$PROJECT_STATE" >> "$PROJECTS_CONF" +} + create_readme() { cat < "$PROJECT_PATH/README.md" # $PROJECT_NAME @@ -61,6 +123,7 @@ Projet initialisé avec l'environnement Lead_tech. - \`AGENTS.md\` : symlink vers \`CLAUDE.md\` - \`README.md\` : documentation projet - \`.gitignore\` : exclusions Git de base +- \`_projects.conf\` (Lead_tech) : registre logique des projets ## Commandes utiles @@ -111,10 +174,14 @@ tmp/ # AI tools .claude/ .codex/ + +# Agent compatibility file (symlink to CLAUDE.md) +AGENTS.md EOF } choose_target_base +prompt_project_metadata if [ ! -d "$TARGET_BASE" ]; then echo "Le dossier cible n'existe pas : $TARGET_BASE" @@ -139,8 +206,11 @@ gen-claude "$PROJECT_NAME" create_readme create_gitignore +register_project_in_conf + echo "" echo "Projet créé : $PROJECT_PATH" +echo "Projet enregistré dans : $PROJECTS_CONF" echo "" echo "Prochaines étapes :" echo " cd $PROJECT_PATH" diff --git a/scripts/resolve-project-path.sh b/scripts/resolve-project-path.sh new file mode 100755 index 0000000..148ab89 --- /dev/null +++ b/scripts/resolve-project-path.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +PROJECTS_CONF="$REPO_ROOT/_projects.conf" +OS="$(uname -s)" +PROJECT_NAME="${1:-}" + +usage() { + echo "Usage: resolve-project-path.sh " >&2 +} + +if [ -z "$PROJECT_NAME" ]; then + usage + exit 1 +fi + +if [ ! -f "$PROJECTS_CONF" ]; then + echo "Erreur : fichier introuvable : $PROJECTS_CONF" >&2 + exit 1 +fi + +resolve_base_path() { + local scope="$1" + + case "$OS" in + Linux) + case "$scope" in + perso|mindleaf|lab|archive) + echo "/srv/projects" + ;; + *) + echo "Erreur : scope inconnu sur Linux : $scope" >&2 + exit 1 + ;; + esac + ;; + Darwin) + case "$scope" in + perso) + echo "/Volumes/TeraSSD/Projets_Dev" + ;; + mindleaf) + echo "/Volumes/TeraSSD/Projets_Dev/__Mindleaf" + ;; + lab) + echo "/Volumes/TeraSSD/Labs" + ;; + archive) + echo "/Volumes/TeraSSD/Archives_Projets" + ;; + *) + echo "Erreur : scope inconnu sur macOS : $scope" >&2 + exit 1 + ;; + esac + ;; + *) + echo "Erreur : système non supporté : $OS" >&2 + exit 1 + ;; + esac +} + +while IFS='|' read -r name stack scope state; do + [[ -z "$name" || "$name" == \#* ]] && continue + + if [ "$name" = "$PROJECT_NAME" ]; then + BASE_PATH="$(resolve_base_path "$scope")" + echo "$BASE_PATH/$name" + exit 0 + fi +done < "$PROJECTS_CONF" + +echo "Erreur : projet introuvable dans _projects.conf : $PROJECT_NAME" >&2 +exit 1 \ No newline at end of file diff --git a/scripts/sync-ai-instructions.sh b/scripts/sync-ai-instructions.sh index 1c70eeb..796573c 100755 --- a/scripts/sync-ai-instructions.sh +++ b/scripts/sync-ai-instructions.sh @@ -9,39 +9,16 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SOURCE="$REPO_ROOT/_AI_INSTRUCTIONS.md" -PROJECTS_CONF="$REPO_ROOT/_projects.conf" # --- Détection machine --- OS="$(uname -s)" CHANGED=0 -# --- Construire la table markdown des projets --- -build_projects_table() { - local os="$1" - echo "| Projet | Stack | Localisation | État |" - echo "|---|---|---|---|" - while IFS='|' read -r nom stack path_nuc path_mac etat; do - # Ignorer lignes vides et commentaires - [[ -z "$nom" || "$nom" == \#* ]] && continue - if [ "$os" = "Darwin" ]; then - path="$path_mac" - else - path="$path_nuc" - fi - if [ -z "$path" ]; then - echo "| $nom | $stack | *non disponible sur cette machine* | $etat |" - else - echo "| $nom | $stack | \`$path\` | $etat |" - fi - done < "$PROJECTS_CONF" -} - generate_repo_claude() { local header="$1" local dest="$2" - local projects_table local tmp - projects_table="$(build_projects_table "$OS")" + tmp="$(mktemp)" mkdir -p "$(dirname "$dest")" @@ -49,14 +26,7 @@ generate_repo_claude() { { echo "$header" echo "" - # Remplacer {{PROJECTS_TABLE}} par la table générée - while IFS= read -r line; do - if [ "$line" = "{{PROJECTS_TABLE}}" ]; then - echo "$projects_table" - else - echo "$line" - fi - done < "$SOURCE" + cat "$SOURCE" } > "$tmp" if [ ! -f "$dest" ] || ! cmp -s "$tmp" "$dest"; then