pi-wakeup0.2.3
schedule_wakeup / cancel_wakeup for the pi coding agent: session-local self-pacing, the pi analog of Claude Code's ScheduleWakeup dynamic mode.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-wakeup
A pi extension giving a running session two tools to pace itself — the pi analog of Claude Code's ScheduleWakeup in dynamic mode.
Tools
schedule_wakeup(delay_seconds, prompt, reason?)— ask to be woken after a delay. When the timer fires,promptis delivered back into the session: immediately as a steered turn if the session is idle, or queued as afollowUpif a turn is already running.delay_secondsis clamped to[60, 3600]. Returns a wakeup id.cancel_wakeup(id?)— cancel one pending wakeup by id, or every pending wakeup when the id is omitted.
Use it to re-check something without a human poking the session — a build that takes a few minutes, a remote queue, a rate-limit window — rather than busy-waiting.
Countdown
While a wakeup is pending, the session shows a live countdown to the soonest one: 17:34 · 12m · <reason> (local fire time, whole minutes left, a truncated reason). Under a minute reads <1m; a missing reason drops that segment; more than one pending appends · +N [6m, 11m], the minutes left on the next two others (… when there are more). It re-renders every 30 s (an unref'd interval) and immediately on schedule / fire / cancel / delivery failure, and clears when nothing is pending or on shutdown.
Where it shows is decided once at session start:
tmux bar — if this pane is inside tmux (
$TMUX+$TMUX_PANE) and the server's globalstatus-left/status-rightalready renders@wakeup, the countdown is written to the pane-session user option@wakeup(muster's@muster_inboxpattern) and nothing is drawn in the pi pane. Add this to your tmuxstatus-rightto render it:set -g status-right '#{?@wakeup,⏰ #{@wakeup} ,}'above the editor — otherwise (no tmux, or a config that doesn't render
@wakeup), one line viactx.ui.setWidget("wakeup", …)above the pi editor.
Every tmux / UI call is best-effort: a failure in a timer callback is caught and logged, never thrown.
Design
- Session-local. A wakeup is an in-process
setTimeout, not a cron job. It lives and dies with the session, and survives/reload: the pending wakeups are handed to the reloaded extension, which re-arms each one for the time it had left. This is deliberate: subagents and pacing in pi are in-process (the muster-teammate shape is shelved), and cross-session scheduling is a different product (cron+pi -p), not this tool. - Busy-gated delivery.
agent_start/agent_settledtrack whether a turn is running; delivery pickssteer(idle) orfollowUp(busy) accordingly, so a wakeup never interrupts a turn in flight. - Best-effort. Every handler and the timer callback swallow-and-log on error — a missed wakeup must never take the session process down. The pure decisions (clamp, delivery mode, message shape) live in
src/schedule.tsand are unit-tested with zero mocking;src/index.tsis the thin pi wiring, in the same split the guardrails package uses. - Persistence. Each schedule / fire / cancel is written with
pi.appendEntryso the session transcript records the wakeup lifecycle.
Known follow-up
Re-arming a pending wakeup across a session resume is not yet implemented. The extension API exposes no entry read-back, and reconstructing pending wakeups by parsing the transcript blind is exactly the kind of vacuous code this project avoids. Within a live session, wakeups fire; a session closed with a pending wakeup drops it on resume. When pi exposes a custom-entry reader (or a resume hook carrying prior entries), SessionStartEvent.reason === "resume" is the place to re-arm from the persisted wakeup_scheduled / wakeup_fired / wakeup_cancelled records.
Tests
node --test src/*.test.ts — pure clamp/delivery/message logic plus the wired tool behavior (registration, idle-vs-busy delivery, clamp, cancel-one, cancel-all, a throwing sendMessage contained, shutdown cleanup) against a fake pi with an injectable timer.
Install
pi install npm:pi-wakeup