Plugin System

Mở rộng OpenCode với plugins — hooks, tools, và integrations tùy chỉnh.


Tổng quan

Plugins cho phép bạn mở rộng OpenCode bằng cách hook vào các events và tùy chỉnh behavior. Bạn có thể tạo plugins để thêm tính năng mới, tích hợp với dịch vụ bên ngoài, hoặc sửa đổi behavior mặc định.


Sử dụng plugin

Từ local files

Đặt file JavaScript/TypeScript trong:

  • .opencode/plugins/ — Project-level
  • ~/.config/opencode/plugins/ — Global

Files được tự động load khi khởi động.

Từ npm

{
  "plugin": ["opencode-helicone-session", "opencode-wakatime"]
}

Cách cài đặt

  • npm plugins: Tự động cài bằng Bun, cache tại ~/.cache/opencode/node_modules/
  • Local plugins: Load trực tiếp, có thể dùng package.json trong thư mục config

Thứ tự load

  1. Global config → Project config → Global plugins → Project plugins

Tạo plugin

Plugin là JavaScript/TypeScript module export function:

export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  console.log("Plugin initialized!")
  return {
    // Hooks go here
  }
}

Context object

PropertyMô tả
projectThông tin project hiện tại
directoryThư mục làm việc
worktreeGit worktree path
clientSDK client để tương tác với AI
$Bun shell API

TypeScript

import type { Plugin } from "@opencode-ai/plugin"

export const MyPlugin: Plugin = async (ctx) => {
  return { /* hooks */ }
}

Events

Command

  • command.executed

File

  • file.edited, file.watcher.updated

Message

  • message.updated, message.removed

Permission

  • permission.asked, permission.replied

Session

  • session.created, session.compacted, session.deleted, session.idle, session.error

Tool

  • tool.execute.before, tool.execute.after

TUI

  • tui.prompt.append, tui.command.execute, tui.toast.show

Ví dụ

Send notifications

export const NotificationPlugin = async ({ $ }) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        await $`osascript -e 'display notification "Done!"'`
      }
    },
  }
}

.env protection

export const EnvProtection = async () => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "read" && output.args.filePath.includes(".env")) {
        throw new Error("Do not read .env files")
      }
    },
  }
}

Custom tools từ plugin

import { type Plugin, tool } from "@opencode-ai/plugin"

export const CustomToolsPlugin: Plugin = async (ctx) => {
  return {
    tool: {
      mytool: tool({
        description: "Custom tool",
        args: { foo: tool.schema.string() },
        async execute(args) {
          return `Hello ${args.foo}`
        },
      }),
    },
  }
}

Inject environment variables

export const InjectEnvPlugin = async () => {
  return {
    "shell.env": async (input, output) => {
      output.env.MY_API_KEY = "secret"
    },
  }
}

Compaction hooks

export const CompactionPlugin: Plugin = async (ctx) => {
  return {
    "experimental.session.compacting": async (input, output) => {
      output.context.push(`## Custom Context\n...`)
    },
  }
}

Logging

await client.app.log({
  body: {
    service: "my-plugin",
    level: "info",
    message: "Plugin initialized",
  },
})

Levels: debug, info, warn, error.


Xem thêm