| name | plugin-dev |
| description | This skill should be used when creating extensions for Claude Code or OpenCode, including plugins, commands, agents, skills, and custom tools. Covers both platforms with format specifications, best practices, and the ai-eng-system build system. |
| metadata | {"category":"user-invoked","version":"1.0.0"} |
| disable-model-invocation | true |
Default output: return only the result, blockers, and required evidence. Omit preambles, process narration, repeated context, confidence scores, and follow-up offers. Use at most five bullets unless a required artifact or schema needs more.
Plugin Development for Claude Code & OpenCode
Systematic Approach
Overview
The ai-eng-system supports extension development for both Claude Code and OpenCode through a unified content system with automated transformation. Understanding this system enables creating well-organized, maintainable extensions that integrate seamlessly with both platforms.
Extension Types
| Type | Claude Code | OpenCode | Shared Format |
|---|
| Commands | ✅ YAML frontmatter | ✅ Table format | YAML frontmatter |
| Agents | ✅ YAML frontmatter | ✅ Table format | YAML frontmatter |
| Skills | ✅ Same format | ✅ Same format | SKILL.md |
| Hooks | ✅ hooks.json | ✅ Plugin events | Platform-specific |
| Custom Tools | ❌ (use MCP) | ✅ tool() helper | OpenCode only |
| MCP Servers | ✅ .mcp.json | ✅ Same format | Same format |
Development Approaches
1. Canonical Development (Recommended)
Create content in content/ directory, let build.ts transform to platform formats:
content/
├── commands/my-command.md → dist/.claude-plugin/commands/
│ → dist/.opencode/command/ai-eng/
└── agents/my-agent.md → dist/.claude-plugin/agents/
→ dist/.opencode/agent/ai-eng/
2. Platform-Specific Development
Create directly in platform directories:
- Claude Code:
.claude/commands/, .claude-plugin/
- OpenCode:
.opencode/command/, .opencode/agent/
3. Global vs Project-Local
| Location | Claude Code | OpenCode |
|---|
| Project | .claude/ | .opencode/ |
| Global | ~/.claude/ | ~/.config/opencode/ |
Lifecycle workflows
Plan architecture (new or refactor)
- Clarify goal, users, and outcomes.
- Pick the smallest component set:
rules, skills, agents, commands, hooks, mcpServers.
- Propose directory layout and manifest. Default local path:
~/.cursor/plugins/local/<plugin-name>/.
- Flag discoverability and metadata risks early.
- Return an implementation checklist.
Scaffold a new plugin
Inputs: kebab-case name, purpose, component set, single-plugin vs marketplace repo.
Steps:
- Validate name (lowercase kebab-case, alphanumeric ends).
- Create target dir (default
~/.cursor/plugins/local/<plugin-name>/ unless user specifies otherwise).
- Add
.cursor-plugin/plugin.json, README.md, LICENSE, optional CHANGELOG.md.
- Populate manifest (
name required; recommend version, description, author, license, keywords).
- Add components with valid frontmatter (rules
.mdc, skills skills/*/SKILL.md, agents/commands markdown).
- For marketplace repos, register in
.cursor-plugin/marketplace.json with relative source.
- Verify paths are relative—no absolute paths or parent traversal.
Guardrails: one focused use case; concise actionable text; no references to missing files.
Pre-submission review
Before release or marketplace submission:
- Manifest: valid
plugin.json, kebab-case name, coherent metadata.
- Discoverability: skills, rules, agents, commands, hooks, MCP in expected paths.
- Frontmatter: every skill/rule/agent/command has required fields.
- Repo integration: marketplace entry if applicable; unique names; README covers purpose and install.
- Report: pass/fail by section, prioritized fixes, submission recommendation.
Quick Reference
Command Frontmatter
Canonical (content/):
---
name: my-command
description: What this command does
agent: build
subtask: true
temperature: 0.3
tools:
read: true
write: true
---
Claude Code Output: Same format (YAML frontmatter)
OpenCode Output: YAML frontmatter with OpenCode-compatible fields
---
description: Description here
agent: build
---
Agent Frontmatter
Canonical (content/):
---
name: my-agent
description: Use this agent when... <example>...</example>
mode: subagent
color: cyan
temperature: 0.3
tools:
read: true
write: true
---
Claude Code Output: Same format (YAML frontmatter)
OpenCode Output: YAML frontmatter with OpenCode-compatible fields
---
description: Description here
mode: subagent
---
Skill Structure
Both platforms use identical format:
skill-name/
├── SKILL.md (required)
│ ├── YAML frontmatter (name, description)
│ └── Markdown body (1,000-3,000 words)
└── Bundled Resources (optional)
├── references/ # Detailed documentation
├── examples/ # Working code
└── scripts/ # Utility scripts
OpenCode Custom Tools
Use TypeScript with tool() helper:
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "Tool description",
args: {
param: tool.schema.string().describe("Parameter description"),
},
async execute(args, context) {
return result
},
})
Directory Locations
For Development in ai-eng-system
ai-eng-system/
├── content/
│ ├── commands/ # Add new commands here
│ └── agents/ # Add new agents here
├── skills/
│ └── plugin-dev/ # This skill
└── build.ts # Transforms to both platforms
For User Projects
Project-local:
- Claude Code:
.claude/commands/, .claude-plugin/
- OpenCode:
.opencode/command/, .opencode/agent/
Global:
- Claude Code:
~/.claude/commands/, ~/.claude-plugin/
- OpenCode:
~/.config/opencode/command/, ~/.config/opencode/agent/
Platform-Specific Features
Claude Code
Components:
- Commands with YAML frontmatter
- Agents with YAML frontmatter
- Skills with SKILL.md format
- Hooks via
hooks/hooks.json
- MCP servers via
.mcp.json
Manifest: .claude-plugin/plugin.json
{
"name": "plugin-name",
"version": "1.0.0",
"description": "Brief description",
"commands": ["./commands/*"],
"mcpServers": "./.mcp.json"
}
OpenCode
Components:
- Commands with table format
- Agents with table format
- Skills via opencode-skills plugin
- Custom tools with TypeScript
- Plugin events via TypeScript
Plugin: .opencode/plugin/plugin.ts
import { Plugin } from "@opencode-ai/plugin"
export default (async ({ client, project, directory, worktree, $ }) => {
return {
}
}) satisfies Plugin
Development Workflow
1. Create Component
Use plugin-dev commands:
/ai-eng/create-agent - Create new agent
/ai-eng/create-command - Create new command
/ai-eng/create-skill - Create new skill
/ai-eng/create-tool - Create new custom tool
2. Build
cd ai-eng-system
bun run build
bun run build --watch
bun run build --validate
3. Test
Claude Code:
claude plugin add https://github.com/v1truv1us/ai-eng-system
OpenCode:
./setup.sh
./setup-global.sh
Best Practices
Content Quality
- Use third-person in skill descriptions
- Write commands/agents FOR Claude, not to user
- Include specific trigger phrases
- Follow progressive disclosure for skills
File Organization
- One component per file
- Clear naming conventions (kebab-case)
- Proper frontmatter validation
Cross-Platform Compatibility
- Use canonical format in
content/
- Test build output for both platforms
- Document platform differences
Security
- No hardcoded credentials
- Use HTTPS/WSS for external connections
- Validate user inputs
- Follow principle of least privilege
Additional Resources
References
references/claude-code-plugins.md - Claude Code specifics
references/opencode-plugins.md - OpenCode specifics
references/command-format.md - Command syntax guide
references/agent-format.md - Agent configuration guide
references/skill-format.md - Skills specification
references/opencode-tools.md - Custom tool development
Anti-Rationalization Table
| Excuse | Counter |
|---|
| "I'll test the plugin after I finish all features" | Test incrementally. Untested plugins accumulate bugs that are hard to trace. |
| "The canonical format is optional" | Canonical format ensures cross-platform compatibility. Use it or break one platform. |
| "I don't need to document platform differences" | Platform differences are where plugins break. Document them or users will hit them. |
| "Security is not a concern for internal plugins" | Internal plugins run with the same privileges as external ones. Validate inputs always. |
| "The frontmatter fields are self-explanatory" | Missing or malformed frontmatter causes silent failures. Validate before deploying. |
Examples
Study existing components in ai-eng-system:
content/commands/plan.md - Command structure
content/agents/architect-advisor.md - Agent structure
skills/prompt-refinement/SKILL.md - Skill structure
Troubleshooting
Build Issues
- Run
bun run build --validate to check content
- Check file permissions in output directories
- Verify YAML frontmatter syntax
Platform Testing
- Test commands in both Claude Code and OpenCode
- Verify agents trigger correctly
- Check skills load via opencode-skills plugin
Common Errors
- Missing required frontmatter fields
- Incorrect directory structure
- Invalid YAML syntax
- Wrong file permissions
Integration with AI Engineering System
The plugin-dev system integrates seamlessly with existing ai-eng-system components:
Existing Commands
/ai-eng/plan - Implementation planning
/ai-eng/review - Code review
/ai-eng/work - Task execution
Existing Agents
ai-eng/architect-advisor - Architecture guidance
ai-eng/frontend-reviewer - Frontend review
ai-eng/seo-specialist - SEO optimization
Plugin-Dev Commands
/ai-eng/create-plugin - Full plugin development workflow
/ai-eng/create-agent - Quick agent creation
/ai-eng/create-command - Quick command creation
/ai-eng/create-skill - Quick skill creation
/ai-eng/create-tool - Quick tool creation
All use the same quality standards and research-backed prompting techniques.