Compare commits
16 Commits
add-apm-in
...
v0.0.36
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec47ecfd16 | ||
|
|
c5f7582470 | ||
|
|
87d4998b9d | ||
|
|
10e56aa67c | ||
|
|
cc686c6621 | ||
|
|
8b49d5d0fb | ||
|
|
66688dffa3 | ||
|
|
b18ef208cb | ||
|
|
5828e58f84 | ||
|
|
dd57e9d444 | ||
|
|
558e682865 | ||
|
|
c5e0c1840b | ||
|
|
856680e3bc | ||
|
|
0c419e5198 | ||
|
|
fe4de3ca45 | ||
|
|
73a9af70a4 |
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -81,7 +81,7 @@ jobs:
|
||||
cat > release_notes.md << EOF
|
||||
Template release ${{ steps.get_tag.outputs.new_version }}
|
||||
|
||||
Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, and Cursor.
|
||||
Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, Cursor and opencode.
|
||||
|
||||
Now includes per-script variants for POSIX shell (sh) and PowerShell (ps).
|
||||
|
||||
@@ -94,6 +94,8 @@ jobs:
|
||||
- spec-kit-template-gemini-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||
- spec-kit-template-cursor-sh-${{ steps.get_tag.outputs.new_version }}.zip
|
||||
- spec-kit-template-cursor-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||
- spec-kit-template-opencode-sh-${{ steps.get_tag.outputs.new_version }}.zip
|
||||
- spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||
EOF
|
||||
|
||||
echo "Generated release notes:"
|
||||
@@ -114,6 +116,8 @@ jobs:
|
||||
spec-kit-template-gemini-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||
spec-kit-template-cursor-sh-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||
spec-kit-template-cursor-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||
spec-kit-template-opencode-sh-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||
spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||
--title "Spec Kit Templates - $VERSION_NO_V" \
|
||||
--notes-file release_notes.md
|
||||
env:
|
||||
|
||||
@@ -6,7 +6,7 @@ set -euo pipefail
|
||||
# Usage: .github/workflows/scripts/create-release-packages.sh <version>
|
||||
# Version argument should include leading 'v'.
|
||||
# Optionally set AGENTS and/or SCRIPTS env vars to limit what gets built.
|
||||
# AGENTS : space or comma separated subset of: claude gemini copilot (default: all)
|
||||
# AGENTS : space or comma separated subset of: claude gemini copilot opencode (default: all)
|
||||
# SCRIPTS : space or comma separated subset of: sh ps (default: both)
|
||||
# Examples:
|
||||
# AGENTS=claude SCRIPTS=sh $0 v0.2.0
|
||||
@@ -114,12 +114,19 @@ build_variant() {
|
||||
local plan_tpl="$base_dir/.specify/templates/plan-template.md"
|
||||
if [[ -f "$plan_tpl" ]]; then
|
||||
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:]]+$//")
|
||||
if [[ -n $variant_line ]]; then
|
||||
# Extract script command from YAML frontmatter
|
||||
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
|
||||
# Always prefix with .specify/ for plan usage
|
||||
script_command=".specify/$script_command"
|
||||
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
|
||||
substituted=$(sed "s|{SCRIPT}|${script_command}|g" "$plan_tpl" | tr -d '\r' | sed "s|__AGENT__|${agent}|g")
|
||||
# Strip YAML frontmatter from plan template output (keep body only)
|
||||
stripped=$(printf '%s\n' "$substituted" | awk 'BEGIN{fm=0;dash=0} /^---$/ {dash++; if(dash==1){fm=1; next} else if(dash==2){fm=0; next}} {if(!fm) print}')
|
||||
printf '%s\n' "$stripped" > "$plan_tpl"
|
||||
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
|
||||
case $agent in
|
||||
@@ -136,13 +143,20 @@ build_variant() {
|
||||
cursor)
|
||||
mkdir -p "$base_dir/.cursor/commands"
|
||||
generate_commands cursor md "\$ARGUMENTS" "$base_dir/.cursor/commands" "$script" ;;
|
||||
qwen)
|
||||
mkdir -p "$base_dir/.qwen/commands"
|
||||
generate_commands qwen md "\$ARGUMENTS" "$base_dir/.qwen/commands" "$script"
|
||||
[[ -f agent_templates/qwen/QWEN.md ]] && cp agent_templates/qwen/QWEN.md "$base_dir/QWEN.md" ;;
|
||||
opencode)
|
||||
mkdir -p "$base_dir/.opencode/command"
|
||||
generate_commands opencode md "\$ARGUMENTS" "$base_dir/.opencode/command" "$script" ;;
|
||||
esac
|
||||
( cd "$base_dir" && zip -r "../spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" . )
|
||||
echo "Created spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
|
||||
}
|
||||
|
||||
# Determine agent list
|
||||
ALL_AGENTS=(claude gemini copilot cursor)
|
||||
ALL_AGENTS=(claude gemini copilot cursor qwen opencode)
|
||||
ALL_SCRIPTS=(sh ps)
|
||||
|
||||
norm_list() {
|
||||
|
||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.0.6] - 2025-09-17
|
||||
|
||||
### Added
|
||||
|
||||
- opencode support as additional AI assistant option
|
||||
|
||||
## [0.0.5] - 2025-09-17
|
||||
|
||||
### Added
|
||||
|
||||
- Qwen Code support as additional AI assistant option
|
||||
|
||||
## [0.0.4] - 2025-09-14
|
||||
|
||||
### Added
|
||||
@@ -20,3 +32,4 @@ N/A
|
||||
### Changed
|
||||
|
||||
N/A
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ These are one time installations required to be able to test your changes locall
|
||||
1. Install [Python 3.11+](https://www.python.org/downloads/)
|
||||
1. Install [uv](https://docs.astral.sh/uv/) for package management
|
||||
1. Install [Git](https://git-scm.com/downloads)
|
||||
1. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), or [Gemini CLI](https://github.com/google-gemini/gemini-cli) are recommended, but we're working on adding support for other agents as well.
|
||||
1. Have an AI coding agent available: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Qwen Code](https://github.com/QwenLM/qwen-code). We're working on adding support for other agents as well.
|
||||
|
||||
## Submitting a pull request
|
||||
|
||||
|
||||
10
README.md
10
README.md
@@ -81,14 +81,14 @@ The `specify` command supports the following options:
|
||||
| Command | Description |
|
||||
|-------------|----------------------------------------------------------------|
|
||||
| `init` | Initialize a new Specify project from the latest template |
|
||||
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `cursor-agent`) |
|
||||
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `opencode`, `cursor-agent`) |
|
||||
|
||||
### `specify init` Arguments & Options
|
||||
|
||||
| Argument/Option | Type | Description |
|
||||
|------------------------|----------|------------------------------------------------------------------------------|
|
||||
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`) |
|
||||
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, or `cursor` |
|
||||
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `opencode`, or `cursor` |
|
||||
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) |
|
||||
| `--ignore-agent-tools` | Flag | Skip checks for AI agent tools like Claude Code |
|
||||
| `--no-git` | Flag | Skip git repository initialization |
|
||||
@@ -170,7 +170,7 @@ Our research and experimentation focus on:
|
||||
## 🔧 Prerequisites
|
||||
|
||||
- **Linux/macOS** (or WSL2 on Windows)
|
||||
- AI coding agent: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), or [Cursor](https://cursor.sh/)
|
||||
- AI coding agent: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Cursor](https://cursor.sh/), [Qwen CLI](https://github.com/QwenLM/qwen-code) or [opencode](https://opencode.ai/)
|
||||
- [uv](https://docs.astral.sh/uv/) for package management
|
||||
- [Python 3.11+](https://www.python.org/downloads/)
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
@@ -207,11 +207,13 @@ You will be prompted to select the AI agent you are using. You can also proactiv
|
||||
specify init <project_name> --ai claude
|
||||
specify init <project_name> --ai gemini
|
||||
specify init <project_name> --ai copilot
|
||||
specify init <project_name> --ai qwen
|
||||
specify init <project_name> --ai opencode
|
||||
# Or in current directory:
|
||||
specify init --here --ai claude
|
||||
```
|
||||
|
||||
The CLI will check if you have Claude Code or Gemini CLI installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command:
|
||||
The CLI will check if you have Claude Code, Gemini CLI, Qwen CLI or opencode installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command:
|
||||
|
||||
```bash
|
||||
specify init <project_name> --ai claude --ignore-agent-tools
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "specify-cli"
|
||||
version = "0.0.4"
|
||||
version = "0.0.6"
|
||||
description = "Setup tool for Specify spec-driven development projects"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
@@ -4,7 +4,7 @@ REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
FEATURE_DIR="$REPO_ROOT/specs/$CURRENT_BRANCH"
|
||||
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"; AGENTS_FILE="$REPO_ROOT/AGENTS.md"
|
||||
AGENT_TYPE="$1"
|
||||
[ -f "$NEW_PLAN" ] || { echo "ERROR: No plan.md found at $NEW_PLAN"; exit 1; }
|
||||
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_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
|
||||
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";
|
||||
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";
|
||||
@@ -51,7 +51,13 @@ case "$AGENT_TYPE" in
|
||||
claude) update_agent_file "$CLAUDE_FILE" "Claude Code" ;;
|
||||
gemini) update_agent_file "$GEMINI_FILE" "Gemini CLI" ;;
|
||||
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 ;;
|
||||
*) echo "ERROR: Unknown agent type '$AGENT_TYPE'"; exit 1 ;;
|
||||
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]"
|
||||
cursor) update_agent_file "$CURSOR_FILE" "Cursor IDE" ;;
|
||||
opencode) update_agent_file "$AGENTS_FILE" "opencode" ;;
|
||||
"") [ -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"; \
|
||||
[ -f "$AGENTS_FILE" ] && update_agent_file "$AGENTS_FILE" "opencode"; \
|
||||
if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ] && [ ! -f "$CURSOR_FILE" ] && [ ! -f "$AGENTS_FILE" ]; then update_agent_file "$CLAUDE_FILE" "Claude Code"; fi ;;
|
||||
*) echo "ERROR: Unknown agent type '$AGENT_TYPE' (expected claude|gemini|copilot|cursor|opencode)"; exit 1 ;;
|
||||
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|opencode]"
|
||||
|
||||
@@ -12,6 +12,8 @@ if (-not (Test-Path $newPlan)) { Write-Error "ERROR: No plan.md found at $newPla
|
||||
$claudeFile = Join-Path $repoRoot 'CLAUDE.md'
|
||||
$geminiFile = Join-Path $repoRoot 'GEMINI.md'
|
||||
$copilotFile = Join-Path $repoRoot '.github/copilot-instructions.md'
|
||||
$cursorFile = Join-Path $repoRoot '.cursor/rules/specify-rules.mdc'
|
||||
$agentsFile = Join-Path $repoRoot 'AGENTS.md'
|
||||
|
||||
Write-Output "=== Updating agent context files for feature $currentBranch ==="
|
||||
|
||||
@@ -30,7 +32,7 @@ $newProjectType = Get-PlanValue 'Project Type'
|
||||
|
||||
function Initialize-AgentFile($targetFile, $agentName) {
|
||||
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 }
|
||||
$content = Get-Content $template -Raw
|
||||
$content = $content.Replace('[PROJECT NAME]', (Split-Path $repoRoot -Leaf))
|
||||
@@ -55,7 +57,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 ($content -match '## Recent Changes\n([\s\S]*?)(\n\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
|
||||
$joined = ($changesBlock -join "`n")
|
||||
$content = [regex]::Replace($content, '## Recent Changes\n([\s\S]*?)(\n\n|$)', "## Recent Changes`n$joined`n`n")
|
||||
@@ -69,16 +71,24 @@ switch ($AgentType) {
|
||||
'claude' { Update-AgentFile $claudeFile 'Claude Code' }
|
||||
'gemini' { Update-AgentFile $geminiFile 'Gemini CLI' }
|
||||
'copilot' { Update-AgentFile $copilotFile 'GitHub Copilot' }
|
||||
'cursor' { Update-AgentFile $cursorFile 'Cursor IDE' }
|
||||
'opencode' { Update-AgentFile $agentsFile 'opencode' }
|
||||
'' {
|
||||
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'}
|
||||
@{file=$agentsFile; name='opencode'}
|
||||
)) {
|
||||
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) -and -not (Test-Path $agentsFile)) {
|
||||
Write-Output 'No agent context files found. Creating Claude Code context file by default.'
|
||||
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, opencode or leave empty for all."; exit 1 }
|
||||
}
|
||||
|
||||
Write-Output ''
|
||||
@@ -88,4 +98,4 @@ if ($newFramework) { Write-Output "- Added framework: $newFramework" }
|
||||
if ($newDb -and $newDb -ne 'N/A') { Write-Output "- Added database: $newDb" }
|
||||
|
||||
Write-Output ''
|
||||
Write-Output 'Usage: ./update-agent-context.ps1 [claude|gemini|copilot]'
|
||||
Write-Output 'Usage: ./update-agent-context.ps1 [claude|gemini|copilot|cursor|opencode]'
|
||||
|
||||
@@ -57,7 +57,9 @@ AI_CHOICES = {
|
||||
"copilot": "GitHub Copilot",
|
||||
"claude": "Claude Code",
|
||||
"gemini": "Gemini CLI",
|
||||
"cursor": "Cursor"
|
||||
"cursor": "Cursor",
|
||||
"qwen": "Qwen Code",
|
||||
"opencode": "opencode"
|
||||
}
|
||||
# Add script type choices
|
||||
SCRIPT_TYPE_CHOICES = {"sh": "POSIX Shell (bash/zsh)", "ps": "PowerShell"}
|
||||
@@ -722,7 +724,7 @@ def ensure_executable_scripts(project_path: Path, tracker: StepTracker | None =
|
||||
@app.command()
|
||||
def init(
|
||||
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here)"),
|
||||
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, or cursor"),
|
||||
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor, qwen or opencode"),
|
||||
script_type: str = typer.Option(None, "--script", help="Script type to use: sh or ps"),
|
||||
ignore_agent_tools: bool = typer.Option(False, "--ignore-agent-tools", help="Skip checks for AI agent tools like Claude Code"),
|
||||
no_git: bool = typer.Option(False, "--no-git", help="Skip git repository initialization"),
|
||||
@@ -735,7 +737,7 @@ def init(
|
||||
|
||||
This command will:
|
||||
1. Check that required tools are installed (git is optional)
|
||||
2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, or Cursor)
|
||||
2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, Cursor, Qwen Code or opencode)
|
||||
3. Download the appropriate template from GitHub
|
||||
4. Extract the template to a new project directory or current directory
|
||||
5. Initialize a fresh git repository (if not --no-git and no existing repo)
|
||||
@@ -747,6 +749,8 @@ def init(
|
||||
specify init my-project --ai gemini
|
||||
specify init my-project --ai copilot --no-git
|
||||
specify init my-project --ai cursor
|
||||
specify init my-project --ai qwen
|
||||
specify init my-project --ai opencode
|
||||
specify init --ignore-agent-tools my-project
|
||||
specify init --here --ai claude
|
||||
specify init --here
|
||||
@@ -794,10 +798,11 @@ def init(
|
||||
))
|
||||
|
||||
# Check git only if we might need it (not --no-git)
|
||||
git_available = True
|
||||
# Only set to True if the user wants it and the tool is available
|
||||
should_init_git = False
|
||||
if not no_git:
|
||||
git_available = check_tool("git", "https://git-scm.com/downloads")
|
||||
if not git_available:
|
||||
should_init_git = check_tool("git", "https://git-scm.com/downloads")
|
||||
if not should_init_git:
|
||||
console.print("[yellow]Git not found - will skip repository initialization[/yellow]")
|
||||
|
||||
# AI assistant selection
|
||||
@@ -825,6 +830,15 @@ def init(
|
||||
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")
|
||||
agent_tool_missing = True
|
||||
elif selected_ai == "qwen":
|
||||
if not check_tool("qwen", "Install from: https://github.com/QwenLM/qwen-code"):
|
||||
console.print("[red]Error:[/red] Qwen CLI is required for Qwen Code projects")
|
||||
agent_tool_missing = True
|
||||
elif selected_ai == "opencode":
|
||||
if not check_tool("opencode", "Install from: https://opencode.ai"):
|
||||
console.print("[red]Error:[/red] opencode CLI is required for opencode projects")
|
||||
agent_tool_missing = True
|
||||
# GitHub Copilot and Cursor checks are not needed as they're typically available in supported IDEs
|
||||
|
||||
if agent_tool_missing:
|
||||
console.print("\n[red]Required AI tool is missing![/red]")
|
||||
@@ -893,7 +907,7 @@ def init(
|
||||
tracker.start("git")
|
||||
if is_git_repo(project_path):
|
||||
tracker.complete("git", "existing repo detected")
|
||||
elif git_available:
|
||||
elif should_init_git:
|
||||
if init_git_repo(project_path, quiet=True):
|
||||
tracker.complete("git", "initialized")
|
||||
else:
|
||||
@@ -950,6 +964,17 @@ def init(
|
||||
steps_lines.append(" - See GEMINI.md for all available commands")
|
||||
elif selected_ai == "copilot":
|
||||
steps_lines.append(f"{step_num}. Open in Visual Studio Code and use [bold cyan]/specify[/], [bold cyan]/plan[/], [bold cyan]/tasks[/] commands with GitHub Copilot")
|
||||
elif selected_ai == "qwen":
|
||||
steps_lines.append(f"{step_num}. Use / commands with Qwen CLI")
|
||||
steps_lines.append(" - Run qwen /specify to create specifications")
|
||||
steps_lines.append(" - Run qwen /plan to create implementation plans")
|
||||
steps_lines.append(" - Run qwen /tasks to generate tasks")
|
||||
steps_lines.append(" - See QWEN.md for all available commands")
|
||||
elif selected_ai == "opencode":
|
||||
steps_lines.append(f"{step_num}. Use / commands with opencode")
|
||||
steps_lines.append(" - Use /specify to create specifications")
|
||||
steps_lines.append(" - Use /plan to create implementation plans")
|
||||
steps_lines.append(" - Use /tasks to generate tasks")
|
||||
|
||||
# Removed script variant step (scripts are transparent to users)
|
||||
step_num += 1
|
||||
@@ -975,18 +1000,22 @@ def check():
|
||||
tracker.add("git", "Git version control")
|
||||
tracker.add("claude", "Claude Code CLI")
|
||||
tracker.add("gemini", "Gemini CLI")
|
||||
tracker.add("qwen", "Qwen Code CLI")
|
||||
tracker.add("code", "VS Code (for GitHub Copilot)")
|
||||
tracker.add("cursor-agent", "Cursor IDE agent (optional)")
|
||||
tracker.add("opencode", "opencode")
|
||||
|
||||
# Check each tool
|
||||
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)
|
||||
gemini_ok = check_tool_for_tracker("gemini", "https://github.com/google-gemini/gemini-cli", tracker)
|
||||
qwen_ok = check_tool_for_tracker("qwen", "https://github.com/QwenLM/qwen-code", 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)
|
||||
opencode_ok = check_tool_for_tracker("opencode", "https://opencode.ai/", tracker)
|
||||
|
||||
# Render the final tree
|
||||
console.print(tracker.render())
|
||||
@@ -997,7 +1026,7 @@ def check():
|
||||
# Recommendations
|
||||
if not git_ok:
|
||||
console.print("[dim]Tip: Install git for repository management[/dim]")
|
||||
if not (claude_ok or gemini_ok):
|
||||
if not (claude_ok or gemini_ok or cursor_ok or qwen_ok or opencode_ok):
|
||||
console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ Given the implementation details provided as an argument, do this:
|
||||
4. Execute the implementation plan template:
|
||||
- Load `/templates/plan-template.md` (already copied to IMPL_PLAN path)
|
||||
- Set Input path to FEATURE_SPEC
|
||||
- Run the Execution Flow (main) function steps 1-10
|
||||
- Run the Execution Flow (main) function steps 1-9
|
||||
- The template is self-contained and executable
|
||||
- Follow error handling and gate checks as specified
|
||||
- Let the template guide artifact generation in $SPECS_DIR:
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
# Implementation Plan: [FEATURE]
|
||||
---
|
||||
description: "Implementation plan template for feature development"
|
||||
scripts:
|
||||
sh: scripts/bash/update-agent-context.sh __AGENT__
|
||||
ps: scripts/powershell/update-agent-context.ps1 -AgentType __AGENT__
|
||||
---
|
||||
|
||||
<!-- VARIANT:sh - Run `/scripts/bash/update-agent-context.sh __AGENT__` for your AI assistant -->
|
||||
<!-- VARIANT:ps - Run `/scripts/powershell/update-agent-context.ps1 -AgentType __AGENT__` for your AI assistant -->
|
||||
# Implementation Plan: [FEATURE]
|
||||
|
||||
**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link]
|
||||
**Input**: Feature specification from `/specs/[###-feature-name]/spec.md`
|
||||
@@ -13,18 +17,19 @@
|
||||
2. Fill Technical Context (scan for NEEDS CLARIFICATION)
|
||||
→ Detect Project Type from context (web=frontend+backend, mobile=app+api)
|
||||
→ Set Structure Decision based on project type
|
||||
3. Evaluate Constitution Check section below
|
||||
3. Fill the Constitution Check section based on the content of the constitution document.
|
||||
4. Evaluate Constitution Check section below
|
||||
→ If violations exist: Document in Complexity Tracking
|
||||
→ If no justification possible: ERROR "Simplify approach first"
|
||||
→ Update Progress Tracking: Initial Constitution Check
|
||||
4. Execute Phase 0 → research.md
|
||||
5. Execute Phase 0 → research.md
|
||||
→ If NEEDS CLARIFICATION remain: ERROR "Resolve unknowns"
|
||||
5. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or `GEMINI.md` for Gemini CLI).
|
||||
6. Re-evaluate Constitution Check section
|
||||
6. Execute Phase 1 → contracts, data-model.md, quickstart.md, agent-specific template file (e.g., `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, `GEMINI.md` for Gemini CLI, `QWEN.md` for Qwen Code or `AGENTS.md` for opencode).
|
||||
7. Re-evaluate Constitution Check section
|
||||
→ If new violations: Refactor design, return to Phase 1
|
||||
→ Update Progress Tracking: Post-Design Constitution Check
|
||||
7. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md)
|
||||
8. STOP - Ready for /tasks command
|
||||
8. Plan Phase 2 → Describe task generation approach (DO NOT create tasks.md)
|
||||
9. STOP - Ready for /tasks command
|
||||
```
|
||||
|
||||
**IMPORTANT**: The /plan command STOPS at step 7. Phases 2-4 are executed by other commands:
|
||||
@@ -48,35 +53,7 @@
|
||||
## Constitution Check
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
**Simplicity**:
|
||||
- Projects: [#] (max 3 - e.g., api, cli, tests)
|
||||
- Using framework directly? (no wrapper classes)
|
||||
- Single data model? (no DTOs unless serialization differs)
|
||||
- Avoiding patterns? (no Repository/UoW without proven need)
|
||||
|
||||
**Architecture**:
|
||||
- EVERY feature as library? (no direct app code)
|
||||
- Libraries listed: [name + purpose for each]
|
||||
- CLI per library: [commands with --help/--version/--format]
|
||||
- Library docs: llms.txt format planned?
|
||||
|
||||
**Testing (NON-NEGOTIABLE)**:
|
||||
- RED-GREEN-Refactor cycle enforced? (test MUST fail first)
|
||||
- Git commits show tests before implementation?
|
||||
- Order: Contract→Integration→E2E→Unit strictly followed?
|
||||
- Real dependencies used? (actual DBs, not mocks)
|
||||
- Integration tests for: new libraries, contract changes, shared schemas?
|
||||
- FORBIDDEN: Implementation before test, skipping RED phase
|
||||
|
||||
**Observability**:
|
||||
- Structured logging included?
|
||||
- Frontend logs → backend? (unified stream)
|
||||
- Error context sufficient?
|
||||
|
||||
**Versioning**:
|
||||
- Version number assigned? (MAJOR.MINOR.BUILD)
|
||||
- BUILD increments on every change?
|
||||
- Breaking changes handled? (parallel tests, migration plan)
|
||||
[Gates determined based on constitution file]
|
||||
|
||||
## Project Structure
|
||||
|
||||
@@ -174,7 +151,7 @@ ios/ or android/
|
||||
- Quickstart test = story validation steps
|
||||
|
||||
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
|
||||
- Preserve manual additions between markers
|
||||
- Update recent changes (keep last 3)
|
||||
@@ -187,7 +164,7 @@ ios/ or android/
|
||||
*This section describes what the /tasks command will do - DO NOT execute during /plan*
|
||||
|
||||
**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)
|
||||
- Each contract → contract test task [P]
|
||||
- Each entity → model creation task [P]
|
||||
|
||||
Reference in New Issue
Block a user