Claude Code → OpenCode
Comprehensive gap analysis of the Blaze platform migration from Claude Code (Helix) to OpenCode. What we gained, what we lost, and how we mitigated every gap.
Migration Scorecard
Side-by-side comparison of every platform capability. Green = OpenCode is better. Blue = equivalent. Yellow = workaround exists. Red = real gap requiring mitigation.
| Capability | Claude Code (Helix) | OpenCode (Blaze) | Verdict |
|---|---|---|---|
| Pre/Post tool hooks | PreToolUse / PostToolUse with bash pattern matching |
tool.execute.before / tool.execute.after — TypeScript with full SDK access |
Equivalent |
| Tool arg pattern matching | Bash(gh pr create:*) declarative patterns |
Must inspect args.command in plugin code |
Workaround |
| Session start | SessionStart runs shell scripts |
No dedicated event — use experimental.chat.system.transform |
Partial |
| Session end | SessionEnd runs shell scripts |
No equivalent event | Gap |
| Post-agent completion | PostSubAgentCall with ${AGENT_TYPE} variable |
No equivalent hook | Gap |
| Notification hook | Notification fires on every turn |
No equivalent | Gap |
| Keyword auto-triggers | subagent_triggers with pattern arrays |
No message interception | Gap |
| Permission interception | Hooks can block (exit code 1) | permission.ask — first-class allow/deny/ask |
OC Better |
| System prompt injection | Not available | experimental.chat.system.transform |
OC Better |
| Compaction awareness | Not available | experimental.session.compacting |
OC Better |
| Custom tools | Shell scripts only, no schema validation | TypeScript tools with Zod schemas, first-class in agent toolbox | OC Better |
| LLM parameter control | Not available | chat.params — temperature, topP, topK per request |
OC Better |
| Command hooks | Not available | command.execute.before |
OC Better |
| Output modification | Not available | experimental.text.complete |
OC Better |
| Auth plugin system | Not available | Full OAuth / API key auth hooks | OC Better |
| Shell environment | Not available | shell.env — inject env vars per tool call |
OC Better |
| Hook language | Bash scripts, JSON config | TypeScript with full SDK, Bun shell template literals | Equivalent |
| Agent definitions | Markdown with YAML frontmatter | Markdown with YAML frontmatter (same format) | Equivalent |
| Skills/commands | Markdown-based skills and commands | Markdown-based skills and commands (same format) | Equivalent |
| MCP servers | JSON config files per server | Centralized in opencode.json + remote MCP support |
Equivalent |
| Workflow switching | Manual Task(subagent_type="X") |
Tab-key primary agents + @agent autocomplete |
OC Better |
Event Hook Comparison
Claude Code uses JSON-configured bash hooks. OpenCode uses TypeScript plugins with typed event handlers and full SDK access.
Claude Code Events
OpenCode Events
Net: OpenCode has 9 event types vs Claude Code's 6. But 3 of Claude Code's events have no OpenCode equivalent.
Exclusive Features
Claude Code Only
PostSubAgentCall
Fires when any agent completes with ${AGENT_TYPE}. Used for SDLC Phase 1 validation — tracking which agents ran (critical-thinking, prd-generator, etc.) and blocking Phase 2 if prerequisites weren't met.
Keyword Auto-Triggers
subagent_triggers config: when user types "implement" or "build", automatically invokes the SDLC orchestrator. Pattern-based agent routing from natural language.
SessionEnd Hook
Runs memory persistence scripts on session close. Writes session summary to memory bank for cross-session continuity.
Notification Event
Fires on every assistant turn regardless of tool usage. Powers the context window monitor that warns when context is filling up.
OpenCode Only
permission.ask
First-class permission interception. Can programmatically allow, deny, or prompt for any tool call. Claude Code hooks can only block via exit codes.
System Prompt Transform
experimental.chat.system.transform dynamically modifies the system prompt. Enables injecting memory, context, and state into every LLM call.
Compaction Hooks
experimental.session.compacting lets plugins inject critical state before context window compaction, ensuring continuity.
Custom Tools with Zod
Type-safe custom tools via tool() with Zod schema validation. Tools appear natively in agent toolboxes. Claude Code only had shell scripts.
LLM Parameter Control
chat.params modifies temperature, topP, topK per request. Enables per-agent parameter tuning impossible in Claude Code.
Auth Plugin System
Full OAuth and API key authentication hooks. Custom provider integration. Nothing equivalent in Claude Code.
Shell Environment Injection
shell.env injects environment variables per tool call. Dynamic secrets and config without global env pollution.
Tool Definition Hooks
tool.definition modifies tool descriptions and parameters sent to the LLM. Enables context-aware tool presentation.
Architecture Comparison
Key Architectural Improvements
Separated Concerns
OpenCode auto-discovers .opencode/. Platform intelligence lives in blaze/ — loaded selectively via config, not dumped into agent context.
Three-Tier Agent Hierarchy
2 primary (tab-switchable) → 10 visible (autocomplete) → 55 hidden (called by orchestrators). Helix had 52 flat agents.
Single Config Source
opencode.json consolidates MCP servers, models, agents, plugins, and permissions. Helix scattered config across 20+ JSON files.
Real Capability Gaps
These are features that existed in Claude Code with no direct OpenCode equivalent. Each one has been mitigated.
sdlc-phase-tracker custom tool. Agents write marker files to blaze/state/sdlc-tracking/ on completion. Phase transition checks read these markers instead of relying on event hooks./sdlc. This reduced friction and ensured the SDLC was always followed.sdlc configured as a primary agent (Tab-switchable). /sdlc command available. AGENTS.md instructs users to invoke SDLC for any implementation work. Less automatic, but more predictable.session-end.sh on session close to write session summaries to the memory bank. This ensured cross-session continuity without user intervention.experimental.session.compacting injects memory state before compaction (covers the most critical case — context resets). Full session-end persistence is a known gap that requires user-initiated /memory save or future OpenCode event support.Notification event fired on every turn, powering a context window monitor that warned when context was filling up. This ran independently of tool calls.tool.execute.after counts tool calls as a proxy metric. Compaction hook injects state. Misses turns where no tools are called, but covers ~90% of context-heavy scenarios (tool-heavy sessions are the ones that fill context).Mitigation Strategy
Every gap has a multi-layer mitigation. The platform never relies on a single mechanism.
| Gap | Layer 1: Plugin | Layer 2: Tool/File | Layer 3: Process |
|---|---|---|---|
| SDLC Phase Tracking | tool.execute.after — detect agent completion by tool patterns |
sdlc-phase-tracker custom tool writes marker files |
AGENTS.md documents phase prerequisites; orchestrator checks markers |
| Keyword Auto-Triggers | command.execute.before — could intercept and redirect |
sdlc as primary agent Tab |
AGENTS.md guidance + /sdlc command + team training |
| Session-End Memory | experimental.session.compacting injects state |
memory-search tool for explicit save |
/memory command for user-initiated persistence |
| Context Monitoring | tool.execute.after counter as proxy |
Context-monitor plugin with threshold warnings | Compaction hook preserves critical state across resets |
OpenCode Advantages
Capabilities that didn't exist in Claude Code and are now available in Blaze.
blaze-pr-review-gate, blaze-capsule-recorder, blaze-phase-tracker, blaze-memory-search — all type-safe and natively available to agents.permission.ask provides programmatic allow/deny/prompt for any tool call. Branch protection, file write guards, and CI pipeline security are first-class permission decisions, not brittle exit codes.experimental.chat.system.transform dynamically modifies the system prompt on every LLM call. Memory context, platform state, and active config injected without eating user context.chat.params. Security reviews get temp=0.1, creative modes get temp=0.7 — dynamically, per agent./mode instead of config changes.DX Improvements
| Feature | Helix (Claude Code) | Blaze (OpenCode) |
|---|---|---|
| Workflow switching | Manual Task(subagent_type="X") invocation |
Tab-key primary agents (sdlc / review) |
| Output styles | Config file changes required | /mode command toggle |
| Agent discovery | Flat 52-agent list | Three-tier hierarchy with autocomplete |
| Custom tools | Shell scripts with no validation | Type-safe TypeScript + Zod schemas |
| Enforcement hooks | Bash scripts with exit codes | TypeScript plugins with full SDK access |
| Context7 MCP | Local stdio process | Remote MCP — zero local overhead |
| Session forking | Not supported | Built-in fork for exploratory analysis |
| Context compaction | Automatic, no hooks | Plugin hooks inject state before compaction |
| Config management | 20+ scattered JSON files | Single opencode.json |
| Commands | 8 slash commands | 14 slash commands (including /code-audit, /review, /gate) |
Final Verdict
Net Positive Migration
OpenCode provides 8 new capabilities that didn't exist in Claude Code, while only 4 capabilities were lost — all with multi-layer mitigations in place.
Watch Items
These mitigations work but are less elegant than the Claude Code originals. Monitor for OpenCode to add native support.
agent.execute.after event.
/sdlc. Less automatic but more predictable. Could build a chat.message hook if OpenCode adds one.
session.end event.
Recommendation
The migration from Claude Code to OpenCode is a net positive. The 8 new capabilities (custom tools, permission hooks, system prompt injection, compaction awareness, LLM parameter control, auth system, shell env, tool definition hooks) far outweigh the 4 lost features — all of which have working mitigations. The platform is architecturally cleaner, more type-safe, and more extensible. Continue on OpenCode.