CtrlK
BlogDocsLog inGet started
Tessl Logo

punkdev/cc2oc

Add and ship OpenCode support for one Claude Code plugin at a time. Includes core migration to a reviewable `opencode-plugin/` adapter, maintainer-facing docs, and follow-up CI/versioning setup for package publishing or skill-copy drift checks.

92

1.25x
Quality

92%

Does it follow best practices?

Impact

97%

1.25x

Average score across 2 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

SKILL.mdskills/migrate-plugin/

name:
migrate-plugin
description:
Add local OpenCode support to one existing Claude Code plugin. Creates one reviewable `opencode-plugin/` adapter package, migrates Claude MCP config to OpenCode config when present, ports hooks by intent, tests behavior, and packages plugin skills when needed. Use when the user says "port a Claude plugin to OpenCode", "add OpenCode support", "make this plugin work in OpenCode", "port the hooks", or the repo has `.claude-plugin/`, `.mcp.json`, or plugin-local `.claude/skills/`. Stop before CI/release automation, but always offer the `ci-setup` follow-up after local support works.

cc2oc — Claude Code → OpenCode Support

Create reviewable local OpenCode support for one Claude Code plugin. Preserve shared prompt assets, port hooks by user-visible intent, and stop at working local files plus tests.

Hard Bounds

  • Do not add PR drafts, GitHub Actions, release workflows, npm publishing automation, or sync automation during local migration. After local support works, offer the ci-setup follow-up for versioning, publishing, and drift-check automation.
  • Use opencode-plugin/ as the neutral generated package root. Use .opencode/ only as an explicitly documented local dogfooding shim.
  • Do not fork Claude/OpenCode skill text unless incompatibility is concrete. If package-local copies are needed, document and test the source-of-truth relationship.
  • Keep MCP config separate from opencode-plugin/package.json; OpenCode plugin packages are not assumed to install MCP servers.
  • Do not claim parity for hook blocking, prompt/context injection timing, compaction, worker lifecycle, transcript semantics, or MCP setup unless tests prove it.

Workflow

Reference only when needed: placement and coverage (placement policy, coverage audit), skills and commands (skill sharing, commands and agents), package layout (OpenCode package layout), MCP (MCP migration), hooks (hook porting), tests (testing and parity), and maintainer wording (maintainer explanations). Templates live in assets/.

Use these assets when producing migration records and review tables: asset inventory table, coverage audit table, discovery checklist, hook parity record, MCP migration record, MCP test checklist, OpenCode MCP config snippet, and test matrix.

1. Inspect And Classify

Run when available:

python3 scripts/inspect_repo.py <repo> --format markdown

Use the output as a starting inventory, then verify manually. If the task names both a pinned upstream commit and an offline fixture path, use the pinned source when available, but prefer the named repo-relative fixture when network or clone access fails. Never make a transient /tmp clone the only fallback. Record the source used in OPENCODE_SUPPORT.md.

Inventory at least:

  • Root .claude-plugin/plugin.json and nested manifests such as plugin/.claude-plugin/plugin.json as separate rows.
  • .claude-plugin/marketplace.json and other marketplace metadata.
  • skills/, .claude/skills/, commands/, agents/, hooks, scripts, package metadata, MCP files, worker/service entrypoints, and existing OpenCode integration code.
  • Runtime substitutions: ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PLUGIN_DATA}, user config/env placeholders, stdin/stdout/exit contracts.

Use labels full, partial, missing, or not-applicable. Do not implement with an unaddressed missing row. If a .claude-plugin/ directory lacks plugin.json, explicitly say so instead of implying it was inspected.

2. Decide Asset Destinations

For each asset choose: shared, wrapped, rewritten, or Claude-only. Keep shared skill sources in place when possible; use .agents/skills/ for new shared skills; use .opencode/commands/ or .opencode/agents/ only for OpenCode-specific wrappers; copy to opencode-plugin/skills/ only for distribution/runtime need and test equality or document intentional divergence. Keep Claude metadata as evidence and do not generate new .claude/ files unless explicitly asked.

3. Validate Skills

Run when skills exist:

python3 scripts/validate_skills.py <repo> --format markdown

Fix or document frontmatter issues before packaging. Tests must prove every source and package-local SKILL.md has parseable name and description. If fixture/helper scripts are intentionally absent, say so in the migration note.

4. Create Minimal opencode-plugin/

Create the smallest package that supports the discovered behavior:

opencode-plugin/
  package.json
  src/plugin.ts        # or plugin.js for JS-only repos
  src/state.ts         # only if state is needed
  skills/<name>/SKILL.md
  tests/opencode-plugin.test.ts

opencode-plugin/package.json must be ESM, set main/exports to an existing entrypoint, include opencode and opencode-plugin keywords, and restrict files to runtime assets such as src/, plugin.js, and skills/. Exclude .claude/, .opencode/, tests, local config, and unrelated agent metadata.

Run after package edits:

python3 scripts/validate_opencode_package.py <repo> --format markdown

5. Migrate MCP Separately

When .mcp.json or plugin.json.mcpServers exists, create a per-server record before writing config.

Convert Claude MCP config to opencode.jsonc / opencode.json:

  • command: "cmd" plus args: [...] becomes command: ["cmd", ...args].
  • env becomes environment.
  • Command servers are type: "local"; URL servers are type: "remote".
  • Resolve ${CLAUDE_PLUGIN_ROOT} only after deciding where equivalent files live.
  • Never inline secrets. Preserve placeholders or document required env vars.
  • Ask before overwriting an existing OpenCode MCP entry with the same name.

Include an actionable config snippet or patch and tests/manual checks (opencode mcp list when available).

6. Port Hooks By Intent

For every Claude hook, create a parity record before coding. Include event/matcher/command, fields used, output/failure behavior, intended user-visible behavior, OpenCode mapping, reuse-vs-rewrite decision, test evidence, and caveats.

Common mappings:

  • PreToolUsetool.execute.before when blocking/mutation is needed; test semantics.
  • PostToolUsetool.execute.after.
  • SessionStart → session lifecycle hook plus skill/context strategy; timing differs.
  • UserPromptSubmit → native TUI command or prompt handling where available; avoid Claude stdin JSON contracts.
  • PreCompact/PostCompact → experimental compaction APIs only with tested-version caveats.

Use OpenCode/XDG-safe state paths, not Claude config/cache paths.

7. Test And Document

Minimum evidence:

  • Package entrypoint imports and plugin factory returns expected hooks/tools/commands.
  • Every ported hook is tested with OpenCode-like fixtures.
  • State writes avoid Claude config paths.
  • Source and packaged skills validate, and copies match when intended.
  • MCP config shape is tested when generated.
  • Existing Claude tests still pass when available.
  • OPENCODE_SUPPORT.md records source URL/commit or fixture path, inventories surfaces with labels, includes hook parity and MCP decisions, compares existing OpenCode integrations if present, lists verification commands, and states honest caveats.

Completion

Finish when the maintainer has:

  1. Surface inventory with support labels and no unaddressed missing rows.
  2. A working opencode-plugin/ adapter package plus optional documented .opencode/ shim.
  3. Separate OpenCode MCP config when Claude MCP servers exist.
  4. Tests for all ported behavior.
  5. Concise install/verification docs that avoid unpublished-package claims.

Then offer next steps:

  • docs to polish README/OPENCODE_SUPPORT wording for maintainers.
  • ci-setup to inspect existing Claude plugin versioning and set up package publishing or skill-copy drift checks. Do not add CI files without user approval.

README.md

tile.json