blackbone/codex-marketplace/tree/main/plugins/todo-claude

ToDo for Claude Code 是一個以 repo 為單位的持久化任務佇列外掛,提供原子化任務拆解、DAG 發布、隔離 worktree 執行、每任務持久 Claude session、重試與合併佇列,並內建終端機/桌面儀表板。
blackbone/codex-marketplace/tree/main/plugins/todo-claude

ToDo 是 Codex ToDo 外掛的 Claude Code 分支,兩者共用 .todo/ 狀態、任務、pipeline、路由規則、MCP 工具與儀表板。安裝方式為 /plugin marketplace add blackbone/codex-marketplace 與 /plugin install todo@blackbone,需求為 Node.js 22+、Git,以及供背景 worker 使用的 claude CLI。在目標 Git repo 中以 /todo:init 啟用,會建立 .todo/config.json、預設排除 .todo/、在根目錄 CLAUDE.md 安裝受管理的路由區塊並宣告該 repo 由 Claude Code 擁有;/todo:start 啟動 detached runner,/todo:dashboard 取得本機 URL。路由在已啟用的 repo 中即使未明講 ToDo 也會套用於專案變更,唯讀分析與狀態檢查留在當前 session;session hooks 會注入路由政策與 Ponytail 全輪廓(因 Claude Code 每次注入上限 10,000 字元而分成第二個 hook 項目)。外掛附帶 Claude Code mod(mod/register.tsx),可在終端機與桌面 Code 分頁原生繪製儀表板,含任務表格、相依圖、每任務視窗(Overview/Chat/Logs)、篩選語法、設定表單,桌面另有狀態磚、進度條與 worker lanes;mod 每三秒輪詢 scripts/mod-api.mjs,且不受沙箱隔離。背景 worker 以 claude -p stream-json 模式在任務 worktree 中執行,每任務維持單一 Claude session(首次以 --session-id 建立,重試/回覆/reopen/merge 修復以 --resume 續用),透過 --json-schema 結構化輸出回傳結果,tool 呼叫與 token 用量記入同一 attempt ledger。worker 權限對應 codexSandbox 設定:read-only 用 dontAsk 加唯讀工具、workspace-write(預設)用 acceptEdits 搭配 Claude Code 沙箱(failIfUnavailable、無網路)、danger-full-access 用 bypassPermissions 不砂箱。/todo:run 以 hook 記錄 session/prompt ID 供同 session 的 MCP server 讀取,停止 hook 只釋放完全相符的 claim。repo 同時只能由一個 host 擁有,host 記錄於 .todo/config.json,未設定者屬 Codex;另一 host 有存活程序時 Claude Code 端停用並回 HOST_MISMATCH,讀取仍可用。設定檔與 Codex 分支共用,Claude 專屬欄位為 claudeCommand、models.claude 與 codexSandbox;內建 profile 沿用 Codex 名稱與角色(mini/fast/standard/medium/proven/advanced/expert/ultra),對應 Sonnet 或 Opus 與不同 effort,模型清單自 CLI 的 initialize 回應取得並快取於 .todo/claude-models.json 一小時,profile 無效時 runner 不會啟動。已知限制包含 workspace-write 需 macOS 或 Linux/WSL2 的 bubblewrap 與 socat(原生 Windows 上 worker 會失敗)、danger-full-access 在 root 下會被拒絕、無法對執行中問題送答案、Codex thread 與 Claude session 不相容、本機儀表板可能暴露 repo 內容與 log,以及更新外掛需開新 session 才會重載 skills/hooks/MCP。測試指令為 npm run test:todo-claude,授權為 MIT。
请先查看作者 README 确认 marketplace 和插件名称;命令可能随仓库结构改变。
claude plugin marketplace add blackbone/codex-marketplace claude plugin install todo
ToDo gives Claude Code a durable, repository-local task queue with automatic atomic decomposition, Ponytail full task formation and execution, connector and Git preflight, atomic DAG publication, optional repository-defined execution pipelines, isolated worktree delivery by default, optional single-branch execution, persistent per-task Claude sessions, tier-escalating retries, a local rebase merge queue, per-attempt telemetry, and a live dashboard.
This is the Claude Code fork of the Codex ToDo plugin. Both
forks use the same .todo/ state, tasks, pipelines, routing rules, MCP tools,
dashboard, and model profile names; only the host integration and the executor
differ. The Codex README describes the shared behavior in full: routing,
Ponytail lifecycle, Git execution and merge queue, single-branch execution,
pipelines, dashboard, and records.

