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

@hyuga/redline

v0.6.1

Published

A limiter that counts the whole session instead of asking about one call: writes to production, irreversible commands and outward sends add up, the number never goes down, and past the edge it stops only when nobody is in the seat.

Readme

redline

The mark on the gauge — you may cross it. It is here so that you know you did.

A limiter for a coding agent. It counts the session, not the call.

redline: 4 — production +2, irreversible +3
Past 3 with nobody in the seat. Stopping here: hand back to a human.

Part of the airframe machine — npx @hyuga/airframe install wires it up along with everything else. It works on its own too.

Why counting, and not asking

A permission prompt asks about one call at a time, and answers it in isolation. Every single call can be defensible while the session as a whole goes somewhere nobody agreed to: a write to production, then another, then a cleanup that deletes something, then a push. Nobody approved that. They approved four things.

redline keeps one number per sortie. It only ever goes up.

| | | |---|---| | 1 | recorded | | 2 | advised | | 3 | stopped — but only when nobody is in the seat |

While you are flying it, past the edge you get told and you decide. Unattended, the tool call is denied.

The number never goes down inside a sortie. What is per-call is which call gets stopped: one that adds nothing to the total is not stopped for the last one that did. Otherwise a scheduled task that deletes a single temporary file spends the rest of its run being refused permission to write to a scratch directory, and cannot even hand back.

The tariff

| | | |---|---| | irreversible — rm -rf, force push, hard reset, DELETE FROM, DROP, TRUNCATE | +3 | | outward — npm publish, git push, gh pr create, a POST, sending mail | +3 | | production — a write to a path you called production | +2 | | dependency — new code entering the tree | +1 | | unnamed — a file nobody asked for | +0, recorded only |

Irreversible and outward sit at the limit on their own, because the first instance is already the whole event: there is no such thing as half a publish.

Unnamed is written down and not charged. A skill is handed a task and knows its own filenames, so a file the prompt never mentions is the normal case, not the runaway — measured over a day, 19 of 22 charges were a skill writing its own declared output, and one skill crossed the limit in 41 seconds. The finding is still filed, so the question is still answerable; it just no longer moves the number.

Charges are not exclusive. git push --force is irreversible and outward at once, and pricing it as one of those would be the cheaper reading of the two.

Reading production is free. Charging for it would make the careful thing cost the same as the dangerous one, which teaches skipping the read.

Quoting is not doing. A command is cut into the things it actually runs before the tariff is applied: grep "npm publish" README.md costs nothing, grep "npm publish" README.md && npm publish costs 3, and what a heredoc writes into a file is not read as commands at all. This limiter learned that on itself — a session that only ever searched for the words reached 20 against a limit of 3, and a number that is mostly noise gets read as noise.

The same goes for what a command means once its variables are read. S="$TEMP/x"; rm -rf "$S/out" is tidying a scratch directory and costs nothing; rm -rf "$TEMP", rm -rf "$S" with S never set, and a relative rm with no cd in front of it still cost 3, because the limiter cannot tell where they land. Code handed to node -e or python -c is data when it can be read — standard file and path modules, no child process, no eval — so a script that reads settings.json is not a write to production and a string containing npm publish is not a publish.

The numbers are meant to be argued with — spend a week disagreeing with them and change them. The structure is what is being claimed, not the weights.

A run that was always going to cost this much

Writing a page into a production tree is two points. Uploading it is two more. So a run that does the whole job crosses the limit on its last step — every time — and a batch is that shape multiplied: ten clients is twenty points, and from the second one onwards every publish is past the edge.

Raising the limit for long sorties would not fix this; it would just mean the limit grows with whatever the agent happens to be doing, which is not a limit. Charging a repeated destination only once would not fix it either — there is no such thing as half a publish, and the tenth client's page is not free because the first one's was charged.

What is actually wrong there is the question. "Is this call past the edge" is the wrong thing to ask, per call, about a sequence whose cost was known before it started. Ask it once, in front:

spar melee --action "monthly karte for all clients" \
           --exit   "yesterday's backup at X:/backup/20260901" \
           --state  "$(curl -sI https://example.com/report/ | head -1)"

A swing needs an exit route and a reading taken at contact, and it refuses to close without either. Inside one, findings accumulate instead of interrupting, and the gate is pulled once, on spar melee leave. For an unattended run that is the operator's line to write in the runner, before the loop — not something the agent argues its way through call by call.

Which paths are production

Yours to say, in .redline.json:

{ "production": ["X:/01-client/", "/var/www/"] }

