npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@davidroman/pi-loop

v0.3.5

Published

Reliable scheduled loops for the Pi coding agent — prompt/notify/shell/message on interval, once, or cron. Always-visible status, working input, bulletproof recurrence.

Readme

pi-loop

Scheduled loops for the Pi coding agent.

Wake the agent with a prompt, fire a reminder, run a command, or post a message — on an interval, once, or cron. Always-visible status, reliable recurrence, survives restarts. Loops coalesce cleanly during long agent runs; prefix ! to force one to interrupt mid-run.

Install

pi install npm:@davidroman/pi-loop

Then /reload in pi. You'll see the 🔁 loops chip in the footer once a loop exists.

Quick start

Type this in your pi prompt:

/loop 5m check the build

That's it — an interval loop now wakes the agent with "check the build" every 5 minutes. The footer shows 🔁 1 loop · next 4m and a widget below the editor tracks it with a live countdown.

Command grammar

Everything is one command. The first token decides what happens:

/loop                                  wizard (add / list / pause / resume / delete)
/loop <schedule> <prompt>              quick prompt loop (schedule-first shortcut)
/loop <action> <schedule> <payload>    explicit action: prompt / notify / shell / message
/loop !<schedule> <prompt>             forced loop — interrupt mid-run if the agent is busy
/loop <verb> <name|id>                 control: pause / resume / delete / run

There's no list command — the widget under the editor (see below) always shows every loop with a live countdown. Pick a loop by name or id for control verbs.

Creating loops

Schedule-first (default action = prompt):

/loop 5m check the build               # prompt, every 5m
/loop +10m review the diff             # prompt, once in 10m
/loop tomorrow 9am write notes         # prompt, once at a clock time
/loop "*/5 * * * *" poll queue depth   # prompt, cron (quote it — it has spaces)

Action-first (any of the four actions):

/loop shell 5m npm test                # run a command every 5m
/loop notify 9am standup               # reminder toast at 9am
/loop notify +5m break time            # reminder in 5 minutes
/loop message 1h heartbeat             # post a transcript line hourly
/loop prompt 1h sync the cache         # explicit prompt (same as schedule-first)

To wake the agent with a shell command's output, add a followUpPrompt — via the wizard or by asking the agent.

Forced loops (!) — prefix ! to make a loop interrupt the agent mid-run instead of waiting for it to finish (see When the agent is busy):

/loop !5m check ci                     # forced: inject at the next tool-call boundary if busy
/loop !+10m remind me to review        # forced one-shot
/loop !shell 1h npm test               # forced shell

Interactive wizard — for cron with a follow-up prompt, a custom name, or a max-fire count:

/loop

Walks you through action → type → schedule → payload → name → max fires, re-prompting on invalid input (you never lose what you already typed).

Controlling loops

By name or id — no menu needed:

/loop pause build-check                # stop firing, keep the loop (resumable)
/loop resume build-check               # re-arm a paused loop
/loop run build-check                  # fire immediately, ignoring the schedule
/loop delete build-check               # permanently remove

Name matching is flexible: full id, id prefix, or unique name. With a single active loop you can even omit the name — /loop pause targets it.

Bulk + browse via the wizard:

/loop  →  Pause all · Resume all · Clear all · List/manage (pick → Pause/Resume/Run now/Delete)

Schedules

| Type | Examples | |---|---| | interval | 5m, 1h30m, 30s, 2h, hourly, daily, every 10m, in 1 hour | | once | +10m, in 2 hours, tomorrow 9am, 9am, 18:30, 2026-01-01T09:00 | | cron | */5 * * * * (every 5 min), 0 9 * * 1-5 (9am weekdays), 0 */2 * * * (every 2h) |

A leading + or in means a one-shot. 5m / every … / bare durations mean interval. Cron is detected from the 5-field shape — quote it on the command line since it contains spaces.

Actions

| Action | Fires as | Use for | |---|---|---| | prompt | wakes the agent with a prompt | polling CI, periodic work — the main use | | notify | a toast reminder (no agent wake) | "standup in 5 min" | | shell | runs a command on schedule | npm test every 5m; optional followUpPrompt wakes the agent with the output | | message | a line in the transcript | logging, breadcrumbs; optionally triggers a turn |

When the agent is busy

A loop can fire while the agent is mid-run (a long task, a goal skill, a stuck loop of tool calls). To understand the two delivery policies, it helps to see how a run flows.

How a run flows (and where your loop lands)

A Pi run is a loop of turns. A loop that fires mid-run has two places it can deliver — pick which one with !:

you send a prompt
   │
   ▼
┌─ turn 1 ──────────────────────┐   a turn = one LLM reply + its tool calls
│  think → bash → edit → …      │
└───────────────────────────────┘
   │  ◄── turn boundary: tools done, before the next LLM call   ← ! lands here
   ▼
┌─ turn 2 ──────────────────────┐
│  think → bash → …             │
└───────────────────────────────┘
   │  ◄── turn boundary
   ▼
   … a goal skill can loop here for an hour …
   ▼
 settled                          the whole run is done — agent idle, nothing queued   ← default lands here
  • Turn boundary — the yield point between one turn's tool calls and the next LLM call. Happens every few seconds.
  • Settled — the entire run is finished. Seconds away for a quick task; potentially an hour away for a long autonomous run.

That gap is the whole reason ! exists:

| | Agent idle | Agent busy | |---|---|---| | default | fires immediately | coalesces → one delivery at settled (even if that's an hour away) | | ! forced | fires immediately | coalesces per-turn → steers in at the next turn boundary (lands in seconds) |

  • default stays out of the way and batches into one message when the agent finishes. Good for background polling ("check CI every 5m").
  • ! interrupts within seconds — use it when waiting for the run to finish would defeat the trigger ("remind me in 10m", "wake me if health checks fail"). Coalesced so a !5m loop never bursts (max one injection per turn).

See what's running

No command needed — the widget under the editor always shows every loop:

  ● build-check    every 5m         in 4m        ×3   prompt !
  ○ standup        cron 0 9 * * 1-5 in 14h       ×0   prompt
  ❚❚ deploys       every 1h         paused       ×12  shell
  ✗ broken-watch   every 30s        errored      ×2   shell

| Glyph / marker | Meaning | |---|---| | | active | | ❚❚ | paused | | | errored (last run failed) | | ! | forced loop — interrupts mid-run when busy | | | a fire is buffered (waiting to deliver) |

Finished loops (a once that fired, or one that hit maxFires) are removed automatically — the widget shows only loops that still have work to do.

Let the agent schedule itself

The agent has schedule_loop, list_loops, and stop_loop tools — just ask in plain language:

Watch the build — run `npm test` every 5 minutes and tell me the result, max 20 times.
Remind me to review the PR at 9am tomorrow.
Poll /health every 30s and wake me up if it's not 200.
Schedule a forced loop: remind me in 10 minutes no matter what I'm doing.
pause the build-check loop
delete the standup loop

stop_loop finds a loop by id, id prefix, or unique name.

Persistence & limits

  • Loops persist to .pi/loops.json in the project. Reopening the project re-arms them automatically; paused loops stay paused.
  • One pi per project: loops are project-scoped. Two pi instances in the same cwd will both fire shared loops — the single-developer case just works.

License

MIT