pi-todo-lite

Pi todo extension: one ordered task table above the editor.

Packages

Package details

extension

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

$ pi install npm:pi-todo-lite
Package
pi-todo-lite
Version
0.3.0
Published
Nov 2, 2026
Downloads
1,596/mo · 464/wk
Author
setwhite
License
MIT
Types
extension
Size
51.8 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

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

README

pi-todo-lite

简体中文 | English

pi-todo-lite: the Todo table above the editor, next to a running tool call

The model keeps one ordered task table above the editor. The table replays after compaction, after a branch switch or after --continue. The package has no runtime dependencies.

Features

  • The model side has one tool, todo(tasks). The call submits the whole table and replaces the old table. tasks: [] clears the table.
  • The table sits above the editor. Pending tasks take lines first. If the table passes ui.widget.maxLines lines, the rest collapse into +N more.
  • alt+t collapses the table and keeps the data. ui.* moves the table and changes the glyphs, the header and the completed style.
  • The extension adds four commands: /todos, /todos clear, /todos export, /todos import <file>.

Install

pi install npm:pi-todo-lite

The old repository moved into this monorepo. Install from npm.

Configuration

The config file is <agent dir>/pi-todo/config.json. <agent dir> is $PI_CODING_AGENT_DIR. If $PI_CODING_AGENT_DIR is unset, the agent dir is ~/.pi/agent.

The extension only reads this file. The extension never writes this file. Without the file, all values are defaults.

These cases throw an error. The message holds the absolute path and one path: reason line per fault: broken JSON, an unknown key, a wrong type or a wrong enum. The extension clamps out-of-range numbers.

Minimal configuration: zero config works. To make the table shorter, set ui.widget.maxLines. The default is 9 lines.

{
  "ui": { "widget": { "maxLines": 5 } }
}

Full configuration: all keys follow, with their default values. The // starts a comment. Remove the comments in a real file.

{
  "tools": { "todo": { "name": "todo" } },           // tool name
  "plan": {
    "maxTasks": 20,                                  // max tasks per table. More fails the call
    "maxSubjectChars": 120,                          // max characters per task
    "requireSingleInProgress": false                 // true = only one in_progress task
  },
  "ui": {
    "widget": {
      "enabled": true,                               // show the widget
      "maxLines": 9,                                 // max lines (3–10)
      "placement": "aboveEditor",                    // aboveEditor / belowEditor
      "showCompleted": true,                         // list completed tasks individually
      "header": "Todo {done}/{total} · {doing} doing", // header template: {done} {total} {doing}
      "glyphs": { "pending": "[ ]", "inProgress": "[-]", "completed": "[x]" }, // per-status glyphs
      "completedStyle": "strikethrough"              // strikethrough / dim / plain
    },
    "shortcut": { "toggle": "alt+t" }                // collapse key. off = don't register
  },
  "lifecycle": { "onFinish": "clear" },              // model / keep / clear
  "commands": {
    "todos": { "enabled": true },                    // /todos
    "export": {
      "enabled": true,                               // /todos export
      "dir": "",                                     // output dir, empty = project root
      "fileNamePattern": "todo-{timestamp}.md"       // file name template. Never overwrites
    },
    "import": { "enabled": true }                    // /todos import <file>
  },
  "guidance": {                                      // what the model sees. Per-key override, empty values included
    "description": "…",                              // tool description. Empty = empty description
    "promptSnippet": "",                             // the tool-list line. Empty = omitted (same as missing)
    "promptGuidelines": ["…"]                        // guidelines. Empty array = omitted
  }
}

An unknown key throws. The extension ignores no key silently.

Usage

A completed table stays on screen. The table clears when you send the next message. lifecycle.onFinish (model or keep) changes this behavior.

/todos export names the file after commands.export.fileNamePattern. On a name clash, /todos export yields and does not overwrite the file. /todos import <file> needs an empty table. Run /todos clear first.

/todos completes its arguments. Start typing clear, export or import and the list pops up. Press Tab to take the entry. After /todos import , the list shows the files and directories in the session directory. A directory ends with /. A path with spaces gets quotes.

Docs

Document Content
docs/specs/0001-pi-todo-lite.md Contract and acceptance criteria
docs/ARCHITECTURE.md Modules and dependency direction
docs/GLOSSARY.md Terms
CHANGELOG.md Release notes

License

MIT © setwhite