Skip to content

feat: wire after_specify and after_plan hook events into command templates#1825

Open
davidniu-0914 wants to merge 2 commits intogithub:mainfrom
davidniu-0914:feature/add-spec-plan-hooks
Open

feat: wire after_specify and after_plan hook events into command templates#1825
davidniu-0914 wants to merge 2 commits intogithub:mainfrom
davidniu-0914:feature/add-spec-plan-hooks

Conversation

@davidniu-0914
Copy link

Description

This PR aligns the extension hooks documentation and command templates for the specify and plan commands, resolving Issue #1788. It ensures that all core command templates (specify.md, plan.md, tasks.md,
implement.md) contain consistent CRITICAL execution instructions for mandatory hooks, preventing AI agents from proceeding before hook execution. Additionally, it synchronizes the project version to 0.2.1 across
pyproject.toml and all extension guides to match the upstream repository.

Testing

  • Verified markdown template rendering and hook logic consistency across all modified command files.
  • Confirmed version consistency in pyproject.toml and documentation.
  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (describe below)

This PR was prepared with the assistance of Gemini CLI to synchronize version numbers across multiple files, standardize hook instructions in markdown templates for behavioral consistency, and ensure
documentation accuracy relative to the implemented features.

…lan (github#1788)

- Update EXTENSION-API-REFERENCE.md to reflect current hook implementation status.
- Add before_tasks and before_implement hooks to EXTENSION-DEVELOPMENT-GUIDE.md.
- Standardize CRITICAL execution instructions for mandatory hooks across all templates (specify, plan, tasks, implement).
- Sync documentation versions and pyproject.toml to 0.2.1 to match upstream.
- Update Last Updated dates in extension guides.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Spec Kit command templates and extension documentation so that the lifecycle hook events for before_specify/after_specify and before_plan/after_plan are represented consistently alongside existing hook points, and bumps the project/docs version to 0.2.1.

Changes:

  • Add pre- and post- hook instructions for specify and plan command templates (before_* and after_* events).
  • Strengthen “mandatory hook” execution instructions across core templates (add explicit CRITICAL “execute immediately” language).
  • Bump version to 0.2.1 and update extension guides + changelog accordingly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
templates/commands/specify.md Adds before_specify and after_specify hook instructions + CRITICAL execution requirements.
templates/commands/plan.md Adds before_plan and after_plan hook instructions + CRITICAL execution requirements.
templates/commands/tasks.md Adds CRITICAL execution requirement wording for mandatory hooks.
templates/commands/implement.md Adds CRITICAL execution requirement wording for mandatory hooks.
src/specify_cli/extensions.py Updates docstrings/examples for hook event names to include specify/plan events.
pyproject.toml Bumps package version to 0.2.1.
extensions/EXTENSION-USER-GUIDE.md Updates stated minimum/version references and last-updated metadata.
extensions/EXTENSION-DEVELOPMENT-GUIDE.md Expands documented hook points to include specify/plan + before_implement, updates examples.
extensions/EXTENSION-API-REFERENCE.md Documents additional standard hook events and adds CRITICAL mandatory-hook instruction.
CHANGELOG.md Adds an Unreleased entry for the new hook wiring.
Comments suppressed due to low confidence (2)

templates/commands/plan.md:87

  • The post-plan hook filtering here will drop hooks that omit enabled (which are enabled by default in HookExecutor) and will skip all hooks that set condition, even though the codebase supports condition evaluation. This makes conditional hooks impossible to trigger from the template-driven workflow.
   - Filter to only hooks where `enabled: true`
   - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
     - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
     - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
   - For each executable hook, output the following based on its `optional` flag:

templates/commands/specify.md:33

  • Hook filtering in the template doesn’t match the actual hook config behavior in HookExecutor: hooks default to enabled when the enabled field is missing (h.get('enabled', True)), so instructing the agent to keep only enabled: true would incorrectly drop hooks without an explicit enabled key. Also, skipping hooks with a non-empty condition means conditional hooks will never run from the template flow even though the codebase supports condition evaluation; consider treating conditions as evaluatable (same rules as HookExecutor.should_execute_hook) or at least not skipping them outright.
- Filter to only hooks where `enabled: true`
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
  - If the hook has no `condition` field, or it is null/empty, treat the hook as executable
  - If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +218 to +223
- Filter to only hooks where `enabled: true`
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
- For each executable hook, output the following based on its `optional` flag:
- **Optional hook** (`optional: true`):
Comment on lines +33 to +38
- Filter to only hooks where `enabled: true`
- For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions:
- If the hook has no `condition` field, or it is null/empty, treat the hook as executable
- If the hook defines a non-empty `condition`, skip the hook and leave condition evaluation to the HookExecutor implementation
- For each executable hook, output the following based on its `optional` flag:
- **Optional hook** (`optional: true`):
@mnriem mnriem self-requested a review March 13, 2026 12:51
Copy link
Collaborator

@mnriem mnriem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback. If not applicable, please explain why

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants