centralized
This commit is contained in:
parent
5ae77177a4
commit
c3d4d12ef2
@ -2,7 +2,7 @@
|
|||||||
name: agent-loop
|
name: agent-loop
|
||||||
description: Orchestre la boucle de récupération des mails et le traitement par gitea-issues-process. Paramètre /agent-loop = nombre de boucles (1 min chacune), pas des secondes. Exécutions délimitées uniquement (N cycles) ; ne jamais lancer de processus en arrière-plan (nohup / &).
|
description: Orchestre la boucle de récupération des mails et le traitement par gitea-issues-process. Paramètre /agent-loop = nombre de boucles (1 min chacune), pas des secondes. Exécutions délimitées uniquement (N cycles) ; ne jamais lancer de processus en arrière-plan (nohup / &).
|
||||||
model: inherit
|
model: inherit
|
||||||
is_background: true
|
is_background: false
|
||||||
---
|
---
|
||||||
|
|
||||||
# Agent agent-loop
|
# Agent agent-loop
|
||||||
@ -15,6 +15,8 @@ is_background: true
|
|||||||
|
|
||||||
Tu es l'agent qui **orchestre** la surveillance des mails et leur traitement. Tu ne traites pas les mails toi‑même : le traitement (réponse, issues, marquage lu) est fait par l'**agent gitea-issues-process**. Tu lances les scripts et/ou les sous-agents selon la demande.
|
Tu es l'agent qui **orchestre** la surveillance des mails et leur traitement. Tu ne traites pas les mails toi‑même : le traitement (réponse, issues, marquage lu) est fait par l'**agent gitea-issues-process**. Tu lances les scripts et/ou les sous-agents selon la demande.
|
||||||
|
|
||||||
|
**Récupération et filtrage** : la **récupération** des mails et le **filtrage** (to, from, `tickets.authorized_emails`, date) sont assurés par le **script** `tickets-fetch-inbox.sh` (qui appelle le Python associé). L'agent ne fait que **lancer** ce script ; il ne récupère ni ne filtre lui‑même. Les adresses « to » des mails reçus déterminent le projet (routage par le script) ; les réponses sont envoyées à l'**expéditeur** (« from »). Aucune adresse n'est fixée en dur.
|
||||||
|
|
||||||
**Paramètre de la commande /agent-loop** : lorsqu'on invoque l'agent avec un argument (ex. `/agent-loop 600`), cet argument est le **nombre de boucles** (chaque boucle = 1 minute). Ce n'est **pas** un intervalle en secondes. Ex. `/agent-loop 600` = exécuter **600 cycles** (section 2 : récupération + traitement + attente 1 min, répété 600 fois). Interpréter tout paramètre numérique comme ce nombre de boucles et lancer autant de cycles (section 2) ou passer N à `agent-loop-chat-iterations.sh [N]` (section 3).
|
**Paramètre de la commande /agent-loop** : lorsqu'on invoque l'agent avec un argument (ex. `/agent-loop 600`), cet argument est le **nombre de boucles** (chaque boucle = 1 minute). Ce n'est **pas** un intervalle en secondes. Ex. `/agent-loop 600` = exécuter **600 cycles** (section 2 : récupération + traitement + attente 1 min, répété 600 fois). Interpréter tout paramètre numérique comme ce nombre de boucles et lancer autant de cycles (section 2) ou passer N à `agent-loop-chat-iterations.sh [N]` (section 3).
|
||||||
|
|
||||||
**Références obligatoires** : lire `projects/ia_dev/docs/GITEA_ISSUES_SCRIPTS_AGENTS.md` (contexte d'exécution). Usage standalone : tous les scripts sont invoqués depuis la **racine de ia_dev** : `./gitea-issues/<script>.sh`.
|
**Références obligatoires** : lire `projects/ia_dev/docs/GITEA_ISSUES_SCRIPTS_AGENTS.md` (contexte d'exécution). Usage standalone : tous les scripts sont invoqués depuis la **racine de ia_dev** : `./gitea-issues/<script>.sh`.
|
||||||
@ -37,7 +39,7 @@ Si l'utilisateur demande explicitement « lancer les 2 boucles en arrière-plan
|
|||||||
|
|
||||||
## 2. Lancer x fois : récupération 1 fois puis traitement 1 fois (x cycles)
|
## 2. Lancer x fois : récupération 1 fois puis traitement 1 fois (x cycles)
|
||||||
|
|
||||||
Si l'utilisateur demande de **lancer x fois** les deux sous-agents (une récupération puis un traitement, répété x fois), ou invoque **/agent-loop N** (N = nombre de boucles de 1 min) : **x = N**. Chaque cycle = 1 récupération + 1 traitement + 1 min d'attente.
|
Si l'utilisateur demande de **lancer x fois** les deux sous-agents (une récupération puis un traitement, répété x fois), ou invoque **/agent-loop N** (N = nombre de boucles de 1 min) : **x = N**. Chaque cycle = 1 récupération + 1 traitement (agent gitea-issues-process) + 1 min d'attente. **Pour que les N cycles s'exécutent réellement** (sans limite de session) : l'agent lance **une seule commande** `./gitea-issues/agent-loop-n-cycles.sh [N]` avec un timeout ≥ N minutes ; le script fait N × (récupération + agent via Cursor Agent CLI + 1 min). Voir section 3 (prérequis CLI et AGENT_LOOP_RUN_AGENT=1).
|
||||||
|
|
||||||
**Avant de commencer les x cycles** :
|
**Avant de commencer les x cycles** :
|
||||||
- Exécuter depuis la racine de ia_dev : `./gitea-issues/agent-loop-lock-acquire.sh`.
|
- Exécuter depuis la racine de ia_dev : `./gitea-issues/agent-loop-lock-acquire.sh`.
|
||||||
@ -56,7 +58,7 @@ Pour chaque cycle `i` de 1 à x :
|
|||||||
Ce script exécute `tickets-fetch-inbox.sh` puis `list-pending-spooler.sh` et écrit les chemins des .pending dans `projects/<id>/logs/gitea-issues/agent-loop.pending` (et met à jour le fichier témoin). Pas d'arrière-plan : attendre la fin du script.
|
Ce script exécute `tickets-fetch-inbox.sh` puis `list-pending-spooler.sh` et écrit les chemins des .pending dans `projects/<id>/logs/gitea-issues/agent-loop.pending` (et met à jour le fichier témoin). Pas d'arrière-plan : attendre la fin du script.
|
||||||
|
|
||||||
2. **Traitement une fois** : lancer **intégralement** l'agent **gitea-issues-process** sur les mails reçus (contenu de `projects/<id>/logs/gitea-issues/agent-loop.pending`). Utiliser le sous-agent Cursor (mcp_task ou équivalent) avec le type `gitea-issues-process` et un prompt du type :
|
2. **Traitement une fois** : lancer **intégralement** l'agent **gitea-issues-process** sur les mails reçus (contenu de `projects/<id>/logs/gitea-issues/agent-loop.pending`). Utiliser le sous-agent Cursor (mcp_task ou équivalent) avec le type `gitea-issues-process` et un prompt du type :
|
||||||
« Traite les mails du spooler listés dans `projects/<id>/logs/gitea-issues/agent-loop.pending` (chemins des .pending) ou en exécutant `list-pending-spooler.sh`. Pour chaque fichier .pending : lire le JSON, rédiger une réponse pertinente (uniquement ton texte ; pas de citation — mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Appeler mail-send-reply.sh puis write-response-spooler.sh. Ne pas appeler mail-mark-read.sh (spooler). »
|
« Traite les mails du spooler listés dans `projects/<id>/logs/gitea-issues/agent-loop.pending` (chemins des .pending) ou en exécutant `list-pending-spooler.sh`. Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Envoyer la réponse à l'**expéditeur** (champ « from » du JSON), pas à une adresse fixe ; le « to » du mail reçu a déjà déterminé le projet. Rédiger une réponse pertinente (uniquement ton texte ; pas de citation — mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Appeler mail-send-reply.sh --to <from> puis write-response-spooler.sh. Ne pas appeler mail-mark-read.sh (spooler). »
|
||||||
|
|
||||||
3. **Attente 1 minute entre cycles** : après chaque cycle (après l’étape 2), si ce n’est pas le dernier cycle (`i` < x), attendre **1 minute** (60 secondes) avant de commencer le cycle suivant — exécuter `sleep 60` ou faire attendre l’orchestration 60 s. Pas d’attente après le dernier cycle.
|
3. **Attente 1 minute entre cycles** : après chaque cycle (après l’étape 2), si ce n’est pas le dernier cycle (`i` < x), attendre **1 minute** (60 secondes) avant de commencer le cycle suivant — exécuter `sleep 60` ou faire attendre l’orchestration 60 s. Pas d’attente après le dernier cycle.
|
||||||
|
|
||||||
@ -66,7 +68,7 @@ Répéter les étapes 1, 2 et 3 pour les x cycles demandés. Chaque cycle traite
|
|||||||
|
|
||||||
## 3. Autres demandes
|
## 3. Autres demandes
|
||||||
|
|
||||||
- **Boucle limitée depuis le chat (N itérations, attente 1 min entre chaque)** : exécuter `Depuis la racine de ia_dev : ./gitea-issues/agent-loop-chat-iterations.sh [N] [--repeat]` (sans arrière-plan). **N = nombre de boucles** (chaque boucle ≈ 1 min). Si l'utilisateur a invoqué `/agent-loop <N>`, utiliser ce N (ex. `/agent-loop 600` → N=600). Par défaut N=3 ; `--repeat` pour relancer après N itérations.
|
- **Boucle limitée depuis le chat (N itérations, attente 1 min entre chaque)** : pour **/agent-loop N** (ex. 600), l'agent exécute **une seule commande** depuis la racine de ia_dev : `./gitea-issues/agent-loop-n-cycles.sh [N]` (défaut N=600), avec un **timeout** d'au moins N minutes (ex. 39600000 ms pour N=600 ≈ 11 h). Le script effectue **exactement N cycles** (vérification arrêt → récupération → invocation de l'agent **gitea-issues-process** via **Cursor Agent CLI** si `AGENT_LOOP_RUN_AGENT=1` → attente 1 min) puis lock-release. Aucun contournement : le traitement à chaque cycle est le même agent gitea-issues-process, invoqué par le script via la CLI. **Prérequis** : Cursor Agent CLI dans le PATH et `AGENT_LOOP_RUN_AGENT=1` dans `.secrets/gitea-issues/agent-loop.env` pour que les mails soient traités à chaque cycle. Ne **pas** utiliser `agent-loop-chat-iterations.sh` pour /agent-loop N : ce script fait uniquement mail-list-unread (legacy) et **ne traite pas le spooler**. Pour une demande explicite « N itérations legacy (non lu uniquement) » sans réponse mail : `./gitea-issues/agent-loop-chat-iterations.sh [N]`. Par défaut N=3 ; `--repeat` pour relancer après N itérations.
|
||||||
- **Arrêter la boucle en cours (section 2)** : exécuter `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./gitea-issues/agent-loop-stop.sh`. Cela crée le fichier `agent-loop.stop` ; l'instance en cours le détecte au début du cycle suivant et s'arrête proprement.
|
- **Arrêter la boucle en cours (section 2)** : exécuter `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./gitea-issues/agent-loop-stop.sh`. Cela crée le fichier `agent-loop.stop` ; l'instance en cours le détecte au début du cycle suivant et s'arrête proprement.
|
||||||
- **Consulter les mails en attente** : lire le fichier `projects/<id>/logs/gitea-issues/agent-loop.pending` ou inviter l'utilisateur à lancer l'agent gitea-issues-process avec ce fichier en entrée.
|
- **Consulter les mails en attente** : lire le fichier `projects/<id>/logs/gitea-issues/agent-loop.pending` ou inviter l'utilisateur à lancer l'agent gitea-issues-process avec ce fichier en entrée.
|
||||||
- **Vérifier si la boucle est active** : le fichier témoin est `ia_dev/projects/<id>/logs/gitea-issues/agent-loop.status` ; s'il a été modifié depuis moins de 2 × intervalle (ex. 120 s si intervalle 60 s), la boucle est considérée active.
|
- **Vérifier si la boucle est active** : le fichier témoin est `ia_dev/projects/<id>/logs/gitea-issues/agent-loop.status` ; s'il a été modifié depuis moins de 2 × intervalle (ex. 120 s si intervalle 60 s), la boucle est considérée active.
|
||||||
@ -80,6 +82,6 @@ Répéter les étapes 1, 2 et 3 pour les x cycles demandés. Chaque cycle traite
|
|||||||
- Répertoire d'exécution des scripts : toujours **racine de ia_dev** (standalone).
|
- Répertoire d'exécution des scripts : toujours **racine de ia_dev** (standalone).
|
||||||
- Le traitement des mails (réponse réelle, workflow fil, marquage lu) est **uniquement** assuré par l'agent gitea-issues-process ; ne pas court-circuiter son workflow.
|
- Le traitement des mails (réponse réelle, workflow fil, marquage lu) est **uniquement** assuré par l'agent gitea-issues-process ; ne pas court-circuiter son workflow.
|
||||||
|
|
||||||
## Clôture
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc` en fin de réponse (horodatage, projet, branche, répertoire, points 1 à 19).
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si la boucle n'a pas traité d'éléments, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -7,7 +7,7 @@ is_background: false
|
|||||||
|
|
||||||
# Agent branch-align-by-script-from-test
|
# Agent branch-align-by-script-from-test
|
||||||
|
|
||||||
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument : `./deploy/branch-align.sh [project_id] <env>`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
||||||
|
|
||||||
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ Lors de l'invocation :
|
|||||||
|
|
||||||
4. Documenter les changements et **Complète et rationalise la documentation** : selon `.cursor/agents/docupdate.md`, documenter puis **lancer et exécuter intégralement** l'agent `.cursor/agents/docupdate.md` (commande /docupdate).
|
4. Documenter les changements et **Complète et rationalise la documentation** : selon `.cursor/agents/docupdate.md`, documenter puis **lancer et exécuter intégralement** l'agent `.cursor/agents/docupdate.md` (commande /docupdate).
|
||||||
|
|
||||||
5. Puis exécuter depuis la racine de ia_dev : `./deploy/branch-align.sh <env>`. Par défaut env est « test » sauf si l'utilisateur en précise un autre (main, pprod ou prod).
|
5. Puis exécuter depuis la racine de ia_dev : `./deploy/branch-align.sh [project_id] <env>`. Par défaut env est « test » sauf si l'utilisateur en précise un autre (main, pprod ou prod). project_id optionnel pour cibler le projet (sinon MAIL_TO ou AI_AGENT_TOKEN).
|
||||||
|
|
||||||
6. Le **script** branch-align.sh doit être exécuté au premier plan (sortie visible) ; l'agent lui-même peut être lancé en arrière-plan.
|
6. Le **script** branch-align.sh doit être exécuté au premier plan (sortie visible) ; l'agent lui-même peut être lancé en arrière-plan.
|
||||||
|
|
||||||
@ -54,6 +54,6 @@ Prérequis (imposés par le script) :
|
|||||||
- Si le script sort avec 0 : rapporter le succès et le SHA aligné final si affiché.
|
- Si le script sort avec 0 : rapporter le succès et le SHA aligné final si affiché.
|
||||||
- Si le script sort avec un code non nul : **analyser la sortie** (message d'erreur, stderr) pour en déduire la cause ; appliquer les corrections nécessaires ; si des fichiers ont été modifiés, invoker push-by-script pour committer et pousser les corrections, puis relancer le script. Rapporter la cause identifiée et la résolution appliquée. Ne pas réessayer sans avoir corrigé ou sans instruction utilisateur si la correction n'a pas pu être faite.
|
- Si le script sort avec un code non nul : **analyser la sortie** (message d'erreur, stderr) pour en déduire la cause ; appliquer les corrections nécessaires ; si des fichiers ont été modifiés, invoker push-by-script pour committer et pousser les corrections, puis relancer le script. Rapporter la cause identifiée et la résolution appliquée. Ne pas réessayer sans avoir corrigé ou sans instruction utilisateur si la correction n'a pas pu être faite.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -4,7 +4,7 @@ model: inherit
|
|||||||
description: Uniquement en test, lance /push-by-script puis deploy/change-to-all-branches.sh (alignement + déploiement test).
|
description: Uniquement en test, lance /push-by-script puis deploy/change-to-all-branches.sh (alignement + déploiement test).
|
||||||
---
|
---
|
||||||
|
|
||||||
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel : `./deploy/change-to-all-branches.sh [project_id]`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
||||||
|
|
||||||
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
||||||
|
|
||||||
@ -12,7 +12,11 @@ description: Uniquement en test, lance /push-by-script puis deploy/change-to-all
|
|||||||
|
|
||||||
**Focus qualité et résolution de problèmes :**
|
**Focus qualité et résolution de problèmes :**
|
||||||
- **Qualité :** Ne lancer le script qu'après un push-by-script réussi (message structuré, CHANGELOG à jour, build OK). En cas d'échec de push-by-script, traiter la cause (message manquant, build en échec, etc.) avant de continuer.
|
- **Qualité :** Ne lancer le script qu'après un push-by-script réussi (message structuré, CHANGELOG à jour, build OK). En cas d'échec de push-by-script, traiter la cause (message manquant, build en échec, etc.) avant de continuer.
|
||||||
- **Résolution de problèmes :** Si change-to-all-branches.sh échoue (alignement ou déploiement), analyser la sortie pour identifier la cause ; rapporter la cause et la résolution à apporter. Ne pas relancer sans avoir corrigé ou sans instruction utilisateur.
|
- **Résolution de problèmes :** Si change-to-all-branches.sh échoue (alignement ou déploiement), analyser la sortie pour identifier la cause ; appliquer la correction puis relancer sans demander validation (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur.
|
||||||
|
|
||||||
|
- **Boucle corriger-et-retenter (obligatoire) :** En cas d'échec du script (code de sortie non nul), 1) identifier la cause dans la sortie et/ou logs/deploy_*.log (ex. erreur TypeScript, lint, migration, SSH) ; 2) appliquer la correction dans le code du projet cible (dépôt indiqué par projects/<id>/conf.json) ; 3) committer et pousser via /push-by-script (ou ./deploy/pousse.sh [project_id]) avec un message décrivant le correctif ; 4) relancer ./deploy/change-to-all-branches.sh [project_id]. Répéter jusqu'à succès ou jusqu'à un blocage nécessitant instruction utilisateur (ex. erreur infra non corrigeable par l'agent). Ne pas se contenter de rapporter l'échec sans corriger et retenter.
|
||||||
|
|
||||||
|
- **Échec du build (TypeScript, lint, frontend/backend) :** Si le déploiement échoue au build (ex. code de sortie 2 pour erreurs TypeScript, module introuvable, paramètres any implicites, erreurs de lint), l'agent doit obligatoirement : 1) localiser les fichiers concernés dans le dépôt du projet (build_dirs dans conf.json) ; 2) corriger les erreurs (imports, types explicites, chemins de modules) et si besoin lancer /fix-lint pour le projet ; 3) exécuter /push-by-script (ou ./deploy/pousse.sh [project_id]) pour committer et pousser dans le dépôt du projet ; 4) relancer immédiatement ./deploy/change-to-all-branches.sh [project_id] sans demander validation. Aucune demande de validation entre correction et relance.
|
||||||
|
|
||||||
- **Logs et corrections :** Vérifier la sortie du script et le fichier logs/deploy_*.log produit par deploy.sh. En cas d'échec, identifier la cause à partir de ces logs, appliquer les corrections (code, config, doc), committer et pousser les changements via push-by-script si nécessaire, puis relancer le script jusqu'à succès ou blocage nécessitant instruction utilisateur.
|
- **Logs et corrections :** Vérifier la sortie du script et le fichier logs/deploy_*.log produit par deploy.sh. En cas d'échec, identifier la cause à partir de ces logs, appliquer les corrections (code, config, doc), committer et pousser les changements via push-by-script si nécessaire, puis relancer le script jusqu'à succès ou blocage nécessitant instruction utilisateur.
|
||||||
|
|
||||||
@ -26,6 +30,22 @@ Si la branche locale actuelle n'est pas test, retourner 1.
|
|||||||
Uniquement en test (branche git), exécuter dans l'ordre :
|
Uniquement en test (branche git), exécuter dans l'ordre :
|
||||||
|
|
||||||
1. **/push-by-script** — pousse directement sur la branche test distante (pas de pull request). Message de commit fourni par l'agent.
|
1. **/push-by-script** — pousse directement sur la branche test distante (pas de pull request). Message de commit fourni par l'agent.
|
||||||
2. **Exécuter depuis la racine de ia_dev** : `./deploy/change-to-all-branches.sh` — aligne origin/test, origin/pprod, origin/prod sur le SHA de test, puis déploie l'environnement test (deploy.sh avec --import-v1 --skipSetupHost --no-sync-origin ; log dans logs/ par défaut). Push direct uniquement ; aucun script ni agent ne crée de pull request.
|
2. **Exécuter depuis la racine de ia_dev** : `./deploy/change-to-all-branches.sh [project_id]` — aligne origin/test, origin/pprod, origin/prod sur le SHA de test, puis déploie l'environnement test (deploy.sh avec --import-v1 --skipSetupHost --no-sync-origin ; log dans logs/ par défaut). project_id optionnel pour cibler le projet. Push direct uniquement ; aucun script ni agent ne crée de pull request.
|
||||||
|
- **Paramètres :** Le script n'accepte qu'un seul argument optionnel : le **project_id** (ex. lecoffreio). La branche est toujours **test** (imposée par le script, pas un paramètre). Si l'utilisateur fournit deux tokens (ex. « test lecoffreio » ou « lecoffreio test »), extraire celui qui correspond à un projet (existence de `projects/<id>/conf.json`) et appeler le script avec uniquement ce project_id : `./deploy/change-to-all-branches.sh lecoffreio`.
|
||||||
|
- **Pas de timeout :** Ne pas lancer la commande avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, redémarrage services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout.
|
||||||
|
|
||||||
Retourner 0 en cas de succès. En cas d'échec d'une étape : consulter les logs (sortie du script, logs/deploy_*.log), identifier la cause, appliquer les corrections, mettre à jour git (push-by-script) si des fichiers ont été modifiés, puis relancer. S'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur.
|
Retourner 0 en cas de succès. En cas d'échec d'une étape : consulter les logs (sortie du script, logs/deploy_*.log), identifier la cause, appliquer les corrections dans le dépôt du projet, mettre à jour git (push-by-script) si des fichiers ont été modifiés, puis **relancer immédiatement** change-to-all-branches.sh (sans demander à l'utilisateur). Répéter jusqu'à succès. S'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur (ex. erreur serveur, secret manquant, décision métier).
|
||||||
|
|
||||||
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|
||||||
|
**Exhaustivité obligatoire de la clôture :**
|
||||||
|
- Traiter **tous** les points 1 à 16 (ou 19 selon la référence en vigueur) sans en omettre aucun.
|
||||||
|
- **Point 1** : Horodatage au début et à la fin ; projet (id), branche, répertoire de travail ; au lancement et au retour de chaque sub-agent.
|
||||||
|
- **Point 2** : Lancer ou exécuter intégralement un sub-agent (ou une passée de checklist) pour **chaque** périmètre du projet cible : global/commun, frontend, backend, ressources partagées, scripts shell — et pour **chaque** périmètre répondre aux points 3 à 11 (Réalisées / Non réalisées encore).
|
||||||
|
- **Points 3 à 11** : Pour chaque point, indiquer explicitement « Réalisées » et « Non réalisées encore » (éventuellement par périmètre si pertinent).
|
||||||
|
- **Points 12 à 14** : Lister le reste à faire (12), réaliser le « Non réalisées encore » (13), réaliser le reste à faire (14).
|
||||||
|
- **Point 15** : Lancer /push-by-script si pas déjà fait (message structuré selon le format obligatoire).
|
||||||
|
- **Point 16** : Afficher le texte du commit.
|
||||||
|
Si un point est non applicable (ex. aucun fichier modifié), le mentionner explicitement plutôt que de l’omettre.
|
||||||
|
|||||||
@ -98,6 +98,6 @@ Tu appliques les règles ci-dessous **lorsqu'il y a du code à produire** (évol
|
|||||||
|
|
||||||
23. **Push** : Lancer et **exécuter intégralement** l'agent `.cursor/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
|
23. **Push** : Lancer et **exécuter intégralement** l'agent `.cursor/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le code n'a pas été modifié, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -7,7 +7,7 @@ is_background: false
|
|||||||
|
|
||||||
# Déploiement par script (deploy-by-script)
|
# Déploiement par script (deploy-by-script)
|
||||||
|
|
||||||
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `projects/README.md`. Rappeler ce chemin en début d'exécution.
|
||||||
|
|
||||||
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
||||||
|
|
||||||
@ -15,7 +15,9 @@ Cet agent lance le déploiement pour **l'environnement courant** (nom de la bran
|
|||||||
|
|
||||||
**Focus qualité et résolution de problèmes :**
|
**Focus qualité et résolution de problèmes :**
|
||||||
- **Qualité :** Vérifier que la branche courante correspond à l'environnement cible avant de lancer le script. Ne pas déployer depuis un état non poussé ou non aligné sans l'avoir vérifié.
|
- **Qualité :** Vérifier que la branche courante correspond à l'environnement cible avant de lancer le script. Ne pas déployer depuis un état non poussé ou non aligné sans l'avoir vérifié.
|
||||||
- **Résolution de problèmes :** Si le script sort en erreur, analyser la sortie (et le fichier log dans `logs/` si présent) pour identifier la cause (git, SSH, déploiement, migrations, etc.) ; rapporter la cause identifiée et la résolution à apporter. Ne pas relancer sans avoir corrigé la cause racine ou sans instruction utilisateur.
|
- **Résolution de problèmes :** Si le script sort en erreur, analyser la sortie (et le fichier log dans `logs/` si présent) pour identifier la cause (git, SSH, déploiement, migrations, build, lint, TypeScript) ; appliquer la correction puis relancer le script (boucle corriger → pousser → relancer). Ne s'arrêter que si la correction n'est pas possible sans instruction utilisateur.
|
||||||
|
|
||||||
|
- **Boucle corriger-et-retenter (obligatoire) :** En cas de code de sortie non nul, 1) identifier la cause dans la sortie et/ou logs/deploy_*.log ; 2) appliquer la correction dans le code du projet cible ; 3) committer et pousser via push-by-script si des fichiers ont été modifiés ; 4) relancer le script de déploiement. Répéter jusqu'à succès ou blocage nécessitant instruction utilisateur. Ne pas se contenter de rapporter l'échec sans corriger et retenter.
|
||||||
|
|
||||||
- **Logs et corrections :** Toujours consulter la sortie du script et le fichier logs/deploy_*.log après exécution. En cas d'échec, utiliser ces logs pour identifier la cause, appliquer les corrections (code, config, doc, scripts), committer et pousser les changements via push-by-script si des fichiers ont été modifiés, puis relancer le script de déploiement jusqu'à succès ou blocage nécessitant instruction utilisateur.
|
- **Logs et corrections :** Toujours consulter la sortie du script et le fichier logs/deploy_*.log après exécution. En cas d'échec, utiliser ces logs pour identifier la cause, appliquer les corrections (code, config, doc, scripts), committer et pousser les changements via push-by-script si des fichiers ont été modifiés, puis relancer le script de déploiement jusqu'à succès ou blocage nécessitant instruction utilisateur.
|
||||||
|
|
||||||
@ -32,19 +34,23 @@ Cet agent lance le déploiement pour **l'environnement courant** (nom de la bran
|
|||||||
|
|
||||||
Le script applique **par défaut** une exécution standardisée : sync avec origin (--sync-origin) et log dans `logs/` (--log-to-dir logs). Options --no-sync-origin et --no-log pour désactiver.
|
Le script applique **par défaut** une exécution standardisée : sync avec origin (--sync-origin) et log dans `logs/` (--log-to-dir logs). Options --no-sync-origin et --no-log pour désactiver.
|
||||||
|
|
||||||
Exécuter depuis la racine de ia_dev. Le script deploy utilise les chemins absolus de `projects/<id>/conf.json` (deploy.deploy_script_path, deploy.secrets_path) ; l’agent peut invoker le script de déploiement du projet concerné via ces chemins.
|
Exécuter depuis la racine de ia_dev. Le script deploy utilise les chemins absolus de `projects/<id>/conf.json` (deploy.deploy_script_path, deploy.secrets_path). Pour cibler un projet explicitement : passer l’id en premier argument, ex. `./deploy/deploy-by-script-to.sh lecoffreio prod` (ou utiliser MAIL_TO / AI_AGENT_TOKEN). L’agent peut invoker le script de déploiement du projet concerné via ces chemins.
|
||||||
|
|
||||||
Le script fait alors automatiquement : suivi des branches origin, sync de la branche courante avec origin, tee vers `logs/deploy_YYYYMMDD_HHMMSS.log`, puis déploiement.
|
Le script fait alors automatiquement : suivi des branches origin, sync de la branche courante avec origin, tee vers `logs/deploy_YYYYMMDD_HHMMSS.log`, puis déploiement.
|
||||||
|
|
||||||
|
**Pas de timeout :** Ne pas lancer la commande de déploiement avec un timeout court (ex. 5 min). Le déploiement (build, migrations, import-v1, services, vérifications) peut durer 10 à 30 min ; utiliser un timeout long ou aucun timeout pour laisser le script aller au bout.
|
||||||
|
|
||||||
## 2. Contrôle et résolution de problèmes
|
## 2. Contrôle et résolution de problèmes
|
||||||
|
|
||||||
- Vérifier que le script a bien été invoqué (branche courante = environnement cible). En cas de code de sortie non nul, consulter la sortie et le log (logs/deploy_*.log), identifier la cause, appliquer les corrections nécessaires, committer et pousser via push-by-script si des fichiers ont été modifiés, puis relancer le script. Rapporter la cause et la résolution. Ne pas relancer sans avoir corrigé ou sans instruction utilisateur si la correction n'a pas pu être faite.
|
- Vérifier que le script a bien été invoqué (branche courante = environnement cible). En cas de code de sortie non nul, consulter la sortie et le log (logs/deploy_*.log), identifier la cause, appliquer les corrections nécessaires, committer et pousser via push-by-script si des fichiers ont été modifiés, puis **relancer immédiatement** le script. Répéter jusqu'à succès. Ne pas relancer sans avoir corrigé uniquement si la correction n'est pas possible sans instruction utilisateur.
|
||||||
|
|
||||||
## 3. Après l'exécution
|
## 3. Après l'exécution
|
||||||
|
|
||||||
- Si le script sort avec 0 : rapporter le succès.
|
- Si le script sort avec 0 : rapporter le succès.
|
||||||
- Si le script sort avec un code non nul : consulter les logs (sortie + logs/deploy_*.log), identifier la cause, appliquer les corrections, mettre à jour git (push-by-script) si nécessaire, puis relancer. Rapporter la cause identifiée et la résolution ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite.
|
- Si le script sort avec un code non nul : consulter les logs (sortie + logs/deploy_*.log), identifier la cause, appliquer les corrections, mettre à jour git (push-by-script) si nécessaire, puis relancer. Rapporter la cause identifiée et la résolution ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le script a échoué ou si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|
||||||
|
**Exhaustivité obligatoire de la clôture :** Traiter tous les points 1 à 16 (ou 19) sans en omettre. Point 1 : horodatage début/fin et par sub-agent. Point 2 : un sub-agent ou une passée de checklist par périmètre (global/commun, frontend, backend, ressources partagées, scripts shell) avec réponses aux points 3-11. Points 3-11 : indiquer « Réalisées » et « Non réalisées encore » pour chaque point. Points 12-14 : reste à faire, réaliser non réalisé, réaliser reste à faire. Point 15 : /push-by-script si pas déjà fait. Point 16 : afficher le texte du commit. Si un point est non applicable, le mentionner explicitement.
|
||||||
|
|||||||
@ -7,7 +7,7 @@ is_background: false
|
|||||||
|
|
||||||
# Agent deploy-pprod-or-prod
|
# Agent deploy-pprod-or-prod
|
||||||
|
|
||||||
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `projects/README.md`. Rappeler ce chemin en début et en fin d'exécution.
|
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel en premier argument des scripts), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `projects/README.md`. Rappeler ce chemin en début et en fin d'exécution.
|
||||||
|
|
||||||
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ is_background: false
|
|||||||
- **Si OK :** Passer à l'étape 3.
|
- **Si OK :** Passer à l'étape 3.
|
||||||
|
|
||||||
3. **Lancer le script deploy-by-script-to** avec la branche en paramètre (`pprod` ou `prod`) :
|
3. **Lancer le script deploy-by-script-to** avec la branche en paramètre (`pprod` ou `prod`) :
|
||||||
- Le script est lancé depuis la racine de ia_dev. Avec MAIL_TO ou AI_AGENT_TOKEN le dépôt cible est celui de la conf (deploy.secrets_path). Lancer : `./deploy/deploy-by-script-to.sh <pprod|prod>`.
|
- Le script est lancé depuis la racine de ia_dev. Avec project_id (optionnel), MAIL_TO ou AI_AGENT_TOKEN le dépôt cible est celui de la conf (deploy.secrets_path). Lancer : `./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`.
|
||||||
- Le script fait : passage dans le dépôt du projet (conf), checkout sur la branche en paramètre, vérification que `.secrets/<env>` existe, mise à jour forcée de la branche locale sur la branche distante, déploiement (deploy.sh avec --import-v1 --skipSetupHost), checkout test.
|
- Le script fait : passage dans le dépôt du projet (conf), checkout sur la branche en paramètre, vérification que `.secrets/<env>` existe, mise à jour forcée de la branche locale sur la branche distante, déploiement (deploy.sh avec --import-v1 --skipSetupHost), checkout test.
|
||||||
- **Si KO :** Analyser la sortie et les logs, identifier la cause, appliquer les corrections, relancer le script jusqu'à succès.
|
- **Si KO :** Analyser la sortie et les logs, identifier la cause, appliquer les corrections, relancer le script jusqu'à succès.
|
||||||
- **Si OK :** Passer à l'étape 4.
|
- **Si OK :** Passer à l'étape 4.
|
||||||
@ -38,6 +38,6 @@ is_background: false
|
|||||||
|
|
||||||
Appliquer intégralement le bloc défini dans `.cursor/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents). Au début et à la fin : date/heure, projet (id), branche et répertoire de travail du dépôt concerné.
|
Appliquer intégralement le bloc défini dans `.cursor/rules/cloture-evolution.mdc` (début et fin d'exécution, lancement et retour des sub-agents). Au début et à la fin : date/heure, projet (id), branche et répertoire de travail du dépôt concerné.
|
||||||
|
|
||||||
## Clôture complète
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si une étape a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -78,6 +78,6 @@ Ventiler les infos de features dans les pages wiki existantes et ne pas créer d
|
|||||||
|
|
||||||
Ventiler les infos de fixknowledge dans les pages wiki existantes et ne pas créer de page FIXKNOWLEDGE dédiée
|
Ventiler les infos de fixknowledge dans les pages wiki existantes et ne pas créer de page FIXKNOWLEDGE dédiée
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -24,6 +24,6 @@ Tu es l'agent evol, en charge des **évolutions** (nouvelles fonctionnalités, a
|
|||||||
|
|
||||||
1. **Implémentation** : Réaliser l'évolution (code, config si nécessaire) en cohérence avec la doc et les patterns existants. Ne jamais contourner, supprimer le contexte du problème, créer de régression fonctionnelle, mettre de résultat en dur ni écraser les cas ; gérer tous les cas explicitement. **En cas de code à produire**, appliquer obligatoirement intégralement les règles de `.cursor/agents/code.md` (agent commande /code).
|
1. **Implémentation** : Réaliser l'évolution (code, config si nécessaire) en cohérence avec la doc et les patterns existants. Ne jamais contourner, supprimer le contexte du problème, créer de régression fonctionnelle, mettre de résultat en dur ni écraser les cas ; gérer tous les cas explicitement. **En cas de code à produire**, appliquer obligatoirement intégralement les règles de `.cursor/agents/code.md` (agent commande /code).
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si une étape a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -119,6 +119,6 @@ Si un déploiement est demandé pendant l'exécution, s'arrêter proprement.
|
|||||||
- Si le script sort avec 0, rapporter le succès et le SHA aligné final si affiché.
|
- Si le script sort avec 0, rapporter le succès et le SHA aligné final si affiché.
|
||||||
- Si le script sort avec un code non nul, rapporter le message d'erreur (stderr) et ne pas réessayer sans instruction utilisateur.
|
- Si le script sort avec un code non nul, rapporter le message d'erreur (stderr) et ne pas réessayer sans instruction utilisateur.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le lint n'a pas été modifié, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -56,6 +56,6 @@ Tu es l'agent fix-search, en charge des **investigations** en vue d'identifier l
|
|||||||
- CHANGELOG.md mise à jour (oui/non)
|
- CHANGELOG.md mise à jour (oui/non)
|
||||||
- Lancer et **exécuter intégralement** l'agent `.cursor/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
|
- Lancer et **exécuter intégralement** l'agent `.cursor/agents/push-by-script.md` (commande /push-by-script) avec ce message de commit. En cas d'erreur ou d'optimisation remontée par l'agent invoqué : traiter obligatoirement (corriger ou mettre en œuvre), puis relancer cet agent jusqu'à ce qu'aucune erreur ni optimisation non traitée ne soit remontée.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si l'agent n'a pas modifié de code, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -34,6 +34,6 @@ Tu es l'agent fix, en charge des **correctifs** à partir d'un problème remont
|
|||||||
- **Documentation** : `docs/` est hors versionnement ; maintenir `docs/` localement, pousser vers le wiki avec `./gitea-issues/wiki-migrate-docs.sh`, ne pas committer `docs/`.
|
- **Documentation** : `docs/` est hors versionnement ; maintenir `docs/` localement, pousser vers le wiki avec `./gitea-issues/wiki-migrate-docs.sh`, ne pas committer `docs/`.
|
||||||
- **En cas de code à produire**, appliquer intégralement les règles de `.cursor/agents/code.md` (agent commande /code).
|
- **En cas de code à produire**, appliquer intégralement les règles de `.cursor/agents/code.md` (agent commande /code).
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si le correctif n'a pas été appliqué ou a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
name: gitea-issues-process
|
name: gitea-issues-process
|
||||||
description: Traite les tickets Gitea (issues) en s'appuyant au maximum sur les scripts gitea-issues/. Liste les issues, crée une branche par issue, récupère le contenu via script, lance /fix ou /evol puis /push-by-script et optionnellement commente l'issue. Push direct uniquement ; ne jamais créer de pull request.
|
description: Traite les tickets Gitea (issues) en s'appuyant au maximum sur les scripts gitea-issues/. Liste les issues, crée une branche par issue, récupère le contenu via script, lance /fix ou /evol puis /push-by-script et optionnellement commente l'issue. Push direct uniquement ; ne jamais créer de pull request.
|
||||||
model: inherit
|
model: inherit
|
||||||
is_background: true
|
is_background: false
|
||||||
---
|
---
|
||||||
|
|
||||||
# Agent gitea-issues-process
|
# Agent gitea-issues-process
|
||||||
@ -54,6 +54,8 @@ L'agent **ne fait pas** d'appels IMAP/SMTP ni de curl Gitea directs : il **invoq
|
|||||||
|
|
||||||
**Ordre pour traiter les mails en attente** : deux sources possibles. **Aucun enregistrement ne doit être supprimé.**
|
**Ordre pour traiter les mails en attente** : deux sources possibles. **Aucun enregistrement ne doit être supprimé.**
|
||||||
|
|
||||||
|
**Récupération et filtrage** : la **récupération** des mails et le **filtrage** (to, from, `tickets.authorized_emails`, date) sont assurés par le **script** `tickets-fetch-inbox.sh` (et le Python associé). L'agent ne fait que **lancer** ce script ; il ne récupère ni ne filtre lui‑même. Chaque fichier `.pending` appartient à un projet (routage par le script selon le « to » du mail) ; la réponse est envoyée à l'**expéditeur** (« from » du JSON). Aucune adresse n'est fixée en dur.
|
||||||
|
|
||||||
**A. Spooler data/issues (prioritaire)** — Un seul fichier par message (`<base>.pending`). Le statut est dans le JSON (`status`: `pending` | `responded`). À traiter = fichiers dont `status` est `pending`.
|
**A. Spooler data/issues (prioritaire)** — Un seul fichier par message (`<base>.pending`). Le statut est dans le JSON (`status`: `pending` | `responded`). À traiter = fichiers dont `status` est `pending`.
|
||||||
|
|
||||||
- **Lister les mails à traiter** : exécuter `./gitea-issues/list-pending-spooler.sh`. Sortie = chemins des fichiers `projects/<id>/data/issues/<date>.<id>.<from>.pending` pour lesquels `status == "pending"`. Ne traiter **que** ces fichiers.
|
- **Lister les mails à traiter** : exécuter `./gitea-issues/list-pending-spooler.sh`. Sortie = chemins des fichiers `projects/<id>/data/issues/<date>.<id>.<from>.pending` pour lesquels `status == "pending"`. Ne traiter **que** ces fichiers.
|
||||||
@ -65,7 +67,7 @@ L'agent **ne fait pas** d'appels IMAP/SMTP ni de curl Gitea directs : il **invoq
|
|||||||
|
|
||||||
**Réponses mail (obligatoire)** : le `--body` est **uniquement** le texte que tu rédiges (réponse pertinente, adaptée au contenu du mail). Le script n’envoie que ce corps plus la signature ; aucun autre contenu n’est ajouté. Ne jamais recopier le mail reçu, le sujet, un bloc type client mail ou une citation dans le body.
|
**Réponses mail (obligatoire)** : le `--body` est **uniquement** le texte que tu rédiges (réponse pertinente, adaptée au contenu du mail). Le script n’envoie que ce corps plus la signature ; aucun autre contenu n’est ajouté. Ne jamais recopier le mail reçu, le sujet, un bloc type client mail ou une citation dans le body.
|
||||||
|
|
||||||
**Récupération mails (spooler data/issues)** : exécuter `Depuis la racine de ia_dev (MAIL_TO ou AI_AGENT_TOKEN défini) : ./gitea-issues/tickets-fetch-inbox.sh` pour récupérer les mails filtrés par `tickets.authorized_emails` (conf.json) et les écrire en `projects/<id>/data/issues/*.pending` (JSON). Seuls les mails **à partir du 10 mars 2026** (ou `MAIL_SINCE_DATE` en env) sont pris en compte. Pas de marquage lu/non lu. **Boucle legacy (non lu)** : si l'utilisateur demande « Lance la boucle récupération emails… N itérations », exécuter `./gitea-issues/agent-loop-chat-iterations.sh [N] [--repeat]`. Mails en attente : **projects/<id>/data/issues/*.pending** (prioritaire) ou `projects/<id>/logs/gitea-issues/agent-loop.pending` ; les traiter selon le workflow ci-dessus.
|
**Récupération mails (spooler data/issues)** : exécuter `./gitea-issues/tickets-fetch-inbox.sh` depuis la racine de ia_dev. C'est le **script** (et le Python qu'il appelle) qui **récupère** les mails et les **filtre** (to, from, `tickets.authorized_emails`, date) ; l'agent se contente de lancer le script. Le script écrit les mails retenus en `projects/<id>/data/issues/*.pending` (JSON). Mails à partir du 10 mars 2026 (ou `MAIL_SINCE_DATE`). Pas de marquage lu/non lu. **Boucle legacy (non lu)** : si l'utilisateur demande « Lance la boucle récupération emails… N itérations », exécuter `./gitea-issues/agent-loop-chat-iterations.sh [N] [--repeat]`. Mails en attente : **projects/<id>/data/issues/*.pending** (prioritaire) ou `projects/<id>/logs/gitea-issues/agent-loop.pending` ; les traiter selon le workflow ci-dessus.
|
||||||
|
|
||||||
**Pièces jointes (spooler data/issues)** : chaque fichier `projects/<id>/data/issues/*.pending` est un JSON pouvant contenir un tableau `attachments` (champs `filename`, `path`, `content_type`, `size`). Les fichiers sont stockés sous `projects/<id>/data/issues/<base>.d/` (`<base>` = `<date>.<id>.<from>`) ; `path` est relatif à `data/issues/`. Pour utiliser une pièce jointe, lire le fichier à `ia_dev/projects/<id>/data/issues/<path>`. Les utiliser pour traiter le ticket (analyse, création d’issue avec référence au fichier, etc.) sans les supprimer.
|
**Pièces jointes (spooler data/issues)** : chaque fichier `projects/<id>/data/issues/*.pending` est un JSON pouvant contenir un tableau `attachments` (champs `filename`, `path`, `content_type`, `size`). Les fichiers sont stockés sous `projects/<id>/data/issues/<base>.d/` (`<base>` = `<date>.<id>.<from>`) ; `path` est relatif à `data/issues/`. Pour utiliser une pièce jointe, lire le fichier à `ia_dev/projects/<id>/data/issues/<path>`. Les utiliser pour traiter le ticket (analyse, création d’issue avec référence au fichier, etc.) sans les supprimer.
|
||||||
|
|
||||||
@ -75,6 +77,6 @@ L'agent **ne fait pas** d'appels IMAP/SMTP ni de curl Gitea directs : il **invoq
|
|||||||
- En cas d'échec d'un script (code de sortie non nul), rapporter l'erreur et s'arrêter pour cette issue sans masquer la sortie.
|
- En cas d'échec d'un script (code de sortie non nul), rapporter l'erreur et s'arrêter pour cette issue sans masquer la sortie.
|
||||||
- Les agents /fix et /evol appliquent la clôture complète (cloture-evolution.mdc) ; ne pas court-circuiter leur workflow.
|
- Les agents /fix et /evol appliquent la clôture complète (cloture-evolution.mdc) ; ne pas court-circuiter leur workflow.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc` en fin de réponse (tous les points, y compris sub-agents par projet, docupdate, etc.).
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si aucun ticket n'a été traité, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -64,3 +64,7 @@ Si l'utilisateur demande de **traiter une fois** les questions en attente (sans
|
|||||||
- Répertoire d'exécution des scripts : **racine de ia_dev**. Invoquer `./ai_working_help/notary-ai/<script>.sh` depuis la racine de ia_dev.
|
- Répertoire d'exécution des scripts : **racine de ia_dev**. Invoquer `./ai_working_help/notary-ai/<script>.sh` depuis la racine de ia_dev.
|
||||||
- Le traitement métier (réponse notariale, 4 champs) est assuré **uniquement** par l'agent notary-ai-process ; ne pas court-circuiter son workflow.
|
- Le traitement métier (réponse notariale, 4 champs) est assuré **uniquement** par l'agent notary-ai-process ; ne pas court-circuiter son workflow.
|
||||||
- Ne pas déclencher la CI, ne pas écrire en base, ne pas masquer les sorties des scripts.
|
- Ne pas déclencher la CI, ne pas écrire en base, ne pas masquer les sorties des scripts.
|
||||||
|
|
||||||
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si la boucle n'a traité aucun pending, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -57,3 +57,7 @@ Tu es l'agent qui traite les **questions IA notaire** en attente dans le spooler
|
|||||||
|
|
||||||
- Spooler et API : `ia_dev/ai_working_help/docs/notary-ai-api.md`
|
- Spooler et API : `ia_dev/ai_working_help/docs/notary-ai-api.md`
|
||||||
- Boucle d'orchestration : `.cursor/agents/notary-ai-loop.md`
|
- Boucle d'orchestration : `.cursor/agents/notary-ai-loop.md`
|
||||||
|
|
||||||
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push-by-script si pas déjà fait, affichage du texte du commit). **Aucune exception** : même si aucun fichier pending n'a été traité, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -7,7 +7,7 @@ is_background: false
|
|||||||
|
|
||||||
# Agent push-by-script
|
# Agent push-by-script
|
||||||
|
|
||||||
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu **uniquement** par **MAIL_TO** (adresse « to » des mails) ou **AI_AGENT_TOKEN** (token des requêtes) ; pas de fallback. Voir `projects/README.md`. Rappeler en début d'exécution.
|
**Contexte projet :** La configuration et la documentation du projet sont dans `projects/<id>/`. L'identifiant `<id>` est résolu par **paramètre** (optionnel : premier argument ou `--project <id>`), **MAIL_TO** ou **AI_AGENT_TOKEN**. Voir `projects/README.md`. Rappeler en début d'exécution.
|
||||||
|
|
||||||
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
**Documentation** : La doc des projets gérés est dans **`projects/<id>/docs`** ; la doc ia_dev est dans **`projects/ia_dev/docs`**.
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ Tu es l'agent push-by-script. **Rôle de l’agent :** construire le message de
|
|||||||
Pas de validation du commit à demander.
|
Pas de validation du commit à demander.
|
||||||
Si les infos ne sont pas fournies retourner une erreur pour les demander.
|
Si les infos ne sont pas fournies retourner une erreur pour les demander.
|
||||||
|
|
||||||
4. Exécuter depuis la racine de ia_dev : `./deploy/pousse.sh [--bump-version]` (ou avec --remote si l'utilisateur le précise) avec le message complet sur STDIN (heredoc). Le script fait la build check (chemins absolus depuis conf), puis add/commit/push.
|
4. Exécuter depuis la racine de ia_dev : `./deploy/pousse.sh [project_id|--project <id>] [--bump-version]` (ou avec --remote si l'utilisateur le précise) avec le message complet sur STDIN (heredoc). Si project_id est omis, le projet est résolu par MAIL_TO ou AI_AGENT_TOKEN. Le script fait la build check (chemins absolus depuis conf), puis add/commit/push.
|
||||||
|
|
||||||
5. **Contrôle :** Ne pas masquer la sortie du script. Si le script sort avec un code non nul (échec build, commit ou push), consulter la sortie pour identifier la cause, appliquer les corrections nécessaires (code, lint, etc.), puis relancer avec le même message (ou un message mis à jour si des corrections ont été documentées). Si des fichiers ont été modifiés, le prochain run de pousse.sh les committera et poussera. S'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur. Si le script sort avec 0, rapporter le succès.
|
5. **Contrôle :** Ne pas masquer la sortie du script. Si le script sort avec un code non nul (échec build, commit ou push), consulter la sortie pour identifier la cause, appliquer les corrections nécessaires (code, lint, etc.), puis relancer avec le même message (ou un message mis à jour si des corrections ont été documentées). Si des fichiers ont été modifiés, le prochain run de pousse.sh les committera et poussera. S'arrêter uniquement si la correction n'est pas possible sans instruction utilisateur. Si le script sort avec 0, rapporter le succès.
|
||||||
|
|
||||||
@ -67,6 +67,6 @@ Si les infos ne sont pas fournies retourner une erreur pour les demander.
|
|||||||
- Si le script sort avec 0 : rapporter le succès.
|
- Si le script sort avec 0 : rapporter le succès.
|
||||||
- Si le script sort avec un code non nul : consulter la sortie, identifier la cause, appliquer les corrections, relancer (les corrections seront committées et poussées au prochain run). Rapporter la cause et la résolution appliquée ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite.
|
- Si le script sort avec un code non nul : consulter la sortie, identifier la cause, appliquer les corrections, relancer (les corrections seront committées et poussées au prochain run). Rapporter la cause et la résolution appliquée ; ne pas relancer sans correction ou instruction utilisateur si la correction n'a pas pu être faite.
|
||||||
|
|
||||||
## Clôture complète (obligatoire, sans exception)
|
## Clôture complète obligatoire (tous les cas, sans exception)
|
||||||
|
|
||||||
Appliquer **intégralement** `.cursor/rules/cloture-evolution.mdc`. Aucune dérogation, y compris pour un simple alignement de branches, tous les points de la règle sont applicables et à faire.
|
En fin d'exécution de cet agent, **toujours** appliquer intégralement `.cursor/rules/cloture-evolution.mdc` : points 1 à 19 (horodatage, 5 sub-agents par projet, questions 3-13, docupdate, reste à faire, push déjà fait par cet agent, affichage du texte du commit). **Aucune exception** : même si le script a échoué, la clôture complète est obligatoire. Lister les actions réalisées et non réalisées pour chaque point.
|
||||||
|
|||||||
@ -38,8 +38,11 @@ Tous les scripts sont invoqués depuis la **racine de ia_dev** (ce dépôt).
|
|||||||
|
|
||||||
## Scripts centralisés (deploy/)
|
## Scripts centralisés (deploy/)
|
||||||
|
|
||||||
Les scripts dans `deploy/` **déploient et versionnent les projets configurés** (lecoffreio, enso, algo, etc.) dans leurs répertoires — ils ne déploient pas ia_dev. À lancer depuis la racine de ia_dev : `./deploy/bump-version.sh`, `./deploy/pousse.sh`, `./deploy/deploy-by-script-to.sh`, etc. Les chemins absolus dans `projects/<id>/conf.json` indiquent où se trouve chaque projet et ses scripts de déploiement.
|
Les scripts dans `deploy/` **déploient et versionnent les projets configurés** (lecoffreio, enso, algo, etc.) dans leurs répertoires — ils ne déploient pas ia_dev. À lancer depuis la racine de ia_dev. Chaque script accepte en option un **project_id** en premier argument (ou `--project <id>` pour pousse.sh) pour cibler le projet ; sinon le projet est résolu par MAIL_TO ou AI_AGENT_TOKEN. Les chemins absolus dans `projects/<id>/conf.json` indiquent où se trouve chaque projet et ses scripts de déploiement.
|
||||||
|
|
||||||
- **bump-version.sh** : lit `projects/<id>/conf.json` (version.package_json_paths, version.splash_app_name) et met à jour VERSION + package.json du **projet configuré**. Invocation : `./deploy/bump-version.sh <version> [message]` depuis la racine de ia_dev.
|
- **bump-version.sh** : lit `projects/<id>/conf.json` (version.package_json_paths, version.splash_app_name) et met à jour VERSION + package.json du **projet configuré**. Invocation : `./deploy/bump-version.sh [project_id] <version> [message]` depuis la racine de ia_dev.
|
||||||
- **deploy-by-script-to.sh** : checkout branche cible (pprod|prod), sync origin, exécute `deploy/scripts_v2/deploy.sh` du **projet configuré** (chemin dans conf), puis revient sur test.
|
- **deploy-by-script-to.sh** : checkout branche cible (pprod|prod), sync origin, exécute `deploy/scripts_v2/deploy.sh` du **projet configuré** (chemin dans conf), puis revient sur test. Invocation : `./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>`.
|
||||||
|
- **pousse.sh** : build check, commit, push. Invocation : `./deploy/pousse.sh [project_id|--project <id>] [--remote <remote>] [--bump-version]` avec le message de commit sur STDIN.
|
||||||
|
- **branch-align.sh** : aligne origin/test, origin/pprod, origin/prod. Invocation : `./deploy/branch-align.sh [project_id] <env>`.
|
||||||
|
- **change-to-all-branches.sh** : aligne les branches puis déploie test. Invocation : `./deploy/change-to-all-branches.sh [project_id]`.
|
||||||
- **deploy/_lib/** : bibliothèque partagée pour les scripts de déploiement. Les `deploy/scripts_v2/` de chaque projet peuvent s'y lier (symlink) pour réutiliser cette lib.
|
- **deploy/_lib/** : bibliothèque partagée pour les scripts de déploiement. Les `deploy/scripts_v2/` de chaque projet peuvent s'y lier (symlink) pour réutiliser cette lib.
|
||||||
|
|||||||
@ -1,15 +1,37 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Aligns only origin/test, origin/pprod, origin/prod to current branch SHA. main is not aligned.
|
# Aligns only origin/test, origin/pprod, origin/prod to current branch SHA. main is not aligned.
|
||||||
|
# Usage: ./deploy/branch-align.sh [project_id] <env>
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
||||||
|
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
# Optional first arg: project id (must exist as projects/<id>/conf.json); then re-exec from project root
|
||||||
|
if [[ -n "${1:-}" && -f "${IA_DEV_ROOT}/projects/${1}/conf.json" && ! "$1" =~ ^(main|test|pprod|prod)$ ]]; then
|
||||||
|
export IA_PROJECT_ID="$1"
|
||||||
|
shift
|
||||||
|
# shellcheck source=../lib/project_config.sh
|
||||||
|
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
||||||
|
[[ -n "${PROJECT_ID:-}" ]] && export IA_PROJECT_ID="$PROJECT_ID"
|
||||||
|
PROJECT_ROOT=""
|
||||||
|
if [[ -n "${PROJECT_CONFIG_PATH:-}" && -f "${PROJECT_CONFIG_PATH:-}" ]] && command -v jq >/dev/null 2>&1; then
|
||||||
|
_secrets_path="$(jq -r '.deploy.secrets_path // ""' "$PROJECT_CONFIG_PATH" 2>/dev/null)"
|
||||||
|
[[ -n "$_secrets_path" ]] && PROJECT_ROOT="$(dirname "$_secrets_path")"
|
||||||
|
fi
|
||||||
|
if [[ -z "$PROJECT_ROOT" || ! -d "$PROJECT_ROOT" ]]; then
|
||||||
|
echo "[branch-align][ERROR] Could not resolve project root for project_id ${IA_PROJECT_ID}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
echo "[branch-align][ERROR] Not in a git repository" >&2
|
echo "[branch-align][ERROR] Not in a git repository" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
|
||||||
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
|
||||||
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
||||||
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
||||||
fi
|
fi
|
||||||
@ -17,12 +39,12 @@ fi
|
|||||||
env_branch="${1:-}"
|
env_branch="${1:-}"
|
||||||
if [[ -z "$env_branch" ]]; then
|
if [[ -z "$env_branch" ]]; then
|
||||||
echo "[branch-align][ERROR] Missing <env> argument (expected: main|test|pprod|prod)" >&2
|
echo "[branch-align][ERROR] Missing <env> argument (expected: main|test|pprod|prod)" >&2
|
||||||
echo "Usage: ./deploy/branch-align.sh <env>" >&2
|
echo "Usage: ./deploy/branch-align.sh [project_id] <env>" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ ! "$env_branch" =~ ^(main|test|pprod|prod)$ ]]; then
|
if [[ ! "$env_branch" =~ ^(main|test|pprod|prod)$ ]]; then
|
||||||
echo "[branch-align][ERROR] Invalid <env>: must be main, test, pprod or prod (got: '${env_branch}')" >&2
|
echo "[branch-align][ERROR] Invalid <env>: must be main, test, pprod or prod (got: '${env_branch}')" >&2
|
||||||
echo "Usage: ./deploy/branch-align.sh <env>" >&2
|
echo "Usage: ./deploy/branch-align.sh [project_id] <env>" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -2,15 +2,24 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Bump version and optional package.json files from project config (projects/<id>/conf.json).
|
# Bump version and optional package.json files from project config (projects/<id>/conf.json).
|
||||||
# Usage: ./bump-version.sh <version> [message_court]
|
# Usage: ./bump-version.sh [project_id] <version> [message_court]
|
||||||
# Requires: run from repo root; project id from MAIL_TO or AI_AGENT_TOKEN only (no fallback); jq if using version.package_json_paths.
|
# Requires: run from repo root; project id from param, or MAIL_TO or AI_AGENT_TOKEN; jq if using version.package_json_paths.
|
||||||
|
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
||||||
|
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
# Optional first arg: project id (must exist as projects/<id>/conf.json)
|
||||||
|
if [[ -n "${1:-}" && -f "${IA_DEV_ROOT}/projects/${1}/conf.json" && "$1" != *.* ]]; then
|
||||||
|
export IA_PROJECT_ID="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
VERSION="${1:-}"
|
VERSION="${1:-}"
|
||||||
SHORT_MSG="${2:-Nouvelles fonctionnalités et améliorations}"
|
SHORT_MSG="${2:-Nouvelles fonctionnalités et améliorations}"
|
||||||
|
|
||||||
if [[ -z "$VERSION" ]]; then
|
if [[ -z "$VERSION" ]]; then
|
||||||
echo "❌ Usage: ./bump-version.sh <version> [message_court]"
|
echo "❌ Usage: ./bump-version.sh [project_id] <version> [message_court]"
|
||||||
echo " Exemple: ./bump-version.sh 2.1.0 'Nouveaux filtres'"
|
echo " Exemple: ./bump-version.sh lecoffreio 2.1.0 'Nouveaux filtres'"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -30,6 +39,7 @@ DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
|||||||
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
||||||
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
||||||
SCRIPT_ABS="${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")"
|
SCRIPT_ABS="${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")"
|
||||||
|
[[ -n "${IA_PROJECT_ID:-}" ]] && export IA_PROJECT_ID
|
||||||
cd "$PROJECT_ROOT" && exec "$SCRIPT_ABS" "$@"
|
cd "$PROJECT_ROOT" && exec "$SCRIPT_ABS" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,37 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# From branch test only: align origin/test, origin/pprod, origin/prod then deploy to test (import-v1, skipSetupHost).
|
# From branch test only: align origin/test, origin/pprod, origin/prod then deploy to test (import-v1, skipSetupHost).
|
||||||
# Use when you have already pushed to test and want to sync other branches and deploy test in one go.
|
# Usage: ./deploy/change-to-all-branches.sh [project_id]
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
||||||
|
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
||||||
|
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
# Optional first arg: project id (must exist as projects/<id>/conf.json); then re-exec from project root
|
||||||
|
if [[ -n "${1:-}" && -f "${IA_DEV_ROOT}/projects/${1}/conf.json" ]]; then
|
||||||
|
export IA_PROJECT_ID="$1"
|
||||||
|
shift
|
||||||
|
# shellcheck source=../lib/project_config.sh
|
||||||
|
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
||||||
|
[[ -n "${PROJECT_ID:-}" ]] && export IA_PROJECT_ID="$PROJECT_ID"
|
||||||
|
PROJECT_ROOT=""
|
||||||
|
if [[ -n "${PROJECT_CONFIG_PATH:-}" && -f "${PROJECT_CONFIG_PATH:-}" ]] && command -v jq >/dev/null 2>&1; then
|
||||||
|
_secrets_path="$(jq -r '.deploy.secrets_path // ""' "$PROJECT_CONFIG_PATH" 2>/dev/null)"
|
||||||
|
[[ -n "$_secrets_path" ]] && PROJECT_ROOT="$(dirname "$_secrets_path")"
|
||||||
|
fi
|
||||||
|
if [[ -z "$PROJECT_ROOT" || ! -d "$PROJECT_ROOT" ]]; then
|
||||||
|
echo "[change-to-all-branches][ERROR] Could not resolve project root for project_id ${IA_PROJECT_ID}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
echo "[change-to-all-branches][ERROR] Not in a git repository" >&2
|
echo "[change-to-all-branches][ERROR] Not in a git repository" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
||||||
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
|
||||||
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
|
||||||
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
||||||
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
cd "$PROJECT_ROOT" && exec "${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")" "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# deploy-by-script-to <target_branch>: checkout target, verify .secrets/<env>, force sync with origin, deploy target, checkout test.
|
# deploy-by-script-to [project_id] <target_branch>: checkout target, verify .secrets/<env>, force sync with origin, deploy target, checkout test.
|
||||||
# Launched from ia_dev root. Project root from projects/<id>/conf.json (deploy.secrets_path) when MAIL_TO or AI_AGENT_TOKEN set. Target: pprod | prod only.
|
# Launched from ia_dev root. Project from projects/<id>/conf.json; id from param, or MAIL_TO or AI_AGENT_TOKEN. Target: pprod | prod only.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
||||||
DEPLOY_IA="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
DEPLOY_IA="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
||||||
IA_DEV_ROOT="$(cd "$DEPLOY_IA/.." && pwd)"
|
IA_DEV_ROOT="$(cd "$DEPLOY_IA/.." && pwd)"
|
||||||
|
|
||||||
|
# Optional first arg: project id (must exist as projects/<id>/conf.json)
|
||||||
|
if [[ -n "${1:-}" && ! "$1" =~ ^(pprod|prod)$ && -f "${IA_DEV_ROOT}/projects/${1}/conf.json" ]]; then
|
||||||
|
export IA_PROJECT_ID="$1"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
# shellcheck source=../lib/project_config.sh
|
# shellcheck source=../lib/project_config.sh
|
||||||
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
||||||
PROJECT_ROOT=""
|
PROJECT_ROOT=""
|
||||||
@ -19,6 +25,8 @@ if [[ -z "$PROJECT_ROOT" || ! -d "$PROJECT_ROOT" ]]; then
|
|||||||
PROJECT_ROOT="$(cd "$DEPLOY_IA/../.." && pwd)"
|
PROJECT_ROOT="$(cd "$DEPLOY_IA/../.." && pwd)"
|
||||||
fi
|
fi
|
||||||
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
||||||
|
# Preserve project id for re-exec so config is still resolved in child
|
||||||
|
[[ -n "${PROJECT_ID:-}" ]] && export IA_PROJECT_ID="$PROJECT_ID"
|
||||||
cd "$PROJECT_ROOT" && exec "$SCRIPT_REAL" "$@"
|
cd "$PROJECT_ROOT" && exec "$SCRIPT_REAL" "$@"
|
||||||
fi
|
fi
|
||||||
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
||||||
@ -29,12 +37,12 @@ fi
|
|||||||
TARGET_BRANCH="${1:-}"
|
TARGET_BRANCH="${1:-}"
|
||||||
if [[ -z "$TARGET_BRANCH" ]]; then
|
if [[ -z "$TARGET_BRANCH" ]]; then
|
||||||
echo "[deploy-by-script-to][ERROR] Missing <target_branch> argument (expected: pprod | prod)" >&2
|
echo "[deploy-by-script-to][ERROR] Missing <target_branch> argument (expected: pprod | prod)" >&2
|
||||||
echo "Usage: ./deploy/deploy-by-script-to.sh <target_branch> (from ia_dev; pprod or prod only)" >&2
|
echo "Usage: ./deploy/deploy-by-script-to.sh [project_id] <target_branch> (from ia_dev; pprod or prod only)" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ ! "$TARGET_BRANCH" =~ ^(pprod|prod)$ ]]; then
|
if [[ ! "$TARGET_BRANCH" =~ ^(pprod|prod)$ ]]; then
|
||||||
echo "[deploy-by-script-to][ERROR] Invalid target branch: must be pprod or prod (got: '${TARGET_BRANCH}')" >&2
|
echo "[deploy-by-script-to][ERROR] Invalid target branch: must be pprod or prod (got: '${TARGET_BRANCH}')" >&2
|
||||||
echo "Usage: ./deploy/deploy-by-script-to.sh <pprod|prod>" >&2
|
echo "Usage: ./deploy/deploy-by-script-to.sh [project_id] <pprod|prod>" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -10,14 +10,25 @@ PROJECT_ROOT="$(git rev-parse --show-toplevel)"
|
|||||||
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
SCRIPT_REAL="$(readlink -f "${BASH_SOURCE[0]:-$0}" 2>/dev/null || realpath "${BASH_SOURCE[0]:-$0}" 2>/dev/null || echo "${BASH_SOURCE[0]:-$0}")"
|
||||||
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
DEPLOY_DIR="$(cd "$(dirname "$SCRIPT_REAL")" && pwd)"
|
||||||
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
IA_DEV_ROOT="$(cd "$DEPLOY_DIR/.." && pwd)"
|
||||||
if [[ "$(pwd)" != "$PROJECT_ROOT" ]]; then
|
|
||||||
SCRIPT_ABS="${DEPLOY_DIR}/$(basename "${BASH_SOURCE[0]:-$0}")"
|
|
||||||
cd "$PROJECT_ROOT" && exec "$SCRIPT_ABS" "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Resolve project id and config path: MAIL_TO or AI_AGENT_TOKEN only (no fallback) → projects/<id>/conf.json
|
# Optional project id: --project <id> or first positional if projects/<id>/conf.json exists
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
if [[ "$1" == --project ]]; then
|
||||||
|
[[ -n "${2:-}" ]] || { echo "[pousse][ERROR] --project requires <project_id>" >&2; exit 1; }
|
||||||
|
export IA_PROJECT_ID="$2"
|
||||||
|
shift 2
|
||||||
|
elif [[ "$1" != --* && -n "${1:-}" && -f "${IA_DEV_ROOT}/projects/${1}/conf.json" ]]; then
|
||||||
|
export IA_PROJECT_ID="$1"
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Resolve project id and config path: param (IA_PROJECT_ID), MAIL_TO or AI_AGENT_TOKEN → projects/<id>/conf.json
|
||||||
# shellcheck source=../lib/project_config.sh
|
# shellcheck source=../lib/project_config.sh
|
||||||
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
source "${IA_DEV_ROOT}/lib/project_config.sh"
|
||||||
|
[[ -n "${PROJECT_ID:-}" ]] && export IA_PROJECT_ID="$PROJECT_ID"
|
||||||
|
|
||||||
remote="origin"
|
remote="origin"
|
||||||
bump_version=false
|
bump_version=false
|
||||||
@ -25,8 +36,10 @@ bump_version=false
|
|||||||
usage() {
|
usage() {
|
||||||
cat <<'EOF'
|
cat <<'EOF'
|
||||||
Usage:
|
Usage:
|
||||||
./deploy/pousse.sh [--remote <remote>] [--bump-version]
|
./deploy/pousse.sh [project_id|--project <project_id>] [--remote <remote>] [--bump-version]
|
||||||
|
|
||||||
|
project_id Optional. Id from projects/<id>/conf.json (e.g. lecoffreio). Else from MAIL_TO or AI_AGENT_TOKEN.
|
||||||
|
--project <id> Same as positional project_id.
|
||||||
--bump-version Increment patch (third component) in VERSION before staging.
|
--bump-version Increment patch (third component) in VERSION before staging.
|
||||||
|
|
||||||
Reads a full multi-line commit message from STDIN, then:
|
Reads a full multi-line commit message from STDIN, then:
|
||||||
|
|||||||
45
deploy/scripts/add-ssh-key-anthony.sh
Executable file
45
deploy/scripts/add-ssh-key-anthony.sh
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Add SSH public key for anthony@4nk to proxy and services (192.168.1.104).
|
||||||
|
# Run from ia_dev root. Uses DEPLOY_SSH_KEY or ~/.ssh/id_ed25519 to authenticate.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="${BASH_SOURCE%/*}"
|
||||||
|
[[ -d "$SCRIPT_DIR" ]] || SCRIPT_DIR=.
|
||||||
|
LIB_DIR="$(cd "$SCRIPT_DIR/../_lib" && pwd)"
|
||||||
|
# shellcheck source=../_lib/ssh.sh
|
||||||
|
source "$LIB_DIR/ssh.sh"
|
||||||
|
|
||||||
|
SSH_KEY="${DEPLOY_SSH_KEY:-$HOME/.ssh/id_ed25519}"
|
||||||
|
SSH_USER="${DEPLOY_SSH_USER:-ncantu}"
|
||||||
|
PROXY_HOST="${DEPLOY_SSH_PROXY_HOST:-4nk.myftp.biz}"
|
||||||
|
SERVICES_IP="192.168.1.104"
|
||||||
|
|
||||||
|
KEY_LINE="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIM7df89eMnNBc85o+hijYTnZALlTZssIZSYlN+hMW3c anthony@4nk"
|
||||||
|
printf -v KEY_ESC '%q' "$KEY_LINE"
|
||||||
|
|
||||||
|
require_ssh_key "$SSH_KEY"
|
||||||
|
|
||||||
|
add_key_remote() {
|
||||||
|
local target_host="$1"
|
||||||
|
local use_proxy="${2:-false}"
|
||||||
|
local proxy_args=()
|
||||||
|
if [[ "$use_proxy" == "true" ]]; then
|
||||||
|
proxy_args=(-o "ProxyJump=$SSH_USER@$PROXY_HOST")
|
||||||
|
fi
|
||||||
|
# shellcheck disable=SC2207
|
||||||
|
local common_opts=($(ssh_common_opts "$SSH_USER" "$target_host"))
|
||||||
|
ssh -i "$SSH_KEY" \
|
||||||
|
"${common_opts[@]}" \
|
||||||
|
"${proxy_args[@]}" \
|
||||||
|
"$SSH_USER@$target_host" \
|
||||||
|
"mkdir -p ~/.ssh && (grep -qF $KEY_ESC ~/.ssh/authorized_keys 2>/dev/null || echo $KEY_ESC >> ~/.ssh/authorized_keys)"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Adding key to proxy ($PROXY_HOST)..."
|
||||||
|
add_key_remote "$PROXY_HOST" false
|
||||||
|
|
||||||
|
echo "Adding key to services ($SERVICES_IP) via proxy..."
|
||||||
|
add_key_remote "$SERVICES_IP" true
|
||||||
|
|
||||||
|
echo "Done. Key anthony@4nk added on proxy and services."
|
||||||
72
gitea-issues/agent-loop-n-cycles.sh
Executable file
72
gitea-issues/agent-loop-n-cycles.sh
Executable file
@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Run N cycles of (retrieval + treatment via Cursor Agent CLI + sleep 60s) in foreground.
|
||||||
|
# Uses same lock as section 2. When AGENT_LOOP_RUN_AGENT=1 and "agent" in PATH, runs
|
||||||
|
# gitea-issues-process workflow via CLI each cycle (same as agent-loop.sh). No contournement:
|
||||||
|
# /agent-loop 600 = agent runs this script with N=600 and timeout ~11h; script does 600 full cycles.
|
||||||
|
#
|
||||||
|
# Usage: from ia_dev root: ./gitea-issues/agent-loop-n-cycles.sh [N]
|
||||||
|
# N = number of cycles (default 600). Each cycle = retrieval + agent CLI (if configured) + 60s sleep.
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
if [ -n "${HOME:-}" ] && [ -r "$HOME/.bashrc" ]; then
|
||||||
|
set +u
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$HOME/.bashrc" 2>/dev/null || true
|
||||||
|
set -u
|
||||||
|
fi
|
||||||
|
[ -n "${HOME:-}" ] && [ -d "$HOME/.local/bin" ] && export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
|
||||||
|
GITEA_ISSUES_DIR="${GITEA_ISSUES_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
|
||||||
|
ROOT="$(cd "${GITEA_ISSUES_DIR}/../.." && pwd)"
|
||||||
|
IA_DEV_ROOT="${GITEA_ISSUES_DIR}/.."
|
||||||
|
export GITEA_ISSUES_DIR
|
||||||
|
export REPO_ROOT="${ROOT}"
|
||||||
|
cd "$ROOT"
|
||||||
|
# shellcheck source=lib.sh
|
||||||
|
source "${GITEA_ISSUES_DIR}/lib.sh" 2>/dev/null || true
|
||||||
|
|
||||||
|
AGENT_LOOP_ENV="${IA_DEV_ROOT}/.secrets/gitea-issues/agent-loop.env"
|
||||||
|
if [ -r "$AGENT_LOOP_ENV" ]; then
|
||||||
|
set +u
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
source "$AGENT_LOOP_ENV"
|
||||||
|
set -u
|
||||||
|
fi
|
||||||
|
|
||||||
|
N="${1:-600}"
|
||||||
|
if ! [[ "$N" =~ ^[0-9]+$ ]] || [ "$N" -lt 1 ]; then
|
||||||
|
echo "[agent-loop-n-cycles] Usage: $0 [N] (N positive integer, default 600)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
"${GITEA_ISSUES_DIR}/agent-loop-lock-acquire.sh" || exit 1
|
||||||
|
|
||||||
|
AGENT_PROMPT="Exécute le workflow mails du spooler (agent gitea-issues-process). 1) Lister les mails à traiter avec ./gitea-issues/list-pending-spooler.sh (ou utiliser les chemins dans agent-loop.pending). 2) Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Répondre à l'expéditeur (--to <from> du JSON), pas à une adresse fixe ; le « to » du mail reçu a déjà déterminé le projet. Rédiger une réponse pertinente (uniquement ton texte, pas de citation ; mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Après envoi réussi : ./gitea-issues/write-response-spooler.sh --base <base> --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Ne pas appeler mail-mark-read.sh (spooler)."
|
||||||
|
|
||||||
|
i=1
|
||||||
|
while [ "$i" -le "$N" ]; do
|
||||||
|
if "${GITEA_ISSUES_DIR}/agent-loop-stop-requested.sh" 2>/dev/null; then
|
||||||
|
echo "[agent-loop-n-cycles] $(date -Iseconds) — Arrêt demandé (cycle $i/$N). Libération du lock."
|
||||||
|
"${GITEA_ISSUES_DIR}/agent-loop-lock-release.sh"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
echo "[agent-loop-n-cycles] $(date -Iseconds) — Cycle $i/$N"
|
||||||
|
"${GITEA_ISSUES_DIR}/agent-loop-retrieval-once.sh" || true
|
||||||
|
|
||||||
|
if [ "${AGENT_LOOP_RUN_AGENT:-0}" = "1" ] && command -v agent >/dev/null 2>&1; then
|
||||||
|
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
||||||
|
if agent -p "$AGENT_PROMPT" -f --model "$AGENT_MODEL" 2>&1; then
|
||||||
|
: # agent done
|
||||||
|
else
|
||||||
|
echo "[agent-loop-n-cycles] $(date -Iseconds) — Agent terminé avec erreur ou interruption (cycle $i/$N)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$i" -lt "$N" ]; then
|
||||||
|
sleep 60
|
||||||
|
fi
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
"${GITEA_ISSUES_DIR}/agent-loop-lock-release.sh"
|
||||||
|
echo "[agent-loop-n-cycles] $(date -Iseconds) — $N cycles terminés."
|
||||||
@ -37,7 +37,7 @@ fi
|
|||||||
INTERVAL="${AGENT_LOOP_TREATMENT_INTERVAL_SEC:-60}"
|
INTERVAL="${AGENT_LOOP_TREATMENT_INTERVAL_SEC:-60}"
|
||||||
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
||||||
|
|
||||||
PROMPT="Exécute le workflow mails du spooler (agent gitea-issues-process). Les chemins des fichiers .pending sont dans projects/<id>/logs/gitea-issues/agent-loop.pending (ou exécuter ./gitea-issues/list-pending-spooler.sh). Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Rédiger une réponse pertinente (uniquement ton texte ; pas de citation — mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Après envoi réussi : ./gitea-issues/write-response-spooler.sh --base <base> --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Ne pas appeler mail-mark-read.sh (spooler)."
|
PROMPT="Exécute le workflow mails du spooler (agent gitea-issues-process). Les chemins des fichiers .pending sont dans projects/<id>/logs/gitea-issues/agent-loop.pending (ou exécuter ./gitea-issues/list-pending-spooler.sh). Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Répondre à l'expéditeur (--to <from> du JSON), pas à une adresse fixe ; le « to » du mail reçu a déjà déterminé le projet. Rédiger une réponse pertinente (uniquement ton texte ; pas de citation — mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Après envoi réussi : ./gitea-issues/write-response-spooler.sh --base <base> --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Ne pas appeler mail-mark-read.sh (spooler)."
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
if [ -s "$PENDING_FILE" ] && command -v agent >/dev/null 2>&1; then
|
if [ -s "$PENDING_FILE" ] && command -v agent >/dev/null 2>&1; then
|
||||||
|
|||||||
@ -73,7 +73,7 @@ while true; do
|
|||||||
echo "[agent-loop] $(date -Iseconds) — Lancement de l'agent Cursor (workflow gitea-issues-process spooler)."
|
echo "[agent-loop] $(date -Iseconds) — Lancement de l'agent Cursor (workflow gitea-issues-process spooler)."
|
||||||
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
AGENT_MODEL="${AGENT_LOOP_MODEL:-sonnet-4.6}"
|
||||||
echo "[agent-loop] $(date -Iseconds) — Modèle: $AGENT_MODEL"
|
echo "[agent-loop] $(date -Iseconds) — Modèle: $AGENT_MODEL"
|
||||||
AGENT_OPTS=(-p "Exécute le workflow mails du spooler (agent gitea-issues-process). 1) Lister les mails à traiter avec ./gitea-issues/list-pending-spooler.sh (ou utiliser les chemins dans agent-loop.pending). 2) Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Rédiger une réponse pertinente (uniquement ton texte, pas de citation ; mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Après envoi réussi : ./gitea-issues/write-response-spooler.sh --base <base> --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Ne pas appeler mail-mark-read.sh (spooler)." -f --model "$AGENT_MODEL")
|
AGENT_OPTS=(-p "Exécute le workflow mails du spooler (agent gitea-issues-process). 1) Lister les mails à traiter avec ./gitea-issues/list-pending-spooler.sh (ou utiliser les chemins dans agent-loop.pending). 2) Pour chaque fichier .pending : lire le JSON (from, to, subject, body, message_id, base). Répondre à l'expéditeur (--to <from> du JSON), pas à une adresse fixe ; le « to » du mail reçu a déjà déterminé le projet. Rédiger une réponse pertinente (uniquement ton texte, pas de citation ; mail-send-reply.sh refuse si le body contient From:, Message-ID, wrote:, etc.). Envoyer avec ./gitea-issues/mail-send-reply.sh --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Après envoi réussi : ./gitea-issues/write-response-spooler.sh --base <base> --to <from> --subject \"Re: ...\" --body \"<ta_réponse>\" --in-reply-to \"<message_id>\". Ne pas appeler mail-mark-read.sh (spooler)." -f --model "$AGENT_MODEL")
|
||||||
if agent "${AGENT_OPTS[@]}" 2>&1; then
|
if agent "${AGENT_OPTS[@]}" 2>&1; then
|
||||||
write_status "agent_done" "Agent terminé."
|
write_status "agent_done" "Agent terminé."
|
||||||
else
|
else
|
||||||
|
|||||||
@ -3,9 +3,10 @@
|
|||||||
# Standalone: run from ia_dev root. Source after IA_DEV_ROOT is set (or it is derived from script location).
|
# Standalone: run from ia_dev root. Source after IA_DEV_ROOT is set (or it is derived from script location).
|
||||||
# Resolves PROJECT_ID and PROJECT_CONFIG_PATH (projects/<id>/conf.json).
|
# Resolves PROJECT_ID and PROJECT_CONFIG_PATH (projects/<id>/conf.json).
|
||||||
#
|
#
|
||||||
# Project id is resolved only by:
|
# Project id is resolved by (first match wins):
|
||||||
# 1. MAIL_TO (env): search all projects for tickets.authorized_emails.to matching this address (config may have a string or a list of env-keyed objects).
|
# 1. IA_PROJECT_ID (env): explicit project id; set by scripts when passed as parameter (e.g. ./pousse.sh lecoffreio).
|
||||||
# 2. AI_AGENT_TOKEN (env): search all projects/.secrets/<env>/ia_token for matching token; sets PROJECT_ID and PROJECT_ENV (project and environment).
|
# 2. MAIL_TO (env): search all projects for tickets.authorized_emails.to matching this address (config may have a string or a list of env-keyed objects).
|
||||||
|
# 3. AI_AGENT_TOKEN (env): search all projects/.secrets/<env>/ia_token for matching token; sets PROJECT_ID and PROJECT_ENV (project and environment).
|
||||||
#
|
#
|
||||||
# No fallback: no IA_PROJECT, no ai_project_id, no .ia_project.
|
# No fallback: no IA_PROJECT, no ai_project_id, no .ia_project.
|
||||||
#
|
#
|
||||||
@ -14,7 +15,13 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
PROJECT_ID=""
|
PROJECT_ID=""
|
||||||
if [[ -n "${MAIL_TO:-}" && -n "${IA_DEV_ROOT:-}" ]]; then
|
if [[ -n "${IA_PROJECT_ID:-}" && -n "${IA_DEV_ROOT:-}" ]]; then
|
||||||
|
_conf="${IA_DEV_ROOT}/projects/${IA_PROJECT_ID}/conf.json"
|
||||||
|
if [[ -f "$_conf" ]]; then
|
||||||
|
PROJECT_ID="${IA_PROJECT_ID}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -z "$PROJECT_ID" && -n "${MAIL_TO:-}" && -n "${IA_DEV_ROOT:-}" ]]; then
|
||||||
_to="$(echo "${MAIL_TO}" | sed 's/[[:space:]]//g' | tr '[:upper:]' '[:lower:]')"
|
_to="$(echo "${MAIL_TO}" | sed 's/[[:space:]]//g' | tr '[:upper:]' '[:lower:]')"
|
||||||
for conf in "${IA_DEV_ROOT}/projects/"*/conf.json; do
|
for conf in "${IA_DEV_ROOT}/projects/"*/conf.json; do
|
||||||
[[ -f "$conf" ]] || continue
|
[[ -f "$conf" ]] || continue
|
||||||
|
|||||||
@ -10,15 +10,18 @@ The scripts in `deploy/` deploy and build the **configured projects** (lecoffrei
|
|||||||
|
|
||||||
## Current project selection
|
## Current project selection
|
||||||
|
|
||||||
The project **id** (directory name under `projects/`) is resolved only by:
|
The project **id** (directory name under `projects/`) is resolved by (first match wins):
|
||||||
|
|
||||||
**1. Mail ticketing — "to" address**
|
**1. Explicit parameter**
|
||||||
|
Scripts in `deploy/` accept an optional project id as first argument or via `--project <id>` (pousse.sh). When present and `projects/<id>/conf.json` exists, that id is used. Example: `./deploy/pousse.sh lecoffreio`, `./deploy/deploy-by-script-to.sh lecoffreio prod`.
|
||||||
|
|
||||||
|
**2. Mail ticketing — "to" address**
|
||||||
From the **To** address of an email: search all `projects/*/conf.json` for `tickets.authorized_emails.to` equal to that address (case-insensitive). The config may have a single string or a list of env-keyed objects (e.g. `[{ "test": "AI.X.TEST@…", "pprod": "…", "prod": "…" }]`). The matching project directory name is the id.
|
From the **To** address of an email: search all `projects/*/conf.json` for `tickets.authorized_emails.to` equal to that address (case-insensitive). The config may have a single string or a list of env-keyed objects (e.g. `[{ "test": "AI.X.TEST@…", "pprod": "…", "prod": "…" }]`). The matching project directory name is the id.
|
||||||
|
|
||||||
**2. Request token**
|
**3. Request token**
|
||||||
The token in the request (e.g. Bearer) is matched by scanning all projects and all envs: each `projects/<id>/.secrets/<env>/ia_token` is read and compared (content or content + env). The first match yields the project id and the environment (`test`, `pprod`, `prod`).
|
The token in the request (e.g. Bearer) is matched by scanning all projects and all envs: each `projects/<id>/.secrets/<env>/ia_token` is read and compared (content or content + env). The first match yields the project id and the environment (`test`, `pprod`, `prod`).
|
||||||
|
|
||||||
Scripts use **`MAIL_TO`** (env) for (1) or **`AI_AGENT_TOKEN`** (env) for (2); they set `PROJECT_ID` and, for (2), `PROJECT_ENV`. No other source (no `IA_PROJECT`, no `ai_project_id`, no `.ia_project`).
|
Scripts use **parameter** (or **`IA_PROJECT_ID`** env set by scripts), **`MAIL_TO`** (env) or **`AI_AGENT_TOKEN`** (env); they set `PROJECT_ID` and, for token, `PROJECT_ENV`. No other source (no `IA_PROJECT`, no `ai_project_id`, no `.ia_project`).
|
||||||
|
|
||||||
**Usage unique : standalone.** Tous les scripts sont lancés depuis la racine de ia_dev. Les chemins dans conf sont absolus (sauf `imap_bridge_env` et `token_file`, relatifs à la racine de ia_dev).
|
**Usage unique : standalone.** Tous les scripts sont lancés depuis la racine de ia_dev. Les chemins dans conf sont absolus (sauf `imap_bridge_env` et `token_file`, relatifs à la racine de ia_dev).
|
||||||
|
|
||||||
|
|||||||
@ -65,7 +65,8 @@ Spooler tickets (nouveau) : mails dans **projects/<id>/data/issues/** (filtre pa
|
|||||||
| `agent-loop-stop.sh` | `./gitea-issues/agent-loop-stop.sh` | **Arrêt à la demande** : crée `agent-loop.stop` ; l'instance en cours s'arrête au début du cycle suivant. |
|
| `agent-loop-stop.sh` | `./gitea-issues/agent-loop-stop.sh` | **Arrêt à la demande** : crée `agent-loop.stop` ; l'instance en cours s'arrête au début du cycle suivant. |
|
||||||
| `agent-loop-stop-requested.sh` | `./gitea-issues/agent-loop-stop-requested.sh` | **Vérification arrêt** : exit 0 si `agent-loop.stop` existe (utilisé par l'agent au début de chaque cycle). |
|
| `agent-loop-stop-requested.sh` | `./gitea-issues/agent-loop-stop-requested.sh` | **Vérification arrêt** : exit 0 si `agent-loop.stop` existe (utilisé par l'agent au début de chaque cycle). |
|
||||||
| `agent-loop-is-running.sh` | `./gitea-issues/agent-loop-is-running.sh` | **Vérifier si l'agent est en cours** : affiche fichier lock, PID et date ; indique si le processus est actif ou lock orphelin. Exit 0 si instance en cours (lock mtime < 24 h), 1 sinon. |
|
| `agent-loop-is-running.sh` | `./gitea-issues/agent-loop-is-running.sh` | **Vérifier si l'agent est en cours** : affiche fichier lock, PID et date ; indique si le processus est actif ou lock orphelin. Exit 0 si instance en cours (lock mtime < 24 h), 1 sinon. |
|
||||||
| `tickets-fetch-inbox.sh` | `./gitea-issues/tickets-fetch-inbox.sh` | **Récupération par expéditeurs autorisés** : mails **à partir du 10 mars 2026** (MAIL_SINCE_DATE), filtre `tickets.authorized_emails` (conf.json), pas de marquage lu/non lu. Écrit les nouveaux mails dans `projects/<id>/data/issues/*.pending` (JSON). Ne crée pas de .pending si un .response existe déjà. Voir `projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md`. |
|
| `agent-loop-n-cycles.sh` | `./gitea-issues/agent-loop-n-cycles.sh [N]` | **N cycles (récupération + 1 min)** : exécute N fois (récupération une fois + sleep 60) en **avant-plan** (défaut N=600). Utilise le même lock que la section 2. Arrêt : `agent-loop-stop.sh`. Ne lance pas l'agent ; lancer **gitea-issues-process** à part pour traiter les pendings. Permet de faire tourner réellement N × 1 minute. |
|
||||||
|
| `tickets-fetch-inbox.sh` | `./gitea-issues/tickets-fetch-inbox.sh` | **Récupération et filtrage par le script** : le script (et le Python qu'il appelle) **récupère** les mails en boîte et les **filtre** (to, from, `tickets.authorized_emails`, date). L'agent ne fait que lancer le script. Mails à partir du 10 mars 2026 (MAIL_SINCE_DATE). Écrit les mails retenus dans `projects/<id>/data/issues/*.pending` (JSON). Ne crée pas de .pending si un .response existe déjà. Voir `projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md`. |
|
||||||
| `list-pending-spooler.sh` | `./gitea-issues/list-pending-spooler.sh` | **Spooler** : liste les fichiers `projects/<id>/data/issues/*.pending` qui n'ont **pas** de fichier `.response` correspondant (mails à traiter). Une ligne par chemin. |
|
| `list-pending-spooler.sh` | `./gitea-issues/list-pending-spooler.sh` | **Spooler** : liste les fichiers `projects/<id>/data/issues/*.pending` qui n'ont **pas** de fichier `.response` correspondant (mails à traiter). Une ligne par chemin. |
|
||||||
| `write-response-spooler.sh` | `./gitea-issues/write-response-spooler.sh --base <base> --to <addr> --subject "..." --body "..." [--in-reply-to "<msg-id>"]` | **Spooler** : après envoi réussi avec `mail-send-reply.sh`, écrit `projects/<id>/data/issues/<base>.response` (JSON de la réponse envoyée). |
|
| `write-response-spooler.sh` | `./gitea-issues/write-response-spooler.sh --base <base> --to <addr> --subject "..." --body "..." [--in-reply-to "<msg-id>"]` | **Spooler** : après envoi réussi avec `mail-send-reply.sh`, écrit `projects/<id>/data/issues/<base>.response` (JSON de la réponse envoyée). |
|
||||||
|
|
||||||
@ -81,7 +82,7 @@ Sous `projects/<id>/logs/gitea-issues/` :
|
|||||||
- **agent-loop.stop** : si présent, l'instance en cours s'arrête au début du cycle suivant. Création : `agent-loop-stop.sh` ou `touch …/agent-loop.stop`.
|
- **agent-loop.stop** : si présent, l'instance en cours s'arrête au début du cycle suivant. Création : `agent-loop-stop.sh` ou `touch …/agent-loop.stop`.
|
||||||
- **agent-loop-chat-iterations.log** : sortie de `agent-loop-chat-iterations.sh` (test d’envoi au lancement, puis à chaque itération le résultat de `mail-list-unread.sh`).
|
- **agent-loop-chat-iterations.log** : sortie de `agent-loop-chat-iterations.sh` (test d’envoi au lancement, puis à chaque itération le résultat de `mail-list-unread.sh`).
|
||||||
|
|
||||||
Le répertoire **projects/<id>/data/issues/** (spooler) est rempli **uniquement** par `./gitea-issues/tickets-fetch-inbox.sh`. Si ce script n'est pas exécuté, `data/issues` reste vide si on n’utilise que la boucle legacy utilise seulement mail-list-unread.sh et agent-loop.pending dans logs/gitea-issues/.
|
Le répertoire **projects/<id>/data/issues/** (spooler) est rempli **uniquement** par `./gitea-issues/tickets-fetch-inbox.sh`. Si ce script n'est pas exécuté, `data/issues` reste vide si on n’utilise que la boucle legacy utilise seulement mail-list-unread.sh et agent-loop.pending dans logs/gitea-issues/. **Récupération et filtrage** : c'est le **script** (et le Python) qui récupère les mails et les filtre (to, from, authorized_emails, date) ; l'agent se contente de lancer le script. Le script route chaque message vers le projet dont `tickets.authorized_emails.to` correspond au « to » du mail ; les réponses sont envoyées à l'**expéditeur** (« from »), pas à une adresse fixe.
|
||||||
|
|
||||||
**Réponse mail** : le `--body` de `mail-send-reply.sh` doit être **uniquement le texte rédigé par l’agent** (la réponse à l’expéditeur). Ne jamais y mettre le mail reçu, le sujet, une citation ou un bloc « From: » / « Message-ID » : sinon le destinataire reçoit son propre message au lieu de la réponse.
|
**Réponse mail** : le `--body` de `mail-send-reply.sh` doit être **uniquement le texte rédigé par l’agent** (la réponse à l’expéditeur). Ne jamais y mettre le mail reçu, le sujet, une citation ou un bloc « From: » / « Message-ID » : sinon le destinataire reçoit son propre message au lieu de la réponse.
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
"uid": "7911",
|
"uid": "7911",
|
||||||
"created_at": "2026-03-16T15:45:30Z",
|
"created_at": "2026-03-16T15:45:30Z",
|
||||||
"issue_number": null,
|
"issue_number": null,
|
||||||
"status": "pending",
|
"status": "responded",
|
||||||
"attachments": [
|
"attachments": [
|
||||||
{
|
{
|
||||||
"filename": "publickey - nicolas.cantu@pm.me -\r\n 0xAFF1ECF4.asc",
|
"filename": "publickey - nicolas.cantu@pm.me -\r\n 0xAFF1ECF4.asc",
|
||||||
@ -25,5 +25,12 @@
|
|||||||
"content_type": "application/pgp-keys",
|
"content_type": "application/pgp-keys",
|
||||||
"size": 653
|
"size": 653
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"response": {
|
||||||
|
"in_reply_to_message_id": "<G1Cb1a_-Vb-E4o4zC1uNbA1u8sSD23ledYvzJozkp4GIkFVS1UJqwloYIKVIVZ5yCmh0mFj7dDcJMOEuWrg3GUu-eTVhY5Nfar5jiM5a-fQ=@pm.me>",
|
||||||
|
"to": "nicolas.cantu@pm.me",
|
||||||
|
"subject": "Re: Présent le projet",
|
||||||
|
"body": "Le projet Lecoffre.io (LeCoffre) est une application de gestion de coffre-fort numérique et de documents, déployée sur les environnements test, préproduction et production. Le dépôt de code est hébergé sur Gitea (git.4nkweb.com). Les tickets et le support sont gérés via les issues Gitea et la boîte de support IA. La configuration et la documentation du projet sont dans ia_dev/projects/lecoffreio/.",
|
||||||
|
"sent_at": "2026-03-16T16:17:12Z"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
xjMEYRoRFBYJKwYBBAHaRw8BAQdA4X6C2Yij4nO2cJQ09WzAjTi4xxKNSuPg
|
||||||
|
jbGiRUzNV/DNJW5pY29sYXMuNG5rQHBtLm1lIDxuaWNvbGFzLjRua0BwbS5t
|
||||||
|
ZT7CjwQQFgoAIAUCYRoRFAYLCQcIAwIEFQgKAgQWAgEAAhkBAhsDAh4BACEJ
|
||||||
|
EJF2OkHvqyEaFiEEbJLPF8vdRKYIhKq1kXY6Qe+rIRo7VwD/TgbhOVf1Z4ya
|
||||||
|
31/zQHlRC1+9r+UAqxAniNIi1bobUJ4A/0DTzj7WXyMub74czIVa/wow2Y+c
|
||||||
|
bFsvx48UFNsWbW8EzjgEYRoRFBIKKwYBBAGXVQEFAQEHQDVg6f93NlVlOt2d
|
||||||
|
AM1Cl2OwF3E/vMcU6/OLrXHm8o8KAwEIB8J4BBgWCAAJBQJhGhEUAhsMACEJ
|
||||||
|
EJF2OkHvqyEaFiEEbJLPF8vdRKYIhKq1kXY6Qe+rIRojXwEAjBBrVJdHNpSd
|
||||||
|
iE6X75PI78D6IxeoYacOi7599nXd5BABAK+XvZ71qv0TSGfjxmoqe8OpWNHA
|
||||||
|
lLah6qIOdar5Io8K
|
||||||
|
=Rm1M
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"type": "incoming",
|
||||||
|
"id": "19e0f3e9",
|
||||||
|
"message_id": "<YZ6wMSX0dOKQc6NSlJIjvN75cLSk0pEwFbmibuA9LrVro-aS_yfrra93ykYgJgAk2XjcuD-cNe2zf_HOtAL1Yl7LKmCaXezG4nBMfjwkrs4=@pm.me>",
|
||||||
|
"from": "nicolas.4nk@pm.me",
|
||||||
|
"to": [
|
||||||
|
"\"AI.LECOFFREIO.TEST@4nkweb.com\" <AI.LECOFFREIO.TEST@4nkweb.com>"
|
||||||
|
],
|
||||||
|
"subject": "Présente le projet",
|
||||||
|
"date": "Mon, 16 Mar 2026 15:46:50 +0000",
|
||||||
|
"body": "",
|
||||||
|
"references": [
|
||||||
|
"<u6qNFTxs-NIyYLGBStXgSKEWAhbL8Ih2kYvH9LcsnP3pFjZmQFqfGBE2an_u2NKbUFDxAUlP7r_gT-z9CdPrKw==@protonmail.internalid>"
|
||||||
|
],
|
||||||
|
"in_reply_to": null,
|
||||||
|
"uid": "7912",
|
||||||
|
"created_at": "2026-03-16T16:06:04Z",
|
||||||
|
"issue_number": null,
|
||||||
|
"status": "responded",
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"filename": "publickey - nicolas.4nk@pm.me -\r\n 0x6C92CF17.asc",
|
||||||
|
"path": "2026-03-16T154650.19e0f3e9.nicolas.4nk_pm.me.d/0_publickey_-_nicolas.4nk_pm.me_-___0x6C92CF17.asc",
|
||||||
|
"content_type": "application/pgp-keys",
|
||||||
|
"size": 645
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"response": {
|
||||||
|
"in_reply_to_message_id": "<YZ6wMSX0dOKQc6NSlJIjvN75cLSk0pEwFbmibuA9LrVro-aS_yfrra93ykYgJgAk2XjcuD-cNe2zf_HOtAL1Yl7LKmCaXezG4nBMfjwkrs4=@pm.me>",
|
||||||
|
"to": "nicolas.4nk@pm.me",
|
||||||
|
"subject": "Re: Présente le projet",
|
||||||
|
"body": "Le projet Lecoffre.io (LeCoffre) est une application de gestion de coffre-fort numérique et de documents, déployée sur les environnements test, préproduction et production. Le dépôt de code est hébergé sur Gitea (git.4nkweb.com). Les tickets et le support sont gérés via les issues Gitea et la boîte de support IA. La configuration et la documentation du projet sont dans ia_dev/projects/lecoffreio/.",
|
||||||
|
"sent_at": "2026-03-16T16:17:25Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user