> pi can help you create pi packages. Ask it to bundle your extensions, skills, prompt templates, or themes. # Pi Packages Pi packages bundle extensions, skills, prompt templates, and themes so you can share them through npm or git. A package can declare resources in `package.json` under the `pi` key, or use conventional directories. ## Table of Contents - [Install and Manage](#install-and-manage) - [Package Sources](#package-sources) - [Creating a Pi Package](#creating-a-pi-package) - [Package Structure](#package-structure) - [Dependencies](#dependencies) - [Package Filtering](#package-filtering) - [Enable and Disable Resources](#enable-and-disable-resources) - [Scope and Deduplication](#scope-and-deduplication) ## Install and Manage > **Security:** Pi packages run with full system access. Extensions execute arbitrary code, and skills can instruct the model to perform any action including running executables. Review source code before installing third-party packages. ```bash pi install npm:@foo/bar@1.0.0 pi install git:github.com/user/repo@v1 pi install https://github.com/user/repo # raw URLs work too pi remove npm:@foo/bar pi list # show installed packages from settings pi update # update all non-pinned packages ``` By default, `install` and `remove` write to global settings (`~/.pi/agent/settings.json`). Use `-l` to write to project settings (`.pi/settings.json`) instead. Project settings can be shared with your team, and pi installs any missing packages automatically on startup. To try a package without installing it, use `--extension` or `-e`. This installs to a temporary directory for the current run only: ```bash pi -e npm:@foo/bar pi -e git:github.com/user/repo ``` ## Package Sources Pi accepts three source types in settings and `pi install`. ### npm ``` npm:@scope/pkg@1.2.3 npm:pkg ``` - Versioned specs are pinned and skipped by `pi update`. - Global installs use `npm install -g`. - Project installs go under `.pi/npm/`. ### git ``` git:github.com/user/repo@v1 https://github.com/user/repo@v1 ``` - Raw `https://` URLs work without the `git:` prefix. - Refs pin the package and skip `pi update`. - Cloned to `~/.pi/agent/git//` (global) or `.pi/git//` (project). - Runs `npm install` after clone or pull if `package.json` exists. ### Local Paths ``` /absolute/path/to/package ./relative/path/to/package ``` Local paths work in settings but not with `pi install`. If the path is a file, it loads as a single extension. If it is a directory, pi loads resources using package rules. ## Creating a Pi Package Add a `pi` manifest to `package.json` or use conventional directories. Include the `pi-package` keyword for discoverability. ```json { "name": "my-package", "keywords": ["pi-package"], "pi": { "extensions": ["./extensions"], "skills": ["./skills"], "prompts": ["./prompts"], "themes": ["./themes"] } } ``` Paths are relative to the package root. Arrays support glob patterns and `!exclusions`. ## Package Structure ### Convention Directories If no `pi` manifest is present, pi auto-discovers resources from these directories: - `extensions/` loads `.ts` and `.js` files - `skills/` recursively finds `SKILL.md` folders and loads top-level `.md` files as skills - `prompts/` loads `.md` files - `themes/` loads `.json` files ## Dependencies Third party runtime dependencies belong in `dependencies` in `package.json`. When pi installs a package from npm or git, it runs `npm install`, so those dependencies are installed automatically. Pi bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@mariozechner/pi-ai`, `@mariozechner/pi-agent-core`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `@sinclair/typebox`. Other pi packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Pi loads packages with separate module roots, so separate installs do not collide or share modules. Example: ```json { "dependencies": { "shitty-extensions": "^1.0.1" }, "bundledDependencies": ["shitty-extensions"], "pi": { "extensions": ["extensions", "node_modules/shitty-extensions/extensions"], "skills": ["skills", "node_modules/shitty-extensions/skills"] } } ``` ## Package Filtering Filter what a package loads using the object form in settings: ```json { "packages": [ "npm:simple-pkg", { "source": "npm:my-package", "extensions": ["extensions/*.ts", "!extensions/legacy.ts"], "skills": [], "prompts": ["prompts/review.md"], "themes": ["+themes/legacy.json"] } ] } ``` `+path` and `-path` are exact paths relative to the package root. - Omit a key to load all of that type. - Use `[]` to load none of that type. - `!pattern` excludes matches. - `+path` force-includes an exact path. - `-path` force-excludes an exact path. - Filters layer on top of the manifest. They narrow down what is already allowed. ## Enable and Disable Resources Use `pi config` to enable or disable extensions, skills, prompt templates, and themes from installed packages and local directories. Works for both global (`~/.pi/agent`) and project (`.pi/`) scopes. ## Scope and Deduplication Packages can appear in both global and project settings. If the same package appears in both, the project entry wins. Identity is determined by: - npm: package name - git: repository URL without ref - local: resolved absolute path