Skip to content

Conversation

@ricardojmendez
Copy link

Contains several commits allowing the user to specify some values around branch and spec name:

  • Branch prefix, allowing for feature/, bugfix/, or other patterns to match the user's / team's approach;
  • An arbitrary spec number, to potentially tie it into the corresponding issue on Github, instead of just using a sequence.

It also includes an optional configuration file for default branch name, since I expect users will create one type of branch more often than others (eg. "feature").

This addresses some of the requests in #407.

When running 'specify', the user can now indicate a branch prefix to use,
in case they have in-house naming conventions for branches.

Examples:

/speckit.specify a feature.  Add this stuff.
/speckit.specify --branch-prefix bugfix. Solve the crash in fizzbuzz.

It also introduces a config file so that you can configure your default
branch names, since I personally end up defaulting to "feature" most of
the time.
This allows you to create branches which have a number that matches your
issue number in Github (or any other tracker).
This makes it clearer that the user may enter input such as:

- "Branch type feature, number 303" or
- "This is bugfix 31416"

It should also allow for timestamp hotfixes, given they're only a number.
Copilot AI review requested due to automatic review settings October 22, 2025 08:08
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 adds configuration capabilities for customizing branch naming patterns and spec numbers in the Specify CLI tool. The changes enable users to set default branch prefixes (e.g., feature/, bugfix/) and specify custom spec numbers to align with issue trackers.

Key changes:

  • Introduced .specify/config.json for project-wide branch prefix configuration
  • Added --branch-prefix and --spec-number parameters to creation scripts
  • Enhanced AI agent instructions to parse natural language patterns like "feature 303" or "bugfix 666"

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
templates/config.json New configuration file template with branch prefix setting
templates/commands/specify.md Extensive documentation for parsing spec numbers and branch prefixes from user input
src/specify_cli/init.py Added setup_config_file() function to copy config template during initialization
scripts/powershell/create-new-feature.ps1 Implemented config parsing and new parameters for branch customization
scripts/bash/create-new-feature.sh Bash equivalent of PowerShell script changes
pyproject.toml Version bump to 0.0.21
README.md Documentation for new configuration features and usage examples
CHANGELOG.md Release notes for version 0.0.21

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

- "hotfix 42" → extract prefix `hotfix/` and number `42`
- "fix 123" → extract prefix `bugfix/` and number `123` (normalize "fix" to "bugfix")
- "chore 999" → extract prefix `chore/` and number `999`

Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The natural language pattern documentation states that "fix" normalizes to "bugfix/" (line 29), but line 69 lists both "bugfix" and "fix" as separate recognized prefix types that map to "bugfix/". This creates ambiguity about whether "fix" is a valid pattern on its own or only when followed by a number. Consider clarifying the distinction between "fix" as a standalone prefix keyword versus its use in natural language patterns.

Suggested change
> **Note:** In natural language patterns, the prefix "fix" is always normalized to "bugfix/" for consistency (e.g., "fix 123" becomes "bugfix/123"). "fix" is not accepted as a standalone prefix; use "bugfix" for explicit prefix specification.

