pi-edit-hooks
Code quality hooks for the pi coding agent — runs syntax checks on edit and format/lint/typecheck at turn end
Package details
Install pi-edit-hooks from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-edit-hooks- Package
pi-edit-hooks- Version
0.2.0- Published
- Apr 30, 2026
- Downloads
- 142/mo · 15/wk
- Author
- mackenney
- License
- MIT
- Types
- extension
- Size
- 59.7 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-edit-hooks
Code quality hooks for the pi coding agent.
Runs syntax checks inline as the agent edits files (onEdit) and runs
format/lint/typecheck at the end of each turn (onStop).
Install
pi install npm:pi-edit-hooks
Configuration
Create .pi/edit-hooks.json in your project, or globally at ~/.pi/agent/edit-hooks.json.
Hooks
| Hook | Trigger | Behavior | Variables |
|---|---|---|---|
onEdit |
After each write/edit tool call |
Appends output to tool result (informational, never blocks). Shows resolved config file and command executed. | {file} |
onStop |
After agent turn ends | Sends a follow-up message with each command and its output. Errors trigger a new agent turn; clean output is informational only. | {files}, {file} |
Variables
{file}— absolute path of the edited file{files}— space-separated absolute paths of all files edited in the current turn, grouped by project (see below){projectRoot}— directory containing the.pi/folder
Commands without a placeholder run as-is (useful for project-wide tools like npx tsc --noEmit).
Monorepo File Grouping
In monorepos, {files} is not a flat list of every edited file. Instead,
pi-edit-hooks groups files by their nearest workspace manifest (pyproject.toml,
package.json, go.mod, etc.) and runs the onStop command once per group,
with {files} containing only the files that belong to that manifest's project
and {projectRoot} pointing to its directory.
This means tools like ruff, tsc, and go vet are always invoked from the
correct project root with the correct subset of files — no cross-project
contamination and no need to wrangle paths manually.
Array Commands
A command value can be a string or an array of strings. When an array is given, each command runs in sequence — all steps always run regardless of exit codes:
"*.py": [
"uv run ruff format {files}",
"uv run ruff check --fix {files}",
"uv run ty check {files}"
]
Path-Keyed Config
Apply different settings per subdirectory:
{
".": {
"onEdit": { "*.py": "python3 -m ast {file}" },
"onStop": { "*.py": "uv run ruff check {files}" }
},
"legacy/": false,
"packages/frontend/": {
"onStop": { "*.{ts,tsx}": "npx biome check {files}" }
}
}
false disables all hooks for that subtree.
Claude Code CLI
The package also ships a pi-edit-hooks binary compatible with Claude Code's
stop-hook protocol:
{
"hooks": {
"Stop": [{ "hooks": [{ "type": "command", "command": "pi-edit-hooks check" }] }],
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "pi-edit-hooks accumulate" }] }]
}
}
Example Configurations
Minimal project setup:
{
"onEdit": {
"*.py": "python3 -c 'import ast,sys;ast.parse(open(sys.argv[1]).read())' {file}",
"*.{js,mjs,cjs}": "node --check {file}",
"*.{ts,tsx}": "esbuild {file} > /dev/null"
},
"onStop": {
"*.py": [
"uv run ruff format {files}",
"uv run ruff check --fix {files}",
"uv run ty check {files}"
],
"*.{ts,tsx}": "npx tsc --noEmit"
}
}
Monorepo with per-subtree overrides:
{
".": {
"onEdit": { "*.py": "python3 -c 'import ast,sys;ast.parse(open(sys.argv[1]).read())' {file}" },
"onStop": {
"*.py": [
"uv run ruff format {files}",
"uv run ruff check --fix {files}",
"uv run basedpyright {files}"
]
}
},
"legacy/": false,
"packages/frontend/": {
"onStop": { "*.{ts,tsx}": "npx biome check {files}" }
}
}