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

td-barrage

v0.2.4

Published

A persistent, dependency-aware task queue for the pi coding agent.

Readme

td-barrage

A persistent, dependency-aware task queue for the pi coding agent. It loads a JSON task file, runs ready tasks through pi, saves state after every transition, and resumes interrupted work on the next invocation.

Requirements

  • Node.js 22.19 or newer
  • npm
  • pi authenticated with a model provider (pi, then /login), or a supported provider API key in the environment

Install

In a target project:

npm install --save-dev td-barrage

Or run ad-hoc without installing:

npx td-barrage --tasks queue.json

Once installed, the td-barrage CLI is on the project PATH:

npx td-barrage --tasks queue.json

For local development on this package:

npm install
npm run build

Task File

Task files use a top-level tasks array. A bare array is also accepted when loading.

{
  "tasks": [
    {
      "id": "build",
      "prompt": "Create .queue/results/build.json with {\"status\":\"ok\"}.",
      "success": { "strategy": "result_json", "path": ".queue/results/build.json" }
    },
    {
      "id": "verify",
      "prompt": "Verify the build result and create .queue/results/verify.json with {\"status\":\"ok\"}.",
      "dependsOn": ["build"],
      "timeoutMs": 600000,
      "maxAttempts": 2,
      "success": { "strategy": "result_json", "path": ".queue/results/verify.json" }
    }
  ]
}

Supported task fields:

  • id: unique task id
  • prompt: prompt sent to pi
  • dependsOn: dependency ids
  • status: pending, running, done, failed, or blocked
  • attempts: persisted attempt counter
  • maxAttempts: per-task retry limit
  • timeoutMs: per-task prompt timeout
  • cwd: per-task working directory
  • success: default, file_exists, or result_json
  • recoveryNotes, error, startedAt, finishedAt: runtime metadata

CLI

With no path given, the queue is read from .agents/skills/barrage/queue.json, resolved against --cwd (the process working directory by default):

npx td-barrage
npm run dev -- --tasks queue.json
npm run dev -- queue.json --max-attempts 3 --cwd /path/to/work
npm run dev -- --tasks queue.json --dry-run
npm run dev -- --tasks queue.json --json
npm run dev -- --tasks queue.json --verbose --timestamps

Options:

  • --tasks, -t <path>: task file (also accepted as a positional argument); defaults to .agents/skills/barrage/queue.json under --cwd
  • --max-attempts <n>: global retry limit (per-task maxAttempts overrides it)
  • --timeout-ms <ms>: global per-prompt timeout, default 600000 (per-task timeoutMs overrides it)
  • --cwd <path>: working directory for tasks that do not set their own
  • --dry-run: print the topological plan (one id per line) and exit without running
  • --no-commit: skip the git commit stage that otherwise runs after each successful task
  • --json: emit newline-delimited JSON events instead of human output

Exit codes:

  • 0: all reachable tasks completed
  • 1: at least one task failed or became blocked
  • 2: CLI usage or missing task-file error
  • 75: the run paused on a provider quota / rate-limit wall (see below)

Pi sessions

Each task runs in its own in-memory pi agent session scoped to the task working directory. Barrage uses pi's existing authentication and model settings. Terminal provider errors from pi's final assistant state feed into the pause/resume flow below. Sessions are disposed after their task prompt settles.

Pausing on quota / rate limits

Running out of provider tokens is treated as a property of the run, not of any task. When a prompt fails with a quota, rate-limit, or overload signal (HTTP 402/429/503/529, or matching error wording), the runner:

  • rolls back the attempt it charged — the task did not really run, so its retry budget is untouched,
  • leaves the task pending (exactly as crash recovery does),
  • stops the rest of the sweep immediately, since every ready task would hit the same wall, and
  • exits 75 (EX_TEMPFAIL) with the reason on stderr.

Because task state and workspace changes are persisted, resuming is just re-running the same command once tokens are back. The pending task starts a fresh in-memory pi session and can inspect the work already on disk; conversation history is not restored. No failed or blocked task is recorded for the pause. The distinct exit code lets a wrapper or scheduler tell "try again later" apart from 1 ("something is broken"). A Retry-After header, when present, is surfaced as a suggested wait in the pause message.

