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

criteria.jsonevals/scenario-1/

{
  "context": "Tests whether the agent can apply the Claude Code to OpenCode migration skill to a pinned real-world Claude plugin instead of a synthetic fixture. The task uses the caveman plugin shape with shared skills, Claude hooks, command metadata, and Claude-specific state paths, so the output should show careful classification, intent-based hook porting, package generation, tests, and reproducible fixture evidence.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "Pinned evidence",
      "description": "The output records the upstream repository URL and exact commit `84cc3c14fa1e10182adaced856e003406ccd250d`, and does not describe the migration as based on an unpinned latest branch.",
      "max_score": 7
    },
    {
      "name": "Offline fallback",
      "description": "The solution uses or preserves the provided offline fixture files when network access is unavailable, rather than failing because GitHub cannot be reached.",
      "max_score": 7
    },
    {
      "name": "Asset inventory",
      "description": "A migration note or report inventories at least these surfaces: `.claude-plugin/plugin.json`, `hooks/`, `skills/`, `commands/`, `.agents/plugins/marketplace.json` or marketplace metadata, and existing non-Claude plugin/package assets if discovered.",
      "max_score": 7
    },
    {
      "name": "Coverage labels",
      "description": "The migration evidence classifies discovered Claude surfaces with support labels such as full, partial, missing, or not-applicable, and does not proceed with an unaddressed missing row.",
      "max_score": 7
    },
    {
      "name": "Shared skills",
      "description": "Existing `skills/*/SKILL.md` content is reused as shared or package-local runtime content without creating divergent `.claude` and OpenCode copies of the same skill text.",
      "max_score": 7
    },
    {
      "name": "Skill validation",
      "description": "The output includes validation evidence or tests that skill frontmatter has parseable `name` and `description`, and that referenced helper scripts for packaged skills are present or explicitly documented as unavailable in the compact fixture.",
      "max_score": 7
    },
    {
      "name": "Hook records",
      "description": "The output includes parity records or equivalent documentation for both `SessionStart`/`caveman-activate.js` and `UserPromptSubmit`/`caveman-mode-tracker.js`, including intended user-visible behavior and caveats.",
      "max_score": 9
    },
    {
      "name": "Intent porting",
      "description": "OpenCode hook/plugin code ports the intent of startup activation, mode tracking, and context reminders rather than shelling out to Claude hook commands with `${CLAUDE_PLUGIN_ROOT}` or relying on Claude stdin JSON contracts unchanged.",
      "max_score": 9
    },
    {
      "name": "Safe state",
      "description": "Generated OpenCode state handling avoids writing to `.claude`, `CLAUDE_CONFIG_DIR`, or `.caveman-active` under Claude config as the OpenCode source of truth, and instead uses an OpenCode/XDG-safe path or clearly injected plugin state path.",
      "max_score": 8
    },
    {
      "name": "Package layout",
      "description": "Generated package files live under `opencode-plugin/` by default, with `.opencode/` used only if explicitly documented as an optional local dogfooding harness.",
      "max_score": 8
    },
    {
      "name": "Package metadata",
      "description": "`opencode-plugin/package.json` is ESM, points `main`/`exports` at an existing plugin entrypoint, includes OpenCode-oriented keywords, and limits published files to runtime/package assets rather than `.claude/`, local config, tests, or unrelated agent metadata.",
      "max_score": 8
    },
    {
      "name": "Hook tests",
      "description": "Tests import or instantiate the OpenCode plugin and exercise OpenCode-like fixtures for both startup activation behavior and user prompt/mode tracking behavior.",
      "max_score": 8
    },
    {
      "name": "Scoped finish",
      "description": "The solution does not add GitHub Actions workflows, npm publishing automation, PR draft files, or claim that `opencode plugin <package>` is already publicly installable before publication.",
      "max_score": 8
    }
  ]
}

README.md

tile.json