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

tetra-run

v0.4.0

Published

A configurable, gated, cross-reviewed multi-agent code pipeline: write, gate, review, fix, stop.

Readme

tetra

npm license node

A configurable, gated, cross-reviewed multi-agent code pipeline.

tetra stops at the human boundary — it never commits, pushes, or opens PRs — and the agent that writes the change is never the agent that judges it, while a real test gate must pass before anything is called done. It is the opposite of "point an agent at a repo and let a loop run unsupervised": every run ends with a clean-or-clearly-stopped working tree left for you to ship.

tetra runs a disciplined loop over any repository:

[plan → plan-review] → write → gate → review → (fix loop) → STOP
  • plan / plan-review (optional) — an agent drafts an implementation plan and an independent agent critiques it; the approved plan is handed to the writer. See Plan stage.
  • write — an agent implements the task in the working tree.
  • gate — the project's own tests/lint run. Nothing proceeds past a red gate.
  • review — an independent agent (ideally a different model) reviews the diff.
  • fix loop — if the gate fails or the reviewer requests changes, the feedback is handed back to the agent and the loop repeats (up to a configurable limit).
  • STOPtetra leaves a clean working tree for you. It never commits, pushes, or opens PRs. That step is always yours.

The idea: keep the opinion (gate-before-merge, cross-model independent review, a bounded auto-fix loop) but never force a particular toolchain. Every stage's agent is swappable.

Why

Most agent tools let one model write and judge its own work. tetra separates the writer from the reviewer, insists the project's real tests pass before anything is considered done, and stops at the human-owned line (commit/push/PR).

Terminal states

Every run ends in exactly one of these. The working tree is always left for you — tetra never reverts your changes, and never commits them either.

| Outcome | Exit code | Working tree | |---|---|---| | Clean — gate passed and reviewer said APPROVE | 0 | left for you to commit | | Gate still red after max fix iterations | 1 | left, gate still failing | | Reviewer still REQUEST-CHANGES after max fix iterations | 1 | left, changes outstanding | | Review produced no verdict (fail-closed) | 1 | left, not declared clean | | A stage crashed (nonzero exit) | 1 | left at the point of failure | | A stage timed out | 1 (inner 124) | left, the agent was killed |

A non-dry run always writes a run report recording which of these it hit.

Scope & honesty

tetra catches noisy failures: a red gate, a reviewer that requests changes, a crash, a hang. Those it stops on, loudly.

It does not catch silent ones. Plausible-but-wrong code that passes your gate and convinces the reviewer still reaches a clean-looking tree with exit 0. tetra is only as strong as your gate — a weak test suite is a weak gate. An independent reviewer reduces this risk but does not eliminate it. A clean run means "passed your tests and a second agent," not "is correct." The final judgement, like the commit, is yours.

Install

npm install -g tetra-run

Requires Node.js ≥ 20, plus whatever CLIs your config references (e.g. claude, codex) installed and authenticated.

Usage

tetra run "Fix the off-by-one in split() and add a test" --repo . --base main
tetra run "..." --dry-run         # print the plan without executing anything
tetra run "..." --plan            # add a plan + plan-review round for this run
tetra run "..." --no-plan         # skip plan stages for this run
tetra run "..." --report run.md   # also write the run report to run.md

