What's OpenCode's take on skills and implementation?

dev
20b52cachore: generate
This post might have stale content, as dev is 2009 commits ahead.

what's opencode's take on "skills"? how do they implement them?

Avatar of anthropic/claude-opus-4.5
Claude Opus 4.5
commented

Now I have a comprehensive understanding. Here's OpenCode's take on "skills" and how they implement them:


##OpenCode's Take on Skills

Skills in OpenCode are reusable, on-demand instruction sets that agents can discover and load during a conversation. Think of them as specialized knowledge modules or "how-to guides" that an AI agent can pull in when needed for a specific task.

###Core Philosophy

  1. Lazy Loading: Skills aren't loaded into the context by default. Agents see a list of available skills (name + description), and only load the full content when they need it. This keeps the context window clean.

  2. Convention over Configuration: Skills are discovered automatically from well-known locations using a simple file structure.

  3. Claude Code Compatible: OpenCode supports the .claude/skills/ directory structure, making it compatible with Claude Code's skill format.


##Implementation Details

###1. Skill Discovery (packages/opencode/src/skill/skill.ts)

Skills are discovered by scanning specific directories for SKILL.md files:

const OPENCODE_SKILL_GLOB = new Bun.Glob("{skill,skills}/**/SKILL.md")
const CLAUDE_SKILL_GLOB = new Bun.Glob("skills/**/SKILL.md")

Search locations (in order):

  • .opencode/skill/<name>/SKILL.md (project-level)
  • ~/.config/opencode/skill/<name>/SKILL.md (global)
  • .claude/skills/<name>/SKILL.md (Claude-compatible, project)
  • ~/.claude/skills/<name>/SKILL.md (Claude-compatible, global)

The discovery walks up from the current directory to the git worktree root, collecting skills along the way.

###2. Skill Format

Each SKILL.md must have YAML frontmatter with:

  • name (required) — lowercase, hyphen-separated, 1-64 chars
  • description (required) — 1-1024 chars, used by agents to decide when to use it

Example:

---
name: git-release
description: Create consistent releases and changelogs
---

## What I do
- Draft release notes from merged PRs
- Propose a version bump
...

###3. The Skill Tool (packages/opencode/src/tool/skill.ts)

Skills are exposed to agents via a built-in skill tool. The tool dynamically builds its description to list all available skills:

export const SkillTool = Tool.define("skill", async (ctx) => {
  const skills = await Skill.all()
  
  // Filter by agent permissions
  const accessibleSkills = agent
    ? skills.filter((skill) => {
        const rule = PermissionNext.evaluate("skill", skill.name, agent.permission)
        return rule.action !== "deny"
      })
    : skills

  const description = [
    "Load a skill to get detailed instructions for a specific task.",
    "<available_skills>",
    ...accessibleSkills.flatMap((skill) => [
      `  <skill>`,
      `    <name>${skill.name}</name>`,
      `    <description>${skill.description}</description>`,
      `  </skill>`,
    ]),
    "</available_skills>",
  ].join(" ")
  // ...
})

When an agent calls skill({ name: "git-release" }), the tool:

  1. Looks up the skill by name
  2. Asks for user permission (respects allow/deny/ask settings)
  3. Parses and returns the full SKILL.md content with its base directory

###4. Permission Control

Skills integrate with OpenCode's permission system. In opencode.json:

{
  "permission": {
    "skill": {
      "*": "allow",
      "internal-*": "deny",
      "experimental-*": "ask"
    }
  }
}
  • allow — skill loads immediately
  • deny — skill is hidden from the agent entirely
  • ask — user prompted before loading

###5. Compaction Protection

Skills are protected from context pruning (packages/opencode/src/session/compaction.ts):

const PRUNE_PROTECTED_TOOLS = ["skill"]

This ensures that loaded skills aren't erased when OpenCode compacts the conversation history.


##Summary

OpenCode's skill system is elegant:

  • Discovery: Glob-based scanning of convention-driven directories
  • Exposure: A dynamic skill tool that lists available skills in its description
  • Loading: On-demand via tool call, with permission checks
  • Format: Simple markdown with YAML frontmatter
  • Compatibility: Works with both OpenCode-native and Claude Code skill directories

END OF POST

What's OpenCode's take on skills and implementation? — anomalyco/opencode