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

@shopdevx/breakerbox

v0.2.0

Published

Hard spend caps and a kill-switch for the non-LLM actions your AI coding agent takes.

Readme

breakerbox

npm version npm downloads CI license: MIT node ≥18.17 dependencies: 0

Hard spend caps and a kill-switch for the non-LLM actions your AI agent takes.

Your LLM gateway meters tokens. It does not see the aws ec2 run-instances your agent just ran.

breakerbox sits in Claude Code's PreToolUse hook, reads every Bash command before it executes, estimates what it will cost, and blocks it if that breaches a cap you set. No proxy, no daemon, no credentials, no account.

breakerbox blocks an 8× p4d.24xlarge EC2 launch before it runs — DENY, estimated $6292.34, nothing billed

Live site & demo → · How it works

$ breakerbox check "aws ec2 run-instances --instance-type p4d.24xlarge --count 8"

DENY  estimated $6292.34

Billable actions
  EC2 p4d.24xlarge x8  $6292.34
  aws.ec2.run-instances · $32.7726/hr · qty 8 · high confidence

Why
  - Single action estimated at $6292.34, over the per-action cap of $20.00.
  - Session spend would reach $6292.34, over the session cap of $50.00.

Why this exists

The well-documented agent-runaway incidents share a shape: the money was not burned on tokens. An agent looped, spun up EC2 instances and CloudFormation stacks on its own, and left its operator with a ~$6,500 bill. Every dollar of that was invisible to an LLM gateway, because not one of those calls was a model call.

Existing tools cover the model call. LiteLLM, Portkey, Bifrost and friends do session budgets, iteration caps and alert→throttle→kill on token spend, and they do it well. Cloud-native budgets (AWS Budgets, billing alarms) are reactive — they tell you hours later, once the money is gone.

Nothing was watching the gap in between: the shell command, the cloud SDK call, the terraform apply. That gap is what breakerbox covers.

breakerbox is not a LiteLLM competitor. Run both. LiteLLM caps what your agent spends on tokens; breakerbox caps what it spends on everything else.


Install

npm i -g @shopdevx/breakerbox
breakerbox init

init writes breakerbox.config.json, creates .breakerbox/, and registers two hooks in .claude/settings.json. Restart Claude Code and it's live.

breakerbox doctor    # verifies the whole chain, including a real block

doctor doesn't just check that files exist — it feeds a synthetic 8×p4d.24xlarge launch through the actually-registered hook command and asserts it comes back denied.

The hook runs on every Bash tool call, so startup cost is paid constantly. breakerbox has zero runtime dependencies and no build step for this reason — a hook evaluation is ~48ms median on a warm machine, essentially all of it Node process start. Routing that through npx each time would multiply it, and npm prunes the _npx cache out from under the registered path. init warns you if it detects it's running from there.


What it catches

| Shape | Example | Result | |---|---|---| | Oversized resource | aws ec2 run-instances --instance-type p4d.24xlarge --count 8 | deny — $6,292 > per-action cap | | Runaway loop | while true; do aws ec2 run-instances ...; done | deny — billable action in an unbounded loop | | Accumulated drift | 30 small launches across one session | deny once the session cap is reached | | Burst velocity | 12 billable actions in 60s | deny — that's a loop, not deliberate work | | Opaque blast radius | terraform apply -auto-approve | ask — cost lives in files, not the command | | Unattended opaque action | same, in bypassPermissions mode | deny — an "ask" nobody can answer isn't a guardrail | | Hidden in substitution | ID=$(aws ec2 run-instances ...) | deny — substitutions are parsed too | | Ordinary work | npm test && git commit -am wip | allow, silently |

Covered today: AWS (EC2, RDS, EKS, SageMaker, Redshift, ElastiCache, OpenSearch, MSK, CloudFormation, ASG, NAT/ALB/TGW, IAM/Organizations), GCP (Compute, GKE, Cloud SQL, Dataproc, Cloud Run, Deployment Manager), Azure (VM, VMSS, AKS, managed DB, ARM/Bicep), IaC (Terraform, OpenTofu, Pulumi, CDK, SAM, Serverless, Helm), plus metered HTTP APIs and rented-GPU CLIs.


How the cost model works

Two numbers per action: oneTime and hourly.

This matters more than it sounds. Launching an EC2 instance costs $0 at the moment you launch it — the bill arrives over the following hours. A guardrail that only counted immediate cost would never fire on the exact command that caused the incident. So breakerbox projects hourly over a horizon (default 24h) and charges that against your cap up front:

charged = (oneTime + hourly × horizonHours) × quantity × loopIterations

Unknown instance types resolve to a deliberately pessimistic rate and report low confidence — a guardrail that guesses low is worse than no guardrail. GPU families are detected by name and default higher still.

For terraform apply and cloudformation create-stack, breakerbox refuses to invent a number at all. The cost is defined by files it isn't reading, so it reports unknownBlastRadius and escalates instead of pretending to price it.


Spend preflight for Terraform

terraform apply is opaque at the command line — which is why the live hook returns unknownBlastRadius and asks. But once you render the plan to JSON, the priced diff is right there. breakerbox plan reads it and gives the plan the same DENY/ASK treatment a command gets:

terraform plan -out tfplan
terraform show -json tfplan > plan.json
breakerbox plan plan.json
DENY  estimated $1197.32

Priced resources
  aws_instance.trainer      $786.54   tf.aws_instance · $32.7726/hr · p4d.24xlarge
  aws_eks_node_group.gpu    $408.38   tf.aws_eks_node_group · $5.6720/hr · qty 3 · g5.12xlarge
  aws_eks_cluster.main        $2.40   tf.aws_eks_cluster · $0.1000/hr

