npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-yaml-hooks

v2026.5.12

Published

YAML hook automation for the PI coding agent: tool guards, session hooks, prompts, notifications, and bash actions.

Readme

pi-yaml-hooks

Run bash around PI tool calls, block risky commands, and post UI notifications, confirmations, and status entries from one hooks.yaml file. pi-yaml-hooks plugs into the PI coding agent as a package; nothing else to wire up.

This repo is the PI port of OpenCode-Hooks. The hook model is familiar; the runtime is PI-native and the limits are explicit.

What it does

  • Run hooks on tool.before.*, tool.after.*, file.changed, session.created, session.idle, and session.deleted
  • Use bash, tool, notify, confirm, and setStatus actions
  • Filter hooks with matchesCodeFiles, matchesAnyPath, and matchesAllPaths
  • Load one global root config and one trusted project root config; imports are gated by trust and opt-in env vars
  • Show built-in diagnostics with /hooks-status, /hooks-validate, /hooks-trust, /hooks-reload, and /hooks-tail-log
  • Emit structured in-session diagnostics when PI supports custom messages
  • Inject a short hook-awareness note before agent start (disable with PI_YAML_HOOKS_PROMPT_AWARENESS=0)

Quick start

Create a minimal global hook file so you can see the extension working right away.

pi install npm:pi-yaml-hooks

mkdir -p ~/.pi/agent/hook
cat > ~/.pi/agent/hook/hooks.yaml <<'YAML'
hooks:
  - event: session.idle
    actions:
      - notify: "Agent is idle"
YAML

pi

Expected startup output:

[pi-yaml-hooks] Loaded 1 hook (global: 1, project: 0).

If a trusted project also has project hooks, the summary includes both scopes:

[pi-yaml-hooks] Loaded 3 hooks (global: 1, project: 2).

Requirements

  • macOS or Linux
  • Node.js >=22.0.0
  • bash on $PATH (override with PI_YAML_HOOKS_BASH_EXECUTABLE)
  • @earendil-works/pi-coding-agent ^0.74.0

Windows is unsupported.

Install

The full install reference, including settings.json edits, project-local installs, npm-library import paths, and local-checkout symlinks, lives in docs/setup.md. The short version:

pi install npm:pi-yaml-hooks         # recommended
pi install https://github.com/KristjanPikhof/pi-yaml-hooks   # latest unreleased
pi -e npm:pi-yaml-hooks               # one-off run, nothing written to settings

Add -l to pi install to write to project settings (.pi/settings.json) instead of global (~/.pi/agent/settings.json).

SDK compatibility matrix

Before widening PI peer support or merging SDK-sensitive changes, run the repeatable SDK matrix:

npm run compat:sdk-matrix

The matrix checks the supported SDK pair (@earendil-works/pi-coding-agent and @earendil-works/pi-tui 0.74.0). It creates a temporary copy of the repository, installs each SDK pair in that copy only, then runs npm run typecheck and the consumer-facing npm test script (which is the documented public-surface check; it does not exercise the internal dev suite). The working checkout's package.json, package-lock.json, and normal node_modules are not mutated.

For the full internal test suite, run npm run test:internal directly in the working checkout.

To preview the matrix workflow without installing anything:

npm run compat:sdk-matrix:dry-run

Runtime PI behavior also has a smoke checklist for surfaces unit tests cannot fully emulate, including slash commands, custom diagnostics, UI actions, follow-up prompts, user_bash, session switching, and /quit:

scripts/smoke/pi-runtime-smoke.sh

Maintainer-facing details, including the smoke checklist, evidence template, and gating rules, live in docs/maintaining.md. Keep the generated evidence file with release notes or SDK-widening PRs.

Future SDK lines (0.75.x and later) are gated, not part of the current peer range. Try them explicitly with:

npm run compat:sdk-matrix:future

Do not widen support until both the future matrix and the runtime smoke pass, including the no-builtin-tools gate.

How it works

pi-yaml-hooks discovers at most one global root config and one project root config. Project hooks and project-root imports load only when the repo or worktree anchor is trusted. Global-root imports require PI_YAML_HOOKS_ALLOW_GLOBAL_IMPORTS=1, package imports require PI_YAML_HOOKS_ALLOW_PACKAGE_IMPORTS=1, and project imports outside the trust anchor require PI_YAML_HOOKS_ALLOW_PROJECT_IMPORTS_OUTSIDE_TRUST_ANCHOR=1. The project root is repo/worktree-aware, not exact-cwd-only.

