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

@bacnh85/pi-classifier

v0.2.3

Published

System One decision models (TypeSafe Jev) for Pi — classify tool for typed probabilistic answers, a Jev-gated permission auto-approve hook for shell commands (default on, static risky list first, never auto-denies, fails safe, observe mode), and a /classi

Readme

pi-classifier

System One decision models (TypeSafe Jev) for Pi. Jev returns typed answers with calibrated probabilities — never text — so this extension surfaces it as a tool, not a model.

Two pieces:

  1. classify tool — the agent sends {state, questions}, gets typed answers: noul (P(yes)), choice (option + probabilities + confidence), score (weighted position + confidence). Use for routing, verification, and gating decisions.
  2. Permission auto-approve hook (on by default; explicit opt-out wins) — shell commands Jev is confident are reversible and serve the task run without prompting; set permission.enabled: false to turn it off. The OpenRouter cookbook pattern.

Install

pi install @bacnh85/pi-classifier

Configure

Run /classifier-config in Pi (TUI): an arrow-key panel for the baseUrl, the decision model — with completions pulled live from the router's GET /v1/systemone/models (yardmaster) — and the permission block below. /classifier-config show prints the config plus discovered models in any mode. Everything is still plain JSON in global settings (~/.pi/agent/settings.json) — never repo scope, because the endpoint receives your API key as Bearer:

{
  "classifier": {
    "baseUrl": "http://localhost:8787/v1",  // yardmaster (or https://openrouter.ai/api)
    "model": "jev/jev-latest",              // id the upstream knows: jev/jev-latest, or/typesafe/jev-1.13, jev-latest…
    "permission": {                          // default ON/enforce — auto-approves reversible,
      "enabled": true,                       // task-serving commands; set enabled:false to opt out
      "mode": "enforce",                     // "observe" logs decisions without acting
      "threshold": 0.9                       // both nouls must clear it
    },
    "planGate": {                            // opt-in — default OFF; used by pi-plan
      "enabled": true,
      "mode": "observe",                     // start here; "enforce" to act
      "threshold": 0.9                       // independent of permission.threshold
    }
  }
}

API key: CLASSIFIER_API_KEY env, or the classifier credential in ~/.pi/agent/auth.json:

{ "classifier": { "key": "ar-..." } }

Through yardmaster: point baseUrl at the router's /v1, set model to the prefixed id (jev/jev-latest for the TypeSafe-direct provider, or/typesafe/jev-1.13 via OpenRouter) and use your router key. Pricing: $0.042/Mtok input, output free. The panel's model completions come from yardmaster's decision-model listing (GET /v1/systemone/models); routers without it (OpenRouter direct, TypeSafe direct) just fall back to manual entry.

The safety envelope

Non-negotiables, in order:

  1. Static risky list first. rm -rf, sudo, force-push/hard-reset, pipe-to-shell, publish/deploy CLIs, credential paths → never sent to Jev, never auto-approved. The list is deliberately short and shallow.
  2. Never auto-denies. Any outcome other than a confident yes (low score, timeout, 4xx/5xx, malformed answer, missing key, no UI) falls back to the normal prompt. Worst case is one extra prompt, never an unwanted command.
  3. Observe mode (opt-in). Enforce is the default posture; set permission.mode: "observe" to log the decision it would have made to ~/.pi/agent/classifier.log without acting. Run it for a few days, read the log, then flip mode: "enforce".
  4. One audit line per decision — command, scores, elapsed ms, model.
  5. Compound commands are split on operators before the risky check; a separator hidden inside quotes can only add a prompt, never hide a command.

Host deny rules always win: pi-classifier only ever allows; it cannot override an explicit deny from pi-permission or the harness.

Plan gate (pi-plan integration)

planGate powers pi-plan's plan-mode confirm tier: when a bash command lands in the "confirm" tier during plan mode, pi-plan asks Jev "is this read-only and needed for planning?" and auto-allows only a confident yes. Jev may only reduce prompts — it can never unlock a write (the outer gate blocks those before the gate runs), never deny (every non-confident outcome falls through to the normal prompt), and every verdict is audited to classifier.log with source: "plan-gate".

Workflow: set classifier.planGate.enabled: true → observe is the default (logs would-be allows, still prompts) → review the log → flip mode: "enforce". Risky-list commands (rm -rf, pipe-to-shell, …) never reach Jev. The library export planGateVerdict(opts, command, cwd, task) is what pi-plan calls; it is exported for tests and library hosts.

Verification cache

Verdicts are cached (LRU, 100 entries) — permission-hook keys are command\0cwd\0task (task truncated to 200 chars, since 0.2.1), plan-gate keys are plan\0command\0cwd (task excluded — plan commands are generic) — so repeated bun test doesn't re-pay Jev or add latency every time.

Using the classify tool directly

Ask the agent: "Classify this ticket: is_urgent noul, team choice (billing/technical/account), severity score 0-3" — it composes the questions and returns the typed answers. Questions run in parallel inside one request; probabilities jitter ±0.08 between identical calls, so thresholds are policy — tune them on your own traffic.

Coexistence with pi-permission

Both observe tool_call. pi-classifier's silent-allow and pi-permission's ask compose by load order: whichever extension returns first wins. If you run both, the intended stack is pi-permission deny rules (they win over everything) + pi-classifier enforce for the confident middle. Test the combination before trusting it.