Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd57e9d444 | ||
|
|
558e682865 | ||
|
|
63bc6b495d | ||
|
|
70b3db27db | ||
|
|
6e94588615 | ||
|
|
ad9c93c13b | ||
|
|
f979b64338 | ||
|
|
b1591282f6 | ||
|
|
60b015a094 | ||
|
|
0c2b367ba0 | ||
|
|
6b8b1a8b93 | ||
|
|
0e6f513c14 | ||
|
|
6f81f7d6a0 | ||
|
|
c875bd0f30 | ||
|
|
736e282562 |
@@ -27,14 +27,6 @@ echo "Building release packages for $NEW_VERSION"
|
|||||||
|
|
||||||
rm -rf sdd-package-base* sdd-*-package-* spec-kit-template-*-${NEW_VERSION}.zip || true
|
rm -rf sdd-package-base* sdd-*-package-* spec-kit-template-*-${NEW_VERSION}.zip || true
|
||||||
|
|
||||||
mkdir -p sdd-package-base
|
|
||||||
SPEC_DIR="sdd-package-base/.specify"
|
|
||||||
mkdir -p "$SPEC_DIR"
|
|
||||||
|
|
||||||
[[ -d memory ]] && { cp -r memory "$SPEC_DIR/"; echo "Copied memory -> .specify"; }
|
|
||||||
[[ -d scripts ]] && { cp -r scripts "$SPEC_DIR/"; echo "Copied scripts -> .specify/scripts"; }
|
|
||||||
[[ -d templates ]] && { mkdir -p "$SPEC_DIR/templates"; find templates -type f -not -path "templates/commands/*" -exec cp --parents {} "$SPEC_DIR"/ \; ; echo "Copied templates -> .specify/templates"; }
|
|
||||||
|
|
||||||
rewrite_paths() {
|
rewrite_paths() {
|
||||||
sed -E \
|
sed -E \
|
||||||
-e 's@(/?)memory/@.specify/memory/@g' \
|
-e 's@(/?)memory/@.specify/memory/@g' \
|
||||||
@@ -93,17 +85,44 @@ build_variant() {
|
|||||||
local base_dir="sdd-${agent}-package-${script}"
|
local base_dir="sdd-${agent}-package-${script}"
|
||||||
echo "Building $agent ($script) package..."
|
echo "Building $agent ($script) package..."
|
||||||
mkdir -p "$base_dir"
|
mkdir -p "$base_dir"
|
||||||
cp -r sdd-package-base/. "$base_dir"/
|
|
||||||
|
# Copy base structure but filter scripts by variant
|
||||||
|
SPEC_DIR="$base_dir/.specify"
|
||||||
|
mkdir -p "$SPEC_DIR"
|
||||||
|
|
||||||
|
[[ -d memory ]] && { cp -r memory "$SPEC_DIR/"; echo "Copied memory -> .specify"; }
|
||||||
|
|
||||||
|
# Only copy the relevant script variant directory
|
||||||
|
if [[ -d scripts ]]; then
|
||||||
|
mkdir -p "$SPEC_DIR/scripts"
|
||||||
|
case $script in
|
||||||
|
sh)
|
||||||
|
[[ -d scripts/bash ]] && { cp -r scripts/bash "$SPEC_DIR/scripts/"; echo "Copied scripts/bash -> .specify/scripts"; }
|
||||||
|
# Copy any script files that aren't in variant-specific directories
|
||||||
|
find scripts -maxdepth 1 -type f -exec cp {} "$SPEC_DIR/scripts/" \; 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
ps)
|
||||||
|
[[ -d scripts/powershell ]] && { cp -r scripts/powershell "$SPEC_DIR/scripts/"; echo "Copied scripts/powershell -> .specify/scripts"; }
|
||||||
|
# Copy any script files that aren't in variant-specific directories
|
||||||
|
find scripts -maxdepth 1 -type f -exec cp {} "$SPEC_DIR/scripts/" \; 2>/dev/null || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -d templates ]] && { mkdir -p "$SPEC_DIR/templates"; find templates -type f -not -path "templates/commands/*" -exec cp --parents {} "$SPEC_DIR"/ \; ; echo "Copied templates -> .specify/templates"; }
|
||||||
# Inject variant into plan-template.md within .specify/templates if present
|
# Inject variant into plan-template.md within .specify/templates if present
|
||||||
local plan_tpl="$base_dir/.specify/templates/plan-template.md"
|
local plan_tpl="$base_dir/.specify/templates/plan-template.md"
|
||||||
if [[ -f "$plan_tpl" ]]; then
|
if [[ -f "$plan_tpl" ]]; then
|
||||||
plan_norm=$(tr -d '\r' < "$plan_tpl")
|
plan_norm=$(tr -d '\r' < "$plan_tpl")
|
||||||
variant_line=$(printf '%s\n' "$plan_norm" | grep -E "<!--[[:space:]]*VARIANT:$script" | head -1 | sed -E "s/.*VARIANT:$script[[:space:]]+//; s/-->.*//; s/^[[:space:]]+//; s/[[:space:]]+$//")
|
# Extract script command from YAML frontmatter
|
||||||
if [[ -n $variant_line ]]; then
|
script_command=$(printf '%s\n' "$plan_norm" | awk -v sv="$script" '/^[[:space:]]*'"$script"':[[:space:]]*/ {sub(/^[[:space:]]*'"$script"':[[:space:]]*/, ""); print; exit}')
|
||||||
|
|
||||||
|
if [[ -n $script_command ]]; then
|
||||||
tmp_file=$(mktemp)
|
tmp_file=$(mktemp)
|
||||||
sed "s|VARIANT-INJECT|${variant_line}|" "$plan_tpl" | tr -d '\r' | sed "s|__AGENT__|${agent}|g" | sed '/<!--[[:space:]]*VARIANT:sh/d' | sed '/<!--[[:space:]]*VARIANT:ps/d' > "$tmp_file" && mv "$tmp_file" "$plan_tpl"
|
# Replace {SCRIPT} placeholder with the script command and __AGENT__ with agent name
|
||||||
|
sed "s|{SCRIPT}|${script_command}|g" "$plan_tpl" | tr -d '\r' | sed "s|__AGENT__|${agent}|g" > "$tmp_file" && mv "$tmp_file" "$plan_tpl"
|
||||||
else
|
else
|
||||||
echo "Warning: no plan-template variant for $script (pattern not matched)" >&2
|
echo "Warning: no plan-template script command found for $script in YAML frontmatter" >&2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
case $agent in
|
case $agent in
|
||||||
|
|||||||
22
CHANGELOG.md
Normal file
22
CHANGELOG.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to the Specify CLI will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.0.4] - 2025-09-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- SOCKS proxy support for corporate environments via `httpx[socks]` dependency
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
N/A
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
N/A
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
- [🤔 What is Spec-Driven Development?](#-what-is-spec-driven-development)
|
- [🤔 What is Spec-Driven Development?](#-what-is-spec-driven-development)
|
||||||
- [⚡ Get started](#-get-started)
|
- [⚡ Get started](#-get-started)
|
||||||
|
- [📽️ Video Overview](#️-video-overview)
|
||||||
- [🔧 Specify CLI Reference](#-specify-cli-reference)
|
- [🔧 Specify CLI Reference](#-specify-cli-reference)
|
||||||
- [📚 Core philosophy](#-core-philosophy)
|
- [📚 Core philosophy](#-core-philosophy)
|
||||||
- [🌟 Development phases](#-development-phases)
|
- [🌟 Development phases](#-development-phases)
|
||||||
@@ -65,6 +66,12 @@ Use **`/tasks`** to create an actionable task list, then ask your agent to imple
|
|||||||
|
|
||||||
For detailed step-by-step instructions, see our [comprehensive guide](./spec-driven.md).
|
For detailed step-by-step instructions, see our [comprehensive guide](./spec-driven.md).
|
||||||
|
|
||||||
|
## 📽️ Video Overview
|
||||||
|
|
||||||
|
Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.com/watch?v=a9eR1xsfvHg&pp=0gcJCckJAYcqIYzv)!
|
||||||
|
|
||||||
|
[](https://www.youtube.com/watch?v=a9eR1xsfvHg&pp=0gcJCckJAYcqIYzv)
|
||||||
|
|
||||||
## 🔧 Specify CLI Reference
|
## 🔧 Specify CLI Reference
|
||||||
|
|
||||||
The `specify` command supports the following options:
|
The `specify` command supports the following options:
|
||||||
@@ -74,7 +81,7 @@ The `specify` command supports the following options:
|
|||||||
| Command | Description |
|
| Command | Description |
|
||||||
|-------------|----------------------------------------------------------------|
|
|-------------|----------------------------------------------------------------|
|
||||||
| `init` | Initialize a new Specify project from the latest template |
|
| `init` | Initialize a new Specify project from the latest template |
|
||||||
| `check` | Check for installed tools (`git`, `claude`, `gemini`) |
|
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `cursor-agent`) |
|
||||||
|
|
||||||
### `specify init` Arguments & Options
|
### `specify init` Arguments & Options
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Spec-Driven Development **flips the script** on traditional software development
|
|||||||
|
|
||||||
- [Installation Guide](installation.md)
|
- [Installation Guide](installation.md)
|
||||||
- [Quick Start Guide](quickstart.md)
|
- [Quick Start Guide](quickstart.md)
|
||||||
- [Local Development](local-development.md)
|
- [Local Development](local-development.md)
|
||||||
|
|
||||||
## Core Philosophy
|
## Core Philosophy
|
||||||
|
|
||||||
|
|||||||
BIN
media/spec-kit-video-header.jpg
Normal file
BIN
media/spec-kit-video-header.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
@@ -1,12 +1,12 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "specify-cli"
|
name = "specify-cli"
|
||||||
version = "0.0.3"
|
version = "0.0.4"
|
||||||
description = "Setup tool for Specify spec-driven development projects"
|
description = "Setup tool for Specify spec-driven development projects"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typer",
|
"typer",
|
||||||
"rich",
|
"rich",
|
||||||
"httpx",
|
"httpx[socks]",
|
||||||
"platformdirs",
|
"platformdirs",
|
||||||
"readchar",
|
"readchar",
|
||||||
"truststore>=0.10.4",
|
"truststore>=0.10.4",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ REPO_ROOT=$(git rev-parse --show-toplevel)
|
|||||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||||
FEATURE_DIR="$REPO_ROOT/specs/$CURRENT_BRANCH"
|
FEATURE_DIR="$REPO_ROOT/specs/$CURRENT_BRANCH"
|
||||||
NEW_PLAN="$FEATURE_DIR/plan.md"
|
NEW_PLAN="$FEATURE_DIR/plan.md"
|
||||||
CLAUDE_FILE="$REPO_ROOT/CLAUDE.md"; GEMINI_FILE="$REPO_ROOT/GEMINI.md"; COPILOT_FILE="$REPO_ROOT/.github/copilot-instructions.md"
|
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"
|
||||||
AGENT_TYPE="$1"
|
AGENT_TYPE="$1"
|
||||||
[ -f "$NEW_PLAN" ] || { echo "ERROR: No plan.md found at $NEW_PLAN"; exit 1; }
|
[ -f "$NEW_PLAN" ] || { echo "ERROR: No plan.md found at $NEW_PLAN"; exit 1; }
|
||||||
echo "=== Updating agent context files for feature $CURRENT_BRANCH ==="
|
echo "=== Updating agent context files for feature $CURRENT_BRANCH ==="
|
||||||
@@ -13,7 +13,7 @@ NEW_FRAMEWORK=$(grep "^**Primary Dependencies**: " "$NEW_PLAN" 2>/dev/null | hea
|
|||||||
NEW_DB=$(grep "^**Storage**: " "$NEW_PLAN" 2>/dev/null | head -1 | sed 's/^**Storage**: //' | grep -v "N/A" | grep -v "NEEDS CLARIFICATION" || echo "")
|
NEW_DB=$(grep "^**Storage**: " "$NEW_PLAN" 2>/dev/null | head -1 | sed 's/^**Storage**: //' | grep -v "N/A" | grep -v "NEEDS CLARIFICATION" || echo "")
|
||||||
NEW_PROJECT_TYPE=$(grep "^**Project Type**: " "$NEW_PLAN" 2>/dev/null | head -1 | sed 's/^**Project Type**: //' || echo "")
|
NEW_PROJECT_TYPE=$(grep "^**Project Type**: " "$NEW_PLAN" 2>/dev/null | head -1 | sed 's/^**Project Type**: //' || echo "")
|
||||||
update_agent_file() { local target_file="$1" agent_name="$2"; echo "Updating $agent_name context file: $target_file"; local temp_file=$(mktemp); if [ ! -f "$target_file" ]; then
|
update_agent_file() { local target_file="$1" agent_name="$2"; echo "Updating $agent_name context file: $target_file"; local temp_file=$(mktemp); if [ ! -f "$target_file" ]; then
|
||||||
echo "Creating new $agent_name context file..."; if [ -f "$REPO_ROOT/templates/agent-file-template.md" ]; then cp "$REPO_ROOT/templates/agent-file-template.md" "$temp_file"; else echo "ERROR: Template not found"; return 1; fi;
|
echo "Creating new $agent_name context file..."; if [ -f "$REPO_ROOT/.specify/templates/agent-file-template.md" ]; then cp "$REPO_ROOT/templates/agent-file-template.md" "$temp_file"; else echo "ERROR: Template not found"; return 1; fi;
|
||||||
sed -i.bak "s/\[PROJECT NAME\]/$(basename $REPO_ROOT)/" "$temp_file"; sed -i.bak "s/\[DATE\]/$(date +%Y-%m-%d)/" "$temp_file"; sed -i.bak "s/\[EXTRACTED FROM ALL PLAN.MD FILES\]/- $NEW_LANG + $NEW_FRAMEWORK ($CURRENT_BRANCH)/" "$temp_file";
|
sed -i.bak "s/\[PROJECT NAME\]/$(basename $REPO_ROOT)/" "$temp_file"; sed -i.bak "s/\[DATE\]/$(date +%Y-%m-%d)/" "$temp_file"; sed -i.bak "s/\[EXTRACTED FROM ALL PLAN.MD FILES\]/- $NEW_LANG + $NEW_FRAMEWORK ($CURRENT_BRANCH)/" "$temp_file";
|
||||||
if [[ "$NEW_PROJECT_TYPE" == *"web"* ]]; then sed -i.bak "s|\[ACTUAL STRUCTURE FROM PLANS\]|backend/\nfrontend/\ntests/|" "$temp_file"; else sed -i.bak "s|\[ACTUAL STRUCTURE FROM PLANS\]|src/\ntests/|" "$temp_file"; fi;
|
if [[ "$NEW_PROJECT_TYPE" == *"web"* ]]; then sed -i.bak "s|\[ACTUAL STRUCTURE FROM PLANS\]|backend/\nfrontend/\ntests/|" "$temp_file"; else sed -i.bak "s|\[ACTUAL STRUCTURE FROM PLANS\]|src/\ntests/|" "$temp_file"; fi;
|
||||||
if [[ "$NEW_LANG" == *"Python"* ]]; then COMMANDS="cd src && pytest && ruff check ."; elif [[ "$NEW_LANG" == *"Rust"* ]]; then COMMANDS="cargo test && cargo clippy"; elif [[ "$NEW_LANG" == *"JavaScript"* ]] || [[ "$NEW_LANG" == *"TypeScript"* ]]; then COMMANDS="npm test && npm run lint"; else COMMANDS="# Add commands for $NEW_LANG"; fi; sed -i.bak "s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$COMMANDS|" "$temp_file";
|
if [[ "$NEW_LANG" == *"Python"* ]]; then COMMANDS="cd src && pytest && ruff check ."; elif [[ "$NEW_LANG" == *"Rust"* ]]; then COMMANDS="cargo test && cargo clippy"; elif [[ "$NEW_LANG" == *"JavaScript"* ]] || [[ "$NEW_LANG" == *"TypeScript"* ]]; then COMMANDS="npm test && npm run lint"; else COMMANDS="# Add commands for $NEW_LANG"; fi; sed -i.bak "s|\[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES\]|$COMMANDS|" "$temp_file";
|
||||||
@@ -51,7 +51,12 @@ case "$AGENT_TYPE" in
|
|||||||
claude) update_agent_file "$CLAUDE_FILE" "Claude Code" ;;
|
claude) update_agent_file "$CLAUDE_FILE" "Claude Code" ;;
|
||||||
gemini) update_agent_file "$GEMINI_FILE" "Gemini CLI" ;;
|
gemini) update_agent_file "$GEMINI_FILE" "Gemini CLI" ;;
|
||||||
copilot) update_agent_file "$COPILOT_FILE" "GitHub Copilot" ;;
|
copilot) update_agent_file "$COPILOT_FILE" "GitHub Copilot" ;;
|
||||||
"") [ -f "$CLAUDE_FILE" ] && update_agent_file "$CLAUDE_FILE" "Claude Code"; [ -f "$GEMINI_FILE" ] && update_agent_file "$GEMINI_FILE" "Gemini CLI"; [ -f "$COPILOT_FILE" ] && update_agent_file "$COPILOT_FILE" "GitHub Copilot"; if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ]; then update_agent_file "$CLAUDE_FILE" "Claude Code"; fi ;;
|
cursor) update_agent_file "$CURSOR_FILE" "Cursor IDE" ;;
|
||||||
*) echo "ERROR: Unknown agent type '$AGENT_TYPE'"; exit 1 ;;
|
"") [ -f "$CLAUDE_FILE" ] && update_agent_file "$CLAUDE_FILE" "Claude Code"; \
|
||||||
|
[ -f "$GEMINI_FILE" ] && update_agent_file "$GEMINI_FILE" "Gemini CLI"; \
|
||||||
|
[ -f "$COPILOT_FILE" ] && update_agent_file "$COPILOT_FILE" "GitHub Copilot"; \
|
||||||
|
[ -f "$CURSOR_FILE" ] && update_agent_file "$CURSOR_FILE" "Cursor IDE"; \
|
||||||
|
if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ] && [ ! -f "$CURSOR_FILE" ]; then update_agent_file "$CLAUDE_FILE" "Claude Code"; fi ;;
|
||||||
|
*) echo "ERROR: Unknown agent type '$AGENT_TYPE' (expected claude|gemini|copilot|cursor)"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
echo; echo "Summary of changes:"; [ -n "$NEW_LANG" ] && echo "- Added language: $NEW_LANG"; [ -n "$NEW_FRAMEWORK" ] && echo "- Added framework: $NEW_FRAMEWORK"; [ -n "$NEW_DB" ] && [ "$NEW_DB" != "N/A" ] && echo "- Added database: $NEW_DB"; echo; echo "Usage: $0 [claude|gemini|copilot]"
|
echo; echo "Summary of changes:"; [ -n "$NEW_LANG" ] && echo "- Added language: $NEW_LANG"; [ -n "$NEW_FRAMEWORK" ] && echo "- Added framework: $NEW_FRAMEWORK"; [ -n "$NEW_DB" ] && [ "$NEW_DB" != "N/A" ] && echo "- Added database: $NEW_DB"; echo; echo "Usage: $0 [claude|gemini|copilot|cursor]"
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ if (-not (Test-Path $newPlan)) { Write-Error "ERROR: No plan.md found at $newPla
|
|||||||
$claudeFile = Join-Path $repoRoot 'CLAUDE.md'
|
$claudeFile = Join-Path $repoRoot 'CLAUDE.md'
|
||||||
$geminiFile = Join-Path $repoRoot 'GEMINI.md'
|
$geminiFile = Join-Path $repoRoot 'GEMINI.md'
|
||||||
$copilotFile = Join-Path $repoRoot '.github/copilot-instructions.md'
|
$copilotFile = Join-Path $repoRoot '.github/copilot-instructions.md'
|
||||||
|
$cursorFile = Join-Path $repoRoot '.cursor/rules/specify-rules.mdc'
|
||||||
|
|
||||||
Write-Output "=== Updating agent context files for feature $currentBranch ==="
|
Write-Output "=== Updating agent context files for feature $currentBranch ==="
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ $newProjectType = Get-PlanValue 'Project Type'
|
|||||||
|
|
||||||
function Initialize-AgentFile($targetFile, $agentName) {
|
function Initialize-AgentFile($targetFile, $agentName) {
|
||||||
if (Test-Path $targetFile) { return }
|
if (Test-Path $targetFile) { return }
|
||||||
$template = Join-Path $repoRoot 'templates/agent-file-template.md'
|
$template = Join-Path $repoRoot '.specify/templates/agent-file-template.md'
|
||||||
if (-not (Test-Path $template)) { Write-Error "Template not found: $template"; return }
|
if (-not (Test-Path $template)) { Write-Error "Template not found: $template"; return }
|
||||||
$content = Get-Content $template -Raw
|
$content = Get-Content $template -Raw
|
||||||
$content = $content.Replace('[PROJECT NAME]', (Split-Path $repoRoot -Leaf))
|
$content = $content.Replace('[PROJECT NAME]', (Split-Path $repoRoot -Leaf))
|
||||||
@@ -43,8 +44,8 @@ function Initialize-AgentFile($targetFile, $agentName) {
|
|||||||
elseif ($newLang -match 'JavaScript|TypeScript') { $commands = 'npm test && npm run lint' }
|
elseif ($newLang -match 'JavaScript|TypeScript') { $commands = 'npm test && npm run lint' }
|
||||||
else { $commands = "# Add commands for $newLang" }
|
else { $commands = "# Add commands for $newLang" }
|
||||||
$content = $content.Replace('[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]', $commands)
|
$content = $content.Replace('[ONLY COMMANDS FOR ACTIVE TECHNOLOGIES]', $commands)
|
||||||
$content = $content.Replace('[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]', "$newLang: Follow standard conventions")
|
$content = $content.Replace('[LANGUAGE-SPECIFIC, ONLY FOR LANGUAGES IN USE]', "${newLang}: Follow standard conventions")
|
||||||
$content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- $currentBranch: Added $newLang + $newFramework")
|
$content = $content.Replace('[LAST 3 FEATURES AND WHAT THEY ADDED]', "- ${currentBranch}: Added ${newLang} + ${newFramework}")
|
||||||
$content | Set-Content $targetFile -Encoding UTF8
|
$content | Set-Content $targetFile -Encoding UTF8
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +56,7 @@ function Update-AgentFile($targetFile, $agentName) {
|
|||||||
if ($newDb -and $newDb -ne 'N/A' -and ($content -notmatch [regex]::Escape($newDb))) { $content = $content -replace '(## Active Technologies\n)', "`$1- $newDb ($currentBranch)`n" }
|
if ($newDb -and $newDb -ne 'N/A' -and ($content -notmatch [regex]::Escape($newDb))) { $content = $content -replace '(## Active Technologies\n)', "`$1- $newDb ($currentBranch)`n" }
|
||||||
if ($content -match '## Recent Changes\n([\s\S]*?)(\n\n|$)') {
|
if ($content -match '## Recent Changes\n([\s\S]*?)(\n\n|$)') {
|
||||||
$changesBlock = $matches[1].Trim().Split("`n")
|
$changesBlock = $matches[1].Trim().Split("`n")
|
||||||
$changesBlock = ,"- $currentBranch: Added $newLang + $newFramework" + $changesBlock
|
$changesBlock = ,"- ${currentBranch}: Added ${newLang} + ${newFramework}" + $changesBlock
|
||||||
$changesBlock = $changesBlock | Where-Object { $_ } | Select-Object -First 3
|
$changesBlock = $changesBlock | Where-Object { $_ } | Select-Object -First 3
|
||||||
$joined = ($changesBlock -join "`n")
|
$joined = ($changesBlock -join "`n")
|
||||||
$content = [regex]::Replace($content, '## Recent Changes\n([\s\S]*?)(\n\n|$)', "## Recent Changes`n$joined`n`n")
|
$content = [regex]::Replace($content, '## Recent Changes\n([\s\S]*?)(\n\n|$)', "## Recent Changes`n$joined`n`n")
|
||||||
@@ -69,16 +70,22 @@ switch ($AgentType) {
|
|||||||
'claude' { Update-AgentFile $claudeFile 'Claude Code' }
|
'claude' { Update-AgentFile $claudeFile 'Claude Code' }
|
||||||
'gemini' { Update-AgentFile $geminiFile 'Gemini CLI' }
|
'gemini' { Update-AgentFile $geminiFile 'Gemini CLI' }
|
||||||
'copilot' { Update-AgentFile $copilotFile 'GitHub Copilot' }
|
'copilot' { Update-AgentFile $copilotFile 'GitHub Copilot' }
|
||||||
|
'cursor' { Update-AgentFile $cursorFile 'Cursor IDE' }
|
||||||
'' {
|
'' {
|
||||||
foreach ($pair in @(@{file=$claudeFile; name='Claude Code'}, @{file=$geminiFile; name='Gemini CLI'}, @{file=$copilotFile; name='GitHub Copilot'})) {
|
foreach ($pair in @(
|
||||||
|
@{file=$claudeFile; name='Claude Code'},
|
||||||
|
@{file=$geminiFile; name='Gemini CLI'},
|
||||||
|
@{file=$copilotFile; name='GitHub Copilot'},
|
||||||
|
@{file=$cursorFile; name='Cursor IDE'}
|
||||||
|
)) {
|
||||||
if (Test-Path $pair.file) { Update-AgentFile $pair.file $pair.name }
|
if (Test-Path $pair.file) { Update-AgentFile $pair.file $pair.name }
|
||||||
}
|
}
|
||||||
if (-not (Test-Path $claudeFile) -and -not (Test-Path $geminiFile) -and -not (Test-Path $copilotFile)) {
|
if (-not (Test-Path $claudeFile) -and -not (Test-Path $geminiFile) -and -not (Test-Path $copilotFile) -and -not (Test-Path $cursorFile)) {
|
||||||
Write-Output 'No agent context files found. Creating Claude Code context file by default.'
|
Write-Output 'No agent context files found. Creating Claude Code context file by default.'
|
||||||
Update-AgentFile $claudeFile 'Claude Code'
|
Update-AgentFile $claudeFile 'Claude Code'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Default { Write-Error "ERROR: Unknown agent type '$AgentType'. Use: claude, gemini, copilot, or leave empty for all."; exit 1 }
|
Default { Write-Error "ERROR: Unknown agent type '$AgentType'. Use: claude, gemini, copilot, cursor or leave empty for all."; exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Output ''
|
Write-Output ''
|
||||||
@@ -88,4 +95,4 @@ if ($newFramework) { Write-Output "- Added framework: $newFramework" }
|
|||||||
if ($newDb -and $newDb -ne 'N/A') { Write-Output "- Added database: $newDb" }
|
if ($newDb -and $newDb -ne 'N/A') { Write-Output "- Added database: $newDb" }
|
||||||
|
|
||||||
Write-Output ''
|
Write-Output ''
|
||||||
Write-Output 'Usage: ./update-agent-context.ps1 [claude|gemini|copilot]'
|
Write-Output 'Usage: ./update-agent-context.ps1 [claude|gemini|copilot|cursor]'
|
||||||
|
|||||||
@@ -825,8 +825,7 @@ def init(
|
|||||||
if not check_tool("gemini", "Install from: https://github.com/google-gemini/gemini-cli"):
|
if not check_tool("gemini", "Install from: https://github.com/google-gemini/gemini-cli"):
|
||||||
console.print("[red]Error:[/red] Gemini CLI is required for Gemini projects")
|
console.print("[red]Error:[/red] Gemini CLI is required for Gemini projects")
|
||||||
agent_tool_missing = True
|
agent_tool_missing = True
|
||||||
# GitHub Copilot check is not needed as it's typically available in supported IDEs
|
|
||||||
|
|
||||||
if agent_tool_missing:
|
if agent_tool_missing:
|
||||||
console.print("\n[red]Required AI tool is missing![/red]")
|
console.print("\n[red]Required AI tool is missing![/red]")
|
||||||
console.print("[yellow]Tip:[/yellow] Use --ignore-agent-tools to skip this check")
|
console.print("[yellow]Tip:[/yellow] Use --ignore-agent-tools to skip this check")
|
||||||
@@ -976,11 +975,18 @@ def check():
|
|||||||
tracker.add("git", "Git version control")
|
tracker.add("git", "Git version control")
|
||||||
tracker.add("claude", "Claude Code CLI")
|
tracker.add("claude", "Claude Code CLI")
|
||||||
tracker.add("gemini", "Gemini CLI")
|
tracker.add("gemini", "Gemini CLI")
|
||||||
|
tracker.add("code", "VS Code (for GitHub Copilot)")
|
||||||
|
tracker.add("cursor-agent", "Cursor IDE agent (optional)")
|
||||||
|
|
||||||
# Check each tool
|
# Check each tool
|
||||||
git_ok = check_tool_for_tracker("git", "https://git-scm.com/downloads", tracker)
|
git_ok = check_tool_for_tracker("git", "https://git-scm.com/downloads", tracker)
|
||||||
claude_ok = check_tool_for_tracker("claude", "https://docs.anthropic.com/en/docs/claude-code/setup", tracker)
|
claude_ok = check_tool_for_tracker("claude", "https://docs.anthropic.com/en/docs/claude-code/setup", tracker)
|
||||||
gemini_ok = check_tool_for_tracker("gemini", "https://github.com/google-gemini/gemini-cli", tracker)
|
gemini_ok = check_tool_for_tracker("gemini", "https://github.com/google-gemini/gemini-cli", tracker)
|
||||||
|
# Check for VS Code (code or code-insiders)
|
||||||
|
code_ok = check_tool_for_tracker("code", "https://code.visualstudio.com/", tracker)
|
||||||
|
if not code_ok:
|
||||||
|
code_ok = check_tool_for_tracker("code-insiders", "https://code.visualstudio.com/insiders/", tracker)
|
||||||
|
cursor_ok = check_tool_for_tracker("cursor-agent", "https://cursor.sh/", tracker)
|
||||||
|
|
||||||
# Render the final tree
|
# Render the final tree
|
||||||
console.print(tracker.render())
|
console.print(tracker.render())
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
description: Create or update the feature specification from a natural language feature description.
|
description: Create or update the feature specification from a natural language feature description.
|
||||||
scripts:
|
scripts:
|
||||||
sh: scripts/bash/create-new-feature.sh --json "{ARGS}"
|
sh: .specify/scripts/bash/create-new-feature.sh --json "{ARGS}"
|
||||||
ps: scripts/powershell/create-new-feature.ps1 -Json "{ARGS}"
|
ps: .specify/scripts/powershell/create-new-feature.ps1 -Json "{ARGS}"
|
||||||
---
|
---
|
||||||
|
|
||||||
Given the feature description provided as an argument, do this:
|
Given the feature description provided as an argument, do this:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
---
|
---
|
||||||
description: Generate an actionable, dependency-ordered tasks.md for the feature based on available design artifacts.
|
description: Generate an actionable, dependency-ordered tasks.md for the feature based on available design artifacts.
|
||||||
scripts:
|
scripts:
|
||||||
sh: scripts/bash/check-task-prerequisites.sh --json
|
sh: .specify/scripts/bash/check-task-prerequisites.sh --json
|
||||||
ps: scripts/powershell/check-task-prerequisites.ps1 -Json
|
ps: .specify/scripts/powershell/check-task-prerequisites.ps1 -Json
|
||||||
---
|
---
|
||||||
|
|
||||||
Given the context provided as an argument, do this:
|
Given the context provided as an argument, do this:
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
# Implementation Plan: [FEATURE]
|
---
|
||||||
|
description: "Implementation plan template for feature development"
|
||||||
|
scripts:
|
||||||
|
sh: .specify/scripts/bash/update-agent-context.sh __AGENT__
|
||||||
|
ps: .specify/scripts/powershell/update-agent-context.ps1 -AgentType __AGENT__
|
||||||
|
---
|
||||||
|
|
||||||
<!-- VARIANT:sh - Run `/scripts/bash/update-agent-context.sh __AGENT__` for your AI assistant -->
|
# Implementation Plan: [FEATURE]
|
||||||
<!-- VARIANT:ps - Run `/scripts/powershell/update-agent-context.ps1 -AgentType __AGENT__` for your AI assistant -->
|
|
||||||
|
|
||||||
**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link]
|
**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link]
|
||||||
**Input**: Feature specification from `/specs/[###-feature-name]/spec.md`
|
**Input**: Feature specification from `/specs/[###-feature-name]/spec.md`
|
||||||
@@ -174,7 +178,7 @@ ios/ or android/
|
|||||||
- Quickstart test = story validation steps
|
- Quickstart test = story validation steps
|
||||||
|
|
||||||
5. **Update agent file incrementally** (O(1) operation):
|
5. **Update agent file incrementally** (O(1) operation):
|
||||||
VARIANT-INJECT
|
- Run `{SCRIPT}` for your AI assistant
|
||||||
- If exists: Add only NEW tech from current plan
|
- If exists: Add only NEW tech from current plan
|
||||||
- Preserve manual additions between markers
|
- Preserve manual additions between markers
|
||||||
- Update recent changes (keep last 3)
|
- Update recent changes (keep last 3)
|
||||||
@@ -187,7 +191,7 @@ ios/ or android/
|
|||||||
*This section describes what the /tasks command will do - DO NOT execute during /plan*
|
*This section describes what the /tasks command will do - DO NOT execute during /plan*
|
||||||
|
|
||||||
**Task Generation Strategy**:
|
**Task Generation Strategy**:
|
||||||
- Load `/templates/tasks-template.md` as base
|
- Load `.specify/templates/tasks-template.md` as base
|
||||||
- Generate tasks from Phase 1 design docs (contracts, data model, quickstart)
|
- Generate tasks from Phase 1 design docs (contracts, data model, quickstart)
|
||||||
- Each contract → contract test task [P]
|
- Each contract → contract test task [P]
|
||||||
- Each entity → model creation task [P]
|
- Each entity → model creation task [P]
|
||||||
|
|||||||
Reference in New Issue
Block a user