@quandev104/pi-rules
Native Pi project rules package with rule injection, commands, and background maintenance.
Package details
Install @quandev104/pi-rules from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@quandev104/pi-rules- Package
@quandev104/pi-rules- Version
0.1.5- Published
- Jun 19, 2026
- Downloads
- 579/mo · 579/wk
- Author
- quandev104
- License
- MIT
- Types
- extension, skill
- Size
- 492.4 KB
- Dependencies
- 0 dependencies · 4 peers
Pi manifest JSON
{
"extensions": [
"./dist/extensions/pi-rules.js"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@quandev104/pi-rules
Zero-dependency Pi extension for path-scoped project rules — auto-discovers, injects, and recommends updates for context-aware rules under
.pi/rules/.
Why?
Every project has conventions that LLMs don't know: naming patterns, architecture decisions, API contracts, team preferences. You could paste them into every prompt — or let pi-rules inject the right ones automatically based on which files you're working on.
How it works
User: "Fix the auth handler in src/api/auth/login.ts"
┌─────────────────────────────────────────────────┐
│ pi-rules extension │
│ │
│ 1. Extract paths from prompt + tool results │
│ 2. Match against .pi/rules/**/*.md frontmatter │
│ 3. Inject matched rules into context │
│ 4. After turn: recommend rule updates │
└─────────────────────────────────────────────────┘
Three injection modes
| Mode | When | What |
|---|---|---|
| Static | Start of each turn | Rules matching prompt + recently-touched files |
| Dynamic | After each tool call | Rules matching files just read/written |
| Both | Default | Both static and dynamic |
Path collection
Rules are matched against paths from multiple sources:
- Prompt extraction — file paths mentioned in user message
- Tool results — files read/written by
read,edit,write,bash - Session hot paths — accumulated across turns (FIFO, capped at 100)
- Last context fallback — re-injects previous rules after
session_compact
Injection tiers
When multiple rules match:
.pi/rules/api/api.md → summary only (parent)
.pi/rules/api/auth/auth.md → full body (child, more specific)
.pi/rules/api/auth/inventory → listed as available (not injected)
Prompt filter
Non-code prompts (e.g. "what is React?") skip path-matched rules. Only alwaysApply: true rules are injected regardless.
Install
pi install npm:@quandev104/pi-rules
Quick start
/pi-rules:init
Scans your project and creates path-scoped rules under .pi/rules/. AGENTS.md is not overwritten — it's maintained separately.
To pass additional instructions to the bootstrapper:
/pi-rules:init Port exactly rule from @.claude/rules
Then write rules as markdown with YAML frontmatter:
---
paths:
- "src/api/**/*.ts"
summary: API route handler conventions
triggers:
- "create endpoint"
- "add route"
priority: 10
---
# API Rules
- All handlers must validate input with Zod.
- Return `Result<T>` — never throw from handlers.
- Auth via `withAuth()` wrapper.
Frontmatter reference
---
paths: # Glob patterns for path matching
- "src/auth/**/*.ts"
summary: One-line description # Used in injection header
triggers: # Natural language phrases
- "fix auth bug"
- "login flow"
alwaysApply: true # Inject on every turn
priority: 10 # Higher = injected first
kind: rules # "rules" | "inventory"
---
| Field | Type | Default | Description |
|---|---|---|---|
paths |
string | string[] |
— | Glob patterns matched against target paths. Supports *, **, ?, {a,b}. |
summary |
string |
— | One-line routing summary. Used in parent injection headers. |
triggers |
string[] |
— | Natural language phrases. If the prompt contains a trigger, the rule is injected. |
alwaysApply |
boolean |
false |
Inject on every turn regardless of path match. Use sparingly. |
priority |
number |
0 |
Sort order. Higher priority rules are injected first. |
kind |
"rules" | "inventory" |
"rules" |
rules files are fully injected. inventory files are listed but not injected. |
description |
string |
— | Longer description (not used in injection). |
Commands
| Command | Description |
|---|---|
/pi-rules:init [...prompt] |
Bootstrap .pi/rules/ via the init-advanced skill (optional prompt forwarded to skill) |
/pi-rules:status |
Show discovered rules, diagnostics, and pending recommendations |
/pi-rules:preview <id> |
Quick heuristic preview: groups changed files by pattern, detects topics missing from rule |
/pi-rules:doctor |
Rule discovery diagnostics report |
/pi-rules:context |
Show last injected rule context |
/pi-rules:approve <id> |
Approve a pending recommendation by ID |
/pi-rules:approve-all |
Approve all pending recommendations |
/pi-rules:cancel <id> |
Cancel a pending recommendation by ID |
/pi-rules:cancel-all |
Cancel all pending recommendations |
/pi-rules:cleanup |
Remove completed/error recommendations older than 24 hours |
/pi-rules:recommendations-log |
Show tail of the maintainer log |
Tools
| Tool | Description |
|---|---|
create_rule |
Create a new .pi/rules/ file programmatically |
Environment variables
| Variable | Default | Description |
|---|---|---|
PI_RULES_DISABLED |
unset | Set 1 to disable extension |
PI_RULES_MAX_RULE_CHARS |
12000 |
Per-rule body character cap |
PI_RULES_MAX_CONTEXT_CHARS |
40000 |
Total injected chars per turn |
PI_RULES_RECOMMENDATIONS_DISABLED |
unset | Set 1 to disable automatic rule recommendations |
Skills
init-advanced
Bootstraps .pi/rules/ for a project. Runs reconnaissance, interviews the developer (up to 5 questions), and creates rule files with proper frontmatter. AGENTS.md is not created or overwritten — it's maintained separately.
rules-maintainer
Hidden skill (disable-model-invocation: true). Invoked per-rule by the recommendation system when a user approves a recommendation. Reads the current rule and changed source files, then rewrites the rule content in-place if needed.
How Recommendations Work
The recommendation system lets you review and approve rule updates before they are applied. No rules are changed without your explicit approval.
Flow
Agent turn completes
→ Changed files are matched to rules via frontmatter paths
→ Recommendation created (or merged into existing pending one)
→ User reviews with /pi-rules:status
→ User previews with /pi-rules:preview (heuristic, instant)
→ User approves with /pi-rules:approve or /pi-rules:approve-all
→ Rule update agent spawned for approved recommendations
One rule, one recommendation
Each rule file can have at most one pending recommendation at a time. If multiple agent turns change files that match the same rule, the changed files are merged into the existing pending recommendation. This keeps the review queue clean and avoids redundant updates.
Preview
Before approving, get a heuristic summary with /pi-rules:preview <id>:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
.pi/rules/module-structure.md
12 files: 10 .cs, 2 .csproj
Các nhóm thay đổi chính:
• AccessManagement/Commands (6 files)
• AccessManagement/Queries (4 files)
⚠️ Rule hiện tại chưa đề cập đến:
- AccessManagement/Commands
➡️ Có thể cần cập nhật rule để bao gồm các pattern mới.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
The preview is instant — no agent spawn. It groups changed files by known pattern directories (Commands, Queries, Handlers, Facades, etc.) and compares against the rule's existing headings.
Path filtering
Before creating recommendations, paths are filtered to remove noise:
- Shell redirects (
2>/dev/null,&>/tmp) — filtered at extraction - Glob patterns (
*.cs,*/Commands/*) — filtered at extraction - Code fragments, bare extensions, version numbers — filtered at extraction
- Dot-directories (
.ralph/,.github/,.vscode/) — excluded from maintenance - Namespace-style tokens without directory (
BuildingBlocks.Cqrs) — excluded
Merge behavior
When a new recommendation would target a rule that already has a pending recommendation:
- The changed files list is merged (deduplicated)
- The merge count is incremented
- The
fileCountandextensionSummaryare recomputed - The existing recommendation ID is preserved
Lifecycle
| Status | Description |
|---|---|
pending |
Awaiting user review |
approved |
User approved, ready to apply |
cancelled |
User cancelled |
completed |
Rule update agent finished successfully |
error |
Rule update agent failed |
Architecture
shared → domain → features → app → pi
Layer boundaries enforced by dependency-cruiser. Only pi/ may skip layers.
extension-src/pi-rules/
├── shared/ Zero-dep utilities (path, fs, hash, glob, frontmatter)
├── domain/ Core logic (parser, scanner, matcher, engine, cache)
├── features/ Workflows (recommender, store, tool-paths)
├── app/ Config and runtime state
└── pi/ Pi API adapters (commands, events, tools, UI)
Zero runtime dependencies
All utilities are implemented from scratch using only node:* builtins:
- Frontmatter parser — custom YAML subset parser (replaces
gray-matter) - Glob matcher — custom glob-to-regex (replaces
picomatch)
Development
npm install
npm run build # Build dist/
npm run typecheck # TypeScript checking
npm run lint # Biome linting
npm run depcruise # Dependency boundary check
npm test # Vitest (217 tests)
npm run check # All of the above
CI/CD
- Push/PR to main → runs full CI (typecheck, lint, depcruise, test, build) on Node 20 + 22
- Push tag
v*→ auto-publishes to npm
git tag v0.1.1
git push origin v0.1.1
# → GitHub Actions publishes @quandev104/pi-rules@0.1.1