Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions scripts/bash/check-prerequisites.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
if $PATHS_ONLY; then
if $JSON_MODE; then
# Minimal JSON paths payload (no validation performed)
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
printf '{"WORKING_DIR":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
"$WORKING_DIR" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
else
echo "REPO_ROOT: $REPO_ROOT"
echo "WORKING_DIR: $WORKING_DIR"
echo "BRANCH: $CURRENT_BRANCH"
echo "FEATURE_DIR: $FEATURE_DIR"
echo "FEATURE_SPEC: $FEATURE_SPEC"
Expand Down
11 changes: 7 additions & 4 deletions scripts/bash/common.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env bash
# Common functions and variables for all scripts

# Set working directory
WORKING_DIR="$(pwd)"

# Get repository root, with fallback for non-git repositories
get_repo_root() {
if git rev-parse --show-toplevel >/dev/null 2>&1; then
Expand Down Expand Up @@ -28,7 +31,7 @@ get_current_branch() {

# For non-git repos, try to find the latest feature directory
local repo_root=$(get_repo_root)
local specs_dir="$repo_root/specs"
local specs_dir="$WORKING_DIR/specs"

if [[ -d "$specs_dir" ]]; then
local latest_feature=""
Expand Down Expand Up @@ -81,7 +84,7 @@ check_feature_branch() {
return 0
}

get_feature_dir() { echo "$1/specs/$2"; }
get_feature_dir() { echo "$WORKING_DIR/specs/$2"; }

get_feature_paths() {
local repo_root=$(get_repo_root)
Expand All @@ -92,10 +95,10 @@ get_feature_paths() {
has_git_repo="true"
fi

local feature_dir=$(get_feature_dir "$repo_root" "$current_branch")
local feature_dir=$(get_feature_dir "$WORKING_DIR" "$current_branch")

cat <<EOF
REPO_ROOT='$repo_root'
WORKING_DIR='$WORKING_DIR'
CURRENT_BRANCH='$current_branch'
HAS_GIT='$has_git_repo'
FEATURE_DIR='$feature_dir'
Expand Down
18 changes: 5 additions & 13 deletions scripts/bash/create-new-feature.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,18 @@ find_repo_root() {
return 1
}

# Resolve repository root. Prefer git information when available, but fall back
# to searching for repository markers so the workflow still functions in repositories that
# were initialised with --no-git.
# Set working directory
Comment on lines 31 to +34
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

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

The find_repo_root function is now unused but still defined in the file. This dead code should be removed to improve maintainability.

Copilot uses AI. Check for mistakes.
WORKING_DIR="$(pwd)"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Check git availability
if git rev-parse --show-toplevel >/dev/null 2>&1; then
REPO_ROOT=$(git rev-parse --show-toplevel)
HAS_GIT=true
else
REPO_ROOT="$(find_repo_root "$SCRIPT_DIR")"
if [ -z "$REPO_ROOT" ]; then
echo "Error: Could not determine repository root. Please run this script from within the repository." >&2
exit 1
fi
HAS_GIT=false
fi

cd "$REPO_ROOT"

SPECS_DIR="$REPO_ROOT/specs"
SPECS_DIR="$WORKING_DIR/specs"
mkdir -p "$SPECS_DIR"

HIGHEST=0
Expand Down Expand Up @@ -80,7 +72,7 @@ fi
FEATURE_DIR="$SPECS_DIR/$BRANCH_NAME"
mkdir -p "$FEATURE_DIR"

TEMPLATE="$REPO_ROOT/templates/spec-template.md"
TEMPLATE="$WORKING_DIR/templates/spec-template.md"
SPEC_FILE="$FEATURE_DIR/spec.md"
if [ -f "$TEMPLATE" ]; then cp "$TEMPLATE" "$SPEC_FILE"; else touch "$SPEC_FILE"; fi

Expand Down
2 changes: 1 addition & 1 deletion scripts/bash/setup-plan.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1
mkdir -p "$FEATURE_DIR"

# Copy plan template if it exists
TEMPLATE="$REPO_ROOT/.specify/templates/plan-template.md"
TEMPLATE="$WORKING_DIR/.specify/templates/plan-template.md"
if [[ -f "$TEMPLATE" ]]; then
cp "$TEMPLATE" "$IMPL_PLAN"
echo "Copied plan template to $IMPL_PLAN"
Expand Down
26 changes: 13 additions & 13 deletions scripts/bash/update-agent-context.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,20 @@ eval $(get_feature_paths)
NEW_PLAN="$IMPL_PLAN" # Alias for compatibility with existing code
AGENT_TYPE="${1:-}"

# Agent-specific file paths
CLAUDE_FILE="$REPO_ROOT/CLAUDE.md"
GEMINI_FILE="$REPO_ROOT/GEMINI.md"
COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md"
CURSOR_FILE="$REPO_ROOT/.cursor/rules/specify-rules.mdc"
QWEN_FILE="$REPO_ROOT/QWEN.md"
AGENTS_FILE="$REPO_ROOT/AGENTS.md"
WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
# Agent-specific file paths
CLAUDE_FILE="$WORKING_DIR/CLAUDE.md"
GEMINI_FILE="$WORKING_DIR/GEMINI.md"
COPILOT_FILE="$WORKING_DIR/.github/copilot-instructions.md"
CURSOR_FILE="$WORKING_DIR/.cursor/rules/specify-rules.mdc"
QWEN_FILE="$WORKING_DIR/QWEN.md"
AGENTS_FILE="$WORKING_DIR/AGENTS.md"
WINDSURF_FILE="$WORKING_DIR/.windsurf/rules/specify-rules.md"
KILOCODE_FILE="$WORKING_DIR/.kilocode/rules/specify-rules.md"
AUGGIE_FILE="$WORKING_DIR/.augment/rules/specify-rules.md"
ROO_FILE="$WORKING_DIR/.roo/rules/specify-rules.md"

# Template file
TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
TEMPLATE_FILE="$WORKING_DIR/.specify/templates/agent-file-template.md"

# Global variables for parsed plan data
NEW_LANG=""
Expand Down Expand Up @@ -481,7 +481,7 @@ update_agent_file() {
log_info "Updating $agent_name context file: $target_file"

local project_name
project_name=$(basename "$REPO_ROOT")
project_name=$(basename "$WORKING_DIR")
local current_date
current_date=$(date +%Y-%m-%d)

Expand Down
4 changes: 2 additions & 2 deletions scripts/powershell/check-prerequisites.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ if (-not (Test-FeatureBranch -Branch $paths.CURRENT_BRANCH -HasGit:$paths.HAS_GI
if ($PathsOnly) {
if ($Json) {
[PSCustomObject]@{
REPO_ROOT = $paths.REPO_ROOT
WORKING_DIR = $paths.WORKING_DIR
BRANCH = $paths.CURRENT_BRANCH
FEATURE_DIR = $paths.FEATURE_DIR
FEATURE_SPEC = $paths.FEATURE_SPEC
IMPL_PLAN = $paths.IMPL_PLAN
TASKS = $paths.TASKS
} | ConvertTo-Json -Compress
} else {
Write-Output "REPO_ROOT: $($paths.REPO_ROOT)"
Write-Output "WORKING_DIR: $($paths.WORKING_DIR)"
Write-Output "BRANCH: $($paths.CURRENT_BRANCH)"
Write-Output "FEATURE_DIR: $($paths.FEATURE_DIR)"
Write-Output "FEATURE_SPEC: $($paths.FEATURE_SPEC)"
Expand Down
11 changes: 7 additions & 4 deletions scripts/powershell/common.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#!/usr/bin/env pwsh
# Common PowerShell functions analogous to common.sh

# Set working directory
$script:WorkingDir = (Get-Location).Path

function Get-RepoRoot {
try {
$result = git rev-parse --show-toplevel 2>$null
Expand Down Expand Up @@ -33,7 +36,7 @@ function Get-CurrentBranch {

# For non-git repos, try to find the latest feature directory
$repoRoot = Get-RepoRoot
$specsDir = Join-Path $repoRoot "specs"
$specsDir = Join-Path $script:WorkingDir "specs"

if (Test-Path $specsDir) {
$latestFeature = ""
Expand Down Expand Up @@ -89,17 +92,17 @@ function Test-FeatureBranch {

function Get-FeatureDir {
param([string]$RepoRoot, [string]$Branch)
Join-Path $RepoRoot "specs/$Branch"
Join-Path $script:WorkingDir "specs/$Branch"
}

function Get-FeaturePathsEnv {
$repoRoot = Get-RepoRoot
$currentBranch = Get-CurrentBranch
$hasGit = Test-HasGit
$featureDir = Get-FeatureDir -RepoRoot $repoRoot -Branch $currentBranch
$featureDir = Get-FeatureDir -RepoRoot $script:WorkingDir -Branch $currentBranch

[PSCustomObject]@{
REPO_ROOT = $repoRoot
WORKING_DIR = $script:WorkingDir
CURRENT_BRANCH = $currentBranch
HAS_GIT = $hasGit
FEATURE_DIR = $featureDir
Expand Down
42 changes: 7 additions & 35 deletions scripts/powershell/create-new-feature.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,50 +14,22 @@ if (-not $FeatureDescription -or $FeatureDescription.Count -eq 0) {
}
$featureDesc = ($FeatureDescription -join ' ').Trim()

# Resolve repository root. Prefer git information when available, but fall back
# to searching for repository markers so the workflow still functions in repositories that
# were initialised with --no-git.
function Find-RepositoryRoot {
param(
[string]$StartDir,
[string[]]$Markers = @('.git', '.specify')
)
$current = Resolve-Path $StartDir
while ($true) {
foreach ($marker in $Markers) {
if (Test-Path (Join-Path $current $marker)) {
return $current
}
}
$parent = Split-Path $current -Parent
if ($parent -eq $current) {
# Reached filesystem root without finding markers
return $null
}
$current = $parent
}
}
$fallbackRoot = (Find-RepositoryRoot -StartDir $PSScriptRoot)
if (-not $fallbackRoot) {
Write-Error "Error: Could not determine repository root. Please run this script from within the repository."
exit 1
}
# Set working directory
$workingDir = Get-Location
Comment on lines +17 to +18
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

The variable $workingDir should use consistent naming with other scripts. All other files use $WORKING_DIR (uppercase with underscore), but this uses camelCase. Consider changing to $WORKING_DIR = (Get-Location).Path for consistency.

Copilot uses AI. Check for mistakes.

# Check git availability
try {
$repoRoot = git rev-parse --show-toplevel 2>$null
git rev-parse --show-toplevel 2>$null | Out-Null
Copy link

Copilot AI Sep 23, 2025

Choose a reason for hiding this comment

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

The git command output is being redirected to Out-Null but the error stream is still redirected to $null. For consistency, consider using git rev-parse --show-toplevel >$null 2>&1 or handle both streams uniformly.

Suggested change
git rev-parse --show-toplevel 2>$null | Out-Null
git rev-parse --show-toplevel >$null 2>&1

Copilot uses AI. Check for mistakes.
if ($LASTEXITCODE -eq 0) {
$hasGit = $true
} else {
throw "Git not available"
$hasGit = $false
}
} catch {
$repoRoot = $fallbackRoot
$hasGit = $false
}

Set-Location $repoRoot

$specsDir = Join-Path $repoRoot 'specs'
$specsDir = Join-Path $workingDir 'specs'
New-Item -ItemType Directory -Path $specsDir -Force | Out-Null

$highest = 0
Expand Down Expand Up @@ -89,7 +61,7 @@ if ($hasGit) {
$featureDir = Join-Path $specsDir $branchName
New-Item -ItemType Directory -Path $featureDir -Force | Out-Null

$template = Join-Path $repoRoot 'templates/spec-template.md'
$template = Join-Path $workingDir 'templates/spec-template.md'
$specFile = Join-Path $featureDir 'spec.md'
if (Test-Path $template) {
Copy-Item $template $specFile -Force
Expand Down
3 changes: 2 additions & 1 deletion scripts/powershell/setup-plan.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ if (-not (Test-FeatureBranch -Branch $paths.CURRENT_BRANCH -HasGit $paths.HAS_GI
New-Item -ItemType Directory -Path $paths.FEATURE_DIR -Force | Out-Null

# Copy plan template if it exists, otherwise note it or create empty file
$template = Join-Path $paths.REPO_ROOT '.specify/templates/plan-template.md'
$workingDir = $paths.WORKING_DIR
$template = Join-Path $workingDir '.specify/templates/plan-template.md'
if (Test-Path $template) {
Copy-Item $template $paths.IMPL_PLAN -Force
Write-Output "Copied plan template to $($paths.IMPL_PLAN)"
Expand Down
30 changes: 15 additions & 15 deletions scripts/powershell/update-agent-context.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,25 @@ $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# Acquire environment paths
$envData = Get-FeaturePathsEnv
$REPO_ROOT = $envData.REPO_ROOT
$WORKING_DIR = $envData.WORKING_DIR
$CURRENT_BRANCH = $envData.CURRENT_BRANCH
$HAS_GIT = $envData.HAS_GIT
$IMPL_PLAN = $envData.IMPL_PLAN
$NEW_PLAN = $IMPL_PLAN

# Agent file paths
$CLAUDE_FILE = Join-Path $REPO_ROOT 'CLAUDE.md'
$GEMINI_FILE = Join-Path $REPO_ROOT 'GEMINI.md'
$COPILOT_FILE = Join-Path $REPO_ROOT '.github/copilot-instructions.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'
$WINDSURF_FILE = Join-Path $REPO_ROOT '.windsurf/rules/specify-rules.md'
$KILOCODE_FILE = Join-Path $REPO_ROOT '.kilocode/rules/specify-rules.md'
$AUGGIE_FILE = Join-Path $REPO_ROOT '.augment/rules/specify-rules.md'
$ROO_FILE = Join-Path $REPO_ROOT '.roo/rules/specify-rules.md'

$TEMPLATE_FILE = Join-Path $REPO_ROOT '.specify/templates/agent-file-template.md'
$CLAUDE_FILE = Join-Path $WORKING_DIR 'CLAUDE.md'
$GEMINI_FILE = Join-Path $WORKING_DIR 'GEMINI.md'
$COPILOT_FILE = Join-Path $WORKING_DIR '.github/copilot-instructions.md'
$CURSOR_FILE = Join-Path $WORKING_DIR '.cursor/rules/specify-rules.mdc'
$QWEN_FILE = Join-Path $WORKING_DIR 'QWEN.md'
$AGENTS_FILE = Join-Path $WORKING_DIR 'AGENTS.md'
$WINDSURF_FILE = Join-Path $WORKING_DIR '.windsurf/rules/specify-rules.md'
$KILOCODE_FILE = Join-Path $WORKING_DIR '.kilocode/rules/specify-rules.md'
$AUGGIE_FILE = Join-Path $WORKING_DIR '.augment/rules/specify-rules.md'
$ROO_FILE = Join-Path $WORKING_DIR '.roo/rules/specify-rules.md'

$TEMPLATE_FILE = Join-Path $WORKING_DIR '.specify/templates/agent-file-template.md'

# Parsed plan data placeholders
$script:NEW_LANG = ''
Expand Down Expand Up @@ -265,7 +265,7 @@ function Update-ExistingAgentFile {
[Parameter(Mandatory=$true)]
[datetime]$Date
)
if (-not (Test-Path $TargetFile)) { return (New-AgentFile -TargetFile $TargetFile -ProjectName (Split-Path $REPO_ROOT -Leaf) -Date $Date) }
if (-not (Test-Path $TargetFile)) { return (New-AgentFile -TargetFile $TargetFile -ProjectName (Split-Path $WORKING_DIR -Leaf) -Date $Date) }

$techStack = Format-TechnologyStack -Lang $NEW_LANG -Framework $NEW_FRAMEWORK
$newTechEntries = @()
Expand Down Expand Up @@ -340,7 +340,7 @@ function Update-AgentFile {
)
if (-not $TargetFile -or -not $AgentName) { Write-Err 'Update-AgentFile requires TargetFile and AgentName'; return $false }
Write-Info "Updating $AgentName context file: $TargetFile"
$projectName = Split-Path $REPO_ROOT -Leaf
$projectName = Split-Path $WORKING_DIR -Leaf
$date = Get-Date

$dir = Split-Path -Parent $TargetFile
Expand Down