todo-enforcer
Todo continuation enforcer for pi-coding-agent — monitors todo state and injects prompts to keep agents working until all tasks complete
Package details
Install todo-enforcer from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:todo-enforcer- Package
todo-enforcer- Version
1.0.0- Published
- May 31, 2026
- Downloads
- not available
- Author
- buihongduc132
- License
- MIT
- Types
- extension
- Size
- 108.5 KB
- Dependencies
- 0 dependencies · 1 peer
Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
todo-enforcer
Todo continuation enforcer for pi-coding-agent — monitors todo state and injects prompts to keep agents working until all tasks complete.
Features
- Automatic task continuation — injects prompts when the agent goes idle with incomplete tasks
- Configurable rule engine — first-match-wins rule evaluation with built-in and custom conditions
- Multiple delivery modes —
userMessage(default) orcustomMessagevia pi's messaging API - External command support — call external scripts/HTTP endpoints for dynamic continuation logic
- Spawn action — run
pi -pin background to generate continuation guidance - Stagnation detection — stops injecting when the agent is stuck on the same incomplete count
- Exponential backoff — rate-limits retries on LLM errors (429, rate limits, etc.)
- Message stall guard — prevents infinite loops from repeated identical messages
- Polling timer — re-evaluates after cooldown even without agent_end events
- Completion summary control — configurable
completionSummaryto suppress or enable the "all done" message (default: suppressed)
Installation
For Humans
npm install -g todo-enforcer
For AI Agents (pi / OpenCode / Claude Code / Codex)
Add to your settings.json:
{
"packages": ["todo-enforcer"]
}
Or tell your agent:
Install and configure todo-enforcer by following:
https://raw.githubusercontent.com/buihongduc132/todo-enforcer/refs/heads/main/README.md
For pi (git-sourced)
In settings.json:
{
"packages": ["https://github.com/buihongduc132/todo-enforcer"]
}
For pi (local path)
In settings.json:
{
"packages": ["/path/to/todo-enforcer"]
}
Usage
todo-enforcer auto-activates via pi's agent_end lifecycle hook. No manual invocation needed.
How It Works
- On each
agent_endevent, the enforcer reads the current todo state - It evaluates rules in order — the first matching rule wins
- If a rule matches, it generates a prompt and delivers it to the agent
- A polling timer re-checks after the cooldown expires
Default Rules
| Rule | Condition | Action |
|---|---|---|
incomplete-tasks-remain |
Any pending/in_progress tasks | Inject continuation prompt |
all-complete-celebration |
All tasks completed | Inject summary (disabled by default) |
Slash Commands
| Command | Description |
|---|---|
/enforcer-status |
Show current enforcer state, rules, and injection count |
/enforcer-switch <rule1,rule2,...> |
Switch active rules for this session |
/enforcer-switch reset |
Reset to config defaults |
/enforcer-reset |
Reset all enforcer state for this session |
Keyboard Shortcut
| Shortcut | Action |
|---|---|
Ctrl+Shift+T |
Toggle enforcer enabled/disabled |
Configuration
Create ~/.todo-enforcer.json (global) or .todo-enforcer.json (project-level):
{
"enabled": true,
"maxInjections": 5, // Max injections per session
"cooldownMs": 5000, // Cooldown between injections (ms)
"completionSummary": false, // Suppress "all done" message (default)
"detectStagnation": true, // Stop injecting when stuck
"stagnationThreshold": 3, // Consecutive idle events before stagnation
"backoff": {
"enabled": true,
"factor": 2,
"maxDelayMs": 3600000,
"errorPatterns": ["429", "rate limit", "No deployments available"]
},
"messageDelivery": {
"mode": "userMessage", // "userMessage" or "customMessage"
"display": true,
"triggerTurn": true
},
"rules": [
{
"name": "incomplete-tasks-remain",
"condition": "has_incomplete",
"action": "prompt",
"prompt": "You have incomplete tasks. Continue working on them.\n\n[Status: {{completed_count}}/{{total_count}} completed, {{incomplete_count}} remaining]\n\nRemaining tasks:\n{{incomplete_list}}\n\nPick up where you left off."
},
{
"name": "all-complete-celebration",
"condition": "all_complete",
"action": "prompt",
"prompt": "All {{total_count}} tasks are complete. Great work.\n\nCompleted tasks:\n{{completed_list}}\n\nYou may now summarize the results or ask the user for next steps."
}
]
}
Built-in Conditions
| Condition | Description |
|---|---|
has_incomplete |
Any pending/in_progress tasks remain |
all_complete |
Every non-deleted task is completed |
has_in_progress |
At least one task is in_progress |
none |
Never matches (disabled rule) |
always |
Always matches |
Template Variables
| Variable | Description |
|---|---|
{{incomplete_count}} |
Number of incomplete tasks |
{{completed_count}} |
Number of completed tasks |
{{total_count}} |
Total non-deleted tasks |
{{incomplete_list}} |
Formatted list of incomplete tasks |
{{completed_list}} |
Formatted list of completed tasks |
{{latest_user_message}} |
Latest user message content |
{{assistant_messages}} |
Recent assistant messages |
Actions
| Action | Description |
|---|---|
prompt |
Inject a static template string |
external |
Call an external command or HTTP endpoint |
spawn |
Run pi -p in background with a template |
noop |
Do nothing (for logging/future use) |
Architecture
todo-enforcer/
├── src/
│ ├── index.ts ← Entry point — hooks, commands, shortcuts
│ ├── config.ts ← Config loader + types + template interpolation
│ ├── conditions.ts ← Built-in + custom condition evaluator
│ ├── external-caller.ts ← External command/HTTP executor
│ ├── session-state.ts ← Per-session state tracking
│ ├── todo-snapshot.ts ← Reads todo state from session branch
│ ├── message-stall.ts ← Repeated message + rate limit guard
│ ├── type-guards.ts ← Runtime type guards
│ └── lib/
│ ├── plugin-logger.ts ← File-based structured logger
│ ├── hooks-manager.ts ← Hook registration and state
│ └── types.ts ← Shared types
├── tests/ ← Test suite (134 tests)
├── package.json
├── tsconfig.json
└── vitest.config.ts
Development
# Install dependencies
npm install
# Run tests
npm test
# Run tests with coverage
npm run test:ci
# Type check
npm run typecheck
License
MIT
Repository
GitHub: buihongduc132/todo-enforcer