Skip to content

Conversation

@Gerkinfeltser
Copy link

Summary

  • Load both user global (~/.config/opencode/command-hooks.jsonc) and project (.opencode/command-hooks.jsonc) configs
  • Concatenate hooks by default — both run
  • Add overrideGlobal flag to suppress global hooks for same event
  • Add ignoreGlobalConfig flag to skip global config entirely

Note: Windows users will also need #1 merged for hooks to work at all.

Behavior

Scenario Result
Different hook IDs Both run (concatenation)
Same hook ID Project replaces global
overrideGlobal: true on hook Suppresses all global hooks for same event/phase+tool
ignoreGlobalConfig: true in project config Skips ~/.config/opencode/ entirely
Tool hook with tool: "*" + overrideGlobal Suppresses ALL global hooks for that phase

Example

// ~/.config/opencode/command-hooks.jsonc (global)
{
  "session": [
    { "id": "global-idle", "when": { "event": "session.idle" }, "run": "echo global" }
  ]
}

// .opencode/command-hooks.jsonc (project)
{
  "session": [
    { "id": "project-idle", "when": { "event": "session.idle" }, "run": "echo project" }
  ]
}
// Result: both hooks fire

To override all global hooks for an event:

{
  "session": [
    { 
      "id": "project-idle", 
      "when": { "event": "session.idle" }, 
      "run": "echo only this runs",
      "overrideGlobal": true
    }
  ]
}

Changes

  • src/types/hooks.ts — added overrideGlobal and ignoreGlobalConfig types
  • src/schemas.ts — added fields to Zod schemas
  • src/config/merge.ts — added overrideGlobal filtering logic
  • src/config/global.ts — loads both configs and merges them
  • tests/config.global.test.ts — 14 tests for merge behavior
  • README.md — updated docs

Testing

bun test tests/config.global.test.ts  # 14 pass
bun test                               # 99 pass, 6 pre-existing failures

- Load both ~/.config/opencode/command-hooks.jsonc and .opencode/command-hooks.jsonc
- Concatenate hooks by default (both run)
- Same hook ID: project replaces global
- overrideGlobal: true on hook suppresses all global hooks for same event/phase+tool
- ignoreGlobalConfig: true in project config skips global config entirely
- Tool hooks with tool: "*" and overrideGlobal override ALL global hooks for that phase

Tests: 14 passing for merge behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant