plugins.mdx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. ---
  2. title: Complementos
  3. description: Escriba sus propios complementos para extender OpenCode.
  4. ---
  5. Los complementos le permiten extender OpenCode al conectarse a varios eventos y personalizar el comportamiento. Puede crear complementos para agregar nuevas funciones, integrarlos con servicios externos o modificar el comportamiento predeterminado de OpenCode.
  6. Para ver ejemplos, consulte los [complementos](/docs/ecosystem#plugins) creados por la comunidad.
  7. ---
  8. ## Usa un complemento
  9. Hay dos formas de cargar complementos.
  10. ---
  11. ### De archivos locales
  12. Coloque los archivos JavaScript o TypeScript en el directorio del complemento.
  13. - `.opencode/plugins/` - Complementos a nivel de proyecto
  14. - `~/.config/opencode/plugins/` - Complementos globales
  15. Los archivos en estos directorios se cargan automáticamente al inicio.
  16. ---
  17. ### De npm
  18. Especifique paquetes npm en su archivo de configuración.
  19. ```json title="opencode.json"
  20. {
  21. "$schema": "https://opencode.ai/config.json",
  22. "plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
  23. }
  24. ```
  25. Se admiten paquetes npm regulares y de alcance.
  26. Explore los complementos disponibles en el [ecosistema](/docs/ecosystem#plugins).
  27. ---
  28. ### Cómo se instalan los complementos
  29. Los **complementos npm** se instalan automáticamente usando Bun al inicio. Los paquetes y sus dependencias se almacenan en caché en `~/.cache/opencode/node_modules/`.
  30. **Los complementos locales** se cargan directamente desde el directorio de complementos. Para usar paquetes externos, debe crear un `package.json` dentro de su directorio de configuración (consulte [Dependencias](#dependencies)), o publicar el complemento en npm y [agregarlo a su configuración](/docs/config#plugins).
  31. ---
  32. ### Cargar orden
  33. Los complementos se cargan desde todas las fuentes y todos los enlaces se ejecutan en secuencia. El orden de carga es:
  34. 1. Configuración global (`~/.config/opencode/opencode.json`)
  35. 2. Configuración del proyecto (`opencode.json`)
  36. 3. Directorio global de complementos (`~/.config/opencode/plugins/`)
  37. 4. Directorio de complementos del proyecto (`.opencode/plugins/`)
  38. Los paquetes npm duplicados con el mismo nombre y versión se cargan una vez. Sin embargo, un complemento local y un complemento npm con nombres similares se cargan por separado.
  39. ---
  40. ## Crear un complemento
  41. Un complemento es un módulo **JavaScript/TypeScript** que exporta uno o más complementos.
  42. funciones. Cada función recibe un objeto de contexto y devuelve un objeto de enlace.
  43. ---
  44. ### Dependencias
  45. Los complementos locales y las herramientas personalizadas pueden utilizar paquetes npm externos. Agregue un `package.json` a su directorio de configuración con las dependencias que necesita.
  46. ```json title=".opencode/package.json"
  47. {
  48. "dependencies": {
  49. "shescape": "^2.1.0"
  50. }
  51. }
  52. ```
  53. OpenCode ejecuta `bun install` al inicio para instalarlos. Luego, sus complementos y herramientas pueden importarlos.
  54. ```ts title=".opencode/plugins/my-plugin.ts"
  55. import { escape } from "shescape"
  56. export const MyPlugin = async (ctx) => {
  57. return {
  58. "tool.execute.before": async (input, output) => {
  59. if (input.tool === "bash") {
  60. output.args.command = escape(output.args.command)
  61. }
  62. },
  63. }
  64. }
  65. ```
  66. ---
  67. ### Estructura básica
  68. ```js title=".opencode/plugins/example.js"
  69. export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  70. console.log("Plugin initialized!")
  71. return {
  72. // Hook implementations go here
  73. }
  74. }
  75. ```
  76. La función del complemento recibe:
  77. - `project`: La información actual del proyecto.
  78. - `directory`: El directorio de trabajo actual.
  79. - `worktree`: La ruta del árbol de trabajo de git.
  80. - `client`: Un cliente SDK opencode para interactuar con la IA.
  81. - `$`: [shell API](https://bun.com/docs/runtime/shell) de Bun para ejecutar comandos.
  82. ---
  83. ### TypeScript soporte
  84. Para los complementos TypeScript, puede importar tipos desde el paquete de complementos:
  85. ```ts title="my-plugin.ts" {1}
  86. import type { Plugin } from "@opencode-ai/plugin"
  87. export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  88. return {
  89. // Type-safe hook implementations
  90. }
  91. }
  92. ```
  93. ---
  94. ### Eventos
  95. Los complementos pueden suscribirse a eventos como se ve a continuación en la sección Ejemplos. Aquí hay una lista de los diferentes eventos disponibles.
  96. #### Eventos de comando
  97. - `command.executed`
  98. #### Eventos de archivo
  99. - `file.edited`
  100. - `file.watcher.updated`
  101. #### Eventos de instalación
  102. - `installation.updated`
  103. #### LSP Eventos
  104. - `lsp.client.diagnostics`
  105. - `lsp.updated`
  106. #### Eventos de mensajes
  107. - `message.part.removed`
  108. - `message.part.updated`
  109. - `message.removed`
  110. - `message.updated`
  111. #### Eventos de permiso
  112. - `permission.asked`
  113. - `permission.replied`
  114. #### Eventos del servidor
  115. - `server.connected`
  116. #### Eventos de sesión
  117. - `session.created`
  118. - `session.compacted`
  119. - `session.deleted`
  120. - `session.diff`
  121. - `session.error`
  122. - `session.idle`
  123. - `session.status`
  124. - `session.updated`
  125. #### Todo Eventos
  126. - `todo.updated`
  127. #### Eventos Shell
  128. - `shell.env`
  129. #### Eventos de herramientas
  130. - `tool.execute.after`
  131. - `tool.execute.before`
  132. #### TUI Eventos
  133. - `tui.prompt.append`
  134. - `tui.command.execute`
  135. - `tui.toast.show`
  136. ---
  137. ## Ejemplos
  138. A continuación se muestran algunos ejemplos de complementos que puede utilizar para ampliar opencode.
  139. ---
  140. ### Enviar notificaciones
  141. Enviar notificaciones cuando ocurran ciertos eventos:
  142. ```js title=".opencode/plugins/notification.js"
  143. export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
  144. return {
  145. event: async ({ event }) => {
  146. // Send notification on session completion
  147. if (event.type === "session.idle") {
  148. await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
  149. }
  150. },
  151. }
  152. }
  153. ```
  154. Estamos usando `osascript` para ejecutar AppleScript en macOS. Aquí lo estamos usando para enviar notificaciones.
  155. :::note
  156. Si está utilizando la aplicación de escritorio OpenCode, puede enviar notificaciones del sistema automáticamente cuando una respuesta esté lista o cuando se produzca un error en una sesión.
  157. :::
  158. ---
  159. ### protección .env
  160. Evite que opencode lea archivos `.env`:
  161. ```javascript title=".opencode/plugins/env-protection.js"
  162. export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
  163. return {
  164. "tool.execute.before": async (input, output) => {
  165. if (input.tool === "read" && output.args.filePath.includes(".env")) {
  166. throw new Error("Do not read .env files")
  167. }
  168. },
  169. }
  170. }
  171. ```
  172. ---
  173. ### Inyectar variables de entorno
  174. Inyecte variables de entorno en toda la ejecución del shell (herramientas de inteligencia artificial y terminales de usuario):
  175. ```javascript title=".opencode/plugins/inject-env.js"
  176. export const InjectEnvPlugin = async () => {
  177. return {
  178. "shell.env": async (input, output) => {
  179. output.env.MY_API_KEY = "secret"
  180. output.env.PROJECT_ROOT = input.cwd
  181. },
  182. }
  183. }
  184. ```
  185. ---
  186. ### Herramientas personalizadas
  187. Los complementos también pueden agregar herramientas personalizadas a opencode:
  188. ```ts title=".opencode/plugins/custom-tools.ts"
  189. import { type Plugin, tool } from "@opencode-ai/plugin"
  190. export const CustomToolsPlugin: Plugin = async (ctx) => {
  191. return {
  192. tool: {
  193. mytool: tool({
  194. description: "This is a custom tool",
  195. args: {
  196. foo: tool.schema.string(),
  197. },
  198. async execute(args, context) {
  199. const { directory, worktree } = context
  200. return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
  201. },
  202. }),
  203. },
  204. }
  205. }
  206. ```
  207. El ayudante `tool` crea una herramienta personalizada a la que opencode puede llamar. Toma una función de esquema Zod y devuelve una definición de herramienta con:
  208. - `description`: Qué hace la herramienta
  209. - `args`: Esquema Zod para los argumentos de la herramienta.
  210. - `execute`: Función que se ejecuta cuando se llama a la herramienta
  211. Sus herramientas personalizadas estarán disponibles para opencode junto con las herramientas integradas.
  212. ---
  213. ### Registro
  214. Utilice `client.app.log()` en lugar de `console.log` para el registro estructurado:
  215. ```ts title=".opencode/plugins/my-plugin.ts"
  216. export const MyPlugin = async ({ client }) => {
  217. await client.app.log({
  218. body: {
  219. service: "my-plugin",
  220. level: "info",
  221. message: "Plugin initialized",
  222. extra: { foo: "bar" },
  223. },
  224. })
  225. }
  226. ```
  227. Niveles: `debug`, `info`, `warn`, `error`. Consulte la [documentación del SDK](https://opencode.ai/docs/sdk) para obtener más detalles.
  228. ---
  229. ### Ganchos de compactación
  230. Personalice el contexto incluido cuando se compacta una sesión:
  231. ```ts title=".opencode/plugins/compaction.ts"
  232. import type { Plugin } from "@opencode-ai/plugin"
  233. export const CompactionPlugin: Plugin = async (ctx) => {
  234. return {
  235. "experimental.session.compacting": async (input, output) => {
  236. // Inject additional context into the compaction prompt
  237. output.context.push(`
  238. ## Custom Context
  239. Include any state that should persist across compaction:
  240. - Current task status
  241. - Important decisions made
  242. - Files being actively worked on
  243. `)
  244. },
  245. }
  246. }
  247. ```
  248. El gancho `experimental.session.compacting` se activa antes de que LLM genere un resumen de continuación. Úselo para inyectar contexto específico del dominio que el mensaje de compactación predeterminado omitiría.
  249. También puede reemplazar completamente el mensaje de compactación configurando `output.prompt`:
  250. ```ts title=".opencode/plugins/custom-compaction.ts"
  251. import type { Plugin } from "@opencode-ai/plugin"
  252. export const CustomCompactionPlugin: Plugin = async (ctx) => {
  253. return {
  254. "experimental.session.compacting": async (input, output) => {
  255. // Replace the entire compaction prompt
  256. output.prompt = `
  257. You are generating a continuation prompt for a multi-agent swarm session.
  258. Summarize:
  259. 1. The current task and its status
  260. 2. Which files are being modified and by whom
  261. 3. Any blockers or dependencies between agents
  262. 4. The next steps to complete the work
  263. Format as a structured prompt that a new agent can use to resume work.
  264. `
  265. },
  266. }
  267. }
  268. ```
  269. Cuando se configura `output.prompt`, reemplaza completamente el mensaje de compactación predeterminado. En este caso, se ignora la matriz `output.context`.