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

spoolway

v0.11.0

Published

spoolway is a descriptive agent workflow builder run by a minimal command line state machine

Readme

spoolway is a descriptive agent workflow builder run by a minimal command line state machine. It turns coding agents into pipelines you can reason about. Determinism where possible. Terminal native. Built for herdr.

Create YAML pipelines that mix agents and commands, cloud and local models. Plan the work however you like, then cut spoolway tasks and assign each to a suitable pipeline. Measurable, comparable, repeatable.

Supported providers:

  • claude
  • codex
  • pi

Why

Running one coding agent is easy. Running five is hard: which one is done, which one is stuck, and which one is rewriting a file another one needs. The order lives in your head.

spoolway keeps that order for you. Its dispatcher has no model inside, so scheduling does not add model costs or depend on an agent's judgment.

How does it work?

spoolway gives each agent a system prompt that tells it how to report its outcome with spoolway report. The task carries context between steps. Through herdr, agents can interact with one another across harnesses.

An agent can report four outcomes:

| Outcome | What happens | |---|---| | pass | Moves to the step's on_pass destination. | | fail | Moves to on_fail or to blocked if none is set. | | block | Moves to blocked, usually handled by a bigger model you configure. | | pause | Stops the pipeline. It won't resume without you. Only gates or the blocked agent can pause a pipeline. |

A gate can pause a task for a person after a step reports.

Features

  • A dispatcher with no model in it. A TUI dashboard gives an overview of your queued tasks.
  • Define agents or commands. Each step names its own agent and model.
  • A worktree per task. Every task works on its own branch in its own checkout. Made visible through herdr.
  • Session context configuration. Set thresholds for when to re-prompt a session, auto-compact, or when to escalate to blocked state.
  • Unattended runs. When a task blocks, a configurable prompt takes over. It pauses the task for you only when it cannot resolve the issue.
  • Trials. Fork a group into one full copy per pipeline you tick, and compare the arms in eval.
  • Routines. Keep the tasks you run more than once in .spoolway/routines/.
  • Jobs. Run a routine on a cron schedule. A running dispatcher fires it.
  • Eval built in. Every lane's spend and outcome go into a ledger. Raise a pipeline's version: when you change it, and compare pass rate and price across versions.

Install

npm install -g spoolway

The package is a small wrapper around a prebuilt binary. It runs on Linux (x64, arm64, musl) and macOS (Apple Silicon, Intel). spoolway update installs a newer release. Run spoolway sync in each project to list the files the new release rewrites and apply them when you confirm. spoolway whats-new prints the release notes offline.

From source instead, in a clone of this repository:

cargo install --path .

As a herdr plugin:

herdr plugin install marvingygas/spoolway

Platform notes and requirements in full: Installation and setup.

Quick start

1. Set up

spoolway init

init asks where the project's setup should live. There are two choices.

| Setup | Where it lives | Use it when | |---|---|---| | repo | .spoolway/ in the checkout, tracked by git | The whole team should share the pipelines and prompts. | | home | A workspace under ~/.spoolway/ | Work with spoolway without touching repo code. |

See Home mode.

2. Create queueable tasks

Use /spoolway-tasks to cut an agreed plan or any other defined scope into Markdown tasks. It assigns each task to a suitable pipeline and writes the tasks to ~/.spoolway/<label>-<id>/pending/. You can create specialized pipelines for different kinds of work. If you want help shaping the work first, you can use /spoolway-plan.

3. Queue

spoolway

spoolway opens on the queue tab, which groups pending tasks. Select a group and press enter to queue it. The tab strip runs dispatch, queue, routines, jobs and eval, and ← and → move between them.

4. Dispatch

To start dispatching, spoolway must run in herdr.

herdr
spoolway

← from the queue tab opens the dispatch tab. Press enter there to start dispatching, or run spoolway dispatch from a script to print a line per pass instead of drawing the board.

Every task on the board is in one of a few states:

| State | Meaning | |---|---| | queued | Waiting for its dependencies and a free slot. | | waiting | Held at a serial: step while another task's run of it finishes. | | starting | A slot is claimed and the lane is booting. | | running | An agent is working the task's current step. | | prompt | A lane's pane is holding a permission prompt. Press a key in the pane. | | silent | A lane has not answered the last reminder, shown as ● silent · 31m. The task stays on its step. A lane that never answers needs the step restarted from the board. | | paused | Waiting for you on purpose: a gated step, or an unresolvable issue. | | blocked | A step reported a block and needs help. An unattended run hands it to the unblocker prompt. | | done | Finished: the worktree removed, the task archived. |

5. Calibrate

The /spoolway-calibrate skill reads your archived tasks, their step-level evaluation results and the spend ledger. It compares them with the prompts, pipelines and settings that produced them. The comparison explains review failures, blocked sessions and wasted loops. This is the feedback loop that enables improvement of your workflows over time.

A task is what travels the line, and you define it

---
id: sessions
title: "feat(auth): add session tokens on top of login"
group: auth
pipeline: default
base: main
depends_on:
  - login
---
## Context
## Intend
## Non-goals
## Acceptance criteria
## References

The frontmatter is spoolway's, the body is yours. spoolway never reads the body. The agent works from it, and you own the skeleton it is written from.

The pipeline is a file

  • Mix agents and commands
  • Set model and effort levels per step
  • Reuse previous sessions until the context threshold is met
  • Give the pipeline a version: and raise it when you change the pipeline, so eval can compare versions
  • Run a command step only on a chain's root task with first:, or one task at a time with serial:
