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-skill-ignore-bypass

v0.1.0

Published

Pi extension that loads skills which pi's skill discovery silently drops because of .gitignore, .ignore, or .fdignore rules

Readme

pi-skill-ignore-bypass

npm version license pi-package

A pi extension that makes pi load skills which its skill discovery silently drops because of .gitignore / .ignore / .fdignore rules.

Install

pi install npm:pi-skill-ignore-bypass

To try it without touching your settings, run pi with the package loaded temporarily:

pi -e npm:pi-skill-ignore-bypass

Then /reload (or restart pi) if you installed it while pi was running. Remove it with pi remove npm:pi-skill-ignore-bypass.

If you prefer not to use a package, index.ts is a self-contained extension file — drop it into ~/.pi/agent/extensions/ (or any auto-discovered extension location) and it works the same way.

The problem

When pi scans a skills directory it reads the ignore files inside that tree and skips any SKILL.md they match:

// packages/coding-agent/src/core/skills.ts
if (!isFile || ig.ignores(relPath)) continue;

That is intentional (it was added to stop pi from recursing into .venv, __pycache__, dist, etc. — see #1072), but it has a nasty side effect: if your skills tree lives in a dotfiles repo that keeps it clean with a whitelist .gitignore:

*
!.gitignore
!/kitty
!/kitty/**

…then every skill that is not whitelisted silently disappears. No warning, no diagnostic, nothing. Claude Code loading the same tree is unaffected, so the gap is easy to miss for months.

Reported upstream, all closed without a fix:

  • #2947 — feat: Allow for gitignored skills
  • #5145 — Skills with a .gitignore file in their directory are not discovered (maintainer reply: "this works as per design and is documented")
  • #8748 — Skill discovery honors .gitignore in skills dirs; excluded skills vanish with no diagnostic

There is no upstream toggle to disable this behavior, and docs/skills.md does not mention it.

How it works

pi's loader treats directory and file skill paths differently:

| skillPath passed to pi | Behavior | | --- | --- | | directory | recursive scan, ignore files are applied, matched SKILL.md files are skipped | | .md file | loadSkillFromFile is called directly — no ignore check at all |

So this extension re-scans the configured skill roots itself, never consulting any ignore file, and hands pi the resulting SKILL.md files as extra skill paths:

pi.on("resources_discover", () => {
  // own no-ignore traversal of the roots
  return { skillPaths: ["/path/to/skill/SKILL.md", ...] };
});

Extension-provided paths are merged into pi's skill path list, and pi deduplicates by realpathSync, so skills that pi already discovered normally are not loaded twice and keep their original source metadata.

Because it works on file paths, it also handles the case where the ignore rule is inside the skill directory itself (a * gitignore used to keep generated files out of version control) — #5145.

Default scan roots

Used when includeDefaults is not false:

Project-level — only when the current project is trusted, walked from cwd up to the git repo root (or the filesystem root when not inside a repo):

<cwd>/.agents/skills
<cwd>/../.agents/skills
...  up to <git-root>/.agents/skills

<home>/.agents/skills is filtered out of this list because the user-level root below already covers it. pi's own project .agents/skills scanning is trust-gated, and this extension does not bypass that: untrusted projects never contribute skills.

User-level:

| Directory | mode | | --- | --- | | $PI_CODING_AGENT_DIR/skills (default ~/.pi/agent/skills) | pi | | ~/.agents/skills | agents | | $XDG_CONFIG_HOME/agents/skills (default ~/.config/agents/skills) | agents |

mode only affects one rule: whether loose *.md files directly inside the root are treated as skills (pi) or ignored (agents). This mirrors pi's own behavior for its two directory conventions.

Configuration

Optional file: $PI_CODING_AGENT_DIR/skills-bypass.json (default ~/.pi/agent/skills-bypass.json). A missing file, or invalid JSON, means all defaults.

{
  // Turn the whole extension off without removing it. Read at startup / reload time.
  "disabled": false,

  // Enable the default roots listed above. Default: true.
  // Set to false to use only "roots" below.
  "includeDefaults": true,

  // Extra roots, APPENDED after the default roots.
  // String form is shorthand for { "dir": "...", "mode": "pi" }.
  // "~/" is expanded; leading "~user" is not. Missing directories are skipped silently.
  "roots": [
    "~/work/shared-skills",
    { "dir": "~/another/tree", "mode": "agents" }
  ],

  // Directory names to skip while recursing (exact match, any depth).
  // Omitted => the built-in dependency list (see below). Empty array => skip nothing.
  "skipDirs": ["node_modules", ".git"],

  // Log the forced skill files to stderr on every discovery (startup and /reload).
  "verbose": false
}

Every field is optional. The config is read once when the extension is instantiated, so changes require /reload.

skipDirs

Exact directory-name matching at any depth. Defaults to common dependency directories — deliberately not build/output artifact directories:

.git .hg .svn
node_modules bower_components jspm_packages .pnpm-store .yarn
.venv venv virtualenv site-packages __pypackages__ .tox .nox
vendor .bundle
.cargo
.gradle .m2
deps
Pods
.stack-work
.terraform

dist, build, target, out, _build, obj, bin, DerivedData, __pycache__, .cache, .next and friends are intentionally absent.

Notes:

  • There is no implicit "skip dot-directories" rule. .git is in the default list for that reason; if you remove it, pi will walk .git object databases.
  • Conversely, a skill placed inside a hidden directory (e.g. .hidden/my-skill/SKILL.md) is now found, which pi itself cannot do.
  • A directory containing SKILL.md is treated as a skill root and is not recursed into, so my-skill/scripts/node_modules/ is never reached for well-formed skills. skipDirs mainly matters for the non-skill branches of the tree, and for symlinks pointing at repositories.

Caveats

  • It re-adds skills you may have deliberately ignored. That is the whole point, but it also means ignore rules can no longer be used to hide a skill from pi.
  • It overrides pi's skills settings -path exclusions for anything it discovers. Extension-provided skill paths do not go through pi's settings override logic. Narrow roots if you need to avoid this.
  • Skills are matched by SKILL.md only (plus loose *.md at pi-mode roots with a non-empty description). Malformed SKILL.md files still produce pi's normal warnings.
  • Directory symlinks are followed, and a symlinked directory without a top-level SKILL.md is recursed into. Point a root at a monorepo and you are subject to its contents, minus skipDirs.
  • ~ expansion only handles a leading ~/ or ~\.
  • Extensions run with full system access. This one only reads the filesystem and never executes anything, but review index.ts before installing any extension.

Verifying it works

A model-free way to inspect which skills pi actually loaded is RPC mode plus get_commands:

printf '{"type":"get_commands"}\n' | pi --mode rpc --no-session --offline \
  | jq -r 'select(.command=="get_commands") | .data.commands[] | select(.source=="skill") | .name'

With the extension disabled ("disabled": true) the ignored skills are missing; with it enabled they are present. Set "verbose": true to also see exactly which files were forced:

[skill-ignore-bypass] forced 6 skill file(s): /home/you/.config/agents/skills/agent-browser/SKILL.md, ...

Development

npm install
npm run typecheck

The extension ships as TypeScript source and is loaded by pi's own TypeScript loader, so there is no build step. @earendil-works/pi-coding-agent is a peerDependency because pi bundles it at runtime; it is only installed as a dev dependency for type checking.

License

MIT