# ai-tools

Dépôt central pour l'**outillage IA interne de Pysae** : skills Claude Code, package Python, image Docker CI et relais webhook GitLab.

## Prérequis

- **Clés d'accès AWS** (`AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`) — **recommandé pour tous les skills d'infra** (`infra-ops`, `aws-eks-optimize`, `teammate-access`, `aws-secrets`, `infra-perf`…) et pour la **résolution des variables/tokens via AWS Secrets Manager**. La majorité des outils (ArgoCD, Datadog, MongoDB Atlas, Slack, URIs Mongo…) résolvent leurs secrets depuis les secrets `ai-tools/<env>/secrets` (et `pysae/*`) au moment de l'installation et à l'exécution. Sans accès AWS, ces outils et skills restent non configurés. Si l'AWS CLI n'est pas encore configurée, `tools install` la configure en interactif (région Pysae par défaut : `eu-west-3`).
- **`curl`** pour le bootstrap (sur Windows : `winget install -e --id cURL.cURL`).
- Le reste de la toolchain (`uv`, Python 3.14, Node, Git, Claude Code…) est installé automatiquement par `tools install` — rien à préparer à la main.

## Installation

### Depuis le registre (recommandé)

```bash
# Linux / macOS
curl -fsSL https://tools.pysae.com/pysae-ai-tools/install.sh | bash

# Windows (PowerShell)
irm https://tools.pysae.com/pysae-ai-tools/install.ps1 | iex

# Windows (cmd.exe) — requiert cURL
winget install -e --id cURL.cURL
curl -fsSL https://tools.pysae.com/pysae-ai-tools/install.cmd -o install.cmd && install.cmd
```

### Depuis un clone git (mode éditable, pour contribuer)

Installe le package en mode éditable (`-e`) et symlinke le plugin Claude Code vers le repo : les modifications du code et des skills sont prises en compte immédiatement, sans réinstaller.

```bash
git clone https://gitlab.com/pysae/tools/ai-tools.git
cd ai-tools
./install.sh            # mode local auto-détecté depuis le repo
```

### Installer les outils gérés

Une fois le package installé, installer (ou mettre à jour) les CLI et serveurs MCP gérés par Pysae :

```bash
pysae-ai-tools tools install            # installation/màj interactive
pysae-ai-tools tools install --configure-only  # (ré)applique la config seule — auth, MCP, contextes, env vars — sans installer ni mettre à jour un binaire
pysae-ai-tools tools status [<tool>…]   # état détaillé d'un ou plusieurs outils
pysae-ai-tools tools status --binaries-only  # versions des binaires uniquement (rapide, sans auth/config/réseau)
pysae-ai-tools tools require <tool>…    # check binaire prêt/pas prêt (utilisé par les skills)
```

`--configure-only` rejoue uniquement la **partie configuration** de chaque outil sélectionné (enregistrement MCP dans chaque CLI assistant présent — `~/.claude.json`, `~/.codex/config.toml` —, tokens ArgoCD, contextes kube, permissions Claude, intégration shell, variables d'env résolues) — jamais de téléchargement ni de mise à jour de binaire. Utile après une rotation de credentials ou pour réparer une config qui a dérivé. Les binaires sans configuration propre sont marqués `skipped — nothing to configure`.

`--install-only` est son miroir : uniquement l'**installation/mise à jour du binaire**, sans aucune configuration (pas d'auth, d'enregistrement MCP, de contextes, ni de résolution de variables d'env). Utile au **build d'image** (les binaires sont figés dans l'image, la config se fait au runtime) ou quand aucun credential n'est disponible. Les deux flags sont mutuellement exclusifs.

`--non-interactive` (sur `tools install` et `tools configure`) force l'absence totale de prompt — pas de checklist, pas de question de variable d'env — **même sur un TTY** ; la sélection sauvée (ou les défauts) est utilisée et les secrets sont auto-résolus quand c'est possible. C'est déjà le comportement implicite hors TTY (CI, pipe) ; le flag le rend explicite et déterministe. Sur `tools configure`, il faut le combiner à `--all` ou `--required-only` (sinon il n'y a rien à sélectionner sans checklist). Exemple build d'image :

```sh
pysae-ai-tools tools configure --all --non-interactive   # fige la sélection, aucun prompt
pysae-ai-tools tools install --install-only              # pose les binaires, config au runtime
```

## Outils gérés (`tools install`)

`tools install` orchestre l'installation de toute la toolchain en tiers (fondations d'abord, dépendants ensuite). **★** = outil REQUIRED (installé par défaut, son échec fait sortir en non-zéro) ; les autres sont optionnels. **🔐** = dépend d'un accès AWS (tokens résolus via AWS Secrets Manager `ai-tools/<env>/secrets`, ou auth EKS via `aws eks`).

**Toolchains de langage** (toutes ★) :

| Toolchain | Rôle | Secrets |
|-----------|------|---------|
| ★ `uv` | Toolchain Python Astral (interpréteurs + CLIs Python) | — |
| ★ `python` | Python 3.14 (géré par uv) | — |
| ★ `poetry` | Gestionnaire de dépendances Python | — |
| ★ `fnm` | Fast Node Manager (versions Node) | — |
| ★ `node` | Node.js (LTS) | — |

