Todo Tool

Browser-native todo tool — session-scoped task list with live UI panel.

pi-forge ships a browser-native implementation of the todo tool: a session-scoped task list the agent uses to plan and track multi-step work. The agent calls todo with action create / update / list / get / delete / clear; the browser shows a checklist that updates live.

UI

A small ListChecks icon appears in the top-right of the chat input only when the active session has at least one task (so it's gone the moment the list is cleared). The badge shows completed/total so you have at-a-glance progress without clicking.

Clicking the icon opens a bottom-strip panel in the right pane. The strip splits whatever right-pane tab is currently visible (Files, Search, Changes, Git, or Context) — bottom-third gets todos, top-two-thirds stays whatever you were looking at. A horizontal divider lets you resize the strip; the height persists in localStorage.

When the right pane is collapsed and you click the icon, the right pane auto-opens so the panel has somewhere to land. Closing the strip (X in its header, or re-clicking the icon) hides only the strip; your right-pane tab is unaffected.

Persistence

State persists via branch replay — exactly the model @juicesharp/rpiv-todo uses. Every successful todo tool call returns the full state (details.tasks, details.nextId) in its result envelope, which gets recorded in the session JSONL. On session resume / fork / compaction, pi-forge walks the branch and reads the latest todo result to rebuild state. There is no separate todo database — the message history is the source of truth.

The in-memory cache (packages/server/src/todo/store.ts) is a fast path for read-heavy consumers (the UI panel, SSE snapshots); cache-miss falls back to branch replay so a server restart can't lie about state.

Disabling the tool

The tool appears under Settings → Tools → Built-in tools. Toggle it off there to filter todo out of every new session's tool allowlist. Live sessions keep the tool list they were created with.

Relationship to @juicesharp/rpiv-todo

The wire contract — tool name (todo), action enum (create | update | list | get | delete | clear), 4-state machine (pending → in_progress → completed plus deleted as a terminal tombstone), blockedBy dependency model with cycle detection, and response envelope ({content:[{type:"text",text}], details:{action, params, tasks, nextId, error?}}) — is contract-compatible with the upstream Pi extension (MIT). An agent prompt authored against the plugin works against this implementation unchanged.

Implementation is independent. The reducer, validators, envelope builder, replay logic, store, and React UI are pi-forge's own. Prompt snippet, tool description, and guidelines are ported verbatim with attribution in packages/server/src/todo/prompt-strings.ts — the plugin author's wording has been tuned against real model behavior (rules like "exactly one task in_progress at a time" and "never mark completed if tests are failing"), and matching it avoids regressions in tool-call quality.