--plan is the easy path: it injects default plan + plan-review stages at the front of the pipeline (planner = your write agent, critic = your review agent) without touching your config. If the write agent is agy (it can't plan — it suppresses stdout off-TTY), the review agent plans instead (and if there is no stdout-capable agent to fall back to, --plan refuses with a clear error rather than injecting a broken plan loop). --no-plan strips any plan stages for a single run. --plan and --no-plan can't be combined, and --plan is a no-op if the pipeline already defines plan stages. For precise control (different planner skills, a dedicated planning agent, custom maxPlanIterations), declare the plan stages explicitly in config instead.

Configure

Copy tetra.config.example.json to tetra.config.json in your repo. Agents are named once and referenced by stages, so you can assign any model to any role:

{
  "agents": {
    "claude": { "command": "claude -p {{PROMPT_FILE}}" },
    "codex":  { "command": "codex exec {{PROMPT_FILE}}" }
  },
  "pipeline": [
    { "stage": "write",  "use": "claude" },
    { "stage": "gate",   "command": "npm test" },
    { "stage": "review", "use": "codex", "failPattern": "REQUEST.?CHANGES" },
    { "stage": "fix",    "use": "claude" }
  ]
}

Want the writer and reviewer the other way round? Swap the use values. The gate is just a shell command — npm test, pytest -q, cargo test, anything.

Skills (per-stage rubrics)

Each stage can fire skills — vetted markdown rubrics that get injected into that stage's prompt. tetra ships two first-party skill packs (code-review, testing-strategy) and you can register your own:

{
  "skills": {
    "code-review": { "path": "./skills/my-code-review.md" }
  },
  "pipeline": [
    { "stage": "write",  "use": "agy",    "skills": ["testing-strategy"] },
    { "stage": "review", "use": "codex",  "skills": ["code-review"] }
  ]
}

So the writer always sees your testing rubric, the reviewer always applies your review rubric, etc. tetra bundles its own skills and injects them — it does not reach into or auto-install another tool's private skill system, and it never bulk-installs third-party skills.

Plan stage (optional)

Add a plan (and optionally plan-review) stage at the start of the pipeline to think before writing:

{
  "maxPlanIterations": 2,
  "pipeline": [
    { "stage": "plan",        "use": "claude", "skills": ["testing-strategy"] },
    { "stage": "plan-review", "use": "codex",  "skills": ["code-review"] },
    { "stage": "write",       "use": "agy" },
    { "stage": "gate",        "command": "node test.js" },
    { "stage": "review",      "use": "codex" },
    { "stage": "fix",         "use": "agy" }
  ]
}
  • plan — the agent outputs an implementation plan as markdown (it edits nothing).
  • plan-review — an independent agent critiques the plan and ends with a single APPROVE / REQUEST-CHANGES line (same verdict detection as the code review).
  • On REQUEST-CHANGES, the planner revises with the critique in hand, bounded by maxPlanIterations (default 2, must be >= 0). If it's still not approved when iterations run out, tetra proceeds to write with the last plan plus a warning — it never aborts, because the hard gate still protects you.
  • A planner or critic that crashes (nonzero exit) aborts the whole run — a failed agent is never silently treated as approval.
  • The approved plan is injected into the write and fix prompts as a ## Plan section.

Both stages are entirely optional: a pipeline without them behaves exactly as before.

Agent choice: plan and plan-review consume the agent's stdout, so agy cannot serve those roles (it suppresses stdout when not attached to a TTY, like the reviewer role). Use claude or codex for plan/plan-review; agy is fine for write/fix.

Command tokens

| Token | Expands to | |---|---| | {{TASK}} | the task string you passed | | {{PROMPT_FILE}} | temp file with the full prompt for the agent | | {{DIFF_FILE}} | temp file with the working-tree diff vs baseBranch | | {{BASE}} | the base git ref |

Config keys

Beyond agents / skills / pipeline, the top-level keys are:

| Key | Default | Meaning | |---|---|---| | baseBranch | "main" | Base git ref the review diff is taken against. | | maxFixIterations | 3 | Max write→gate→review→fix rounds (must be >= 0). | | maxPlanIterations | 2 | Plan-revision rounds for the optional plan pre-stage (>= 0). | | reviewFailClosed | true | If the review stage exits cleanly but emits no verdict, abort rather than call the tree clean. Set false for the old warn-and-pass behavior. | | defaultTimeoutMs | 600000 | Kill any stage running longer than this (exit 124). 0 = no timeout. |

A stage can override the timeout with its own timeoutMs (also 0 = off, >= 0):

{ "stage": "gate", "command": "npm test", "timeoutMs": 120000 }

Timeout kill is best-effort (both platforms): tetra kills the whole process tree of a timed-out stage — on POSIX the child runs in its own process group (detached) and is signalled via SIGTERM, then SIGKILL after a 3s grace; on Windows it shells out to taskkill /T /F. This is best-effort: a process that re-parents or detaches itself can still outlive the timeout. Either way the stage resolves as 124 and the run stops.

Run report

Every non-dry run writes a markdown report to its temp workdir (tetra-report.md) and prints the absolute path. Pass --report <path> to also write a persistent copy. The report records the pipeline shape, a per-stage table (exit code, verdict, duration, ok), the fix iterations used, the terminal summary, and the final exit code — plus a footer restating what a clean run does and does not guarantee.

The report contains only stage metadata, never the agents' stdout/stderr, so it won't leak anything they printed, and it is never written into the target repo by default (it can't dirty your tree or be committed by accident).

Treat it like a log. The report does echo your task text verbatim, and the default copy lands in a temp dir. If you point --report somewhere, choose a path you won't commit (and don't put secrets in the task string).

Safety

  • Never auto-commits / pushes / opens PRsrequireHumanForPush is a hard, always-on boundary.
  • Bounded loopmaxFixIterations prevents infinite retries.
  • Treat repositories and their scripts as untrusted; review what your configured agents are allowed to run.

Status

v0.4.0. The core loop (write → gate → review → fix → stop), configurable agents, an optional plan / plan-review pre-stage, per-run --plan/--no-plan control, fail-closed review, per-stage timeouts, per-run reports, and a self-gating test suite are in place. Planned next: richer skill packs. See CHANGELOG.md.

License

MIT