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

pi-schedule-prompt

v0.4.0

Published

Pi's Heartbeat - A pi extension for scheduling recurring and one-shot main agent or background prompts with cron-like functionality

Readme

pi-schedule-prompt

A "Heartbeat" like prompt scheduling Pi extension that allows the Agent to self-schedule future prompts to execute at specific times or intervals - for reminders, deferred tasks, and recurring automation.

https://github.com/user-attachments/assets/8c723cc4-cf3e-4b6a-abf5-85d4f46c73ba

Status: Production-ready. Natural language scheduling with cron expressions, intervals, relative time, and one-shot timers.

Schedule future prompts with natural language:

  • "schedule 'analyze logs' every hour" (recurring)
  • "remind me to review PR in 30 minutes" (one-time)
  • "defer that task until tomorrow at 9am" (specific time)

Features

Core schedule_prompt Tool

  • Natural language scheduling: "schedule X in 5 minutes", "every hour do Y"
  • Multiple formats: Cron expressions, intervals, ISO timestamps, relative time (+5m, +1h)
  • Job types:
    • Recurring (cron/interval) — repeats automatically
    • One-shot (once) — runs once then auto-disables
  • Per-task model (optional): set model on a job to run that prompt in a separate in-process agent session — your current chat is not affected
  • Actions: add, remove, list, enable, disable, update, cleanup
  • Auto-cleanup: Removes disabled jobs on session exit

Use Cases

Schedule (Recurring Tasks)

Execute prompts repeatedly at set intervals:

"schedule 'check build status' every 5 minutes"
"run 'analyze metrics' every hour"
"execute 'daily summary' at midnight every day"

Remind (One-time Notifications)

Get prompted to do something once at a specific time:

"remind me to review the PR in 30 minutes"
"remind me to check deployment status in 1 hour"
"remind me tomorrow at 9am to follow up on the issue"

Enhanced Pi Features

  • Live widget below editor showing active schedules (auto-hides when empty)
  • Human-readable display: "every minute", "daily at 9:00" instead of raw cron expressions
  • Status tracking: next run, last run, execution count, errors, prompt preview
  • Flexible scheduling: 6-field cron, intervals (5m, 1h), relative time (+10s), ISO timestamps
  • User commands: /schedule-prompt opens a Jobs overlay (hotkey-driven: ↑↓ select, a add, t toggle enabled, s toggle scope, x remove, c cleanup) and a Settings submenu
  • Persistent settings: widget visibility persists across sessions and package upgrades (project file overrides global defaults)
  • Safety features: duplicate name prevention, infinite loop detection, past timestamp handling

Install

Option A — Install from npm:

pi install npm:pi-schedule-prompt

Option B — Load directly (dev):

pi -e ~/projects/pi-cron-schedule/src/index.ts

Option C — Install from local folder:

pi install ~/projects/pi-cron-schedule

Then run pi normally; the extension auto-discovers.

Usage

LLM-driven (automatic)

The agent automatically uses schedule_prompt when you want to schedule, defer, or be reminded:

You: Remind me to check the deployment logs in 10 minutes

Agent: [calls schedule_prompt with schedule="+10m", prompt="check the deployment logs"]
✓ Scheduled job "abc123" to run in 10 minutes

The widget displays below your editor (only when jobs exist):

 Scheduled Prompts (3 jobs)
  ✓ check-logs    every hour      check deployment logs     in 45m    12m ago  5
  ✗ daily-report  daily           analyze metrics           in 8h     never    0
  ✓ review-pr     Feb 13 15:30    review PR #123            in 2h     never    0

Manual commands

/schedule-prompt opens a two-item menu:

  • Jobs — full-screen overlay listing every scheduled prompt in this cwd. Your session's jobs are at the top; jobs bound to other sessions render read-only below. Hotkeys: / select, a add (opens the input series — name/type/schedule/prompt/scope/confirm), t toggle enabled, s toggle scope (session-bound ↔ shared with all pi sessions in this cwd), x remove (with y/n confirm), c cleanup all disabled jobs, q/esc close.
  • Settings — widget visibility and the default scope for new jobs (Bind new jobs to session: yes/no). Persists across sessions.

Tool Parameters (schedule_prompt)

| Param | Type | Required | Description | |-------|------|----------|-------------| | action | add | remove | list | enable | disable | update | cleanup | yes | Operation to perform | | name | string | no | Job name (auto-generated if omitted on add) | | schedule | string | on add | Cron expression, ISO timestamp, relative time (+10s, +5m), or interval (5m) | | prompt | string | on add | Prompt text to execute when the job fires | | jobId | string | on remove / enable / disable / update | Target job | | type | cron | once | interval | no | Job type. Default cron; use once for relative times like +10s | | description | string | no | Free-form note | | model | non-empty string | no | If set, run the prompt in a fresh in-process agent session with this model instead of injecting into the current chat. Accepts fuzzy names (haiku, sonnet) or provider/model-id. To switch a job from subagent back to inline mode, remove and re-add it without model (no in-place clearing) | | notify | boolean | no | Subagent-only. If true, the parent agent is woken to react to the subagent's result. Default false (result shown in chat, parent not interrupted). No-op for inline (no-model) jobs — the prompt itself already wakes the parent. Recommended only for low-frequency jobs |

Schedule Formats

The tool accepts multiple time formats:

| Format | Example | Type | Description | |--------|---------|------|-------------| | Relative time | +5m, +1h, +30s, +2d | once | Runs once after delay | | Interval | 5m, 1h, 30s, 2d | interval | Repeats at interval | | ISO timestamp | 2026-02-13T15:30:00Z | once | Runs once at exact time | | Cron expression | 0 */5 * * * * | cron | Runs on cron schedule |

