Skip to content

Commit b08d665

Browse files
docs: document extensions.yml hook configuration (#3563)
* docs: document extesnion.yml hook confriguration * docs: address hook confriguration review feedback * clarify auto execute hooks behavior * docs: clarify hook priority and condition behavior
1 parent aaf6bc2 commit b08d665

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

docs/reference/extensions.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,63 @@ To set up configuration for a newly installed extension, copy the template:
171171
cp .specify/extensions/<ext>/<ext>-config.template.yml \
172172
.specify/extensions/<ext>/<ext>-config.yml
173173
```
174+
## Project Extension and Hook Configuration
175+
176+
Spec Kit stores project-level extension registration and hook configuration in:
177+
178+
```text
179+
.specify/extensions.yml
180+
```
181+
The file contains installed extensions, global settings, and hooks that are surfaced before or after Spec Kit commands.
182+
183+
```yaml
184+
installed:
185+
- git
186+
- my-extension
187+
188+
settings:
189+
auto_execute_hooks: true
190+
191+
hooks:
192+
before_implement:
193+
- extension: git
194+
command: speckit.git.commit
195+
enabled: true
196+
optional: true
197+
priority: 10
198+
prompt: "Commit outstanding changes before implementation?"
199+
description: "Auto-commit before implementation"
200+
201+
after_implement:
202+
- extension: my-extension
203+
command: speckit.my-extension.verify
204+
enabled: true
205+
optional: false
206+
priority: 5
207+
description: "Run verification after implementation"
208+
```
209+
210+
### Configuration fields
211+
212+
The top-level `installed` list records extensions installed in the project. The `settings` mapping stores project-wide extension settings, and `hooks` groups hook registrations by event.
213+
214+
`auto_execute_hooks` defaults to `true`, but is currently reserved and is not consulted when hooks are surfaced or invoked.
215+
216+
Each hook entry supports the following fields:
217+
218+
| Field | Description |
219+
| --- | --- |
220+
| `extension` | ID of the extension that registered the hook. |
221+
| `command` | Extension command associated with the hook. |
222+
| `enabled` | Whether the hook is active. Hooks with `enabled: false` are skipped. |
223+
| `optional` | Whether the hook is optional. If `true`, the hook is presented with its `prompt` and can be skipped; if `false`, the hook is emitted as an automatic hook (includes `EXECUTE_COMMAND` markers). |
224+
| `priority` | Priority metadata for the hook. Values must be integers >= 1; invalid values fall back to the default priority `10`. Current command templates surface hooks in their configured YAML order and do not sort them by `priority`. |
225+
| `prompt` | Message shown when asking whether to run an optional hook. |
226+
| `description` | Human-readable explanation of what the hook does. |
227+
| `condition` | Optional expression evaluated by `HookExecutor` (using `config.<path>` or `env.<VAR>` with `is set`, `==`, or `!=`). Current command templates do not evaluate conditions and skip hooks with a non-empty condition. |
228+
Hook event names identify when a hook is invoked. They generally use `before_<command>` or `after_<command>`, such as `before_implement`, `after_implement`, `before_tasks`, and `after_tasks`.
229+
230+
`HookExecutor.get_hooks_for_event()` returns hooks ordered by `priority`, with lower values first. However, current command templates read hook lists directly and surface them in their configured YAML order rather than using priority ordering.
174231

175232
## FAQ
176233

0 commit comments

Comments
 (0)