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

diedinchat

v0.12.0

Published

File-bound rules for coding agents. Pin a constraint to the paths it is about; it lives in git, survives session end and tool switches, and re-checks itself. Measured: agents followed pinned rules 18/20 times versus 0/20 without.

Readme


Before / after

Your src/config.ts is generated from a schema. Nothing in the file says so. You ask any coding agent to change the API base URL.

Without diedinchat — it edits the generated file. The next build silently throws your change away:

// src/config.ts        ← generated. edited anyway.
export const config = {
  apiBase: "https://api.acme.production",   // gone on next build
};

With the rule pinned — it edits the source and leaves the generated file alone:

// src/config.schema.ts ← edited here
  apiBase: "https://api.acme.production",

// src/config.ts        ← untouched
  apiBase: "https://api.acme.test",

Same repo, same request, same agent. The only difference is one file:

{
  "text": "src/config.ts is generated from the schema. Never edit it directly.",
  "files": ["src/config.ts", "src/config.schema.ts"],
  "evidence": ["ConfigSchema"],
  "status": "supported"
}

Both snippets are verbatim from the measured run.

The numbers

Three rules a coding agent cannot read from the code. Ten trials each, with and without the rule pinned.

18/20 versus 0/20. +90 points, 95% interval +65 to +99.

The third row is a control, fixed before the run: a rule the agent already follows. It scored 10/10 in both arms. Tickets moved the two things that were broken and left the working one alone — which is the part that makes the other two rows worth believing.

Four experiments, 117 invocations, every raw record committed and re-runnable. Two exclude zero; two are nulls published anyway. Method, failures and data: docs/evidence/.

Install

npx diedinchat init

One command. It detects your agent, writes the rule it reads, installs a pre-write gate where the agent supports one, and adds a git hook that covers everything else — hand edits, autocomplete, teammates, CI. No server, no config edit, no account.

The rule goes into the file your agent already reads:

| | | |---|---| | Claude Code | .claude/skills/diedinchat/SKILL.md | | Cursor | .cursor/rules/diedinchat.mdc | | Copilot | .github/instructions/diedinchat.instructions.md | | Windsurf | .windsurf/rules/diedinchat.md | | Cline | .clinerules/diedinchat.md | | Gemini | AGENTS.md, skills/… | | anything else | AGENTS.md |

Then pin a rule — or just say it in chat and let the agent pin it for you (measured: 6/6 with the convention installed, 0/6 without):

diedinchat pin --text "src/config.ts is generated. Edit the schema." \
  --file src/config.ts --file src/config.schema.ts \
  --evidence ConfigSchema
diedinchat status src/config.ts     # what rules cover this path
diedinchat check --json             # for CI
diedinchat install-hook --hook pre-commit

Or over MCP

For clients that prefer tools to files, via Smithery:

npx -y smithery mcp add pawankumar94/diedinchat

That installs a bundled copy, so it needs no global diedinchat. It asks for a project root — the repository whose .diedinchat/ you want it to read. Set it: an MCP client starts the server in its own working directory rather than your repo, and without it every lookup comes back empty.

Five tools: list_claims_for_file (call it before editing), pin_claim, check_claim, close_claim, unpin_claim.

Configuring a client by hand instead? Point it at the dedicated MCP binary and set the root, since the client's working directory will not be your repo:

{
  "command": "npx",
  "args": ["-y", "diedinchat", "diedinchat-mcp"],
  "env": { "DIEDINCHAT_ROOT": "/absolute/path/to/your/repo" }
}

diedinchat mcp does the same thing and takes the root from wherever you launch it.

How it works

One JSON file per rule in .diedinchat/, committed next to your code. files is the address. evidence is a phrase that must stay true.

Status is recomputed from disk on every read. No model is involved.

| | | |---|---| | supported | the evidence still holds | | contradicted | the evidence is gone — red, the way a test goes red | | stale | files moved and nothing was frozen to check against | | open | pinned, nothing to verify yet |

That last property is what a rules file cannot do. .cursorrules saying "auth is in middleware" keeps saying it after someone deletes middleware. A ticket re-checks itself and goes red.

FAQ

How is this different from .cursorrules or agent memory? Three ways. A rule in .cursorrules is about the whole repo, so it is either always in context — costing tokens every turn — or absent when it matters. It never expires, so it recites facts that stopped being true. And it does not travel: Cursor's memory is not Claude Code's. A ticket is addressed to paths, re-checks itself, and is a file in your repo.

Why not just write a test? Tests lock behaviour. "This file is generated" is not behaviour — both versions return the same thing and both go green.

What should I pin? Things the code cannot tell an agent: a generated file, a library that is installed but banned, a value that is cents behind a number type. Pinning things the code already demonstrates does nothing — we measured that and got 9/9 in both arms.

What if the agent just ignores it? Sometimes it does — at 90%, roughly one invocation in ten still misses. Two answers, in increasing strength:

init sets both up. To be explicit, or to make the gate refuse when diedinchat itself cannot run:

diedinchat install-agent-hook --agent cursor --fail-closed
diedinchat review --markdown        # what rules this PR touches

A pre-write hook only covers agent writes. Cursor's Tab completions, a hand edit, and a teammate who never installed anything are all outside it. That is what the git hook is for, and why init installs both.

The agent hook runs before an edit: it puts the rules covering that file in front of the model, and denies the write outright when one is contradicted. That closes the exact failure we measured — an agent editing a generated file having never looked. The git hook is the floor under everything, including a human editing by hand.

Gating needs a host that exposes a pre-write hook. Claude Code and Cursor do — both adapters ship. Copilot's path-scoped instructions are advisory, and Cursor's own afterFileEdit is observational, so neither can stop a write. Nothing can gate what exposes no gate, and no hook covers a human editing by hand, so git and CI stay the editor-independent backstop.

What does it cost? Tokens. In the measured runs, tickets in the workspace raised mean cost per invocation from $0.026 to $0.045 and median latency from 22s to 31s. The agent reads them and runs status. On short tasks that is a large fraction of a small number.

Does it work with my agent? install writes to nine targets and the store is plain files, so anything that reads your repo can use it. But every number above is Claude Code on claude-sonnet-4-6 — Copilot, Cursor and Gemini are untested, and that is the next measurement.

Can I reproduce your numbers? Yes, that is the point.

diedinchat run --tasks examples/honor-invisible/tasks-v2.json \
  --agent examples/honor-rate/claude-code.json \
  --policy no-tickets --policy with-tickets --trials 10
diedinchat score --tasks examples/honor-invisible/tasks-v2.json
diedinchat report --baseline no-tickets --candidate with-tickets

Used it on a real repo?

Every number above comes from a synthetic fixture and one agent. If you ran it somewhere real, tell us what happened — especially if it blocked a write it should not have. A wrong block stops your work, and we would rather hear about one than ship a gate people switch off.

Docs

| | | |---|---| | how-it-works.md | the handoff, status derivation, what is actually guaranteed | | docs/evidence/ | every experiment, its design, and its raw records | | integrations.md | per-client MCP setup | | PLANNER.md | what is left to build |

npm test        # 143 tests, no network or agent CLI required

Releases publish from GitHub Actions with npm provenance, so the registry attests which commit built the tarball.

MIT.