Plugins
Escribe tus propios plugins para extender OpenCode.
Los plugins te permiten extender OpenCode enganchandote a varios eventos y personalizando el comportamiento. Puedes crear plugins para agregar nuevas funciones, integrarte con servicios externos o modificar el comportamiento predeterminado de OpenCode.
Consulta los plugins creados por la comunidad como ejemplos.
Usar un plugin
Hay dos formas de cargar plugins.
Desde archivos locales
Coloca archivos JavaScript o TypeScript en el directorio de plugins.
.opencode/plugins/- Plugins a nivel de proyecto~/.config/opencode/plugins/- Plugins globales
Los archivos en estos directorios se cargan automaticamente al inicio.
Desde npm
Especifica paquetes npm en tu archivo de configuracion.
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}Se admiten tanto paquetes npm regulares como con scope.
Explora los plugins disponibles en el ecosistema.
Como se instalan los plugins
Los plugins de npm se instalan automaticamente usando Bun al inicio. Los paquetes y sus dependencias se almacenan en cache en ~/.cache/opencode/node_modules/.
Los plugins locales se cargan directamente desde el directorio de plugins. Para usar paquetes externos, debes crear un package.json dentro de tu directorio de configuracion (ver Dependencias), o publicar el plugin en npm y agregarlo a tu configuracion.
Orden de carga
Los plugins se cargan desde todas las fuentes y todos los hooks se ejecutan en secuencia. El orden de carga es:
- Configuracion global (
~/.config/opencode/opencode.json) - Configuracion del proyecto (
opencode.json) - Directorio de plugins global (
~/.config/opencode/plugins/) - Directorio de plugins del proyecto (
.opencode/plugins/)
Los paquetes npm duplicados con el mismo nombre y version se cargan una sola vez. Sin embargo, un plugin local y un plugin npm con nombres similares se cargan por separado.
Crear un plugin
Un plugin es un modulo JavaScript/TypeScript que exporta una o mas funciones de plugin. Cada funcion recibe un objeto de contexto y devuelve un objeto de hooks.
Dependencias
Los plugins locales y las herramientas personalizadas pueden usar paquetes npm externos. Agrega un package.json a tu directorio de configuracion con las dependencias que necesites.
{
"dependencies": {
"shescape": "^2.1.0"
}
}OpenCode ejecuta bun install al inicio para instalarlas. Tus plugins y herramientas pueden entonces importarlas.
import { escape } from "shescape"
export const MyPlugin = async (ctx) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "bash") {
output.args.command = escape(output.args.command)
}
},
}
}Estructura basica
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Las implementaciones de hooks van aqui
}
}La funcion del plugin recibe:
project: La informacion del proyecto actual.directory: El directorio de trabajo actual.worktree: La ruta del git worktree.client: Un cliente SDK de opencode para interactuar con la IA.$: La shell API (opens in a new tab) de Bun para ejecutar comandos.
Soporte de TypeScript
Para plugins de TypeScript, puedes importar tipos desde el paquete de plugins:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Implementaciones de hooks con seguridad de tipos
}
}Eventos
Los plugins pueden suscribirse a eventos como se muestra en la seccion de Ejemplos a continuacion. Aqui hay una lista de los diferentes eventos disponibles.
Eventos de comando
command.executed
Eventos de archivo
file.editedfile.watcher.updated
Eventos de instalacion
installation.updated
Eventos de LSP
lsp.client.diagnosticslsp.updated
Eventos de mensaje
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Eventos de permiso
permission.askedpermission.replied
Eventos de servidor
server.connected
Eventos de sesion
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Eventos de tareas
todo.updated
Eventos de Shell
shell.env
Eventos de herramientas
tool.execute.aftertool.execute.before
Eventos de TUI
tui.prompt.appendtui.command.executetui.toast.show
Ejemplos
Aqui hay algunos ejemplos de plugins que puedes usar para extender opencode.
Enviar notificaciones
Envia notificaciones cuando ocurran ciertos eventos:
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
// Enviar notificacion al completar la sesion
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}Estamos usando osascript para ejecutar AppleScript en macOS. Aqui lo usamos para enviar notificaciones.
Nota: Si estas usando la aplicacion de escritorio de OpenCode, puede enviar notificaciones del sistema automaticamente cuando una respuesta esta lista o cuando una sesion tiene un error.
Proteccion de .env
Evita que opencode lea archivos .env:
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "read" && output.args.filePath.includes(".env")) {
throw new Error("Do not read .env files")
}
},
}
}Inyectar variables de entorno
Inyecta variables de entorno en todas las ejecuciones de shell (herramientas de IA y terminales de usuario):
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}Herramientas personalizadas
Los plugins tambien pueden agregar herramientas personalizadas a opencode:
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
return {
tool: {
mytool: tool({
description: "This is a custom tool",
args: {
foo: tool.schema.string(),
},
async execute(args, context) {
const { directory, worktree } = context
return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
},
}),
},
}
}El helper tool crea una herramienta personalizada que opencode puede llamar. Toma una funcion de esquema Zod y devuelve una definicion de herramienta con:
description: Lo que hace la herramientaargs: Esquema Zod para los argumentos de la herramientaexecute: Funcion que se ejecuta cuando se llama a la herramienta
Tus herramientas personalizadas estaran disponibles en opencode junto con las herramientas integradas.
Registro de logs
Usa client.app.log() en lugar de console.log para registro estructurado:
export const MyPlugin = async ({ client }) => {
await client.app.log({
body: {
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" },
},
})
}Niveles: debug, info, warn, error. Consulta la documentacion del SDK (opens in a new tab) para mas detalles.
Hooks de compactacion
Personaliza el contexto incluido cuando se compacta una sesion:
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Inyectar contexto adicional en el prompt de compactacion
output.context.push(`
## Custom Context
Include any state that should persist across compaction:
- Current task status
- Important decisions made
- Files being actively worked on
`)
},
}
}El hook experimental.session.compacting se dispara antes de que el LLM genere un resumen de continuacion. Usalo para inyectar contexto especifico del dominio que el prompt de compactacion predeterminado podria pasar por alto.
Tambien puedes reemplazar el prompt de compactacion completamente configurando output.prompt:
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Reemplazar todo el prompt de compactacion
output.prompt = `
You are generating a continuation prompt for a multi-agent swarm session.
Summarize:
1. The current task and its status
2. Which files are being modified and by whom
3. Any blockers or dependencies between agents
4. The next steps to complete the work
Format as a structured prompt that a new agent can use to resume work.
`
},
}
}Cuando se establece output.prompt, reemplaza completamente el prompt de compactacion predeterminado. El array output.context se ignora en este caso.