pi-mono/packages/coding-agent/examples/extensions
Aliou Diallo 01ec6e2e7f
docs(coding-agent): fix promptGuidelines examples to name tools explicitly (#3489)
promptGuidelines bullets are appended flat to the Guidelines section
with no tool name prefix. Using 'Use this tool when...' is ambiguous
because the LLM cannot tell which tool 'this' refers to. Updated docs
and examples to use explicit tool names instead.
2026-04-21 13:07:42 +02:00
..
custom-provider-anthropic Release v0.68.0 2026-04-20 23:54:54 +02:00
custom-provider-gitlab-duo Release v0.68.0 2026-04-20 23:54:54 +02:00
custom-provider-qwen-cli Release v0.68.0 2026-04-20 23:54:54 +02:00
doom-overlay fix: quote $RESX and $RESY in doom build script (SC2086) (#2817) 2026-04-05 01:07:34 +02:00
dynamic-resources feat(coding-agent): add resources_discover hook 2026-02-01 02:20:35 +01:00
plan-mode chore(coding-agent): replace exa with eza in plan-mode extension (#3240) 2026-04-15 20:45:31 +02:00
sandbox Update sandbox extension configuration instructions (#2915) 2026-04-09 02:39:50 +02:00
subagent fix(coding-agent): do not inject bunfs script path into subagent prompts (#3002) 2026-04-14 20:33:05 +02:00
with-deps Release v0.68.0 2026-04-20 23:54:54 +02:00
antigravity-image-gen.ts fix: bump antigravity User-Agent header version (#2901) 2026-04-09 03:10:05 +02:00
auto-commit-on-exit.ts Merge hooks and custom-tools into unified extensions system (#454) 2026-01-05 01:43:35 +01:00
bash-spawn-hook.ts fix(coding-agent): align ToolDefinition.execute signature with AgentTool 2026-02-02 00:29:47 +01:00
bookmark.ts docs(coding-agent): improve extensions.md, add missing examples 2026-01-26 11:43:01 +01:00
built-in-tool-renderer.ts fix(coding-agent): stabilize edit diff previews closes #3134 2026-04-15 23:11:50 +02:00
claude-rules.ts Allow extensions to modify system prompt in before_agent_start 2026-01-08 19:54:34 +01:00
commands.ts fix(coding-agent): unify source provenance, closes #1734 2026-03-23 02:02:42 +01:00
confirm-destructive.ts Rename /branch command to /fork 2026-01-11 23:12:31 +01:00
custom-compaction.ts fix(coding-agent): resolve models.json auth per request closes #1835 2026-03-27 00:47:40 +01:00
custom-footer.ts feat(coding-agent): add FooterDataProvider for git branch and extension statuses 2026-01-09 07:39:30 -08:00
custom-header.ts feat(coding-agent): export VERSION and update custom-header example (#798) 2026-01-17 10:54:00 +01:00
dirty-repo-guard.ts Rename /branch command to /fork 2026-01-11 23:12:31 +01:00
dynamic-tools.ts docs(coding-agent): fix promptGuidelines examples to name tools explicitly (#3489) 2026-04-21 13:07:42 +02:00
event-bus.ts docs(coding-agent): improve extensions.md, add missing examples 2026-01-26 11:43:01 +01:00
file-trigger.ts Merge hooks and custom-tools into unified extensions system (#454) 2026-01-05 01:43:35 +01:00
git-checkpoint.ts Rename /branch command to /fork 2026-01-11 23:12:31 +01:00
handoff.ts fix(coding-agent): resolve models.json auth per request closes #1835 2026-03-27 00:47:40 +01:00
hello.ts add(coding-agent): add defineTool helper closes #2746 2026-04-01 23:07:14 +02:00
hidden-thinking-label.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
inline-bash.ts feat(extensions): add inline-bash example for expanding !{command} in prompts (#881) 2026-01-21 14:08:07 +01:00
input-transform.ts feat(coding-agent): add input event for extension input interception (#761) 2026-01-16 02:41:56 +01:00
interactive-shell.ts feat(coding-agent): add interactive-shell.ts extension example 2026-01-09 00:08:52 +01:00
mac-system-theme.ts Make mac-system-theme extension async to avoid blocking keyboard input 2026-01-09 00:49:31 +01:00
message-renderer.ts docs(coding-agent): improve extensions.md, add missing examples 2026-01-26 11:43:01 +01:00
minimal-mode.ts fix(coding-agent): built-in tools work like extension tools 2026-03-22 04:20:38 +01:00
modal-editor.ts fix(tui): add vertical scrolling to Editor when content exceeds terminal height 2026-01-16 04:12:21 +01:00
model-status.ts feat(coding-agent): add model_select extension hook 2026-01-11 18:12:46 +01:00
notify.ts feat(notify): add Kitty (OSC 99) and Windows Terminal support 2026-02-03 15:06:14 +01:00
overlay-qa-tests.ts feat(tui): add non-capturing overlays with focus control (#1916) 2026-03-07 14:19:16 +01:00
overlay-test.ts feat(tui): hardware cursor positioning for IME support 2026-01-16 04:30:07 +01:00
permission-gate.ts Merge hooks and custom-tools into unified extensions system (#454) 2026-01-05 01:43:35 +01:00
pirate.ts Allow extensions to modify system prompt in before_agent_start 2026-01-08 19:54:34 +01:00
preset.ts fix(coding-agent): restore verbose startup expansion 2026-04-16 21:42:57 +02:00
prompt-customizer.ts feat: Expose BuildSystemPromptOptions on before-agent-start event. (#3473) 2026-04-20 23:06:47 +02:00
protected-paths.ts Merge hooks and custom-tools into unified extensions system (#454) 2026-01-05 01:43:35 +01:00
provider-payload.ts feat(coding-agent): add after_provider_response hook closes #3128 2026-04-16 20:28:08 +02:00
qna.ts fix(coding-agent): resolve models.json auth per request closes #1835 2026-03-27 00:47:40 +01:00
question.ts fix(coding-agent): built-in tools work like extension tools 2026-03-22 04:20:38 +01:00
questionnaire.ts fix(coding-agent): built-in tools work like extension tools 2026-03-22 04:20:38 +01:00
rainbow-editor.ts fix(tui): add vertical scrolling to Editor when content exceeds terminal height 2026-01-16 04:12:21 +01:00
README.md feat(coding-agent): add configurable working indicator closes #3413 2026-04-20 16:28:39 +02:00
reload-runtime.ts feat(coding-agent): add ctx.reload and reload-runtime example closes #1371 2026-02-08 15:34:47 +01:00
rpc-demo.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
send-user-message.ts Extensions: add pi.sendUserMessage() for sending user messages 2026-01-06 13:40:24 +01:00
session-name.ts docs(coding-agent): improve extensions.md, add missing examples 2026-01-26 11:43:01 +01:00
shutdown-command.ts fix(coding-agent): align ToolDefinition.execute signature with AgentTool 2026-02-02 00:29:47 +01:00
snake.ts Revert "Remove Anthropic OAuth support" 2026-01-09 06:00:20 +01:00
space-invaders.ts feat(coding-agent): add Space Invaders example extension 2026-01-22 01:39:51 +01:00
ssh.ts fix(coding-agent): align ToolDefinition.execute signature with AgentTool 2026-02-02 00:29:47 +01:00
status-line.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
summarize.ts fix(coding-agent): resolve models.json auth per request closes #1835 2026-03-27 00:47:40 +01:00
system-prompt-header.ts feat(coding-agent): add ctx.getSystemPrompt() to extension context 2026-01-30 17:44:25 +01:00
tic-tac-toe.ts feat(agent,coding-agent): per-tool executionMode override for sequential tool execution (#3345) 2026-04-18 00:45:57 +02:00
timed-confirm.ts feat(coding-agent): add timeout option to extension dialogs with live countdown 2026-01-06 21:49:27 -08:00
titlebar-spinner.ts chore: Fix import order 2026-02-01 09:34:44 +01:00
todo.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
tool-override.ts fix(coding-agent): queue file mutations across edit and write 2026-03-20 01:55:30 +01:00
tools.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
trigger-compact.ts fix(coding-agent): unify compaction UI events closes #2617 2026-03-27 03:14:24 +01:00
truncated-tool.ts fix(coding-agent): built-in tools work like extension tools 2026-03-22 04:20:38 +01:00
widget-placement.ts refactor(coding-agent): add runtime host for session switching closes #2024 2026-03-31 13:49:57 +02:00
working-indicator.ts fix(coding-agent): remove process-cwd tool singletons and use tool-name allowlists 2026-04-20 22:05:28 +02:00

Extension Examples

Example extensions for pi-coding-agent.

Usage

# Load an extension with --extension flag
pi --extension examples/extensions/permission-gate.ts

# Or copy to extensions directory for auto-discovery
cp permission-gate.ts ~/.pi/agent/extensions/

Examples

Lifecycle & Safety

Extension Description
permission-gate.ts Prompts for confirmation before dangerous bash commands (rm -rf, sudo, etc.)
protected-paths.ts Blocks writes to protected paths (.env, .git/, node_modules/)
confirm-destructive.ts Confirms before destructive session actions (clear, switch, fork)
dirty-repo-guard.ts Prevents session changes with uncommitted git changes
sandbox/ OS-level sandboxing using @anthropic-ai/sandbox-runtime with per-project config

Custom Tools

Extension Description
todo.ts Todo list tool + /todos command with custom rendering and state persistence
hello.ts Minimal custom tool example
question.ts Demonstrates ctx.ui.select() for asking the user questions with custom UI
questionnaire.ts Multi-question input with tab bar navigation between questions
tool-override.ts Override built-in tools (e.g., add logging/access control to read)
dynamic-tools.ts Register tools after startup (session_start) and at runtime via command, with prompt snippets and tool-specific prompt guidelines
built-in-tool-renderer.ts Custom compact rendering for built-in tools (read, bash, edit, write) while keeping original behavior
minimal-mode.ts Override built-in tool rendering for minimal display (only tool calls, no output in collapsed mode)
truncated-tool.ts Wraps ripgrep with proper output truncation (50KB/2000 lines)
antigravity-image-gen.ts Generate images via Google Antigravity with optional save-to-disk modes
ssh.ts Delegate all tools to a remote machine via SSH using pluggable operations
subagent/ Delegate tasks to specialized subagents with isolated context windows

Commands & UI

Extension Description
preset.ts Named presets for model, thinking level, tools, and instructions via --preset flag and /preset command
plan-mode/ Claude Code-style plan mode for read-only exploration with /plan command and step tracking
tools.ts Interactive /tools command to enable/disable tools with session persistence
handoff.ts Transfer context to a new focused session via /handoff <goal>
qna.ts Extracts questions from last response into editor via ctx.ui.setEditorText()
status-line.ts Shows turn progress in footer via ctx.ui.setStatus() with themed colors
widget-placement.ts Shows widgets above and below the editor via ctx.ui.setWidget() placement
hidden-thinking-label.ts Customizes the collapsed thinking label via ctx.ui.setHiddenThinkingLabel()
working-indicator.ts Customizes the streaming working indicator via ctx.ui.setWorkingIndicator()
model-status.ts Shows model changes in status bar via model_select hook
snake.ts Snake game with custom UI, keyboard handling, and session persistence
tic-tac-toe.ts Tic-tac-toe vs the agent with executionMode: "sequential" tools to prevent race conditions on shared cursor state
send-user-message.ts Demonstrates pi.sendUserMessage() for sending user messages from extensions
timed-confirm.ts Demonstrates AbortSignal for auto-dismissing ctx.ui.confirm() and ctx.ui.select() dialogs
rpc-demo.ts Exercises all RPC-supported extension UI methods; pair with examples/rpc-extension-ui.ts
modal-editor.ts Custom vim-like modal editor via ctx.ui.setEditorComponent()
rainbow-editor.ts Animated rainbow text effect via custom editor
notify.ts Desktop notifications via OSC 777 when agent finishes (Ghostty, iTerm2, WezTerm)
titlebar-spinner.ts Braille spinner animation in terminal title while the agent is working
summarize.ts Summarize conversation with GPT-5.2 and show in transient UI
custom-footer.ts Custom footer with git branch and token stats via ctx.ui.setFooter()
custom-header.ts Custom header via ctx.ui.setHeader()
overlay-test.ts Test overlay compositing with inline text inputs and edge cases
overlay-qa-tests.ts Comprehensive overlay QA tests: anchors, margins, stacking, overflow, animation
doom-overlay/ DOOM game running as an overlay at 35 FPS (demonstrates real-time game rendering)
shutdown-command.ts Adds /quit command demonstrating ctx.shutdown()
reload-runtime.ts Adds /reload-runtime and reload_runtime tool showing safe reload flow
interactive-shell.ts Run interactive commands (vim, htop) with full terminal via user_bash hook
inline-bash.ts Expands !{command} patterns in prompts via input event transformation

Git Integration

Extension Description
git-checkpoint.ts Creates git stash checkpoints at each turn for code restoration on fork
auto-commit-on-exit.ts Auto-commits on exit using last assistant message for commit message

System Prompt & Compaction

Extension Description
pirate.ts Demonstrates systemPromptAppend to dynamically modify system prompt
claude-rules.ts Scans .claude/rules/ folder and lists rules in system prompt
custom-compaction.ts Custom compaction that summarizes entire conversation
trigger-compact.ts Triggers compaction when context usage exceeds 100k tokens and adds /trigger-compact command

System Integration

Extension Description
mac-system-theme.ts Syncs pi theme with macOS dark/light mode

Resources

Extension Description
dynamic-resources/ Loads skills, prompts, and themes using resources_discover

Messages & Communication

Extension Description
message-renderer.ts Custom message rendering with colors and expandable details via registerMessageRenderer
event-bus.ts Inter-extension communication via pi.events

Session Metadata

Extension Description
session-name.ts Name sessions for the session selector via setSessionName
bookmark.ts Bookmark entries with labels for /tree navigation via setLabel

Custom Providers

Extension Description
custom-provider-anthropic/ Custom Anthropic provider with OAuth support and custom streaming implementation
custom-provider-gitlab-duo/ GitLab Duo provider using pi-ai's built-in Anthropic/OpenAI streaming via proxy
custom-provider-qwen-cli/ Qwen CLI provider with OAuth device flow and OpenAI-compatible models

External Dependencies

Extension Description
with-deps/ Extension with its own package.json and dependencies (demonstrates jiti module resolution)
file-trigger.ts Watches a trigger file and injects contents into conversation

Writing Extensions

See docs/extensions.md for full documentation.

import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { Type } from "@sinclair/typebox";

export default function (pi: ExtensionAPI) {
  // Subscribe to lifecycle events
  pi.on("tool_call", async (event, ctx) => {
    if (event.toolName === "bash" && event.input.command?.includes("rm -rf")) {
      const ok = await ctx.ui.confirm("Dangerous!", "Allow rm -rf?");
      if (!ok) return { block: true, reason: "Blocked by user" };
    }
  });

  // Register custom tools
  pi.registerTool({
    name: "greet",
    label: "Greeting",
    description: "Generate a greeting",
    parameters: Type.Object({
      name: Type.String({ description: "Name to greet" }),
    }),
    async execute(toolCallId, params, onUpdate, ctx, signal) {
      return {
        content: [{ type: "text", text: `Hello, ${params.name}!` }],
        details: {},
      };
    },
  });

  // Register commands
  pi.registerCommand("hello", {
    description: "Say hello",
    handler: async (args, ctx) => {
      ctx.ui.notify("Hello!", "info");
    },
  });
}

Key Patterns

Use StringEnum for string parameters (required for Google API compatibility):

import { StringEnum } from "@mariozechner/pi-ai";

// Good
action: StringEnum(["list", "add"] as const)

// Bad - doesn't work with Google
action: Type.Union([Type.Literal("list"), Type.Literal("add")])

State persistence via details:

// Store state in tool result details for proper forking support
return {
  content: [{ type: "text", text: "Done" }],
  details: { todos: [...todos], nextId },  // Persisted in session
};

// Reconstruct on session events
pi.on("session_start", async (_event, ctx) => {
  for (const entry of ctx.sessionManager.getBranch()) {
    if (entry.type === "message" && entry.message.toolName === "my_tool") {
      const details = entry.message.details;
      // Reconstruct state from details
    }
  }
});