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

agentspine

v0.2.0

Published

One-shot scaffolder for a shared agent setup across Claude Code, Codex, opencode, Mistral Vibe, and Cursor.

Readme

agentspine

npm ci node licence

Five coding agents, five config directories, one setup. agentspine writes your conventions, skills and blocking hooks once into .agents/, then wires Claude Code, Codex, opencode, Mistral Vibe and Cursor to read them.

npx agentspine
  • One copy of everything. Edit a skill once, every tool sees it.
  • Hooks that actually block. Shared policies, a per-tool adapter for each host's protocol, and doctor to prove the block landed rather than assuming it.
  • Opt-in skill packs. Multi-agent code review, TDD, diagnosis, planning: installed once, read by every tool.

Architecture and the reasoning behind each decision: docs/design/0001-architecture.md. What each tool actually supports, with sources and dates: docs/capability-matrix.md.

The problem

Every one of these tools wants its own directory. Maintain five and they drift: a skill written three times, a hook wired four ways, a convention updated in one file and stale in the rest.

agentspine writes one real copy of the content under .agents/ and points each tool at it.

.agents/
├── skills/          # SKILL.md — read natively by four of the five tools
├── agents/          # intersection-only frontmatter, symlinked where portable
├── hooks/
│   ├── policies/    # tool-agnostic shell: git safety, quality gate, naming
│   └── adapters/    # per-tool input parsing and exit-code mapping
├── scripts/         # worktree-create.sh, worktree-remove.sh
├── worktree.env     # install command and branch prefix for new worktrees
└── quality.toml     # per-path lint/typecheck commands, detection-seeded

.claude/skills -> ../.agents/skills
.cursor/skills -> ../.agents/skills
...

Two facts make this work, both verified in docs/capability-matrix.md: all five tools follow the Anthropic Agent Skills spec, and .agents/skills/ is already read natively by four of them — Codex, opencode, Mistral Vibe and Cursor. Only Claude Code needs the symlink.

Design in one table

| | | | :-- | :-- | | Scaffolder, not sync engine | Writes once. Templates bundled in the package, offline-safe. | | Emitted output is Node-free | Markdown and POSIX shell. A Go or Python repo gets no package.json. | | One content copy | .agents/ is canonical; symlinks reconcile, --no-symlink copies. | | Three normalised hook events | pre-tool:bash, post-edit, turn-end; policies written once. | | Stack-agnostic quality gate | Commands live in .agents/quality.toml, per-path array. | | Core plus opt-in packs | adapt-to-project always; --packs thinking,engineering,planning,review,ci-review. | | Honest tiers | What a tool cannot do is documented, not emulated. |

Support matrix

| Tool | Memory | Skills | Hooks | Blocking verified by doctor | | :-- | :-- | :-- | :-- | :-- | | Claude Code | CLAUDE.md -> AGENTS.md | symlink | settings.json | yes | | Codex | native | native | config.toml block | yes | | Cursor | native | native | hooks.json | yes | | Mistral Vibe | native | native | hooks.toml block | yes | | opencode | native | native | JS plugin shim | no — needs a live session |

Skills need no translation: all five follow the Anthropic Agent Skills spec. Hooks do — each host names its events differently, and Mistral Vibe denies by printing JSON rather than by exit code — so shared policies are written once and a per-tool adapter speaks each host's protocol.

Hooks read their policies, and the quality gate its commands, from .agents/, and Claude Code runs hooks outside its sandbox. So its settings.json also denies sandboxed commands writes to .agents/ (sandbox.filesystem.denyWrite), in effect once you turn the sandbox on. Codex write-protects .agents/ itself. Cursor has no setting that denies a write inside the workspace, and opencode and Mistral Vibe run commands without a sandbox: who can rewrite .agents/.

Skill packs

One skill ships with every scaffold: adapt-to-project. Run it once after init. It runs each inferred quality-gate command, activates the ones that pass once you confirm them, and writes a project map into AGENTS.md: the lint, typecheck and test commands, the trunk, the issue tracker, and where the glossary, ADRs and conventions live.

Everything else is opt-in and off by default:

npx agentspine --packs thinking,engineering

| Pack | Skills | | :-- | :-- | | thinking | grilling, grill-me, grill-with-docs, codebase-design, domain-modeling, improve-codebase-architecture, prototype, handoff, zoom-out, writing-for-agents, research, wait-what, to-questionnaire, caveman, retro | | engineering | tdd, diagnosing-bugs, wizard, find-dead-code | | planning | to-spec, to-tickets, wayfinder, implement, implement-spec; installs thinking, engineering and review too, since it invokes their skills | | review | review-changes (seven-area multi-agent review), address-review-comments, pr-description, and the eight reviewer subagents they dispatch | | ci-review | pr-ci-review, review-retro, and a GitHub Actions workflow that reviews every PR; installs review too. Claude Code only, and it needs setup: see below |

They install once into .agents/skills/, where three of the five tools find them with no further wiring. Each is written against no particular stack: where a skill needs project conventions, a command or a tracker, it reads the project map rather than assuming a layout. The planning skills publish to whatever issue tracker the session can reach, or write local markdown under docs/plans/ when there is none.

Several of these skills are meant to run only when you name them. Claude Code and Cursor honour that from frontmatter, and Codex gets the same effect from a file emitted beside each one. On opencode and Mistral Vibe the model can still fire them itself. See the matrix.

The review pack also installs .agents/agents/ and links it into opencode and Cursor. Claude Code gets a rendered copy in .claude/agents/ instead of a link, because three of the reviewers carry a key only it reads (effort: high) and opencode would forward that key to the model provider. Codex and Mistral Vibe have no project-scoped subagents, so nothing is emitted for them and review-changes degrades to dispatching the reviewer briefs inline — the review shrinks in mechanism, never silently to nothing.

