
Tutoriels vérifiés et vidéos de démonstration provenant de votre README. Un agent IA l'exécute dans un bac à sable Docker renforcé et le rejoue dans un conteneur frais avant que quoi que ce soit ne soit publié.
# readme2demo — tutoriels vérifiés et vidéos de démonstration à partir de votre README
[](https://github.com/alphacrack/readme2demo/actions/workflows/ci.yml)
[](https://github.com/alphacrack/readme2demo/blob/main/LICENSE)
[](https://github.com/alphacrack/readme2demo/blob/main/pyproject.toml)
<!-- HERO:START — scripts/self-demo.sh rewrites this block with a fresh self-run.
Run it locally (needs Docker + VHS + a model credential):
./scripts/self-demo.sh
It runs readme2demo on this very repo, following docs/step-by-step.md,
and drops the verified demo.gif in right here. -->
[](https://github.com/alphacrack/readme2demo/tree/main/examples/readme2demo)
<sub>▶ readme2demo générant son propre tutoriel : un agent IA exécute ce README dans un bac à sable, un nouveau conteneur rejoue chaque étape, puis la démo est rendue. Sortie complète de l'auto-exécution dans <a href="https://github.com/alphacrack/readme2demo/blob/main/examples/readme2demo">examples/readme2demo</a> · exécution sur un autre projet dans <a href="https://github.com/alphacrack/readme2demo/blob/main/examples/toolhive">examples/toolhive</a>.</sub>
<!-- HERO:END -->
**Générateur de tutoriel et de vidéo de démonstration vérifié par IA.** Pointez-le vers un dépôt. Un agent IA lit le README et l'exécute réellement à l'intérieur d'un bac à sable Docker renforcé. Ce n'est qu'après une relecture en environnement vierge réussie qu'il génère une vidéo de démonstration (VHS) et publie le tutoriel, le guide pas à pas et le document de dépannage.
La valeur ne réside pas dans « l'IA qui écrit un tutoriel » — c'est que le tutoriel **a été exécuté, deux fois**, avant que vous ne le voyiez.
**Voyez-le en action :** parcourez [les exemples d'exécutions vérifiées](https://github.com/alphacrack/readme2demo/tree/main/examples) — de vrais tutoriels, guides pas à pas et vidéos de démonstration, chacun rejoué indépendamment dans un conteneur propre avant d'être publié.
## Comment ça marche
```
repo URL → ingest/plan → agent run (in Docker) → normalize transcript
→ distill minimal path → VERIFY replay in fresh container
→ generate tutorial.md + troubleshooting.md → render VHS video
```
Consultez [architecture/README.md](https://github.com/alphacrack/readme2demo/blob/main/architecture/README.md) pour l'architecture complète.
## Prérequis
- Python ≥ 3.10, Docker
- Authentification, l'une des suivantes :
- **Votre abonnement Claude (pas de clé API) :** une installation locale de Claude Code. Les passes planificateur/condenseur/tutoriel s'exécutent sur votre abonnement via `--llm-backend claude-cli` (`claude -p`), et l'agent dans le bac à sable s'authentifie avec `CLAUDE_CODE_OAUTH_TOKEN` (créez-en un : `claude setup-token`). Entièrement pris en charge pour les exécutions **auto-hébergées, mono-opérateur** sur vos propres dépôts — les plans Pro/Max incluent un crédit mensuel Agent SDK qui couvre `claude -p`.
- `ANTHROPIC_API_KEY` — facturation API à l'utilisation ; idéal pour le passage à l'échelle et la concurrence, et **obligatoire si vous hébergez readme2demo en tant que service pour d'autres** (selon les conditions d'Anthropic, l'authentification par abonnement peut ne pas alimenter un produit multi-locataire — voir [ROADMAP.md](https://github.com/alphacrack/readme2demo/blob/main/ROADMAP.md)). Ajoutez `--anthropic [model]` pour exécuter l'agent en bac à sable sur le moteur OpenHands avec un modèle Claude au lieu de claude-code.
- **Google Gemini (`--gemini [model]`) :** une seule `GEMINI_API_KEY` exécute toute la session sans Claude — les passes planificateur/condenseur/tutoriel utilisent Gemini et l'agent en bac à sable tourne sur le moteur OpenHands (également sur Gemini). Aucun nom de modèle n'est intégré (Google retire les anciens avec une erreur 404 définitive) : nommez-le par exécution (`--gemini gemini-3.5-flash`) ou exportez `GEMINI_MODEL` une fois pour toutes. Installez l'extra : `pip install 'readme2demo[gemini]'`.
- **OpenAI (`--openai [model]`) :** même structure que Gemini — une seule `OPENAI_API_KEY` alimente les passes et l'agent OpenHands, aucun nom de modèle n'est intégré (`--openai gpt-5.1` ou exportez `OPENAI_MODEL`). Installez l'extra : `pip install 'readme2demo[openai]'`.
- Optionnel : `LLM_API_KEY` + `LLM_MODEL` pour `--engine openhands` (expérimental) avec tout autre fournisseur litellm — les préréglages ci-dessus les remplissent automatiquement
```bash
# exécution sur votre abonnement Claude (pas de clé API) — pris en charge pour les exécutions auto-hébergées
claude setup-token # interactif : approuvez dans le navigateur, puis COPIEZ le
# token sk-ant-oat01-... qu'il affiche (n'utilisez PAS $(...))
export CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...
readme2demo run <url-du-dépôt> --llm-backend claude-cli
# exécution sur facturation API à l'utilisation (passage à l'échelle, concurrence, hébergement pour d'autres)
export ANTHROPIC_API_KEY=sk-ant-...
readme2demo run <url-du-dépôt> # --llm-backend auto choisit api
# exécution de toute la session sur Google Gemini (agent OpenHands + passes Gemini)
pip install 'readme2demo[gemini]'
docker build -t readme2demo/openhands:latest images/openhands # une fois : image du bac à sable OpenHands
export GEMINI_API_KEY=...
readme2demo run <url-du-dépôt> --gemini gemini-3.5-flash # modèle nommé par exécution
export GEMINI_MODEL=gemini-3.5-flash # ...ou défini une fois, puis :
readme2demo run <url-du-dépôt> --gemini # le simple drapeau lit GEMINI_MODEL
# exécution de toute la session sur OpenAI (agent OpenHands + passes OpenAI)
pip install 'readme2demo[openai]'
export OPENAI_API_KEY=sk-...
readme2demo run <url-du-dépôt> --openai gpt-5.1 # ou exportez OPENAI_MODEL une fois
# exécution de l'agent OpenHands avec un modèle Claude sur facturation API
export ANTHROPIC_API_KEY=sk-ant-...
readme2demo run <url-du-dépôt> --anthropic # utilise le modèle de configuration par défaut
```
## Installation
```bash
pip install -e ".[dev]"
docker build -t readme2demo/base:latest images/base/
docker build -t readme2demo/openhands:latest images/openhands/ # seulement pour --engine openhands / --gemini / --openai / --anthropic
```
## Utilisation
```bash
readme2demo run https://github.com/example/tool
readme2demo run -gr https://github.com/example/tool # identique, via le drapeau
readme2demo run -s mon_guide.md # guide seul : pas de dépôt, votre guide est autonome
readme2demo run -gr https://github.com/example/tool -s mon_guide.md # les deux : votre guide pilote tout
readme2demo run https://github.com/example/tool --gemini gemini-3.5-flash # exécution sur Google Gemini (nécessite GEMINI_API_KEY ; utilise l'agent OpenHands ; --gemini seul lit GEMINI_MODEL)
readme2demo run https://github.com/example/tool --openai gpt-5.1 # exécution sur OpenAI (nécessite OPENAI_API_KEY ; utilise l'agent OpenHands ; --openai seul lit OPENAI_MODEL)
readme2demo run https://github.com/example/tool --anthropic # agent OpenHands avec un modèle Claude sur ANTHROPIC_API_KEY
readme2demo run https://github.com/example/tool --allow-docker-socket # pour les outils qui gèrent les conteneurs (COMPROMIS DE SÉCURITÉ : perce l'isolation du bac à sable — dépôts de confiance uniquement)
readme2demo run https://github.com/example/tool --skip-video --budget-usd 3
readme2demo resume runs/tool-20260702-... --from-stage render
readme2demo report runs/tool-20260702-...
```
Le dépôt est **optionnel** : passez-le en positionnel ou avec `-gr/--github-repo`, fournissez un guide avec `-s/--step-by-step`, ou les deux. Au moins l'un des deux est requis. Avec un guide seul, aucun dépôt n'est cloné — le guide doit être autonome (installer un paquet publié, ou cloner ce dont il a besoin comme étape explicite) ; la relecture en conteneur vierge vérifie toujours chaque commande.
Les sorties atterrissent dans `runs/<id-exec>/` : `tutorial.md`, `step_by_step.md`, `troubleshooting.md`, `commands.sh`, `demo.tape`, `demo.mp4`, `demo.gif`, plus `manifest.json` avec les statuts des étapes et le coût total.
## GitHub Action — vérifiez votre README en CI
Obtenez une croix rouge quand votre README cesse de fonctionner. L'action composite à la racine du dépôt installe readme2demo à partir de son propre checkout épinglé, construit l'image du bac à sable, exécute le pipeline complet contre l'URL de votre dépôt et **fait échouer la vérification lorsque la relecture en conteneur vierge ne passe pas** :
```yaml
name: readme-check
on:
push:
branches: [main] # le mode url teste le HEAD de la branche par défaut — voir la remarque ci-dessous
paths: ["README.md"]
schedule:
- cron: "0 6 * * 1" # hebdomadaire : détecter les changements du monde extérieur sous un README inchangé
permissions:
contents: read
jobs:
verify-readme:
runs-on: ubuntu-latest
steps:
- uses: alphacrack/readme2demo@main # épinglez un tag ou un SHA une fois publié
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
skip-video: "true"
```
> **⚠ Mode URL uniquement — cela ne vérifie PAS encore les têtes de PR.** L'action clone le **HEAD distant de la branche par défaut** de `repo-url` (par défaut : le dépôt exécutant le workflow) ; l'ingestion n'accepte que les URLs https, `--depth 1`, pas d'épinglage de ref. Sur `pull_request`, cela testerait le README de la branche *de base* — pas celui de la PR — donc ne l'utilisez pas sur des PR en attendant un verdict avant fusion. Jusqu'à ce que [#74](https://github.com/alphacrack/readme2demo/issues/74) (ingestion par chemin local) arrive, `on: push` sur la branche par défaut et un cron sont les déclencheurs honnêtes ; une entrée `repo-path` pour une véritable vérification des têtes de PR arrivera avec.
**Coût :** chaque exécution dépense de l'argent réel d'agent sur votre `ANTHROPIC_API_KEY` — typiquement quelques dollars, plafonné par `budget-usd` (par défaut `"5"` ; l'exécution est interrompue si dépassé). Le filtre `paths:` plus un cron maintient les dépenses proportionnelles aux modifications du README, et `skip-video: "true"` réduit le temps réel (le rendu ne coûte pas d'argent API non plus).
La vérification échoue de deux manières distinctes, nommées dans le journal d'étape : **README cassé** (pipeline terminé, relecture en environnement vierge échouée — détectée via `readme2demo report --json`, car `readme2demo run` se termine délibérément par 0 sur une exécution terminée mais non vérifiée) et **infrastructure d'action cassée** (sortie non nulle du pipeline : pré-vérification, budget, Docker). Sorties : `verified` (`"true"`/`"false"`) et `run-dir` ; `tutorial.md`, `step_by_step.md`, `verify.log` (et `demo.gif` lorsque la vidéo est activée) sont téléchargés comme artefact `readme2demo-run`.
## step_by_step.md — la source de la vidéo
La vidéo de démonstration est toujours construite **à partir** de `step_by_step.md` : ses étapes sont analysées, et chaque commande sécurisée pour la démo et ancrée devient une commande tapée dans la vidéo avec le titre de l'étape affiché comme commentaire à l'écran. Trois façons dont elle peut exister, par ordre de priorité :
1. **Vous en passez une :** `readme2demo run <url> -s mon_guide.md` — injectée dans le clone comme guide faisant autorité ; le planificateur et l'agent la suivent, la vidéo la joue. L'`<url>` est optionnelle ici : `readme2demo run -s mon_guide.md` exécute seulement le guide dans un bac à sable vide.
2. **Le dépôt en fournit une** (`step_by_step.md` / `step-by-step.md` à la racine ou dans `docs/`, n'importe quelle casse) : même traitement, automatiquement.
3. **Aucune n'existe :** le pipeline *génère* un `step_by_step.md` détaillé — chaque commande du `commands.sh` vérifié sous forme d'étape numérotée avec les sorties réelles capturées — puis construit la vidéo à partir de celui-ci. Prêt à être contribué au dépôt.
Les étapes d'installation (clonages, installations, builds) sont documentées dans le guide mais exclues de la vidéo — elle est jouée sur l'arbre de travail vérifié et déjà construit, montrant le résultat.
Chaque tutoriel porte un badge de vérification : `✅ Vérifié le <date> · image <digest> · commit <sha>` — ou un `⚠ NON VÉRIFIÉ` bruyant si la relecture n'a pas passé. La sortie non vérifiée n'est jamais publiée silencieusement.
## Configuration
Les drapeaux CLI > `readme2demo.toml` > valeurs par défaut :
```toml
engine = "claude-code" # ou "openhands"
model = "claude-sonnet-5" # passes planificateur/condenseur/tutoriel
max_turns = 60
budget_usd = 5.0
base_image = "readme2demo/base:latest"
skip_video = false
```
## Développement
```bash
python -m pytest tests/ -q # 175 tests unitaires, aucun besoin de docker/réseau
ruff check src/ tests/ # lint de correction (correspond à CI)
python -m pytest -m integration # nécessite docker + clés API (aucune pour l'instant)
```
## Modèle de sécurité
Les READMEs sont du code non fiable. L'agent s'exécute *à l'intérieur* d'un conteneur renforcé (cap-drop ALL, no-new-privileges, limites mémoire/CPU/pids, non-root) — ce conteneur est la frontière de permission. Compromis connu du MVP : la clé API entre dans le bac à sable ; utilisez une clé dédiée à faible limite. Un proxy de sortie injectant la clé côté hôte est prévu (Jalon 4).
Modèle de menace complet et signalement privé de vulnérabilité : [SECURITY.md](https://github.com/alphacrack/readme2demo/blob/main/SECURITY.md).
## Projet & communauté
- [Exemples](https://github.com/alphacrack/readme2demo/tree/main/examples) — sorties vérifiées commitées comme preuve
- [Feuille de route](https://github.com/alphacrack/readme2demo/blob/main/ROADMAP.md) — où cela se dirige (y compris la direction exploratoire hébergée/SaaS)
- [Contribuer](https://github.com/alphacrack/readme2demo/blob/main/CONTRIBUTING.md) — la règle unique non négociable, et comment s'installer
- [Politique de sécurité](https://github.com/alphacrack/readme2demo/blob/main/SECURITY.md) · [Code de conduite](https://github.com/alphacrack/readme2demo/blob/main/CODE_OF_CONDUCT.md)
- [Architecture](https://github.com/alphacrack/readme2demo/blob/main/architecture/README.md) — limites des étapes et diagrammes
Sous licence MIT. Le CLI et le pipeline de vérification sont, et resteront, gratuits et open source.
## Contributeurs
Un immense merci à tous ceux qui ont contribué à readme2demo !
[](https://github.com/alphacrack/readme2demo/graphs/contributors)
<a href="https://github.com/alphacrack/readme2demo/graphs/contributors">
<img src="https://contrib.rocks/image?repo=alphacrack/readme2demo" alt="Contributeurs" />
</a>