Plugins
Escribe tus propios plugins para extender OpenCode.
Los plugins te permiten extender OpenCode enganchándote a varios eventos y personalizando el comportamiento. Puedes crear plugins para agregar nuevas funciones, integrarte con servicios externos o modificar el comportamiento por defecto de OpenCode.
Para ver ejemplos, consulta los plugins creados por la comunidad.
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 automáticamente al iniciar.
Desde npm
Especifica paquetes de npm en tu archivo de configuración.
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}Se admiten tanto los paquetes de npm normales como los scoped.
Explora los plugins disponibles en el ecosistema.
Cómo se instalan los plugins
Los plugins de npm se instalan automáticamente usando Bun al iniciar. Los paquetes y sus dependencias se almacenan en caché 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 configuración (consulta Dependencias) o publicar el plugin en npm y agregarlo a tu configuración.
Orden de carga
Los plugins se cargan desde todas las fuentes y todos los hooks se ejecutan en secuencia. El orden de carga es:
- Configuración global (
~/.config/opencode/opencode.json) - Configuración del proyecto (
opencode.json) - Directorio global de plugins (
~/.config/opencode/plugins/) - Directorio de plugins del proyecto (
.opencode/plugins/)
Los paquetes de npm duplicados con el mismo nombre y versión se cargan una sola vez. Sin embargo, un plugin local y un plugin de npm con nombres similares se cargan ambos por separado.
Crear un plugin
Un plugin es un módulo de JavaScript/TypeScript que exporta una o más funciones de plugin. Cada función recibe un objeto de contexto y devuelve un objeto de hooks.
Dependencias
Los plugins locales y las herramientas personalizadas pueden usar paquetes externos de npm. Agrega un package.json a tu directorio de configuración con las dependencias que necesites.
{
"dependencies": {
"shescape": "^2.1.0"
}
}OpenCode ejecuta bun install al iniciar 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 básica
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}La función del plugin recibe:
project: La información del proyecto actual.directory: El directorio de trabajo actual.worktree: La ruta del git worktree.client: Un cliente del SDK de opencode para interactuar con la IA.$: La API de shell (opens in a new tab) de Bun para ejecutar comandos.
Soporte de TypeScript
Para los plugins de TypeScript, puedes importar tipos del paquete del plugin:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}Eventos
Los plugins pueden suscribirse a eventos como se ve más abajo en la sección de Ejemplos. Aquí tienes una lista de los distintos eventos disponibles.
Eventos de comandos
command.executed
Eventos de archivos
file.editedfile.watcher.updated
Eventos de instalación
installation.updated
Eventos de LSP
lsp.client.diagnosticslsp.updated
Eventos de mensajes
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Eventos de permisos
permission.askedpermission.replied
Eventos del servidor
server.connected
Eventos de sesión
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Eventos de todo
todo.updated
Eventos de shell
shell.env
Eventos de herramientas
tool.execute.aftertool.execute.before
Eventos de la TUI
tui.prompt.appendtui.command.executetui.toast.show
Ejemplos
Aquí tienes algunos ejemplos de plugins que puedes usar para extender opencode.
Enviar notificaciones
Envía notificaciones cuando ocurren ciertos eventos:
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
// Send notification on session completion
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}Estamos usando osascript para ejecutar AppleScript en macOS. Aquí lo usamos para enviar notificaciones.
Nota: Si usas la aplicación de escritorio de OpenCode, esta puede enviar notificaciones del sistema automáticamente cuando una respuesta está lista o cuando una sesión falla.
Protección de .env
Evita que opencode lea los 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 también 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 invocar. Toma una función de esquema de Zod y devuelve una definición de herramienta con:
description: Qué hace la herramientaargs: Esquema de Zod para los argumentos de la herramientaexecute: Función que se ejecuta cuando se invoca la herramienta
Tus herramientas personalizadas estarán disponibles para opencode junto con las herramientas integradas.
Nota: Si una herramienta de un plugin usa el mismo nombre que una herramienta integrada, la herramienta del plugin tiene prioridad.
Logging
Usa client.app.log() en lugar de console.log para un logging 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 documentación del SDK (opens in a new tab) para más detalles.
Hooks de compactación
Personaliza el contexto que se incluye cuando se compacta una sesión:
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Inject additional context into the compaction prompt
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 activa antes de que el LLM genere un resumen de continuación. Úsalo para inyectar contexto específico del dominio que el prompt de compactación por defecto pasaría por alto.
También puedes reemplazar el prompt de compactación por completo estableciendo output.prompt:
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
// Replace the entire compaction prompt
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 por completo el prompt de compactación por defecto. En este caso, el array output.context se ignora.