npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-hooks

v1.1.0

Published

OpenCode hooks plugin - all hooks from oh-my-opencode without agents/tools/MCPs

Downloads

192

Readme

Opencode Hooks

A minimal fork of oh-my-opencode containing only the hook infrastructure - the Claude Code compatible hook system for OpenCode plugins.


TABLE OF CONTENTS

  1. 📖 OVERVIEW
  2. 🔧 HOOK EVENTS
  3. ✅ INSTALLATION & SETUP
  4. 📦 USAGE PATTERNS
  5. ⚙️ CONFIGURATION
  6. 🔨 API REFERENCE
  7. 📋 WHAT'S INCLUDED VS EXCLUDED
  8. 📚 RESOURCES

1. 📖 OVERVIEW

What This Package Provides

This package extracts the hook infrastructure from oh-my-opencode, giving you Claude Code compatible hooks without the full plugin's agents, tools, and MCP integrations.

┌─────────────────────────────────────────────────────────────────────────────┐
│                         HOOK EXECUTION FLOW                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  User Prompt → UserPromptSubmit hooks → Claude processes                    │
│                                              │                              │
│                                              ▼                              │
│                                    Tool Call Requested                      │
│                                              │                              │
│                                              ▼                              │
│                                    PreToolUse hooks                         │
│                                    (can block/modify)                       │
│                                              │                              │
│                                              ▼                              │
│                                    Tool Executes                            │
│                                              │                              │
│                                              ▼                              │
│                                    PostToolUse hooks                        │
│                                    (can modify output)                      │
│                                              │                              │
│                                              ▼                              │
│                                    Session Idle                             │
│                                              │                              │
│                                              ▼                              │
│                                    Stop hooks                               │
│                                    (can inject prompts)                     │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Why Use This?

| Use Case | Full oh-my-opencode | oh-my-opencode-hooks | | -------------------------- | ------------------- | -------------------- | | Claude Code hook compat | ✅ | ✅ | | Custom agents (OmO, etc.) | ✅ | ❌ | | MCP integrations | ✅ | ❌ | | Minimal dependencies | ❌ (7+ deps) | ✅ (1 dep) | | Bundle size | ~500KB | ~48KB | | Build your own hook plugin | Overkill | ✅ Perfect |


2. 🔧 HOOK EVENTS

The Four Hook Types

| Hook Event | When It Fires | Can Block? | Can Modify? | | ------------------ | ------------------------ | ---------- | ---------------- | | PreToolUse | Before tool execution | ✅ Yes | ✅ Tool input | | PostToolUse | After tool execution | ⚠️ Warn | ✅ Tool output | | UserPromptSubmit | When user submits prompt | ✅ Yes | ✅ Inject content | | Stop | When session goes idle | ✅ Yes | ✅ Inject prompt |

Hook Input/Output Structure

// PreToolUse - Runs before each tool call
interface PreToolUseInput {
  session_id: string
  tool_name: string           // e.g., "Edit", "Bash", "Read"
  tool_input: Record<string, unknown>
  cwd: string
  hook_event_name: "PreToolUse"
}

// Hook can return:
// - exit code 0: allow
// - exit code 1: ask user
// - exit code 2: deny/block

// PostToolUse - Runs after each tool call
interface PostToolUseInput {
  session_id: string
  tool_name: string
  tool_input: Record<string, unknown>
  tool_response: { title?: string; output?: string }
  transcript_path?: string    // Full session transcript
  cwd: string
  hook_event_name: "PostToolUse"
}

// UserPromptSubmit - Runs when user sends a message
interface UserPromptSubmitInput {
  session_id: string
  prompt: string
  cwd: string
  hook_event_name: "UserPromptSubmit"
}

// Stop - Runs when session becomes idle
interface StopInput {
  session_id: string
  stop_hook_active: boolean
  todo_path?: string          // Path to todo file
  cwd: string
  hook_event_name: "Stop"
}

3. ✅ INSTALLATION & SETUP

Installation

# Using bun (recommended)
bun add oh-my-opencode-hooks

# Using npm
npm install oh-my-opencode-hooks

# Local development (already built)
# Just reference the dist folder in opencode.json

OpenCode Configuration

Add to your opencode.json:

{
  "plugin": [
    ".opencode/oh-my-opencode-hooks/dist/index.js"
  ]
}

Build From Source

cd .opencode/oh-my-opencode-hooks
bun install
bun run build

4. 📦 USAGE PATTERNS

Pattern 1: Direct Plugin Export (Simplest)

Use the default export as your OpenCode plugin:

import OhMyOpenCodeHooksPlugin from "oh-my-opencode-hooks"

// This enables all Claude Code hooks automatically
export default OhMyOpenCodeHooksPlugin

Pattern 2: Hook Factory (Recommended)