Copilot uses AI. Check for mistakes.
Comment on lines 204 to 206
# Use grep and sed to extract the prefix value from JSON
# This avoids requiring jq to be installed
local prefix=$(grep -o '"prefix"[[:space:]]*:[[:space:]]*"[^"]*"' "$config_file" | sed 's/.*"prefix"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The JSON parsing logic fails when the prefix value contains escaped quotes or special characters. For example, a prefix value of "test\"value" would break the regex pattern. While unlikely in typical branch prefix usage, consider adding validation or a comment warning about this limitation.

Suggested change
# Use grep and sed to extract the prefix value from JSON
# This avoids requiring jq to be installed
local prefix=$(grep -o '"prefix"[[:space:]]*:[[:space:]]*"[^"]*"' "$config_file" | sed 's/.*"prefix"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
# Use jq to extract the prefix value from JSON. jq correctly handles escaped quotes and special characters.
# If jq is not available, fall back to grep/sed but warn about limitations.
local prefix=""
if command -v jq >/dev/null 2>&1; then
prefix=$(jq -r '.prefix // empty' "$config_file")
else
echo "Warning: jq not found. Falling back to regex-based JSON parsing, which may fail for escaped quotes or special characters in the prefix value." >&2
# Fallback: regex-based extraction (does not handle escaped quotes/special chars)
prefix=$(grep -o '"prefix"[[:space:]]*:[[:space:]]*"[^"]*"' "$config_file" | sed 's/.*"prefix"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
fi

Copilot uses AI. Check for mistakes.
if ($SpecNumber) {
# Validate it's a positive integer
$num = 0
if (-not [int]::TryParse($SpecNumber, [ref]$num) -or $num -lt 0) {
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The validation check allows zero as a valid spec number ($num -lt 0), but spec numbers starting at 0 could create ambiguous directory names like 000-feature-name. Consider changing the condition to $num -le 0 to require positive integers starting from 1.

Copilot uses AI. Check for mistakes.
Comment on lines 130 to 131
if ! [[ "$SPEC_NUM_ARG" =~ ^[0-9]+$ ]]; then
echo "Error: --spec-number must be a positive integer" >&2
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The bash validation allows zero as a valid spec number (regex ^[0-9]+$ matches "0"), but this could create ambiguous directory names like 000-feature-name. The PowerShell version has the same issue. Both scripts should reject zero to ensure spec numbers start from 1.

Suggested change
if ! [[ "$SPEC_NUM_ARG" =~ ^[0-9]+$ ]]; then
echo "Error: --spec-number must be a positive integer" >&2
if ! [[ "$SPEC_NUM_ARG" =~ ^[1-9][0-9]*$ ]]; then
echo "Error: --spec-number must be a positive integer greater than zero" >&2

Copilot uses AI. Check for mistakes.
I had missed it during the original push.
It's sometimes missing cases - for instance, if a prompt says near the
end that "This is feature 221", it may pick up on the feature number but
not the branch type.

Testing a more verbose, explicit approach.
Preserving the --number parameter from merge commit e6d6f3c, while
maintaining the new --branch-prefix parameter.
Copilot AI review requested due to automatic review settings October 31, 2025 10:33
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

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


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

Comment on lines +2 to +4
"branch": {
"prefix": ""
}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The config file structure uses "branch": { "prefix": "" } (nested structure), but the PowerShell script at line 257 reads $config.branch_prefix (flat structure with underscore). The bash script at line 250 also searches for "branch_prefix" (flat structure). This mismatch means the config file will not be read correctly. Either change the config structure to {"branch_prefix": ""} or update the scripts to read $config.branch.prefix and "branch"[^"]*"prefix".

Suggested change
"branch": {
"prefix": ""
}
"branch_prefix": ""

Copilot uses AI. Check for mistakes.
# Account for: feature number (3) + hyphen (1) = 4 chars
MAX_SUFFIX_LENGTH=$((MAX_BRANCH_LENGTH - 4))
# Account for: prefix length + feature number (3) + hyphen (1)
local prefix_length=${#BRANCH_PREFIX}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The local keyword is used outside a function scope. This variable declaration is in the main script body (inside an if block), not within a function. Remove the local keyword or the script will fail with a syntax error.

Suggested change
local prefix_length=${#BRANCH_PREFIX}
prefix_length=${#BRANCH_PREFIX}

Copilot uses AI. Check for mistakes.
@ricardojmendez
Copy link
Author

Any feedback on this PR, @localden?

@ricardojmendez ricardojmendez marked this pull request as draft November 23, 2025 09:56
@ricardojmendez ricardojmendez marked this pull request as ready for review November 23, 2025 10:00
Copilot AI review requested due to automatic review settings November 23, 2025 10:00
Copilot finished reviewing on behalf of ricardojmendez November 23, 2025 10:04
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

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

Comments suppressed due to low confidence (3)

scripts/bash/create-new-feature.sh:229

  • The SPECIFY_SPEC_NUMBER environment variable is documented in README.md and the specify.md template (line 103), but the bash script doesn't check or use this environment variable. The BRANCH_NUMBER variable is only set from the CLI argument (--number).

To match the documented behavior, add a check for the environment variable. For example, after parsing arguments and before the auto-increment logic:

if [ -z "$BRANCH_NUMBER" ] && [ -n "$SPECIFY_SPEC_NUMBER" ]; then
    BRANCH_NUMBER="$SPECIFY_SPEC_NUMBER"
fi
    # Common stop words to filter out
    local stop_words="^(i|a|an|the|to|for|of|in|on|at|by|with|from|is|are|was|were|be|been|being|have|has|had|do|does|did|will|would|should|could|can|may|might|must|shall|this|that|these|those|my|your|our|their|want|need|add|get|set)$"
    
    # Convert to lowercase and split into words
    local clean_name=$(echo "$description" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/ /g')
    
    # Filter words: remove stop words and words shorter than 3 chars (unless they're uppercase acronyms in original)
    local meaningful_words=()
    for word in $clean_name; do
        # Skip empty words
        [ -z "$word" ] && continue
        
        # Keep words that are NOT stop words AND (length >= 3 OR are potential acronyms)
        if ! echo "$word" | grep -qiE "$stop_words"; then
            if [ ${#word} -ge 3 ]; then
                meaningful_words+=("$word")
            elif echo "$description" | grep -q "\b${word^^}\b"; then
                # Keep short words if they appear as uppercase in original (likely acronyms)
                meaningful_words+=("$word")

scripts/powershell/create-new-feature.ps1:258

  • The configuration file structure uses a nested JSON format ("branch": { "prefix": "" }), but the PowerShell script is looking for a flat branch_prefix field. This mismatch will prevent the configuration file from working correctly.

The script should access the nested structure like: $config.branch.prefix instead of $config.branch_prefix.

    $branchSuffix = Get-BranchName -Description $featureDesc
}

scripts/bash/create-new-feature.sh:252

  • The configuration file structure uses a nested JSON format ("branch": { "prefix": "" }), but the bash script is looking for a flat branch_prefix field using grep. This mismatch will prevent the configuration file from working correctly.

The grep pattern should be updated to extract from the nested structure. For example:

local branch_prefix=$(grep -A 1 '"branch"' "$config_file" | grep '"prefix"' | sed 's/.*"prefix"[^"]*"\([^"]*\)".*/\1/')
        local cleaned=$(clean_branch_name "$description")
        echo "$cleaned" | tr '-' '\n' | grep -v '^$' | head -3 | tr '\n' '-' | sed 's/-$//'
    fi

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


**If no spec number is specified:** The script will auto-increment from the highest existing spec number (default behavior).

**Priority order:**
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Duplicate line detected. The mapping 'fix' → 'bugfix/' appears twice (lines 108 and 109).

Copilot uses AI. Check for mistakes.
Comment on lines 59 to 225
d. Run the script `{SCRIPT}` with the calculated number and short-name:
- Pass `--number N+1` and `--short-name "your-short-name"` along with the feature description
- **CRITICAL**: Use the spec number and branch prefix **extracted in Step 1a** if available.
- Bash example: `{SCRIPT} --json --number 5 --short-name "user-auth" "Add user authentication"`
- PowerShell example: `{SCRIPT} -Json -Number 5 -ShortName "user-auth" "Add user authentication"`
- PowerShell example: `{SCRIPT} -Json -Number 5 -ShortName "user-auth" "Add user authentication"`

**IMPORTANT**:

- Check all three sources (remote branches, local branches, specs directories) to find the highest number
- Only match branches/directories with the exact short-name pattern
- If no existing branches/directories found with this short-name, start with number 1
- You must only ever run this script once per feature
- Append the short-name argument to the `{SCRIPT}` command with the 2-4 word short name you created in step 1. Keep the feature description as the final argument.
- If a spec number was extracted in Step 1a, include it as a parameter
- If a branch prefix was extracted in Step 1a, include it as a parameter
- **Note:** Natural language patterns like "feature 303" or "bugfix 666" provide BOTH prefix and number - extract and pass both parameters
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

This section contains duplicate instructions. Lines 211-217 are nearly identical to lines 219-225, repeating guidance about checking all sources, matching patterns, and extracting parameters. This duplication makes the documentation harder to maintain and could confuse users. Consider consolidating these into a single, clear set of instructions.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +33
Write-Host " SPECIFY_SPEC_NUMBER Set default spec/branch number"
Write-Host " SPECIFY_BRANCH_PREFIX Set default branch prefix"
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

The help text mentions SPECIFY_SPEC_NUMBER environment variable, but the script doesn't actually check or use this environment variable. The $Number parameter is only set from the CLI argument (-Number), not from the environment variable.

To match the documented behavior, add a check for the environment variable before defaulting to 0. For example, after the param block:

if ($Number -eq 0 -and $env:SPECIFY_SPEC_NUMBER) {
    $Number = [int]$env:SPECIFY_SPEC_NUMBER
}

Copilot uses AI. Check for mistakes.
Comment on lines 201 to 203

2. **Check for existing branches before creating new one**:

Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Step 2 is missing sub-step 'c'. The outline jumps from step 2b (line 201-202) directly to step 2d (line 203). This makes the documentation confusing and incomplete.

Based on the removed lines in the diff context, it appears that step 2c should contain the logic for determining the next available number (extracting all numbers, finding the highest N, using N+1).

Copilot uses AI. Check for mistakes.
- "issue #221" ✓ (just number)
- "Add shopping cart feature 303" ✓ (adjacent but later in sentence)

**Examples of user input with spec number:**
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

Duplicate line detected. The example "bugfix 666 fix payment timeout" appears twice (lines 69 and 70).

Copilot uses AI. Check for mistakes.
local matches=()
if [[ -d "$specs_dir" ]]; then
for dir in "$specs_dir"/"$prefix"-*; do
for dir in "$specs_dir"/*"$number"-*; do
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

The glob pattern "$specs_dir"/*"$number"-* could match unintended directories. For example, if $number is "001", this would match directories like "foo-001-bar" or "2001-space" in addition to the intended "001-name" or "feature/001-name".

Consider using a more precise search approach similar to the PowerShell implementation that explicitly checks the directory names against the regex pattern, or improve the glob pattern to avoid false matches.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings November 25, 2025 18:01
Copilot finished reviewing on behalf of ricardojmendez November 25, 2025 18:05
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

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

Comments suppressed due to low confidence (2)

scripts/bash/common.sh:48

  • When spec directories are created with branch prefixes (e.g., specs/feature/001-user-auth/), this glob "$specs_dir"/* will match specs/feature/ but basename will return just feature, which won't match the pattern ^(([a-z]+/)?([0-9]{3,}))-. This function will fail to find the latest feature when prefixed directories are used.

Consider searching at depth 2 or using a different approach to handle the nested directory structure created by branch prefixes.

        for dir in "$specs_dir"/*; do
            if [[ -d "$dir" ]]; then
                local dirname=$(basename "$dir")
                # Support both formats: 001-name or feature/001-name
                if [[ "$dirname" =~ ^(([a-z]+/)?([0-9]{3,}))- ]]; then
                    local number=${BASH_REMATCH[3]}
                    number=$((10#$number))
                    if [[ "$number" -gt "$highest" ]]; then
                        highest=$number
                        latest_feature=$dirname
                    fi
                fi

scripts/powershell/common.ps1:50

  • When spec directories are created with branch prefixes (e.g., specs/feature/001-user-auth/), Get-ChildItem -Path $specsDir -Directory will return specs/feature/ but $_.Name will be just feature, which won't match the pattern ^(([a-z]+/)?(\d{3,}))-. This function will fail to find the latest feature when prefixed directories are used.

Consider using -Recurse -Depth 1 or searching in nested subdirectories to handle the directory structure created by branch prefixes.

        Get-ChildItem -Path $specsDir -Directory | ForEach-Object {
            # Support both formats: 001-name or feature/001-name
            if ($_.Name -match '^(([a-z]+/)?(\d{3,}))-') {
                $num = [int]$matches[3]
                if ($num -gt $highest) {
                    $highest = $num
                    $latestFeature = $_.Name
                }
            }

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

Comment on lines +302 to +303
if ($config.branch_prefix) {
return $config.branch_prefix
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The config file uses the key "prefix" nested under "branch" (see templates/config.json), but this code is looking for "branch_prefix" at the root level. This should be $config.branch.prefix to match the documented JSON structure:

{
  "branch": {
    "prefix": "feature/"
  }
}
Suggested change
if ($config.branch_prefix) {
return $config.branch_prefix
if ($config.branch -and $config.branch.prefix) {
return $config.branch.prefix

Copilot uses AI. Check for mistakes.
Comment on lines +297 to +298
# Extract branch_prefix from config (avoid jq dependency)
local branch_prefix=$(grep '"branch_prefix"' "$config_file" | sed 's/.*"branch_prefix"[^"]*"\([^"]*\)".*/\1/')
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The config file uses the key "prefix" nested under "branch", but this code is looking for "branch_prefix" at the root level. The grep/sed pattern should match the nested structure. For example:

local branch_prefix=$(grep -A 1 '"branch"' "$config_file" | grep '"prefix"' | sed 's/.*"prefix"[^"]*"\([^"]*\)".*/\1/')

Or use a JSON parser if available (e.g., jq -r '.branch.prefix // ""').

Suggested change
# Extract branch_prefix from config (avoid jq dependency)
local branch_prefix=$(grep '"branch_prefix"' "$config_file" | sed 's/.*"branch_prefix"[^"]*"\([^"]*\)".*/\1/')
# Extract branch prefix from config (avoid jq dependency)
local branch_prefix=$(grep -A 10 '"branch"' "$config_file" | grep '"prefix"' | sed 's/.*"prefix"[^"]*"\([^"]*\)".*/\1/')

Copilot uses AI. Check for mistakes.
```

This creates:
- Spec directory: `specs/123-fix-payment-timeout/`
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

This documentation is inconsistent with the actual implementation. When using --branch-prefix bugfix/, the spec directory will be specs/bugfix/123-fix-payment-timeout/ (including the prefix), not specs/123-fix-payment-timeout/ as stated here. The git branch correctly includes the prefix as shown.

Suggested change
- Spec directory: `specs/123-fix-payment-timeout/`
- Spec directory: `specs/bugfix/123-fix-payment-timeout/`

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +129
Get-ChildItem -Path $specsDir -Directory | Where-Object {
# Check if directory name contains our number and matches the pattern
$_.Name -match "^(([a-z]+/)?$number)-"
} | ForEach-Object {
$matchedDirs += $_.Name
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

When $branchName contains a slash (e.g., "feature/001-user-auth"), Join-Path creates a nested directory structure (specs/feature/001-user-auth/). However, Get-ChildItem -Path $specsDir -Directory only returns immediate children of specs/, so it won't find the nested directories. This will cause Find-FeatureDirByPrefix to fail when looking for prefixed branches.

Consider using -Recurse -Depth 1 or searching in both $specsDir and $specsDir/* subdirectories to handle the nested structure created by prefixed branches.

Suggested change
Get-ChildItem -Path $specsDir -Directory | Where-Object {
# Check if directory name contains our number and matches the pattern
$_.Name -match "^(([a-z]+/)?$number)-"
} | ForEach-Object {
$matchedDirs += $_.Name
# Search recursively for directories up to depth 2 (immediate children and their subdirectories)
Get-ChildItem -Path $specsDir -Directory -Recurse | Where-Object {
# Get the relative path from specs/ to the directory
$relativePath = $_.FullName.Substring($specsDir.Length + 1)
# Check if relative path matches the pattern for numeric prefix
$relativePath -match "^(([a-z]+/)?$number)-"
} | ForEach-Object {
$matchedDirs += $_.FullName.Substring($specsDir.Length + 1)

Copilot uses AI. Check for mistakes.
Comment on lines +113 to +120
# Use find to search more precisely - avoid glob matching issues
while IFS= read -r -d '' dir; do
local dirname=$(basename "$dir")
# Verify it actually matches our pattern: starts with optional prefix/ then number-
if [[ "$dirname" =~ ^(([a-z]+/)?$number)- ]]; then
matches+=("$dirname")
fi
done
done < <(find "$specs_dir" -mindepth 1 -maxdepth 1 -type d -print0)
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

When $branch_name contains a slash (e.g., "feature/001-user-auth"), the directory structure created is nested (specs/feature/001-user-auth/). However, find "$specs_dir" -mindepth 1 -maxdepth 1 only searches immediate children of specs/, so it will find specs/feature/ but not specs/feature/001-user-auth/. The basename of specs/feature/ is just feature, which won't match the pattern ^(([a-z]+/)?$number)-.

Consider using -maxdepth 2 and adjusting the logic to handle the nested structure, or use a different approach to find prefixed branch directories.

Copilot uses AI. Check for mistakes.
# Account for: feature number (3) + hyphen (1) = 4 chars
MAX_SUFFIX_LENGTH=$((MAX_BRANCH_LENGTH - 4))
# Account for: prefix length + feature number (3) + hyphen (1)
local prefix_length=${#BRANCH_PREFIX}
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

Using local keyword outside of a function is a bash extension and may not work in POSIX-compliant shells. Since this is already at the top level of the script (not inside get_branch_prefix function), this should just be prefix_length=${#BRANCH_PREFIX} without the local keyword.

Suggested change
local prefix_length=${#BRANCH_PREFIX}
prefix_length=${#BRANCH_PREFIX}

Copilot uses AI. Check for mistakes.

## [Unreleased]

## [0.0.23] - 2025-10-22 / 2025-11-23
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The version date appears to be in the future: "2025-10-22 / 2025-11-23". Given that my knowledge cutoff is January 2025 and the current date is November 2025, the first date (October 2025) would be in the past, but the dual-date format is unusual. This should likely be a single date in the format YYYY-MM-DD. Please verify the correct release date.

Suggested change
## [0.0.23] - 2025-10-22 / 2025-11-23
## [0.0.23] - 2025-11-23

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +24
- New `.specify/config.json` configuration file with `branch.prefix` setting
- Environment variable `SPECIFY_BRANCH_PREFIX` for per-session overrides
- **Per-feature override**: `--branch-prefix` / `-BranchPrefix` parameter for `create-new-feature` scripts
- Priority order: Command-line parameter > Environment variable > Config file > Default (no prefix)
- Automatically created during project initialization via `specify init`
- Examples:
- With `"prefix": "feature/"`: `001-user-auth``feature/001-user-auth`
- With `"prefix": "bugfix/"`: `001-fix-login``bugfix/001-fix-login`
Copy link

Copilot AI Nov 25, 2025

Choose a reason for hiding this comment

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

The CHANGELOG states the config uses branch.prefix (which matches templates/config.json), but the actual code in both Bash and PowerShell scripts is looking for branch_prefix at the root level instead of the nested branch.prefix structure. This discrepancy between documentation and implementation needs to be resolved - either fix the code to match the documented structure or update the documentation.

Suggested change
- New `.specify/config.json` configuration file with `branch.prefix` setting
- Environment variable `SPECIFY_BRANCH_PREFIX` for per-session overrides
- **Per-feature override**: `--branch-prefix` / `-BranchPrefix` parameter for `create-new-feature` scripts
- Priority order: Command-line parameter > Environment variable > Config file > Default (no prefix)
- Automatically created during project initialization via `specify init`
- Examples:
- With `"prefix": "feature/"`: `001-user-auth` → `feature/001-user-auth`
- With `"prefix": "bugfix/"`: `001-fix-login` → `bugfix/001-fix-login`
- New `.specify/config.json` configuration file with `branch_prefix` setting
- Environment variable `SPECIFY_BRANCH_PREFIX` for per-session overrides
- **Per-feature override**: `--branch-prefix` / `-BranchPrefix` parameter for `create-new-feature` scripts
- Priority order: Command-line parameter > Environment variable > Config file > Default (no prefix)
- Automatically created during project initialization via `specify init`
- Examples:
- With `"branch_prefix": "feature/"`: `001-user-auth` → `feature/001-user-auth`
- With `"branch_prefix": "bugfix/"`: `001-fix-login` → `bugfix/001-fix-login`

Copilot uses AI. Check for mistakes.
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.

2 participants