Telemetry & output

By default the runner is deliberately verbose, narrating progress as it happens: a startup header (version, task file, cwd, limits), the resolved execution plan, a line as each task starts, a running account of what the model is doing inside the task (below), and a line as each task finishes with its duration and overall progress (2/5 complete). Failures, retries, and blocks are always reported, along with a closing summary and total elapsed time.

In-progress activity

A single task can run for minutes. Rather than leave that as a silent spinner, Barrage subscribes to the pi session for the life of the prompt and reports each step the model takes:

▶ add-parser starting (attempt 1/2)
  ↳ thinking…
  ↳ I'll look at the existing lexer first, then add the parser beside it.
  ↳ grep tokenize
  ↳ read src/lexer.ts
  ↳ write src/parser.ts
  ↳ bash npm test -- --run
  ↳ bash failed: FAIL test/parser.test.ts — 2 failed
✔ add-parser done in 1m12s · 1/1 complete

Four kinds of step are reported: thinking (the model is working but has produced nothing yet), the assistant's own prose, a tool call with the argument that best identifies it (a command, a search pattern, or a path), and a tool call that failed. Successful tool calls get no line of their own — the next step supersedes them. Arguments and prose are collapsed to a single line and clipped to 80 characters, and raw model thinking is never printed.

On an interactive terminal these fold into the live spinner line, so the newest step replaces the last rather than stacking rows; piped or in CI they are plain ↳ lines as above. They appear at normal verbosity and are suppressed by --quiet. In --json mode each one is a task_activity event carrying the task id and a structured activity object, so a log aggregator can reconstruct the trace.

On that live line a step holds its place for at least four seconds, so a burst of quick tool calls is read one at a time instead of flashing past. Steps that arrive inside that window queue behind it and are shown in turn; a task that outruns the window for long keeps only the three most recent waiting steps, so the line stays close to what the model is doing now rather than drifting minutes behind it. When a task ends, whatever is still waiting is dropped and the result line lands at once. Piped output and --json are unpaced — every step is written as it happens.

Verbosity flags:

  • --verbose, -v: add per-step traces — the agent session id and the success-check result for every task
  • --quiet, -q: show only failures, blocks, and the final summary
  • --timestamps: prefix each line with a wall-clock time
  • --color / --no-color: force or disable ANSI color (auto-detected from the TTY otherwise; the NO_COLOR and FORCE_COLOR environment variables are honored)

--json emits every event — including the enriched fields above — as one JSON object per line, regardless of verbosity, which is the format to pipe into log aggregators or jq. --dry-run always prints a bare, uncolored id list so it stays easy to pipe.

Success Checks

default succeeds unconditionally.

file_exists succeeds when the configured path exists relative to the task cwd.

result_json succeeds when the configured JSON file parses and contains "status": "ok".

Commits

After a task passes its success check, the orchestrator stages everything with git add -A and commits it in the task's cwd with the message feat: <id>. A clean working tree (nothing to commit) is a quiet no-op, and a commit that fails outright is reported as a warning but never flips the task back to failed — the task already succeeded. Pass --no-commit to skip this stage entirely.

Recovery

On startup, any task persisted as running is reset to pending, annotated in recoveryNotes, and retried. The attempts counter is preserved, so a task that crashed mid-run still counts that attempt.

Scripts

npm test
npm run test:watch
npm run typecheck
npm run build
npm run test:integration

Integration tests are excluded by default. Run them with:

RUN_INTEGRATION=1 npm run test:integration

The integration test runs real pi sessions using your configured authentication and model, so it may consume provider credits.

Architecture

The orchestrator accepts its dependencies as arguments:

  • client: pi-compatible agent client seam
  • fs: filesystem seam
  • clock: timer seam for timeout tests
  • log: human or JSON event logger

Pi's session event stream is translated into Barrage's small progress vocabulary in src/activity.ts, which is pure and typed against unknown at the boundary: an unfamiliar or newly added pi event is ignored rather than crashing a run. The minimum time a step holds the live spinner row lives in src/pace.ts, a generic queue with an injected timer seam, so its rules are tested on a hand-wound clock rather than in real time.

This keeps most behavior covered by fast unit tests using a fake client and in-memory filesystem.