Writing Opencode Plugins logo

Writing Opencode Plugins

Organization
sveltejs
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.

Overview

Publishersveltejs
Repositoryai-tools
Skill namewriting-opencode-plugins
Stars
331
Forks
40
Bundled files
3
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 3 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by sveltejs on GitHub. Read the source before you install it.

Installation

Install the Writing Opencode Plugins AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/sveltejs/ai-tools/tree/main/.agents/skills/writing-opencode-plugins
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/sveltejs/ai-tools.git /tmp/ai-tools
mkdir -p .claude/skills
cp -r /tmp/ai-tools/.agents/skills/writing-opencode-plugins .claude/skills/writing-opencode-plugins
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Writing Opencode Plugins in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Writing Opencode Plugins on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Writing Opencode Plugins is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

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

  1. Decide which runtime owns the feature.
  2. Read the relevant public type before writing code.
  3. Find one focused in-repository example using the same API.
  4. Implement the smallest target-specific module.
  5. Test loading, behavior, failure, and cleanup in the owning package.
NeedPlugin targetImportConfiguration
Hooks, tools, auth, providers, model parameters, shell environmentServer@opencode-ai/pluginopencode.json or auto-discovered .opencode/plugins/*.{ts,js}
Commands, keybindings, routes, dialogs, slots, themes, notificationsTUI@opencode-ai/plugin/tuiExplicit tui.json plugin entry
BothTwo target-only entrypointsBoth imports in separate filesPackage 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:

ts
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:

tsx
/** @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 satisfies against the public plugin type.
  • Parse and validate options; they arrive as unvalidated Record<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 AbortSignal for long-running or cancellable work.
  • Use client.app.log() for structured server logging instead of console.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

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Writing Opencode Plugins AI skill do?

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.

Why use Writing Opencode Plugins on TypingMind?

Because you install it once and use it with any model. Writing Opencode Plugins is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Writing Opencode Plugins in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/sveltejs/ai-tools/tree/main/.agents/skills/writing-opencode-plugins. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Writing Opencode Plugins?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Writing Opencode Plugins?

As many as you like. As long as a model supports skills, you can use Writing Opencode Plugins with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Writing Opencode Plugins AI skill free?

Yes. It is published on GitHub by sveltejs under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