When an event matches, pi-yaml-hooks evaluates conditions and runs the configured actions. bash actions receive hook context JSON on stdin plus injected PI_* environment variables such as PI_PROJECT_DIR, PI_WORKTREE_DIR, PI_SESSION_ID, and PI_GIT_COMMON_DIR. At agent start, the extension also appends a short hook-awareness note to the system prompt so PI has the current hook and trust context while it works.

Native PI surface

Events

| Event | Meaning | |---|---| | tool.before.* | Before a tool call | | tool.after.* | After a tool call | | file.changed | Synthesized after recognized file mutations | | session.created | PI startup or a genuinely new session | | session.idle | Agent turn finished and no messages are pending | | session.deleted | Best-effort cleanup on shutdown or session switch; includes PI's reason (quit, reload, new, resume, or fork) when available |

Actions

| Action | PI behavior | |---|---| | bash | Runs a shell command with injected context | | tool | Sends a follow-up prompt into the current PI session | | notify | Shows a PI notification when a UI surface exists | | confirm | Shows a confirmation dialog before a tool runs | | setStatus | Sets a PI status-bar entry keyed to the hook |

Slash commands

| Command | What it shows | |---|---| | /hooks-status | Active hooks, config paths, trust state, and log path | | /hooks-validate | Validation results for active hooks and skipped untrusted project hooks | | /hooks-trust | Adds the current repo/worktree anchor to ~/.pi/agent/trusted-projects.json | | /hooks-reload | Asks PI to reload extensions; edited hooks also refresh lazily on the next relevant event | | /hooks-tail-log | Log path plus a ready-to-run tail -F command; --follow starts a detached live tail, and --path prints only the path |

/hooks-status, /hooks-validate, and hook-load validation errors also emit structured in-session diagnostics when PI supports custom messages.

PI exposes ctx.ui.addAutocompleteProvider on the supported ^0.74.0 line, so pi-yaml-hooks layers guarded /hooks autocomplete into the editor. Suggestions include the command names plus contextual hook IDs, event names, config paths, and log-tail options where useful. Hook IDs are loaded lazily and memoized by hook-snapshot signature, not fixed at extension registration time.

Important limitations

These are the PI-specific constraints that matter most:

  • command: actions are unsupported on PI and are rejected at load time
  • tool: is prompt injection, not imperative tool execution
  • action: stop only has real effect on tool.before.*
  • runIn: main is unsupported for non-bash actions
  • session.deleted is best-effort and intentionally lossy: PI fires it for shutdown and for session switches like /new, /resume, and /fork, and pi-yaml-hooks forwards PI's reason (quit, reload, new, resume, or fork) on the envelope so hooks can disambiguate
  • user_bash interception is opt-in with PI_YAML_HOOKS_ENABLE_USER_BASH=1

Keep those rules in mind when authoring hooks. They explain most surprising behavior.

What trust grants when user_bash is enabled

When PI_YAML_HOOKS_ENABLE_USER_BASH=1 is set, every human ! / !! shell command typed in PI is routed through tool.before.bash hooks before PI executes it. This expands the trust surface significantly:

  • Observation: hooks receive the typed command in stdin JSON as tool_args.command, so a trusted-project bash hook can read the full text of every command you type.
  • Blocking: a tool.before.bash hook that exits with code 2 will prevent the command from running. A misconfigured or malicious hook can silently block commands.
  • Exfiltration risk: the same bash hook can forward tool_args.command to an external service. Only enable PI_YAML_HOOKS_ENABLE_USER_BASH=1 if you trust every hook in every trusted project.

pi-yaml-hooks emits a one-time stderr warning on startup listing which trusted projects will have access when this env var is set, and shows a PI UI warning on the first intercepted command when a UI is available. The warning fires once per process and names the projects currently in ~/.pi/agent/trusted-projects.json.

This mode is disabled by default. Agent-generated bash tool calls are always intercepted regardless of this setting.

Config paths and trust

Global root config paths:

  1. ~/.pi/agent/hook/hooks.yaml
  2. ~/.pi/agent/hooks.yaml

Project root config paths:

  1. <project>/.pi/hook/hooks.yaml
  2. <project>/.pi/hooks.yaml

Project hooks are gated by trust because they can run arbitrary bash with your user permissions. Trust is evaluated against the repo or worktree anchor, not an arbitrary nested directory string. trusted-projects.json entries must be absolute paths; relative entries such as . are ignored.

Two ways to trust a project:

PI_YAML_HOOKS_TRUST_PROJECT=1 pi

or use the built-in command:

/hooks-trust

Examples

Example workflows live under examples/. Start with examples/README.md for complete example packs, including pre-tool developer guards and post-tool developer feedback hooks.

These packs are opt-in examples, not built-in PI features.

Docs

Full reference and reading order live in docs/README.md.

License

MIT.