2026-04-05 14:04:21 +09:00
# src/plugin/ — 10 OpenCode Hook Handlers + Hook Composition
2026-02-18 01:26:19 +09:00
2026-05-08 12:08:42 +09:00
**Generated: ** 2026-05-08
2026-02-18 01:26:19 +09:00
## OVERVIEW
2026-05-08 12:08:42 +09:00
Core glue layer. Files assemble the 10 OpenCode hook handlers and compose the 5-tier hook system into the `PluginInterface` . Each handler file maps to one OpenCode hook type.
2026-02-18 01:26:19 +09:00
## HANDLER FILES
| File | OpenCode Hook | Purpose |
|------|---------------|---------|
2026-05-08 12:08:42 +09:00
| `config.ts` | `config` | 6-phase config loading pipeline (delegates to `plugin-handlers/` ) |
| `tool-registry.ts` | `tool` | 20– 39 tools assembled with config gates (team-mode +12, task system +4, hashline +1, interactive_bash +1, look_at +1) |
| `chat-message.ts` | `chat.message` | First-message variant resolution, session setup, keyword detection trigger |
| `chat-params.ts` | `chat.params` | Anthropic effort, think mode, runtime fallback model override |
| `chat-headers.ts` | `chat.headers` | Copilot `x-initiator` header injection |
| `event.ts` | `event` | Session lifecycle (created/deleted/idle/error/status), openclaw dispatch, runtime fallback |
| `tool-execute-before.ts` | `tool.execute.before` | Pre-tool guards |
| `tool-execute-after.ts` | `tool.execute.after` | Post-tool hooks (truncation, comment-checker, hashline read tagging, json-error-recovery) |
| `messages-transform.ts` | `experimental.chat.messages.transform` | Context injection, thinking-block validation, tool-pair validation, keyword detection |
| `session-compacting.ts` | `experimental.session.compacting` | Context + todo preservation across compaction |
| `skill-context.ts` | (helper) | Skill/browser/category context shared with tool creation |
2026-02-18 01:26:19 +09:00
## HOOK COMPOSITION (hooks/ subdir)
| File | Tier | Count |
|------|------|-------|
2026-05-08 12:08:42 +09:00
| `create-session-hooks.ts` | Session | 24 |
2026-04-05 14:04:21 +09:00
| `create-tool-guard-hooks.ts` | Tool Guard | 14 |
| `create-transform-hooks.ts` | Transform | 5 |
2026-02-18 01:26:19 +09:00
| `create-skill-hooks.ts` | Skill | 2 |
2026-05-08 12:08:42 +09:00
| `create-core-hooks.ts` | Aggregator | Session + Guard + Transform = 43 |
`createContinuationHooks()` (7) lives in `src/create-hooks.ts` next to `createCoreHooks()` and `createSkillHooks()` .
2026-02-18 01:26:19 +09:00
## SUPPORT FILES
| File | Purpose |
|------|---------|
| `available-categories.ts` | Build `AvailableCategory[]` for agent prompt injection |
| `session-agent-resolver.ts` | Resolve which agent owns a session |
| `session-status-normalizer.ts` | Normalize session status across OpenCode versions |
2026-05-08 12:08:42 +09:00
| `recent-synthetic-idles.ts` | Dedup rapid synthetic idle events |
2026-02-18 01:26:19 +09:00
| `unstable-agent-babysitter.ts` | Track unstable agent behavior across sessions |
| `types.ts` | `PluginContext` , `PluginInterface` , `ToolsRecord` , `TmuxConfig` |
2026-02-19 18:41:37 +09:00
| `ultrawork-model-override.ts` | Ultrawork mode model override logic |
| `ultrawork-db-model-override.ts` | DB-level model override for ultrawork |
2026-03-06 17:59:05 +09:00
| `config-handler.ts` | Runtime config loading and caching |
2026-05-08 12:08:42 +09:00
| `normalize-tool-arg-schemas.ts` | Coerce tool arg schemas into a normalized shape |
## TOOL REGISTRATION GATES
``` typescript
// src/plugin/tool-registry.ts
const taskToolsRecord = isTaskSystemEnabled ( config ) ? { task_create , task_get , task_list , task_update } : { }
const hashlineToolsRecord = config . hashline_edit ? { edit : createHashlineEditTool ( ctx ) } : { }
const teamModeToolsRecord = config . team_mode ? . enabled ? { team_create , team_delete , team_shutdown_request , team_approve_shutdown , team_reject_shutdown , team_send_message , team_task_create , team_task_list , team_task_update , team_task_get , team_status , team_list } : { }
const lookAt = isMultimodalLookerEnabled ? { look_at : createLookAt ( ctx ) } : { }
const interactiveBashTool = interactiveBashEnabled ? { interactive_bash } : { }
const allTools = {
. . . builtinTools , // 6 LSP
. . . createGrepTools ( ctx ) ,
. . . createGlobTools ( ctx ) ,
. . . createAstGrepTools ( ctx ) ,
. . . createSessionManagerTools ( ctx ) ,
. . . backgroundTools , // 2 background_*
call_omo_agent , task ,
. . . lookAt ,
skill_mcp , skill ,
. . . interactiveBashTool ,
. . . teamModeToolsRecord , // +12 conditional
. . . taskToolsRecord , // +4 conditional
. . . hashlineToolsRecord , // +1 conditional
}
```
2026-02-18 01:26:19 +09:00
## KEY PATTERNS
2026-05-08 12:08:42 +09:00
- Each handler exports a function receiving `(hookRecord, ctx, pluginConfig, managers)` → returns the OpenCode hook function.
- Handlers iterate over hook records, calling each hook with `(input, output)` in registration order.
- `safeHook()` wrapper isolates hook errors so one broken hook does not crash the chain.
- `filterDisabledTools(allTools, disabled_tools)` prunes tools listed in `disabled_tools` config.
- `experimental.max_tools` cap trims tool count when set (selects the highest-priority tools).