플러그인
플러그인을 사용하면 다양한 이벤트에 후킹하고 동작을 사용자 정의하여 OpenCode를 확장할 수 있습니다. 새로운 기능을 추가하거나, 외부 서비스와 통합하거나, OpenCode의 기본 동작을 수정하는 플러그인을 만들 수 있습니다.
예제는 커뮤니티에서 만든 플러그인을 확인하세요.
플러그인 사용
플러그인을 로드하는 방법에는 두 가지가 있습니다.
로컬 파일에서
JavaScript 또는 TypeScript 파일을 플러그인 디렉토리에 배치하세요.
.opencode/plugins/- 프로젝트 레벨 플러그인~/.config/opencode/plugins/- 전역 플러그인
이 디렉토리의 파일은 시작 시 자동으로 로드됩니다.
npm에서
설정 파일에 npm 패키지를 지정하세요.
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}
일반 npm 패키지와 스코프가 있는 npm 패키지 모두 지원됩니다.
ecosystem에서 사용 가능한 플러그인을 찾아보세요.
플러그인 설치 방법
npm 플러그인은 시작 시 Bun을 사용하여 자동으로 설치됩니다. 패키지와 그 의존성은 ~/.cache/opencode/node_modules/에 캐시됩니다.
로컬 플러그인은 플러그인 디렉토리에서 직접 로드됩니다. 외부 패키지를 사용하려면 설정 디렉토리 내에 package.json을 만들어야 합니다(의존성 참조), 또는 플러그인을 npm에 게시하고 설정에 추가하세요.
로드 순서
플러그인은 모든 소스에서 로드되며 모든 후크가 순차적으로 실행됩니다. 로드 순서는:
- 전역 설정 (
~/.config/opencode/opencode.json) - 프로젝트 설정 (
opencode.json) - 전역 플러그인 디렉토리 (
~/.config/opencode/plugins/) - 프로젝트 플러그인 디렉토리 (
.opencode/plugins/)
동일한 이름과 버전의 중복 npm 패키지는 한 번만 로드됩니다. 그러나 로컬 플러그인과 유사한 이름의 npm 플러그인은 별도로 로드됩니다.
플러그인 만들기
플러그인은 하나 이상의 플러그인 함수를 내보내는 JavaScript/TypeScript 모듈입니다. 각 함수는 컨텍스트 객체를 받아 후크 객체를 반환합니다.
의존성
로컬 플러그인과 커스텀 도구는 외부 npm 패키지를 사용할 수 있습니다. 필요한 의존성을 설정 디렉토리의 package.json에 추가하세요.
{
"dependencies": {
"shescape": "^2.1.0"
}
}
OpenCode는 시작 시 bun install을 실행하여 이를 설치합니다. 그런 다음 플러그인과 도구에서 가져올 수 있습니다.
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)
}
},
}
}
기본 구조
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}
플러그인 함수는 다음을 받습니다:
project: 현재 프로젝트 정보.directory: 현재 작업 디렉토리.worktree: git worktree 경로.client: AI와 상호작용하기 위한 opencode SDK 클라이언트.$: 명령을 실행하기 위한 Bun의 shell API.
TypeScript 지원
TypeScript 플러그인의 경우 플러그인 패키지에서 타입을 가져올 수 있습니다:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}
이벤트
플러그인은 예제 섹션에서 볼 수 있듯이 이벤트를 구독할 수 있습니다. 다음은 사용 가능한 다양한 이벤트의 목록입니다.
Command Events
command.executed
File Events
file.editedfile.watcher.updated
Installation Events
installation.updated
LSP Events
lsp.client.diagnosticslsp.updated
Message Events
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Permission Events
permission.askedpermission.replied
Server Events
server.connected
Session Events
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Todo Events
todo.updated
Shell Events
shell.env
Tool Events
tool.execute.aftertool.execute.before
TUI Events
tui.prompt.appendtui.command.executetui.toast.show
예제
다음은 opencode를 확장하는 데 사용할 수 있는 플러그인의 예입니다.
알림 보내기
특정 이벤트가 발생할 때 알림을 보냅니다:
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"'`
}
},
}
}
macOS에서 AppleScript를 실행하기 위해 osascript를 사용하고 있습니다. 여기서는 알림을 보내는 데 사용하고 있습니다.
.env 보호
opencode가 .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")
}
},
}
}
환경 변수 주입
모든 셸 실행(AI 도구 및 사용자 터미널)에 환경 변수를 주입합니다:
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}
커스텀 도구
플러그인은 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})`
},
}),
},
}
}
tool 헬퍼는 opencode가 호출할 수 있는 커스텀 도구를 만듭니다. Zod 스키마 함수를 받아 다음을 가진 도구 정의를 반환합니다:
description: 도구가 수행하는 작업args: 도구의 인수에 대한 Zod 스키마execute: 도구가 호출될 때 실행되는 함수
커스텀 도구는 내장 도구와 함께 opencode에서 사용할 수 있습니다.
로깅
구조화된 로깅을 위해 console.log 대신 client.app.log()를 사용하세요:
export const MyPlugin = async ({ client }) => {
await client.app.log({
body: {
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" },
},
})
}
레벨: debug, info, warn, error. 자세한 내용은 SDK 문서를 참조하세요.
압축 후크
세션이 압축될 때 포함되는 컨텍스트를 사용자 정의합니다:
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
`)
},
}
}
experimental.session.compacting 후크는 LLM이 계속 요약을 생성하기 전에 실행됩니다. 기본 압축 프롬프트가 놓칠 수 있는 도메인별 컨텍스트를 주입하는 데 사용하세요.
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.
`
},
}
}
output.prompt가 설정되면 기본 압축 프롬프트를 완전히 대체합니다. 이 경우 output.context 배열은 무시됩니다.