Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Commands are shown here in `/speckit.*` form, but the exact invocation depends o
## Recommended Process

> [!TIP]
> **Context Awareness**: Spec Kit tracks the active feature by the feature directory recorded in `.specify/feature.json` (overridable with the `SPECIFY_FEATURE_DIRECTORY` environment variable). Commands resolve the feature from that state, **not** from the checked-out Git branch — no Git required. The opt-in **git** extension adds numbered feature branches (e.g. `001-feature-name`) for organizing work in version control, but the active feature is still whichever directory that state points to; `git checkout` alone does not change it. To point commands at a different feature, update `.specify/feature.json` (or set `SPECIFY_FEATURE_DIRECTORY`).
> **Context Awareness**: Spec Kit tracks the active feature by the feature directory recorded in `.specify/feature.json` (overridable with the `SPECIFY_FEATURE_DIRECTORY` environment variable). Commands resolve the feature from that state, **not** from the checked-out Git branch — no Git required. Set a per-feature `FEATURE_ID` such as `ENHANCEMENT-XYZ` when invoking `/speckit.specify` to replace the default numeric/timestamp prefix; it is normalized to lowercase for the directory and branch. The opt-in **git** extension uses the same identifier for its branch when enabled. The active feature is still whichever directory `.specify/feature.json` points to; `git checkout` alone does not change it.

After installing Spec Kit, each command below is a step in the process. Two paths are common:

Expand Down
1 change: 1 addition & 0 deletions docs/reference/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ specify init my-project --integration copilot --preset compliance
| ----------------- | ------------------------------------------------------------------------ |
| `SPECKIT_INTEGRATION_DEFAULT` | Override the fallback integration used by `specify init` when `--integration` is omitted (interactive prompt default and non-interactive fallback). Set it to any registered integration key (e.g. `gemini`, `claude`). An unrecognized value is ignored with a warning and the built-in default (`copilot`) is used. An explicit `--integration <key>` always takes precedence. |
| `SPECIFY_INIT_DIR` | Target a member project from outside its directory (e.g. a monorepo root) without `cd`, for non-interactive / CI use. Set it to the **project root** — the directory *containing* `.specify/` (relative paths resolve against the current directory). The path must exist and contain `.specify/`, otherwise the command errors and does **not** fall back to the current directory. Resolved once in the core root helper (`get_repo_root` in Bash, `Get-RepoRoot` in PowerShell), so it is honored by the core feature scripts (`/speckit.plan`, `/speckit.tasks`, …) and the Git extension's feature-branch creation, which inherit it. The `specify` CLI applies the **same** validation rules to every project-scoped subcommand (`specify integration …`, `specify extension …`, `specify workflow …`, `specify preset …`, and the rest that operate on a `.specify/` project), so those can target a member project too. When unset, Bash/PowerShell helpers keep their existing upward search; the `specify` CLI keeps its project-scoped resolver cwd-only unless a command explicitly defines broader detection (for example, bundle commands). |
| `FEATURE_ID` | Use a per-feature custom identifier instead of the configured sequential or timestamp prefix. Values are normalized to lowercase, must start and end with a letter or digit, and may contain letters, digits, dots, underscores, and hyphens. For example, `FEATURE_ID=ENHANCEMENT-XYZ` produces `specs/enhancement-xyz-<short-name>` and, when the Git extension is enabled, a matching branch prefix. |
| `SPECIFY_FEATURE_DIRECTORY` | Override the active feature directory *within* the resolved project (takes precedence over `.specify/feature.json`). Relative paths resolve under the project root. Combine with `SPECIFY_INIT_DIR` to pick both the project and the feature non-interactively. |
| `SPECIFY_FEATURE` | Override feature detection for non-Git repositories. Set to the feature directory name (e.g., `001-photo-albums`) to work on a specific feature when not using Git branches. Must be set in the context of the agent prior to using `/speckit.plan` or follow-up commands. |

