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

@cuzfrog/pi-module-gates

v0.21.0

Published

pi extension that controls the entropy of the codebase by enforcing code module boundaries.

Downloads

3,633

Readme

pi-module-gates - Constraints liberate, liberties constrain.

Experimental pi cli extension that controls the entropy of the codebase by enforcing code module boundaries. It helps combat slop generation and code architecture degradation.

  • Claude Code supported via a hook, see below.

Problem

AI coding agents produce edits with limited context knowledge (myopia) — their changes may leak implementation details, and break architectural contracts (slop).

Approach

Module contracts as guardrails. Each directory can contain a descriptor file that declares:

  • readonly — files and directories the agent must not touch
  • sealed — files where no new exports are allowed (body still editable)
  • visible — the set of exports allowed to be added or modified in that module

The extension intercepts agent write/edit operations and enforces these contracts. Violations are blocked with a clear reason.

The attempt to add 2 public helper functions is blocked, forcing the agent to re-think the design. Module Gate denial example

How it works

  1. Indexing — On session start, scans the project tree for descriptor files and builds a module index.
  2. System prompt — Injects a hint so the agent knows to respect descriptor file conventions.
  3. Gating — On every write/edit, checks:
    • Readonly gate — is the target file locked? Sealed gate — would the change add new exports to a file in the sealed list?
    • Export gate — would the change introduce an export not in the visible list?
    • Module interface import gate — external files can only import from the module not internal files, i.e. re-exports from index.ts or mod.rs. A child module may import from a parent module's internal files (not recommended but allowed). (Only Typescript/JavaScript and Rust are supported)
    • Import gate (not implemented yet) — would the change introduce an import violating visibility scope?

Installation

pi install npm:@cuzfrog/pi-module-gates

Or load directly for a single session:

pi -e npm:@cuzfrog/pi-module-gates

Module Descriptor Semantics

A module descriptor is a Markdown file (default name: MODULE.md) placed in a directory. You can piggy-back on your module context file for example CONTEXT.md.

Readonly constraints

---
readonly: [mod.rs]
---

Any prose for the agent to better understand the module.

Sealed constraints

sealed: [mod.rs]

Sealed files cannot change their surface size: no new exports or public entries are allowed. The file body is still editable.

A skill module-seal-all has been included to auto-seal modules.

Visibility whitelist (under redesign)

visible:
  - greet # equivalent to `path: ./greet`
  - sub/mod1/Foo

or:

visible:
  - path: my_function
    modifier: pub(crate) # (optional) demands an exact match

| Scenario | Behavior | |----------|----------| | visible key absent or no MODULE.md | Module is unconstrained — exports are not gated. Equivalent to null internally. | | visible: [] | Module is fully closed — no new exports may be added. Editing existing exports is still allowed. | | Malformed YAML frontmatter | The module is left unguarded and an info notification is emitted. |

Export gating

project/
  MODULE.md          visible: [Foo, Bar]
  src/
    MODULE.md        visible: [Bar, Baz]
    app.ts           ← checked against `src/MODULE.md` only

A MODULE.md only enforces exports within its immediate directory.

Import gating (not implemented yet)

# parent/MODULE.md
visible:
  - sub/Tool # type Tool is allowed to be imported from parent

# parent/sub/MODULE.md (before complement pass)
visible:
  - Bar # type Bar is allowed to be imported from parent/sub within parent, but not outside parent

A MODULE.md semantically gates exposures at the module level it resides.

Configuration

Add a module-gates entry to .pi/settings.json:

{
  "module-gates": {
    "moduleDescriptorFileName": "MODULE.md",
    "moduleDescriptorReadonly": "file",
    "sourceRoots": ["src/"],
    "outputModuleProseOnBlock": false
  }
}

| Option | Default | Description | |--------|---------|-------------| | moduleDescriptorFileName | MODULE.md | File name used for module descriptors (case-insensitive) | | moduleDescriptorReadonly | "frontmatter" | "file" makes the whole descriptor readonly; "frontmatter" locks only the YAML frontmatter (body prose stays editable); "off" disables descriptor readonly. true/false are also accepted for backward compatibility. | | sourceRoots | ["src/"] | Directories to scan for descriptor files and enforce gates. Pass a single string for one root, or an array for multiple roots (e.g. monorepos with ["packages/app/src/", "packages/lib/src/"]). Use [""] to scan from the project root. Legacy singular sourceRoot (string) is still accepted. | | disableModuleInterfaceImportGate | false | When true, imports will not be forced to be from module interface. | | disableSystemPrompt | false | When true, skip injecting the module-gates hint into the agent's system prompt. | | outputModuleProseOnBlock | false | When true, the violating module descriptor's prose is appended to the block message so the agent sees the contract context. Disabled by default to keep the error message concise. |

When no settings file exists or no module-gates key is present, defaults apply.

Claude Code Support

Install

Add the following to .claude/settings.json in the current project, pointing the PreToolUse hook at the installed binary.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|MultiEdit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "bun ${CLAUDE_PROJECT_DIR}/node_modules/@cuzfrog/pi-module-gates/src/claude/pre-tool-use.ts",
            "statusMessage": "Module gate checking edit..."
          }
        ]
      }
    ]
  }
}

If pi-module-gates is already installed in pi global dir, you can use below path instead:

~/.pi/agent/npm/node_modules/@cuzfrog/pi-module-gates/src/claude/pre-tool-use.ts

System prompt

You need to add system-prompt.md manually to your context.

Configuration

Claude Code uses the same .pi/settings.json#module-gates block as the pi extension. See the Configuration section above.

Troubleshooting

Prompt:

Check if PreToolUse hook `pi-module-gates` is triggered and runs expectedly.

License

MIT

Author

Cause Chung ([email protected])