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

opencode-gbuild

v0.6.1

Published

OpenCode plugin for gbuild — graph-native task planning and execution with concurrent fan-out, per-node review, and durable checkpoints.

Downloads

555

Readme

gbuild — Claude Code + OpenCode plugin

Graph-native task planning and execution: plan a feature as a real dependency graph, then run it with actual concurrent fan-out, a dedicated review pass on every node, and durable per-node checkpoints.

The workflow

Plan in conversation first (your agent's normal plan mode), then hand that plan to gbuild:

  1. /gbuild:plan <the plan> — chart it as a dependency graph
  2. /gbuild:run <slug> — run it, once; it iterates waves until the graph completes (re-invoke only to resume an interrupted run)
  3. /gbuild:review <slug> — audit the accumulated branch
  4. Issues? /gbuild:plan <slug> --add "<fix>", then /gbuild:run again. Clean? /gbuild:pr <slug>

(OpenCode: /gbuild-plan, /gbuild-run, … — same loop.)

Inspired by the graph-engineering thread at x.com/0xwhrrari/status/2086784668003598356: sequence isn't dependency, every node needs an explicit contract, edges carry data not just order, and verification never grades itself.

Install

gbuild needs the cypherlite CLI on PATH — see Runtime.

Claude Code

From the marketplace:

claude plugin marketplace add oskarhane/oskars.ai
claude plugin install [email protected]

For local development:

claude --plugin-dir ./plugins/gbuild

OpenCode

The same directory is also an OpenCode (V2) plugin, published to npm as opencode-gbuild — index.ts registers the five skills and five slash commands (/gbuild-plan, /gbuild-run, /gbuild-status, /gbuild-review, /gbuild-pr) from the same markdown the Claude plugin uses.

opencode plugin add opencode-gbuild

opencode plugin update opencode-gbuild moves to the latest published version. For local development, point any opencode.json(c) at a checkout instead:

{
  "plugins": ["/path/to/oskars.ai/plugins/gbuild"]
}

Releasing

The npm package is published from this directory:

  1. Bump version in package.json — keep .claude-plugin/plugin.json's version in sync.
  2. npm publish (2FA on the account; contents are whitelisted via files + .npmignore).
  3. Users pick it up with opencode plugin update opencode-gbuild.

One translation note: OpenCode plugins can't register agents, so where the Claude plugin spawns its bundled gbuild-reviewer/gbuild-auditor agents, the OpenCode skills dispatch the built-in general subagent with the same agents/gbuild-*.md text inlined as its brief. The review is still a fresh, isolated agent — never the implementer.

Usage

Claude Code:

/gbuild:plan add OAuth login with GitHub
/gbuild:run add-oauth-login-with-github
/gbuild:status add-oauth-login-with-github
/gbuild:review add-oauth-login-with-github
/gbuild:pr add-oauth-login-with-github

OpenCode (same order, kebab-case names):

/gbuild-plan add OAuth login with GitHub
/gbuild-run add-oauth-login-with-github
/gbuild-status add-oauth-login-with-github
/gbuild-review add-oauth-login-with-github
/gbuild-pr add-oauth-login-with-github
  • plan charts a feature into a CypherLite graph store at .gbuild/<feature>/db/ — Feature, Acceptance, and GbuildNode nodes, each node's contract as INPUT/OUTPUT Field nodes, and FROM edges carrying data from one node's output to the next node's input. Every dependency edge passes the cut test — and because data flow is explicit, the validator checks it; every node has mandatory concrete acceptance criteria. Written and validated entirely in Cypher.
  • run dispatches every node in the current ready wave concurrently — not one at a time — reviews each node's output with a dedicated gbuild-reviewer subagent before recording it complete, and applies the node's declared failure policy on a review failure. Re-invoking after an interruption resumes only the remaining frontier.
  • status reports the graph — frontier, blocked, in-flight, completed, each node's review verdict, and evidence of what actually ran concurrently vs. serially.
  • review audits the finished branch as a whole in a gbuild-auditor subagent — abstraction quality, file size, spaghetti growth, and the cross-node duplication that per-node review can't see (two nodes, two contexts, same sub-problem solved twice). Blocking findings go back into the graph as a plan --add requirement. Ported from hone-ai's review.
  • pr pushes the feature branch, opens a PR, then watches CI. A red check becomes a new requirement on the graph (plan --add) and gets run like any other node, rather than patched around — looping until the checks are green or the round cap is hit. Ported from hone-ai's pr.

Why a graph instead of a task list

A flat ordered list encodes the order you thought of things in, not what actually depends on what. Two independent nodes end up serialized for no reason, and nothing catches it. gbuild's plan states real edges; run acts on them — independent nodes in the same wave dispatch together, a join waits for every incoming edge, and a controlled cycle gets a hard round cap instead of an open-ended loop.

Node statuses

A node's status is its status property in the store, next to its outputs and its review history (Review nodes, one per attempt). There are five, and each exists to answer a different question run has to ask on every invocation:

| status | means | why it exists | | ------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | pending | not started | Every node is charted pending. Interrupted work goes back to pending when the next run resets it, so nothing is left half-declared. | | in_progress | dispatched, no verdict yet | Distinguishes "running right now" from "never started", so a resumed run doesn't double-dispatch a node whose agent was killed mid-flight. | | completed | reviewed and passed | The only status that satisfies a dependent's edge on merit. The write refuses without a passing Review and a value for every output — an implementing agent cannot mark its own success. | | cancelled | deliberately abandoned, dependents may proceed | The skip failure policy's landing spot. Counts as satisfied, so abandoning an optional node doesn't permanently wedge everything downstream. | | failed | escalated, dependents held | Records that the node is genuinely stuck and needs a human. Does not satisfy dependents — they stay blocked rather than building on a broken foundation. |

The distinction that does the most work is cancelled vs failed. Both mean "this node isn't going to produce its output," but they answer the dependents' question oppositely: cancelled says proceed without me, failed says stop and wait. Collapsing them into one "didn't work" status would force run to guess which one a given failure meant.

Everything else the tooling reports — frontier, blocked, in_flight, waves — is derived from these five by cypher/status.cypher, never stored. Nothing can drift out of sync with itself, and the frontier is a query result rather than a judgement call:

frontier  = pending ∧ every dependency completed-or-cancelled
blocked   = pending ∧ some dependency not completed-or-cancelled
in_flight = in_progress

When a node needs you

Subagents are forked, so they cannot talk to you directly — a subagent's final message is a tool result, not chat output. Anything it finds that needs a human decision therefore travels a specific path: the subagent reports it, run records it, and run's report surfaces it. Nothing gets silently resolved by the agent that found it, and nothing gets routed around.

Three things can trigger it:

  • A node exhausts its failure policy. escalate sets the node failed, stops dispatching its dependents (siblings elsewhere in the graph keep going), and surfaces it as needing a decision. repair escalates the same way once its 2 attempts are spent; retry and fallback are capped at 2 attempts too, so no policy can loop unbounded. See reference/failure-policies.md.
  • A node's work invalidates an already-completed one. gbuild-reviewer labels this CONTRADICTS <slug> and stops. It is explicitly not the reviewer's job to re-decide an upstream node's accepted output, so this always reaches you rather than being reconciled in place. When the contradiction undermines the graph's premise rather than one node, the stop policy halts the entire run instead of just one branch.
  • The end-of-branch audit finds something blocking. gbuild-auditor returns findings to /gbuild:review, which relays them to chat verbatim — a subagent's audit is worthless if the caller paraphrases it. Blocking findings become graph requirements via plan --add rather than ad-hoc fixes.

So a run stops early in one of two shapes: an empty frontier with nodes still incomplete (something escalated — /gbuild:status names it), or a hard halt (stop). Both report what's blocking and what decision is wanted; neither guesses.

Runtime

gbuild requires the CypherLite CLI, 0.7.0 or newer:

curl -sSfL https://neo4j-labs.github.io/cypherlite/install.sh | bash

Every skill reads and writes the graph with cypherlite and nothing else — there is no Python and no direct JSON editing. The plugin ships the queries as .cypher files; skills pipe them into the store:

cypherlite .gbuild/<feature>/db --mode jsonl < plugins/gbuild/cypher/validate.cypher   # format gate: no output = valid
cypherlite .gbuild/<feature>/db --mode jsonl < plugins/gbuild/cypher/progress.cypher   # one row per wave: counts + open nodes
cypherlite .gbuild/<feature>/db --mode jsonl "MATCH (n:GbuildNode {status: 'failed'}) RETURN n.slug"   # anything else

Reads are deliberately narrow so a run doesn't pay for the whole graph on every step: run claims a wave (dispatch.cypher returns only that wave's nodes, with their inputs resolved) and records it (record.cypher, one batched call) — two store calls per wave, regardless of graph size. The full per-node view (status.cypher) is only for the human-facing /gbuild:status.

