# Resources, Extensions, Skills, and Packages

> The portable extension layer for loading repository, file, npm, git, and catalog-like resources without binding the architecture to one model provider or hosted service.

- Repository: earendil-works/pi
- GitHub: https://github.com/earendil-works/pi
- Human wiki: https://grok-wiki.com/public/wiki/earendil-works-pi-121d322b171c
- Complete Markdown: https://grok-wiki.com/public/wiki/earendil-works-pi-121d322b171c/llms-full.txt

## Source Files

- `packages/coding-agent/src/core/resource-loader.ts`
- `packages/coding-agent/src/core/package-manager.ts`
- `packages/coding-agent/src/core/extensions/loader.ts`
- `packages/coding-agent/src/core/extensions/types.ts`
- `packages/coding-agent/src/core/extensions/runner.ts`
- `packages/coding-agent/src/core/skills.ts`
- `packages/coding-agent/src/core/prompt-templates.ts`
- `packages/coding-agent/src/core/settings-manager.ts`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [packages/coding-agent/src/core/resource-loader.ts](packages/coding-agent/src/core/resource-loader.ts)
- [packages/coding-agent/src/core/package-manager.ts](packages/coding-agent/src/core/package-manager.ts)
- [packages/coding-agent/src/core/extensions/loader.ts](packages/coding-agent/src/core/extensions/loader.ts)
- [packages/coding-agent/src/core/extensions/types.ts](packages/coding-agent/src/core/extensions/types.ts)
- [packages/coding-agent/src/core/extensions/runner.ts](packages/coding-agent/src/core/extensions/runner.ts)
- [packages/coding-agent/src/core/skills.ts](packages/coding-agent/src/core/skills.ts)
- [packages/coding-agent/src/core/prompt-templates.ts](packages/coding-agent/src/core/prompt-templates.ts)
- [packages/coding-agent/src/core/settings-manager.ts](packages/coding-agent/src/core/settings-manager.ts)
- [packages/coding-agent/src/core/source-info.ts](packages/coding-agent/src/core/source-info.ts)
- [packages/coding-agent/src/core/agent-session.ts](packages/coding-agent/src/core/agent-session.ts)
- [packages/coding-agent/docs/extensions.md](packages/coding-agent/docs/extensions.md)
- [packages/coding-agent/docs/skills.md](packages/coding-agent/docs/skills.md)
- [packages/coding-agent/docs/prompt-templates.md](packages/coding-agent/docs/prompt-templates.md)
- [packages/coding-agent/docs/packages.md](packages/coding-agent/docs/packages.md)
</details>

# Resources, Extensions, Skills, and Packages

This page explains Pi’s portable extension layer: how local files, repository resources, npm packages, git packages, and package-manifest resources become runtime extensions, skills, prompt templates, themes, context files, and system-prompt inputs.

The architecture is intentionally provider-neutral. Resource loading discovers and annotates capabilities; model providers are a separate extension capability through `registerProvider`, so a package or skill source does not imply a hosted service, model vendor, or proprietary catalog dependency.

## Architecture at a Glance

`DefaultResourceLoader` is the central facade. It exposes loaded extensions, skills, prompts, themes, context files, system prompt content, and append-system-prompt content through a small `ResourceLoader` interface. It delegates source resolution to `DefaultPackageManager`, extension module loading to `extensions/loader.ts`, and resource-specific parsing to `skills.ts`, `prompt-templates.ts`, and theme loading.

Sources: [packages/coding-agent/src/core/resource-loader.ts:23-37](), [packages/coding-agent/src/core/resource-loader.ts:321-493](), [packages/coding-agent/src/core/package-manager.ts:863-915]()

