docs: track GIT_ISSUES_SCRIPTS_AGENTS.md under projects/ia_dev/docs
This commit is contained in:
parent
e86a9fbb6e
commit
b4ce81858c
160
projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md
Normal file
160
projects/ia_dev/docs/GIT_ISSUES_SCRIPTS_AGENTS.md
Normal file
@ -0,0 +1,160 @@
|
||||
# Gitea issues – scripts et agents
|
||||
|
||||
Dossier dédié au traitement des tickets (issues) Gitea du dépôt **4nk/lecoffre_ng** (https://git.4nkweb.com/4nk/lecoffre_ng/issues). Toute la logique d'appel API et Git est dans les scripts ; les agents orchestrent et appellent /fix ou /evol.
|
||||
|
||||
## Contraintes de confidentialité et d'accès des agents
|
||||
|
||||
L'agent ne doit **jamais révéler** :
|
||||
|
||||
- Quelle IA il utilise
|
||||
- Des informations personnelles
|
||||
- Des informations sur 4NK
|
||||
- Des informations sur l'équipe de réalisation
|
||||
- Des informations sur des fichiers hors périmètre du projet configuré
|
||||
- Des informations sur les autres questions et réponses traitées
|
||||
|
||||
L'agent ne doit **jamais accéder ni modifier** :
|
||||
|
||||
- Les fichiers hors projet (périmètre = ia_dev et dépôt du projet configuré via conf.json)
|
||||
- Les fichiers dans `.smartIde` et `.secrets`
|
||||
- D'autres branches que celle en cours de travail
|
||||
- D'autres environnements (test / pprod / prod) que celui défini par le contexte
|
||||
|
||||
## Agents (.smartIde/agents/)
|
||||
|
||||
| Agent | Fichier | Rôle |
|
||||
|-------|---------|------|
|
||||
| **agent-loop** | `agent-loop.md` | Orchestre la boucle de récupération des mails et le traitement par **exécutions délimitées** uniquement (N itérations ou x cycles) ; ne lance jamais de processus en arrière-plan (nohup/&). |
|
||||
| **git-issues-process** | `git-issues-process.md` | Traite les issues Gitea et les mails en attente : liste les issues/mails, crée des branches, lance /fix ou /evol, /push-by-script ; workflow mails (fil, réponse réelle, marquage lu). |
|
||||
|
||||
Spooler tickets (nouveau) : mails dans **projects/<id>/data/issues/** (filtre par `tickets.authorized_emails` dans conf.json), pas de « non lu », aucun enregistrement supprimé. Format : `projects/ia_dev/docs/TICKETS_SPOOL_FORMAT.md`. Récupération : `./git-issues/tickets-fetch-inbox.sh`. Référence boucle mails (legacy) : `.smartIde/agents/agent-loop.md`. Hook Cursor : `sessionStart` → `.smartIde/hooks/remonter-mails.sh` (lit `projects/<id>/data/issues/*.pending`).
|
||||
|
||||
## Contexte d'exécution
|
||||
|
||||
- **Emplacement (usage standalone)** : ia_dev est un dépôt autonome. `git-issues/` est à la racine de ia_dev. Un même clone ia_dev peut servir plusieurs projets (id résolu par MAIL_TO ou AI_AGENT_TOKEN).
|
||||
- **Projet cible** : le projet est identifié **dynamiquement** par **MAIL_TO** (adresse « to » des mails, recherchée dans les configs ticketing de tous les projets) ou **AI_AGENT_TOKEN** (token des requêtes). L'id sert à charger la config dans `projects/<id>/`. Pas de fallback. Voir `docs/repo/ia-dev-project-conf-schema.md` (racine monorepo **smart_ide**).
|
||||
- **Lancement** : tous les scripts sont invoqués depuis la **racine de ia_dev** : `./git-issues/<script>.sh`. Les opérations (issues, mails, déploiement) utilisent les chemins absolus de `projects/<id>/conf.json` pour le projet cible.
|
||||
- **Secrets et logs** : `.secrets` est à la racine de ia_dev (`.secrets/git-issues/token`, `agent-loop.env`, `imap-bridge.env`). Les logs et data par projet sont sous `projects/<id>/logs/` et `projects/<id>/data/issues/`.
|
||||
|
||||
## Prérequis
|
||||
|
||||
- **jq** : `apt install jq` ou `brew install jq`
|
||||
- **Token Gitea** : variable d'environnement `GITEA_TOKEN` ou fichier `.secrets/git-issues/token` (contenu = le token, non versionné). Créer le token dans Gitea : Settings → Applications → Generate New Token (scopes `read:issue`, `write:issue` si commentaires).
|
||||
|
||||
## Scripts (depuis la racine de ia_dev)
|
||||
|
||||
| Script | Usage | Description |
|
||||
|--------|--------|-------------|
|
||||
| `list-open-issues.sh` | `./git-issues/list-open-issues.sh [--lines] [--limit N]` | Liste les issues ouvertes (JSON ou lignes `number\|title\|state`). |
|
||||
| `get-issue.sh` | `./git-issues/get-issue.sh <num> [--summary]` | Détail d'une issue (JSON ou résumé texte). |
|
||||
| `print-issue-prompt.sh` | `./git-issues/print-issue-prompt.sh <num>` | Affiche titre + corps pour fournir la consigne à l'agent. |
|
||||
| `create-branch-for-issue.sh` | `./git-issues/create-branch-for-issue.sh <num> [base]` | Crée et checkout la branche `issue/<num>` depuis `base` (défaut `test`). |
|
||||
| `comment-issue.sh` | `./git-issues/comment-issue.sh <num> <message>` ou `echo "msg" \| ./git-issues/comment-issue.sh <num> -` | Ajoute un commentaire à l'issue. |
|
||||
| `mail-list-unread.sh` | `./git-issues/mail-list-unread.sh` | Liste les mails **non lus envoyés à l'alias** (MAIL_FILTER_TO), **à partir du 10 mars 2026** (MAIL_SINCE_DATE) ; lecture seule ; sortie : UID, Message-ID, From, To, Subject, Date, Body. Aucun autre mail n'est listé. |
|
||||
| `mail-get-thread.sh` | `./git-issues/mail-get-thread.sh <uid>` | Récupère **tout le fil** (conversation) du mail donné : tous les messages liés par References/In-Reply-To, tri chronologique (ancien → récent). Même format de sortie que mail-list-unread. À utiliser avant de décider ou répondre sur un mail. |
|
||||
| `mail-send-reply.sh` | `./git-issues/mail-send-reply.sh --to <addr> --subject "..." [--body "..." \| stdin] [--in-reply-to "<msg-id>" [--references "..."]]` | Envoie une réponse par mail via le Bridge (SMTP) ; signature « Support IA du projet Lecoffre.io » / ai.support.lecoffreio@4nkweb.com ajoutée automatiquement. |
|
||||
| `mail-create-issue-from-email.sh` | `./git-issues/mail-create-issue-from-email.sh --uid <uid> [--title "..." ] [--body "..."]` | Crée une issue à partir d'un mail (UID), optionnel titre/corps formalisés ; marque le mail lu. |
|
||||
| `mail-mark-read.sh` | `./git-issues/mail-mark-read.sh <uid>` | Marque un mail comme lu. |
|
||||
| `mail-thread-log.sh` | `./git-issues/mail-thread-log.sh get-id \| init \| append-sent \| append-issue \| append-commit ...` | **Log par fil** : un fichier par conversation dans `projects/<id>/logs/git-issues/threads/` (échanges reçus/envoyés, tickets, commits). `get-id --uid <uid>` affiche `THREAD_ID=...` ; `init --uid <uid>` crée/met à jour le fichier ; `append-sent/issue/commit` enregistrent une réponse, une issue ou un commit. |
|
||||
| `mail-to-issue.sh` | `./git-issues/mail-to-issue.sh` | **Batch** : crée une issue par mail non lu (titre = sujet, corps = texte + From), marque lus. À éviter si on suit le workflow agent (voir ci‑dessous). |
|
||||
| `agent-loop.sh` | `./git-issues/agent-loop.sh [interval_sec]` | **Boucle de surveillance** : tourne indéfiniment (spooler ou legacy). **Ne pas lancer depuis l'agent** ; utiliser agent-loop-chat-iterations.sh ou cycles délimités. Voir `.smartIde/agents/agent-loop.md`. |
|
||||
| `agent-loop-treatment.sh` | `./git-issues/agent-loop-treatment.sh` | **Boucle traitement** : vérifie périodiquement `agent-loop.pending` ; si non vide, lance l'agent Cursor. Tourne indéfiniment ; **ne pas lancer depuis l'agent** (préférer agent-loop-chat-iterations.sh ou cycles délimités). |
|
||||
| `agent-loop-retrieval-once.sh` | `./git-issues/agent-loop-retrieval-once.sh` | **Récupération une fois** (legacy, basé non lu) : exécute `mail-list-unread.sh` et écrit dans `agent-loop.pending`. Utilisé par l'agent agent-loop pour les cycles « x fois ». |
|
||||
| `agent-loop-lock-acquire.sh` | `./git-issues/agent-loop-lock-acquire.sh` | **Lock (section 2)** : acquiert `agent-loop.lock` si absent ou périmé (>24 h). Exit 1 si lock actif ; l'agent ne doit pas lancer une deuxième instance. |
|
||||
| `agent-loop-lock-release.sh` | `./git-issues/agent-loop-lock-release.sh` | **Lock (section 2)** : supprime `agent-loop.lock` et `agent-loop.stop`. À exécuter en fin de cycles (normale ou arrêt). |
|
||||
| `agent-loop-stop.sh` | `./git-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` | `./git-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` | `./git-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-n-cycles.sh` | `./git-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 **git-issues-process** à part pour traiter les pendings. Permet de faire tourner réellement N × 1 minute. |
|
||||
| `tickets-fetch-inbox.sh` | `./git-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` | `./git-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` | `./git-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). |
|
||||
|
||||
Variables optionnelles : `GITEA_API_URL`, `GITEA_REPO_OWNER`, `GITEA_REPO_NAME`, `GIT_ISSUES_DIR`.
|
||||
|
||||
### Fichiers témoins et logs (boucle agent)
|
||||
|
||||
Sous `projects/<id>/logs/git-issues/` :
|
||||
|
||||
- **agent-loop.status** : fichier témoin de la boucle de surveillance (`agent-loop.sh` ou `agent-loop-retrieval-once.sh`). Trois lignes : horodatage (ISO), statut (`running` ou `idle`), détail (ex. « Aucun mail non lu »). Mis à jour à chaque itération. Si la date de modification est plus récente que 2× l’intervalle (ex. 120 s pour intervalle 60 s), la boucle est considérée active.
|
||||
- **agent-loop.pending** : liste des mails non lus (legacy) écrite par `mail-list-unread.sh` via la boucle ; l’agent git-issues-process traite ce fichier.
|
||||
- **agent-loop.lock** : lock pour une seule instance (section 2). Contenu : PID + date. Si mtime < 24 h, une nouvelle instance ne doit pas démarrer. Géré par `agent-loop-lock-acquire.sh` / `agent-loop-lock-release.sh`.
|
||||
- **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`).
|
||||
|
||||
Le répertoire **projects/<id>/data/issues/** (spooler) est rempli **uniquement** par `./git-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/git-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.
|
||||
|
||||
### Création d'issues depuis les mails (IMAP) – workflow agent
|
||||
|
||||
**Ne pas enchaîner directement** : l'agent doit d'abord lire les non lus, formaliser l'issue ou répondre par mail, et ne créer/traiter qu'au moment où la demande est prête.
|
||||
|
||||
1. **Lire les non lus** : `./git-issues/mail-list-unread.sh` (ne marque pas les mails comme lus).
|
||||
2. **Pour chaque mail** : consulter **tout l'historique du fil** avec `./git-issues/mail-get-thread.sh <uid>`, créer/mettre à jour le **log du fil** avec `./git-issues/mail-thread-log.sh init --uid <uid>` (sortie `THREAD_ID=...` à conserver), puis décider soit d'envoyer une réponse directe (demande d'infos) via `mail-send-reply.sh`, soit de formaliser et créer l'issue avec `mail-create-issue-from-email.sh` (optionnel `--title` / `--body` formalisés). Si la demande est une correction/évolution prête : créer l'issue, traiter (fix/evol), commenter l'issue, répondre au mail via `mail-send-reply.sh` (avec `--in-reply-to` pour le fil). **Le corps de la réponse** doit contenir la **réponse réelle** à la question (ex. si le mail demande « Décrit les rôles », le body = une description des rôles), jamais le sujet du mail ni la question reçue.
|
||||
3. **Réponses aux mails** : toujours via le Bridge avec `mail-send-reply.sh`. Le `--body` doit être la **réponse réelle** rédigée par l'agent (contenu de la réponse à la demande), pas le sujet du mail, pas la question reçue, pas un message précédent du fil. Chaque envoi est enregistré dans le log du fil avec `mail-thread-log.sh append-sent --thread-id <id> --to <addr> --subject "..." --body "..."` pour tracer l'expéditeur, le titre et le corps de la réponse envoyée.
|
||||
|
||||
**Prérequis :**
|
||||
|
||||
- Python 3 (stdlib : imaplib, email, smtplib, json, urllib).
|
||||
- Token Gitea : comme les autres scripts (`GITEA_TOKEN` ou `.secrets/git-issues/token`).
|
||||
- Config IMAP/SMTP : copier `git-issues/imap-bridge.env.example` vers `.secrets/git-issues/imap-bridge.env`. Pour la boucle agent (optionnel) : `agent-loop.env.example` vers `.secrets/git-issues/agent-loop.env` (voir `.smartIde/agents/agent-loop.md`). Renseigner `IMAP_USER`, `IMAP_PASSWORD` (et optionnellement `SMTP_*` pour l'envoi ; par défaut SMTP reprend les mêmes host/port Bridge 1025). Optionnel : `MAIL_FILTER_TO=ai.support.lecoffreio@4nkweb.com` (seuls les mails envoyés à cette adresse sont listés) ; `MAIL_SINCE_DATE=10-Mar-2026` (seuls les mails à partir de cette date sont récupérés/listés).
|
||||
- Proton Mail Bridge (ou serveur IMAP/SMTP) en cours d'exécution.
|
||||
|
||||
**Scripts :** `mail-list-unread.sh`, `mail-get-thread.sh`, `mail-thread-log.sh`, `mail-send-reply.sh`, `mail-create-issue-from-email.sh`, `mail-mark-read.sh`. Le script batch `mail-to-issue.sh` reste disponible mais ne doit pas être utilisé dans le cadre du workflow agent (liste → lecture du fil → log du fil → décision → création/ réponse). Le script **`agent-loop.sh`** permet de lancer une boucle de surveillance des mails avec fichier témoin ; voir `.smartIde/agents/agent-loop.md`.
|
||||
|
||||
## API Wiki (tests préalables)
|
||||
|
||||
Script de test de l'API Wiki Gitea pour le même dépôt (prérequis à une éventuelle migration de `docs/` vers le wiki) :
|
||||
|
||||
| Script | Usage | Description |
|
||||
|--------|--------|-------------|
|
||||
| `wiki-api-test.sh` | `./git-issues/wiki-api-test.sh [--create]` | Teste GET list pages, GET page Home ; avec `--create` : POST une page test puis DELETE. |
|
||||
|
||||
**Prérequis :** même token que les issues (`GITEA_TOKEN` ou `.secrets/git-issues/token`). Pour l'écriture (création / suppression de pages), le token doit avoir les droits d'écriture sur le dépôt.
|
||||
|
||||
**Endpoints utilisés (référence Gitea API 1.25) :**
|
||||
|
||||
- `GET /repos/{owner}/{repo}/wiki/pages` — liste des pages
|
||||
- `GET /repos/{owner}/{repo}/wiki/page/{pageName}` — contenu d'une page (ex. `Home`)
|
||||
- `POST /repos/{owner}/{repo}/wiki/new` — créer une page (body : `title`, `content_base64`, `message`)
|
||||
- `PATCH /repos/{owner}/{repo}/wiki/page/{pageName}` — modifier une page
|
||||
- `DELETE /repos/{owner}/{repo}/wiki/page/{pageName}` — supprimer une page
|
||||
|
||||
Si le wiki n'a jamais été initialisé (aucune page créée via l'interface), les GET peuvent renvoyer 404 ou une liste vide. **Initialiser le wiki** : aller sur https://git.4nkweb.com/4nk/lecoffre_ng/wiki et créer au moins une page (ex. « Home ») via l'interface, puis relancer le script avec un token valide.
|
||||
|
||||
**Branche par défaut du wiki :** si l'API renvoie `object does not exist [id: refs/heads/master]` alors que la branche par défaut du dépôt wiki est autre (ex. `prod`), c'est un bug connu de certaines versions de Gitea (l'API suppose `master`). Contournements possibles : (1) **mettre à jour Gitea** (correctif dans les versions récentes, ex. PR #34244) ; (2) **changer la branche par défaut du wiki** en `master` dans les réglages du dépôt (Settings → Branches). Variable optionnelle `GITEA_WIKI_REF=master` (défaut si wiki configuré sur master).
|
||||
|
||||
### Migration docs/ → wiki
|
||||
|
||||
**Décision :** tout le contenu de `docs/` (racine du dépôt) est migré vers le wiki ; pas de CI sur le wiki.
|
||||
|
||||
**Script de migration :**
|
||||
|
||||
| Script | Usage | Description |
|
||||
|--------|--------|-------------|
|
||||
| `wiki-migrate-docs.sh` | `./git-issues/wiki-migrate-docs.sh [--dry-run] [fichier.md ...]` | Migre `docs/*.md` vers le wiki. `--dry-run` affiche le mapping sans appel API. Si des fichiers sont passés en argument, migre uniquement ceux-là. |
|
||||
| `wiki-put-page.sh` | `./git-issues/wiki-put-page.sh <page_name> <file_path>` | Met à jour ou crée une page wiki à partir d'un fichier local (ex. `Home docs/README.md`). |
|
||||
| `wiki-get-page.sh` | `./git-issues/wiki-get-page.sh <page_name>` | Affiche le markdown brut d'une page wiki (pour scripts ou agents). |
|
||||
|
||||
**Correspondance fichier → page wiki :** nom de fichier sans `.md`, `_` remplacé par `-`, title-case par segment. Ex. OPERATIONS.md → Operations, README.md → Readme.
|
||||
|
||||
Les 17 fichiers de `docs/` ont été migrés ; les pages sont visibles sur https://git.4nkweb.com/4nk/lecoffre_ng/wiki. La page **Home** contient le contenu de `docs/README.md` (index et correspondance). **`docs/` est exclu du versionnement** (`.gitignore`) : maintenir `docs/` localement (ne pas le supprimer), pousser les modifications vers le wiki avec `wiki-migrate-docs.sh` ou `wiki-put-page.sh` ; ne pas committer `docs/`.
|
||||
|
||||
### Après un clone
|
||||
|
||||
Le répertoire `docs/` n'est pas versionné. Pour disposer d'une copie locale (édition puis synchro wiki), recréer le contenu à partir du wiki : ex. `./git-issues/wiki-get-page.sh Home > docs/README.md`, ou créer les fichiers manuellement à partir des pages wiki listées dans la section Migration ci-dessus.
|
||||
|
||||
### Usage « wiki uniquement » pour les agents
|
||||
|
||||
La connaissance du projet peut reposer **uniquement sur le wiki** (sans lire `docs/`) : les agents peuvent exécuter `./git-issues/wiki-get-page.sh <PageName>` pour récupérer le contenu markdown d'une page et l'utiliser comme référence. Exemples : `./git-issues/wiki-get-page.sh Home`, `./git-issues/wiki-get-page.sh Operations`, `./git-issues/wiki-get-page.sh Code-Standards`. Prérequis : token Gitea (comme pour les autres scripts wiki). Les agents peuvent ainsi consulter la doc projet à la demande depuis le wiki, sans dépendre des fichiers locaux `docs/`. La documentation des projets gérés est dans **`projects/<id>/docs`** (ex. `projects/lecoffreio/docs`) ; la documentation propre à ia_dev est dans **`projects/ia_dev/docs`**.
|
||||
|
||||
## Agents (commandes)
|
||||
|
||||
- **/agent-loop** (`agent-loop.md`) : gère les boucles par exécutions délimitées uniquement (N itérations avec `agent-loop-chat-iterations.sh [N]`, ou x cycles récupération + traitement). Ne lance jamais agent-loop.sh ni agent-loop-treatment.sh en arrière-plan.
|
||||
- **/git-issues-process** (`git-issues-process.md`) : traite les issues Gitea et les mails en attente (workflow script au maximum, /fix ou /evol, /push-by-script). Voir le fichier de l'agent pour le workflow exact.
|
||||
|
||||
## Référence
|
||||
|
||||
- Wiki : https://git.4nkweb.com/4nk/lecoffre_ng/wiki
|
||||
- Documentation opérationnelle (ex. `docs/OPERATIONS.md`) : page wiki **Operations** (après migration).
|
||||
Loading…
x
Reference in New Issue
Block a user