Cron format (6 fields - must include seconds):

┌─ second (0-59)
│ ┌─ minute (0-59)
│ │ ┌─ hour (0-23)
│ │ │ ┌─ day of month (1-31)
│ │ │ │ ┌─ month (1-12)
│ │ │ │ │ ┌─ day of week (0-6, Sun-Sat)
│ │ │ │ │ │
0 * * * * *   → every minute
0 0 * * * *   → every hour
0 */5 * * * * → every 5 minutes
0 0 0 * * *   → daily at midnight
0 0 9 * * 1-5 → 9am on weekdays
* * * * * *   → every second

Note: Traditional 5-field cron expressions (without seconds) are not supported. Use 0 * * * * * for "every minute", not * * * * *.

How It Works

Storage:

  • Job data: .pi/schedule-prompts.json (project-local, atomic writes, auto-created)
  • Settings: two-layer config — ~/.pi/agent/schedule-prompts-settings.json (global, hand-edited defaults) and <cwd>/.pi/schedule-prompts-settings.json (project, written by the UI). Project overrides global on load.

Job binding:

By default a job fires only in the session that created it — opening two pi sessions in the same directory won't double-fire schedules. To make a job fire in every pi in this cwd (useful for hand-edited project-wide cron), remove its session field from <cwd>/.pi/schedule-prompts.json.

Toggle the default for new jobs in /schedule-prompt → Settings → Bind new jobs to session. Flipping only affects future jobs.

Heads up: schedules only fire while a pi session is open in this directory; nothing is queued. A daily 9am cron only fires on days at least one pi is open at 9am.

Scheduler:

  • Uses croner library for cron expressions
  • Native setTimeout/setInterval for intervals and one-shots
  • Tracks: next run, last run, execution count, status (running/success/error)

Execution:

  • Sends scheduled prompt as user message to Pi agent
  • Displays custom message showing what was triggered
  • Updates job statistics after each run

Safety:

  • Infinite loop prevention: Blocks scheduled jobs from creating more schedules
  • Past timestamp detection: Auto-disables jobs scheduled in the past
  • Duplicate names: Prevents name collisions
  • Auto-cleanup: Removes disabled jobs on exit

Widget:

  • Auto-hides when no jobs configured
  • Shows: status icon, name, schedule (human-readable), prompt (truncated), next run, last run, run count
  • Human-readable formatting: "every minute", "daily", "Feb 13 15:30" instead of raw cron/ISO
  • Auto-refreshes every 30 seconds
  • Visibility togglable via /schedule-prompt → Settings; persists across sessions (and package upgrades) in <cwd>/.pi/schedule-prompts-settings.json, with ~/.pi/agent/schedule-prompts-settings.json as the global default
  • Status icons: enabled, disabled, running, ! error

Examples

One-time reminders

"remind me to check logs in 5 minutes"
  → schedule="+5m", type=once

"schedule 'review metrics' for 3pm today"
  → schedule="2026-02-13T15:00:00Z", type=once

Recurring tasks

"analyze error rates every 10 minutes"
  → schedule="10m", type=interval

"run daily summary at midnight"
  → schedule="0 0 0 * * *", type=cron

"check build status every hour"
  → schedule="0 0 * * * *", type=cron

"execute every minute"
  → schedule="0 * * * * *", type=cron

Heartbeat monitoring

"check system health every 5 minutes"
  → schedule="5m", type=interval

Run in a separate agent session (per-task model)

By default a scheduled prompt is injected into your current chat. Set model on the job to run it in a fresh in-process agent session instead — your current chat keeps its own model and context untouched.

"every morning at 9, summarise yesterday's logs using haiku"
  → schedule="0 0 9 * * *", type=cron, model="haiku", prompt="summarise yesterday's logs"

"in 30s reply with OK using sonnet"
  → schedule="+30s", type=once, model="sonnet", prompt="Reply with OK"

model is permissive: pass a fuzzy name (haiku, sonnet) or fully qualified provider/model-id. The first match in the available model registry is used. When the job fires you'll see a 🕐 Scheduled (subagent: <model>) marker in chat, followed by a ✓ finished (or ✗ failed) marker with the response snippet once the subagent completes.

By default the result is shown in chat but the parent agent is not woken up — you read it, the agent isn't interrupted. Set notify: true on the job if you want the parent to react to each completion (e.g. for autonomous workflows). Recommended only for low-frequency jobs; a notify: true recurring job that fires every 5 minutes will trigger a parent-agent turn every 5 minutes.

Heads up: Subagent jobs run unattended at fire time with the full default tool set (bash, read, edit, write, …) under your credentials. Treat persisted jobs in .pi/schedule-prompts.json as you would any auto-executed task — review prompts before adding, especially anything that mutates files or shells out.

Development

TypeScript check:

npx tsc --noEmit

Run the test suite (vitest):

npm test

Test with Pi:

pi -e ./src/index.ts

Project Structure

src/
  types.ts          # CronJob, CronJobType, CronToolParams
  storage.ts        # Job persistence (.pi/schedule-prompts.json)
  settings.ts       # Settings persistence (global + project, project overrides)
  scheduler.ts      # Core scheduling engine with croner
  subagent.ts       # Lightweight in-process agent runner (per-task model)
  tool.ts           # schedule_prompt tool definition
  ui/
    cron-widget.ts  # Live status widget below editor
  index.ts          # Extension entry point

License

MIT (see LICENSE)

Author

tintinweb