ワンクリックで
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 ページを確認してインストールできます。
Chrome 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
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 manually