# relay-baton **為編碼代理打造的可攜式延續性基礎設施** 在 Codex CLI、Claude Code 與未來出現的工具之間 ― 不需要重新貼上聊天紀錄、diff 或整個倉庫 ― 傳遞壓縮後的編碼狀態。 [English](../../README.md) · [한국어](./README.ko.md) · [日本語](./README.ja.md) · [简体中文](./README.zh-CN.md) · **繁體中文** · [Español](./README.es.md) · [Français](./README.fr.md) · [Deutsch](./README.de.md) · [Português](./README.pt-BR.md) · [Русский](./README.ru.md)
```bash # Codex 在任務途中撞上 quota 牆。relay-baton 偵測到後,根據倉庫的實際狀態 # 建立 compact handoff,Claude 接手繼續。 $ relay-baton run "重構 upload pipeline" --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 ``` --- ## 為何存在 AI 編碼工作正在多個工具間碎片化。真實的工作階段是這樣的: - 一批編輯用 Codex CLI,另一批用 Claude Code。 - 早上用筆電,晚上換另一台機器。 - context window 被填滿、崩潰,或者悄悄被截斷。 目前在代理間轉移工作的預設方法是 **複製貼上聊天紀錄** ― 更糟的是把整個倉庫丟進 prompt。這種方式有三個問題: 1. **Token。** 聊天紀錄大部分是雜訊。你為這些雜訊每輪都付費。 2. **延續性。** 下一個代理拿到的不是 *意圖*,而是 transcript。 3. **脆弱性。** 漏一個檔案、diff 過時,代理就從錯誤前提重新開始。 relay-baton 是鋪在代理底下的 **本地 harness**。在交接之間只搬運 *最小必要狀態* ― compact 摘要、repo map、檔案參照,不是 transcript。 > **在最少 token 消耗下,把 Codex CLI 和 Claude Code CLI 合併成單一工作流。** ## 核心構想 ``` ┌─────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │ Codex │ → │ Fallback │ → │ Token Diet │ → │ Claude │ │ exec │ │ Detector │ │ Handoff │ │ Code │ └─────────┘ └──────────────┘ └──────────────┘ └────────┘ ↓ ↓ .ai-session/handoff.md, compact-state.md, repo-map.md, full-diff.patch, commands.log ``` 為編碼代理設計的 baton-pass ― 4 步 primitive: - **Detect** 偵測目前代理是否觸頂 (quota、context、rate、errors)。 - **Capture** 只收集要緊的 (repo 狀態、變更檔案、決策、下一步)。 - **Compact** 壓縮到下一個代理實際能消化的預算內。 - **Hand off** 通過 quality gate 後才交付。 handoff 是一個小檔案 (`.ai-session/handoff.md`) 加參照。重量級內容 (完整 diff、完整日誌、完整 repo map) 留在磁碟上,按需載入。 ## Quick Start **安裝(無需建置)** ```bash # npm (所有系統) 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 ``` **從原始碼(開發用)** ```bash pnpm install pnpm build pnpm relay-baton login # 登入 Codex + Claude pnpm relay-baton doctor # 環境檢查 pnpm relay-baton run "修復郵件附件上傳流程" --diet balanced ``` ## 工作流 ```bash $ relay-baton init # 建立 .ai-session/ $ relay-baton run "修復 flaky upload test" --diet balanced ... codex 輸出即時串流 ... ▲ 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 接手編輯檔案並完成 ... $ relay-baton status # 工作階段狀態 $ relay-baton budget # diet 預算用量 ``` 只生成 handoff,不自動 fallback: ```bash $ relay-baton handoff --to claude --no-run --diet caveman ``` 多倉庫切換: ```bash $ relay-baton project add /path/to/repo-a --diet caveman $ relay-baton project switch repo-a $ relay-baton run "接上新的 metrics endpoint" ``` ## 特性 - **自動 fallback** ― 從 Codex 輸出偵測 `quota exceeded`、`rate limit exceeded`、`maximum context length` 等。跳過 grep 結果行與解釋這些 pattern 的散文 (避免誤判)。 - **Token diet** ― 5 個確定性壓縮 profile (`off · lite · balanced · caveman · ultra`)。排除 lock/build/min 檔案,日誌取 tail,以 repo map 取代原始碼。 - **Quality gates** ― 在 fallback 啟動 *之前* 驗證 handoff 完整性與預算。 - **Auth-safe by default** ― `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` 預設從子行程剝除,只能透過 `--allow-api-key-env` opt-in。金鑰從不儲存、列印、紀錄。 - **Project registry** ― 註冊多個倉庫一次,任意位置以 `--project` 或 `--path` 呼叫。 - **Ink TUI** ― project / session dashboard。從不啟動代理。 - **沒有自家的 API 呼叫** ― relay-baton 不直接呼叫 OpenAI / Anthropic API。只以 subprocess 呼叫本地 `codex` / `claude` CLI。 ## 指令 | 指令 | 說明 | |---|---| | `relay-baton init` | 在目前倉庫建立 `.ai-session/` | | `relay-baton doctor` | 檢查 git / codex / claude / env / config(`--deep` 進行擴充診斷) | | `relay-baton verify` | 模擬端到端檢查 — 不進行真實模型呼叫 | | `relay-baton login [agent]` | Codex / Claude 登入流程 | | `relay-baton run ""` | 主代理執行 + fallback 偵測 + handoff | | `relay-baton route ""` | 建議性路由提示預覽(唯讀, `--json`) | | `relay-baton handoff --to claude` | 手動 handoff (`--diet`、`--no-run`、`--force`) | | `relay-baton handoff history` | 列出目前 + 備份的 handoff 文件 (僅 metadata) | | `relay-baton plan ""` | Plan-execute:planner 寫出 `plan.md`(`--with`、`--no-run`、`--then-execute`) | | `relay-baton execute` | Plan-execute:executor 實作 `plan.md`(`--with`、`--from`) | | `relay-baton compress-context` | 壓縮進行中的 context(state.md / commands.log)(`--dry-run`、`--threshold`) | | `relay-baton compact` / `squeeze` | 重建 compact-state / repo-map / full-diff | | `relay-baton budget` | 顯示 context budget 用量 | | `relay-baton compress ` | markdown 檔案的確定性壓縮 | | `relay-baton status` | 工作階段狀態 | | `relay-baton project add/list/switch/current/doctor/remove` | project registry 管理 | | `relay-baton tui` | Ink dashboard | 支援 project 的指令接受 `--project ` 與 `--path `。優先順序:`--path` > `--project` > active project > 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 ``` 預設儲存路徑為 `~/.relay-baton/projects.json`。可用 `RELAY_BATON_PROJECTS_FILE` 覆蓋路徑 (CI、sandbox、測試)。損壞的檔案會備份為 `projects.json.corrupt-.bak` 並重設為空 registry ― 指令繼續運作。 ## Token diet profiles | Profile | 意圖 | |---|---| | `off` | 最小截斷 | | `lite` | 輕量整理 | | `balanced` *(預設)* | 日常使用 | | `caveman` | aggressive minimal-context | | `ultra` | 極端壓縮 | > `caveman` 不是搞笑語氣,而是 **aggressive minimal-context**。技術準確性保留。 ## 與其他方案比較 | 方案 | 攜帶內容 | Token 成本 | 延續性 | 失敗模式 | |---|---|---|---|---| | 原始聊天 export | 整段 transcript | 高 (大部分是雜訊) | 脆弱 ― 代理重讀自己的思考 | context window 溢出 | | 複製貼上 prompting | 人記得的部分 | 浮動 | 易碎 | 與實際狀態 silent drift | | 整倉庫 dump | 全部 | 極高 | 強但昂貴 | 模型中途截斷 | | **relay-baton** | compact 摘要 + repo map + 檔案參照 | **低,以 profile 設上限** | 強 ― 由 *實際* repo 狀態驅動 | 經 quality gate *明確* 失敗 | ## 哲學 relay-baton 是 **針對 AI 原生開發工作流的小而銳利工具**。 - **Local-first.** 一切都在本地磁碟。無雲端、無 daemon、無遙測、無帳號。 - **可組合性。** `.ai-session/` 目錄就是一堆檔案。可讀、可 grep、可 diff、可放進 PR。 - **輕量狀態轉移。** handoff 是 markdown 檔案,不是資料庫。 - **確定性優於聰明。** harness 內部不做 LLM 摘要 ― 模型若摘要錯誤,handoff 就是謊言。只用字元預算、結構規則、明確參照。 - **Repo 狀態是真相之源。** 對話是詮釋,repo 是事實。 - **Token 效率本身就是功能** ― 不是藏在選單裡的開關。 ### 設計原則 1. 不是 chat relay,是 **work handoff**。 2. **目前倉庫狀態** 優先於對話歷史。 3. handoff 必須 **人類可讀**。 4. 所有 UI 都是 core 之上的薄殼。 5. **Token diet 不是附加功能,而是核心功能**。 ## 未來方向 relay-baton 從雙代理 fallback harness 起步。同一 primitive 可以延伸: - **多代理 relay 鏈** ― Codex → Claude → OpenCode → 回到 Codex。 - **分支工作階段樹** ― 同一任務以並行代理嘗試,經 diff 調和。 - **遠端 relay state** ― 將 `.ai-session/` push 到共享 remote,下一台機器接續。 - **編排式工作流** ― `review`、`diagnose`、`continue` 模式 (帶明確 checkpoint 的 bounded autopilot)。 - **更多 adapter** ― OpenCode、Gemini CLI、Aider,任何有合理本地 subprocess 介面的工具。 harness 的形狀不變:detect、capture、compact、hand off。 ## 需求 | 項目 | 版本 / 備註 | |---|---| | Node.js | ≥ 20 | | pnpm | ≥ 9 | | git | 必需 | | `codex` | **需要 ChatGPT Plus 以上訂閱** | | `claude` | **需要 Claude Pro 以上訂閱** | > relay-baton 不直接呼叫 OpenAI / Anthropic API,使用本地 `codex` / `claude` CLI 的 **訂閱驗證**。API key 驗證技術上可行但 **預設封鎖** (需 `--allow-api-key-env` opt-in)。 ## 登入 ```bash pnpm relay-baton login # 兩者 pnpm relay-baton login codex pnpm relay-baton login claude ``` `claude --version` 通過 **不代表** 已登入。看到 "Not logged in" 就重新執行上面的指令。 ## 發布說明 **最新: v1.6.1** — [English](../../release-notes/v1.6.1.md) · [한국어](../../release-notes/ko/v1.6.1.md) · [繁體中文](../../release-notes/zh-TW/v1.6.1.md) relay-baton 已 **正式發佈(GA)v1.0.0**,目前最新為 **v1.6.1**。 - 完整版本歷史: [`CHANGELOG.md`](../../CHANGELOG.md) - 各版本詳細修補說明: [release-notes index](../../release-notes/README.md) ### 安裝 ```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。詳見 [`LICENSE`](../../LICENSE)。 > 完整文件 (quality gate 細節、`.ai-session/` 檔案含義、config schema、TUI 鍵位、疑難排解等) 見 [English README](../../README.md) 與 [`install/install.md`](../../install/install.md)。