**Binaires CLI** :

| CLI | Rôle | Secrets |
|-----|------|---------|
| ★ `aws` | Auth EKS, Secrets Manager, S3 | `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` (interactif via `aws configure`) |
| ★ `git` | Version control | — |
| `claude-code` | Claude Code CLI (Anthropic) | — |
| `codex` | Codex CLI (OpenAI) | — |
| `glab` | GitLab CLI — MRs, issues, pipelines | — |
| `gh` | GitHub CLI (désélectionné par défaut) | — |
| `kubectl` | Kubernetes — pods, logs, exec ; contextes `pysae-dev`/`pysae-prod` | 🔐 EKS via `aws eks update-kubeconfig` |
| `helm` | Templating et releases de charts Kubernetes | — |
| `argocd` | Déploiements GitOps | 🔐 `ARGOCD_AUTH_TOKEN_DEV`, `ARGOCD_AUTH_TOKEN_PROD` |
| `terraform` | Infrastructure as code | — |
| `prefect` | Orchestration de workflows | — |
| `mongo-tools` | mongodump / mongorestore / mongoexport | — |
| `atlas` | MongoDB Atlas CLI — clusters, users, network (profils dev/prod/org) | 🔐 clés MongoDB Atlas |
| `jq` | Processeur JSON en ligne de commande | — |
| `docker` | Conteneurs (désélectionné par défaut) | — |
| `postman` | Postman / Newman CLI (désélectionné par défaut) | — |
| `bruno` | Bruno — client API open-source, alternative à Postman (désélectionné par défaut) | — |

**Serveurs MCP** (enregistrés dans chaque CLI assistant présent : `~/.claude.json` pour Claude, `~/.codex/config.toml` pour Codex) :

| MCP | Rôle | Secrets |
|-----|------|---------|
| `chrome-mcp` | Chrome DevTools (automatisation navigateur) | — |
| `kubernetes-mcp-dev` | Kubernetes dev — pods, logs, exec (contexte `pysae-dev`, read/write) | — |
| `kubernetes-mcp-prod` | Kubernetes prod (contexte `pysae-prod`, read-only) | — |
| `gitlab-mcp` | API GitLab (MRs, issues, jobs) | `GITLAB_PERSONAL_ACCESS_TOKEN` |
| `datadog-mcp` | Logs, métriques, monitors Datadog | 🔐 `DD_API_KEY`, `DD_APP_KEY` |
| `mongo-mcp-dev` | Requêtes MongoDB (dev, read/write) | 🔐 `MONGO_URI_DEV` |
| `mongo-mcp-prod` | Requêtes MongoDB (prod, read-only) | 🔐 `MONGO_URI_PROD` |
| `mongodb-atlas-mcp-dev` | Admin clusters MongoDB Atlas (dev) | 🔐 (clés Atlas) |
| `mongodb-atlas-mcp-prod` | Admin clusters MongoDB Atlas (prod) | 🔐 (clés Atlas) |
| `mongodb-atlas-mcp-org` | Admin organisation MongoDB Atlas (opt-in) | 🔐 (clés Atlas org) |
| `postman-mcp` | Collections et specs Postman (désélectionné par défaut) | `POSTMAN_API_KEY` |

**Plugin & outils embarqués** :

| Outil | Rôle | Secrets |
|-------|------|---------|
| `claude-plugin` | Skills Pysae + marketplace Claude Code, et allow-list outils/MCP par défaut dans `settings.json` | — |
| `codex-plugin` | Skills Pysae pour Codex (`~/.agents/skills`, si le CLI `codex` est présent), et accès réseau du sandbox (`network_access` dans `config.toml`) | — |
| `slack-env` | Env vars pour les commandes `pysae-ai-tools slack` | 🔐 `SLACK_BOT_TOKEN`, `SLACK_CLIENT_ID`, `SLACK_CLIENT_SECRET` |
| `mcp-cleanup-hook` | Hook `SessionEnd` qui kill les MCP orphelins (Linux + macOS) | — |
| `pysae-env-shell` | `pysae-env` dans tous les shells installés (bash/zsh/fish/PowerShell + shim `.bat` cmd.exe) | — |

## Mise à jour

La CLI **s'auto-met à jour automatiquement** : après n'importe quelle commande, au plus une fois par heure (cache TTL 1h), elle vérifie si une version plus récente existe (PyPI en install registre, nouveaux commits sur `origin/main` en clone git) et lance `self-update` toute seule. C'est activé par défaut (`auto_update = true` dans `~/.config/pysae-ai-tools/config.toml`) ; à désactiver pour ne recevoir qu'une notification. La vérification est silencieuse en CI et en sortie non-interactive.

Mise à jour manuelle à tout moment :

```bash
pysae-ai-tools self-update    # git pull + reinstall depuis un clone, ou bump PyPI
```

## Charger un environnement dans le shell (`env activate`)

`pysae-ai-tools env activate [--env dev|prod]` résout toutes les variables supportées pour un
environnement (défaut : `dev`) et les charge dans le shell courant **sous leur nom usuel**
(`MONGO_URI`, `ATLAS_PUBLIC_KEY`, `ARGOCD_AUTH_TOKEN`, `ARGOCD_SERVER`…). La commande n'exporte
rien elle-même : elle **émet des assignations shell** à passer à `eval` (les logs de résolution
partent sur stderr, jamais sur stdout). La résolution est non-interactive — aucune variable ne
déclenche de prompt navigateur/OAuth.

