feat: add modifies_hooks support for extension hook overrides#2209
feat: add modifies_hooks support for extension hook overrides#2209dango85 wants to merge 1 commit intogithub:mainfrom
Conversation
Extensions can now declare a `modifies_hooks` section in extension.yml
to disable or set_optional hooks from other extensions during installation.
This solves conflicts like the worktree-parallel extension needing to
disable the git extension's `before_specify -> speckit.git.feature` hook,
which forces branch switching and breaks the worktree-first workflow.
Safety model:
- Requires explicit user consent (Y/N prompt) before applying modifications
- Non-TTY (CI) defaults to NO (fail-closed)
- Granular targeting: hook + extension + command triple required
- Limited actions: only disable and set_optional (no removal)
- Reason field is mandatory and shown in consent prompt
- Extra warning when modifying community (non-bundled) extension hooks
- Fully reversible: original state restored on extension removal
- Audit trail in registry via _modified_hooks metadata
Schema:
modifies_hooks:
- hook: before_specify
extension: git
command: speckit.git.feature
action: disable
reason: "Worktree-parallel keeps primary checkout stable"
Closes: related to github#61, github#1476
Made-with: Cursor
Declares modifies_hooks in extension.yml so that installing this extension automatically disables the git extension's before_specify -> speckit.git.feature hook (with explicit user consent). This keeps the primary checkout on a stable branch while worktrees handle feature branch isolation. Requires: github/spec-kit#2209 (modifies_hooks support) Made-with: Cursor
|
Are you aware that you can disable an extension? |
|
Thanks for the feedback @mnriem! Yes — though Today there's no per-hook granularity at the CLI level, so the only option is manually editing Happy to adjust the approach if there's a preferred direction — e.g., a |
Re-adds modifies_hooks to disable git before_specify on install with consent. Bumps extension to 1.2.2. Supersedes the 1.2.1 revert for users who want automatic hook coordination. Requires: github/spec-kit#2209 Made-with: Cursor
|
I am very hesitant to allow one extension to change the configuration of another. It creates a whole sleuth of other potentital problems with dependencies. I think the best approach here is to use a preset that overrides just the commands (either core command or extension command) you need to behave differently. That way you are in control of what happens. As otherwise any change to the Git extension could very easily break you? Note at 1.0.0 time the Git extension becomes an opt-in so you cannot rely on the fact it will be auto enabled then |
|
Thanks for the clear guidance — I agree. I won’t merge or pursue cross-extension configuration (one extension changing another’s hooks/config on install). It’s too easy to break when the Git extension changes, and it doesn’t fit Git becoming opt-in at 1.0.0. For parallel worktrees, the fix is explicit user control: e.g. set enabled: false on the Git extension’s before_specify → speckit.git.feature entry in .specify/extensions.yml when you need a stable primary checkout, and use git worktree add -b so feature branches don’t require git checkout on the shared root. I’ll treat any stronger “do X before specify” workflow as a preset that overrides only the commands that need to differ. I’m closing this PR; follow-up is documentation (and a separate preset repo/zip if useful), not more hook-override machinery in core. |
Summary
modifies_hookssection inextension.ymlto disable or set_optional hooks from other installed extensions duringspecify extension addbefore_specify -> speckit.git.featurehook (which forces branch switching, breaking the worktree-first workflow)Related Issues
This PR addresses a common pain point across many open issues — the inability for extensions to coordinate hook behavior, especially around git branch creation:
modifies_hookslets extension authors provide alternativesgit.featureto stay on the current branchmodifies_hooksprovides the mechanism for conditional branch behaviormodifies_hooksinstead of forking thespecifycommandmodifies_hooksprovides a granular alternative: keep git for commits, disable branch creation--no-gitflag--no-gitas a blunt instrument — extensions surgically disable specific hooksmodifies_hooksis the install-time hook automation mechanismmodifies_hooks: action: disableon the branch hook is exactly thismodifies_hookslets people disable git hooks selectivelySafety Model
hook+extension+commandtripledisableandset_optional(no removal, no arbitrary mutation)reasonfield required and shown in consent promptspecify extension remove_modified_hooksSchema
Consent UX
Test plan