Looked for from every tree a call touches at once: the directory the session was started in, the directory of the file being written, and up to four absolute paths a shell command names — each walking upwards, then falling back to your home directory.

Both, because a hook's working directory is not where the work is. It is where the session started, and an agent started in a home directory writes to a client tree on a network share all day without ever changing it. A config at the top of that share would never be reached, and a config that is not found fails silently: the most exposed write of the day gets charged as an ordinary one. Which paths are production is a property of the tree the file lives in, the way .gitignore is, and that tree is the one that knows.

What they say is added together, never ranked. Ranking would let a config anywhere in the write path shorten the list the session started with — a quieter limiter, chosen by the directory being written to. A union can only make more things count as production, which is the direction a limiter is allowed to be wrong in.

A shell command gets one too, from the absolute paths it names — because the last step of publishing anything is a shell command, and it was the one call whose charge depended on where you had filed the config. Staging a file into a client tree was priced; the upload that put it in front of the public was free.

Taking a path out of a string is a guess, and the reason a wrong guess is tolerable here is the union: anything found this way can only add to what counts as production. A guess that lands nowhere costs a few existsSync calls and changes no number. Read-only segments are dropped first, so grep /var/www -r is not asked about the tree it is reading.

Or, as well, REDLINE_PRODUCTION, semicolon-separated — it is unioned with whatever the files say, never ignored because a file exists. A substring match, on the path for a write tool and on the command line for a shell call — so cp build/index.html /var/www/site/ is charged too, and so is anything run after cd /var/www/site. An assignment or a cd on its own is not a write, and a command that only prints is charged for what it redirects there.

"Unnamed" needs to know what you asked for

The UserPromptSubmit hook records the filenames you mentioned in your own words. A write to something else is the agent's own idea — written down, and free.

Naming nothing is recorded too, and is not the same as the hook being absent. "/karte <client>" names a task and no files, so everything the run writes is the agent's own idea — which is when the record is worth most, and was the one case that used to leave none.

Without that hook redline does not guess — it charges nothing for scope rather than pricing every file in the repo as unasked-for. It matches on filename only, so two files with the same basename in different directories look alike to it.

Install

npm i -D @hyuga/redline

Then, in settings.json:

"PreToolUse":       [{ "hooks": [{ "type": "command", "command": "npx @hyuga/redline hook pre",    "timeout": 10 }] }],
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "npx @hyuga/redline hook prompt", "timeout": 10 }] }]
redline score      # what this sortie has spent so far

Where the number lives

Nowhere in this package. redline has no store: it sums its own findings back out of the spar ledger, which is also what resets it when a new sortie launches, keeps it quiet while you are drafting, and holds it silent inside a committed deploy.

That is the point of the frame. A melee case was written into this file and turned out to be unreachable, because the frame had already handled it — so it was deleted.

This is a gauge, not a guard

redline is not a security boundary, and it cannot be made into one. Its number comes from the ledger, and the ledger is a file in your repository that the agent can write to with the same tools it uses for everything else. An agent that wanted a lower score could edit it. So could a stray sed.

That is not a hole waiting to be closed. Move the ledger out of the repository and an agent with a shell still reaches it; sign every line and the key has to live somewhere the same agent can read. Anything that runs commands on your machine on your behalf is inside the boundary already, and a limiter that pretends otherwise is worse than one that does not, because you would trust the number.

What it is for is the case that actually happens: not an agent trying to get past you, but one that has no idea it is on its fourth irreversible operation, and a human who has lost count too. For that, a number summed from the record is exactly right, and its being editable costs nothing.

Read the gauge the way a pilot reads one. It tells you where you are. It is not holding the aircraft together.

What this does not buy

It does not know what is dangerous. It knows what you told it to charge for, plus a list of command shapes. A destructive thing spelled in a way the tariff does not match is free.

It still over-charges, in one place on purpose. A verb that prints — grep, cat, echo — has its arguments treated as text, and so does a heredoc body. A verb that takes another command does not: node -e "…rm -rf…", sed, awk, xargs and find -exec are charged on what they contain, because nothing here can tell whether that string is about to run or about to be printed. Erring toward charging is deliberate where the answer is genuinely unknown. Erring toward it where the answer was obvious is what cost this limiter 20 points for reading a README.

Advice is advice. With you in the seat, the message is text the model can reason its way past, and sometimes it will. Only the unattended case is enforced.

Node 18+. One dependency, the frame. No daemon, no network, no LLM.

MIT.