# relay-baton **Infrastructure portable de continuation pour agents de codage.** Transmet un état de codage compressé entre Codex CLI, Claude Code et ce qui viendra ensuite — sans recoller le log de chat, le diff ou le dépôt. [English](../../README.md) · [한국어](./README.ko.md) · [日本語](./README.ja.md) · [简体中文](./README.zh-CN.md) · [繁體中文](./README.zh-TW.md) · [Español](./README.es.md) · **Français** · [Deutsch](./README.de.md) · [Português](./README.pt-BR.md) · [Русский](./README.ru.md)
```bash # Codex frappe un mur de quota au milieu d'une tâche. relay-baton détecte, # construit un handoff compact à partir de l'état réel du dépôt, et Claude continue. $ relay-baton run "refactoriser le pipeline d'upload" --diet caveman ● relay chain: codex → claude ▲ codex hit a limit — fallback pattern detected: "rate limit exceeded" → building a compact handoff for claude… ✓ claude resumed from .ai-session/handoff.md ``` --- ## Pourquoi ça existe Le travail de codage IA se fragmente entre outils. Une vraie session ressemble à ça : - Codex CLI pour un lot d'éditions. - Claude Code pour un autre. - Un portable le matin, une autre machine le soir. - Une fenêtre de contexte qui se remplit, casse, ou tronque silencieusement. La méthode par défaut aujourd'hui pour déplacer le travail entre agents est de **copier-coller le log de chat** — ou pire, vider le dépôt entier dans un prompt. Trois problèmes : 1. **Tokens.** Les logs de chat sont surtout du bruit. Tu paies ce bruit à chaque tour. 2. **Continuité.** L'agent suivant reçoit le *transcript*, pas l'*intention*. 3. **Fragilité.** Un fichier manqué, un diff périmé, et l'agent redémarre depuis une prémisse fausse. relay-baton est un **harness local** qui se place sous les agents et transporte le *minimum d'état suffisant* à travers le handoff : un résumé compact, une carte du dépôt et des références fichiers — pas un transcript. > **Dépense le moins de tokens possible tout en fusionnant Codex CLI et Claude Code CLI en un seul flux.** ## L'idée ``` ┌─────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │ Codex │ → │ Fallback │ → │ Token Diet │ → │ Claude │ │ exec │ │ Detector │ │ Handoff │ │ Code │ └─────────┘ └──────────────┘ └──────────────┘ └────────┘ ↓ ↓ .ai-session/handoff.md, compact-state.md, repo-map.md, full-diff.patch, commands.log ``` Une passe de témoin pour agents de codage — primitive en 4 étapes : - **Detect** détecter quand l'agent actuel n'est plus utile (quota, contexte, rate, errors). - **Capture** capturer ce qui compte (état du dépôt, fichiers modifiés, décisions, étape suivante). - **Compact** compresser sous un budget que l'agent suivant peut réellement consommer. - **Hand off** passer la main seulement après les quality gates. Le handoff est un petit fichier (`.ai-session/handoff.md`) + des références. Le lourd (diff complet, log complet, repo map complet) reste sur disque et n'est chargé qu'à la demande. ## Quick Start **Installation (sans build)** ```bash # npm (tous les OS) npm i -g @relay-baton/cli # -> relay-baton # macOS / Linux — Homebrew brew tap dgl1231/relay-baton && brew install relay-baton # Windows — Scoop / Winget scoop bucket add relay-baton https://github.com/dgl1231/scoop-relay-baton && scoop install relay-baton winget install dgl1231.relay-baton ``` ```bash relay-baton doctor relay-baton login relay-baton run "..." --diet balanced ``` **Depuis les sources (développement)** ```bash pnpm install pnpm build pnpm relay-baton login # connexion Codex + Claude pnpm relay-baton doctor # vérification de l'environnement pnpm relay-baton run "Corriger le flux d'upload des pièces jointes" --diet balanced ``` ## Flux de travail ```bash $ relay-baton init # crée .ai-session/ $ relay-baton run "corriger le test d'upload flaky" --diet balanced ... la sortie de codex est diffusée en direct ... ▲ codex hit a limit — fallback pattern detected: "maximum context length" → building a compact handoff for claude… ✓ Handoff Quality Gate: ok · Token Diet Quality Gate: ok ... claude reprend, modifie les fichiers, termine ... $ relay-baton status # état de la session $ relay-baton budget # consommation du budget diet ``` Handoff manuel sans fallback automatique : ```bash $ relay-baton handoff --to claude --no-run --diet caveman ``` Bascule entre plusieurs dépôts : ```bash $ relay-baton project add /path/to/repo-a --diet caveman $ relay-baton project switch repo-a $ relay-baton run "câbler le nouveau endpoint metrics" ``` ## Fonctionnalités - **Fallback automatique** — Détecte `quota exceeded`, `rate limit exceeded`, `maximum context length`, etc. dans la sortie de l'agent. Les lignes de résultat grep et la prose qui explique les patterns sont ignorées (évite les faux positifs). - **Token diet** — 5 profiles déterministes (`off · lite · balanced · caveman · ultra`). Lock/build/min exclus, tail des logs, repo map à la place du source. - **Quality gates** — Complétude et budget vérifiés *avant* le lancement du fallback. - **Auth-safe par défaut** — `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` retirés des subprocess. Opt-in seulement via `--allow-api-key-env`. Jamais stockés, imprimés, ou loggés. - **Project registry** — Enregistre plusieurs dépôts une fois, exécute des commandes contre n'importe lequel avec `--project` ou `--path`. - **Ink TUI** — Tableau de bord project/session. Ne lance jamais d'agents. - **Pas d'API propre** — relay-baton n'appelle pas l'API OpenAI / Anthropic. Uniquement les subprocess locaux `codex` / `claude`. ## Commandes | Commande | Description | |---|---| | `relay-baton init` | Crée `.ai-session/` dans le dépôt courant | | `relay-baton doctor` | Vérifie git / codex / claude / env / config (`--deep` pour un diagnostic étendu) | | `relay-baton verify` | Vérification end-to-end simulée — aucun appel réel au modèle | | `relay-baton login [agent]` | Flux de login Codex / Claude | | `relay-baton run ""` | Lance l'agent primaire + détecte fallback + handoff | | `relay-baton route ""` | Aperçu de l’indication de routage (lecture seule, `--json`) | | `relay-baton handoff --to claude` | Handoff manuel (`--diet`, `--no-run`, `--force`) | | `relay-baton handoff history` | Liste le handoff courant + les sauvegardes (métadonnées seulement) | | `relay-baton plan ""` | Plan-execute : le planificateur écrit `plan.md` (`--with`, `--no-run`, `--then-execute`) | | `relay-baton execute` | Plan-execute : l'exécuteur implémente `plan.md` (`--with`, `--from`) | | `relay-baton compress-context` | Compresse le contexte courant (state.md / commands.log) (`--dry-run`, `--threshold`) | | `relay-baton compact` / `squeeze` | Régénère compact-state / repo-map / full-diff | | `relay-baton budget` | Affiche l'usage du context budget | | `relay-baton compress ` | Compression déterministe d'un markdown | | `relay-baton status` | État de la session | | `relay-baton project add/list/switch/current/doctor/remove` | Gestion du registry de projets | | `relay-baton tui` | Tableau de bord Ink | Les commandes project-aware acceptent `--project ` et `--path `. Priorité : `--path` > `--project` > projet actif > cwd. ## Project registry ```bash relay-baton project add /path/to/relay-baton --name relay-baton --diet caveman --primary codex --fallback claude relay-baton project switch relay-baton relay-baton status --project relay-baton ``` Emplacement par défaut : `~/.relay-baton/projects.json`. `RELAY_BATON_PROJECTS_FILE` override le chemin (CI, sandbox, tests). Un fichier corrompu est sauvegardé en `projects.json.corrupt-.bak` et le registry est réinitialisé vide — les commandes continuent à fonctionner. ## Token diet profiles | Profile | Intention | |---|---| | `off` | Troncature minimale | | `lite` | Nettoyage léger | | `balanced` *(par défaut)* | Usage quotidien | | `caveman` | Minimal agressif | | `ultra` | Compression extrême | > `caveman` **n'est pas un ton humoristique** — il signifie *aggressive minimal-context*. La précision technique est préservée. ## Face aux alternatives | Approche | Ce qui passe | Coût en tokens | Continuité | Mode d'échec | |---|---|---|---|---| | Export brut du chat | Transcript entier | Élevé (majoritairement du bruit) | Fragile — l'agent relit son propre raisonnement | Débordement de fenêtre de contexte | | Copier-coller prompting | Ce dont l'humain se souvient | Variable | Cassant | Drift silencieux par rapport à l'état réel | | Dump du dépôt entier | Tout | Très élevé | Fort mais cher | Le modèle tronque en plein milieu | | **relay-baton** | Résumé compact + repo map + références fichiers | **Faible, plafonné par profile** | Fort — guidé par l'état *réel* du dépôt | Échoue *bruyamment* via quality gates | ## Philosophie relay-baton est **un outillage petit et aiguisé pour les workflows AI-natifs**. - **Local-first.** Tout vit sur ton disque. Pas de cloud, pas de daemon, pas de télémétrie, pas de compte. - **Composabilité.** Un dossier `.ai-session/` n'est que des fichiers. Lis-les, grep, diff, mets-les dans une PR. - **Transfert d'état léger.** Un handoff est un fichier markdown, pas une base de données. - **Déterministe avant tout.** Pas de résumé LLM dans le harness — si le modèle résume mal, le handoff ment. Budgets de caractères, règles structurelles, références explicites uniquement. - **L'état du dépôt est la source de vérité.** La conversation est interprétation ; le dépôt est fait. - **L'efficience en tokens est la fonctionnalité** — pas un bouton caché dans un menu. ### Principes de conception 1. C'est du **work handoff**, pas du chat relay. 2. **L'état actuel du dépôt** prime sur tout historique de conversation. 3. Le handoff doit être **lisible par un humain**. 4. Chaque UI est une fine couche au-dessus de `core`. 5. **Le token diet n'est pas une option secondaire — c'est la fonctionnalité centrale.** ## Direction future relay-baton démarre comme un harness de fallback à deux agents. La même primitive s'étend : - **Chaînes de relay multi-agent** — Codex → Claude → OpenCode → retour à Codex. - **Arbres de session ramifiés** — Forke une tâche en tentatives parallèles ; réconcilie via diffs. - **État de relay distant** — Push de `.ai-session/` vers un remote partagé pour que la machine suivante reprenne. - **Workflows orchestrés** — Modes `review`, `diagnose`, `continue` (autopilot borné avec checkpoints explicites). - **Plus d'adapters** — OpenCode, Gemini CLI, Aider, tout ce qui a une interface subprocess locale propre. La forme du harness ne change pas : detect, capture, compact, hand off. ## Prérequis | Item | Version / Note | |---|---| | Node.js | ≥ 20 | | pnpm | ≥ 9 | | git | requis | | `codex` | **requiert un abonnement ChatGPT Plus ou supérieur** | | `claude` | **requiert un abonnement Claude Pro ou supérieur** | > relay-baton n'appelle pas directement l'API OpenAI / Anthropic. Il utilise l'**auth par abonnement** des CLIs locales `codex` / `claude`. L'auth par API key est techniquement possible mais **bloquée par défaut** (opt-in via `--allow-api-key-env`). ## Login ```bash pnpm relay-baton login # les deux pnpm relay-baton login codex pnpm relay-baton login claude ``` `claude --version` qui passe ne veut **pas** dire connecté. Si tu vois "Not logged in", relance la commande ci-dessus. ## Notes de version **Dernière: v1.6.1** — [English](../../release-notes/v1.6.1.md) · [한국어](../../release-notes/ko/v1.6.1.md) · [Français](../../release-notes/fr/v1.6.1.md) relay-baton est **disponible en version stable (GA) depuis v1.0.0** ; la plus récente est **v1.6.1**. - Historique complet des versions: [`CHANGELOG.md`](../../CHANGELOG.md) - Notes de correctif détaillées par version: [release-notes index](../../release-notes/README.md) ### Installation ```bash npm i -g @relay-baton/cli # -> relay-baton brew tap dgl1231/relay-baton && brew install relay-baton # macOS / Linux scoop bucket add relay-baton https://github.com/dgl1231/scoop-relay-baton && scoop install relay-baton # Windows winget install dgl1231.relay-baton # Windows ``` ## License MIT. Détails dans [`LICENSE`](../../LICENSE). > Documentation complète (détails des quality gates, sémantique des fichiers `.ai-session/`, schéma de config, raccourcis du TUI, troubleshooting) dans [English README](../../README.md) et [`install/install.md`](../../install/install.md).