feat: Git extension stage 1 — bundled extensions/git with hooks on all core commands#1941
feat: Git extension stage 1 — bundled extensions/git with hooks on all core commands#1941
extensions/git with hooks on all core commands#1941Conversation
extensions/git extension (opt-out, auto-enabled)
There was a problem hiding this comment.
Pull request overview
This PR migrates git/branching workflow logic into a bundled extensions/git/ extension and wires it into specify init as an auto-enabled (opt-out) migration step, aiming to decouple branching behavior from core and reduce platform-specific breakages.
Changes:
- Add a new
extensions/git/extension (manifest, commands, config template, and cross-platform scripts) for feature-branch creation/validation/remote detection. - Auto-install the bundled git extension during
specify initand bundle it into the wheel viapyproject.tomlforce-include. - Update the
/speckit.specifycommand template to consult extension enablement/config and prefer extension scripts with fallback behavior.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| templates/commands/specify.md | Updates specify command flow to check git extension enablement/config and prefer extension scripts. |
| src/specify_cli/init.py | Adds bundled-extension discovery + auto-install during specify init. |
| pyproject.toml | Bundles extensions/git into the wheel’s core_pack. |
| extensions/git/extension.yml | New extension manifest defining commands, hooks, and defaults. |
| extensions/git/config-template.yml | New user-facing config template for git extension settings. |
| extensions/git/README.md | Documentation for git extension usage, config, and behavior. |
| extensions/git/commands/speckit.git.feature.md | Command template for creating a feature branch via extension scripts. |
| extensions/git/commands/speckit.git.validate.md | Command template for validating branch naming conventions. |
| extensions/git/commands/speckit.git.remote.md | Command template for detecting git remote URL safely. |
| extensions/git/scripts/bash/create-new-feature.sh | Bash feature-creation script adapted for extension install locations. |
| extensions/git/scripts/bash/git-common.sh | Bash git-only helper functions extracted for reuse. |
| extensions/git/scripts/powershell/create-new-feature.ps1 | PowerShell feature-creation script adapted for extension install locations. |
| extensions/git/scripts/powershell/git-common.ps1 | PowerShell git-only helper functions extracted for reuse. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
All 9 review comments addressed in
All 818 tests pass, CodeQL clean. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
with tempfile.TemporaryDirectory() as tmpdir:
with tempfile.TemporaryDirectory() as tmpdir:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
All 7 review comments addressed in
All 818 tests pass, CodeQL clean. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
Both comments addressed in
All 818 tests pass. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot apply changes based on the comments in this thread |
Both comments addressed in
All 819 tests pass. |
- Create extensions/git/ with 5 commands: initialize, feature, validate, remote, commit - 18 hooks covering before/after for all 9 core commands - Scripts: create-new-feature, initialize-repo, auto-commit, git-common (bash + powershell) - Configurable: branch_numbering, init_commit_message, per-command auto-commit with custom messages - Add hooks to analyze, checklist, clarify, constitution, taskstoissues command templates - Allow hooks-only extensions (no commands required) - Bundle extension in wheel via pyproject.toml force-include - Resolve bundled extensions locally before catalog lookup - Remove planned-but-unimplemented before/after_commit hook refs - Update extension docs (API ref, dev guide, user guide) - 37 new tests covering manifest, install, all scripts (bash+pwsh), config reading, graceful degradation Stage 1: opt-in via 'specify extension add git'. No auto-install, no changes to specify.md or core git init code. Refs: #841, #1382, #1066, #1791, #1191
7396683 to
a084d09
Compare
extensions/git extension (opt-out, auto-enabled)extensions/git with hooks on all core commands
There was a problem hiding this comment.
Pull request overview
This PR introduces a bundled extensions/git extension to decouple Git/branching workflow behaviors from core logic, and wires extension hooks into the core command templates and CLI extension install flow to support opt-out/override workflows.
Changes:
- Allow extension manifests with hooks-only (no commands) and add coverage for that validation.
- Add a bundled
extensions/git/extension (manifest, commands, scripts, config template) plus tests validating install + cross-platform scripts. - Update core command templates and extension docs to recognize additional hook events and surface hooks in agent workflows; bundle the extension into the wheel and prefer bundled extensions during
specify extension add.
Show a summary per file
| File | Description |
|---|---|
| tests/test_extensions.py | Updates manifest validation tests for hooks-only behavior and revised error messaging. |
| tests/extensions/init.py | Declares extensions tests package. |
| tests/extensions/git/init.py | Declares git extension tests package. |
| tests/extensions/git/test_git_extension.py | Adds end-to-end tests for git extension manifest, install, and scripts (bash/pwsh). |
| src/specify_cli/extensions.py | Relaxes manifest validation to allow hooks-only extensions. |
| src/specify_cli/init.py | Adds bundled-extension locator and prefers bundled installs in extension add. |
| pyproject.toml | Bundles extensions/git into the wheel under core_pack/extensions/git. |
| templates/commands/analyze.md | Adds pre/post hook discovery/output instructions for analyze workflow. |
| templates/commands/checklist.md | Adds pre/post hook discovery/output instructions for checklist workflow. |
| templates/commands/clarify.md | Adds pre/post hook discovery/output instructions for clarify workflow. |
| templates/commands/constitution.md | Adds pre/post hook discovery/output instructions for constitution workflow. |
| templates/commands/taskstoissues.md | Adds pre/post hook discovery/output instructions for tasks-to-issues workflow. |
| extensions/git/extension.yml | Defines the bundled git extension: commands, hooks, defaults, metadata. |
| extensions/git/README.md | Documents the git extension’s purpose/config/usage. |
| extensions/git/config-template.yml | Provides default config for branch numbering + auto-commit behavior. |
| extensions/git/commands/speckit.git.feature.md | Adds command template for feature branch creation via extension scripts. |
| extensions/git/commands/speckit.git.validate.md | Adds command template for validating feature branch naming. |
| extensions/git/commands/speckit.git.remote.md | Adds command template for remote URL detection. |
| extensions/git/commands/speckit.git.initialize.md | Adds command template for initializing a repo via extension scripts. |
| extensions/git/commands/speckit.git.commit.md | Adds command template for auto-commit hook behavior. |
| extensions/git/scripts/bash/create-new-feature.sh | Extension-scoped bash implementation of feature creation. |
| extensions/git/scripts/bash/git-common.sh | Extension-scoped bash git helpers (has_git + branch validation). |
| extensions/git/scripts/bash/initialize-repo.sh | Extension-scoped bash repo initialization. |
| extensions/git/scripts/bash/auto-commit.sh | Extension-scoped bash auto-commit. |
| extensions/git/scripts/powershell/create-new-feature.ps1 | Extension-scoped PowerShell implementation of feature creation. |
| extensions/git/scripts/powershell/git-common.ps1 | Extension-scoped PowerShell git helpers (Test-HasGit/Test-FeatureBranch). |
| extensions/git/scripts/powershell/initialize-repo.ps1 | Extension-scoped PowerShell repo initialization. |
| extensions/git/scripts/powershell/auto-commit.ps1 | Extension-scoped PowerShell auto-commit. |
| extensions/EXTENSION-USER-GUIDE.md | Expands documented hook event list. |
| extensions/EXTENSION-DEVELOPMENT-GUIDE.md | Updates extension authoring guidance for commands vs hooks and hook events. |
| extensions/EXTENSION-API-REFERENCE.md | Updates API reference for expanded hook event taxonomy. |
| extensions/catalog.json | Adds git extension to catalog and bumps updated_at. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (5)
templates/commands/analyze.md:45
- Hook output hardcodes
/{command}as the invocation, but the CLI supports agent-specific skill invocation modes (e.g., Codex$speckit-..., Claude/{speckit-...}, Kimi/skill:speckit-...) as implemented inHookExecutor._render_hook_invocation. To avoid telling users to run the wrong thing, emit the correct invocation form (and/or include both raw command id and rendered invocation, likeEXECUTE_COMMAND_INVOCATION).
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
templates/commands/checklist.md:66
- Hook output hardcodes
/{command}as the invocation, but the CLI supports agent-specific skill invocation modes (e.g., Codex$speckit-..., Claude/{speckit-...}, Kimi/skill:speckit-...) as implemented inHookExecutor._render_hook_invocation. To avoid telling users to run the wrong thing, emit the correct invocation form (and/or include both raw command id and rendered invocation, likeEXECUTE_COMMAND_INVOCATION).
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
templates/commands/clarify.md:48
- Hook output hardcodes
/{command}as the invocation, but the CLI supports agent-specific skill invocation modes (e.g., Codex$speckit-..., Claude/{speckit-...}, Kimi/skill:speckit-...) as implemented inHookExecutor._render_hook_invocation. To avoid telling users to run the wrong thing, emit the correct invocation form (and/or include both raw command id and rendered invocation, likeEXECUTE_COMMAND_INVOCATION).
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
templates/commands/constitution.md:45
- Hook output hardcodes
/{command}as the invocation, but the CLI supports agent-specific skill invocation modes (e.g., Codex$speckit-..., Claude/{speckit-...}, Kimi/skill:speckit-...) as implemented inHookExecutor._render_hook_invocation. To avoid telling users to run the wrong thing, emit the correct invocation form (and/or include both raw command id and rendered invocation, likeEXECUTE_COMMAND_INVOCATION).
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
templates/commands/taskstoissues.md:45
- Hook output hardcodes
/{command}as the invocation, but the CLI supports agent-specific skill invocation modes (e.g., Codex$speckit-..., Claude/{speckit-...}, Kimi/skill:speckit-...) as implemented inHookExecutor._render_hook_invocation. To avoid telling users to run the wrong thing, emit the correct invocation form (and/or include both raw command id and rendered invocation, likeEXECUTE_COMMAND_INVOCATION).
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
```
- **Mandatory hook** (`optional: false`):
```
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
- Files reviewed: 32/32 changed files
- Comments generated: 11
- Fix commands property KeyError for hooks-only extensions - Fix has_git() operator precedence in git-common.sh - Align default commit message to '[Spec Kit] Initial commit' across config-template, extension.yml defaults, and both init scripts - Update README to reflect all 5 commands and 18 hooks
There was a problem hiding this comment.
Pull request overview
This PR introduces a bundled, opt-in Git extension (extensions/git/) and expands hook support so all core commands can participate in the extension hook lifecycle (before/after). It also updates extension-manifest validation to allow hooks-only extensions and adds tests covering the new bundled extension and hook behavior.
Changes:
- Bundle a new
gitextension (commands + hooks + bash/PowerShell scripts + config template) and makespecify extension add gitresolve locally before using the catalog. - Expand hook support documentation/templates to include hooks for
analyze,checklist,clarify,constitution, andtaskstoissues. - Add/adjust tests for hooks-only extensions and for the bundled git extension behaviors.
Show a summary per file
| File | Description |
|---|---|
tests/test_extensions.py |
Updates manifest validation tests to allow hooks-only extensions and adjust error message. |
tests/extensions/git/test_git_extension.py |
Adds comprehensive tests for bundled git extension manifest, install, and scripts. |
tests/extensions/git/__init__.py |
Marks git extension tests as a package. |
tests/extensions/__init__.py |
Marks extensions tests as a package. |
templates/commands/taskstoissues.md |
Adds before/after hook-check sections for task-to-issues flow. |
templates/commands/constitution.md |
Adds before/after hook-check sections for constitution flow. |
templates/commands/clarify.md |
Adds before/after hook-check sections for clarify flow. |
templates/commands/checklist.md |
Adds before/after hook-check sections for checklist flow. |
templates/commands/analyze.md |
Adds before/after hook-check sections for analyze flow. |
src/specify_cli/extensions.py |
Allows manifests with hooks-only; adjusts commands accessor defaulting. |
src/specify_cli/__init__.py |
Adds _locate_bundled_extension() and installs bundled extensions before catalog download. |
pyproject.toml |
Forces extensions/git into the wheel as core_pack/extensions/git. |
extensions/git/scripts/powershell/initialize-repo.ps1 |
Implements repo initialization (PowerShell) with config-driven commit message. |
extensions/git/scripts/powershell/git-common.ps1 |
Adds git detection + feature-branch validation helpers (PowerShell). |
extensions/git/scripts/powershell/create-new-feature.ps1 |
Implements feature branch creation (PowerShell) with sequential/timestamp numbering. |
extensions/git/scripts/powershell/auto-commit.ps1 |
Implements config-driven auto-commit hook (PowerShell). |
extensions/git/scripts/bash/initialize-repo.sh |
Implements repo initialization (bash) with config-driven commit message. |
extensions/git/scripts/bash/git-common.sh |
Adds git detection + feature-branch validation helpers (bash). |
extensions/git/scripts/bash/create-new-feature.sh |
Implements feature branch creation (bash) with sequential/timestamp numbering. |
extensions/git/scripts/bash/auto-commit.sh |
Implements config-driven auto-commit hook (bash). |
extensions/git/README.md |
Documents git extension commands, hooks, config, and install/disable usage. |
extensions/git/extension.yml |
Declares git extension metadata, commands, hooks, and defaults. |
extensions/git/config-template.yml |
Provides default git-config.yml template including per-event auto-commit config. |
extensions/git/commands/speckit.git.validate.md |
Adds validation command documentation for feature-branch naming. |
extensions/git/commands/speckit.git.remote.md |
Adds remote detection command documentation for GitHub integration. |
extensions/git/commands/speckit.git.initialize.md |
Adds initialize command documentation and script wiring. |
extensions/git/commands/speckit.git.feature.md |
Adds feature-branch command documentation and script wiring. |
extensions/git/commands/speckit.git.commit.md |
Adds auto-commit command documentation and script wiring. |
extensions/EXTENSION-USER-GUIDE.md |
Updates list of supported hook events (removes planned commit hooks). |
extensions/EXTENSION-DEVELOPMENT-GUIDE.md |
Updates guidance: commands optional if hooks exist; expands hook event list. |
extensions/EXTENSION-API-REFERENCE.md |
Updates hook event reference to include newly supported events. |
extensions/catalog.json |
Adds git extension entry for discoverability and updates timestamp. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 32/32 changed files
- Comments generated: 6
- Add type validation for provides.commands (must be list) and hooks (must be dict) in manifest _validate() - Tighten malformed timestamp detection in git-common.sh to catch 7-digit dates without trailing slug (e.g. 2026031-143022) - Pass REPO_ROOT to has_git/Test-HasGit in create-new-feature scripts - Fix initialize command docs: surface errors on git failures, only skip when git is not installed - Fix commit command docs: 'skips with a warning' not 'silently' - Add tests for commands:null and hooks:list rejection
There was a problem hiding this comment.
Pull request overview
Adds an opt-in, bundled Git extension (extensions/git) and expands the core hook surface so extensions can hook into all core commands (including analyze/checklist/clarify/constitution/taskstoissues). It also updates extension manifest validation to allow hooks-only extensions and adds tests around bundled extension installation and git scripts.
Changes:
- Bundle and catalog a new
gitextension (commands, hooks, bash/PowerShell scripts, config template, docs). - Expand hook support in core command templates by adding pre/post hook checks to additional commands.
- Allow extensions with no commands as long as they provide hooks, and add tests for these manifest rules plus bundled-extension installation.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/extensions.py |
Manifest validation now allows hooks-only extensions and adds type checks for provides.commands / hooks. |
src/specify_cli/__init__.py |
Adds bundled extension locator and installs bundled extensions before catalog downloads. |
pyproject.toml |
Forces extensions/git into the wheel under core_pack/extensions/git. |
extensions/git/** |
New bundled git extension: manifest, docs, config template, commands, and bash/PowerShell scripts. |
templates/commands/{analyze,checklist,clarify,constitution,taskstoissues}.md |
Adds hook pre/post checks so hooks can run on these commands too. |
extensions/EXTENSION-*.md |
Updates docs to reflect new hook events and hooks-only extensions. |
extensions/catalog.json |
Adds git to catalog metadata. |
tests/test_extensions.py |
Updates manifest validation tests for hooks-only rule and invalid hooks/commands shapes. |
tests/extensions/git/test_git_extension.py |
New test suite validating git extension manifest, install path, and scripts behavior. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 32/32 changed files
- Comments generated: 5
- Remove scripts frontmatter from command files (CommandRegistrar rewrites ../../scripts/ to .specify/scripts/ which points at core scripts, not extension scripts) - Update speckit.git.commit command to derive event name from hook context rather than using a static example - Clarify that hook argument passthrough works via AI agent context (the agent carries conversation state including user's original feature description)
There was a problem hiding this comment.
Pull request overview
Introduces a bundled, opt-in extensions/git extension that encapsulates Git branching/initialization/auto-commit behavior and wires extension hooks into additional core command templates, while updating manifest validation to allow hooks-only extensions and enabling local installation of bundled extensions.
Changes:
- Add bundled
extensions/git/(commands, scripts, config template, docs) plus comprehensive tests for install + script behavior. - Expand hook support across additional core command templates and update extension docs to reflect the new hook events.
- Update extension manifest validation to allow hooks-only extensions; add bundled-extension resolution for
specify extension add.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/extensions.py |
Allow hooks-only manifests; tighten provides.commands/hooks type validation. |
src/specify_cli/__init__.py |
Add bundled-extension locator and prefer bundled install in extension add. |
pyproject.toml |
Force-include bundled git extension into wheel core_pack/. |
extensions/catalog.json |
Add git extension entry and refresh catalog timestamp. |
extensions/EXTENSION-API-REFERENCE.md |
Document additional hook events; remove planned before_commit/after_commit. |
extensions/EXTENSION-DEVELOPMENT-GUIDE.md |
Update guidance: commands optional; hooks/commands requirement clarified; expand hook list. |
extensions/EXTENSION-USER-GUIDE.md |
Update available hook event list. |
templates/commands/analyze.md |
Add pre/post hook-check instructions for before_analyze/after_analyze. |
templates/commands/checklist.md |
Add pre/post hook-check instructions for before_checklist/after_checklist. |
templates/commands/clarify.md |
Add pre/post hook-check instructions for before_clarify/after_clarify. |
templates/commands/constitution.md |
Add pre/post hook-check instructions for before_constitution/after_constitution. |
templates/commands/taskstoissues.md |
Add pre/post hook-check instructions for before_taskstoissues/after_taskstoissues. |
tests/test_extensions.py |
Add manifest-validation tests for hooks-only + invalid shapes. |
tests/extensions/__init__.py |
Define test package. |
tests/extensions/git/__init__.py |
Define git extension test package. |
tests/extensions/git/test_git_extension.py |
New test suite for bundled git extension install + bash/pwsh scripts. |
extensions/git/extension.yml |
New git extension manifest (commands, hooks, config metadata, defaults). |
extensions/git/README.md |
User-facing documentation for the git extension. |
extensions/git/config-template.yml |
Sample configuration template for git behavior (branch numbering, auto-commit). |
extensions/git/commands/speckit.git.feature.md |
Command template for feature-branch creation (config-aware invocation). |
extensions/git/commands/speckit.git.initialize.md |
Command template for repository initialization. |
extensions/git/commands/speckit.git.validate.md |
Command template for branch validation. |
extensions/git/commands/speckit.git.remote.md |
Command template for remote URL detection. |
extensions/git/commands/speckit.git.commit.md |
Command template for per-event auto-commit. |
extensions/git/scripts/bash/create-new-feature.sh |
Extension-scoped bash feature-branch creation script. |
extensions/git/scripts/bash/git-common.sh |
Extension-scoped bash git helpers (has_git, branch validation). |
extensions/git/scripts/bash/initialize-repo.sh |
Extension-scoped bash repo init script. |
extensions/git/scripts/bash/auto-commit.sh |
Extension-scoped bash auto-commit script (config-driven). |
extensions/git/scripts/powershell/create-new-feature.ps1 |
Extension-scoped PowerShell feature-branch creation script. |
extensions/git/scripts/powershell/git-common.ps1 |
Extension-scoped PowerShell git helpers. |
extensions/git/scripts/powershell/initialize-repo.ps1 |
Extension-scoped PowerShell repo init script. |
extensions/git/scripts/powershell/auto-commit.ps1 |
Extension-scoped PowerShell auto-commit script (config-driven). |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 32/32 changed files
- Comments generated: 5
- Validate extension_id against ^[a-z0-9-]+$ in _locate_bundled_extension to prevent path traversal (security fix) - Move defaults under config.defaults in extension.yml to match ConfigManager._get_extension_defaults() schema - Ship git-config.yml in extension directory so it's copied during install (provides.config template isn't materialized by ExtensionManager) - Condition handling in hook templates: intentionally matches existing pattern from specify/plan/tasks/implement templates (not a new issue)
There was a problem hiding this comment.
Pull request overview
This PR introduces a bundled, opt-in extensions/git extension that encapsulates Spec Kit’s Git workflow (init/branch/validate/remote/auto-commit) and expands hook support so all core commands can participate in before/after extension hooks.
Changes:
- Add bundled
extensions/git/(manifest, commands, config templates, bash + PowerShell scripts) plus comprehensive extension-level tests. - Update extension manifest validation to allow hooks-only extensions (must provide at least one command or hook).
- Add hook-checking guidance to additional core command templates and enable local install of bundled extensions via
specify extension add <id>.
Show a summary per file
| File | Description |
|---|---|
| tests/test_extensions.py | Adds manifest validation tests for hooks-only and invalid hooks/commands types. |
| tests/extensions/git/test_git_extension.py | New test suite covering git extension manifest + scripts + bundled locator. |
| tests/extensions/git/init.py | Initializes git extension test package. |
| tests/extensions/init.py | Initializes extensions test package. |
| templates/commands/taskstoissues.md | Adds pre/post hook-check sections for tasks-to-issues command template. |
| templates/commands/constitution.md | Adds pre/post hook-check sections for constitution command template. |
| templates/commands/clarify.md | Adds pre/post hook-check sections for clarify command template. |
| templates/commands/checklist.md | Adds pre/post hook-check sections for checklist command template. |
| templates/commands/analyze.md | Adds hook-check guidance for analyze command template. |
| src/specify_cli/extensions.py | Allows manifests with hooks-only; adds stricter type checks for commands/hooks. |
| src/specify_cli/init.py | Adds _locate_bundled_extension() + installs bundled extensions before catalog fallback. |
| pyproject.toml | Force-includes extensions/git into wheel core_pack. |
| extensions/git/scripts/powershell/initialize-repo.ps1 | New PS repo init script for git extension. |
| extensions/git/scripts/powershell/git-common.ps1 | New PS git helper functions (has git, feature-branch validation). |
| extensions/git/scripts/powershell/create-new-feature.ps1 | New PS feature-branch creation script for git extension. |
| extensions/git/scripts/powershell/auto-commit.ps1 | New PS auto-commit script for git extension. |
| extensions/git/scripts/bash/initialize-repo.sh | New bash repo init script for git extension. |
| extensions/git/scripts/bash/git-common.sh | New bash git helper functions (has git, feature-branch validation). |
| extensions/git/scripts/bash/create-new-feature.sh | New bash feature-branch creation script for git extension. |
| extensions/git/scripts/bash/auto-commit.sh | New bash auto-commit script for git extension. |
| extensions/git/README.md | Documents git extension commands, hooks, config, and install/disable workflow. |
| extensions/git/git-config.yml | Default git extension configuration (auto-commit disabled by default). |
| extensions/git/extension.yml | Git extension manifest (commands + hooks + config template). |
| extensions/git/config-template.yml | Config template copied into project on install. |
| extensions/git/commands/speckit.git.validate.md | Command doc for branch validation behavior. |
| extensions/git/commands/speckit.git.remote.md | Command doc for remote URL detection behavior. |
| extensions/git/commands/speckit.git.initialize.md | Command doc for repo initialization behavior. |
| extensions/git/commands/speckit.git.feature.md | Command doc for feature-branch creation behavior. |
| extensions/git/commands/speckit.git.commit.md | Command doc for hook-driven auto-commit behavior. |
| extensions/EXTENSION-USER-GUIDE.md | Updates documented list of hook events (removes before/after_commit). |
| extensions/EXTENSION-DEVELOPMENT-GUIDE.md | Updates extension authoring guidance for hooks-only + expanded hook events. |
| extensions/EXTENSION-API-REFERENCE.md | Updates hook event reference list to include newly supported events. |
| extensions/catalog.json | Adds git extension to catalog for discoverability and updates updated_at. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 33/33 changed files
- Comments generated: 3
| | Command | Description | | ||
| |---------|-------------| | ||
| | `speckit.git.initialize` | Initialize a Git repository with a configurable commit message | | ||
| | `speckit.git.feature` | Create a feature branch with sequential or timestamp numbering | | ||
| | `speckit.git.validate` | Validate current branch follows feature branch naming conventions | | ||
| | `speckit.git.remote` | Detect Git remote URL for GitHub integration | | ||
| | `speckit.git.commit` | Auto-commit changes (configurable per-command enable/disable and messages) | | ||
|
|
||
| ## Hooks | ||
|
|
||
| | Event | Command | Optional | Description | | ||
| |-------|---------|----------|-------------| | ||
| | `before_constitution` | `speckit.git.initialize` | No | Init git repo before constitution | | ||
| | `before_specify` | `speckit.git.feature` | No | Create feature branch before specification | | ||
| | `before_clarify` | `speckit.git.commit` | Yes | Commit outstanding changes before clarification | | ||
| | `before_plan` | `speckit.git.commit` | Yes | Commit outstanding changes before planning | | ||
| | `before_tasks` | `speckit.git.commit` | Yes | Commit outstanding changes before task generation | | ||
| | `before_implement` | `speckit.git.commit` | Yes | Commit outstanding changes before implementation | | ||
| | `before_checklist` | `speckit.git.commit` | Yes | Commit outstanding changes before checklist | | ||
| | `before_analyze` | `speckit.git.commit` | Yes | Commit outstanding changes before analysis | | ||
| | `before_taskstoissues` | `speckit.git.commit` | Yes | Commit outstanding changes before issue sync | | ||
| | `after_constitution` | `speckit.git.commit` | Yes | Auto-commit after constitution update | | ||
| | `after_specify` | `speckit.git.commit` | Yes | Auto-commit after specification | | ||
| | `after_clarify` | `speckit.git.commit` | Yes | Auto-commit after clarification | | ||
| | `after_plan` | `speckit.git.commit` | Yes | Auto-commit after planning | | ||
| | `after_tasks` | `speckit.git.commit` | Yes | Auto-commit after task generation | | ||
| | `after_implement` | `speckit.git.commit` | Yes | Auto-commit after implementation | | ||
| | `after_checklist` | `speckit.git.commit` | Yes | Auto-commit after checklist | | ||
| | `after_analyze` | `speckit.git.commit` | Yes | Auto-commit after analysis | | ||
| | `after_taskstoissues` | `speckit.git.commit` | Yes | Auto-commit after issue sync | |
There was a problem hiding this comment.
The Markdown tables are written with a double leading pipe (|| ...), which renders as an extra empty column in most Markdown parsers. Use the standard | col | col | syntax for both the header and rows so the tables render correctly on GitHub.
| # Initialize | ||
| _git_out=$(git init -q 2>&1) || { echo "[specify] Error: git init failed: $_git_out" >&2; exit 1; } | ||
| _git_out=$(git add . 2>&1) || { echo "[specify] Error: git add failed: $_git_out" >&2; exit 1; } | ||
| _git_out=$(git commit -q -m "$COMMIT_MSG" 2>&1) || { echo "[specify] Error: git commit failed: $_git_out" >&2; exit 1; } |
There was a problem hiding this comment.
git commit will fail in an otherwise-empty repo ("nothing to commit") because the script doesn't use --allow-empty. Since this script is meant to initialize a repo reliably, consider adding --allow-empty (or ensuring at least one file exists) so initialization succeeds even when there are no tracked files yet.
| _git_out=$(git commit -q -m "$COMMIT_MSG" 2>&1) || { echo "[specify] Error: git commit failed: $_git_out" >&2; exit 1; } | |
| _git_out=$(git commit --allow-empty -q -m "$COMMIT_MSG" 2>&1) || { echo "[specify] Error: git commit failed: $_git_out" >&2; exit 1; } |
| if ($LASTEXITCODE -ne 0) { throw "git init failed: $out" } | ||
| $out = git add . 2>&1 | Out-String | ||
| if ($LASTEXITCODE -ne 0) { throw "git add failed: $out" } | ||
| $out = git commit -q -m $commitMsg 2>&1 | Out-String |
There was a problem hiding this comment.
git commit can fail in an otherwise-empty repo ("nothing to commit") because it isn't run with --allow-empty. Since this script is intended to initialize a repo robustly, consider using --allow-empty (or ensuring at least one file exists) so initialization succeeds even when there are no files to commit yet.
| $out = git commit -q -m $commitMsg 2>&1 | Out-String | |
| $out = git commit --allow-empty -q -m $commitMsg 2>&1 | Out-String |
Stage 1: Git Extension (opt-in, bundled)
Extracts Git branching operations into a self-contained
extensions/git/extension. This is stage 1 — the extension is opt-in viaspecify extension add git(resolves locally from the bundled copy, no network required). Core git init and branching code remains unchanged.Refs: #841, #1382, #1066, #1791, #1191
Extension structure (
extensions/git/)5 commands:
speckit.git.initializespeckit.git.featurespeckit.git.validatespeckit.git.remotespeckit.git.commit18 hooks across all 9 core commands:
before_constitutionspeckit.git.initializebefore_specifyspeckit.git.featurebefore_clarify/plan/tasks/implement/checklist/analyze/taskstoissuesspeckit.git.commitafter_constitution/specify/clarify/plan/tasks/implement/checklist/analyze/taskstoissuesspeckit.git.commitScripts (bash + powershell):
create-new-feature.{sh,ps1}— branch creation with sequential/timestamp numberinginitialize-repo.{sh,ps1}— git init with configurable commit messageauto-commit.{sh,ps1}— per-command auto-commit with config-driven enable/disable and custom messagesgit-common.{sh,ps1}— extractedhas_git()andcheck_feature_branch()helpersAll scripts capture git output and suppress it on success; full output is included in error messages on failure.
Configuration (
git-config.yml):branch_numbering: sequential or timestampinit_commit_message: custom initial commit messageauto_commit: per-command enable/disable with custom commit messages (all disabled by default)Hook system improvements
before_*/after_*hook support toanalyze,checklist,clarify,constitution, andtaskstoissues(previously onlyspecify,plan,tasks,implementhad hooks)before_commit/after_commit: These were documented as "planned" but never implemented and had no backing core command. Removed from API reference, user guide, and dev guideBundled extension install
pyproject.tomlforce-includesextensions/gitinto the wheel_locate_bundled_extension()resolves bundled extensions fromcore_pack/(wheel) orextensions/(source checkout)specify extension add gitresolves locally before falling back to catalog — no network neededcatalog.jsonfor discoverability viaspecify extension searchWhat stays in core (unchanged)
is_git_repo(),init_git_repo(),--branch-numberingflag,--no-gitflag,get_current_branch(),SPECIFY_FEATUREenv var,find_feature_dir_by_prefix(),specify.mdtemplate — all unchanged. The core{SCRIPT}flow continues to work as before.Disable/re-enable
Tests
37 new tests in
tests/extensions/git/test_git_extension.py:ExtensionManagerinitialize-repo.sh/.ps1— init, skip-if-exists, custom commit messagecreate-new-feature.sh/.ps1— sequential, timestamp, spec dir creation, increments, no-git degradation, dry-runauto-commit.sh/.ps1— disabled by default, per-command enable, custom messages, default fallback, no-changes skip, no-config skip, no-git skipgit-common.sh— has_git, check_feature_branch (sequential, timestamp, reject main, reject malformed)Stage 2 (future)
specify init(controlled by--no-git→ don't install git extension)git init/is_git_repo/init_git_repo—before_constitutionhook handles itspecify.md—before_specifyhook handles it viaspeckit.git.feature; changespecify.mdscript ref fromcreate-new-featuretocheck-prerequisitesonlycreate-new-featurescripts)