### La fonction `pysae-env` (recommandé)

`tools install` installe par défaut `pysae-env` dans **tous les shells présents sur la machine**
(bash, zsh, fish, PowerShell — approche façon `conda init`, plus un shim `pysae-env.bat` sur le PATH
pour cmd.exe), qui fait le `eval` pour toi. Au quotidien :

```bash
pysae-env activate --env dev   # charge l'env dev
pysae-env deactivate           # restaure l'état précédent
pysae-env run pytest           # exécute une commande avec l'env dev chargé (one-shot)
pysae-env run -e prod ./deploy.sh   # idem en prod, sans toucher au shell courant
pysae-env dotenv --env prod    # écrit un fichier .env (KEY=value)
pysae-env list              # (passe-plat vers `env list`, resolve, …)
```

`env run` est le pendant one-shot d'`activate` : il charge les variables de l'environnement (mêmes règles, même whitelist projet) **uniquement pour la commande lancée**, puis rend son code de sortie — le shell courant n'est jamais modifié. Les options `-e/--env` et `--ignore-project-config` se placent **avant** la commande ; tout ce qui suit est passé tel quel (`pysae-env run -e prod pytest -v`).

Les environnements valides sont **`dev`**, **`prod`**, **`testing`** et **`all`**. Avec `dev`/`prod`/`testing`
les variables sont exposées sous leur **nom usuel** (`MONGO_URI`, `ATLAS_PUBLIC_KEY`…) ; avec `all` chaque
variable garde son **nom d'origine** (`MONGO_URI_DEV`, `MONGO_URI_PROD`…, les deux environnements).

**Restriction par projet.** `activate` et `generate` respectent une whitelist optionnelle dans le
`.pysae-ai-tools.yaml` du repo (cherché dans le dossier courant puis les parents, sans sortir du dépôt git).
`resolve` n'est **jamais** restreint — c'est le point d'entrée des skills, qui doivent tout voir :

```yaml
env:
  variables: [MONGO_URI, ATLAS_PUBLIC_KEY]   # ne charger que celles-ci (matché sur le nom résolu)
```

`null` (défaut) charge **toutes** les variables ; une **liste vide** n'en charge aucune. Si au final aucune
variable n'est chargée, la commande **échoue** (exit ≠ 0). Passer `--ignore-project-config` pour ignorer la whitelist.

Ouvre un nouveau shell (ou re-source ton rc) après l'install pour en disposer. `pysae-ai-tools
uninstall` retire proprement la fonction de tous les rc (et le shim `.bat`). Pour l'ajouter manuellement :
`eval "$(pysae-ai-tools env shell-init)"` (bash/zsh), `… --shell fish | source` (fish),
`… --shell powershell | Out-String | Invoke-Expression` (PowerShell). Sous cmd.exe, écris le shim
sur le PATH : `pysae-ai-tools env shell-init --shell cmd > "%USERPROFILE%\.local\bin\pysae-env.bat"`.

### Formes brutes (sans `pysae-env`)

Si tu n'as pas `pysae-env` (rc non re-sourcé, shim non installé), le format est auto-détecté selon le
shell (surchargeable avec `--shell posix|powershell|cmd|fish`) — **Linux, macOS et Windows** sont
supportés, seule la façon de consommer la sortie change :

```bash
# Linux / macOS / Git Bash / WSL (bash, zsh, sh, ksh)
eval "$(pysae-ai-tools env activate)"              # dev
eval "$(pysae-ai-tools env activate --env prod)"   # prod

# fish
pysae-ai-tools env activate --shell fish | source

# Windows PowerShell
pysae-ai-tools env activate --shell powershell | Invoke-Expression

# Windows cmd.exe
for /f "delims=" %i in ('pysae-ai-tools env activate --shell cmd') do @%i
```

`env activate` mémorise la valeur d'origine de chaque variable dans `$PYSAE_ENV_ACTIVATE_BACKUP`.
`pysae-ai-tools env deactivate` la relit pour **restaurer les anciennes valeurs** (ou supprimer les
variables qui n'existaient pas), puis efface le backup. Même mécanisme de consommation par shell :

```bash
# Linux / macOS / Git Bash / WSL (bash, zsh, sh, ksh)
eval "$(pysae-ai-tools env deactivate)"

# fish
pysae-ai-tools env deactivate --shell fish | source

# Windows PowerShell
pysae-ai-tools env deactivate --shell powershell | Invoke-Expression

