Skip to content

Commit 69ea6b8

Browse files
committed
fix: wire after_tasks and after_implement hook events into command templates (#1701)
The HookExecutor backend in extensions.py was fully implemented but check_hooks_for_event() was never called by anything — the core command templates had no instructions to check .specify/extensions.yml. Add a final step to templates/commands/tasks.md (step 6, after_tasks) and templates/commands/implement.md (step 10, after_implement) that instructs the AI agent to: - Read .specify/extensions.yml if it exists - Filter hooks.{event} to enabled: true entries - Evaluate any condition fields and skip non-matching hooks - Output the RFC-specified hook message format, including EXECUTE_COMMAND: markers for mandatory (optional: false) hooks Bumps version to 0.1.7.
1 parent 56deda7 commit 69ea6b8

4 files changed

Lines changed: 62 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@ Recent changes to the Specify CLI and templates are documented here.
77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10+
## [0.1.7] - 2026-02-26
11+
12+
### Fixed
13+
14+
- **Extension hooks never triggered (#1701)**: Wired `after_tasks` and `after_implement` hook events into their respective command templates
15+
- `templates/commands/tasks.md` now includes a final step that reads `.specify/extensions.yml`, evaluates registered `after_tasks` hooks (respecting `enabled` flag and `condition`), and outputs the correct hook message format — including `EXECUTE_COMMAND:` markers for mandatory hooks
16+
- `templates/commands/implement.md` does the same for `after_implement` hooks
17+
- The `HookExecutor` backend in `extensions.py` was already complete; only the template wiring was missing
18+
1019
## [0.1.6] - 2026-02-23
1120

1221
### Fixed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "specify-cli"
3-
version = "0.1.6"
3+
version = "0.1.7"
44
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
55
requires-python = ">=3.11"
66
dependencies = [

templates/commands/implement.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,29 @@ You **MUST** consider the user input before proceeding (if not empty).
136136
- Report final status with summary of completed work
137137
138138
Note: This command assumes a complete task breakdown exists in tasks.md. If tasks are incomplete or missing, suggest running `/speckit.tasks` first to regenerate the task list.
139+
140+
10. **Check for extension hooks**: After completion validation, check if `.specify/extensions.yml` exists in the project root.
141+
- If it exists, read it and look for entries under the `hooks.after_implement` key
142+
- Filter to only hooks where `enabled: true`
143+
- For each remaining hook, evaluate any `condition` value; skip the hook if the condition is not met
144+
- For each executable hook, output the following based on its `optional` flag:
145+
- **Optional hook** (`optional: true`):
146+
```
147+
## Extension Hooks
148+
149+
**Optional Hook**: {extension}
150+
Command: `/{command}`
151+
Description: {description}
152+
153+
Prompt: {prompt}
154+
To execute: `/{command}`
155+
```
156+
- **Mandatory hook** (`optional: false`):
157+
```
158+
## Extension Hooks
159+
160+
**Automatic Hook**: {extension}
161+
Executing: `/{command}`
162+
EXECUTE_COMMAND: {command}
163+
```
164+
- If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently

templates/commands/tasks.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,32 @@ You **MUST** consider the user input before proceeding (if not empty).
6363
- Suggested MVP scope (typically just User Story 1)
6464
- Format validation: Confirm ALL tasks follow the checklist format (checkbox, ID, labels, file paths)
6565

66+
6. **Check for extension hooks**: After tasks.md is generated, check if `.specify/extensions.yml` exists in the project root.
67+
- If it exists, read it and look for entries under the `hooks.after_tasks` key
68+
- Filter to only hooks where `enabled: true`
69+
- For each remaining hook, evaluate any `condition` value; skip the hook if the condition is not met
70+
- For each executable hook, output the following based on its `optional` flag:
71+
- **Optional hook** (`optional: true`):
72+
```
73+
## Extension Hooks
74+
75+
**Optional Hook**: {extension}
76+
Command: `/{command}`
77+
Description: {description}
78+
79+
Prompt: {prompt}
80+
To execute: `/{command}`
81+
```
82+
- **Mandatory hook** (`optional: false`):
83+
```
84+
## Extension Hooks
85+
86+
**Automatic Hook**: {extension}
87+
Executing: `/{command}`
88+
EXECUTE_COMMAND: {command}
89+
```
90+
- If no hooks are registered or `.specify/extensions.yml` does not exist, skip silently
91+
6692
Context for task generation: {ARGS}
6793
6894
The tasks.md should be immediately executable - each task must be specific enough that an LLM can complete it without additional context.

0 commit comments

Comments
 (0)