Use the hook factory for more control:

import type { Plugin } from "@opencode-ai/plugin"
import { createClaudeCodeHooksHook } from "oh-my-opencode-hooks"

const MyPlugin: Plugin = async (ctx) => {
  // Create hooks with optional configuration
  const claudeHooks = createClaudeCodeHooksHook(ctx, {
    // Disable specific hook types if needed
    disabledHooks: ["Stop"]  // or true to disable all
  })

  return {
    "chat.message": claudeHooks["chat.message"],
    "tool.execute.before": claudeHooks["tool.execute.before"],
    "tool.execute.after": claudeHooks["tool.execute.after"],
    event: claudeHooks.event,
    
    // Add your own hooks alongside
    config: async (config) => {
      // Your config modifications
    }
  }
}

export default MyPlugin

Pattern 3: Individual Hook Executors (Advanced)

Execute hooks manually for custom integrations:

import { 
  executePreToolUseHooks,
  executePostToolUseHooks,
  executeUserPromptSubmitHooks,
  executeStopHooks,
  loadClaudeHooksConfig,
  loadPluginExtendedConfig
} from "oh-my-opencode-hooks"

// Load hook configurations
const claudeConfig = await loadClaudeHooksConfig()
const extendedConfig = await loadPluginExtendedConfig()

// Execute PreToolUse hooks
const preResult = await executePreToolUseHooks({
  sessionId: "session-123",
  toolName: "Edit",
  toolInput: { file_path: "/src/index.ts", content: "..." },
  cwd: process.cwd(),
}, claudeConfig, extendedConfig)

if (preResult.decision === "deny") {
  console.log("Blocked by hook:", preResult.reason)
  // Don't execute the tool
}

if (preResult.modifiedInput) {
  // Use modified input instead
}

Pattern 4: Message Injection

Inject synthetic messages into the conversation:

import { injectHookMessage } from "oh-my-opencode-hooks"

// Inject a message that appears as if the user sent it
const success = injectHookMessage(
  sessionID,
  "<system-reminder>Remember to follow the coding standards.</system-reminder>",
  {
    agent: "general",
    model: { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" },
    path: { cwd: process.cwd(), root: "/" }
  }
)

5. ⚙️ CONFIGURATION

Configuration File Locations

Hooks are configured via Claude Code compatible settings files:

| Location | Scope | Priority | | ----------------------------- | ------------- | -------- | | ~/.claude/settings.json | User (global) | Base | | .claude/settings.json | Project | Override | | .claude/settings.local.json | Local | Highest |

Settings File Structure

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "~/hooks/validate-edit.sh" }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "~/hooks/log-tool-use.sh" }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "~/hooks/inject-context.sh" }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "~/hooks/session-end.sh" }
        ]
      }
    ]
  }
}

Matcher Patterns

| Pattern | Matches | Example Tools | | ------------- | ------------------- | ----------------- | | * | All tools | Any | | Edit | Exact match | Edit only | | Edit\|Write | Multiple tools (OR) | Edit or Write | | Bash* | Wildcard | Bash, BashSession | | *Read* | Contains | Read, TodoRead |

Extended Configuration

Additional configuration via .opencode/opencode-cc-plugin.json:

{
  "disabledHooks": {
    "PreToolUse": [".*secret.*"],
    "PostToolUse": [],
    "UserPromptSubmit": [],
    "Stop": []
  }
}

6. 🔨 API REFERENCE

Core Exports

// Main hook factory
export { createClaudeCodeHooksHook } from "./hooks/claude-code-hooks"

// Hook executors
export { executePreToolUseHooks } from "./hooks/claude-code-hooks/pre-tool-use"
export { executePostToolUseHooks } from "./hooks/claude-code-hooks/post-tool-use"
export { executeUserPromptSubmitHooks } from "./hooks/claude-code-hooks/user-prompt-submit"
export { executeStopHooks } from "./hooks/claude-code-hooks/stop"

// Config loaders
export { loadClaudeHooksConfig } from "./hooks/claude-code-hooks/config"
export { loadPluginExtendedConfig } from "./hooks/claude-code-hooks/config-loader"

// Message injection
export { injectHookMessage } from "./features/hook-message-injector"

// Utilities
export { log } from "./shared/logger"
export { executeHookCommand } from "./shared/command-executor"
export { transformToolName } from "./shared/tool-name"

Type Exports

// Hook event types
export type { ClaudeHookEvent }  // "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop"

// Input types (what hooks receive)
export type { PreToolUseInput, PostToolUseInput, UserPromptSubmitInput, StopInput }

// Output types (what hooks return)
export type { PreToolUseOutput, PostToolUseOutput, StopOutput }

// Result types (after execution)
export type { PreToolUseResult, PostToolUseResult, UserPromptSubmitResult, StopResult }

