On this page
Extensions
Extensions
#Extensions add executable capabilities to the pig coding agent using 100% pure PHP. Use an extension when a workflow requires custom Agent tools, slash commands, lifecycle hooks, custom message renderers, or interactive terminal confirmation dialogs (Terminal UI).
Extensions execute directly inside the pig process with the same permissions. They can inspect prompts, tools, files, credentials, and session histories, so load extensions only from trusted sources.
---
Create and Load an Extension
#An extension file returns a PHP closure receiving a Pig\CodingAgent\Extensions\ExtensionApi instance:
Create ~/.pig/agent/extensions/hello.php:
<?php
use Pig\CodingAgent\Extensions\ExtensionApi;
use Pig\CodingAgent\Hooks\HookContext;
return function (ExtensionApi $pig): void {
$pig->registerCommand('hello', function (string $args, HookContext $ctx): void {
$name = trim($args) !== '' ? trim($args) : 'world';
$ctx->ui->notify("Hello, {$name}!");
}, description: 'Display a friendly greeting');
};
Launch pig and run /hello. During local development, you can also load an extension on the fly:
pig --extension ./hello.php
---
Extension Locations and Conventions
#pig automatically discovers and loads extensions from:
- User Global Extensions:
~/.pig/agent/extensions/
- Single-file: ~/.pig/agent/extensions/my-ext.php
- Multi-file directory: ~/.pig/agent/extensions/my-ext/index.php
- Project Local Extensions:
<cwd>/.pig/extensions/or<cwd>/extensions/, loaded only once the project is trusted - Settings and packages: paths in the
extensionssetting and extensions of installed packages - CLI Temporary Flag:
pig --extension /path/to/ext.php - Built-in extensions:
builtin:mcp,builtin:llama.cpp,builtin:codemode, andbuiltin:tool-search, loaded from pig itself (see Settings)
A copy of a built-in extension's folder (for example ~/.pig/agent/extensions/pig-mcp) is not loaded and is reported as stale; the built-in loads instead.
Note on PHP Reload Safety:
Always use scoped closures and
HookContextstate storage. Never declare top-level global named classes or named functions inside extension files, ensuring/reloadhot-reloads cleanly without PHP fatal redeclaration crashes.
---
Core Capabilities
#1. Register Tools with the Model (registerTool)
#use Pig\CodingAgent\CustomTools\CustomTool;
use Pig\Agent\AgentToolResult;
use Pig\Ai\TextContent;
$pig->registerTool(new CustomTool(
name: 'fetch_stock_price',
label: 'Get Stock Price',
description: 'Fetch real-time stock quote for a given ticker symbol',
parameters: [
'type' => 'object',
'properties' => [
'symbol' => ['type' => 'string', 'description' => 'Ticker symbol, e.g. AAPL']
],
'required' => ['symbol']
],
execute: function ($id, $params, $onUpdate, $ctx) {
$symbol = $params['symbol'];
return new AgentToolResult([
new TextContent("Current price for {$symbol} is $230.50")
]);
}
));
Pass defaultActive: false to register a tool inactive, as codemode is: it stays off until --tools, defaultTools or setActiveTools() names it.
2. Guard Dangerous Operations (tool_call)
#Prompt for confirmation before destructive bash commands (rm -rf, git push --force):
use Pig\CodingAgent\Hooks\Results\ToolCallEventResult;
$pig->on('tool_call', function ($event, $ctx) {
if ($event->toolName === 'bash' && str_contains($event->input['command'] ?? '', 'rm -rf')) {
$allowed = $ctx->ui->confirm('⚠️ Destructive Action', 'Detected dangerous deletion. Allow execution?');
if (!$allowed) {
return new ToolCallEventResult(block: true, reason: 'User rejected destructive operation.');
}
}
return null;
});
3. Task Settlement Notification (agent_settled)
#$pig->on('agent_settled', function ($event, $ctx) {
$ctx->ui->notify('Agent task completed!');
});
4. Overrule a Cache Refresh (cache_warming_decision)
#Before each prompt cache refresh pig asks the extensions. The event carries warmCost, missCost, continuationProbability and pig's own action; return a result to change it. The last handler with an answer wins, and a handler that throws leaves pig's answer standing.
use Pig\CodingAgent\Hooks\Results\CacheWarmingDecisionEventResult;
$pig->on('cache_warming_decision', function ($event, $ctx) {
// Never pay more than a cent to keep a cache warm.
return $event->warmCost > 0.01 ? new CacheWarmingDecisionEventResult('stop') : null;
});
5. Register and Distribute Language Packs (registerLocale)
#Extensions can register complete custom language packs (e.g. Japanese, Traditional Chinese, Spanish). The Web UI automatically discovers them via /api/locales and exposes them in the Language Settings menu:
// ~/.pig/agent/extensions/pig-lang-ja/index.php
use Pig\CodingAgent\Extensions\ExtensionApi;
return function (ExtensionApi $pig): void {
$pig->registerLocale('ja', '日本語', [
'workspaces' => 'ワークスペース',
'directories' => 'ディレクトリ',
'sessions' => 'セッション',
'new_session' => '+ 新規セッション',
'placeholder' => '質問を入力するか、画像を貼り付けてください...(⌘+Enter で送信)',
'accounts' => 'アカウントとクォータ',
'copy' => 'コピー',
'copied' => 'コピーしました!',
'delete_session' => 'セッションを削除',
'rename_session' => 'セッション名を変更',
// Refer to Web UI exported JSON template for complete key lists
]);
};
---
Extension References
#- pig-computer: native macOS desktop control (screenshots, mouse, keyboard, apps) for Computer Use.
- pig-web-search: DuckDuckGo search and clean web page text extraction.
- pig-vless: a VLESS inbound beside the agent so a phone can proxy through this machine (TCP, optional TLS).
- pig-antigravity: Antigravity Code Assist quota tracking, multi-account rotation, and image generation tool.
- pig-android-use: control a physical or emulated Android device over ADB (
android_*tools and/android).
The extensions that are not built in are copied into ~/.pig/agent/extensions/ by pig update --extensions.