pi-rules

May 19, 2026 · View on GitHub

ci license: MIT npm

Rule context loader for the pi coding agent. Discovers rule files from .omo/rules/, .claude/rules/, .cursor/rules/, .github/instructions/, AGENTS.md, CLAUDE.md, and injects them into the agent context.

Origin

pi-rules is inspired by oh-my-openagent (omo) .omo/rules/ and opencode's AGENTS.md / CLAUDE.md instruction file mechanisms.

  • omo at https://github.com/code-yeongyu/oh-my-openagent is by Yeongyu Kim, originally SUL-1.0.
  • This package is an independent pi-coding-agent extension by the same author.
  • Source distributed here is MIT (see LICENSE and NOTICE).
  • The logic is structurally similar to omo's rules-injector hook, adapted to pi-mono's ExtensionAPI hooks (before_agent_start, tool_result).

Quick Demo

$ pi -e ./src/index.ts

[pi-rules] 5 active rules

> Read src/auth/login.ts

  ✓ src/auth/login.ts (1.2KB)

[pi-rules] +2 instructions injected (security.md, typescript.md)

Installation

The package targets the pi coding agent. Pi loads extensions from ~/.pi/agent/extensions/, project .pi/extensions/, or via the --extension / -e CLI flag.

Pick whichever route fits:

# 1. From npm (once published)
pi install npm:@code-yeongyu/pi-rules

# 2. From git (once the repository is pushed)
pi install git:github.com/code-yeongyu/pi-rules

# 3. Manual placement (always works)
git clone https://github.com/code-yeongyu/pi-rules ~/.pi/agent/extensions/pi-rules
cd ~/.pi/agent/extensions/pi-rules && npm install

# 4. Dev / one-shot test
pi -e /path/to/pi-rules/src/index.ts

After installation, restart pi (or run /reload inside an interactive session).

What gets loaded

Project rule directories (recursive *.md / *.mdc)

DirectoryStyle
.omo/rules/omo style
.claude/rules/Claude Code style
.cursor/rules/Cursor style
.github/instructions/GitHub Copilot style (only *.instructions.md)

These use walk-up stack semantics: from the target file's directory up to the project root, rules at every level are collected. Closer directories win in precedence.

Project single-file rules

FileStyle
.github/copilot-instructions.mdGitHub Copilot
AGENTS.mdopencode style
CLAUDE.mdClaude Code style
CONTEXT.mddeprecated, still supported

These use first-match-wins at the project root: AGENTS.md takes priority over CLAUDE.md, which takes priority over CONTEXT.md.

User-home rules (always-on, distance 9999)

PathType
~/.omo/rules/directory
~/.opencode/rules/directory
~/.claude/rules/directory
~/.config/opencode/AGENTS.mdsingle-file
~/.claude/CLAUDE.mdsingle-file

User-home rules are global and apply to every project with the lowest precedence.

Rule format

Rules are Markdown files with an optional YAML frontmatter block:

FieldTypeDescription
descriptionstringOptional short description
globsstring | string[]Glob patterns; rule applies if target file matches any
pathsstring | string[]Claude Code alias for globs (merged)
applyTostring | string[]GitHub Copilot alias for globs (merged)
alwaysApplybooleanIf true, rule always applies regardless of target

Example rule file:

---
description: TypeScript-specific rules
globs: ["**/*.ts", "**/*.tsx"]
---

# TypeScript

Prefer `unknown` over `any`. Use exhaustive switch checks.

Precedence and merging

Rules are ordered deterministically before injection:

  1. Local before global — project rules outrank user-home rules.
  2. Closest distance first — rules from directories nearer to the target file take priority.
  3. Source priority.omo/rules > .claude/rules > .cursor/rules > .github/instructions > AGENTS.md > CLAUDE.md > CONTEXT.md > user-home variants.
  4. Lexicographic relativePath — final tiebreaker for same-source, same-distance rules.

Deduplication is in-memory per session by realPath + content hash. No filesystem persistence.

Slash commands

CommandPurpose
/rulesSummary of active rules
/rules listList all rule files with paths
/rules show <id>Show body of one rule
/rules pathsList absolute paths only
/rules statusCounts and warnings
/reload-rulesRescan and clear injection cache

All commands work in both UI and plain-text modes.

TUI widget

On session start, a banner appears above the editor with a [pi-rules] prefix and a list of top rules. Active rules show a indicator; rules with warnings show . The banner dismisses on the first before_agent_start event.

A persistent status line reads [pi-rules] N active and updates as rules are discovered or rescanned.

Configuration

CLI flags

FlagTypeDefaultPurpose
pi-rules-disabledbooleanfalseDisable all injection
pi-rules-modestringbothstatic | dynamic | both | off
pi-rules-widgetbooleantrueShow banner and status line

Environment variables

VariableDefaultPurpose
PI_RULES_DISABLEDunsetIf 1, disables injection
PI_RULES_MAX_RULE_CHARS12000Per-rule body cap
PI_RULES_MAX_RESULT_CHARS40000Total injected per tool result

Trust model

Rule files are prompt and context input. Do NOT load untrusted repositories. All rule loading is local filesystem reads. There is no network or remote rule fetching.

Troubleshooting

SymptomFix
No rules loadedVerify .omo/rules/, AGENTS.md, etc. exist in the project root or ancestors. Run /rules to inspect.
Rule not matchingCheck frontmatter globs / paths / applyTo. Confirm the target file path matches the glob.
Duplicate injectionAutomatically deduplicated per session. Try /reload-rules to reset.
Extension not loadedConfirm pi.extensions in your package.json or use pi -e ./src/index.ts for one-shot.
Context too largeAdjust PI_RULES_MAX_RULE_CHARS and PI_RULES_MAX_RESULT_CHARS.
TUI widget missingCheck pi-rules-widget flag is true and your terminal supports the relevant glyphs.

Development

git clone https://github.com/code-yeongyu/pi-rules
cd pi-rules
npm install            # install dev + peer deps
npm test               # 229 unit tests
npm run test:integration  # 43 integration tests
npm run typecheck      # tsc --noEmit
npm run check          # tsc + biome
pi -e ./src/index.ts   # smoke-test inside a real pi session

The test suite uses Vitest. Test descriptions follow #given X #when Y #then Z style; bodies use // given / // when / // then plain comments. No any in production code, no enums.

License

MIT. See NOTICE for re-license disclosure relative to omo.

  • senpi — the fork/runtime these extensions are extracted from.
  • Ultraworkers Discord — community link from the senpi README.
  • Dori — the product powered by senpi under the hood.

Acknowledgements

  • Yeongyu Kim (@code-yeongyu) — author of oh-my-openagent (origin of the rules-injection idea), and of this pi port.
  • Mario Zechner (@badlogic) — author of pi-mono and the pi-coding-agent extension API this package targets.
  • opencode — for the elegant Instructions from: <path> formatting convention adopted here.