// Context types
export type { PreToolUseContext, PostToolUseContext, UserPromptSubmitContext, StopContext }

// Config types
export type { ClaudeHooksConfig, HookMatcher, HookCommand, PluginConfig }

Utility Functions

| Function | Purpose | Example | | -------------------- | ------------------------------------ | ------------------------------------- | | log(msg, data?) | Write to plugin log file | log("Hook fired", { tool: "Edit" }) | | executeHookCommand | Run a hook command with stdin | Execute shell scripts | | transformToolName | Convert to Claude Code format | "webfetch""WebFetch" | | injectHookMessage | Inject message into conversation | Add synthetic user messages | | cacheToolInput | Cache input between pre/post hooks | Internal state management | | getTranscriptPath | Get transcript file path for session | ~/.claude/transcripts/{id}.jsonl | | getTodoPath | Get todo file path for session | ~/.claude/todos/{id}.json |


7. 📋 WHAT'S INCLUDED VS EXCLUDED

Included (28 files)

src/
├── hooks/claude-code-hooks/     # Core hook system (12 files)
│   ├── index.ts                 # createClaudeCodeHooksHook factory
│   ├── types.ts                 # All type definitions
│   ├── config.ts                # Claude settings loader
│   ├── config-loader.ts         # Extended config loader
│   ├── plugin-config.ts         # Default config (zsh settings)
│   ├── pre-tool-use.ts          # PreToolUse execution
│   ├── post-tool-use.ts         # PostToolUse execution
│   ├── user-prompt-submit.ts    # UserPromptSubmit execution
│   ├── stop.ts                  # Stop hook execution
│   ├── tool-input-cache.ts      # Input caching between hooks
│   ├── transcript.ts            # Transcript management
│   └── todo.ts                  # Todo file management
│
├── features/hook-message-injector/  # Message injection (4 files)
│   ├── index.ts
│   ├── injector.ts
│   ├── types.ts
│   └── constants.ts
│
└── shared/                      # Utilities (8 files)
    ├── index.ts
    ├── logger.ts
    ├── command-executor.ts
    ├── hook-disabled.ts
    ├── pattern-matcher.ts
    ├── snake-case.ts
    ├── tool-name.ts
    └── deep-merge.ts

Excluded (from oh-my-opencode)

| Component | Files | Why Excluded | | ----------------------- | ----- | --------------------------------- | | src/agents/ | 12 | OmO, oracle, librarian agents | | src/auth/ | 15 | Google Antigravity authentication | | src/tools/ | 5 | Background tools, OmO caller | | src/mcp/ | 3 | MCP server integrations | | src/features/loaders/ | 12 | Agent/command/MCP/skill loaders | | src/hooks/ (specific) | 70+ | Individual hook implementations | | Heavy dependencies | 6 | ast-grep, picomatch, hono, etc. |

Dependency Comparison

| Dependency | oh-my-opencode | oh-my-opencode-hooks | | ------------------------------- | -------------- | -------------------- | | @opencode-ai/plugin | ✅ | ✅ | | @ast-grep/cli | ✅ | ❌ | | @ast-grep/napi | ✅ | ❌ | | @code-yeongyu/comment-checker | ✅ | ❌ | | @openauthjs/openauth | ✅ | ❌ | | hono | ✅ | ❌ | | picomatch | ✅ | ❌ | | zod | ✅ | ❌ |


8. 📚 RESOURCES

Related Documentation

| Resource | URL | | ----------------------- | ---------------------------------------------------- | | oh-my-opencode (parent) | https://github.com/code-yeongyu/oh-my-opencode | | OpenCode Plugin Docs | https://opencode.ai/docs/plugins | | OpenCode Plugin Events | https://opencode.ai/docs/plugins#events | | Claude Code Hooks Spec | https://docs.anthropic.com/en/docs/claude-code/hooks |

File Locations

| File Type | Location | | --------------- | --------------------------------------- | | Plugin log | /tmp/oh-my-opencode.log | | Transcripts | ~/.claude/transcripts/{session}.jsonl | | Todos | ~/.claude/todos/{session}.json | | User config | ~/.claude/settings.json | | Project config | .claude/settings.json | | Extended config | .opencode/opencode-cc-plugin.json |


Summary

oh-my-opencode-hooks gives you Claude Code compatible hooks for OpenCode without the full oh-my-opencode plugin overhead:

// Minimal usage - just import and export
import OhMyOpenCodeHooksPlugin from "oh-my-opencode-hooks"
export default OhMyOpenCodeHooksPlugin

Configure hooks in ~/.claude/settings.json and they'll execute automatically on tool calls, prompts, and session events.


MIT License - Forked from oh-my-opencode by YeonGyu-Kim