Add the marketplace and install only this plugin:
/plugin marketplace add blackbone/codex-marketplace
/plugin install todo@blackbone
Requirements: Node.js 22+ and Git on the PATH of the Claude Code process, and
the claude CLI for background workers. On Windows the workers need the native
claude.exe (an npm claude.cmd shim cannot be started without a shell); set
claudeCommand to its full path if it is not on PATH.
Installing ToDo does not activate it in every repository. In a target Git
repository, invoke /todo:init. Initialization creates .todo/config.json,
excludes .todo/ from Git by default, installs a managed routing block in the
root CLAUDE.md without replacing other rules, and claims the repository for
Claude Code. Use /todo:start to start the detached runner and
/todo:dashboard to retrieve its local URL.
| Skill | Purpose |
| --- | --- |
| /todo:init | Activate ToDo in a Git repository. |
| /todo:route | Route project changes into tasks; perform tool setup directly. |
| /todo:create | Create an explicit self-contained task. |
| /todo:run | Claim and execute a task in the current session. |
| /todo:start | Start the runner and return its dashboard URL. |
| /todo:stop | Stop the runner. |
| /todo:supervise | Inspect runner health and failed tasks on request. |
| /todo:status, /todo:list, /todo:get | Inspect tasks, workers, and results. |
| /todo:dashboard, /todo:workers | Show the dashboard or worker state. |
| /todo:update, /todo:retry, /todo:reopen, /todo:cancel | Manage an unclaimed or closed task. |
| /todo:artifact-add | Attach files, images, URLs, code, or text context. |
In an activated repository, /todo:route applies to repository mutations even
when ToDo is not mentioned explicitly. Read-only analysis, planning, status, and
inspection stay in the current session.
Classify each operation by its purpose and effects, not just its file path or the fact that a plugin/tool is invoked.
The tooling and local verification exceptions do not expand a claimed worker's assigned task scope, repository access, permissions, or authority to create follow-up tasks. Perform tool setup or local verification only when required for the assigned task and already allowed by its restrictions; never use these exceptions to alter unrelated repositories, managed routing instructions, or .todo runtime state.
<!-- TODO TOOLING EXCEPTION END -->In an activated repository the session hooks inject the routing policy and the Ponytail full contour, so project mutations are routed through ToDo even when ToDo is not mentioned. The contour arrives through a second hook entry because Claude Code caps each injected context at 10,000 characters.
The plugin ships a Claude Code mod (mod/register.tsx) that draws the
dashboard natively, in the terminal and in the desktop Code tab. Open it with
/todo-dashboard, or from the band above the prompt: it always shows a
colored count per task state (running, waiting, failed, queued, blocked,
merging) beside a button with the state's colored circle that opens the table
filtered to that state, and ToDo opens it unfiltered. The pane has the web dashboard's
task table and columns, the task graph, one window per task (ⓘ in the
table, Details in the graph) with Overview, Chat and Logs tabs, header sorting, the same filter syntax
(status:failed|blocked profile:advanced text) with status and profile chips,
task files, chat with reply, steer and continue, task and runner logs, and the
settings form. The desktop also draws status tiles, a progress bar and worker
lanes. The status line carries a task summary, and toasts report tasks that
fail, wait for input, or complete.
Graph (desktop only; the terminal has no Graph button) draws the dependency graph: arrows run from a blocker to the task that waited for it, columns follow dependency depth, colors follow status. It shows the active tasks with everything they depend on, the whole history, or one task's ancestors and dependents (Focus), as a pipeline view of task cards. It opens at 100% centered on running work (else a task waiting for input, else a failed one). Pan and zoom with the buttons above it (arrows, − / +, Fit, Center, 100%). The drawing is a script-less image, so it takes no mouse drags, wheel zoom or clicks: the 🔍 button beside each task in the table opens the graph centered on that task, and Details opens the selected task's window.
Hovering a card lights it, its dependencies and the tasks they reach in their status colors and fades the rest; hovering an arrow lights it and its two cards. Running tasks glow blue slowly, failed ones red quickly, tasks waiting for input amber. The graph redraws only when a task's status, title or dependencies change, not while a running task's duration or tokens grow, so hover highlights stay.
The table and the graph fill the pane's height. The surface reports its size only in cells, so on the desktop Taller / Shorter tune the fit; the setting is kept across sessions.
Closed tasks keep their dependencies in .todo/history; records written before
dependencies were kept fall back to the ## Dependencies section of the task
body, so older history may lack edges.
The mod polls scripts/mod-api.mjs every three seconds. Reads and settings
saves work without a runner; task input goes through the running dashboard and
keeps its same-origin checks. Mods are not sandboxed: the mod runs with Claude
Code's own access, like the plugin's hooks.
Each background attempt is one claude -p process in stream-json mode, started
in the task worktree with TODO_RUNNER_WORKER=1. A task keeps one Claude
session: the first attempt creates it with --session-id, retries, answers,
reopen, and merge repair continue it with --resume. The worker returns its
result through --json-schema structured output. Tool calls, token usage
(including cache reads and writes) and failures are recorded in the same
attempt ledger and usage files as the Codex fork. Steer in the dashboard
queues an instruction into the running process. Claude Code has no session
archive or remote title API, so those steps are no-ops and the dashboard title
status reads unsupported.
Worker permissions are the Claude Code equivalents of the Codex sandbox modes
selected by codexSandbox in .todo/config.json:
| codexSandbox | Claude worker |
| --- | --- |
| read-only | --permission-mode dontAsk with read-only tools (Read, Grep, Glob, web reads, read-only Git) |
| workspace-write (default) | --permission-mode acceptEdits: file edits are accepted inside the worktree only; shell commands run in the Claude Code sandbox (failIfUnavailable, no unsandboxed fallback, strict empty network allowlist), so writes stay in the worktree and network access is off. Other tools that would need a prompt are denied, except the ToDo MCP server |
| danger-full-access | --permission-mode bypassPermissions without the sandbox |
/todo:run claims a task for the current session. Claude Code sends no session
or turn in MCP requests, so the SessionStart and UserPromptSubmit hooks
record the session ID and prompt ID under the Claude process ID in the plugin
data directory; the ToDo MCP server of the same session reads them. The Stop
hook releases only a claim of the exact session and prompt.
A repository is claimed by one host at a time; host in .todo/config.json
records it, and a repository without it belongs to Codex. While a live process
of the other host works in the repository (its runner PID from
.todo/daemon.json, or the PID of a task claim), ToDo in Claude Code stays
disabled: the session hook says so and task-changing MCP tools fail with
HOST_MISMATCH. Reads keep working. When that PID is dead, the first
task-changing call, runner start, or activation claims the repository for
Claude Code. Interactive claims left by Codex become waiting-input, and Codex
threads are not resumed: the next attempt starts a new Claude session. To hand a
repository over, stop the runner from the host that owns it.
The configuration file is shared with the Codex fork. Fields specific to this fork:
claudeCommand — the Claude CLI used by workers (default claude).
codexCommand belongs to the Codex fork and is ignored here.models — either the legacy Codex profile array or a map keyed by host.
This fork reads and writes models.claude; without it, the built-in profiles
below apply. A plain array stays with Codex.codexSandbox — the worker permission mode described above.Built-in profiles keep the Codex names and task roles:
| Profile | Model | Effort |
| --- | --- | --- |
| mini | claude-sonnet-5-5 | low |
| fast | claude-sonnet-5-5 | medium |
| standard | claude-sonnet-5-5 | high |
| medium | claude-sonnet-5-5 | xhigh |
| proven | claude-opus-5-5 | medium |
| advanced | claude-opus-5-5 | high |
| expert (default) | claude-opus-5-5 | xhigh |
| ultra | claude-opus-5-5 | max |
Profiles are edited in the dashboard settings, both in the Claude Code pane
(/todo-dashboard → Settings) and in the web dashboard: add, rename, remove
(not while open tasks use the profile), and choose each profile's model,
effort, and description. Saving writes models.claude; until then the
built-ins below apply.
Profile models come from the Claude CLI model list: the models the CLI
reports to an SDK initialize request (what /model offers), with each
model's effort levels. Reading it makes no model request; it is cached in
.todo/claude-models.json for an hour. A profile may name a model id, an
alias such as opus, or a dated id's base (claude-haiku-4-5). The settings
refuse a model outside the list or an effort the model does not support, and
while any profile is invalid runner_start and the dashboard Start runner
button return start-blocked with the problems; the runner does not start until
the profiles are fixed in settings. The list says which models the CLI knows,
not which the account may use: a listed model that needs usage credits still
fails at the first task attempt.
Built-ins use only Sonnet and Opus. Haiku and Fable stay in the executor
catalog for custom profiles; saved former Haiku and Fable built-ins are offered
for migration by model_profiles.
Profile updates only recommend built-ins at their declared supported effort; unavailable tiers are not silently downgraded.
The model catalog is built in, because the Claude CLI does not list models;
preflight checks that the CLI runs (claude-command). Pipelines keep their step
types (codex-exec, codex-thread); both run as Claude sessions here.
workspace-write
requires the Claude Code sandbox (macOS, or Linux/WSL2 with bubblewrap and
socat); where it is unavailable, such as native Windows, worker turns fail
instead of running unsandboxed. Choose danger-full-access there explicitly.
Interactive runs use the permissions of the current session.danger-full-access uses bypassPermissions, which Claude Code refuses when
running as root outside a recognized sandbox.claude -p does
not ask questions mid-turn, so a worker that needs input finishes with
requiresInteractive and the answer continues the task in a new turn..todo/ runtime state or place secrets in task descriptions.npm run test:todo-claude
The suite covers the host claim, the Claude executor against a fake claude
CLI, a daemon run end to end, and the executor-independent ToDo tests. Daemon
scenarios that drive the Codex app-server protocol run in the Codex fork.