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-keep-going

v1.1.0

Published

Pi extension: one-shot /kg scheduling and usage-limit auto-resume for Anthropic, Codex, and Gemini.

Readme

pi-keep-going

English · 繁體中文 · 日本語 · Français · Español

A Pi extension that keeps a run alive across provider usage limits, and schedules one-shot follow-up messages when you ask for them.

Zero setup — it just runs

You do not have to run any command. Auto-resume is on by default (autoResume.enabled: true), so once the extension is installed it watches every turn on its own:

  1. It caches any 429 response it sees from the provider.
  2. When a turn ends on a usage-limit error, it classifies the error and resolves the reset time (headers → error body → provider usage API).
  3. It schedules the continuation message (continue) for reset + 90s and tells you when that is: Usage limit reached (anthropic) — auto-resuming at 14:05.

When the window reopens the message is sent and the agent picks up where it stopped. The /kg command exists for the times you want to schedule something yourself — it is never required for the automatic path.

Install

pi install npm:pi-keep-going

Pi prompts you to run pi update --extensions only when a new version is published: for an npm source it compares the installed package.json version against the registry. Leave the spec unversioned — npm:[email protected] counts as pinned, and Pi skips update checks for pinned sources entirely.

To hack on it, install a clone by path instead. A local-path install is referenced from ~/.pi/agent/settings.json, not copied, so your edits take effect on the next Pi start:

git clone https://github.com/ohlulu/pi-keep-going
pi install ./pi-keep-going

/kg command

| Command | Effect | | --- | --- | | /kg 40m keep going | Send keep going after 40 minutes. | | /kg 2h30m | Send the default message (keep going) after 2h30m. | | /kg 90s ship it | Duration is largest-unit-first: d h m s, each unit at most once. | | /kg auto [message] | Query the current provider's usage API and schedule at the reset time + buffer. | | /kg list | List pending scheduled messages. | | /kg cancel | Cancel a scheduled message (prompts when several are pending). | | /kg help | Show usage. A bare /kg does the same. |

Scheduled jobs are persisted per branch, so they survive /tree, /fork, and reload. Timers use an absolute fire timestamp checked on a 30s tick, so a job still fires correctly after the machine sleeps. Nothing enters the LLM context except the final message that is actually sent.

Countdown widget

While anything is pending, a countdown sits above the editor with a small animated companion — a dog or a cat, chosen at random each time a countdown starts:

⏱ keep going in 7m 58s (14:23)

The art is original pixel art, drawn as truecolor half-blocks so one terminal cell carries two pixels. Colour degrades on its own: 24-bit where the terminal advertises it, 256 colours otherwise, and flat ASCII art when there is no colour at all. Frames advance every 900ms, and the timer only exists while a job is pending — an idle session is left completely alone.

Auto-resume

When a turn ends on a usage-limit error, the extension:

  1. Classifies the error per provider (from the assistant error message plus any cached 429 response headers).
  2. Resolves the reset time (headers → embedded time → provider usage API). The usage-API step is load-bearing for Anthropic: the SDK throws on 429 before pi can observe the response, so the unified-reset headers are never cached and the error body carries no reset time.
  3. Schedules a continuation message at reset + bufferSeconds, guarded by the settings below.

Auto-resume is skipped silently inside a 5-minute window after a previous resume (loop protection), and turns into a notification (rather than a schedule) when the per-session cap is reached or the reset is further away than maxWaitHours.

Provider support

| Provider | Detection | auto usage API | | --- | --- | --- | | OpenAI Codex (openai-codex) | hit your ChatGPT usage limit, usage_limit_reached, 429 | GET /backend-api/wham/usagerate_limit.primary_window.reset_at | | Anthropic (anthropic) | rate-limit errors, 429, unified-reset headers | GET /api/oauth/usagefive_hour.resets_at (needs an OAuth login, not an API key) | | Google Gemini (google-gemini-cli, google) | RESOURCE_EXHAUSTED, quota errors | POST v1internal:retrieveUserQuota → earliest buckets[].resetTime (needs the CLI login's project id) |

Tokens are resolved through ctx.modelRegistry.getApiKeyForProvider() (Pi handles OAuth refresh); the extension never reads auth.json or refreshes tokens itself. If a usage API is unreachable or unsupported, auto degrades to a notification suggesting a manual /kg <duration>.

Settings

Everything below already has a working default — you only need a config file to change behavior, e.g. to turn auto-resume off or send a different message.

Global config lives at <pi agent dir>/keep-going.json. A project-local override at <cwd>/<pi config dir>/keep-going.json is applied only when the project is trusted. Later layers win; unknown or invalid fields are ignored.

{
  "defaultMessage": "keep going",
  "autoResume": {
    "enabled": true,        // master switch for usage-limit auto-resume
    "message": "continue",  // message sent when a window reopens
    "bufferSeconds": 90,    // wait past the reset before sending
    "maxPerSession": 5,     // cap auto-resumes per session
    "maxWaitHours": 24      // beyond this, notify instead of scheduling
  }
}

How it stays safe

  • Generation guard — every session gets an AbortController + generation id. auto usage-API fetches run with a 10s timeout composed with the session signal, and the result is discarded if the session was replaced while the request was in flight.
  • Single-firer lease — if two Pi processes attach to the same session, an advisory lock elects one firer; the other runs read-only so a job is sent exactly once.

Development

npm install
npm run typecheck
npm test
pi -e ./src/index.ts   # load locally

@earendil-works/pi-coding-agent is a peer dependency — it is provided by the Pi runtime that loads the extension, so it must not be bundled. It is also a dev dependency here so tsc and vitest resolve it locally.