AgentSkillsCN

create-opencode-plugin

利用@opencode-ai/plugin SDK创建OpenCode插件。无论是构建自定义工具、事件钩子、认证提供商,还是拦截工具执行流程,此功能都能助你事半功倍。在.opencode/plugin/或~/.config/opencode/plugin/目录下开发新插件时,更应主动运用此功能。 示例: - 用户输入:“创建阻止危险命令的插件” → 在钩子前置中加入拦截逻辑,防止工具被执行 - 用户输入:“为Jira添加自定义工具” → 基于SDK上下文,设计工具的Schema与实现方案 - 用户输入:“在文件编辑时弹出Toast提示” → 监听文件编辑事件,适时显示状态信息 - 用户输入:“构建自定义认证提供商” → 为新型模型提供商实现认证流程 - 用户输入:“拦截Git提交” → 在提交执行前添加钩子,对提交信息进行校验

SKILL.md
--- frontmatter
name: create-opencode-plugin
description: |-
  Create OpenCode plugins using the @opencode-ai/plugin SDK. Use for building custom tools, event hooks, auth providers, or tool execution interception. Use proactively when developing new plugins in .opencode/plugin/ or ~/.config/opencode/plugin/.
  Examples:
  - user: "Create a plugin to block dangerous commands" → implement tool execution before hook with blocking logic
  - user: "Add a custom tool for jira" → design tool schema and implementation using SDK context
  - user: "Show toast on file edit" → react to file edit events and display status message
  - user: "Build a custom auth provider" → implement auth flow for new model provider
  - user: "Intercept git commits" → add hook to validate commit messages before execution
<overview> Create OpenCode plugins using the @opencode-ai/plugin SDK for custom tools, event hooks, auth providers, or tool execution interception.

You SHOULD re-read this file periodically during plugin development to refresh context and ensure correct procedure. </overview>

<workflow> <phase name="overview">

Procedure Overview

StepActionRead
1Verify SDK referenceRun extract script
2Validate feasibilityThis file
3Design pluginreferences/hooks.md, references/hook-patterns.md, references/CODING-TS.MD
4Implementreferences/tool-helper.md (if custom tools)
5Add UI feedbackreferences/toast-notifications.md, references/ui-feedback.md (if needed)
6Testreferences/testing.md
7Publishreferences/publishing.md, references/update-notifications.md (if npm)
</phase> <phase name="verify-sdk">

Step 1: Verify SDK Reference (REQUIRED)

Before creating any plugin, you MUST regenerate the API reference to ensure accuracy:

bash
bun run .opencode/skill/create-opencode-plugin/scripts/extract-plugin-api.ts

This generates:

  • references/hooks.md - All available hooks and signatures
  • references/events.md - All event types and properties
  • references/tool-helper.md - Tool creation patterns
</phase> <phase name="validate-feasibility">

Step 2: Validate Feasibility (REQUIRED)

You MUST determine if the user's concept is achievable with available hooks.

Feasible as plugins:

  • Intercepting/blocking tool calls
  • Reacting to events (file edits, session completion, etc.)
  • Adding custom tools for the LLM
  • Modifying LLM parameters (temperature, etc.)
  • Custom auth flows for providers
  • Customizing session compaction
  • Displaying status messages (toasts, inline)

NOT feasible (inform user):

  • Modifying TUI rendering or layout
  • Adding new built-in tools (requires OC source)
  • Changing core agent behavior/prompts
  • Intercepting assistant responses mid-stream
  • Adding new keybinds or commands
  • Modifying internal file read/write
  • Adding new permission types

If not feasible, you MUST inform user clearly. Suggest:

  • OC core changes: contribute to packages/opencode
  • MCP tools: use MCP server configuration
  • Simple automation: use shell scripts
</phase> <phase name="design">

Step 3: Design Plugin

You MUST read references/hooks.md for available hooks and references/hook-patterns.md for implementation patterns.

You MUST read references/CODING-TS.MD for code architecture principles and follow these design guidelines:

  • Modular structure: Split complex plugins into multiple focused files (types, utilities, hooks, tools)
  • Single purpose: Each function does ONE thing well
  • DRY: Extract common patterns into shared utilities immediately
  • Small files: Keep individual files under 150 lines - split into smaller modules as needed
  • No monoliths: You MUST NOT put all plugin code in a single index.ts file

