omp packages

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.

GitHub Actions Published 7 days ago MIT ~247 downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

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, prompt is delivered back into the session: immediately as a steered turn if the session is idle, or queued as a followUp if a turn is already running. delay_seconds is 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 global status-left / status-right already renders @wakeup, the countdown is written to the pane-session user option @wakeup (muster's @muster_inbox pattern) and nothing is drawn in the pi pane. Add this to your tmux status-right to render it:

    set -g status-right '#{?@wakeup,⏰ #{@wakeup}  ,}'
    
  • above the editor — otherwise (no tmux, or a config that doesn't render @wakeup), one line via ctx.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_settled track whether a turn is running; delivery picks steer (idle) or followUp (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.ts and are unit-tested with zero mocking; src/index.ts is the thin pi wiring, in the same split the guardrails package uses.
  • Persistence. Each schedule / fire / cancel is written with pi.appendEntry so 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