Expand Down
4 changes: 2 additions & 2 deletions extensions/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@
"git": {
"name": "Git Branching Workflow",
"id": "git",
"version": "1.0.0",
"description": "Feature branch creation, numbering (sequential/timestamp), validation, and Git remote detection",
"version": "1.0.1",
"description": "Feature branch creation with custom identifiers or sequential/timestamp prefixes, validation, and Git remote detection",
"author": "spec-kit-core",
"repository": "https://github.com/github/spec-kit",
"bundled": true,
Expand Down
22 changes: 19 additions & 3 deletions extensions/git/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Git Branching Workflow Extension

Git repository initialization, feature branch creation, numbering (sequential/timestamp), validation, remote detection, and auto-commit for Spec Kit.
Git repository initialization, feature branch creation, custom identifiers or numbering, validation, remote detection, and auto-commit for Spec Kit.

## Overview

This extension provides Git operations as an optional, self-contained module. It manages:

- **Repository initialization** with configurable commit messages
- **Feature branch creation** with sequential (`001-feature-name`) or timestamp (`20260319-143022-feature-name`) numbering and optional templates for branch namespaces
- **Feature branch creation** with custom identifiers (`enhancement-xyz-feature-name`), sequential numbering (`001-feature-name`), or timestamps (`20260319-143022-feature-name`) and optional templates for branch namespaces
- **Branch validation** to ensure branches follow naming conventions
- **Git remote detection** for GitHub integration (e.g., issue creation)
- **Auto-commit** after core commands (configurable per-command with custom messages, or Conventional Commit messages generated by the agent)
Expand All @@ -17,7 +17,7 @@ This extension provides Git operations as an optional, self-contained module. It
| 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.feature` | Create a feature branch with a custom identifier, sequential number, or timestamp |
| `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) |
Expand Down Expand Up @@ -56,6 +56,7 @@ branch_numbering: sequential
# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}; {slug} must not appear
# before {number}, and the final path segment must start with {number}-.
# {number} receives the selected custom identifier, sequential number, or timestamp.
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""

Expand Down Expand Up @@ -84,6 +85,21 @@ auto_commit:

For simple namespace-only customization, `branch_prefix` is also accepted as a shorthand and expands to `<branch_prefix>/{number}-{slug}`.

### Custom feature identifiers

Supply a per-feature identifier through `FEATURE_ID` or the script option
`--feature-id` (`-FeatureId` in PowerShell). The value replaces the numeric or
timestamp prefix and is normalized to lowercase:

```bash
FEATURE_ID=ENHANCEMENT-XYZ /speckit.specify Add user authentication
```

This produces `enhancement-xyz-user-auth` for both the Git branch and the
default `specs/` directory. Identifiers must start and end with a letter or
digit and may contain letters, digits, dots, underscores, and hyphens.
`GIT_BRANCH_NAME` remains the higher-precedence exact branch override.

## Installation

