Synced from monorepo
Synced from monorepo Changes: - Report invalid MCP server config instead of failing startup - Keep completed terminal output when the gateway connection is lost - Show a duration-only detail view for single-task task output - Don't let a stale registry turn counter hide local sessions - Raise the file-descriptor soft limit on Linux and log effective limits at startup - Stop aborting when HTTP client construction fails - Make session thread and runtime spawn failures recoverable - Fix main-prompt paste parity in the question freeform input - Fire SessionEnd hooks on /exit and headless quit - Embed the deployment-config signing public key - Repaint paste-chip background on inline panel inputs - Security: prevent acceptEdits from auto-approving agent writes into the always-trusted global hook root - Fix stacked "Worked for" markers so parks render as status and turns close with exactly one marker - Parse hooks from config files - Add a remote kill-switch for managed-config signature verification - Security: fix workspace file-reference resolution bypassing workspace filesystem confinement Source-Revision: d02693a856a54f1030695b36b91d276e96b30b23
This commit is contained in:
parent
6e38642082
commit
47348d13ec
138 changed files with 7283 additions and 5796 deletions
|
|
@ -68,9 +68,12 @@ Hooks are discovered from several places (all are merged):
|
|||
| Project | `<project>/.grok/hooks/*.json` | Requires trust | Per-repo automation |
|
||||
| Project | `<project>/.claude/settings.json` (and `settings.local.json`) | Requires trust | Claude compatibility (configurable) |
|
||||
| Project | `<project>/.cursor/hooks.json` | Requires trust | Cursor compatibility (configurable) |
|
||||
| Config | `~/.grok/config.toml` | Always | Your hooks alongside the rest of your config |
|
||||
| Config | `managed_config.toml` (`$GROK_HOME` and `/etc/grok`) | Always | Organization-distributed hooks (server-synced and on-device) |
|
||||
| Config | `requirements.toml` (user and system) | Always | Organization-distributed hooks in the requirements layer |
|
||||
| Plugin | Bundled inside installed plugins | Per-plugin | Shared team hooks |
|
||||
|
||||
The Claude and Cursor hook sources are scanned by default. To disable scanning for a specific vendor, set `[compat.<vendor>] hooks = false` in `~/.grok/config.toml` or the corresponding environment variable. See [Configuration](05-configuration.md#harness-compatibility) for details.
|
||||
Config-file hooks live in the same TOML your organization already controls; see [Hooks in Config Files](#hooks-in-config-files) for the format. The compatible vendor hook sources are scanned by default. To disable scanning for a specific vendor, set `[compat.<vendor>] hooks = false` in `~/.grok/config.toml` or the corresponding environment variable. See [Configuration](05-configuration.md#harness-compatibility) for details.
|
||||
|
||||
**Trusting a project**: The first time you open a project with hooks, you must trust it before its project hooks will run -- until then they are silently skipped. Grant trust by running `/hooks-trust` (or launching with `--trust`); the decision is recorded in the unified folder-trust store (`~/.grok/trusted_folders.toml`), the same gate that governs repo-local MCP/LSP servers. Global hooks in `~/.grok/hooks/` are always trusted and need no entry. This prevents untrusted repos from running arbitrary code.
|
||||
|
||||
|
|
@ -168,6 +171,47 @@ A matcher keeps its original name too, so `Bash` matches both `Bash` and `run_te
|
|||
|
||||
---
|
||||
|
||||
## Hooks in Config Files
|
||||
|
||||
Hooks can also live directly in your Grok config, so a team can distribute them with the rest of their configuration instead of shipping separate JSON files. The same `hooks` object is read from three TOML files:
|
||||
|
||||
| File | Tier | Who sets it |
|
||||
|------|------|-------------|
|
||||
| `~/.grok/config.toml` | User | You |
|
||||
| `managed_config.toml` (`$GROK_HOME`, `/etc/grok`) | Managed / system | Your organization |
|
||||
| `requirements.toml` (user and system) | Requirements | Your organization |
|
||||
|
||||
The TOML is structurally identical to the JSON hook object, so an existing hook transliterates directly:
|
||||
|
||||
```toml
|
||||
[[hooks.PreToolUse]]
|
||||
matcher = "Bash|Write|Edit"
|
||||
hooks = [
|
||||
{ type = "command", command = "/opt/guard/pretooluse.sh", timeout = 10 },
|
||||
]
|
||||
```
|
||||
|
||||
Each matcher group is a `[[hooks.<Event>]]` entry with an optional `matcher` and an inner `hooks` array of handlers. The handler fields (`type`, `command`, `url`, `timeout`, `env`) and event names are exactly the same as the [JSON format](#the-hook-json-format).
|
||||
|
||||
TOML offers two equivalent notations for the inner handlers, and both parse to the identical structure. The inline-table array shown above is recommended: it reads best for the common single-handler case. The nested array-of-tables form is also accepted:
|
||||
|
||||
```toml
|
||||
[[hooks.PreToolUse]]
|
||||
matcher = "Bash|Write|Edit"
|
||||
[[hooks.PreToolUse.hooks]]
|
||||
type = "command"
|
||||
command = "/opt/guard/pretooluse.sh"
|
||||
timeout = 10
|
||||
```
|
||||
|
||||
Prefer the inline form to avoid repeating the `[[hooks.<Event>.hooks]]` header for each handler.
|
||||
|
||||
- **Additive across layers.** Every layer's hooks run; a lower-priority layer adds hooks but never replaces another layer's block. A hook defined identically in more than one layer is deduplicated, keeping the highest-authority copy.
|
||||
- **Provenance labels.** Config hooks appear in `/hooks` tagged by origin (`managed:`, `requirements/user:`, `user:`, and so on) so you can see which layer contributed each one.
|
||||
- **No read-time expansion.** A literal `${VAR}` in a `command` or `url` reaches the hook runner unchanged, matching JSON hook-file semantics; the runner performs the single expansion.
|
||||
|
||||
---
|
||||
|
||||
## Writing Hook Scripts
|
||||
|
||||
### Input
|
||||
|
|
|
|||
Loading…
Reference in a new issue