Load personal skills conditionally by OS, hostname, cwd marker, executable availability, and environment variable presence.
Place skills under <agent-dir>/skillz/ instead of Pi's native skills/ directories.
Pi's normal skill discovery rules apply inside this directory, including nested skill directories and standalone Markdown skills.
Matching skills become native /skill:<name> commands; they do not appear individually in pi config.
Enable or disable the extension itself through pi config.
Use top-level os, host, path, which, or env fields in skill frontmatter; at least one is required.
Every field accepts a single string, a nonempty list of strings (any), or an explicit { any: [...] } or { all: [...] } selector.
any matches at least one entry; all requires every entry; different fields must all match.
---
name: jj-workflow
description: Use in a Jujutsu working directory on this machine.
os: [lnx, mac]
host: desktop
path: .jj
---
os accepts lnx, win32, or mac.
host matches the exact machine hostname.
path checks an explicit path under Pi's cwd; use / separators on every OS.
which checks executable names on PATH without running them; Windows honors PATHEXT.
Absolute paths, .., backslashes, and symlink components in marker paths are rejected.
Command names for which must not contain path separators, whitespace, or :.
env checks whether named variables contain nonempty values; empty strings count as absent.
Variable names must use letters, digits, or underscores and start with a letter or underscore.
For example, gate a skill on multiple credentials with env: { all: [GATEBRIDGE_R2_ACCESS_KEY_ID, GATEBRIDGE_R2_SECRET_ACCESS_KEY, GATEBRIDGE_R2_ENDPOINT] }.
Conditions are reevaluated at startup and on /reload; changes to markers, executables, or environment variables do not update an open session until reload.
Run /skillz to inspect the last discovery snapshot: every discovered candidate is marked loaded or excluded with condition evidence, validation problems, or name collisions.
The report shows variable names and presence only, never environment values; it stays in the UI rather than entering model context.
Pi's native scanner may silently ignore files, so ignored files are not included in this report.
If Pi has not registered an eligible skill, the report labels it as eligible but not registered rather than guessing a cause.
At startup, a TUI summary reports eligible skills; /reload omits the summary because Pi replaces informational notifications with its reload-success status.
Invalid conditions and duplicate names still produce warnings.
Pi remains responsible for validating standard skill fields.
Performance
mise run //extensions/skillz:bench measures isolated discovery and full Pi session reload with 256 generated 4 KiB skills, of which 75% match.
The fixture warms up for 20 cycles and reports 12 rounds of five operations by default; compare independent runs with //extensions/skillz:benchstat.
mise run //extensions/skillz:profile captures a Node V8 CPU profile under the OS temporary directory.
Pi's native skill loader and YAML parsing dominate discovery; avoid replacing native discovery without proof that Pi's ignore, symlink, validation, and collision behavior stays intact.
See index.ts for resource registration, match.ts for condition semantics, and inspect.ts for the report.
Debug
Opt in through debug configuration.
Safe events: session.start, session.shutdown, skillz.inspect.start, skillz.inspect.finish, skillz.inspect.error.
# skillz
Load personal skills conditionally by OS, hostname, cwd marker, executable availability, and environment variable presence.
Place skills under `<agent-dir>/skillz/` instead of Pi's native `skills/` directories.
Pi's normal skill discovery rules apply inside this directory, including nested skill directories and standalone Markdown skills.
Matching skills become native `/skill:<name>` commands; they do not appear individually in `pi config`.
Enable or disable the extension itself through `pi config`.
Use top-level `os`, `host`, `path`, `which`, or `env` fields in skill frontmatter; at least one is required.
Every field accepts a single string, a nonempty list of strings (`any`), or an explicit `{ any: [...] }` or `{ all: [...] }` selector.
`any` matches at least one entry; `all` requires every entry; different fields must all match.
```yaml
---
name: jj-workflow
description: Use in a Jujutsu working directory on this machine.
os: [lnx, mac]
host: desktop
path: .jj
---
```
`os` accepts `lnx`, `win32`, or `mac`.
`host` matches the exact machine hostname.
`path` checks an explicit path under Pi's cwd; use `/` separators on every OS.
`which` checks executable names on `PATH` without running them; Windows honors `PATHEXT`.
Absolute paths, `..`, backslashes, and symlink components in marker paths are rejected.
Command names for `which` must not contain path separators, whitespace, or `:`.
`env` checks whether named variables contain nonempty values; empty strings count as absent.
Variable names must use letters, digits, or underscores and start with a letter or underscore.
For example, gate a skill on multiple credentials with `env: { all: [GATEBRIDGE_R2_ACCESS_KEY_ID, GATEBRIDGE_R2_SECRET_ACCESS_KEY, GATEBRIDGE_R2_ENDPOINT] }`.
Conditions are reevaluated at startup and on `/reload`; changes to markers, executables, or environment variables do not update an open session until reload.
Run `/skillz` to inspect the last discovery snapshot: every discovered candidate is marked loaded or excluded with condition evidence, validation problems, or name collisions.
The report shows variable names and presence only, never environment values; it stays in the UI rather than entering model context.
Pi's native scanner may silently ignore files, so ignored files are not included in this report.
If Pi has not registered an eligible skill, the report labels it as eligible but not registered rather than guessing a cause.
At startup, a TUI summary reports eligible skills; `/reload` omits the summary because Pi replaces informational notifications with its reload-success status.
Invalid conditions and duplicate names still produce warnings.
Pi remains responsible for validating standard skill fields.
## Performance
`mise run //extensions/skillz:bench` measures isolated discovery and full Pi session reload with 256 generated 4 KiB skills, of which 75% match.
The fixture warms up for 20 cycles and reports 12 rounds of five operations by default; compare independent runs with `//extensions/skillz:benchstat`.
`mise run //extensions/skillz:profile` captures a Node V8 CPU profile under the OS temporary directory.
Pi's native skill loader and YAML parsing dominate discovery; avoid replacing native discovery without proof that Pi's ignore, symlink, validation, and collision behavior stays intact.
See [`index.ts`](index.ts) for resource registration, [`match.ts`](match.ts) for condition semantics, and [`inspect.ts`](inspect.ts) for the report.
## Debug
Opt in through [debug configuration](../DEBUG.md).
Safe events: `session.start`, `session.shutdown`, `skillz.inspect.start`, `skillz.inspect.finish`, `skillz.inspect.error`.