# relay-baton **Infraestrutura portátil de continuação para agentes de codificação.** Passa estado de codificação comprimido entre Codex CLI, Claude Code e o que vier a seguir — sem recolar o log do chat, o diff ou o repositório. [English](../../README.md) · [한국어](./README.ko.md) · [日本語](./README.ja.md) · [简体中文](./README.zh-CN.md) · [繁體中文](./README.zh-TW.md) · [Español](./README.es.md) · [Français](./README.fr.md) · [Deutsch](./README.de.md) · **Português** · [Русский](./README.ru.md)
```bash # Codex bate num muro de quota no meio da tarefa. relay-baton detecta, # constrói um handoff compacto a partir do estado real do repo, e Claude continua. $ relay-baton run "refatorar o pipeline de 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 ``` --- ## Por que existe O trabalho de codificação com IA está se fragmentando entre ferramentas. Uma sessão real fica assim: - Codex CLI para um lote de edições. - Claude Code para outro. - Um laptop pela manhã, outra máquina à noite. - Uma context window que enche, quebra ou trunca em silêncio. A forma padrão hoje de mover trabalho entre agentes é **copiar e colar o log do chat** — ou pior, despejar o repo inteiro num prompt. Três problemas: 1. **Tokens.** Logs de chat são em sua maioria ruído. Você paga por esse ruído a cada turno. 2. **Continuidade.** O próximo agente recebe transcript, não *intenção*. 3. **Fragilidade.** Um arquivo perdido, um diff defasado, e o agente reinicia de uma premissa errada. relay-baton é um **harness local** que fica sob os agentes e transporta o *estado mínimo suficiente* através do handoff: um resumo compacto, um repo map e referências de arquivo — não um transcript. > **Gaste o mínimo de tokens possível enquanto unifica Codex CLI e Claude Code CLI num único fluxo.** ## A ideia ``` ┌─────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │ Codex │ → │ Fallback │ → │ Token Diet │ → │ Claude │ │ exec │ │ Detector │ │ Handoff │ │ Code │ └─────────┘ └──────────────┘ └──────────────┘ └────────┘ ↓ ↓ .ai-session/handoff.md, compact-state.md, repo-map.md, full-diff.patch, commands.log ``` Um baton-pass para agentes de codificação — primitiva em 4 passos: - **Detect** detecta quando o agente atual deixa de ser útil (quota, context, rate, errors). - **Capture** captura só o que importa (estado do repo, arquivos alterados, decisões, próximo passo). - **Compact** comprime dentro de um orçamento que o próximo agente consegue consumir. - **Hand off** entrega apenas depois dos quality gates. O handoff é um arquivo pequeno (`.ai-session/handoff.md`) mais referências. Tudo pesado (diff completo, log completo, repo map completo) fica em disco e é carregado sob demanda. ## Quick Start **Instalação (sem build)** ```bash # npm (todos os SO) 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 ``` **A partir do código-fonte (desenvolvimento)** ```bash pnpm install pnpm build pnpm relay-baton login # login Codex + Claude pnpm relay-baton doctor # checagem de ambiente pnpm relay-baton run "Corrigir o fluxo de upload de anexos de e-mail" --diet balanced ``` ## Fluxo de trabalho ```bash $ relay-baton init # cria .ai-session/ $ relay-baton run "corrigir teste flaky de upload" --diet balanced ... a saída do codex flui ao vivo ... ▲ 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 retoma, edita arquivos, termina ... $ relay-baton status # estado da sessão $ relay-baton budget # uso do budget do diet ``` Handoff manual sem fallback automático: ```bash $ relay-baton handoff --to claude --no-run --diet caveman ``` Troca entre múltiplos repositórios: ```bash $ relay-baton project add /path/to/repo-a --diet caveman $ relay-baton project switch repo-a $ relay-baton run "conectar o novo metrics endpoint" ``` ## Recursos - **Fallback automático** — Detecta `quota exceeded`, `rate limit exceeded`, `maximum context length` etc. na saída do agente. Pula linhas tipo grep e prosa que explica esses padrões (evita falsos positivos). - **Token diet** — 5 profiles determinísticos (`off · lite · balanced · caveman · ultra`). Lock/build/min excluídos, tail de logs, repo map no lugar do fonte. - **Quality gates** — Completude e budget verificados *antes* do lançamento do fallback. - **Auth-safe por padrão** — `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` removidos dos subprocesses. Opt-in só via `--allow-api-key-env`. Nunca armazenados, impressos ou logados. - **Project registry** — Registre múltiplos repos uma vez, execute em qualquer um com `--project` ou `--path`. - **Ink TUI** — Dashboard de project / sessão. Nunca lança agentes. - **Sem API própria** — relay-baton não chama a API da OpenAI / Anthropic. Só subprocess locais `codex` / `claude`. ## Comandos | Comando | Descrição | |---|---| | `relay-baton init` | Cria `.ai-session/` no repo atual | | `relay-baton doctor` | Checa git / codex / claude / env / config (`--deep` para diagnóstico estendido) | | `relay-baton verify` | Verificação end-to-end simulada — sem chamadas reais ao modelo | | `relay-baton login [agent]` | Fluxos de login Codex / Claude | | `relay-baton run ""` | Roda agente primário + detecta fallback + handoff | | `relay-baton route ""` | Prévia da dica de roteamento (somente leitura, `--json`) | | `relay-baton handoff --to claude` | Handoff manual (`--diet`, `--no-run`, `--force`) | | `relay-baton handoff history` | Lista o handoff atual + backups (apenas metadados) | | `relay-baton plan ""` | Plan-execute: o planejador escreve `plan.md` (`--with`, `--no-run`, `--then-execute`) | | `relay-baton execute` | Plan-execute: o executor implementa `plan.md` (`--with`, `--from`) | | `relay-baton compress-context` | Comprime o contexto vivo (state.md / commands.log) (`--dry-run`, `--threshold`) | | `relay-baton compact` / `squeeze` | Regera compact-state / repo-map / full-diff | | `relay-baton budget` | Mostra uso do context budget | | `relay-baton compress ` | Compressão determinística de markdown | | `relay-baton status` | Estado da sessão | | `relay-baton project add/list/switch/current/doctor/remove` | Gerencia registry de projects | | `relay-baton tui` | Dashboard Ink | Comandos com awareness de project aceitam `--project ` e `--path `. Prioridade: `--path` > `--project` > project ativo > 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 ``` Caminho padrão: `~/.relay-baton/projects.json`. `RELAY_BATON_PROJECTS_FILE` faz override (CI, sandbox, testes). Arquivo corrompido é salvo como `projects.json.corrupt-.bak` e o registry é resetado vazio — comandos continuam funcionando. ## Token diet profiles | Profile | Intenção | |---|---| | `off` | Truncamento mínimo | | `lite` | Limpeza leve | | `balanced` *(padrão)* | Uso diário | | `caveman` | Mínimo agressivo | | `ultra` | Compressão extrema | > `caveman` **não é tom jocoso** — significa *aggressive minimal-context*. Precisão técnica é preservada. ## Frente às alternativas | Abordagem | O que é levado | Custo em tokens | Continuidade | Modo de falha | |---|---|---|---|---| | Export bruto do chat | Transcript inteiro | Alto (a maior parte é ruído) | Frágil — agente relê seu próprio raciocínio | Estouro da context window | | Copy-paste prompting | O que o humano lembrou | Variável | Quebradiço | Drift silencioso do estado real | | Dump do repo inteiro | Tudo | Muito alto | Forte mas caro | Modelo trunca no meio do arquivo | | **relay-baton** | Resumo compacto + repo map + referências | **Baixo, limitado por profile** | Forte — guiado pelo estado *real* do repo | Falha *de forma ruidosa* via quality gates | ## Filosofia relay-baton é **ferramental pequeno e afiado para workflows de desenvolvimento AI-native**. - **Local-first.** Tudo vive no seu disco. Sem nuvem, sem daemon, sem telemetria, sem conta. - **Composabilidade.** Um diretório `.ai-session/` são só arquivos. Leia, grep, diff, anexe num PR. - **Transferência de estado leve.** Um handoff é um arquivo markdown, não um banco de dados. - **Determinístico antes de esperto.** Sem sumarização LLM dentro do harness — se o modelo erra o resumo, o handoff mente. Só budgets de caractere, regras estruturais e referências explícitas. - **Estado do repo é a fonte da verdade.** Conversa é interpretação; repo é fato. - **Eficiência de tokens é a feature** — não um botão escondido num menu. ### Princípios de design 1. É **work handoff**, não chat relay. 2. **Estado atual do repositório** vence qualquer histórico de conversa. 3. O handoff precisa ser **legível por humano**. 4. Cada UI é uma casca fina sobre `core`. 5. **Token diet não é feature secundária — é a feature principal.** ## Direção futura relay-baton começa como harness de fallback de dois agentes. A mesma primitiva escala mais longe: - **Cadeias de relay multi-agente** — Codex → Claude → OpenCode → de volta a Codex. - **Árvores de sessão com bifurcação** — Forka uma tarefa em tentativas paralelas; reconcilia via diffs. - **Estado de relay remoto** — Push de `.ai-session/` para um remote compartilhado para a próxima máquina retomar. - **Workflows orquestrados** — Modos `review`, `diagnose`, `continue` (autopilot limitado com checkpoints explícitos). - **Mais adapters** — OpenCode, Gemini CLI, Aider, qualquer coisa com interface subprocess local sã. A forma do harness não muda: detect, capture, compact, hand off. ## Requisitos | Item | Versão / Nota | |---|---| | Node.js | ≥ 20 | | pnpm | ≥ 9 | | git | obrigatório | | `codex` | **requer assinatura ChatGPT Plus ou superior** | | `claude` | **requer assinatura Claude Pro ou superior** | > relay-baton não chama diretamente a API da OpenAI / Anthropic. Usa a **autenticação por assinatura** das CLIs locais `codex` / `claude`. Auth por API key é tecnicamente possível, mas **bloqueada por padrão** (opt-in via `--allow-api-key-env`). ## Login ```bash pnpm relay-baton login # ambos pnpm relay-baton login codex pnpm relay-baton login claude ``` `claude --version` passar **não** significa que você está logado. Se aparecer "Not logged in", rode novamente o comando acima. ## Notas de versão **Mais recente: v1.6.1** — [English](../../release-notes/v1.6.1.md) · [한국어](../../release-notes/ko/v1.6.1.md) · [Português](../../release-notes/pt-BR/v1.6.1.md) O relay-baton chegou à **disponibilidade geral (GA) na v1.0.0**; a mais recente é **v1.6.1**. - Histórico completo de versões: [`CHANGELOG.md`](../../CHANGELOG.md) - Notas de correção detalhadas por versão: [release-notes index](../../release-notes/README.md) ### Instalação ```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. Detalhes em [`LICENSE`](../../LICENSE). > Documentação completa (detalhes dos quality gates, semântica dos arquivos `.ai-session/`, schema de config, atalhos do TUI, troubleshooting) em [English README](../../README.md) e [`install/install.md`](../../install/install.md).