Hook Manager
Manage the hooks that ship with the core plugin across Claude Code, Codex,
and Grok Build. The catalog source of truth is hooks/manifest.json in the
installed plugin — read it live rather than trusting a memorized list:
cat "$(ls -d ~/.claude/plugins/cache/b-open-io/core/*/ | sort -V | tail -1)hooks/manifest.json"
Each entry carries name, event, matcher, tier, runtimes, summary, and
description. Hooks register automatically when the plugin is installed;
this skill controls which ones actually run.
The config file
Per-hook enable/disable lives in a JSON config. Resolution order (first file
with an explicit true/false verdict for a hook wins):
$BOPEN_HOOKS_CONFIG— explicit override (tests, scripts)<project>/.claude/bopen-hooks.json— per-project (Claude)<project>/.grok/bopen-hooks.json— per-project (Grok)~/.claude/core/hooks-config.json— per-user (Claude)~/.grok/core/hooks-config.json— per-user (Grok)
{
"version": 1,
"hooks": {
"bouncer": true,
"damage-control": true,
"publish-gate": true,
"agent-browser-solo": true,
"session-context": true,
"hammertime": true,
"browser-intent": true
}
}
A hook is disabled ONLY by an explicit false. Missing files, missing keys,
or unparseable JSON all mean enabled — a broken config must never silently
switch the guards off. Changes take effect on the next hook invocation; no
restart is required.
First-time setup (the [BOPEN-HOOKS-SETUP] directive)
When session context carries [BOPEN-HOOKS-SETUP], the user has no config
yet. Do not interrupt their task; offer setup at a natural pause. The flow:
- Read the manifest (command above) and present the hooks in two tiers via
AskUserQuestion (multiSelect):
- Guards (recommended on): entries with
tier: "guard"— they prevent work loss, secret exposure, and unticketed publishes. - Workflow (preference): entries with
tier: "workflow".
- Guards (recommended on): entries with
- Run the prerequisite checks below and fold findings into the recommendation (e.g. agent-browser-solo without agent-browser installed silently falls back to native WebFetch — still safe to leave on).
- Write
~/.claude/core/hooks-config.json(Claude/Codex) or~/.grok/core/hooks-config.json(Grok) with the full hooks map — include every hook with an explicit boolean, even the all-defaults case. Writing the file is what dismisses the setup notice permanently.
Enabling / disabling a hook
Edit the user config (or project config for repo-scoped changes) with the Read and Write tools — read, flip the boolean, write back. Create the file from the template above when it does not exist. Never edit files inside the plugin cache; updates overwrite them.
Expect a confirmation prompt on every config write: damage-control treats these files as ask-tier so guards can never be disarmed without the user's explicit yes (on Codex the write is denied outright — have the user edit the file themselves). This is by design; do not route around it.
Warn before disabling guards: bouncer stops git reset --hard-class work
loss, damage-control enforces zero-access paths like .env, publish-gate
blocks unticketed npm/on-chain publishes. Disabling them is the user's call,
but say plainly what protection goes away.
Diagnosis
When a hook misbehaves or the user asks "why did X get blocked/skipped":
# Which config verdict applies to a hook?
for f in "$BOPEN_HOOKS_CONFIG" ./.claude/bopen-hooks.json ./.grok/bopen-hooks.json ~/.claude/core/hooks-config.json ~/.grok/core/hooks-config.json; do
[ -f "$f" ] && echo "$f: $(jq -r '.hooks["<name>"] // "no verdict"' "$f")"
done
# Prerequisites
command -v jq || echo "jq missing — hooks fail open without it"
command -v agent-browser || echo "agent-browser missing — agent-browser-solo falls back to native WebFetch"
[ -n "$LINEAR_API_KEY" ] || echo "LINEAR_API_KEY unset — publish-gate fails closed on gated publishes"
command -v python3 || echo "python3 missing — hammertime and JSON escaping degrade"
- Hard denies surface to the model as structured permission denials; on the Codex runtime they arrive as stderr JSON with exit 2. Both are by design.
- hammertime also has its own controls —
Skill(core:hammertime)and thehammertime:manageskill — for rule-level tuning beyond on/off. - The definitive behavior reference for every hook is its script header in
the plugin's
hooks/directory; read it before guessing.
What this skill never does
- Never copies hook files into
~/.claude— hooks ship with the plugin and update throughclaude plugin update core@b-open-io. - Never edits
hooks/*.sh,claude-hooks.json, or anything in the plugin cache. - Never disables a guard hook without telling the user what it protected.