```mermaid
flowchart TD
  subgraph Config["Settings and CLI inputs"]
    Settings["SettingsManager\npackages/extensions/skills/prompts/themes"]
    CLI["additional* paths\n--extension, --skill, --prompt-template"]
  end

  subgraph Resolution["DefaultPackageManager"]
    PM["resolve() / resolveExtensionSources()"]
    Manifest["package.json pi manifest\nor convention dirs"]
  end

  subgraph Loading["DefaultResourceLoader"]
    RL["reload()"]
    ExtLoad["loadExtensions()"]
    Skills["loadSkills()"]
    Prompts["loadPromptTemplates()"]
    Themes["loadThemes()"]
    Context["AGENTS.md / SYSTEM.md"]
  end

  subgraph Runtime["Agent session runtime"]
    Runner["ExtensionRunner"]
    Prompt["System prompt and commands"]
  end

  Settings --> PM
  CLI --> PM
  PM --> Manifest
  PM --> RL
  RL --> ExtLoad
  RL --> Skills
  RL --> Prompts
  RL --> Themes
  RL --> Context
  ExtLoad --> Runner
  Skills --> Prompt
  Prompts --> Prompt
  Context --> Prompt
  Runner --> RL
```

## Resource Types and Provenance

Pi tracks four package-managed resource types: `extensions`, `skills`, `prompts`, and `themes`. Every resolved resource carries `PathMetadata` with a source label, scope (`user`, `project`, or `temporary`), origin (`package` or `top-level`), and optional base directory. `SourceInfo` is the runtime-facing form of that metadata and is attached to extension tools, commands, skills, prompts, and themes.

Sources: [packages/coding-agent/src/core/package-manager.ts:72-89](), [packages/coding-agent/src/core/source-info.ts:3-28](), [packages/coding-agent/src/core/resource-loader.ts:589-630]()

| Field | Meaning |
|---|---|
| `source` | Where the resource came from, such as a package spec, `local`, `auto`, or `extension:*`. |
| `scope` | Whether it is user, project, or temporary runtime input. |
| `origin` | Whether it came from an installed package or a top-level local/auto path. |
| `baseDir` | Directory used to resolve relative assets and provenance. |

This metadata is not cosmetic. It drives precedence, diagnostics, command provenance, and portable UI flows such as “show commands by source” without parsing paths.

## Settings, Package Sources, and Local Paths

Settings support both package sources and direct resource paths. A package source can be a string or an object with filters for `extensions`, `skills`, `prompts`, and `themes`. Direct arrays exist for local `extensions`, `skills`, `prompts`, and `themes`.

Sources: [packages/coding-agent/src/core/settings-manager.ts:67-100](), [packages/coding-agent/src/core/settings-manager.ts:118-138](), [packages/coding-agent/src/core/settings-manager.ts:407-437]()

```ts
// packages/coding-agent/src/core/settings-manager.ts
export type PackageSource =
  | string
  | {
      source: string;
      extensions?: string[];
      skills?: string[];
      prompts?: string[];
      themes?: string[];
    };
```

`SettingsManager` loads global and project settings and deep-merges project settings over global settings. `DefaultPackageManager.resolve()` then processes project packages before user packages, resolves local entries relative to the appropriate base directory, and adds auto-discovered resources.

## Package Manager Responsibilities

`DefaultPackageManager` accepts three broad source families:

| Source type | Example | Behavior |
|---|---|---|
| npm | `npm:@scope/pkg@1.2.3` | Installed under the user or project npm root; pinned versions are recognized. |
| git | `git:github.com/user/repo@v1` | Cloned under the user or project git root; temporary unpinned git sources can refresh. |
| local | `./path/to/package` | Used directly; files can be single extensions and directories can use package rules. |

Sources: [packages/coding-agent/src/core/package-manager.ts:1200-1280](), [packages/coding-agent/src/core/package-manager.ts:1380-1401](), [packages/coding-agent/docs/packages.md:31-93]()

Package directories are resolved by manifest first, then convention directories. A `package.json` `pi` manifest can list resource entries; otherwise convention directories such as `extensions/`, `skills/`, `prompts/`, and `themes/` are scanned. Package filters can narrow or disable resource types.

Sources: [packages/coding-agent/src/core/package-manager.ts:1985-2036](), [packages/coding-agent/src/core/package-manager.ts:2040-2130](), [packages/coding-agent/src/core/package-manager.ts:2135-2176]()

## Discovery and Precedence

The package manager sorts resolved resources so collision handling is deterministic. Project top-level settings have the highest precedence, followed by project auto-discovery, user settings, user auto-discovery, and finally package resources. After sorting, canonical path deduplication removes duplicate filesystem entries.

