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

@projectpac/flow-template

v0.6.0

Published

Part of PAC: @projectpac/flow-template.

Downloads

132

Readme

@projectpac/flow-template

The smallest complete flow, doing the smallest complete network thing: it advertises itself, finds a peer through discovery, opens a session, sends one message, and echoes the same message back when a peer sends it. Locally it answers at once, or asks its own model what to say when configured to.

It exists to keep the sdk honest. Everything it touches -- the host events, the caller-aware components, the manifest -- comes from @projectpac/sdk and cordis alone, so if the template compiles and runs, a flow nobody here wrote needs no core package either. Two things sit beyond them. The router's contract, and only its types: what a flow declares to ctx.router is the router's shape to define, so the router is a devDependency imported for the declaration alone, and nothing of it is loaded at runtime. And @projectpac/prompting, which is functions rather than a plugin: the kernel hands a turn's text back verbatim and composes no prompt, so a flow that asks its model anything composes the prompt and reads the answer itself, and these are the helpers every such flow shares. That is why the loader smoke suite and the two-node tests reach for the template: a failure in it is a failure in the seam, not in a workload.

It is also what the name says: the smallest thing to copy when starting a flow of your own.

A seam test and a thing to copy, not a workload. It declares the fallback intent to the router, from an optional scope, so on a node whose router has nothing better it answers -- by echoing; a node with no router runs it all the same. Install it to prove the machinery; uninstall it before it answers for something real.

Nothing is done for it. The flow tells the network this node runs it (ctx.network.route), or an envelope naming it is rejected; it advertises itself under kind: "flow" -- version, package, payload types -- which is how a router learns which peers a flow can be started with; and it runs its own timers, as effects of its own scope. The host fires no schedule and advertises nothing on a flow's behalf, so what you copy is the whole of what a flow does.

| | | | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- | | routes | POST /echo -- locally, or across the wire with peer (from GET /board) or anyone; GET /echoes is where replies land | | payloads | echo.request, echo.reply | | advertises | itself under kind: "flow" (version, package, payload types), and its echo under kind: "echo", which is what the board shows | | background | two intervals of its own: advertise every 60s until both advertisements stick, sweep every 60s (a pending echo ends unanswered) | | needs | nothing: no sources, no operations, no tools | | intent | echo, declared to ctx.router from an optional scope and fallback, so a router has something to pick when nothing else fits | | results | one echo per echo sent, declared to ctx.results from an optional scope: GET /flows/results/results reads them beside every flow's |

Running it

pnpm check       # includes tests/template.spec.ts: two whole nodes, one echo across the wire
just demo        # headless: a directory, two seeded nodes, one echo over iroh, down
just dev         # the same, lived in: panes, both pages, driven by hand

With the environment up: just a1 api GET /flows/template/board says who is offering, just echo "anything" sends it across and waits for the reply, and just a1 api POST /flows/template/echo --body '{"text":"hi"}' is the local case.

A real model

The lane needs none: the scripted executor answers, and the echo across the wire is a plain echo either way. MODEL= swaps in a real one, the way the other flow lanes take it -- the command is spawned rather than shelled and gets the prompt on stdin, so its flags ride MODEL_ARG, space-separated:

MODEL=pi MODEL_ARG="-p --model anthropic/claude-sonnet-4-5" just dev

Check the command works headless first (echo hi | pi -p): it authenticates from your home directory, which the executor passes through. With MODEL set the flow is installed with reasonAboutReplies, so the local POST /echo starts a run rather than answering itself and comes back 202 with a run id -- the page's runs pane is where that answer lands. The wire path is unchanged: a peer answering an echo.request still echoes it. The executor is chosen when a node is set up, so switching MODEL, or going back to the scripted one, takes a just reset first.

The sibling layout

Cross-repo dependencies are link: paths into checkouts beside this one -- nothing of PAC's is fetched from a registry. Clone the repos this one links into the same parent directory, run pnpm install in each, and everything resolves from source. The flow's whole-node suite lives in tests/, standing up real nodes from the sibling pac-node. Copy this repository to start a flow of your own.