Skip to main content

Extensibility System

Pi’s extensibility system allows you to customize and extend its behavior without forking the codebase. The system provides four primary extension mechanisms: Extensions, Skills, Prompt Templates, and Themes.

Extension Mechanisms


Extensions

Extensions are TypeScript or JavaScript modules that receive full access to the agent’s lifecycle, allowing you to:
  • Subscribe to lifecycle events
  • Register LLM-callable tools
  • Add slash commands
  • Define keyboard shortcuts
  • Customize the UI
  • Modify context before LLM calls
  • Intercept tool executions

Extension Structure

An extension is a module that exports a factory function:

Discovery and Loading

Extensions are discovered from:
  1. Global: ~/.pi/agent/extensions/
  2. Project: .pi/extensions/
  3. Explicit: --extension path/to/extension.ts
Discovery rules:
  • Direct .ts or .js files in the extensions directory
  • Subdirectories with index.ts or index.js
  • Subdirectories with package.json containing a pi.extensions field

Extension API Reference

The ExtensionAPI provides methods for registering functionality and accessing the agent:

Event Subscription

Key event types:
  • session_start, session_switch, session_compact
  • agent_start, agent_end
  • turn_start, turn_end
  • message_start, message_update, message_end
  • tool_execution_start, tool_execution_update, tool_execution_end
  • tool_call, tool_result (interceptors)
  • context (modify messages before LLM)
  • model_select, input

Tool Registration

Command Registration

Keyboard Shortcuts

UI Customization

Provider Registration

Extension Context

The context object (ctx) passed to event handlers provides:

Extension Patterns


Skills

Skills are markdown files that provide task-specific instructions to the agent. They’re discovered automatically and presented in the system prompt or loaded explicitly via /skill commands.

Skill Structure

  1. Commit messages: Use conventional commits format
    • feat: New feature
    • fix: Bug fix
    • docs: Documentation
    • refactor: Code restructuring
  2. Before pushing: Review changes
Subdirectories:

Skill Frontmatter

disable-model-invocation: When true, the skill is NOT automatically added to the system prompt. It can only be loaded explicitly via /skill:name commands. Useful for:
  • Large reference documents
  • Context-specific guides
  • Skills that conflict with default behavior

Using Skills

Automatic loading: Skills are presented in the system prompt:
Manual invocation: Extensions can check for and load skills:

Prompt Templates

Prompt templates are reusable prompts with argument substitution. They’re useful for frequently used prompts or standardized workflows.

Template Structure

Template Syntax

Positional arguments: $1, $2, $3, … All arguments: $@ or $ARGUMENTS Argument slicing: ${@:N} or ${@:N:L}
  • ${@:2}: All arguments from 2nd onwards
  • ${@:2:3}: 3 arguments starting from 2nd

Template Discovery

Templates are loaded from:
  1. Global: ~/.pi/agent/prompts/
  2. Project: .pi/prompts/
  3. Explicit: --prompt path/to/template.md
Usage:

Themes

Themes customize the visual appearance of Pi’s TUI. They’re JSON files that define colors and styles.

Theme Structure

Theme Discovery

Themes are loaded from:
  1. Global: ~/.pi/agent/themes/
  2. Project: .pi/themes/
  3. Built-in: Shipped with pi-coding-agent
Usage:

Pi Packages

Pi packages bundle extensions, skills, prompts, and themes into a single npm package for distribution.

Package Structure

Installation

Creating a Package

1

Initialize package

2

Add package.json pi field

3

Create extension

4

Build and publish


Extension Loading

Extensions are loaded using jiti, a just-in-time TypeScript compiler. This enables:
  • Writing extensions in TypeScript without pre-compilation
  • Hot module reloading during development
  • Support for ES modules and CommonJS
  • Automatic dependency resolution

Module Resolution

Extensions have access to bundled packages:
  • @mariozechner/pi-coding-agent
  • @mariozechner/pi-agent-core
  • @mariozechner/pi-ai
  • @mariozechner/pi-tui
  • @sinclair/typebox
Example:

Error Handling

Extension errors are caught and logged without crashing Pi:
Check ~/.pi/agent/logs/ for detailed error logs.

Best Practices

  • Keep extensions focused on a single responsibility
  • Use event handlers for observation, tools for capabilities
  • Provide clear descriptions for commands and tools
  • Handle errors gracefully (extensions shouldn’t crash Pi)
  • Use TypeScript for type safety
  • Write clear, actionable instructions
  • Include code examples where relevant
  • Keep skills focused on a specific task or domain
  • Use descriptive names (lowercase, hyphens)
  • Test skills by invoking manually first
  • Use positional args for required parameters
  • Use $ARGUMENTS for optional/flexible content
  • Provide good default behavior
  • Include examples in the description
  • Avoid expensive operations in frequently-called event handlers
  • Use onUpdate for streaming tool results
  • Debounce UI updates if needed
  • Clean up resources in dispose() methods

Next Steps

Architecture

Understand the overall system design

Packages

Explore package capabilities