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

@agentspec/claude-plugin

v0.2.0

Published

AgentSpec plugin for Claude Code — live spec↔runtime bridge, policy enforcement, and status line, with no fork of Claude Code

Downloads

145

Readme

@agentspec/claude-plugin

A Claude Code plugin that makes a Claude Code session live-observed and policy-governed by AgentSpec — with no fork of Claude Code. Your agent.yaml becomes the source of truth; the plugin rides Claude Code's documented extension surface (hooks + MCP + statusline).

What it does

| Capability | Mechanism | |---|---| | Live spec↔runtime gap | A per-user bridge daemon serves GET /agentspec/health. The AgentSpec sidecar control-plane polls it and flips /gap · /explore · /health/ready to live mode (source: agent-sdk) — the exact endpoint the sidecar expects from an SDK-integrated agent. | | Policy enforcement (opt-in) | With AGENTSPEC_ENFORCE set, a PreToolUse hook denies Task spawns whose subagent_type isn't in spec.subagents, denies tools not in spec.tools, and asks-for-approval on destructiveHint tools when spec.humanInTheLoop requires it. Off by default — see Enforcement. | | Live tool/health status | PreToolUse/PostToolUse/SubagentStop hooks feed the bridge, which synthesizes the tool health category from the real event stream. | | Status line | agentspec-statusline renders ● healthy · gap 3 · tools 11/12 from cached daemon data. | | Self-query | Bundles the AgentSpec MCP server so Claude can call agentspec_gap/agentspec_audit in-session. |

How it works

claude (closed binary)
  │  hooks (SessionStart / PreToolUse / PostToolUse / SubagentStop / SessionEnd)
  ▼
agentspec-bridge daemon (127.0.0.1, per-user, lockfile-guarded)
  ├─ :8000  GET /agentspec/health   ← the sidecar polls this (the "hinge")
  │         POST /events            ← hook observation sink
  │         POST /decide            ← enforcement decision (from agent.yaml)
  └─ :4001  control-plane           → /gap /explore /health/ready (live)

The bridge sets UPSTREAM_URL=http://127.0.0.1:8000 before importing the sidecar control-plane (@agentspec/sidecar/embed), so the control-plane's probeAgent() targets the bridge and serves live data. Claude Code is never introspected — the bridge reconstructs runtime state from config + the hook event stream.

Quick start

# 1. Derive agent.yaml from your .claude/ config (deterministic, no LLM):
agentspec scan --dir . --profile claude-code

# 2. Install + enable the plugin.
#    Published:  npm i -g @agentspec/claude-plugin  &&  /plugin marketplace add agents-oss/agentspec  &&  /plugin install agentspec
#    Local/dev:  pnpm -F @agentspec/claude-plugin build && (cd packages/claude-plugin && npm link)
#                /plugin marketplace add /abs/path/to/agentspec  &&  /plugin install agentspec
#    (or commit .claude/settings.json → { "enabledPlugins": { "agentspec": true }, "statusLine": { "type": "command", "command": "agentspec-statusline" } })

# 3. Start a session. SessionStart backgrounds the bridge; the sidecar shows live state:
curl 127.0.0.1:4001/gap        # → { "source": "agent-sdk", ... }

Distribution status: the repo ships .claude-plugin/marketplace.json, so the local/dev route works today. npm i -g @agentspec/claude-plugin requires the first npm publish (tracked in task.md).

The daemon is a per-user background process (like a language server): the SessionStart hook does an idempotent ensure-running via a lockfile under .claude/agentspec/, it binds loopback only, and it is left running across sessions.

Enforcement (opt-in)

The plugin is observe-only by default — it records events, serves health, and drives the status line, but never blocks a tool call. Turn gates on with AGENTSPEC_ENFORCE (a comma list) in your environment or .claude/settings.json env:

| AGENTSPEC_ENFORCE | Effect | |---|---| | (unset) | Observe only. Every tool call is allowed. | | subagents | Deny Task spawns not declared in spec.subagents. | | tools | Deny tools not in spec.tools; ask-for-approval on destructiveHint tools when spec.humanInTheLoop requires it. | | tools,subagents | Both gates. |

Why opt-in: scan --profile claude-code builds spec.tools from .claude/settings.json permissions.allow, which is Claude Code's auto-approve list — not an exhaustive capability list. Enforcing it by default would deny tools the session would normally permit. Likewise, unspecified spec.subagents (the scan default when there is no .claude/agents/) means unrestricted; only an explicit spec.subagents: [] means "deny all delegation."

Compose into an existing status line

Claude Code allows only one statusLine command, so to keep your existing bar (e.g. ccstatusline, claude-hud) and show AgentSpec, run agentspec-statusline with --segment: it emits only AgentSpec ● healthy · gap N · tools x/y (dropping model/cost, which the host already shows) and prints nothing when the daemon is down — a natural on/off. Wrap it with your existing status line:

#!/usr/bin/env bash
input="$(cat)"
host="$(printf '%s' "$input" | your-existing-statusline 2>/dev/null || true)"
seg="$(printf '%s'  "$input" | agentspec-statusline --segment 2>/dev/null || true)"
[ -n "$host" ] && printf '%s' "$host"
[ -n "$host" ] && [ -n "$seg" ] && printf '\n'
[ -n "$seg" ]  && printf '%s' "$seg"

Point statusLine at that wrapper. Either half can be absent and the bar still works.

Fidelity note

Infra checks (env/model/mcp/memory/service) are real reachability probes from the SDK. The tool category is reconstructed from the hook stream: a tool that ran is pass/fail by its outcome; a declared tool not yet invoked this session is skip (no behavioral evidence yet — the same blind spot the in-process Reporter has for a registered-but-uncalled tool).

Layout

.claude-plugin/plugin.json   plugin manifest (references hooks + mcp)
hooks/hooks.json + *.mjs      lifecycle hooks (dependency-free, fail-open)
.mcp.json                     registers @agentspec/mcp for the session
src/policy.ts                 enforcement decision (pure, tested)
src/event-log.ts              hook event → tool observations (pure, tested)
src/health-overlay.ts         synthesize the `tool` category (pure, tested)
src/bridge.ts                 the daemon (bin: agentspec-bridge)
src/statusline.ts             the status line (bin: agentspec-statusline)