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

@floez-werk/pi-extension-release-tool

v0.1.4

Published

Release tooling for FloezWerk pi extensions: scaffolding, README release-notes sync, GitHub release notes and the shared CI/CD workflows.

Readme

pi-extension-release-tool

npm license CI changelog

Release tooling, shared CI/CD and the project template for the FloezWerk pi extensions. Everything that used to be copied into each extension repository lives here once.

Table of contents

What is in here

  • tooling/ - the published npm package @floez-werk/pi-extension-release-tool (command pi-release): scaffolding, generated README blocks (badges, release notes) and the GitHub release body. Used by every extension repository via npx -y …@^0.1 ….
  • template/ - the skeleton a new extension repository starts from (extension stub, README with badges and the changelog block, CHANGELOG.md, package.json, AGENTS.md, LICENSE, .gitignore/.gitattributes, thin CI/release callers, and a .gitea/workflows/ placeholder that keeps Gitea from scheduling the GitHub-only workflows).
  • .github/workflows/reusable-*.yml - the shared CI and release pipelines. Extension repositories call them with uses: …/[email protected], so a fix here reaches all of them without touching their files.
  • prompts/ - the interactive prompt template shipped with the package (/new-pi-extension): it collects the scaffold parameters, then follows the "New extension repository" flow below. Install the package as a pi package to get it.

Nothing in here is specific to a single extension; extension-specific code stays in the extension repository.

Tooling

# scaffold a new extension repository (see below for the full flow)
npx -y @floez-werk/pi-extension-release-tool@^0.1 init /srv/projects/piagent-my-ext \
  --name @floez-werk/piagent-my-ext \
  --desc "Pi extension: one-line description"

# regenerate the generated README blocks (badges, release notes) / verify them
npx -y @floez-werk/pi-extension-release-tool@^0.1 sync-readme
npx -y @floez-werk/pi-extension-release-tool@^0.1 sync-readme --check

# GitHub release body (the CHANGELOG section of the current version)
npx -y @floez-werk/pi-extension-release-tool@^0.1 release-notes --out /tmp/notes.md

# move the moving "v<major>.<minor>" tag (run after a release, from the repo)
npx -y @floez-werk/pi-extension-release-tool@^0.1 tag-major --push

The README and release-notes subcommands read package.json and CHANGELOG.md from the current directory, so they work in any repository. Two blocks in README.md are generated instead of maintained by hand (both guarded by --check in CI):

  • the badges block (badges:start / badges:end) - npm version, license, CI and changelog badges built from package.json (skipped in repositories without the markers)
  • the release-notes block (changelog:start / changelog:end) - the notes of the current version from CHANGELOG.md

Write those marker names in prose and in CHANGELOG.md without the comment syntax; a literal marker would look like a second block to the check.

Prompt template: new extension

The package is also a pi package and ships one prompt template. Install it once and the wizard is available as a slash command:

pi install npm:@floez-werk/pi-extension-release-tool

Run /new-pi-extension (no arguments needed). It asks for the package name, the brief and the optional init flags, then scaffolds the repository and implements the extension as described under New extension repository. After a package update, /reload picks up the new version of the template.

New extension repository

