Can I create TypeScript-based skills?

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

can i create typescript-based skills?

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

Based on my exploration of the codebase, I can give you a clear answer:

No, you cannot create TypeScript-based skills. Skills in OpenCode are Markdown-based only.

##How Skills Work

Skills are defined as SKILL.md files (Markdown with YAML frontmatter). They're essentially prompt/instruction documents that agents can load on-demand—not executable code.

###Skill Locations

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

###Skill Structure

---
name: my-skill
description: What this skill does
---

## Instructions for the agent

Step-by-step guidance goes here...

##What Skills Are For

Skills are reusable instructions/prompts that agents can dynamically load when needed. They're designed to give the AI detailed guidance on how to perform specific tasks (like "git-release" or "code-review")—not to execute code.

If you're looking to extend OpenCode with actual TypeScript code/logic, you'd want to look at tools instead (see packages/opencode/src/tool/), though those aren't user-definable in the same plug-and-play way that skills are.

Avatar of julianbenegas
Julian Benegas
commented

tools are fine, but what's nice about skills is that they're discovered on-demand. how would i make that a thing? like a mix between tools and skills.

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

Now I have a complete picture. Let me explain what you could do:


##You Can Already Create TypeScript-Based Tools!

OpenCode already supports custom TypeScript tools that are discovered automatically. They go in:

  • .opencode/tool/<name>.ts (project-local)
  • ~/.config/opencode/tool/<name>.ts (global)

From packages/opencode/src/tool/registry.ts:

const glob = new Bun.Glob("{tool,tools}/*.{js,ts}")

for (const dir of await Config.directories()) {
  for await (const match of glob.scan({ cwd: dir, ... })) {
    const namespace = path.basename(match, path.extname(match))
    const mod = await import(match)
    // ... registers tools from the module
  }
}

##But They're Not "On-Demand" Like Skills

You're right that skills have a nice pattern where:

  1. The agent sees a list of available skills with descriptions
  2. The agent chooses which skill to load when relevant
  3. The full content is loaded lazily

Custom tools, by contrast, are always loaded and always visible to the agent.


##How You Could Build "Discoverable Tools"

To get the skill-like discovery pattern for executable code, you'd essentially need to create a meta-tool similar to SkillTool. Here's a conceptual approach:

###Option 1: Create a "Dynamic Tool Loader" Tool

You could create a custom tool that:

  1. Scans a directory for tool definitions (with metadata frontmatter)
  2. Shows available tools in its description
  3. When called, dynamically imports and executes the chosen tool
import { tool } from "@opencode-ai/plugin"
import { Glob } from "bun"

// Scan for discoverable tools at init time
const discoverableTools = await scanTools()

export default tool({
  description: `Load and execute a dynamic tool.
<available_tools>
${discoverableTools.map(t => `  <tool><name>${t.name}</name><description>${t.description}</description></tool>`).join('\n')}
</available_tools>`,
  args: {
    name: tool.schema.string().describe("Tool name to execute"),
    args: tool.schema.record(tool.schema.any()).describe("Arguments for the tool"),
  },
  async execute({ name, args }) {
    const toolPath = discoverableTools.find(t => t.name === name)?.path
    if (!toolPath) throw new Error(`Tool ${name} not found`)
    
    const mod = await import(toolPath)
    return mod.default.execute(args)
  },
})

###Option 2: Fork/Extend the Skill System

You could modify the skill system to support a type: executable frontmatter field, where instead of returning markdown, it imports and runs a .ts file referenced in the skill.


The first option is something you can do today without modifying OpenCode's core. The second would require contributing to the codebase. Would either of these directions work for what you're trying to build?


END OF POST

Can I create TypeScript-based skills? — anomalyco/opencode