Required properties and their types are engine constraints, so an invalid write never lands; the rest of the contract (enums, edge shapes, coverage, acyclicity, the cut test) is validate.cypher. CypherLite locks a store while a process has it open, so only the main-context skill touches it, one command at a time — subagents get their inputs in their prompt and report back. reference/cypher.md has the full operating rules.

Tests (repo-root npm test) run the Cypher layer against the real binary: cypher.test.ts drives the worked example through a full run, checks every validator rule and write guard, and holds a token budget — a 40-node run must take two store calls per wave and stay under a fixed number of bytes read.

Layout

plugins/gbuild/
  agents/gbuild-reviewer.md   # per-node review, ported from hone-ai's reviewer, never self-review
  agents/gbuild-auditor.md    # end-of-branch maintainability audit, ported from hone-ai's auditor
  reference/                  # graph-format.md (normative model), cypher.md (how to talk to the store), queries.md (ad-hoc recipes); shapes/failure-policies/cost-model/checklist inform plan
  cypher/                     # schema, validate, progress/attention/status/node/feature reads, and run's dispatch/record/set-status
  templates/example.cypher    # a worked 4-node diamond, written the way plan writes a feature
  skills/{plan,run,status,review,pr}/
  index.ts                    # OpenCode plugin entry: registers the skills + /gbuild-* commands, translating paths/names
  package.json                # OpenCode plugin manifest (npm package "opencode-gbuild")
  cypher.test.ts              # node --test contract tests for the Cypher layer (repo-root `npm test`)
  smoke.test.ts               # node --test smoke test for the OpenCode translation

State lives outside the plugin, in the project: one CypherLite store per feature at .gbuild/<feature>/db/. It holds the plan, every node's status and output values, and the full review history. Only db/graph.json (CypherLite's JSON snapshot, kept current by every write) and the store's own .gitignore are committed.