Prerequisites: Node >= 20 to run the scaffolder, and jq, awk, sed and bash >= 3.2 on any machine where the hooks run.

Reviewing every pull request

--packs ci-review emits .github/workflows/claude-code-review.yml: a deterministic preflight decides full versus incremental, Claude Code reviews the PR through the review pack's seven reviewers, and a poster writes the verdict. The model has no write access to the PR. It emits a structured record; the poster renders it, anchors each important finding to a line in the diff, and pins a claude-review commit status. A complete run that dies, or that ends before every reviewer it spawned has reported, still posts "not reviewed" or "review incomplete" and fails the check, because green silence reads exactly like a clean review.

The model's job holds a read-only token, and its tools are locked by managed settings that no file in the PR can widen: read-only gh and git verbs, no file edits, and a Bash sandbox that writes only to the checkout and Claude Code's temp directory and reaches no host but GitHub's API. Credentials are scrubbed from the shell it drives, except the job's read-only GitHub token, which gh needs. A verb the lock refuses lands in the run's record as a denied call rather than stalling the run.

The workflow's deterministic steps are agentspine review preflight|schema|post|metrics, installed from npm at the version that scaffolded the file, so the repository gets a workflow and no toolchain of its own. The workflow, the pr-ci-review skill and that tooling share a contract, and re-running with --packs ci-review updates the skill but never rewrites an existing workflow. To upgrade all three, delete the workflow and commit that, re-run npx agentspine --yes --packs ci-review,<every other pack you use>, then re-apply any edits you had made to the workflow.

The anthropics/claude-code-action pin also fixes which Claude Code runs the review, since the action bundles it; the capability matrix records which version. To follow Claude Code releases, let Dependabot bump the workflow's actions. It changes the action pins only, never the tooling version, and its pull requests get no review, because its author is none of the associations below:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: daily

Two setup steps, both in the comment at the top of the emitted workflow: add the CLAUDE_CODE_OAUTH_TOKEN secret, and create the ci/review-metrics orphan branch that stores each run's record for review-retro to mine.

Only the repository's owner, members of its organisation and invited collaborators can start a review, whether by opening a PR or by commenting @claude review. GitHub records that association without a permission level, so a read-only collaborator counts. A push to a PR only triggers a review when the PR's author pushed it.

Asking by comment. @claude review on a PR runs the review on demand, and the words right after it on the same line, in any order, shape it. The first word that is not one of them ends the request, so @claude review, thanks is a plain review.

| Comment | Review | | :------ | :----- | | @claude review | the changes since the last complete review; the whole PR when there is none, when it reviewed this same head, or after a rebase or a merge from the base | | @claude review full | the whole PR diff | | @claude review quick | correctness, plus security when a trust boundary is touched, one instance each | | @claude review deep | every area, gate or not (spec still needs an issue the PR closes); one more instance of each size-scaled area (up to 3); maintainability on Opus; the orchestrator at high effort | | @claude review security docs | only the named areas (correctness, security, context, conventions, maintainability, docs), plus spec when the PR closes an issue |

A quick or area-restricted review is partial: the next review diffs from the last complete one, so what it skipped is covered then; comment @claude review for a complete pass now. The review adds its verdict to the comment as a reaction when it ends: 🚀 (no important findings), 👍 (no important findings from a partial review, which leaves the claude-review status to the last complete one, and on a head none has covered leaves it unset), 👎 (important findings posted), or 😕 (not reviewed: the run failed or was cancelled). A partial review sets no status even when it fails; its 😕 and the failed post-review job show it. A comment on a PR that closed before the review started gets no reaction, and neither does a request displaced from the queue by a later push, which never starts; comment again. If the Claude GitHub app is installed it also reacts 👀 to any @claude mention on its own.

GitHub and Claude Code only, because it runs through anthropics/claude-code-action. On any other host, review-changes reviews the same seven areas locally.

Install safety

Refuses a dirty git tree without --force — git is the backup. Existing markdown is edited only between <!-- agentspine:start --> markers. JSON config is deep-merged, never clobbered. TOML gets a text-spliced managed block so comments survive. Re-runs are idempotent.

Usage

agentspine [init]      Scaffold .agents/ and wire each detected tool
agentspine doctor      Probe the wiring and verify hooks actually block
agentspine review <step>   CI review tooling, run by the emitted workflow

--tools <list>     claude-code, opencode, codex, mistral-vibe, cursor (default: detected)
--packs <list>     thinking, engineering, planning, review, ci-review (default: none)
--dir <path>       Target repository (default: cwd)
--no-symlink       Copy shared content instead of symlinking it
--skip-hooks       Scaffold content but wire no hooks
--dry-run          Print the plan, write nothing
--check            Exit non-zero if the tree differs from what init would emit
--yes              Apply without confirming
--json             Machine-readable output
--force            Proceed even though the git tree is dirty

Every prompt has a flag, so an interactive run is always reproducible as one command — and an agent driving the CLI never hits a prompt that hangs. Without a TTY and without --yes, init prints its plan and exits non-zero rather than guessing.

Verify it actually works

npx agentspine doctor

Fires a probe hook against each locally installed tool and checks the block landed. Hooks that silently fail to block are the main risk in a five-tool port; doctor is how you catch them, and --json makes its output worth attaching to a bug report.

Contributing

.agents/ in this repository symlinks into templates/, so editing a skill here edits the shipped skill. CONTRIBUTING.md says which path is canonical and what CI will hold you to. Bug reports are welcome.

Licence

MIT