module-gates
Health Uyari
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- process.env — Environment variable access in bin/module-gates.mjs
- process.env — Environment variable access in scripts/gh-bot.mjs
- network request — Outbound network request in scripts/gh-bot.mjs
- crypto private key — Private key handling in scripts/gh-bot.mjs
- spawnSync — Synchronous process spawning in src/bootstrap-jiti.mjs
- process.env — Environment variable access in src/bootstrap-jiti.mjs
- spawnSync — Synchronous process spawning in src/bridges/claude/pre-tool-use.test.ts
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
controls the entropy of the codebase by enforcing code module boundaries.
module-gates - Constraints liberate, liberties constrain.
Hooks that controls the entropy of the codebase by enforcing module boundaries, helping combat slops.
Supported agent harnesses:
- pi — pi extension
- Claude Code — plugin, or plain hooks installed by the CLI
Adding support for another agent (qwen-code, cursor, ...) means adding a bridge.
Approach
Module contracts as guardrails. Each directory can contain a descriptor file (default MODULE.md) that declares:
readonly— files cannot be editedno-new-exports— files where no new exports are allowed (body still editable)
The extension intercepts agent write/edit operations and enforces these contracts. Violations are blocked with a reason.
The attempt to add 2 public helper functions is blocked, forcing the agent to re-think the design.
How it works
- Indexing — On session start, scans the project tree for descriptor files and builds a module index.
- System prompt — Injects a hint so the agent knows to respect descriptor file conventions.
- Gating — On every write/edit, checks:
- Readonly gate — is the target file locked?
- No-new-exports gate — would the change add new exports to a file in the
no-new-exportslist? - Module interface import gate — external files can only import from the module not internal files, i.e. re-exports from
index.tsormod.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?
- System prompt: system-prompt.md
- Currently supported languages: TypeScript/JavaScript, Rust, Java, Go, Kotlin, Scala
Installation
pi
pi install npm:@cuzfrog/module-gates
Or load directly for a single session:
pi -e npm:@cuzfrog/module-gates
Claude Code
As a plugin, from this repository's marketplace (no login required — public repo):
/plugin marketplace add cuzfrog/module-gates
/plugin install module-gates@cuzfrog
On the first hook invocation the plugin installs its runtime dependencies into its data directory.
Or as plain hooks wired into a project (requires the package installed in the project):
npm install --save-dev @cuzfrog/module-gates
npx module-gates install-claude
This writes PreToolUse and SessionStart hooks into .claude/settings.json; npx module-gates uninstall-claude removes them. The SessionStart hook injects the system prompt hint automatically.
Or reuse an existing pi installation by pointing hooks at it manually in ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|MultiEdit|Write",
"hooks": [
{
"type": "command",
"command": "node \"$HOME/.pi/agent/npm/node_modules/@cuzfrog/module-gates/src/bridges/claude/run.mjs\" pre-tool-use"
}
]
}
],
"SessionStart": [
{
"matcher": "startup|resume|clear",
"hooks": [
{
"type": "command",
"command": "node \"$HOME/.pi/agent/npm/node_modules/@cuzfrog/module-gates/src/bridges/claude/run.mjs\" session-start"
}
]
}
]
}
}
The pi install directory may differ; locate run.mjs under your pi npm root. The SessionStart hook (system prompt injection) is optional — PreToolUse alone enforces the 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. A MODULE.md only enforces its own immediate directory.
Readonly constraints
---
readonly: [mod.rs]
---
Any prose for the agent to better understand the module.
No-new-exports constraints
no-new-exports: [mod.rs]
No-new-exports files cannot change their surface size: no new exports or public entries are allowed. The file body is still editable.
A skill module-no-new-exports-all has been included to populate no-new-exports entries in modules.
| Scenario | Behavior |
|---|---|
No MODULE.md |
Module is unconstrained — nothing is gated. |
| Malformed YAML frontmatter | The module is left unguarded and an info notification is emitted. |
Configuration
The canonical agent-independent location is .module-gates/config.json (the whole file is the config, no wrapper key). When it is absent, each bridge falls back to the agents' settings files under a module-gates key — e.g. .pi/settings.json, .claude/settings.json.
{
"module-gates": {
"moduleDescriptorFileName": "MODULE.md",
"moduleDescriptorReadonly": "off",
"sourceRoots": ["src/"],
"outputModuleProseOnBlock": false
}
}
| Option | Default | Description |
|---|---|---|
moduleDescriptorFileName |
MODULE.md |
File name used for module descriptors (case-insensitive) |
moduleDescriptorReadonly |
"off" |
"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.
Troubleshooting
Prompt:
Check if PreToolUse hook `module-gates` is triggered and runs expectedly.
License
MIT
Author
Cause Chung ([email protected])
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi