pi-mono/packages/coding-agent/examples/extensions
2026-04-24 01:00:41 +02:00
..
custom-provider-anthropic Release v0.70.0 2026-04-24 01:00:41 +02:00
custom-provider-gitlab-duo Release v0.70.0 2026-04-24 01:00:41 +02:00
custom-provider-qwen-cli Release v0.70.0 2026-04-24 01:00:41 +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(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02:00
with-deps Release v0.70.0 2026-04-24 01:00:41 +02:00
antigravity-image-gen.ts fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +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 fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +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
github-issue-autocomplete.ts feat(coding-agent,tui): add stacked autocomplete providers closes #2983 2026-04-22 15:44:08 +02:00
handoff.ts fix(coding-agent): handle stale extension contexts 2026-04-23 22:07:13 +02: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(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02:00
questionnaire.ts fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02: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 fix(coding-agent,tui): drop typebox compiler shim and fix progress 2026-04-22 21:12:20 +02:00
reload-runtime.ts fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02: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(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02: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
structured-output.ts fix(coding-agent,tui): drop typebox compiler shim and fix progress 2026-04-22 21:12:20 +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 fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +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 fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02:00
tool-override.ts fix(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02: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(typebox): migrate to v1 with extension compat (#3474) 2026-04-22 19:59:33 +02: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
working-message-test.ts fix(coding-agent): persist custom working message across loader recreation 2026-04-22 22:24:32 +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
structured-output.ts Final structured-output tool that returns terminate: true so the agent can end on the tool call
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
github-issue-autocomplete.ts Adds #1234 issue completions by stacking a custom autocomplete provider that preloads open issues from gh issue list
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 "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
    }
  }
});