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

@maheidem/pi-loop

v0.7.1

Published

Pi extension: /loop — a generic recurring-prompt loop (Claude Code /loop style) delivered as in-session steer custom messages. Skills (e.g. shepherd) are consumers of /loop, not part of it.

Readme

loop — /loop for pi

Run any prompt on a schedule inside the current session. Modeled on Claude Code's /loop (CronCreate): the interval and the prompt are yours; the loop just keeps injecting the prompt into this conversation every X.

The loop knows nothing about what the prompt says. It is a generic mechanism. Specializations — like the bundled shepherd skill (skills/shepherd/) — are consumers of /loop, not part of it.

Usage

/loop                                               # interactive dashboard
/loop 5m check the deploy and tell me what happened
/loop 30s run the test suite and fix failures       # fast loop (min 15s)
/loop 2h <prompt>                                    # slow loop
/loop status                                         # show active loop
/loop stop                                           # cancel

The bare command opens a responsive dashboard in TUI mode. It shows the current schedule, live countdown, delivery mode, prompt preview, and safe start/edit/stop actions. In print/RPC/JSON modes, the bare command reports status instead. The nested forms remain the stable scripting interface and are taught by argument autocomplete.

Interval formats: 30s, 5m, 2h, 1d (minimum 15s). Omit the interval for the default 10m. A trailing every 5m clause also works: /loop check CI every 5m.

Each tick arrives as a loop-tick custom message — the prompt verbatim, with a one-line provenance header so the model knows it is a scheduled message, not a fresh user request — rendered in the TUI as a collapsible card (↻ loop tick #7 · check the deploy…):

[loop tick #7 · scheduled by /loop, not typed by the user]
check the deploy and tell me what happened

How it works

One mechanism: an in-session timer (index.ts). Each tick is a single pi.sendMessage({ customType: "loop-tick", content, display: true, details }, { deliverAs: "steer", triggerTurn: true }) call — steer injects into a busy agent and wakes an idle one in the same call, so there is no idle check to race. Catch-up: on agent_settled, if a tick's fire time passed while the agent was busy, it fires immediately (at most one catch-up tick, no backlog). The timer dies with the pi process, the same lifetime a Claude Code in-session cron has. (An earlier version also spawned an external RPC runner; it was removed — old state entries carrying a runnerPid are still read, the field is ignored.)

State & resume

Loop state persists as a loop custom entry in the session JSONL (pi.appendEntry). On /resume, session_start re-arms the timer — CC's "restored on --resume" semantics. /loop stop appends a stopped: true entry. (Entries written by earlier versions under the old entry type, or carrying a legacy runnerPid, are still read.)

Safety & limits

  • One active loop per session (/loop while armed → stop first).
  • Session-scoped by lifetime (delivery is a single in-process call — no child processes, nothing to orphan). No wall-clock expiry.

The shepherd skill (a consumer of /loop)

The bundled skills/shepherd/ skill (installed at ~/.pi/agent/skills/shepherd) is the pi port of the Claude Code shepherd plugin: it pins /loop to a fixed 10-minute cadence with the shepherd-role prompt (watch, act, unblock, understand problems). It's a separate thing from the loop — the loop is generic; the skill just builds a specific prompt and hands it to /loop.

/skill:shepherd <goal to shepherd>

Differences vs Claude Code /loop

| | Claude Code | pi /loop | |---|---|---| | Scheduler | built-in CronCreate (in-process, session-scoped) | in-session timer, single steer delivery | | Survives model stall | yes (cron fires between turns) | yes (steer injects into a busy turn) | | Survives restart | no (restored on --resume) | no (re-armed on /resume via session entry) | | Interval | cron granularity, 1m–7d | any ≥15s, no expiry | | Dynamic interval | yes (model picks delay) | no — fixed interval only | | Jitter | yes (deterministic offset) | no |

Development

cd custom-extensions/loop
npm install
npm run typecheck
npm test            # domain + dashboard contracts + real pi E2E (~30s)

Install as a pi package (~/.pi/agent/settings.jsonpackages):

"/Users/maheidem/Documents/dev/pi-coder-management/custom-extensions/loop"

then /reload in pi. The skill is in skills/shepherd/SKILL.md (source of truth) and installed to ~/.pi/agent/skills/shepherd/ (copy after edits).

Files

  • index.ts — the extension: /loop commands, timer, steer delivery, catch-up, tick renderer
  • state.ts — pure helpers: interval parsing, tick provenance line, state
  • ui/loop-panel.ts — Pi-free dashboard view model
  • ui/settings-panel.ts — vendored workbench panel interaction primitive
  • skills/shepherd/SKILL.md — the shepherd skill (a consumer of /loop)