Platforms · OpenCode

Self-contained `.opencode/` runtime with TypeScript plugins.

CafeKit installs a complete OpenCode runtime that does not share files with `.claude/`. Hooks become typed plugins loaded by OpenCode at session start.

Installed layout#

.opencode/
├── skills/         # Self-contained skill packs
├── agents/         # Subagent prompts (no hapo: prefix)
├── commands/       # Slash commands without hapo: prefix
├── plugins/        # TypeScript plugins (see below)
├── rules/          # Workflow, dev, docs, hook, state-sync rules
├── scripts/        # Helper scripts
├── references/     # Static lookup material
├── runtime.json    # Locale, paths, docs.maxLoc, gemini model
├── cafekit.json    # CafeKit marker + version
└── package.json    # Declares @opencode-ai/plugin
AGENTS.md           # Project-level operating instructions
opencode.json       # Merged with the installer (empty file is valid)

After install, plugin dependencies are installed automatically via bun install inside .opencode/.

TypeScript plugins#

Claude Code hooks are ported to typed OpenCode plugins:

PluginOpenCode eventPurpose
privacy-block.tstool.execute.beforeBlock reads of sensitive paths until user approves
inspect-block.tstool.execute.beforeGate broad inspection scans
state.tstool.execute.afterReject task done without verification receipt
docs-sync.tssession.createdFlag missing docs, sync hash drift
session.tssession.createdInject session banner and context
usage.tssession.createdTrack token/usage hints
rules.tssession.createdRefresh dynamic rules block inside AGENTS.md

OpenCode lacks a per-prompt injection channel, so rules.ts upserts a managed block in AGENTS.md between <!-- CAFEKIT DYNAMIC RULES START --> and <!-- CAFEKIT DYNAMIC RULES END -->. OpenCode auto-loads AGENTS.md per session, so the dynamic rules still reach the model at session start.

Commands#

OpenCode intentionally drops the hapo: prefix:

/question     /brainstorm    /specs       /develop
/test         /code-review   /sync        /debug
/hotfix       /docs          /inspect     /git

Plus all domain skills under /<skill>.

Detection#

The installer recognizes OpenCode when any of these exist:

  • .opencode/ directory
  • AGENTS.md at project root
  • opencode.json or opencode.jsonc at project root (empty file counts)

If only an empty opencode.json is present, the installer treats it as a valid marker and populates $schema, instructions: ["AGENTS.md"], and a permission block on first install.