Sources: [packages/coding-agent/src/core/package-manager.ts:153-177](), [packages/coding-agent/src/core/package-manager.ts:2403-2423]()

Auto-discovery covers `.pi` resource directories and `.agents/skills`. Project `.agents/skills` directories are collected from the current working directory upward to the git repository root, or to the filesystem root when no git repository is found. User `.agents/skills` remains user-scoped.

Sources: [packages/coding-agent/src/core/package-manager.ts:387-427](), [packages/coding-agent/src/core/package-manager.ts:2184-2375]()

## Extension Loading and Runtime Binding

Extensions are TypeScript or JavaScript modules loaded through `jiti`. The loader creates an `Extension` record with maps for handlers, tools, renderers, commands, flags, and shortcuts. During module loading, registration methods write into that extension record, while action methods delegate to a shared runtime.

Sources: [packages/coding-agent/src/core/extensions/loader.ts:124-189](), [packages/coding-agent/src/core/extensions/loader.ts:177-318](), [packages/coding-agent/src/core/extensions/types.ts:1537-1568]()

Before the runner is bound, action methods throw or queue provider registrations. `ExtensionRunner.bindCore()` copies host-provided actions into the runtime and flushes queued provider registrations. This is the key separation point: extensions can register tools, commands, events, and providers, but the model registry and session actions are supplied by the host runtime.

Sources: [packages/coding-agent/src/core/extensions/loader.ts:124-169](), [packages/coding-agent/src/core/extensions/runner.ts:266-333](), [packages/coding-agent/src/core/extensions/types.ts:1450-1535]()

## Extension API Surface

The extension API includes event subscription, tool registration, commands, shortcuts, flags, message rendering, session actions, tool activation, model selection, thinking-level controls, provider registration, and an event bus.

Sources: [packages/coding-agent/src/core/extensions/types.ts:1084-1318](), [packages/coding-agent/src/core/extensions/types.ts:424-472]()

Provider registration is intentionally one API among many. It can add or override model providers, but resource packages are still loaded from files, npm, git, or local directories. That keeps BYOC/BYOK flows portable: a team can distribute skills and prompts without coupling them to a model vendor, or distribute a provider extension without changing the resource-loading architecture.

## Skills

A skill is loaded from Markdown, usually `SKILL.md`, with frontmatter metadata. The loader validates names and descriptions, skips skills with missing descriptions, records diagnostics for warnings, and preserves `disable-model-invocation` so hidden skills can be invoked explicitly without appearing in the system prompt.

Sources: [packages/coding-agent/src/core/skills.ts:67-120](), [packages/coding-agent/src/core/skills.ts:168-275](), [packages/coding-agent/src/core/skills.ts:277-327]()

Skills are formatted into an XML-like block for the system prompt. Only name, description, and location are always included; the model is instructed to read the skill file when the task matches. This implements progressive disclosure: descriptions are always visible, full instructions remain file-backed.

Sources: [packages/coding-agent/src/core/skills.ts:335-370](), [packages/coding-agent/docs/skills.md:35-76]()

## Prompt Templates

Prompt templates are Markdown files whose filename becomes the slash command name. Frontmatter can provide `description` and `argument-hint`; otherwise the first non-empty body line becomes a fallback description. Templates support positional substitution (`$1`, `$2`), all-argument substitution (`$@`, `$ARGUMENTS`), and bash-style slicing (`${@:N}` / `${@:N:L}`).

Sources: [packages/coding-agent/src/core/prompt-templates.ts:11-18](), [packages/coding-agent/src/core/prompt-templates.ts:68-102](), [packages/coding-agent/src/core/prompt-templates.ts:104-131]()

Prompt loading is non-recursive for default prompt directories, but explicit paths can point to files or directories. At runtime, `expandPromptTemplate()` only expands text that starts with `/` and matches a loaded template name.

Sources: [packages/coding-agent/src/core/prompt-templates.ts:194-262](), [packages/coding-agent/src/core/prompt-templates.ts:269-282](), [packages/coding-agent/docs/prompt-templates.md:1-68]()

## Context Files and System Prompt Files

