writing-opencode-plugins
OpenCode plugins, @opencode-ai/plugin, @opencode-ai/plugin/tui, plugin hooks, custom tools, TUI routes, slots, keymaps, and packaging. Use when creating, editing, reviewing, testing, or publishing server or TUI plugins for OpenCode.
- 0
- Installs
- —
- Rating
- —
- Success rate
- 4
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 7e802baf127e09e6… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
Writing OpenCode Plugins
Use this skill to implement production-quality OpenCode plugins. Treat the repository's exported types and runtime as authoritative because plugin APIs are evolving and public docs may lag.
Start Here
- Decide which runtime owns the feature.
- Read the relevant public type before writing code.
- Find one focused in-repository example using the same API.
- Implement the smallest target-specific module.
- Test loading, behavior, failure, and cleanup in the owning package.
| Need | Plugin target | Import | Configuration |
|---|---|---|---|
| Hooks, tools, auth, providers, model parameters, shell environment | Server | @opencode-ai/plugin | opencode.json or auto-discovered .opencode/plugins/*.{ts,js} |
| Commands, keybindings, routes, dialogs, slots, themes, notifications | TUI | @opencode-ai/plugin/tui | Explicit tui.json plugin entry |
| Both | Two target-only entrypoints | Both imports in separate files | Package exports ./server and ./tui |
Never export server and tui from the same module. Do not use server event hooks as a substitute for interactive TUI APIs.
Verify The Current Contract
Read these files before implementing unfamiliar behavior:
packages/plugin/src/index.ts: authoritative server plugin and hook types.packages/plugin/src/tool.ts: custom tool schema, context, permission, metadata, attachments, and result types.packages/plugin/src/tui.ts: authoritative TUI API and module types.packages/opencode/specs/tui-plugins.md: TUI loading, packaging, lifecycle, and API semantics.packages/opencode/src/plugin/shared.ts: target validation, IDs, and entrypoint resolution.packages/opencode/src/plugin/loader.ts: install, compatibility, and import behavior.
If these disagree with examples or website docs, follow exported types and runtime behavior, then update stale documentation when appropriate.
Choose A Module Shape
Prefer the explicit module object for new server plugins:
import type { Plugin, PluginModule } from '@opencode-ai/plugin';
const server: Plugin = async ({ client, directory }, options) => ({
dispose: async () => {},
});
export default {
id: 'acme.example',
server,
} satisfies PluginModule & { id: string };
Legacy server-only local plugins may export a plugin function directly. In a legacy module every distinct named export is interpreted as a plugin, so do not export unrelated constants. Prefer a default module object for new code.
TUI plugins always use a default module object:
/** @jsxImportSource @opentui/solid */
import type { TuiPlugin, TuiPluginModule } from '@opencode-ai/plugin/tui';
const tui: TuiPlugin = async (api) => {
api.ui.toast({ message: 'Plugin loaded' });
};
export default {
id: 'acme.example-tui',
tui,
} satisfies TuiPluginModule & { id: string };
File plugins require a stable, non-empty id. npm plugins may derive the ID from the package name, but an explicit namespaced ID makes state, diagnostics, and collision handling clearer.
Engineering Rules
- Use TypeScript and
satisfiesagainst the public plugin type. - Parse and validate
options; they arrive as unvalidatedRecord<string, unknown>. - Namespace plugin IDs, command IDs, route names, modes, slot names, and shared KV keys.
- Use the directory supplied by the plugin or tool context, not
process.cwd(). - Honor
AbortSignalfor long-running or cancellable work. - Use
client.app.log()for structured server logging instead ofconsole.log. - Request permission before sensitive or consequential custom-tool work.
- Keep notifications privacy-safe; do not expose prompts, secrets, paths, commands, or raw errors.
- Register only needed hooks and UI resources. Avoid broad event subscriptions when a specific hook exists.
- Make cleanup bounded, idempotent, and safe after partial initialization.
- Do not depend on undocumented load order to resolve ownership conflicts.
Testing Workflow
Server plugin tests belong under packages/opencode/test/plugin/ or the closest owning subsystem. TUI runtime tests belong under packages/opencode/test/cli/tui/; component-level TUI tests may belong in packages/tui.
Test at least:
- valid loading and target/entrypoint selection;
- configured options and malformed options;
- the observable behavior, not a duplicate of implementation logic;
- abort, failure, and partial-initialization behavior;
- cleanup or disposal;
- duplicate IDs or registrations when relevant;
- local file and npm packaging behavior when publishing.
Run tests from the package directory, never the repository root. Use bun typecheck from the owning package for type checking.
Review Checklist
- The feature is in the correct server or TUI runtime.
- Module shape and import path match the target.
- Server and TUI entrypoints are separate.
- IDs and persistent keys are stable and namespaced.
- Options and external data are validated.
- Hook output mutation preserves other plugins' changes.
- Tools use context directory, permission, metadata, and abort correctly.
- TUI keybindings are mode-gated unless intentionally global.
- TUI resources and custom side effects are disposed.
- Package exports,
engines.opencode, and config target are correct. - Tests cover behavior and lifecycle.
References
- Server plugins: hooks, custom tools, lifecycle, and examples.
- TUI plugins: keymaps, routes, dialogs, slots, state, and lifecycle.
- Packaging and testing: config, package exports, compatibility, and test locations.
Files
4- SKILL.md
f9687fb8ab6.3 KB - references/packaging-testing.md
25441e45f44.9 KB - references/server-plugins.md
581f87451b5.4 KB - references/tui-plugins.md
d7d2ab40926.1 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from sveltejs/ai-tools3
CLI tools for Svelte 5 documentation lookup and code analysis. MUST be used whenever creating, editing or analyzing any Svelte component (.svelte) or Svelte module (.svelte.ts/.svelte.js). If possible, this skill should be executed within the svelte-file-editor agent for optimal results.
Guidance on writing fast, robust, modern Svelte code. Load this skill whenever in a Svelte project and asked to write/edit or analyze a Svelte component or module. Covers reactivity, event handling, styling, integration with libraries and more.
Reference for writing and editing skills well — the vocabulary and principles that make a skill predictable.
Related ai-ml skillsscan passed
Install and operate Everything Claude Code (ECC) on the DeepSeek Harness (DSH): native skill roots (~/.dsh/skills, .agents/skills), the @deepseek-ai/dsh-hooks-claude-code bridge for command hooks, bare-insert patch mounting, generator usage, event-support limits, and update workflow. Use when settin
Pair a remote AI agent with your browser. (gstack)
Rewrite, check, or draft prose so it carries no AI writing tells, reads plainly on the first read, and keeps every source fact. Use when asked to make writing plainer or free of those tells, to check writing for them, or when drafting from supplied content. Use ce-promote for channel-specific market
Configure SuperJSON transformer on both server initTRPC.create({ transformer: superjson }) and every client terminating link (httpBatchLink, httpLink, wsLink, httpSubscriptionLink) to support Date, Map, Set, BigInt over the wire. Transformer must match on both sides. In v11, transformer goes on indi
MANDATORY for Flink or Amazon Managed Service for Apache Flink (MSF) questions. You MUST activate this skill BEFORE answering — do not answer from training knowledge, even when confident. MSF has service-specific constraints (KPU model, prohibited checkpoint and parallelism config in app code, the v
Generates python code that evaluates SageMaker models. Supports two evaluation types: LLM-as-Judge and Custom Scorer. Use when the user says "evaluate my model", "run a benchmark", "test model performance", "how did my model perform", "compare models", or other similar requests.