# Windows cmd.exe
for /f "delims=" %i in ('pysae-ai-tools env deactivate --shell cmd') do @%i
```

`env dotenv [--env dev|prod] [-o .env]` écrit les variables résolues dans un fichier `.env`
(`KEY=value`, perms `0600`) au lieu de les exporter — pratique pour Docker `--env-file` ou dotenv.
Résolution non-interactive. Si le fichier existe déjà, il est **fusionné** : les variables gérées
par pysae-ai-tools sont mises à jour en place (ou ajoutées), les autres lignes (variables tierces,
commentaires) sont préservées.

`env list [--json]` liste toutes les variables supportées, leur nom résolu et leur chaîne de
résolution.

## Workflow complet (idée → deploy)

```mermaid
flowchart TD
    A["Idéation et cadrage<br/>/product-discover"] --> B["Création du ticket<br/>/glab-issue-create"]
    B --> R["Affinage jusqu'à « prêt »<br/>/glab-issue-refine"]
    R --> C{"Écran UI standard ?<br/>(décision automatique)"}
    subgraph DAUTO ["Pilote design — autonome (design-autopilot-batch)"]
        D["Maquette HTML générée<br/>/design-generate"]
        D -. "corrige, revérifie · jusqu'à maquette conforme + critères couverts" .-> D
        D --> DP["Maquette publiée<br/>URL partageable sur le ticket"]
    end
    C -->|oui| D
    DP --> E["Validation humaine (PM)<br/>juge le rendu, puis « validé »"]
    C -->|"non · sur-mesure"| M["Design manuel<br/>designer + Figma"]
    M --> E
    E --> F["Implémentation<br/>/code-implement"]
    subgraph CAUTO ["Pilote code — autonome (code-autopilot)"]
        F --> G["Revue de code<br/>/code-review-fix"]
        G -. "corrige, re-revue · jusqu'à revue OK (max 5)" .-> G
        G --> H["Intégration continue (CI)"]
        H --> I["Déploiement<br/>/ci-deploy"]
    end
    I --> P(["Production"])
