pi-config-valid¶
Pi package and project resource declarations must have valid types
| Severity | warning (auto) |
| Autofix | - |
| Since | v0.21.0 |
| Repo Types | pi, pi-package |
| Category | Pi |
Why¶
Pi reads resource declarations from package.json#pi and project
.pi/settings.json. A string where an array belongs silently drops resources
in the current package loader. This rule identifies the field and expected type
before the package is installed.
Checks¶
- JSON must parse to an object. Duplicate keys use JavaScript's last-value behavior.
- The package's
pifield must be an object when present. extensions,skills,prompts, andthemesmust be arrays of strings.- Project
packagesmust contain source strings or objects with a nonemptysource, optional resource filter arrays, and an optional booleanautoload.
Unknown npm fields, Pi gallery metadata, and unrelated settings are accepted. Empty resource lists are valid. Findings are consolidated by file and default to warning: current Pi ignores malformed manifest fields instead of failing startup.
How to fix¶
Put paths in arrays, such as "skills": ["./skills"]. In project settings,
use "packages": [{"source": "npm:my-package", "skills": []}] to configure
a package and disable its skills. Keep settings paths relative to the directory
containing settings.json, and package paths relative to package.json.
Examples¶
Use arrays for resource paths:
A string such as "skills": "./skills" is invalid and drops that resource type.
Discovery and boundaries¶
The pi-package repository type comes from a pi key, the pi-package npm
keyword, or a repository-local directory listed in project packages. Ordinary
npm packages and unmarked conventional directories do not establish Pi ownership.
A conventional-only package can be selected through project settings. The pi
type comes from .pi project resources, including those in monorepo subprojects.
Portable SKILL.md files not selected by Pi keep their Agent Skills checks.
A pi object replaces conventional Pi package discovery; omitted resource types
and empty arrays contribute no resources. Without that object, packages use
extensions/, skills/, prompts/, and themes/. Manifest globs discover visible
paths; ! exclusions, + exact re-inclusions and - exact exclusions filter
those resources. Project resource lists resolve literal paths and use wildcards
as filters, matching the native loader. Project prompt and theme autoload is shallow;
explicit prompt directories and package prompts are recursive.
Locally referenced packages are linted as authored packages, including resources
that a particular consumer's package filters disable. Package filters are
validated, but do not suppress diagnostics on the package's authored content.
Remote sources and paths outside the checkout are not loaded. Glob traversal
does not descend through symlinked directories; exact contained roots may use
symlinks. Resource walks read .gitignore, .ignore, and .fdignore at or below each
resource root, using Pi's directory-relative prefixing.
Pi-only packages receive shared prose checks for README, commands, agents and
rules. Claude configuration at hooks/hooks.json or settings.json is checked
only when the directory also declares Claude ownership.
Extensions are represented as entrypoint nodes. Themes are configuration nodes, not prose; theme colors and runtime extension behavior are outside this rule. No core Pi MCP schema is assumed.
Upstream reference¶
Pinned to Pi commit
36b60d2e,
particularly packages/coding-agent/src/core/pi-manifest.ts,
package-manager.ts, and skills.ts. See the Pi package documentation.
Configuration¶
Run skillsaw explain pi-config-valid to see this documentation and the rule's effective configuration in your terminal.