# .spoolway/pipelines/default.yml
steps:
  - id: implement
    description: Write the code to satisfy the task's acceptance criteria.
    agent: pi
    prompt: implementer
    model: Ornith-1.5-35B-A3B
    session: true
    loop: 2
    on_pass: review

  - id: review
    description: Check the diff against the acceptance criteria and project standards.
    agent: claude
    prompt: reviewer
    model: claude-opus-5
    effort: high
    session: true
    on_pass: document
    on_fail: implement

  - id: document
    description: Bring the domain documents in line with what this task changed.
    agent: pi
    prompt: archivist
    model: Ornith-1.5-35B-A3B
    on_pass: handover

  - id: handover
    description: Create a stacked pull request without an LLM call.
    run: spoolway stack
    on_pass: done

Try changes without committing them

In a repo-mode project, the tracked .spoolway/ is shared with everyone. You can still change things on your own machine first. There are two ways:

Overrides

Apply changes that only affect you. An override patches a tracked pipeline, prompt or config value. It lives in ~/.spoolway/<project>/overrides/. Use it to apply changes for making your own setup compatible (e.g. use your local LLM to replace certain steps).

Private pipelines

A private pipeline is a whole new pipeline that only your machine sees. It lives in ~/.spoolway/<project>/local/ with its own prompts and task skeleton. Use this to copy pipelines or prompts to try something new without having to update the repository.

Tip: the /spoolway-config skill activates whenever you want to change something in the spoolway config.

See The overrides layer and Private pipelines.

Jobs

A job runs a routine on a schedule. It has three parts: a cron expression, a pipeline, and a routine saved under .spoolway/routines/.

A job is a few lines of TOML in ~/.spoolway/<label>-<id>/jobs.toml:

[jobs.nightly-audit]
schedule = "0 3 * * 1-5"   # weekdays at 03:00, local time
pipeline = "impl_fast"
routine  = "nightly"       # a folder or a single .md under .spoolway/routines/

Routines

A routine is a saved task or group of tasks that you can queue again. It lives in .spoolway/routines/. On the queue screen, press o on a group and pick save as routine to save it there, and r to browse and queue what is saved.

Trials

A trial answers one question: which pipeline fits this group best? On the queue screen, press o on a group and pick trial, tick any number of pipelines to compare, and tick any steps to skip. Each ticked pipeline gets one full copy of the whole group, and all arms share one trial id. Compare them with spoolway eval --by task --trial <id>, or open the trial from the eval tab's trials table. An arm never pushes a branch or opens a pull request. When the last arm finishes, every arm's copy is removed. The source group and the ledger rows stay.

Issue tracker

Event hooks can sync tasks with an issue tracker.

| Event | When it fires | |---|---| | fetch | spoolway issue show <ref> reads one issue out of the tracker | | open | spoolway queue add opens a ticket per task | | queued | A task arrives in the queue | | started | A queued task is ready and about to leave queued for its entry step | | blocked | A task comes to rest on blocked | | paused | A task arrives on the persisted paused stage | | done | A task finishes |

The two shipped scripts are editable samples. Choosing a tracker in spoolway init copies github.sh and jira.sh into .spoolway/hooks/, where they belong to your project. Change them, replace them, or leave issue tracking disabled; spoolway hook contract describes the events and environment available to any custom script.

See Issue Tracking.

Configurable per project

  • Unattended mode hands blocked tasks to a prompt you define, so the pipeline keeps running while nobody is watching.
[dispatch]
lane_quiet = "15m"           # silence before a lane is reminded to report
auto_commit = true           # commit a lane's leftover work when its step settles

[unattended]
enabled = true               # the overnight switch
max_output_tokens = 0        # output-token ceiling for a run with nobody watching; 0 is none
max_cost_usd = 0.0           # dollar ceiling for the same run; 0 is none
blocked_agent = "claude"     # who staffs `blocked` when nobody is at the keyboard
blocked_model = "claude-opus-5"
blocked_effort = "medium"
blocked_session = true       # the unblocker carries its own earlier session forward
blocked_prompt = "unblocker"

[housekeeping]
update_check = true          # show a newer release in the dispatcher header
calibrate_window = "14d"     # how far back `/spoolway-calibrate` reads
retention_days = 30          # how long run records, logs and scratch space are kept; 0 keeps everything
archive_retention_days = 0   # how long finished tasks are kept; 0 keeps every one
price_max_age_days = 30      # how old the price table may be before `spoolway doctor` says so

[issue_tracking]
hook = ""                    # a script in .spoolway/hooks/, e.g. "github.sh"; blank runs none
project_key = ""             # handed to the hook verbatim, e.g. owner/repo
key_in_names = true          # prefix branch and worktree names with the tracker's slug

[agents.claude]
kind = "claude"
concurrency = 3              # most lanes of this profile at once
session_reuse_ctx = 20       # % of the window before a carried session restarts fresh
session_blocked_ctx = 40     # % of the window at which a running lane is stopped and blocked; 0 is off
permission_mode = "auto"

[agents.codex]
kind = "codex"
concurrency = 3
session_reuse_ctx = 20
session_blocked_ctx = 40
permission_mode = "never"

[agents.pi]
kind = "pi"
session_reuse_ctx = 50
session_blocked_ctx = 0

[models."Ornith-1.5-35B-A3B"]  # a local model, served by llama.cpp
context_window = 100096
slots = 2                    # parallel lanes the local server can actually hold
local = true                 # runs on hardware you own

See Configuration.

Eval every run

When a lane finishes, its transcript is read and written to a ledger: tokens, cost, wall time, and what the lane reported. spoolway eval shows what each pipeline costs to run, by pass rate and price.

spoolway eval

spoolway eval prints the lanes table, grouped by pipeline. spoolway eval --by version compares a pipeline's versions. Bare spoolway's eval tab opens the same table interactively: tab cycles to the directory table and the trials table, t switches between totals and per-run figures, f filters, and e exports CSV.

Documentation

See Documentation.

License

MIT. See LICENSE.