```bash
Expand Down
12 changes: 8 additions & 4 deletions extensions/git/commands/speckit.git.feature.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Create a feature branch with sequential or timestamp numbering"
description: "Create a feature branch with a custom identifier, sequential number, or timestamp"
---

# Create Feature Branch
Expand All @@ -21,6 +21,8 @@ If the user explicitly provided `GIT_BRANCH_NAME` (e.g., via environment variabl
- `--short-name`, `--number`, and `--timestamp` flags are ignored
- `FEATURE_NUM` is extracted when the final path segment starts with a numeric or timestamp feature marker (for example `042-name`, `feat/042-name`, or `jdoe/app/042-name`), otherwise set to the full branch name

If the user explicitly provided `FEATURE_ID` (for example, `FEATURE_ID=ENHANCEMENT-XYZ`), pass it to the script with `--feature-id`/`-FeatureId`. The script normalizes it to lowercase and creates a branch such as `enhancement-xyz-user-auth`. `GIT_BRANCH_NAME` takes precedence when both are provided.

## Prerequisites

- Verify Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
Expand All @@ -41,7 +43,7 @@ Check `.specify/extensions/git/git-config.yml` for an optional `branch_template`

- `{author}`: sanitized Git config author (`user.name`, falling back to the email local part)
- `{app}`: sanitized Spec Kit init directory name
- `{number}`: sequential number or timestamp
- `{number}`: selected feature prefix (custom identifier, sequential number, or timestamp)
- `{slug}`: generated short branch slug

For monorepos, a template such as `{author}/{app}/{number}-{slug}` creates names like `jdoe/web/008-guided-tour` while preserving per-project feature numbering.
Expand All @@ -61,6 +63,8 @@ Run the appropriate script based on your platform:
- **Bash (timestamp)**: `.specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --timestamp --short-name "<short-name>" "<feature description>"`
- **PowerShell**: `.specify/extensions/git/scripts/powershell/create-new-feature-branch.ps1 -Json -ShortName "<short-name>" "<feature description>"`
- **PowerShell (timestamp)**: `.specify/extensions/git/scripts/powershell/create-new-feature-branch.ps1 -Json -Timestamp -ShortName "<short-name>" "<feature description>"`
- **Bash (custom identifier)**: `.specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --feature-id "<FEATURE_ID>" --short-name "<short-name>" "<feature description>"`
- **PowerShell (custom identifier)**: `.specify/extensions/git/scripts/powershell/create-new-feature-branch.ps1 -Json -FeatureId "<FEATURE_ID>" -ShortName "<short-name>" "<feature description>"`

**IMPORTANT**:
- Do NOT pass `--number` — the script determines the correct next number automatically
Expand All @@ -78,5 +82,5 @@ If Git is not installed or the current directory is not a Git repository:
## Output

The script outputs JSON with:
- `BRANCH_NAME`: The branch name (e.g., `003-user-auth`, `20260319-143022-user-auth`, or `jdoe/web/003-user-auth`)
- `FEATURE_NUM`: The numeric or timestamp prefix used
- `BRANCH_NAME`: The branch name (e.g., `003-user-auth`, `20260319-143022-user-auth`, `enhancement-xyz-user-auth`, or `jdoe/web/003-user-auth`)
- `FEATURE_NUM`: The selected feature prefix; this legacy key also contains a custom identifier when one is used
4 changes: 3 additions & 1 deletion extensions/git/commands/speckit.git.validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ The branch name's final path segment must start with one of these feature marker

1. **Sequential**: `[0-9]{3,}-` (e.g., `001-feature-name`, `042-fix-bug`, `1000-big-feature`, `jdoe/web/008-guided-tour`)
2. **Timestamp**: `[0-9]{8}-[0-9]{6}-` (e.g., `20260319-143022-feature-name`, `jdoe/web/20260319-143022-feature-name`)
3. **Custom identifier**: the lowercase-normalized `FEATURE_ID` followed by `-`, or a final path segment that exactly matches the active feature directory basename from `.specify/feature.json` (e.g., `enhancement-xyz-user-auth`)

## Execution

Expand All @@ -34,12 +35,13 @@ If on a feature branch (matches either pattern):
- Check if the corresponding spec directory exists under `specs/`:
- For sequential branches, look for `specs/<prefix>-*` where prefix matches the numeric portion, regardless of branch namespace prefixes
- For timestamp branches, look for `specs/<prefix>-*` where prefix matches the `YYYYMMDD-HHMMSS` portion, regardless of branch namespace prefixes
- For custom identifiers, prefer the exact active feature directory recorded in `.specify/feature.json`; when `FEATURE_ID` is available, look for `specs/<FEATURE_ID>-*`
- If spec directory exists: `✓ Spec directory found: <path>`
- If spec directory missing: `⚠ No spec directory found for prefix <prefix>`

If NOT on a feature branch:
- Output: `✗ Not on a feature branch. Current branch: <branch-name>`
- Output: `Feature branches should be named like: 001-feature-name, 20260319-143022-feature-name, or <namespace>/001-feature-name`
- Output: `Feature branches should be named like: 001-feature-name, 20260319-143022-feature-name, enhancement-xyz-feature-name, or <namespace>/001-feature-name`

## Graceful Degradation

Expand Down
1 change: 1 addition & 0 deletions extensions/git/config-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ branch_numbering: sequential

# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}
# {number} receives the selected prefix: custom FEATURE_ID, sequential number, or timestamp.
# {slug} must not appear before {number}; final path segment must start with {number}-.
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""
Expand Down
6 changes: 3 additions & 3 deletions extensions/git/extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ schema_version: "1.0"
extension:
id: git
name: "Git Branching Workflow"
version: "1.0.0"
description: "Feature branch creation, numbering (sequential/timestamp), templating, validation, and Git remote detection"
version: "1.0.1"
description: "Feature branch creation with custom identifiers or sequential/timestamp prefixes, templating, validation, and Git remote detection"
author: spec-kit-core
repository: https://github.com/github/spec-kit
license: MIT
Expand All @@ -19,7 +19,7 @@ provides:
commands:
- name: speckit.git.feature
file: commands/speckit.git.feature.md
description: "Create a feature branch with sequential or timestamp numbering and optional templates"
description: "Create a feature branch with a custom identifier, sequential number, or timestamp and optional templates"
- name: speckit.git.validate
file: commands/speckit.git.validate.md
description: "Validate current branch follows feature branch naming conventions"
Expand Down
1 change: 1 addition & 0 deletions extensions/git/git-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ branch_numbering: sequential

# Optional branch name template. Leave empty for the default "{number}-{slug}".
# Supported tokens: {author}, {app}, {number}, {slug}
# {number} receives the selected prefix: custom FEATURE_ID, sequential number, or timestamp.
# {slug} must not appear before {number}; final path segment must start with {number}-.
# Example for monorepos: "{author}/{app}/{number}-{slug}"
branch_template: ""
Expand Down
Loading