Steps 1-2 happen in the browser, 3-4 on the shell, 5-8 once for the repository. <repo> below is the repository name, e.g. piagent-my-ext.

  1. Gitea: create the repository (FloezWerk/<repo>, no README/license), then GitHub: create it as well (empty, public) - the GitHub repository is the mirror target and runs the workflows.

  2. Gitea: add the push mirror - Settings → Repository → Mirror Settings → Add Push Mirror with the GitHub URL and "Sync when new commits are pushed" enabled. Branches and tags are mirrored, which is what makes the release flow work: the tag is pushed to Gitea and GitHub Actions reacts on GitHub.

    Gitea must not run the workflows itself (it has no runner): the scaffolded .gitea/workflows/ directory makes Gitea stop looking for workflows before it reads .github/workflows. Keep that placeholder in place, otherwise every push shows up in the Gitea Actions tab as a queued run with "No runner is online to pick up this job."

  3. Scaffold the repository (the tooling comes from npm, no clone needed):

    npx -y @floez-werk/pi-extension-release-tool@^0.1 init /srv/projects/<repo> \
      --name @floez-werk/<repo> \
      --desc "Pi extension: one-line description"
    cd /srv/projects/<repo> && npm run check

    The scaffolder replaces all placeholders, generates the README release-notes block, runs git init -b main and creates the initial commit. Useful flags: --ext <file.ts> (extension file, default <repo>.ts), --cmd <name> (command without slash), --owner, --no-git.

  4. Push to Gitea:

    git remote add origin ssh://git@gitea/FloezWerk/<repo>.git
    git push -u origin main

    Verify on GitHub that the commit arrived (the mirror reacts on push).

  5. First npm publish (manual, once per package): the package does not exist on npm yet, so an automation token cannot be scoped to it. Run locally:

    npm login
    npm publish --access public

    Do not push the tag of this version (v0.1.0): the release workflow rejects versions that are already published, so the first tag-driven release is the next patch (v0.1.1). Keep the [0.1.0] link in CHANGELOG.md pointing at npm.

  6. GitHub: set the secret NPM_TOKEN (Settings → Secrets and variables → Actions): a granular token with publish rights for the new package (or an account-level automation token). Nothing else is needed - permissions and the workflow call are already in the scaffolded files.

  7. Optional, after the first tag-driven release: point the [Unreleased] link in CHANGELOG.md at compare/v0.1.1...HEAD instead of commits/main.

  8. Verify the pipeline with the next change: bump the patch version, move the [Unreleased] bullets into ## [X.Y.Z], npm run readme, commit, then

    git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z

    GitHub Actions then publishes to npm (with provenance), creates the GitHub release from the CHANGELOG section and attaches the tarball. pi.dev/packages lists the package automatically (pi-package keyword).

Releasing an extension

  1. Move the [Unreleased] bullets into ## [X.Y.Z] - YYYY-MM-DD in CHANGELOG.md.
  2. Bump "version" in package.json, run npm run readme, commit both.
  3. git tag -a vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z.

The rest is the shared pipeline (see reusable-release.yml).

Updating this toolkit

  • Versioning is 0.y.z; every change to tooling/ or template/ must end in a release, otherwise the pinned npx version in the extensions does not see it.
  • Release: CHANGELOG.md ([Unreleased] → ## [X.Y.Z]), npm run readme, version bump, commit, tag vX.Y.Z, push. The release workflow then publishes to npm and creates the GitHub release.
  • Afterwards move the moving tag locally: npm run tag-major sets vX.Y to this release and pushes it to Gitea, which mirrors it to GitHub. Tags are never created in a workflow, so Gitea stays the single source of truth for refs.
  • Extension repositories pin two refs: the npm package (@^X.Y in their package.json scripts) and the reusable workflows (@vX.Y in their ci.yml/release.yml). A patch release reaches them after the tag move; a minor release is a deliberate update - after a 0.2.0 release, update the pins in the affected repositories.
  • Workflows can be changed without touching the extensions: the tag move is what delivers the change. Watch the first run after a change (publish job of the tag build).
  • Changes that require new placeholders in template/ must also update tooling/scaffold.mjs; npm run check (self-test) fails otherwise.

Changelog

Notable changes per version are documented in CHANGELOG.md.

0.1.4 - 2026-09-20

Added

  • The toolkit doubles as a pi package and ships one prompt template (prompts/new-pi-extension.md): after pi install npm:@floez-werk/pi-extension-release-tool, /new-pi-extension asks for the package name, the brief and the optional init flags, then scaffolds the repository and implements the extension following this README. The package is flagged as a pi package (pi-package keyword, pi.prompts), so pi discovers the template automatically (/reload after an update).
  • The template ships .gitea/workflows/ with a README placeholder. Gitea scans that directory before .github/workflows and only falls back when it does not exist, so the scaffolded repositories no longer queue a run for every push to Gitea (“No runner is online to pick up this job.”): the GitHub-only workflows are never scheduled there.

Full history and all versions: CHANGELOG.md