| name | create-pi-extension |
| description | Como criar uma extensão TypeScript para pi. Use quando o usuário precisar de hooks, tools customizadas, UI no TUI, ou persistência de estado.
|
Criando uma Extensão Pi
Extensões são módulos TypeScript que se registram no ciclo de vida do pi. Use quando skills não são suficientes.
Estrutura Mínima
extensions/minha-extension.ts
Ou como pacote:
packages/minha-extension/
├── package.json
├── index.ts
└── README.md
Template Base
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
}
Registrando uma Tool
import { Type } from "@sinclair/typebox";
pi.registerTool({
name: "minha_tool",
label: "Minha Tool",
description: "O que esta tool faz (visível ao LLM)",
parameters: Type.Object({
input: Type.String(),
}),
async execute(toolCallId, params, signal, onUpdate, ctx) {
return {
content: [{ type: "text", text: `Resultado: ${params.input}` }],
details: {},
};
},
});
Registrando um Comando
pi.registerCommand("meu-comando", {
description: "O que o /meu-comando faz",
handler: async (args, ctx) => {
ctx.ui.notify("Executado!", "info");
},
});
Eventos Comuns
pi.on("session_start", async (event, ctx) => {
});
pi.on("before_agent_start", async (event, ctx) => {
});
pi.on("tool_call", async (event, ctx) => {
});
pi.on("session_shutdown", async (event, ctx) => {
});
Empacotando como npm
{
"name": "@aretw0/minha-extension",
"keywords": ["pi-package"],
"type": "module",
"pi": {
"extensions": ["./index.ts"]
},
"peerDependencies": {
"@earendil-works/pi-coding-agent": "*",
"@earendil-works/pi-ai": "*",
"@earendil-works/pi-tui": "*",
"@sinclair/typebox": "*"
}
}
peerDependencies com "*" — o pi bundla esses pacotes, não inclua no seu tarball.
Desenvolvimento Local
- Crie a extensão em
packages/minha-extension/
- Adicione ao
.pi/settings.json:
{ "packages": ["./packages/minha-extension"] }
- Edite →
/reload → teste na mesma sessão
registerTool() aplica imediatamente, sem reload
Heurística: Quando usar o quê
| Necessidade | API |
|---|
| Tool para o LLM chamar | pi.registerTool() |
Comando /slash para o operador | pi.registerCommand() |
| Atalho de teclado | pi.registerShortcut() |
| Mensagem injetada no contexto | pi.sendMessage() |
| Widget no TUI | ctx.ui.setWidget() / ctx.ui.setStatus() |
| Diálogo com o usuário | ctx.ui.select() / ctx.ui.confirm() / ctx.ui.input() |
| Persistir estado na sessão | pi.appendEntry() + reconstruir em session_start |
| Reload após mudança | ctx.reload() dentro de um command handler |
Extensões com superfície Web (HTTP/UI)
Se a extensão incluir servidor HTTP, painel web, ou integração browser↔sessão,
use também /skill:create-pi-web-extension para seguir o contrato first-party
(mode local|lan|public, health endpoint, token auth e e2e via test-harness).
Referência Avançada
Para exemplos reais de extensões e padrões arquiteturais:
gh api repos/aretw0/agents-lab/contents/packages/pi-stack/extensions --jq '.[].name'
gh api repos/badlogic/pi-mono/contents/packages/coding-agent/examples/extensions --jq '.[].name'
Docs relevantes:
docs/research/extension-factory-blueprint.md — design da fábrica
- A documentação completa do pi está em
@earendil-works/pi-coding-agent/docs/extensions.md
- Para temas, prompts e mais: ver as skills irmãs deste pacote (
/skill:create-pi-theme, /skill:create-pi-prompt)