@dumbmice/pi-todo-loop
Keep pi working while a todo list still has open tasks, and stop when the agent asks for a person.
Package details
Install @dumbmice/pi-todo-loop from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@dumbmice/pi-todo-loop- Package
@dumbmice/pi-todo-loop- Version
0.3.0- Published
- Nov 6, 2026
- Downloads
- 197/mo · 197/wk
- Author
- dumbmice
- License
- MIT
- Types
- extension
- Size
- 115.6 KB
- Dependencies
- 0 dependencies · 0 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
@dumbmice/pi-todo-loop
Keeps the pi coding agent working while its todo list still has open tasks.
rpiv-todo gives the agent a task list and shows it to you. It never asks pi for another turn, so the
agent still stops halfway and hands control back. This extension adds the turn: while tasks are open it
keeps the agent going, and stops when you clear the list — or when the agent tells you it needs a
person. It never writes the list into your prompt: the agent reads it with its own todo tool.
Quick start
pi install npm:@juicesharp/rpiv-todo # the list this reads (skip if installed)
pi install npm:@dumbmice/pi-todo-loop
Then start a session and ask for something with several steps:
Use the todo tool to plan this, then work through it: make the reports page
export CSV, add tests, and update the docs.
There is nothing else to configure. /todoloop shows what it is doing; touch ~/.pi/agent/todo-loop-off turns it off.
What it looks like
you: make the whole sequence web-editable, then expose it in the browser
pi: [todo: 12 tasks created, first marked in_progress]
pi: T5 backend is in and verified. Committing a report of the state …
← without this extension the run ends here, with 11 tasks open.
pi: [todo: T5 completed, T6 in_progress]
pi: T6 audio/face lanes wired. T7 per-camera PNG export next …
pi: [todo: all 12 completed]
pi: All 12 tasks are complete; here is what was verified …
← the list is clear, so the loop stops and stays stopped.
It stops for one of these reasons, and /todoloop always says which:
| Why it stopped | What you see |
|---|---|
| the list is clear | stopped: list is clear — the normal ending |
| the model said it needs a person | waiting for you: waiting on Dana's review — it called todo_loop_block; your next message resumes |
| a configured cap is reached | stopped: 12 continuations used, 3 tasks still open — only when maxRounds is set; if it ends with the agent may need you, ask what it is waiting on |
| it never had a list | stopped: no list — the model has not called the todo tool in this session |
| the turn failed | stopped: turn outcome was error — the provider failed, or you aborted it |
When it helps
- Long, multi-step work where the agent summarises and hands back halfway.
- Sessions long enough to be compacted — the list survives on disk; the nudge is what gets the model to read it again.
- A model that runs tools but rarely updates its list. It will still be nudged, and with no cap by default it keeps going until the list clears.
When it does not
- No todo tool installed. The extension is inert: nothing continues.
- You want an autonomous agent that invents its own goals. This drives the list you have; nothing here adds work you did not ask for.
- You want a hard ceiling on cost. There is no continuation cap by default — set
maxRoundsif you want one, otherwise a model that keeps stopping will keep costing turns./todoloopsays(no limit), and every tenth reply that leaves the list unchanged raises a warning. - You want the continuations visible. They are silent by design.
- You want your "stop" to be final. Your instruction reaches the model, not the loop. A model that
reads "stop" as final can say so with
todo_loop_block, and that ends it; otherwise the loop keeps asking, so use/todoloop pausewhile you are away.
It buys liveness, not work. A model can satisfy the loop by closing tasks, including deleting
placeholders, and a list that is never updated looks the same as one that is finished. What ends it is
the list emptying, the agent asking for a person, a turn that fails, the maxRounds limit you set, or
you pausing it — so the list has to mean something to you.
The extension never edits your prompt. The only variable text it gives the model is a one-line nudge —
continue, and read or update the list with the todo tool — which adds one sentence offering
todo_loop_block when the agent has stopped twice without doing anything. Plus one constant tool
declaration and the prompt entry pi derives from it; neither carries task state. The list stays the
agent's to maintain and the conversation stays yours.
Configuration
Optional, at ~/.pi/agent/todo-loop.json:
{
"maxRounds": null
}
| Key | Default | What it does |
|---|---|---|
maxRounds |
null |
continuations allowed per message; null means no limit, a number caps it (clamped to 1000) |
A missing or broken file falls back to these values; a bad config never fails a turn.
Commands
| Command | What it does |
|---|---|
/todoloop |
status: mode, how often it has been asked to continue, replies since the todo list last changed, open tasks, whether it waits for you, why it last stopped, config path |
/todoloop pause |
stop continuing until you resume or restart |
/todoloop resume |
allow the next turn to continue again |
/todoloop reset |
restart the count for this message and forget any pending todo_loop_block |
Kill switch — checked before every decision:
touch ~/.pi/agent/todo-loop-off # everywhere
touch .pi/todo-loop-off # this directory only
Is it working?
After a response that made no tool calls while tasks are open, /todoloop should read something like:
todo-loop active
asked to continue: 1 (no limit)
replies since the todo list last changed: 0
tasks open: 2 of 5
counting from: your message 4f3c1a2e — a new message restarts the count
last: continuing: 2 tasks still open, continue 1
config /home/you/.pi/agent/todo-loop.json
To count continuations in a session file:
grep -c 'todo-loop:continue' ~/.pi/agent/sessions/<project>/*.jsonl
Troubleshooting
| Symptom | What to do |
|---|---|
| Nothing continues | Check /todoloop: DISABLED means a kill-switch file exists, PAUSED means you paused it. last: stopped: no list with tasks open: 0 of 0 means the model has not created a list in this session. last: only changes on a reply that ends a run, so it can lag a turn behind the counts |
| The model asked for a person | It called todo_loop_block with a reason, so the loop is stopped until your next message. The reason appears in /todoloop as waiting for you: … |
It stopped at your maxRounds limit |
Only happens when maxRounds is set: the continuations for that message are used up; send another message. no todo change for N replies means it was working without updating the list; the agent may need you means it stopped twice in a row without doing anything — ask what it is waiting on |
| Continuations jump by two, or the same reply appears twice | Two continuation extensions are installed; pi list shows them, remove one, then /reload |
| The list is stale | The extension nudges, it does not write statuses. Nothing here fabricates progress |
| No status or warning appears | /todoloop and the warnings need a UI. In pi -p and --mode json the loop still runs, but the only controls are the kill-switch file and maxRounds |
| A warning says tasks were deleted | The list was emptied by a turn whose only tool was todo, and that turn deleted tasks rather than completing them. Check the work before trusting it |
Uninstall
pi remove npm:@dumbmice/pi-todo-loop
rm -f ~/.pi/agent/todo-loop.json
rm -f ~/.pi/agent/todo-loop-off .pi/todo-loop-off
Then /reload. Nothing was ever written to your working tree, and old session files keep only the
hidden continuation entries.
Requirements
- pi 1.5.0 (tested; needs the
turn_endboundary). - A todo tool named
todothat stores its list in the session — tested with@juicesharp/rpiv-todo2.15.0. - Node 22.19+, the floor pi itself requires. The extension has no dependencies.
Last verified 2026-11-06; the exact table and what was checked is in docs/pi-api-alignment.md.
Install only one continuation extension: a second one that also requests turns doubles every continuation and makes the counts meaningless.
Further reading
- How it behaves, precisely — counters, markers, stalls, cost: docs/behaviour.md
- pi API alignment — the deliberate workarounds: docs/pi-api-alignment.md
- Working on the repository: AGENTS.md
- Changes by version: CHANGELOG.md
- Why it exists — the upstream issues: rpiv-mono#159, #222, #259
License
MIT. Source and issues: https://github.com/DumbMice/pi-todo-loop.