plugin-introspection
Require every OpenCode plugin to expose get_skills and get_version tools.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Menú
Require every OpenCode plugin to expose get_skills and get_version tools.
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Basado en la clasificación ocupacional SOC
Create and manage isolated git worktrees safely.
Opinionated workflow for submodule development + PRs + control-center pointer bumps.
Store Apple notarization IDs in Keychain and notarize/staple OpenWork DMGs locally.
Sync control-center master and update submodule pointers safely.
Use client.app.log() instead of console.log in OpenCode plugins
Guide for creating effective skills. Use when users want to create or update a skill that extends Claude with specialized knowledge, workflows, or tool integrations.
| name | plugin-introspection |
| description | Require every OpenCode plugin to expose get_skills and get_version tools. |
When creating an OpenCode plugin, always include two introspection tools:
get_version — returns the plugin name + versionget_skills — returns the skills the plugin provides (or an empty list)This makes plugins discoverable, debuggable, and UI-friendly.
get_versionname (package name or plugin id)version (semver or "unknown")get_skillsname and version (same as get_version)skills: array of skill descriptorsA skill descriptor should be stable and minimal:
{
"name": "scheduled-job-best-practices",
"description": "Patterns for resilient, non-interactive scheduled opencode jobs"
}
If the plugin does not ship skills, return skills: [].
import type { Plugin } from "@opencode-ai/plugin"
import { tool } from "@opencode-ai/plugin"
import { readFileSync } from "fs"
import { dirname, join } from "path"
import { fileURLToPath } from "url"
function getPackageVersion(): string {
try {
const packagePath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json")
const raw = readFileSync(packagePath, "utf-8")
const parsed = JSON.parse(raw) as { version?: string }
return typeof parsed.version === "string" ? parsed.version : "unknown"
} catch {
return "unknown"
}
}
const PLUGIN_NAME = "my-plugin" // replace with your package name
export const MyPlugin: Plugin = async () => {
return {
tool: {
get_version: tool({
description: "Return plugin name and version.",
args: {},
async execute() {
return JSON.stringify({ name: PLUGIN_NAME, version: getPackageVersion() })
},
}),
get_skills: tool({
description: "List skills provided by this plugin.",
args: {},
async execute() {
return JSON.stringify({
name: PLUGIN_NAME,
version: getPackageVersion(),
skills: [],
})
},
}),
},
}
}
client.app.log() (not console.log) for structured logs.