- Bump root AGENTS.md header: 2026-05-14 → 2026-05-15, commit5ffbe0e24→53a740636, release v4.1.1 → v4.1.2 - Update file counts: 2034 (1337+697) → 2041 (1340+701), LOC ~292k → ~294k - Fix STRUCTURE: openclaw lives at src/openclaw/ (not src/features/); list more accurate feature modules in the parenthetical - Clarify interactive_bash gate: tmux binary on PATH via isInteractiveBashEnabled() (not 'tmux enabled') - Fix docs/reference/features.md hook counts: Tool Guard 14→16, Total base 52→54, total with team-mode 59→61 - Bump 'Generated' date on all 43 subdir AGENTS.md files to 2026-05-15 - Preserve promptAsync injection cautions verbatim (per request)
2.9 KiB
src/features/claude-code-plugin-loader/ — Unified Claude Code Plugin Loader
Generated: 2026-05-15
OVERVIEW
16 files. Full Claude Code plugin compatibility layer. Discovers and loads ALL plugin components (commands, agents, skills, hooks, MCP servers, LSP servers) from .opencode/plugins/ and ~/.claude/plugins/.
WHY IT EXISTS
Claude Code plugins ship commands/agents/skills as separate files with plugin.json manifest. OmO uses this loader to ingest them into its own registry so existing Claude Code plugins work unchanged under OmO.
LOAD PIPELINE
loadAllPluginComponents(ctx)
→ discoverPlugins() # scan .opencode/plugins + ~/.claude/plugins
→ readPluginManifest(plugin.json) # parse name/version/commands/agents/skills/hooks/mcpServers
→ loadPluginCommands()
→ loadPluginAgents()
→ loadPluginSkills()
→ loadPluginHooks() # register hook handlers
→ loadPluginMcpServers() # feed into mcp-config-handler (tier 2)
→ loadPluginLspServers()
→ return LoadedPluginBundle
Called from src/plugin-handlers/plugin-components-loader.ts during Phase 2 of config handler (10s timeout with error isolation — one broken plugin does not sink the plugin load).
KEY FILES
| File | Purpose |
|---|---|
index.ts |
Barrel: loadAllPluginComponents, PluginManifest, ClaudeSettings types |
plugin-discovery.ts |
Find plugin directories across scopes |
plugin-manifest-parser.ts |
Parse plugin.json with Zod validation |
command-loader.ts |
Load commands from commands/ or COMMANDS.md |
agent-loader.ts |
Load agents from agents/ or AGENTS.md frontmatter |
skill-loader.ts |
Load skills from skills/ or SKILL.md |
hook-loader.ts |
Load hooks config from hooks/ or manifest |
mcp-loader.ts |
Extract MCP server configs |
lsp-loader.ts |
Extract LSP server configs |
settings-loader.ts |
Parse Claude Code settings.json |
PLUGIN MANIFEST (plugin.json)
{
"name": "my-plugin",
"version": "1.0.0",
"description": "...",
"commands": ["./commands"], // or string[] of paths
"agents": ["./agents"],
"skills": ["./skills"],
"hooks": "./hooks/config.json",
"mcpServers": "./.mcp.json",
"lspServers": "./lsp"
}
SCOPES
| Scope | Path | Priority |
|---|---|---|
project |
.opencode/plugins/ |
Highest |
local |
~/.opencode/plugins/ |
Medium |
user |
~/.claude/plugins/ |
Medium |
managed |
Built-in | Lowest |
ERROR ISOLATION
Each plugin loads in isolation — if one fails (bad manifest, missing file, syntax error), others still load. Errors surface as warnings in bunx oh-my-opencode doctor.
RELATED
- Phase 2 loader:
src/plugin-handlers/plugin-components-loader.ts - Tier 2 MCP integration:
src/features/claude-code-mcp-loader/ - Claude Code compat hooks:
src/hooks/claude-code-hooks/