From opencode-sync
Generates OpenCode agents and MCP config from canonical Claude Code sources, validates both runtimes' rule sets, and detects drift. Use when adding OpenCode support or checking cross-runtime compliance.
How this skill is triggered — by the user, by Claude, or both
Slash command
/opencode-sync:opencode-syncThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Keeps one canonical source of truth (skills, agents, commands, MCP config, rules files) usable on BOTH Claude Code and OpenCode. Skills and rules are single-source by design (OpenCode reads `.claude/skills/` and `AGENTS.md` natively); agents, commands, and MCP config are generated from the canonical Claude-side files by the bundled scripts. Plugin skills are exposed to OpenCode via `skills.path...
Keeps one canonical source of truth (skills, agents, commands, MCP config, rules files) usable on BOTH Claude Code and OpenCode. Skills and rules are single-source by design (OpenCode reads .claude/skills/ and AGENTS.md natively); agents, commands, and MCP config are generated from the canonical Claude-side files by the bundled scripts. Plugin skills are exposed to OpenCode via skills.paths (see Mode E). The canonical copy always lives on the open side of the fence - if Claude Code access is capped, everything here still runs.
On Claude Code, run these TaskCreate calls before anything else:
t0 = TaskCreate("Phase 0: Pre-Flight checks")
t1 = TaskCreate("Phase 1: Mode selection (Ingest / Sync / Validate / Drift / Setup)")
t2 = TaskCreate("Phase 2: Execute selected mode")
t3 = TaskCreate("Phase 3: Report, ledger, commit")
TaskUpdate(t1, addBlockedBy=[t0])
TaskUpdate(t2, addBlockedBy=[t1])
TaskUpdate(t3, addBlockedBy=[t2])
Mark t0 in_progress immediately, mark each phase completed at its boundary.
OpenCode or Cowork runtime:
TaskCreatedoes not exist there. Mirror the same four phases as atodowritechecklist (OpenCode) or a visible markdown checklist (Cowork) instead. Full translation recipe:references/tool-translation.md. Do not skip phase tracking just because Task* is unavailable.
This skill is itself dual-runtime. Detect capabilities before acting, never assume:
CAPABILITY CHECK (run mentally at start):
- Task* tools available? yes -> use the bootstrap chain above
no -> todowrite / markdown checklist
- AskUserQuestion available? yes -> use it (4 options max)
no -> ask in plain text with lettered options
- Bash available? yes -> run bundled scripts
no -> follow the manual tables in references/
The bundled scripts are plain Python 3 stdlib (PyYAML optional, with graceful fallback) so they run identically from either runtime's bash tool.
Stored at <repo>/.opencode-sync/config.json (recommend committing it so CI can use it):
{
"canonical_agent_dirs": [".claude/agents", "plugins/work/agents"],
"opencode_agent_dir": ".opencode/agent",
"default_agent_mode": "subagent",
"model_map": {
"sonnet": "anthropic/claude-sonnet-4-5",
"opus": "anthropic/claude-opus-4-1",
"haiku": "anthropic/claude-haiku-4-5"
},
"mcp_servers": [],
"claude_plugin_roots": ["plugins"],
"skip_paths": []
}
The model map MUST be verified against the live models.dev registry on first run - model ids change and this skill never hardcodes a guess silently (see E5).
There are five modes: Ingest, Sync, Validate, Drift, and Setup. Skip this phase when a Happy Path trigger already names one (for example "ingest this marketplace", "is this repo opencode-ready", "check drift"). Otherwise ask (AskUserQuestion, these 4 options; plain-text lettered fallback on OpenCode):
Mode A (Setup - AGENTS.md canonicalisation, provider notes) runs as the first-run step of ingesting your own repo, or name "setup" to run it on its own.
CLAUDE.md exists, AGENTS.md does not -> mv CLAUDE.md AGENTS.md && ln -s AGENTS.md CLAUDE.md, commit the symlink. Both exist and differ -> STOP (E2), show a diff, user merges into AGENTS.md. Symlink already in place -> report OK.~/.claude/CLAUDE.md as a global fallback (unless ~/.config/opencode/AGENTS.md exists, which takes precedence). Symlink the global if you want it canonical.skills.paths). Global ~/.claude/skills/ skills are discovered natively.opencode auth login with an API key, Copilot, OpenCode Zen, or a local model. Do not auth on the user's behalf.All writes preview-first. Work on a branch, never commit to main, open a PR.
validate_dual.py --target opencode <paths> and fix-forward portability warnings in the canonical file.sync_agents.py --config .opencode-sync/config.json emits translated files with a GENERATED header. Per-file failures (E3, E4, E5) skip and continue.sync_commands.py emits OpenCode command wrappers from canonical commands/*.md files, preserving template bodies and argument placeholders for OpenCode-first slash workflows.opencode.json mcp block, diff-first (MCP runs code).check_drift.py --update.Point the assessor at a file, plugin, repo, or .claude tree. It discovers SKILL.md, agents/*.md, commands/*.md by location and skips docs/READMEs.
--depth): (A) this folder shallow, (B) whole repo source standard (recommended), (C) everything incl caches deep, (D) a single file. Preview with --list.python3 scripts/validate_dual.py --target both --depth <d> <paths> - FAIL/WARN/INFO with rule IDs. Scans over 15 files print an aggregate; --verbose for per-finding, --json for machine output.python3 scripts/check_drift.py --check compares hashes against the manifest: CANONICAL_CHANGED (re-sync), GENERATED_EDITED (canonical wins; regenerate or back-port, E8), MISSING (regenerate). CI wiring runs the same --check.
Onboard any Claude Code marketplace, plugin, or plain repo so OpenCode can find and run its skills, agents, and tools. One entry point, three source types, auto-detected. Driven by scripts/ingest_source.py; full exposure mechanics in references/skill-exposure.md.
Resolve the source (python3 scripts/ingest_source.py <path-or-url>). Local path is used directly. For a URL the script searches --search-roots (default ~/Projects) for an existing clone:
--fetch). Confirm it is current before using.URL_NOT_FOUND_LOCALLY): ask the user (AskUserQuestion): (A) I already have it -> --local-path <dir>; (B) Clone it -> a second question confirms where (~/.opencode-sources recommended, ~/Projects, or typed) -> --clone-into <dir>.~/Projects. For exact parity with what Claude Code has installed, prefer the snapshot under ~/.claude/plugins/cache/.... The cache is authoritative for installed versioning; the repo clone is authoritative for local edits.Choose the enablement strategy (AskUserQuestion; plain-text lettered fallback on OpenCode). This is the headline choice - it decides which plugins/skills/MCP get exposed:
--respect-claude-settings. Keeps all non-disabled plugins available, denies the explicitly disabled ones, emits user-scope MCP to the GLOBAL config, and emits repo mcpServers from .claude/settings.json plus .claude/settings.local.json to the PROJECT config. The turnkey path - OpenCode inherits exactly the machine and repo enablement, so nothing that is on is silently missing and nothing that is off leaks in.~/.config/opencode/opencode.json, everywhere), All project (opencode.json in the checkout, portable relative paths), Both, or Per-plugin. Pass --config-target global|project|both; for per-plugin, list the discovered plugins with a default target and let the user name exceptions as --global-plugins NAME... / --project-plugins NAME.... Routing is per plugin, so one ingest can populate both config files.--no-deny. Use when the user wants everything on to prune later.These compose: --respect-claude-settings decides what is exposed, --config-target decides where the enabled plugins land (default project; user-scope MCP always goes global), and --no-deny is the escape hatch when mirroring is too strict. Add --wire-memory with any strategy to wire OpenCode's session-start memory read. When the repo tracks MEMORY.md, the instructions order becomes project memory first, then AGENTS.md, then ~/.claude/memory/memory.md. See references/memory-wiring.md for the remaining gap versus memory-os.
Preview (dry-run, the default): the script prints the detected type, discovered counts, the deny-list, and the exact config fragment(s) to merge per target. Confirm before writing.
Apply (--apply): merges skills.paths + permission.skill deny-list + mcp blocks into each target config, then delegates agent generation to sync_agents.py and command generation to sync_commands.py. A non-writable target (for example a global config the runtime cannot reach) degrades gracefully - the fragment is printed for manual application. The hide set is skills that are BOTH disable-model-invocation: true AND user-invocable: false. Generated agents default to ~/.config/opencode/agent when any global target is in play, otherwise .opencode/agent. Generated commands default to ~/.config/opencode/command when any global target is in play, otherwise .opencode/command. Hooks are verification-only and are never written into OpenCode config.
Offer the resolution block. The preview reports the source's rules-file state. If the source has no AGENTS.md/CLAUDE.md, or one missing the plugin skill resolution block described in references/skill-exposure.md, use AskUserQuestion (header "Resolution block"; recommended option "Add it", description: pass --add-resolution-block - appends to AGENTS.md, or to CLAUDE.md so it is not shadowed, or creates AGENTS.md if neither exists; other option "Skip for now"). Do not add it on an assumed default - see references/askuserquestion-protocol.md.
Verify: open OpenCode and run /skills - the invocable skills appear, the denied reference-only ones do not. Then check agent visibility where the sync wrote them: ~/.config/opencode/agent/ for global sync, .opencode/agent/ for project-local sync. The ingest preview also prints a catalogue-style verification summary for expected skills, agents, commands, hooks, and Claude MCP sources.
Skills are never copied or symlinked - skills.paths points OpenCode at the canonical folders (symlinks are unreliable: OpenCode's glob defaults to not following them). Single-source preserved.
Prompt-box autocomplete note: skills show under /skills, but if the user wants slash-like prompt-box completion for a workflow, that generally needs a command wrapper rather than a skill alone. Upstream OpenCode work may reduce this gap, but a plugin cannot fully fake it today.
| ID | Error | Resolution |
|---|---|---|
| E1 | Config file missing | Switch to Consultation wizard, create .opencode-sync/config.json on approval |
| E2 | AGENTS.md and CLAUDE.md both exist and differ | Show diff, user merges into AGENTS.md, re-run. Never auto-merge |
| E3 | PyYAML unavailable, block-scalar frontmatter | Script skips the file with a message and continues |
| E4 | Agent has no description | FAIL that file, list it, continue with the rest |
| E5 | Model not in model_map | Emit anthropic/<original> + TODO-VERIFY - never silently guess |
| E6 | opencode binary not found | Author-only mode: generate and validate, mark UNTESTED ON OPENCODE |
| E7 | Manifest missing on drift check | Build a fresh manifest, exit 0, note first-run |
| E8 | Generated file hand-edited | Canonical wins. Regenerate, or back-port the edit then regenerate |
| E9 | Ingest URL has no local clone | Exit 3 URL_NOT_FOUND_LOCALLY. Ask: --local-path or --clone-into. Never clone without confirmation |
| E10 | Marketplace entry points at an external (non ./) source | Skipped with a note. Ingest that plugin/repo separately |
references/field-mapping.md - frontmatter, model, command, MCP, and rules-file mapping tablesreferences/tool-translation.md - tool-name map, degradation recipes, capability preamblereferences/validator-rules.md - the dual-runtime rule inventory (SH / CC / OC / TR)references/skill-exposure.md - how plugin skills reach OpenCode (skills.paths, permission.skill, AGENTS.md resolution)references/memory-wiring.md - what --wire-memory reproduces from memory-os, and what it does notscripts/ingest_source.py - Mode E: resolve a source, discover, emit OpenCode configscripts/sync_agents.py, scripts/sync_commands.py, scripts/validate_dual.py, scripts/check_drift.py - the executable side of Modes B, C, DGuides collaborative design exploration before implementation: explores context, asks clarifying questions, proposes approaches, and writes a design doc for user approval.
Creates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.
Synthesizes the current conversation into a structured spec (PRD) and publishes it to the project issue tracker with a ready-for-agent label, without interviewing the user.
npx claudepluginhub youngleadersdottech/young-leaders-tech-marketplace --plugin opencode-sync