Skip to content

epic: OpenCode harness support — manifest, contract injection, skills/commands, guards, sub-agent dispatch #316

Description

@thewrz

This was written agentically; verify its assertions:

Why

Agent Kit ships two harness surfaces (Claude Code via .claude-plugin/, Codex via .codex-plugin/). OpenCode is the third harness already in live use on this project's fleet (OpenCode + open-weight Qwen models on the local cluster), and a phase-1 prototype already exists: two OpenCode sessions ("AgentKit OpenCode plugin spec execution", "OpenCode plugin fixes and verification", 2026-08-19, qwen3-coder/qwen3.8-27b) executed docs/superpowers/specs/2026-08-18-agentkit-opencode-plugin-spec.md and produced a working contract-injection plugin. Its branch was deleted but both commits survive unreferenced in the object store — 18106a2 (initial) and 7db1a90 (post-review fixes) — recoverable with git branch feat/opencode-adapter 7db1a90.

Verified architecture (2026-08-20, docs + @opencode-ai/plugin typings)

  • Plugin shape (typings): Plugin = (input: PluginInput, options?) => Promise<Hooks>; PluginInput carries client, project, directory, worktree, $ (Bun shell), serverUrl. PluginModule = { id?, server: Plugin }. A tool() helper is exported for custom tools.
  • Loading (docs): opencode.json "plugin" array (npm, auto-installed via Bun to ~/.cache/opencode/node_modules/) or plugin directories (docs currently say .opencode/plugins/ and ~/.config/opencode/plugins/). Config sources merge with project overriding global.
  • Hooks (typings — authoritative; the docs page omits several): chat.message, chat.params, experimental.chat.system.transform (alters the system prompt array — the injection point the prototype used, confirmed real), experimental.chat.messages.transform, tool.execute.before, tool.execute.after, tool.definition, permission.ask, command.execute.before, shell.env, event, config, tool, auth.
  • Skills: native skill tool; discovery includes Claude-compatible paths — .claude/skills/<name>/SKILL.md, ~/.claude/skills/... — plus .opencode/skills/ and .agents/skills/. Frontmatter: name (lowercase alphanumeric+hyphens, ≤64, must match dir) and description (≤1024) required.
  • Agents: .opencode/agents/*.md (+ ~/.config/opencode/agents/), frontmatter description (required), mode: primary|subagent|all, model: provider/model-id, temperature, permission; sub-agents invoked by @-mention, the task tool, or automatically by description.
  • Commands: .opencode/commands/*.md (+ global), frontmatter template (required), description, agent, model, subtask; $ARGUMENTS/$1..$n placeholders; !`cmd` shell interpolation runs at project root.
  • Instructions: AGENTS.md is NOT auto-loaded; the "instructions" config array references files explicitly.
  • Known churn risk: the injection hook is experimental.*-prefixed, and the docs/typings disagree on the hook list and on plugin/ vs plugins/ directory naming — every slice re-verifies its exact identifiers from the installed typings at implementation time, never from this epic.

Prototype findings worth inheriting (from the session cache)

  1. $ must come from PluginInput — a const { $ } = this; inside a plain function throws outside try/catch and rejects the hook on every message.
  2. Bun shell: stdin is a readonly WritableStream property (not a method); there is no .timeout() — feed stdin via file redirection (bash -c 'script < file') and bound time with Promise.race or coreutils timeout.
  3. Export shape vs PluginModule ({ id?, server }) needs loader evidence before choosing default-export.

Slices

# Slice Blocked by
S1 Packaging: OpenCode plugin manifest + build surface —
S2 Harness identity: opencode in harness-id, contract, spawn-contract —
S3 Contract-injection plugin (productionize the phase-1 prototype) S1, S2
S4 Skills + commands surface (native skill tool + /command wrappers) S3
S5 Guard parity via tool.execute.before/after S3
S6 Sub-agent dispatch parity (worker agents + task tool) S2, S4

Sub-issues carry the per-slice spec; this epic closes when all six merge.

🤖 Co-authored by Claude Fable 5.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/skillsThe three skills and their proceduresenhancementNew feature or requestp2Wanted before public release

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions