[PR #11525] feat: Add complete native hook system with all 12 Claude Code hooks #13823

Open
opened 2026-02-16 18:18:39 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/11525

State: open
Merged: No


This PR adds a native hook system to OpenCode that provides full Claude Code compatibility with all 12 lifecycle hooks, enabling the Claude Code tool ecosystem to work seamlessly with OpenCode.

All 12 Hooks Implemented

Session Lifecycle

  • SessionStart: Fired when a new session is initialized
  • SessionStop: Fired when a session completes

Tool Execution

  • PreToolUse: Fired before tool execution begins
  • PostToolUse: Fired after successful tool execution
  • PostToolUseFailure: Fired after tool execution fails

User Input

  • UserPromptSubmit: Fired when user submits a prompt

Automation Loop

  • Stop: Fired when the automation loop ends

Permissions

  • PermissionRequest: Fired before permission dialogs appear

Subagent Lifecycle

  • SubagentStart: Fired when a subagent starts
  • SubagentStop: Fired when a subagent stops

Context Management

  • PreCompact: Fired before context compaction

Notifications

  • Notification: Available for custom notifications

Changes

  • New HookService singleton that listens to the event bus and executes configured hook scripts
  • New hooks configuration key in opencode.jsonc with Claude Code compatible PascalCase naming
  • Hook scripts receive JSON payloads via stdin and run in isolated Bun subprocesses with configurable timeouts
  • Hook emissions added throughout the codebase at appropriate lifecycle points

Configuration Example

{
  "hooks": {
    "SessionStart": [{ "name": "init", "path": "~/.opencode/hooks/init.js", "enabled": true }],
    "PreToolUse": [{ "name": "validate", "path": "~/.opencode/hooks/validate.js", "enabled": true }],
    "SubagentStart": [{ "name": "track", "path": "~/.opencode/hooks/track.js", "enabled": true }]
  }
}

Motivation

  • Closes #5409 (SessionStart hook feature request)
  • Enables Claude Code ecosystem tools (like GSD) to run on OpenCode
  • Provides full extensibility without modifying core code

Implementation Notes

  • Hooks are non-blocking (run in background)
  • Each hook runs in its own sandboxed process
  • Supports ~ expansion in paths
  • Uses PascalCase naming for Claude Code compatibility
  • All hooks support timeout configuration (default 5s)

What does this PR do?

Please provide a description of the issue (if there is one), the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the pr.

If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!

How did you verify your code works?

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/11525 **State:** open **Merged:** No --- This PR adds a native hook system to OpenCode that provides full Claude Code compatibility with all 12 lifecycle hooks, enabling the Claude Code tool ecosystem to work seamlessly with OpenCode. ## All 12 Hooks Implemented ### Session Lifecycle - **SessionStart**: Fired when a new session is initialized - **SessionStop**: Fired when a session completes ### Tool Execution - **PreToolUse**: Fired before tool execution begins - **PostToolUse**: Fired after successful tool execution - **PostToolUseFailure**: Fired after tool execution fails ### User Input - **UserPromptSubmit**: Fired when user submits a prompt ### Automation Loop - **Stop**: Fired when the automation loop ends ### Permissions - **PermissionRequest**: Fired before permission dialogs appear ### Subagent Lifecycle - **SubagentStart**: Fired when a subagent starts - **SubagentStop**: Fired when a subagent stops ### Context Management - **PreCompact**: Fired before context compaction ### Notifications - **Notification**: Available for custom notifications ## Changes - New `HookService` singleton that listens to the event bus and executes configured hook scripts - New `hooks` configuration key in opencode.jsonc with Claude Code compatible PascalCase naming - Hook scripts receive JSON payloads via stdin and run in isolated Bun subprocesses with configurable timeouts - Hook emissions added throughout the codebase at appropriate lifecycle points ## Configuration Example ```json { "hooks": { "SessionStart": [{ "name": "init", "path": "~/.opencode/hooks/init.js", "enabled": true }], "PreToolUse": [{ "name": "validate", "path": "~/.opencode/hooks/validate.js", "enabled": true }], "SubagentStart": [{ "name": "track", "path": "~/.opencode/hooks/track.js", "enabled": true }] } } ``` ## Motivation - Closes #5409 (SessionStart hook feature request) - Enables Claude Code ecosystem tools (like GSD) to run on OpenCode - Provides full extensibility without modifying core code ## Implementation Notes - Hooks are non-blocking (run in background) - Each hook runs in its own sandboxed process - Supports ~ expansion in paths - Uses PascalCase naming for Claude Code compatibility - All hooks support timeout configuration (default 5s) ### What does this PR do? Please provide a description of the issue (if there is one), the changes you made to fix it, and why they work. It is expected that you understand why your changes work and if you do not understand why at least say as much so a maintainer knows how much to value the pr. **If you paste a large clearly AI generated description here your PR may be IGNORED or CLOSED!** ### How did you verify your code works?
yindo added the pull-request label 2026-02-16 18:18:39 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#13823