```

Trois phases, **deux pilotes automatiques séparés par une seule décision humaine** :

1. **De l'idée au ticket prêt.** L'idée devient un ticket avec des critères d'acceptation testables, puis on lève les zones d'ombre jusqu'à ce qu'il soit prêt à travailler.
2. **Design, quand c'est un écran standard.** Le système décide seul si la feature est un écran courant (liste, formulaire, détail, onglets, modale) ou une interaction sur-mesure. Si c'est courant : il génère une maquette HTML fidèle au design system, la vérifie en boucle (vraies couleurs et composants du produit, tous les critères couverts) jusqu'à ce qu'elle soit propre, et la publie sur une URL partageable. Sinon, il s'arrête et laisse la main à un designer.
3. **Validation humaine, le seul point de contrôle.** Le PM ouvre l'URL, juge le rendu, le fait éventuellement tester par des utilisateurs, puis valide ou demande une nouvelle passe. Une maquette douteuse s'arrête ici : elle n'atteint jamais la prod.
4. **Du code à la prod, en autopilote.** Une fois validé, l'implémentation, la revue, la CI et le déploiement s'enchaînent sans intervention.

Ce qui dure, c'est le **contrat** (critères d'acceptation + constitution du design). La maquette est **jetable** : régénérée à la demande, jamais stockée ni partagée à la main.

Les deux pilotes autonomes sont la phase 2 (design) et la phase 4 (code) ; les commandes de chaque étape sont dans la section [Skills](#skills) ci-dessous. *À venir : génération automatique de la merge request depuis la maquette validée.*

## Skills

### Code lifecycle

| Skill | Description | Invocation |
|-------|-------------|------------|
| `code-implement` | Implémenter un ticket GitLab : branche, code, tests, commits, MR | `/pysae:code-implement` |
| `code-autopilot` | Pipeline autonome : implémentation, boucle de review, CI, déploiement review | `/pysae:code-autopilot` |
| `code-autopilot-batch` | Orchestrateur batch : pioche les tickets `agent::ready`, score (déterministe + Haiku), enchaîne `/code-autopilot` séquentiellement | `/pysae:code-autopilot-batch` |
| `code-quality` | Lancer tests, linters, pre-commit hooks ; corriger les erreurs avec des commits atomiques | `/pysae:code-quality` |
| `code-review` | Revue de code (bugs, sécurité, perf, qualité) — mode local interactif ou CI headless | `/pysae:code-review` |
| `code-review-fix` | Boucle review-fix : review, correction de tous les problèmes, re-review jusqu'à APPROVED | `/pysae:code-review-fix` |
| `code-review-pre-release` | Audit pré-release : revue du diff depuis le dernier tag semver, vérification de la cohérence des changelogs en attente vs commits et changements observés (correction optionnelle add/reword/remove sur la branche release), triage des problèmes avec création optionnelle de tickets, enchaînement sur `/ci-release`, puis post du recap sur le canal Slack tech du repo | `/pysae:code-review-pre-release` |
| `code-get-next-version` | Déterminer la prochaine version semver d'une application (auto-détection depuis les changelogs, confirmation utilisateur avec changelog agrégé en local, retour direct en CI) — utilisé par `/ci-release` et `/code-review-pre-release` | `/pysae:code-get-next-version` |
| `code-changelog` | Ajouter une entrée changelog dans `changelogs/` | `/pysae:code-changelog` |
| `code-release-notes` | Générer et committer les notes de release destinées aux utilisateurs (jusqu'à 3 langues FR/EN/IT × 3 formats markdown/Google Play/App Store sous `docs/release-notes/`) pour la prochaine version, à partir des commits et entrées changelog depuis le dernier tag. Langues, formats et prompt de génération configurables par projet via `docs/release-notes/.config.yaml` (défaut : tout) — invoqué par `/ci-release` et `/code-review-pre-release` juste avant la création du tag | `/pysae:code-release-notes` |
| `code-profile` | Profiler le code (cProfile, py-spy, pyinstrument, clinic, chrome-devtools MCP) sur un test, un nouveau test ou l'app, analyser les bottlenecks et proposer des pistes d'optimisation | `/pysae:code-profile` |
| `code-python-guidelines` | Appliquer les conventions Python Pysae lors de l'écriture ou la revue de code | `/pysae:code-python-guidelines` |
| `dast-fix` | Auto-remédiation des findings DAST (OWASP ZAP) Medium+ d'un scan planifié : triage, correction des findings prouvés appartenant à ce service, MR `dast-autofix/*` pour vérification et auto-merge par le gate CI, escalade du reste en tickets GitLab. Tourne en CI via `claude-ci "/dast-fix"` | `/pysae:dast-fix` |

### Design phase

| Skill | Description | Invocation |
|-------|-------------|------------|
| `design-generate` | Générer un prototype HTML fidèle au design system (feature commodity), vérifié par `design check` / `design coverage` puis la **boucle proto-review** (navigateur : écrans atteignables + fidélité visuelle), prêt pour revue PM + handoff dev | `/pysae:design-generate` |
| `design-autopilot-batch` | Orchestrateur batch au-dessus de `design-generate` : pioche les tickets `workflow::Ready` UI, décide l'éligibilité **automatiquement** (prefilter déterministe + classifieur Haiku + seuil, sans label manuel), enchaîne `design-generate --auto`, rend chaque proto en URL Pages et passe le ticket en `design::review` | `/pysae:design-autopilot-batch` |

**Workflow** (fronts React+Tailwind, features commodity) : `design kit` génère la constitution `design.md` (tokens + catalogue) depuis le code → `design-generate` produit un prototype HTML à vraies classes-tokens depuis les FR du ticket → boucle `design check` jusqu'à `CLEAN` → `design coverage` vérifie qu'aucun FR n'est sans écran → **boucle proto-review** (navigateur headless : aucun overlay bloquant au chargement, chaque écran atteignable, fidélité à l'app réelle) → proto poussé sur la branche `design/<iid>` du front, rendu en **URL GitLab Pages** (même lien pour revue PM et user-test) → revue PM (label GitLab) → PR React au dev. Contrat durable = `design.md` + AC du ticket ; le proto HTML est jetable (régénéré). Détail complet : [`docs/specs/2026-06-09-design-phase-harness-design.md`](docs/specs/2026-06-09-design-phase-harness-design.md).

**Full auto** : `design-autopilot-batch` (CLI `pysae-ai-tools agent design-run`) draine les tickets `workflow::Ready` à signal UI sans label manuel. L'éligibilité est décidée en 2 étages (prefilter déterministe gratuit + classifieur Haiku au-dessus d'un seuil de confiance) ; `design::eligible` / `design::skip` restent des overrides humains optionnels. Le gate PM reste humain (revue de `design::review` + URL Pages).

Commandes CLI (project-agnostic, auto-découverte des tokens `@theme` + du catalogue `components/ui/`) :

- `pysae-ai-tools design kit --root <front> --out design.md` — génère la constitution `design.md`.
- `pysae-ai-tools design check <fichier> [--root <front>]` — oracle déterministe (R1 couleur brute, R2 valeur arbitraire sauf `-[var(--token)]`, R3 primitive hors catalogue, R4 palette Tailwind par défaut ; exit 1 si `VIOLATIONS`).
- `pysae-ai-tools design coverage <spec.md> <coverage-map.md>` — liste les FR de la spec sans écran (exit 1 si `GAPS`).

### GitLab — Issues & Epics

| Skill | Description | Invocation |
|-------|-------------|------------|
| `glab-issue-create` | Créer un ticket GitLab avec templates, labels, poids et epic parent (scoring automatique) | `/pysae:glab-issue-create` |
| `glab-issue-refine` | Affiner un ticket en `workflow::Refinement` : lever toutes les incertitudes fonctionnelles et techniques (lecture code, POC jetables), réécrire la description au présent sans trace des doutes initiaux, transition vers `workflow::Ready` | `/pysae:glab-issue-refine` |
| `glab-issue-find` | Trouver un ticket par IID, URL, auteur, assignee ou mots-clés | `/pysae:glab-issue-find` |
| `glab-issue-next` | Choisir le prochain ticket à implémenter depuis le backlog (scoring par priorité/colonne) | `/pysae:glab-issue-next` |
| `glab-issue-audit` | Auditer les tickets ouverts : conformité labels, placement board, templates, titres | `/pysae:glab-issue-audit` |
| `glab-issue-workflow-update` | Réconcilier les statuts du board avec la réalité MR/changelog : MR ouverte → « In progress » (« Under review » si approuvée), MR toutes mergées → « To deploy », ticket de la dernière version déployée → fermé | `/pysae:glab-issue-workflow-update` |
| `glab-issue-from-ai-note` | Créer des issues GitLab de followup depuis les Open questions d'un fichier ai-note | `/pysae:glab-issue-from-ai-note` |
| `glab-epic-attach-issues` | Trouver les tickets orphelins et les rattacher aux epics (scoring + validation manuelle) | `/pysae:glab-epic-attach-issues` |
| `glab-epic-create` | Générer titre et description d'une epic à partir de ses tickets enfants, ou créer une epic depuis un thème | `/pysae:glab-epic-create` |
| `glab-user-find` | Trouver un utilisateur GitLab par nom (fuzzy match dans le groupe Pysae) | `/pysae:glab-user-find` |

### GitLab — Merge Requests

| Skill | Description | Invocation |
|-------|-------------|------------|
| `glab-mr` | Créer une MR depuis la branche courante avec le bon template | `/pysae:glab-mr` |
| `glab-mr-find` | Trouver une MR par IID, URL, auteur ou mots-clés | `/pysae:glab-mr-find` |
| `glab-mr-approve` | Approuver une MR via glab CLI | `/pysae:glab-mr-approve` |
| `glab-mr-merge` | Fusionner une MR via glab CLI (avec contrôles préalables) | `/pysae:glab-mr-merge` |
| `glab-mr-rebase` | Rebaser une MR sur sa branche cible (avec résolution auto des conflits) et push | `/pysae:glab-mr-rebase` |
| `glab-mr-refresh` | Rebaser les MR ouvertes sur leur branche cible et relancer les pipelines | `/pysae:glab-mr-refresh` |
| `glab-clone-group` | Cloner tous les repos du groupe Pysae récursivement, vérifier les remotes, pull | `/pysae:glab-clone-group` |
| `glab-mr-checkout` | Checkout la branche associée à une MR ou un ticket | `/pysae:glab-mr-checkout` |
| `git-worktree` | Créer un worktree git pour isoler les changements | `/pysae:git-worktree` |

### CI/CD

| Skill | Description | Invocation |
|-------|-------------|------------|
| `ci-run` | Lancer un job CI ou une chaîne de dépendances sur la branche courante | `/pysae:ci-run` |
| `ci-run-local` | Rejouer un job CI en local : env GitLab reconstruit (CI_* + variables groupe/projet + YAML) + artefacts d'entrée, exécution dans l'image Docker du job | `/pysae:ci-run-local` |
| `ci-prepare` | Installer les dépendances projet en mode CI (Node via nvm, Python via poetry/pip) | `/pysae:ci-prepare` |
| `ci-debug` | Déboguer les échecs de pipeline CI (logs, analyse, correctifs proposés) | `/pysae:ci-debug` |
| `ci-reports` | Lire le rapport de tests JUnit d'un pipeline (cas en échec, message, stack trace) et mesurer la durée des tests (`--slowest`) | `/pysae:ci-reports` |
| `ci-artifacts` | Inspecter et télécharger les artefacts d'un job CI (coverage, fichiers générés, logs) | `/pysae:ci-artifacts` |
| `ci-deploy` | Déployer une application (prod, review, dev) — utilise le job `redeploy` si disponible ; pour les apps mobiles, publication optionnelle sur les stores | `/pysae:ci-deploy` |
| `ci-deploy-status` | Vérifier le statut de déploiement (review, dev, prod) via GitLab, CI, kubectl | `/pysae:ci-deploy-status` |
| `ci-release` | Release complète : bump semver, pipeline, déploiement prod, monitoring rollout. Supporte les releases `support/vX.Y.x` (hotfix/backport d'une ancienne ligne : version bornée à la plage, déploiement mobile/stores only, back-merge dans la branche support) | `/pysae:ci-release` |
| `ci-rollback` | Rollback ou redéploiement prod (utilise `redeploy` si disponible, sinon `deploy_prod`) | `/pysae:ci-rollback` |

### Infra & AWS

| Skill | Description | Invocation |
|-------|-------------|------------|
| `project-configuration` | Lire et expliquer la config `.pysae-ai-tools.yaml` d'un repo (un projet, le repo courant, ou tous) : identité, routing Slack, topologie deploy k8s, ressources AWS (S3/ECR/ElastiCache/secrets), Prefect, flags release/board — et documenter chaque section du schéma pour le LLM | `/pysae:project-configuration` |
| `infra-ops` | Opérations infrastructure : kubectl, ArgoCD, Helm, déploiements, finops | `/pysae:infra-ops` |
| `aws-eks-optimize` | Optimiser les node groups EKS (SPOT et on-demand) en croisant Spot Advisor (taux prédictif), notre historique d'évictions CloudTrail, le prix (spot + on-demand) et la performance effective (vCPU × fréquence × IPC). Par environnement et par node group : plusieurs mix d'instances proposés avec l'évolution de 4 facteurs (coût, perf, coût/perf, risque d'éviction) et la liste Terraform | `/pysae:aws-eks-optimize` |
| `teammate-access` | Onboarder ou offboarder un collaborateur dans l'IaC Terraform : accès AWS IAM, EKS et MongoDB Atlas, à partir de l'email, du niveau et des environnements | `/pysae:teammate-access` |
| `aws-secrets` | Lire ou écrire des secrets applicatifs dans AWS Secrets Manager | `/pysae:aws-secrets` |
| `env-resolve` | Résoudre des variables d'environnement (MCP config → AWS Secrets Manager) et les exporter dans le shell | `/pysae:env-resolve` |

### Performance & Monitoring

| Skill | Description | Invocation |
|-------|-------------|------------|
| `infra-perf` | Diagnostics performance API : latence, erreurs, pods, CPU/RAM par service | `/pysae:infra-perf` |
| `infra-perf-setup` | Créer les monitors Datadog pour l'alerting performance API (P99, erreurs, restarts) | `/pysae:infra-perf-setup` |
| `infra-perf-report` | Planifier des rapports de santé API automatiques sur Slack (6h-9h en semaine) | `/pysae:infra-perf-report` |
| `mongodb-index-usage` | Analyser l'usage des index MongoDB (via `$indexStats`, mongosh) pour détecter les index inutilisés et l'espace disque qu'ils gaspillent ; regroupe les databases en cohortes (flotte tenant vs singletons) et raisonne globalement, avec la volumétrie data/disque/index par collection | `/pysae:mongodb-index-usage` |

### Activity Tracker

| Skill | Description | Invocation |
|-------|-------------|------------|
| `track-install` | Installer le hook de suivi d'activité (git, glab, fichiers, skills, agents) | `/pysae:track-install` |
| `track-dashboard` | Ouvrir le tableau de bord d'activité dans le navigateur | `/pysae:track-dashboard` |
| `track-manual` | Enregistrer du temps manuellement sur un ticket ou une epic | `/pysae:track-manual` |
| `track-context` | Attribuer un contexte (ticket, epic, labels) à une session existante | `/pysae:track-context` |

### Forfait Claude

| Skill | Description | Invocation |
|-------|-------------|------------|
| `usage-install` | Installer le hook PreToolUse qui notifie sur le bureau dès 90 % d'usage du forfait (session 5H / semaine, puis tous les 5 %), affiche le surcoût d'extra-usage, peut bloquer au-delà d'un seuil, et estime le coût en mode clé API | `/pysae:usage-install` |

### API & Intégrations

| Skill | Description | Invocation |
|-------|-------------|------------|
| `pysae-api` | S'authentifier (Auth0) et appeler l'API Pysae (dev/prod) : découverte dynamique du spec OpenAPI puis requêtes authentifiées | `/pysae:pysae-api` |
| `openapi-to-postman` | Convertir un spec OpenAPI en collection Postman avec variables d'environnement | `/pysae:openapi-to-postman` |
| `openapi-to-bruno` | Convertir un spec OpenAPI en collection Bruno (`.bru`), alternative open-source à Postman | `/pysae:openapi-to-bruno` |

### Communication & Reporting

| Skill | Description | Invocation |
|-------|-------------|------------|
| `slack-ask-review` | Poster une demande de review sur le bon canal Slack avec le contexte MR | `/pysae:slack-ask-review` |
| `stats-weekly-summary` | Générer un récap hebdomadaire de l'activité engineering formaté pour Slack | `/pysae:stats-weekly-summary` |
| `stats-kpi-ops` | Collecter et formater les KPIs tech hebdo/mensuels du sheet « Suivi des indicateurs Opérations » (uptime, latence p95, incidents, vélocité, DORA) en bloc colonne prêt à coller | `/pysae:stats-kpi-ops` |
| `post-mortem` | Générer un double rapport post-mortem (interne + externe) depuis un incident | `/pysae:post-mortem` |

### Support client (Patrick / CSM)

| Skill | Description | Invocation |
|-------|-------------|------------|
| `support-bug-investigate` | Enquêter sur un bug Pysae en lisant le code cloné localement ; livre un rapport concis (30-40 lignes) avec cause racine et correctif | `/pysae:support-bug-investigate` |
| `support-ticket-create` | Créer un ticket Airtable Customer Service depuis une conversation Intercom, avec pré-analyse injectée dans Notes | `/pysae:support-ticket-create` |
| `support-mr-fix` | Ouvrir une MR de correction directe après un ticket Airtable et une issue GitLab — gate « petit fix sans risque » puis délégation à `/code-implement` | `/pysae:support-mr-fix` |
| `support-product-ticket` | Créer une suggestion produit dans la DB Notion Roadmap (sans investigation GitLab) | `/pysae:support-product-ticket` |
| `support-intercom-article` | Rédiger un article Help Center Intercom opérationnel (FR + EN + IT), draft publié via MCP Intercom + Composio | `/pysae:support-intercom-article` |
| `support-intercom-news` | Produire une annonce News Intercom (HTML autonome pour copier-coller) pour une feature shippée | `/pysae:support-intercom-news` |

`glab-issue-create` accepte un flag `--from-airtable <recID>` pour enchaîner depuis un ticket support : il lit le ticket Airtable, mappe `Sujet` → projet et `Criticité` → label priority, ajoute les labels `workflow::To Do` + `Support 📞`, et écrit l'URL de l'issue dans le champ `Ticket Gitlab` du ticket Airtable après création.

### Meta & DX

| Skill | Description | Invocation |
|-------|-------------|------------|
| `clawd-compound` | Extraire les apprentissages de la session et les persister dans CLAUDE.md | `/pysae:clawd-compound` |
| `clawd-skill-review` | Auditer les skills contre les bonnes pratiques Anthropic | `/pysae:clawd-skill-review` |
| `clawd-route-eval` | Mesurer le déclenchement des skills en langage naturel (recall@1 + collisions) via les agents de la session, sans clé API | `/pysae:clawd-route-eval` |
| `pysae-design` | Appliquer la charte graphique Pysae à tous les documents et artefacts visuels | `/pysae:pysae-design` |
| `product-discover` | Scanner le codebase, détecter les angles morts fonctionnels, proposer des features | `/pysae:product-discover` |

## Skills publiés sur claude.ai (Claude Desktop)

Une whitelist de skills est aussi poussée vers l'API Workspace Anthropic à
chaque merge sur `main` qui les modifie (job CI `publish-skills`). Les
membres de l'orga les voient dans Claude Desktop et n'ont rien à installer
côté skill, le serveur Anthropic les sert.

| Skill | Pré-requis côté poste user |
|-------|----------------------------|
| `pysae-design` | aucun |
| `clawd-skill-review` | aucun |
| `clawd-route-eval` | aucun (route via les agents de la session, pas de clé API) |
| `clawd-compound` | aucun |
| `post-mortem` | aucun (les références projet sont bundlées dans le skill) |
| `product-discover` | `pysae-ai-tools` + `glab` installés, monorepo Pysae cloné localement |

La whitelist est définie dans [`pysae_ai_tools/skills/whitelist.py`](pysae_ai_tools/skills/whitelist.py).
Critère d'éligibilité : skill pure-prompt OU compatible avec un poste sur
lequel `pysae-ai-tools` est installé. Pour publier manuellement en local, voir
[CONTRIBUTING.md](CONTRIBUTING.md#publier-les-skills-sur-claudeai).

## Fonctionnement

Les skills tournent dans trois modes :

- **Interactif (dev)** — les développeurs invoquent les skills localement via Claude Code CLI (`/pysae:<skill>`)
- **CI (headless)** — l'image Docker est utilisée comme image de job GitLab CI ; le template `.ai-tools-skill` lance `claude /<skill>` en mode non-interactif
- **Claude Desktop (non-tech)** — les skills de la whitelist sont disponibles directement dans Claude Desktop pour toute l'orga, sans installation côté user

## Autopilot batch (`/code-autopilot-batch`)

Orchestrateur batch au-dessus de `/code-autopilot` : draine une queue GitLab de tickets opt-in sans intervention humaine. Le PM tague les tickets éligibles, l'orchestrateur les ramasse en séquence, ouvre une MR draft, lance review + CI + merge, et émet un footer JSON parseable.

### Workflow

1. **PM** pose le label `agent::ready` sur un ticket éligible (scope clair, < 1j dev, hors paths sensibles)
2. L'orchestrateur (local manuel, `gstack /loop 15m`, ou CI scheduled) :
   - Pulle les tickets `agent::ready` multi-projets
   - Score : métier déterministe (priorité × type × âge) × signal LLM (Haiku) en moyenne pondérée 70/30
   - Filtre les paths sensibles (regex + LLM) avec override `agent::override-sensitive`
   - Transition labels : `agent::ready` → `agent::wip` + commentaire pickup horodaté
   - Subprocess `claude /code-autopilot <issue_url>` (implement → review-fix → CI → merge → footer JSON)
   - Si escalation : `agent::wip` → `agent::blocked` + commentaire structuré (raison, run_id)
   - Reclaim automatique des WIP orphelins (> 2h sans pickup marker)
3. Report stdout (table ASCII) + Slack (`#tech-ci-agent-autopilot`)

### Labels (à créer au niveau groupe `pysae`)

| Label | Posé par | Sémantique |
|-------|----------|------------|
| `agent::ready` | PM (opt-in explicite) | Ticket éligible à l'agent |
| `agent::wip` | Orchestrateur (pickup) | Lock implicite contre double-pickup |
| `agent::blocked` | Orchestrateur (escalade) | Humain doit reprendre, voir commentaire |
| `agent::override-sensitive` | PM | Force l'agent à traiter malgré la garde regex/LLM |

### Modes d'invocation

```bash
# Local manuel, repo courant
claude /code-autopilot-batch

# Multi-projets, dry-run pour valider sans muter
claude /code-autopilot-batch --project shift --project driver --dry-run

# Cap budget (defaults: --max-tickets 5 --max-tokens 100M, calibrated for
# interactive sessions where real Pysae tickets observed at 3-30M tokens each)
claude /code-autopilot-batch --max-tickets 3 --max-tokens 30000000 --timeout 1h

# Scheduled CI run (conservative: ~2-3 tickets/run, $30-40 cap)
claude /code-autopilot-batch --max-tickets 3 --max-tokens 30000000

# Replay manuel d'un ticket (bypasse les gardes sensitive)
claude /code-autopilot-batch --tickets https://gitlab.com/pysae/shift/app/-/issues/42

# Sans LLM (score métier déterministe seul, pas de clé API requise)
claude /code-autopilot-batch --skip-llm-rank
```

### Exit codes (utiles en CI scheduled)

- `0` : tout traité avec succès, aucune escalade
- `1` : ≥ 1 ticket escaladé en `agent::blocked` (fait échouer le job pour visibilité équipe)
- `2` : erreur technique (GitLab API down, `claude` absent, etc.)

## Contribuer

Setup de développement (linters, tests), publication manuelle des skills, et
intégration des reviews IA dans un projet (template CI + variables groupe) :
voir [CONTRIBUTING.md](CONTRIBUTING.md).