Plugin Locations

ScopePathUse Case
Project.opencode/plugin/<name>/index.tsTeam-shared, repo-specific
Global~/.config/opencode/plugin/<name>/index.tsPersonal, all projects

Basic Structure

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

export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  // Setup code runs once on load

  return {
    // Hook implementations - see references/hook-patterns.md
  }
}

Context Parameters

ParameterTypeDescription
projectProjectCurrent project info (id, worktree, name)
clientSDK ClientOpenCode API client
$BunShellBun shell for commands
directorystringCurrent working directory
worktreestringGit worktree path
</phase> <phase name="implement">

Step 4: Implement

You MUST read:

  • references/hook-patterns.md for hook implementation examples
  • references/tool-helper.md if adding custom tools (Zod schemas)
  • references/events.md if using event hook (event types/properties)
  • references/examples.md for complete plugin examples
  • references/CODING-TS.MD and follow modular design principles

Plugin Structure (Non-Monolithic)

For complex plugins, you MUST use a modular directory structure:

code
.opencode/plugin/my-plugin/
├── index.ts          # Entry point, exports Plugin
├── types.ts          # TypeScript types/interfaces
├── utils.ts          # Shared utilities
├── hooks/            # Hook implementations
│   ├── event.ts
│   └── tool-execute.ts
└── tools/            # Custom tool definitions
    └── my-tool.ts

Example modular index.ts:

typescript
import type { Plugin } from "@opencode-ai/plugin"
import { eventHooks } from "./hooks/event"
import { toolHooks } from "./hooks/tool-execute"
import { customTools } from "./tools"

export const MyPlugin: Plugin = async ({ project, client }) => {
  return {
    ...eventHooks({ client }),
    ...toolHooks({ client }),
    tool: customTools,
  }
}

Keep each file under 150 lines. Split as complexity grows.

Common Mistakes

MistakeFix
Using client.registerTool()Use tool: { name: tool({...}) }
Wrong event property namesCheck references/events.md
Sync event handlerYou MUST use async
Not throwing to blockthrow new Error() in tool.execute.before
Forgetting TypeScript typesimport type { Plugin } from "@opencode-ai/plugin"
</phase> <phase name="ui-feedback">

Step 5: Add UI Feedback (Optional)

Only if plugin needs user-visible notifications:

Read references/toast-notifications.md for transient alerts (brief popups).

Read references/ui-feedback.md for persistent inline status messages.

Choose based on:

NeedUse
Brief alerts, warningsToast
Detailed stats, multi-lineInline message
Config validation errorsToast
Session completion noticeToast or inline
</phase> <phase name="test">

Step 6: Test

Read references/testing.md for full testing procedure.

Quick Test Steps

  1. Create test folder with opencode.json:

    jsonc
    {
      "plugin": ["file:///path/to/your/plugin/index.ts"],
    }
    
  2. Verify plugin loads:

    bash
    cd /path/to/test-folder
    opencode run hi
    
  3. Test interactively:

    bash
    opencode
    
  4. You SHOULD recommend specific tests based on hook type used.

</phase> <phase name="publish">

Step 7: Publish (Optional)

Read references/publishing.md for npm publishing.

Read references/update-notifications.md for version update toasts (for users with pinned versions).

</phase> </workflow> <reference>

Reference Files Summary

FilePurposeWhen to Read
hooks.mdHook signatures (auto-generated)Step 3-4
events.mdEvent types (auto-generated)Step 4 (if using events)
tool-helper.mdZod tool schemas (auto-generated)Step 4 (if custom tools)
hook-patterns.mdHook implementation examplesStep 3-4
CODING-TS.MDCode architecture principlesStep 3 (Design)
examples.mdComplete plugin examplesStep 4
toast-notifications.mdToast popup APIStep 5 (if toasts needed)
ui-feedback.mdInline message APIStep 5 (if inline needed)
testing.mdTesting procedureStep 6
publishing.mdnpm publishingStep 7
update-notifications.mdVersion toast patternStep 7 (for npm plugins)
</reference>