Desenvolvimento de Plugins do Zero
Avançado⏱60 min📖2 min de leituraLição 1 de 5

Desenvolvimento de Plugins do Zero

Crie plugins personalizados do OpenCode do zero. Aprenda a arquitetura de plugins, eventos de ciclo de vida, API surface e como criar plugins que estendem as capacidades do OpenCode.

Arquitetura de Plugins

Plugins são pacotes Node.js que estendem a funcionalidade do OpenCode:

.opencode/plugins/my-plugin/ ├── package.json ├── src/ │ └── index.ts ├── assets/ ├── examples/ ├── references/ └── scripts/

Ciclo de Vida do Plugin

100%
Fase
Descrição
Load
O plugin é descoberto e carregado
Initialize
O plugin configura recursos
Register
Os handlers de eventos são registrados
Active
O plugin escuta eventos
Shutdown
Limpeza e liberação de recursos

Criando um Plugin

Passo 1: Inicializar o Pacote

bash
mkdir -p .opencode/plugins/code-metrics cd .opencode/plugins/code-metrics npm init -y

Passo 2: Criar o Entry do Plugin

Crie src/index.ts:

typescript
import { Plugin, PluginContext } from "opencode"; export default class CodeMetricsPlugin implements Plugin { name = "code-metrics"; version = "1.0.0"; async initialize(context: PluginContext) { console.log("Code Metrics plugin initialized"); } async onFileWrite(filePath: string, content: string) { const lines = content.split("\n").length; const bytes = Buffer.byteLength(content); console.log(`File written: ${filePath}`); console.log(` Lines: ${lines}`); console.log(` Bytes: ${bytes}`); return { lines, bytes }; } async onToolExecute(tool: string, args: any, result: any) { // Log tool usage metrics return { tool, timestamp: Date.now(), success: !result.error }; } async shutdown() { console.log("Code Metrics plugin shutting down"); } }

Passo 3: Registrar o Plugin

Adicione ao opencode.json:

json
{ "plugins": { "code-metrics": { "path": ".opencode/plugins/code-metrics", "enabled": true } } }

API Surface do Plugin

Eventos Disponíveis

Evento
Parâmetros
Retorno
session.start
sessionId
void
session.end
sessionId
void
file.read
path, content
content
file.write
path, content
content
file.edit
path, old, new
new
tool.execute.before
tool, args
args
tool.execute.after
tool, args, result
result
agent.route
request, agent
agent

Métodos do Context

typescript
context.log(message: string, level: "info" | "warn" | "error"); context.getConfig(key: string): any; context.setConfig(key: string, value: any): void; context.getMemory(key: string): any; context.setMemory(key: string, value: any): void;

Exemplo: Plugin de Scanner de Segurança

typescript
import { Plugin, PluginContext } from "opencode"; const DANGEROUS_PATTERNS = [ /eval\s*\(/, /new\s+Function\s*\(/, /process\.exit/, /require\s*\(\s*['"]child_process['"]\s*\)/, ]; export default class SecurityScannerPlugin implements Plugin { name = "security-scanner"; version = "1.0.0"; async onFileWrite(path: string, content: string) { const warnings: string[] = []; for (const pattern of DANGEROUS_PATTERNS) { if (pattern.test(content)) { warnings.push(`Potentially dangerous pattern: ${pattern.source}`); } } if (warnings.length > 0) { console.warn(`Security warnings for ${path}:`); warnings.forEach(w => console.warn(` - ${w}`)); } return { warnings }; } }

Testando Plugins

Testes Unitários

typescript
import CodeMetricsPlugin from "../src/index"; describe("CodeMetricsPlugin", () => { let plugin: CodeMetricsPlugin; beforeEach(() => { plugin = new CodeMetricsPlugin(); }); it("should count lines correctly", async () => { const result = await plugin.onFileWrite("test.ts", "line1\nline2\nline3"); expect(result.lines).toBe(3); }); it("should count bytes correctly", async () => { const result = await plugin.onFileWrite("test.ts", "hello"); expect(result.bytes).toBe(5); }); });

Testes de Integração

bash
npm test

Melhores Práticas

Prática
Motivo
Responsabilidade única
Um plugin, um propósito
Tratamento de erros
Degradation graciosa
Performance
Não bloquear a thread principal
Logging
Informações úteis de debug
Configuração
Tornar o comportamento ajustável

Perguntas de Prática (Practice Questions)

Questão de Prática
Como responder

Questão de múltipla escolha com 4 opções. Selecione uma opção e escolha Verificar resposta.

Qual é a primeira fase no ciclo de vida do plugin?

Questão de Prática
Como responder

Questão de múltipla escolha com 4 opções. Selecione uma opção e escolha Verificar resposta.

Qual evento dispara antes de um arquivo ser escrito?

Questão de Prática
Como responder

Questão de múltipla escolha com 4 opções. Selecione uma opção e escolha Verificar resposta.

Onde os plugins devem ser registrados?

Questão de Prática
Como responder

Questão de múltipla escolha com 4 opções. Selecione uma opção e escolha Verificar resposta.

O que um plugin deve fazer durante o shutdown?

Questão de Prática
Como responder

Questão de múltipla escolha com 4 opções. Selecione uma opção e escolha Verificar resposta.

Como os plugins acessam a configuração?


✅Sucesso

Key Takeaways

  • Plugins são pacotes Node.js que estendem a funcionalidade do OpenCode
  • O ciclo de vida inclui as fases Load, Initialize, Register, Active e Shutdown
  • Use o evento file.write para validar ou transformar o conteúdo antes de salvar
  • Registre plugins no opencode.json sob a chave plugins
  • Siga o princípio de responsabilidade única para o design de plugins
  • Sempre limpe recursos durante o shutdown
  • Teste plugins com testes unitários e de integração
Progresso20%