@spences10/pi-coding-preferences

Configurable Pi guardrails that keep agents aligned with local coding workflow preferences before bad commands run

Packages

Package details

extension

Install @spences10/pi-coding-preferences from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@spences10/pi-coding-preferences
Package
@spences10/pi-coding-preferences
Version
0.1.1
Published
Nov 4, 2026
Downloads
557/mo · 490/wk
Author
spences10
License
MIT
Types
extension
Size
44.8 KB
Dependencies
3 dependencies · 1 peer
Pi manifest JSON
{
  "image": "https://raw.githubusercontent.com/spences10/my-pi/main/assets/pi-package-preview.png",
  "extensions": [
    "./dist/index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@spences10/pi-coding-preferences

built with Vite+ tested with Vitest npm version license

my-pi package preview

Keep agents aligned with your workflow and naming preferences before commands run or files are written. Workflow rules use text patterns; automatic naming checks use bundled TypeScript and Svelte parsers. No project lint configuration or parser installation is required.

It ships with default workflow preferences. Configure user rules in codingPreferences.rules in ~/.pi/agent/my-pi-settings.json and project rules in .pi/coding-preferences.json. When either supplies a rules array, configured rules are loaded instead of the built-in defaults. Naming-only configuration preserves the default workflow rules. The example below is a project configuration.

{
	"rules": [
		{
			"name": "no-npm",
			"toolNames": ["bash"],
			"target": "command",
			"pattern": "^npm\\b",
			"reason": "Use pnpm in this repo."
		}
	]
}

Rule targets are:

  • command: the shell command.
  • path: the tool's file path.
  • input (default): every string in the tool input, including edit oldText and newText. Existing rules keep this behavior.
  • content: only write.content, single-edit newText, and every batched edits[].newText. Paths, old text, commands, and unrelated fields are excluded, so removing a violation is allowed.

Patterns are JavaScript regular expressions. A blocked call reports the rule name and nested input field, but not the matched value. content is still text matching, not syntax-aware validation.

Use these rules for workflow restrictions or explicit text policies. For naming conventions, use the syntax-aware policy below and remove custom declaration-matching regexes such as prefer-project-snake-case-identifiers. Those old rules still run independently and can match prose; switching their target to content does not fix that. User configuration is not rewritten automatically.

Automatic naming policy

Naming checks apply by default whenever this extension is loaded. Configure them globally under codingPreferences.naming in ~/.pi/agent/my-pi-settings.json:

{
	"codingPreferences": {
		"naming": {
			"variables": "snake_case",
			"functions": "snake_case",
			"types": "PascalCase"
		}
	}
}

These are the defaults. Each category accepts snake_case, camelCase, PascalCase, or false to disable that category. Set "naming": false to disable all naming checks. Leading/trailing _ and $ markers are allowed. Existing rules entries are independent of naming preferences.

An optional project .pi/coding-preferences.json can set naming using the same shape (without the codingPreferences wrapper). Project categories override global categories; omitted categories inherit. Project false disables naming, while an explicit project object re-enables it after a global false. No project file is needed for global preferences to apply, including in a new project.

Coverage:

  • JavaScript/TypeScript: .js, .jsx, .mjs, .cjs, .ts, .tsx, .mts, .cts, including .svelte.js and .svelte.ts modules.
  • Svelte components: JavaScript/TypeScript in instance and module script blocks. Template bindings and style blocks are not checked.
  • Variables include parameters, catch bindings, and array/destructured local bindings. Function declarations/expressions and bindings initialized with an arrow/function use the functions category. Classes, interfaces, type aliases, enums, and class-expression bindings use types.
  • Imports, object/class/interface member names, enum members, constructor parameter properties, and shorthand object bindings are left alone to preserve API names. Aliased destructuring checks the local binding. Comments, strings, and identifier references are not declaration checks.

The extension reuses Pi's native write and edit tools with checked file operations. Pi resolves edits and supplies the complete proposed file; parsing and naming validation happen before the file write. Rejected calls report the file, location, name, expected style, and rule. Retry with a corrected change; the rejected file stays unchanged.

Unchanged legacy violations are tolerated by comparing counts of each name/category against the original file. Fixing or removing violations is allowed; introducing another violation is blocked. Invalid proposed syntax is rejected because naming cannot be reliably checked. Invalid original files can still be repaired. These are syntax/naming checks, not type checks or a replacement for project linting and tests.

This covers direct and Codemode-mediated calls to these native tools, not arbitrary shell writes or other file-writing tools. Another extension replacing write/edit can conflict with these overrides; compose its file operations explicitly rather than assuming coverage.

Direct tool calls and native Codemode's tools.edit() / tools.write() pass through the same guardrail hooks. Codemode coordinates tools; it does not replace enforcement or language-aware checks. See the validation workflow.

pi install npm:@spences10/pi-coding-preferences

This is opt-in: installing the package globally applies it to your Pi sessions, but projects and downstream users do not inherit it unless they install the package.

Development

Package scripts build transitive workspace dependencies first, then run local tools through Vite+ with vp exec.

pnpm --filter @spences10/pi-coding-preferences run check
pnpm --filter @spences10/pi-coding-preferences run test
pnpm --filter @spences10/pi-coding-preferences run build