Refactor feature script logic and update agent context scripts

Refactored both Bash and PowerShell create-new-feature scripts to modularize and deduplicate logic for determining the next feature number, including new helper functions for extracting the highest number from specs and branches. Improved branch name cleaning and generation. In update-agent-context scripts, removed redundant updates to AGENTS.md for Copilot, streamlining agent update logic.
This commit is contained in:
den (work)
2025-11-07 13:17:35 -08:00
parent 24b6d31471
commit 3dcbb6e3a9
4 changed files with 110 additions and 124 deletions

View File

@@ -59,6 +59,46 @@ function Find-RepositoryRoot {
}
}
function Get-HighestNumberFromSpecs {
param([string]$SpecsDir)
$highest = 0
if (Test-Path $SpecsDir) {
Get-ChildItem -Path $SpecsDir -Directory | ForEach-Object {
if ($_.Name -match '^(\d+)') {
$num = [int]$matches[1]
if ($num -gt $highest) { $highest = $num }
}
}
}
return $highest
}
function Get-HighestNumberFromBranches {
param()
$highest = 0
try {
$branches = git branch -a 2>$null
if ($LASTEXITCODE -eq 0) {
foreach ($branch in $branches) {
# Clean branch name: remove leading markers and remote prefixes
$cleanBranch = $branch.Trim() -replace '^\*?\s+', '' -replace '^remotes/[^/]+/', ''
# Extract feature number if branch matches pattern ###-*
if ($cleanBranch -match '^(\d+)-') {
$num = [int]$matches[1]
if ($num -gt $highest) { $highest = $num }
}
}
}
} catch {
# If git command fails, return 0
Write-Verbose "Could not check Git branches: $_"
}
return $highest
}
function Get-NextBranchNumber {
param(
[string]$ShortName,
@@ -127,6 +167,12 @@ function Get-NextBranchNumber {
# Return next number
return $maxNum + 1
}
function ConvertTo-CleanBranchName {
param([string]$Name)
return $Name.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', ''
}
$fallbackRoot = (Find-RepositoryRoot -StartDir $PSScriptRoot)
if (-not $fallbackRoot) {
Write-Error "Error: Could not determine repository root. Please run this script from within the repository."
@@ -150,46 +196,6 @@ Set-Location $repoRoot
$specsDir = Join-Path $repoRoot 'specs'
New-Item -ItemType Directory -Path $specsDir -Force | Out-Null
# Get highest number from specs directory
$highestFromSpecs = 0
if (Test-Path $specsDir) {
Get-ChildItem -Path $specsDir -Directory | ForEach-Object {
if ($_.Name -match '^(\d{3})') {
$num = [int]$matches[1]
if ($num -gt $highestFromSpecs) { $highestFromSpecs = $num }
}
}
}
# Get highest number from branch names (both local and remote)
$highestFromBranches = 0
try {
$branches = git branch -a 2>$null
if ($LASTEXITCODE -eq 0) {
foreach ($branch in $branches) {
# Clean branch name: remove leading markers and remote prefixes
# The following regex removes:
# - Git's current branch marker ('*') and leading whitespace (e.g., '* main')
# - Remote prefixes (e.g., 'remotes/origin/')
$cleanBranch = $branch.Trim() -replace '^\*?\s+', '' -replace '^remotes/[^/]+/', ''
# Extract feature number if branch matches pattern ###-*
if ($cleanBranch -match '^(\d{3})-') {
$num = [int]$matches[1]
if ($num -gt $highestFromBranches) { $highestFromBranches = $num }
}
}
}
} catch {
# If git command fails, just continue with specs-only check
Write-Verbose "Could not check Git branches: $_"
}
# Use the highest number from either source
$highest = [Math]::Max($highestFromSpecs, $highestFromBranches)
$next = $highest + 1
$featureNum = ('{0:000}' -f $next)
# Function to generate branch name with stop word filtering and length filtering
function Get-BranchName {
param([string]$Description)
@@ -229,7 +235,7 @@ function Get-BranchName {
return $result
} else {
# Fallback to original logic if no meaningful words found
$result = $Description.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', ''
$result = ConvertTo-CleanBranchName -Name $Description
$fallbackWords = ($result -split '-') | Where-Object { $_ } | Select-Object -First 3
return [string]::Join('-', $fallbackWords)
}
@@ -238,7 +244,7 @@ function Get-BranchName {
# Generate branch name
if ($ShortName) {
# Use provided short name, just clean it up
$branchSuffix = $ShortName.ToLower() -replace '[^a-z0-9]', '-' -replace '-{2,}', '-' -replace '^-', '' -replace '-$', ''
$branchSuffix = ConvertTo-CleanBranchName -Name $ShortName
} else {
# Generate from description with smart filtering
$branchSuffix = Get-BranchName -Description $featureDesc
@@ -251,16 +257,7 @@ if ($Number -eq 0) {
$Number = Get-NextBranchNumber -ShortName $branchSuffix -SpecsDir $specsDir
} else {
# Fall back to local directory check
$highest = 0
if (Test-Path $specsDir) {
Get-ChildItem -Path $specsDir -Directory | ForEach-Object {
if ($_.Name -match '^(\d{3})') {
$num = [int]$matches[1]
if ($num -gt $highest) { $highest = $num }
}
}
}
$Number = $highest + 1
$Number = (Get-HighestNumberFromSpecs -SpecsDir $specsDir) + 1
}
}

View File

@@ -47,7 +47,6 @@ $NEW_PLAN = $IMPL_PLAN
$CLAUDE_FILE = Join-Path $REPO_ROOT 'CLAUDE.md'
$GEMINI_FILE = Join-Path $REPO_ROOT 'GEMINI.md'
$COPILOT_FILE = Join-Path $REPO_ROOT '.github/agents/copilot-instructions.md'
$COPILOT_AGENTS_FILE = Join-Path $REPO_ROOT 'AGENTS.md'
$CURSOR_FILE = Join-Path $REPO_ROOT '.cursor/rules/specify-rules.mdc'
$QWEN_FILE = Join-Path $REPO_ROOT 'QWEN.md'
$AGENTS_FILE = Join-Path $REPO_ROOT 'AGENTS.md'
@@ -371,10 +370,7 @@ function Update-SpecificAgent {
switch ($Type) {
'claude' { Update-AgentFile -TargetFile $CLAUDE_FILE -AgentName 'Claude Code' }
'gemini' { Update-AgentFile -TargetFile $GEMINI_FILE -AgentName 'Gemini CLI' }
'copilot' {
Update-AgentFile -TargetFile $COPILOT_FILE -AgentName 'GitHub Copilot'
Update-AgentFile -TargetFile $COPILOT_AGENTS_FILE -AgentName 'GitHub Copilot (AGENTS.md)'
}
'copilot' { Update-AgentFile -TargetFile $COPILOT_FILE -AgentName 'GitHub Copilot' }
'cursor-agent' { Update-AgentFile -TargetFile $CURSOR_FILE -AgentName 'Cursor IDE' }
'qwen' { Update-AgentFile -TargetFile $QWEN_FILE -AgentName 'Qwen Code' }
'opencode' { Update-AgentFile -TargetFile $AGENTS_FILE -AgentName 'opencode' }
@@ -396,8 +392,6 @@ function Update-AllExistingAgents {
if (Test-Path $CLAUDE_FILE) { if (-not (Update-AgentFile -TargetFile $CLAUDE_FILE -AgentName 'Claude Code')) { $ok = $false }; $found = $true }
if (Test-Path $GEMINI_FILE) { if (-not (Update-AgentFile -TargetFile $GEMINI_FILE -AgentName 'Gemini CLI')) { $ok = $false }; $found = $true }
if (Test-Path $COPILOT_FILE) { if (-not (Update-AgentFile -TargetFile $COPILOT_FILE -AgentName 'GitHub Copilot')) { $ok = $false }; $found = $true }
# Also update AGENTS.md for Copilot if the Copilot directory exists
if (Test-Path (Join-Path $REPO_ROOT '.github/agents')) { if (-not (Update-AgentFile -TargetFile $COPILOT_AGENTS_FILE -AgentName 'GitHub Copilot (AGENTS.md)')) { $ok = $false }; $found = $true }
if (Test-Path $CURSOR_FILE) { if (-not (Update-AgentFile -TargetFile $CURSOR_FILE -AgentName 'Cursor IDE')) { $ok = $false }; $found = $true }
if (Test-Path $QWEN_FILE) { if (-not (Update-AgentFile -TargetFile $QWEN_FILE -AgentName 'Qwen Code')) { $ok = $false }; $found = $true }
if (Test-Path $AGENTS_FILE) { if (-not (Update-AgentFile -TargetFile $AGENTS_FILE -AgentName 'Codex/opencode')) { $ok = $false }; $found = $true }