Plugin Architecture
The plugin follows a four-phase initialization:src/index.ts:16
PluginContext
The OpenCode plugin context provides core APIs:src/plugin/types.ts
Plugin Interface
The plugin interface defines 8 OpenCode hook handlers:src/plugin/types.ts
Creating Custom Tools
Tools follow the factory patterncreateXXXTool() → ToolDefinition.
import { z } from "zod"
export const MyToolArgsSchema = z.object({
input: z.string().describe("Input to process"),
options: z.object({
verbose: z.boolean().optional().describe("Verbose output")
}).optional()
})
export type MyToolArgs = z.infer<typeof MyToolArgsSchema>
import type { ToolDefinition } from "@opencode-ai/plugin"
import type { PluginContext } from "../../plugin/types"
import { MyToolArgsSchema, type MyToolArgs } from "./types"
import { log } from "../../shared"
export function createMyTool(ctx: PluginContext): ToolDefinition {
return {
name: "my_tool",
description: "Process input and return result",
input_schema: MyToolArgsSchema,
execute: async (args: MyToolArgs) => {
log("my_tool: executing", { input: args.input })
try {
const result = await processInput(args.input, args.options)
return {
content: result,
metadata: {
timestamp: new Date().toISOString(),
verbose: args.options?.verbose ?? false
}
}
} catch (error) {
return {
error: `Tool execution failed: ${error.message}`,
isError: true
}
}
}
}
}
async function processInput(
input: string,
options?: { verbose?: boolean }
): Promise<string> {
// Implementation
return `Processed: ${input}`
}
import { createMyTool } from "../tools/my-tool"
export function createToolRegistry(args: {
ctx: PluginContext
pluginConfig: OhMyOpenCodeConfig
managers: Managers
skillContext: SkillContext
availableCategories: AvailableCategory[]
}): ToolRegistryResult {
const { ctx, pluginConfig } = args
const allTools: Record<string, ToolDefinition> = {
// ... existing tools
my_tool: createMyTool(ctx)
}
const filteredTools = filterDisabledTools(allTools, pluginConfig.disabled_tools)
return { filteredTools, taskSystemEnabled }
}
src/plugin/tool-registry.ts:41
Tool Registry Structure
The tool registry assembles tools from factories:src/plugin/tool-registry.ts:121
Manager System
Managers handle stateful subsystems:src/create-managers.ts
Config Handler
The config handler implements a 6-phase config pipeline:src/plugin-interface.ts
Hook System Integration
Hooks are composed and wired to the plugin interface:src/plugin-interface.ts and src/index.ts:76
Tool Execution Lifecycle
Tool execution flows through hooks:Before Hook Pattern
After Hook Pattern
Disabling Tools
Tools can be disabled via configuration:filterDisabledTools() function removes disabled tools:
Testing Tools
Test tool factories and execution:Plugin State
Manage plugin-wide state:src/plugin-state.ts
Logging
Use the shared logger:/tmp/oh-my-opencode.log
Error Handling
Follow error handling conventions:Plugin Build Pipeline
Build the plugin:dist/index.js— ESM bundledist/index.d.ts— TypeScript declarationsdist/schema.json— Configuration schema
tsconfig.json, bun.build.ts
Related Files
- Plugin Entry:
src/index.ts - Plugin Interface:
src/plugin-interface.ts - Tool Registry:
src/plugin/tool-registry.ts - Manager Creation:
src/create-managers.ts - Hook Composition:
src/create-hooks.ts - Plugin Types:
src/plugin/types.ts - Config Handler:
src/plugin-handlers/