smithery/sandgardenhq

opencode-plugin-development

Guide for creating and implementing plugins to extend OpenCode functionality, including hooks, custom tools, and event handling. When you need to add custom functionality to OpenCode, such as notifications, custom tools, or modifying behavior.

Installation

$ npx skills add smithery/sandgardenhq --skill opencode-plugin-development

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/sandgardenhq.

npx skills add smithery/sandgardenhq

Browse all from smithery/sandgardenhq

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Declared

Skill metadata

Parsed from SKILL.md frontmatter.

Declared agents opencode

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,783 B
  • docs SUMMARY.md 162 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

OpenCode Plugin Development

Overview

Plugins allow you to extend OpenCode by hooking into various events, adding custom tools, and customizing behavior. This skill guides you through creating plugins using JavaScript/TypeScript modules that export plugin functions.

When to Use

  • Adding new features or integrations
  • Modifying OpenCode's default behavior
  • Implementing custom tools
  • Handling specific events (e.g., notifications)
  • Protecting sensitive files

Plugin Structure

Basic Plugin Format

A plugin is a JavaScript/TypeScript module that exports one or more plugin functions. Each function receives a context object and returns a hooks object.

export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  console.log("Plugin initialized!")
  return {
    // Hook implementations go here
  }
}

Context Parameters

  • project: Current project information
  • directory: Current working directory
  • worktree: Git worktree path
  • client: OpenCode SDK client for AI interactions
  • $: Bun's shell API for executing commands

TypeScript Support

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

export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  return {
    // Type-safe hook implementations
  }
}

Plugin Location

Plugins are loaded from:

  1. .sgai/plugin directory in your project
  2. Or globally in ~/.config/opencode/plugin

Available Hooks

Event Hook

Listen for OpenCode events:

return {
  event: async ({ event }) => {
    if (event.type === "session.idle") {
      await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
    }
  }
}

Tool Hook

Add custom tools:

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, ctx) {
          return `Hello ${args.foo}!`
        },
      }),
    },
  }
}

Tool Execution Hooks

Intercept tool execution:

return {
  "tool.execute.before": async (input, output) => {
    if (input.tool === "read" && output.args.filePath.includes(".env")) {
      throw new Error("Do not read .env files")
    }
  }
}

Development Process

  1. Plan the Plugin: Determine what functionality to add and which hooks to use
  2. Create Plugin File: Write the plugin module in .sgai/plugin/
  3. Implement Hooks: Add the necessary hook functions
  4. Test Plugin: Load and test in OpenCode
  5. Handle Errors: Add proper error handling and logging

Best Practices

  • Use TypeScript for better development experience
  • Handle errors gracefully in hooks
  • Test plugins thoroughly before deployment
  • Document custom tools clearly
  • Follow OpenCode's plugin conventions

Common Patterns

Notification Plugin

Send notifications on events:

export const NotificationPlugin = async ({ $ }) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        await $`notify-send "OpenCode" "Session completed"`
      }
    }
  }
}

File Protection Plugin

Prevent access to sensitive files:

export const FileProtection = async () => {
  return {
    "tool.execute.before": async (input) => {
      const protectedPatterns = [/\.env$/, /secrets\//, /private\//]
      if (input.tool === "read" && protectedPatterns.some(p => p.test(input.args.filePath))) {
        throw new Error("Access denied to protected file")
      }
    }
  }
}

Custom Tool Plugin

Add domain-specific tools:

export const DomainTools: Plugin = async () => {
  return {
    tool: {
      analyzeCode: tool({
        description: "Analyze code for specific patterns",
        args: {
          filePath: tool.schema.string(),
          pattern: tool.schema.string()
        },
        execute: async (args) => {
          // Implementation
          return "Analysis complete"
        }
      })
    }
  }
}

Troubleshooting

  • Ensure plugin files are in the correct location
  • Check console logs for initialization errors
  • Verify hook signatures match the expected types
  • Test custom tools with simple inputs first
  • Use the OpenCode client for AI interactions when needed