@capdiem/pi-todo

A lightweight atomic todo tool for the Pi coding agent: one-call snapshot plans, three states, stale-write guard, plus a TUI widget and a pi-agent-desktop sidebar panel

Packages

Package details

extension

Install @capdiem/pi-todo from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@capdiem/pi-todo
Package
@capdiem/pi-todo
Version
0.3.2
Published
Sep 1, 2026
Downloads
1,440/mo · 579/wk
Author
capdiem
License
MIT
Types
extension
Size
46.8 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./index.min.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-todo

A lightweight, minimal, atomic todo tool for the Pi coding agent. The model writes the complete task plan in one call instead of issuing one create call per task.

It is deliberately small — only the essential plan-maintenance core, with no dependencies or settings menus, no collapse/expand, and exactly one lightweight reminder (a run-end reconcile nudge, see Features). The live plan renders as a read-only widget above Pi's input box, and when hosted by pi-agent-desktop it also appears in the desktop's left-nav sidebar todo panel with zero extra configuration (desktop-side support is upcoming — see Desktop integration).

Features

  • One-call creation of a complete plan (snapshot semantics)
  • Three statuses: pending, in_progress, completed
  • Stable task keys; omission-based deletion (no cancelled or archived state)
  • baseVersion stale-write guard against concurrent/out-of-order updates
  • At most one in_progress task at a time
  • Atomic validation — a failed write never mutates state
  • Completed todos are never auto-removed; the model prunes them (by omitting their keys) once their whole work content is complete
  • State persists in tool-result details and survives /reload and /tree
  • A read-only widget above Pi's input box using markdown-style glyphs ([ ] pending, [-] in_progress, [x] completed); no collapse/expand
  • Run-end reconcile reminder (invisible): when a turn settles (agent_settled) while tasks are still in_progress, the extension records a reminder and injects it into the system prompt of the next turn via before_agent_start. The model is reminded to mark them completed if the work is actually done — with no visible chat message, no extra agent run, and no toggle needed. It fires at most once per turn, is skipped while the plan has no in_progress tasks, and cannot loop (there is no steer message to loop on).
  • When hosted by pi-agent-desktop, the live plan also renders in the desktop's left-nav sidebar todo panel (the desktop-owned pi-agent-desktop:todo widget extension point) — no extra configuration needed

Install

This extension registers the todo tool. Remove any other extension that owns the same todo tool name before installing it, e.g.:

pi remove <the-other-todo-extension>
pi install npm:@capdiem/pi-todo

To try it without installing:

pi -e ./extensions/pi-todo/index.ts

Tool schema

The todo tool accepts the complete authoritative list of tasks to retain. Existing tasks may omit unchanged fields; a new key requires subject and status. Any current key omitted from tasks is permanently deleted:

todo({
  baseVersion?: number,
  tasks: Array<{
    key: string,
    subject?: string,
    status?: "pending" | "in_progress" | "completed",
  }>,
})

Example:

{
  "baseVersion": 0,
  "tasks": [
    { "key": "inspect", "subject": "Inspect the existing implementation", "status": "in_progress" },
    { "key": "implement", "subject": "Implement the optimized protocol", "status": "pending" },
    { "key": "verify", "subject": "Verify the implementation", "status": "pending" }
  ]
}

To hand work off, include every current key but only send changed fields:

{
  "baseVersion": 1,
  "tasks": [
    { "key": "inspect", "status": "completed" },
    { "key": "implement", "status": "in_progress" },
    { "key": "verify" }
  ]
}

Subjects are inherited from the previous snapshot; both status changes commit atomically.

To cancel or otherwise delete work, omit its key from the next complete plan. Deletion is permanent state removal — there is no cancelled status or archived record.

Semantics

  • key is the task identity while that task remains in the plan.
  • Existing keys inherit omitted fields from their previous state.
  • New keys require subject and status.
  • Every key present in tasks remains in the plan; omitted current keys are permanently deleted.
  • Completed tasks remain visible (struck through) until the model prunes them by omitting their keys once their whole work content is complete.
  • tasks: [] clears the plan.
  • baseVersion, when provided, rejects stale writes.
  • At most one task may be in_progress at a time.
  • Validation is all-or-nothing; failed writes do not mutate state.
  • A write that leaves the plan unchanged does not bump the version.

Each successful result includes the current version and complete plan.

Rendering

The task list is rendered in a read-only widget above Pi's input box. It always shows the full list (no collapse/expand): a progress header plus every task with a markdown-style status glyph. in_progress labels are bold, completed labels are struck through. The widget appears only while a plan exists.

Desktop integration

When hosted by pi-agent-desktop (in rpc mode), the live plan renders in the desktop's left-nav sidebar todo panel — a persistent checkbox list next to the chat that stays in view while you work.

The plan is pushed over the desktop-owned todo widget extension point (defined by pi-agent-desktop; see its lib/todo-state.ts and docs/todo-widget.md): a setWidget request with the desktop-reserved key "pi-agent-desktop:todo", one JSON TodoTask per line. The desktop routes it straight into its sidebar todo panel. It is fire-and-forget (not persisted); when the desktop opens a session, this extension's session_start restore re-emits the current plan, so the panel shows the latest snapshot. The TUI keeps its own component widget (see Rendering) and is unchanged.

Status: the desktop-side panel is upcoming. The todo-panel support currently lives on a feature branch in pi-agent-desktop and has not been merged into a release yet. @capdiem/pi-todo already conforms to the pi-agent-desktop:todo widget protocol, so once the panel ships you get the sidebar rendering with zero extra configuration.

Persistence

Writes are stored in tool-result details. On session_start and /tree navigation, the extension restores the latest valid state entry from the active branch. (For backwards compatibility it also recognizes legacy hidden custom-message snapshots emitted by older versions that auto-removed completed tasks.)

This minimal extension does not handle compaction checkpoints: if compaction drops every todo tool result from the branch, the plan resets to empty (the model's own context still contains the plan text). Add compaction handling from a full-featured todo extension if that matters to your workflow.

License

MIT