{ "_comment": [ "TEMPLATE. Do not edit hooks/hooks.json by hand - it is generated from this file by", "`scripts/gen-hooks.mjs`, which runs as part of `npm run build` and on `glance sync-hooks`.", "", "Everything is a `command` hook, including the 13 passive recorders. That is not a style", "choice: an `http` hook cannot reach this daemon by any route. Grok Build's http runner", "(xai-grok-hooks/src/runner/http.rs, `validate_hook_url`) rejects every scheme but https,", "then resolves the host and refuses the resolved address if it is private, link-local or", "CGNAT - so plain http on loopback is out, and so is the tailnet, because *.ts.net resolves", "into 100.64/10 (and fd7a::/48, inside the blocked fc00::/7). Pointing a hook at the public", "https origin therefore fails upstream, before a request is ever sent. The runner also sends", "no request header but Content-Type, so such a hook could not authenticate itself even if it", "could connect.", "", "A command hook has none of those problems: it is a local process, so there is no URL to", "validate, no proxy in the path, and it can present the shared secret. It costs one Node", "start (~40ms) per event.", "", "SessionStart boots the daemon. PreToolUse is wired twice on purpose: one entry records", "every call for the timeline, and a second, narrowly matched entry runs the approval gate,", "because PreToolUse is the only blocking event and only a command hook can return a deny.", "", "Placeholders, written in the template as a name wrapped in double braces:", " APPROVAL_TIMEOUT_SECS derived from approval.timeoutMs in ~/.grok/glance/config.json.", " HOOK_TOKEN the secret from ~/.grok/glance/hook.secret, for a caller that", " cannot set a header: the daemon accepts it as a ?k= query", " parameter too. Nothing below uses it and no http hook can (see", " above); it stays because the daemon's ?k= path is real. Note the", " daemon also refuses any /hook/* request carrying x-forwarded-*,", " so a reverse-proxied transport is out as well. Using this", " placeholder makes the generated hooks.json secret-bearing, so", " gen-hooks writes it 0600 and it must not be committed.", "", "Do not spell those names with their braces anywhere in this comment block: the comment is", "copied verbatim into hooks.json, and substitution would happily expand it there too." ], "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-up.mjs\"", "timeout": 20 } ] } ], "PreToolUse": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] }, { "matcher": "^(Bash|Write|Edit|MultiEdit|NotebookEdit)$", "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-approve.mjs\"", "timeout": 125 } ] } ], "PostToolUse": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "PostToolUseFailure": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "PermissionDenied": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "Notification": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "StopFailure": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "SubagentStart": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "SubagentStop": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "PreCompact": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "PostCompact": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ], "SessionEnd": [ { "hooks": [ { "type": "command", "command": "node \"$GROK_PLUGIN_ROOT/bin/glance-record.mjs\"", "timeout": 5 } ] } ] } }