원클릭으로
opencode-plugin-dev
OpenCode plugin development guidance including structure, events, tools, patterns, and best practices
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
OpenCode plugin development guidance including structure, events, tools, patterns, and best practices
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | opencode-plugin-dev |
| description | OpenCode plugin development guidance including structure, events, tools, patterns, and best practices |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"developers","category":"development"} |
A plugin is a JavaScript/TypeScript module that extends OpenCode by hooking into events, adding custom tools, and modifying behavior. Plugins can integrate with external services, enforce policies, and automate workflows.
A plugin exports one or more functions that receive a context object and return a hooks object:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Hook implementations
}
}
Plugins receive:
project: Current project informationdirectory: Current working directoryworktree: Git worktree pathclient: OpenCode SDK client for AI interaction$: Bun's shell API for executing commandstool.execute.before: Before any tool executestool.execute.after: After any tool executessession.created: New session createdsession.updated: Session metadata updatedsession.deleted: Session deletedsession.status: Session status changessession.error: Session errorssession.idle: Session becomes idlesession.compacted: Session compactedsession.diff: Session diff generatedmessage.updated: Message content changedmessage.removed: Message deletedmessage.part.updated: Message part changedmessage.part.removed: Message part deletedfile.edited: File modifiedfile.watcher.updated: File watcher detected changecommand.executed: Slash command executedserver.connected: Client connected to serverpermission.updated: Permissions changedpermission.replied: Permission request responded totui.prompt.append: Text appended to prompttui.command.execute: Command executedtui.toast.show: Toast notification showninstallation.updated: Installation status changedlsp.client.diagnostics: LSP diagnostics availablelsp.updated: LSP status updatedtodo.updated: Todo list changedPlace files in:
.opencode/plugins/ - Project-level~/.config/opencode/plugins/ - GlobalAdd to opencode.json:
{
"plugin": ["my-plugin", "@scope/custom-plugin"]
}
Local plugins can use npm packages. Create .opencode/package.json:
{
"dependencies": {
"shescape": "^2.1.0"
}
}
OpenCode runs bun install at startup to install dependencies.
import { type Plugin, tool } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async (ctx) => {
return {
tool: {
mytool: tool({
description: "Tool description",
args: {
foo: tool.schema.string().describe("Parameter"),
},
async execute(args, ctx) {
return `Hello ${args.foo}!`
},
}),
},
}
}
<filename>_<exportname> (e.g., math_add)Tools receive:
agent: Agent IDsessionID: Current session IDmessageID: Current message IDimport { tool } from "@opencode-ai/plugin"
export const add = tool({
description: "Add two numbers",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number"),
},
async execute(args) {
return args.a + args.b
},
})
export const multiply = tool({
description: "Multiply two numbers",
args: {
a: tool.schema.number(),
b: tool.schema.number(),
},
async execute(args) {
return args.a * args.b
},
})
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")
}
},
}
}
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
},
}
}
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 ({ client }) => {
await client.app.log({
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" },
})
return {}
}
Log levels: debug, info, warn, error
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
output.context.push(`
## Custom Context
- Current task status
- Important decisions made
- Files being actively worked on
`)
},
}
}
import type { Plugin } from "@opencode-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
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
`
},
}
}
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe implementations
}
}
import { z } from "zod"
export default {
description: "Tool description",
args: {
param: z.string().describe("Parameter description"),
},
async execute(args, context) {
return "result"
},
}
Plugins load in this order:
~/.config/opencode/opencode.json)opencode.json)~/.config/opencode/plugins/).opencode/plugins/)Duplicate npm packages with same name and version load once. Local and npm plugins with similar names load separately.
{
"name": "opencode-my-plugin",
"version": "1.0.0",
"type": "module",
"exports": {
".": "./dist/index.js",
"./package.json": "./package.json"
},
"peerDependencies": {
"@opencode-ai/plugin": "*"
}
}
# TypeScript
npm install typescript @types/node
npx tsc
# Or use Bun
bun build ./src/index.ts --outdir ./dist --target node
npm login
npm publish
Users install via:
{
"plugin": ["opencode-my-plugin"]
}
Always throw descriptive errors:
"tool.execute.before": async (input, output) => {
if (someCondition) {
throw new Error("Descriptive error message")
}
}
await for async operationsUse structured logging:
await client.app.log({
service: "my-plugin",
level: "debug",
message: "Debug information",
extra: { input, output },
})
opencode.json.opencode/package.jsonbun install manuallyChrome DevTools automation for browser testing, debugging, and performance analysis
Clojure development workflows including REPL, deps.edn, testing, and linting
Docker Compose orchestration for multi-container applications
Full stack integration patterns connecting Clojure backend and React frontend
Git workflow management including branching, commits, PRs, and conflict resolution
PM2 process management for Node.js applications in production