Resource loading also discovers context and prompt files. Context files are `AGENTS.md`, `AGENTS.MD`, `CLAUDE.md`, or `CLAUDE.MD`, loaded first from the agent directory and then from ancestors of the current working directory. System prompt files are discovered as `.pi/SYSTEM.md` before global `SYSTEM.md`; append-system-prompt files use `.pi/APPEND_SYSTEM.md` before global `APPEND_SYSTEM.md`.

Sources: [packages/coding-agent/src/core/resource-loader.ts:40-111](), [packages/coding-agent/src/core/resource-loader.ts:468-487](), [packages/coding-agent/src/core/resource-loader.ts:853-880]()

## Runtime Resource Extension

Extensions can contribute additional skill, prompt, and theme paths through the `resources_discover` event. `ExtensionRunner.emitResourcesDiscover()` collects paths from handlers, and `AgentSession` passes them into `DefaultResourceLoader.extendResources()` with temporary `extension:*` provenance. The system prompt is then rebuilt with the newly loaded resources.

Sources: [packages/coding-agent/src/core/extensions/types.ts:493-502](), [packages/coding-agent/src/core/extensions/runner.ts:990-1036](), [packages/coding-agent/src/core/agent-session.ts:2058-2109](), [packages/coding-agent/src/core/resource-loader.ts:281-319]()

This is the main hook for catalog-like or repository-driven resource discovery. A connector can map an external index into ordinary file paths, but the runtime still receives portable resource paths and source metadata rather than a provider-specific object model.

## Collisions and Diagnostics

Collision handling favors first-loaded resources after package-manager precedence sorting. `loadSkills()` keeps the first skill for a given name and emits collision diagnostics for later duplicates. `DefaultResourceLoader` deduplicates prompts by command name and themes by theme name. Extension tool and flag conflicts are reported as errors while keeping extensions loaded; command conflicts are resolved by numeric invocation suffixes in the runner.

Sources: [packages/coding-agent/src/core/skills.ts:387-487](), [packages/coding-agent/src/core/resource-loader.ts:800-850](), [packages/coding-agent/src/core/resource-loader.ts:890-925](), [packages/coding-agent/src/core/extensions/runner.ts:514-556]()

## Trust Boundaries

Extensions are executable modules and package installs can fetch npm or git code. Skills are instructions that can cause the model to run tools or scripts. Pi’s code keeps provenance and diagnostics, but it does not sandbox third-party package code at the resource-loader layer. Installed or auto-discovered sources should be treated as trusted code/content.

Sources: [packages/coding-agent/src/core/extensions/loader.ts:331-389](), [packages/coding-agent/src/core/package-manager.ts:956-1005](), [packages/coding-agent/docs/extensions.md:92-110](), [packages/coding-agent/docs/packages.md:14-29]()

## Provider-Neutral Integration Pattern

For a Grok-Wiki-style or catalog-like integration, keep the boundary file-oriented:

1. Resolve remote/catalog selections to local files or cloned repositories.
2. Expose resources through package manifests or convention directories.
3. Preserve `SourceInfo` so UI and commands can show provenance.
4. Use `resources_discover` for dynamic session-time additions.
5. Keep model-provider setup in a separate extension or user settings path.

Sources: [packages/coding-agent/src/core/source-info.ts:3-28](), [packages/coding-agent/src/core/package-manager.ts:1985-2036](), [packages/coding-agent/src/core/extensions/types.ts:1253-1318]()

This design stays portable across local files, repositories, npm packages, git packages, and future catalog frontends because the core runtime consumes paths and metadata, not hosted-service-specific resource handles.

## Summary

Pi’s extension layer is a path-and-metadata resource system. `DefaultPackageManager` resolves sources, `DefaultResourceLoader` loads typed resources, `ExtensionRunner` binds executable extension capabilities, and `SourceInfo` preserves provenance across tools, commands, skills, prompts, and themes. The result is extensible without making repository knowledge, skill packs, or package catalogs depend on one model provider or hosted service. Sources: [packages/coding-agent/src/core/resource-loader.ts:23-37](), [packages/coding-agent/src/core/package-manager.ts:863-915](), [packages/coding-agent/src/core/extensions/runner.ts:266-333]()