Coverage
  Priced 3 of 4 created resource(s); 1 unpriced (no rule yet).

Only resources whose plan action includes create are billed — that covers fresh creates and replaces; updates and deletes are left alone. It reuses the same price catalog and 24h horizon as the command engine, and reports how many resources it couldn't price rather than guessing. This is an opt-in step: it is deliberately not wired into the hook, so the hot path stays pure string-parsing with no subprocess and no Terraform dependency. Run it in CI before apply, or by hand.


Ledger: decide on Pre, charge on Post

PreToolUse writes a pending intent. PostToolUse promotes it to a committed charge. Nothing counts against your caps until the tool has actually run.

Without this split, a command you denied — or the user cancelled at the permission prompt — would still eat the session cap, and a few blocked commands could lock out an agent that never spent a cent.


Configuration

breakerbox.config.json in your project root:

{
  "caps": {
    "action":  20,    // any single command line
    "session": 50,    // one agent session
    "daily":   200    // per UTC day
  },
  "rateLimit": { "actions": 12, "windowSeconds": 60 },

  "horizonHours": 24,             // hours of runtime charged up front
  "unboundedLoopAssumption": 25,  // iterations assumed for `while true`

  "onBreach": "deny",                  // deny | ask
  "onUnknownBlastRadius": "ask",       // terraform apply, CFN stacks
  "onUnboundedLoop": "deny",
  "unattendedEscalation": "deny",      // ask -> this, in bypassPermissions
  "unmatched": "allow",                // commands with no rule

  "allow": ["aws s3 ls"],              // substring or /regex/
  "deny":  ["/aws\\s+organizations/"],
  "ignoreRules": ["aws.s3.transfer"],
  "priceOverrides": { "aws.ec2.run-instances": { "hourly": 0.2 } },

  "failMode": "open"                   // open | closed
}

Env overrides: BREAKERBOX_SESSION_CAP, BREAKERBOX_DAILY_CAP, BREAKERBOX_DISABLE=1, BREAKERBOX_CONFIG, BREAKERBOX_DIR.

Commands

breakerbox check "<command>"   # dry-run the policy engine, explain the verdict
breakerbox plan <plan.json>    # spend preflight for a Terraform plan (terraform show -json)
breakerbox status              # spend against every cap, with meters
breakerbox log -n 20           # recent committed actions
breakerbox reset --session     # clear a session's spend (--day, --all)
breakerbox doctor              # verify the install end to end

What this cannot see

Read this part. A guardrail that oversells itself is worse than none, because you stop watching.

  • It is a spend guardrail, not a security sandbox. It reads the command line. eval "$(echo YXdzIGVjMi4uLg== | base64 -d)", a cost-incurring action inside a shell script it invokes, or a Python SDK call inside python deploy.py are all invisible to it. It defends against runaway agents, not against an adversary deliberately evading it.
  • Prices are approximate list prices (src/catalog/prices.js, stamped 2026-08). No region adjustment, no reserved instances, no savings plans, no spot, no committed-use discounts, no data transfer or storage. They exist to make caps trip at roughly the right time, not to reconcile your invoice.
  • Only Bash is inspected today. MCP tool calls and other tools pass through.
  • failMode defaults to open. If breakerbox itself errors, the command proceeds and the error lands in .breakerbox/errors.log. A bug in this tool should not brick your agent. Set "failMode": "closed" to invert that.
  • allow is expressed as silence. breakerbox never emits permissionDecision: "allow", because that would bypass Claude Code's own permission checks and auto-approve commands it merely had no opinion about. It only ever speaks up to deny or ask.
  • Hourly resources are charged once, at launch. breakerbox does not track whether you later terminated the instance. The 24h horizon is a heuristic for "is this worth stopping", not an accrual system.

Belt and suspenders

breakerbox is a backstop, not the only line of defence. The strongest setup pairs it with least privilege: during phases that don't need cloud access, strip raw Bash from Claude's tool list (--allowedTools) so no cloud command can be issued at all. If the guard never has to evaluate a command, it can never fail open on one. Use breakerbox for the phases where the agent legitimately needs a terminal.

The decision log

When someone wakes up to a surprising bill, three outcomes look identical from the outside: the guard ran and priced it under the cap, the guard ran and crashed into fail-open, or the guard was never invoked at all. Tests prove the code does the right thing in each case — they don't tell you which case you were in on the day.

So breakerbox appends one line per evaluated command to .breakerbox/decisions.jsonl: the command, the verdict (allow/ask/deny), and which failMode was live. A crash is recorded as outcome: "evaluation-error" rather than vanishing. And the absence of a line during the incident window is itself the signal that the hook wasn't wired. It's cheap, local-only, and doubles as the artifact you hand to whoever asks why the bill looks like that.


Roadmap

  • MCP tool-call interception (mcp__* matchers)
  • A PreToolUse matcher for Write/Edit on IaC files, to catch spend at authoring time rather than apply time
  • Framework adapters beyond Claude Code (LangGraph, CrewAI) via a generic subprocess wrapper
  • Auto-trigger the Terraform preflight when terraform apply <saved-plan> is seen at the hook (today breakerbox plan is opt-in; see "Spend preflight for Terraform")
  • cloudformation / CDK / Pulumi plan parsing, the same way the Terraform preflight works

Development

npm test     # 67 tests, node:test, no dependencies

MIT © ShopDevX