Update with Windsurf support
This commit is contained in:
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -81,7 +81,7 @@ jobs:
|
|||||||
cat > release_notes.md << EOF
|
cat > release_notes.md << EOF
|
||||||
Template release ${{ steps.get_tag.outputs.new_version }}
|
Template release ${{ steps.get_tag.outputs.new_version }}
|
||||||
|
|
||||||
Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, Cursor, Qwen, and opencode.
|
Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, Cursor, Qwen, opencode, and Windsurf.
|
||||||
|
|
||||||
Now includes per-script variants for POSIX shell (sh) and PowerShell (ps).
|
Now includes per-script variants for POSIX shell (sh) and PowerShell (ps).
|
||||||
|
|
||||||
@@ -98,6 +98,8 @@ jobs:
|
|||||||
- spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
- spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||||
- spec-kit-template-qwen-sh-${{ steps.get_tag.outputs.new_version }}.zip
|
- spec-kit-template-qwen-sh-${{ steps.get_tag.outputs.new_version }}.zip
|
||||||
- spec-kit-template-qwen-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
- spec-kit-template-qwen-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||||
|
- spec-kit-template-windsurf-sh-${{ steps.get_tag.outputs.new_version }}.zip
|
||||||
|
- spec-kit-template-windsurf-ps-${{ steps.get_tag.outputs.new_version }}.zip
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
echo "Generated release notes:"
|
echo "Generated release notes:"
|
||||||
@@ -122,6 +124,8 @@ jobs:
|
|||||||
spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
spec-kit-template-opencode-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||||
spec-kit-template-qwen-sh-${{ steps.get_tag.outputs.new_version }}.zip \
|
spec-kit-template-qwen-sh-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||||
spec-kit-template-qwen-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
spec-kit-template-qwen-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||||
|
spec-kit-template-windsurf-sh-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||||
|
spec-kit-template-windsurf-ps-${{ steps.get_tag.outputs.new_version }}.zip \
|
||||||
--title "Spec Kit Templates - $VERSION_NO_V" \
|
--title "Spec Kit Templates - $VERSION_NO_V" \
|
||||||
--notes-file release_notes.md
|
--notes-file release_notes.md
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -154,13 +154,16 @@ build_variant() {
|
|||||||
opencode)
|
opencode)
|
||||||
mkdir -p "$base_dir/.opencode/command"
|
mkdir -p "$base_dir/.opencode/command"
|
||||||
generate_commands opencode md "\$ARGUMENTS" "$base_dir/.opencode/command" "$script" ;;
|
generate_commands opencode md "\$ARGUMENTS" "$base_dir/.opencode/command" "$script" ;;
|
||||||
|
windsurf)
|
||||||
|
mkdir -p "$base_dir/.windsurf/workflows"
|
||||||
|
generate_commands windsurf md "\$ARGUMENTS" "$base_dir/.windsurf/workflows" "$script" ;;
|
||||||
esac
|
esac
|
||||||
( cd "$base_dir" && zip -r "../spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" . )
|
( cd "$base_dir" && zip -r "../spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" . )
|
||||||
echo "Created spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
|
echo "Created spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Determine agent list
|
# Determine agent list
|
||||||
ALL_AGENTS=(claude gemini copilot cursor qwen opencode)
|
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf)
|
||||||
ALL_SCRIPTS=(sh ps)
|
ALL_SCRIPTS=(sh ps)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
230
AGENTS.md
Normal file
230
AGENTS.md
Normal file
@@ -0,0 +1,230 @@
|
|||||||
|
# AGENTS.md
|
||||||
|
|
||||||
|
## About Spec Kit and Specify
|
||||||
|
|
||||||
|
**GitHub Spec Kit** is a comprehensive toolkit for implementing Spec-Driven Development (SDD) - a methodology that emphasizes creating clear specifications before implementation. The toolkit includes templates, scripts, and workflows that guide development teams through a structured approach to building software.
|
||||||
|
|
||||||
|
**Specify CLI** is the command-line interface that bootstraps projects with the Spec Kit framework. It sets up the necessary directory structures, templates, and AI agent integrations to support the Spec-Driven Development workflow.
|
||||||
|
|
||||||
|
The toolkit supports multiple AI coding assistants, allowing teams to use their preferred tools while maintaining consistent project structure and development practices.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adding New Agent Support
|
||||||
|
|
||||||
|
This section explains how to add support for new AI agents/assistants to the Specify CLI. Use this guide as a reference when integrating new AI tools into the Spec-Driven Development workflow.
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
Specify supports multiple AI agents by generating agent-specific command files and directory structures when initializing projects. Each agent has its own conventions for:
|
||||||
|
|
||||||
|
- **Command file formats** (Markdown, TOML, etc.)
|
||||||
|
- **Directory structures** (`.claude/commands/`, `.windsurf/workflows/`, etc.)
|
||||||
|
- **Command invocation patterns** (slash commands, CLI tools, etc.)
|
||||||
|
- **Argument passing conventions** (`$ARGUMENTS`, `{{args}}`, etc.)
|
||||||
|
|
||||||
|
### Current Supported Agents
|
||||||
|
|
||||||
|
| Agent | Directory | Format | CLI Tool | Description |
|
||||||
|
|-------|-----------|---------|----------|-------------|
|
||||||
|
| **Claude Code** | `.claude/commands/` | Markdown | `claude` | Anthropic's Claude Code CLI |
|
||||||
|
| **Gemini CLI** | `.gemini/commands/` | TOML | `gemini` | Google's Gemini CLI |
|
||||||
|
| **GitHub Copilot** | `.github/prompts/` | Markdown | N/A (IDE-based) | GitHub Copilot in VS Code |
|
||||||
|
| **Cursor** | `.cursor/commands/` | Markdown | `cursor-agent` | Cursor CLI |
|
||||||
|
| **Qwen Code** | `.qwen/commands/` | TOML | `qwen` | Alibaba's Qwen Code CLI |
|
||||||
|
| **opencode** | `.opencode/command/` | Markdown | `opencode` | opencode CLI |
|
||||||
|
| **Windsurf** | `.windsurf/workflows/` | Markdown | N/A (IDE-based) | Windsurf IDE workflows |
|
||||||
|
|
||||||
|
### Step-by-Step Integration Guide
|
||||||
|
|
||||||
|
Follow these steps to add a new agent (using Windsurf as an example):
|
||||||
|
|
||||||
|
#### 1. Update AI_CHOICES Constant
|
||||||
|
|
||||||
|
Add the new agent to the `AI_CHOICES` dictionary in `src/specify_cli/__init__.py`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
AI_CHOICES = {
|
||||||
|
"copilot": "GitHub Copilot",
|
||||||
|
"claude": "Claude Code",
|
||||||
|
"gemini": "Gemini CLI",
|
||||||
|
"cursor": "Cursor",
|
||||||
|
"qwen": "Qwen Code",
|
||||||
|
"opencode": "opencode",
|
||||||
|
"windsurf": "Windsurf" # Add new agent here
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Update CLI Help Text
|
||||||
|
|
||||||
|
Update all help text and examples to include the new agent:
|
||||||
|
|
||||||
|
- Command option help: `--ai` parameter description
|
||||||
|
- Function docstrings and examples
|
||||||
|
- Error messages with agent lists
|
||||||
|
|
||||||
|
#### 3. Update Release Package Script
|
||||||
|
|
||||||
|
Modify `.github/workflows/scripts/create-release-packages.sh`:
|
||||||
|
|
||||||
|
##### Add to ALL_AGENTS array:
|
||||||
|
```bash
|
||||||
|
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf)
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Add case statement for directory structure:
|
||||||
|
```bash
|
||||||
|
case $agent in
|
||||||
|
# ... existing cases ...
|
||||||
|
windsurf)
|
||||||
|
mkdir -p "$base_dir/.windsurf/workflows"
|
||||||
|
generate_commands windsurf md "\$ARGUMENTS" "$base_dir/.windsurf/workflows" "$script" ;;
|
||||||
|
esac
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Update Agent Context Scripts
|
||||||
|
|
||||||
|
##### Bash script (`scripts/bash/update-agent-context.sh`):
|
||||||
|
|
||||||
|
Add file variable:
|
||||||
|
```bash
|
||||||
|
WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
|
||||||
|
```
|
||||||
|
|
||||||
|
Add to case statement:
|
||||||
|
```bash
|
||||||
|
case "$AGENT_TYPE" in
|
||||||
|
# ... existing cases ...
|
||||||
|
windsurf) update_agent_file "$WINDSURF_FILE" "Windsurf" ;;
|
||||||
|
"")
|
||||||
|
# ... existing checks ...
|
||||||
|
[ -f "$WINDSURF_FILE" ] && update_agent_file "$WINDSURF_FILE" "Windsurf";
|
||||||
|
# Update default creation condition
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
```
|
||||||
|
|
||||||
|
##### PowerShell script (`scripts/powershell/update-agent-context.ps1`):
|
||||||
|
|
||||||
|
Add file variable:
|
||||||
|
```powershell
|
||||||
|
$windsurfFile = Join-Path $repoRoot '.windsurf/rules/specify-rules.md'
|
||||||
|
```
|
||||||
|
|
||||||
|
Add to switch statement:
|
||||||
|
```powershell
|
||||||
|
switch ($AgentType) {
|
||||||
|
# ... existing cases ...
|
||||||
|
'windsurf' { Update-AgentFile $windsurfFile 'Windsurf' }
|
||||||
|
'' {
|
||||||
|
foreach ($pair in @(
|
||||||
|
# ... existing pairs ...
|
||||||
|
@{file=$windsurfFile; name='Windsurf'}
|
||||||
|
)) {
|
||||||
|
if (Test-Path $pair.file) { Update-AgentFile $pair.file $pair.name }
|
||||||
|
}
|
||||||
|
# Update default creation condition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Update CLI Tool Checks (Optional)
|
||||||
|
|
||||||
|
For agents that require CLI tools, add checks in the `check()` command and agent validation:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# In check() command
|
||||||
|
tracker.add("windsurf", "Windsurf IDE (optional)")
|
||||||
|
windsurf_ok = check_tool_for_tracker("windsurf", "https://windsurf.com/", tracker)
|
||||||
|
|
||||||
|
# In init validation (only if CLI tool required)
|
||||||
|
elif selected_ai == "windsurf":
|
||||||
|
if not check_tool("windsurf", "Install from: https://windsurf.com/"):
|
||||||
|
console.print("[red]Error:[/red] Windsurf CLI is required for Windsurf projects")
|
||||||
|
agent_tool_missing = True
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Skip CLI checks for IDE-based agents (Copilot, Windsurf).
|
||||||
|
|
||||||
|
## Agent Categories
|
||||||
|
|
||||||
|
### CLI-Based Agents
|
||||||
|
Require a command-line tool to be installed:
|
||||||
|
- **Claude Code**: `claude` CLI
|
||||||
|
- **Gemini CLI**: `gemini` CLI
|
||||||
|
- **Cursor**: `cursor-agent` CLI
|
||||||
|
- **Qwen Code**: `qwen` CLI
|
||||||
|
- **opencode**: `opencode` CLI
|
||||||
|
|
||||||
|
### IDE-Based Agents
|
||||||
|
Work within integrated development environments:
|
||||||
|
- **GitHub Copilot**: Built into VS Code/compatible editors
|
||||||
|
- **Windsurf**: Built into Windsurf IDE
|
||||||
|
|
||||||
|
## Command File Formats
|
||||||
|
|
||||||
|
### Markdown Format
|
||||||
|
Used by: Claude, Cursor, opencode, Windsurf
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
description: "Command description"
|
||||||
|
---
|
||||||
|
|
||||||
|
Command content with {SCRIPT} and $ARGUMENTS placeholders.
|
||||||
|
```
|
||||||
|
|
||||||
|
### TOML Format
|
||||||
|
Used by: Gemini, Qwen
|
||||||
|
|
||||||
|
```toml
|
||||||
|
description = "Command description"
|
||||||
|
|
||||||
|
prompt = """
|
||||||
|
Command content with {SCRIPT} and {{args}} placeholders.
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
## Directory Conventions
|
||||||
|
|
||||||
|
- **CLI agents**: Usually `.<agent-name>/commands/`
|
||||||
|
- **IDE agents**: Follow IDE-specific patterns:
|
||||||
|
- Copilot: `.github/prompts/`
|
||||||
|
- Cursor: `.cursor/commands/`
|
||||||
|
- Windsurf: `.windsurf/workflows/`
|
||||||
|
|
||||||
|
## Argument Patterns
|
||||||
|
|
||||||
|
Different agents use different argument placeholders:
|
||||||
|
- **Markdown/prompt-based**: `$ARGUMENTS`
|
||||||
|
- **TOML-based**: `{{args}}`
|
||||||
|
- **Script placeholders**: `{SCRIPT}` (replaced with actual script path)
|
||||||
|
- **Agent placeholders**: `__AGENT__` (replaced with agent name)
|
||||||
|
|
||||||
|
## Testing New Agent Integration
|
||||||
|
|
||||||
|
1. **Build test**: Run package creation script locally
|
||||||
|
2. **CLI test**: Test `specify init --ai <agent>` command
|
||||||
|
3. **File generation**: Verify correct directory structure and files
|
||||||
|
4. **Command validation**: Ensure generated commands work with the agent
|
||||||
|
5. **Context update**: Test agent context update scripts
|
||||||
|
|
||||||
|
## Common Pitfalls
|
||||||
|
|
||||||
|
1. **Forgetting update scripts**: Both bash and PowerShell scripts must be updated
|
||||||
|
2. **Missing CLI checks**: Only add for agents that actually have CLI tools
|
||||||
|
3. **Wrong argument format**: Use correct placeholder format for each agent type
|
||||||
|
4. **Directory naming**: Follow agent-specific conventions exactly
|
||||||
|
5. **Help text inconsistency**: Update all user-facing text consistently
|
||||||
|
|
||||||
|
## Future Considerations
|
||||||
|
|
||||||
|
When adding new agents:
|
||||||
|
- Consider the agent's native command/workflow patterns
|
||||||
|
- Ensure compatibility with the Spec-Driven Development process
|
||||||
|
- Document any special requirements or limitations
|
||||||
|
- Update this guide with lessons learned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This documentation should be updated whenever new agents are added to maintain accuracy and completeness.*
|
||||||
@@ -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"; CURSOR_FILE="$REPO_ROOT/.cursor/rules/specify-rules.mdc"; QWEN_FILE="$REPO_ROOT/QWEN.md"; AGENTS_FILE="$REPO_ROOT/AGENTS.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"; QWEN_FILE="$REPO_ROOT/QWEN.md"; AGENTS_FILE="$REPO_ROOT/AGENTS.md"; WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
|
||||||
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 ==="
|
||||||
@@ -54,13 +54,15 @@ case "$AGENT_TYPE" in
|
|||||||
cursor) update_agent_file "$CURSOR_FILE" "Cursor IDE" ;;
|
cursor) update_agent_file "$CURSOR_FILE" "Cursor IDE" ;;
|
||||||
qwen) update_agent_file "$QWEN_FILE" "Qwen Code" ;;
|
qwen) update_agent_file "$QWEN_FILE" "Qwen Code" ;;
|
||||||
opencode) update_agent_file "$AGENTS_FILE" "opencode" ;;
|
opencode) update_agent_file "$AGENTS_FILE" "opencode" ;;
|
||||||
|
windsurf) update_agent_file "$WINDSURF_FILE" "Windsurf" ;;
|
||||||
"") [ -f "$CLAUDE_FILE" ] && update_agent_file "$CLAUDE_FILE" "Claude Code"; \
|
"") [ -f "$CLAUDE_FILE" ] && update_agent_file "$CLAUDE_FILE" "Claude Code"; \
|
||||||
[ -f "$GEMINI_FILE" ] && update_agent_file "$GEMINI_FILE" "Gemini CLI"; \
|
[ -f "$GEMINI_FILE" ] && update_agent_file "$GEMINI_FILE" "Gemini CLI"; \
|
||||||
[ -f "$COPILOT_FILE" ] && update_agent_file "$COPILOT_FILE" "GitHub Copilot"; \
|
[ -f "$COPILOT_FILE" ] && update_agent_file "$COPILOT_FILE" "GitHub Copilot"; \
|
||||||
[ -f "$CURSOR_FILE" ] && update_agent_file "$CURSOR_FILE" "Cursor IDE"; \
|
[ -f "$CURSOR_FILE" ] && update_agent_file "$CURSOR_FILE" "Cursor IDE"; \
|
||||||
[ -f "$QWEN_FILE" ] && update_agent_file "$QWEN_FILE" "Qwen Code"; \
|
[ -f "$QWEN_FILE" ] && update_agent_file "$QWEN_FILE" "Qwen Code"; \
|
||||||
[ -f "$AGENTS_FILE" ] && update_agent_file "$AGENTS_FILE" "opencode"; \
|
[ -f "$AGENTS_FILE" ] && update_agent_file "$AGENTS_FILE" "opencode"; \
|
||||||
if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ] && [ ! -f "$CURSOR_FILE" ] && [ ! -f "$QWEN_FILE" ] && [ ! -f "$AGENTS_FILE" ]; then update_agent_file "$CLAUDE_FILE" "Claude Code"; fi ;;
|
[ -f "$WINDSURF_FILE" ] && update_agent_file "$WINDSURF_FILE" "Windsurf"; \
|
||||||
*) echo "ERROR: Unknown agent type '$AGENT_TYPE' (expected claude|gemini|copilot|cursor|qwen|opencode)"; exit 1 ;;
|
if [ ! -f "$CLAUDE_FILE" ] && [ ! -f "$GEMINI_FILE" ] && [ ! -f "$COPILOT_FILE" ] && [ ! -f "$CURSOR_FILE" ] && [ ! -f "$QWEN_FILE" ] && [ ! -f "$AGENTS_FILE" ] && [ ! -f "$WINDSURF_FILE" ]; then update_agent_file "$CLAUDE_FILE" "Claude Code"; fi ;;
|
||||||
|
*) echo "ERROR: Unknown agent type '$AGENT_TYPE' (expected claude|gemini|copilot|cursor|qwen|opencode|windsurf)"; 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|cursor|qwen|opencode]"
|
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|qwen|opencode|windsurf]"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ $copilotFile = Join-Path $repoRoot '.github/copilot-instructions.md'
|
|||||||
$cursorFile = Join-Path $repoRoot '.cursor/rules/specify-rules.mdc'
|
$cursorFile = Join-Path $repoRoot '.cursor/rules/specify-rules.mdc'
|
||||||
$qwenFile = Join-Path $repoRoot 'QWEN.md'
|
$qwenFile = Join-Path $repoRoot 'QWEN.md'
|
||||||
$agentsFile = Join-Path $repoRoot 'AGENTS.md'
|
$agentsFile = Join-Path $repoRoot 'AGENTS.md'
|
||||||
|
$windsurfFile = Join-Path $repoRoot '.windsurf/rules/specify-rules.md'
|
||||||
|
|
||||||
Write-Output "=== Updating agent context files for feature $currentBranch ==="
|
Write-Output "=== Updating agent context files for feature $currentBranch ==="
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ switch ($AgentType) {
|
|||||||
'cursor' { Update-AgentFile $cursorFile 'Cursor IDE' }
|
'cursor' { Update-AgentFile $cursorFile 'Cursor IDE' }
|
||||||
'qwen' { Update-AgentFile $qwenFile 'Qwen Code' }
|
'qwen' { Update-AgentFile $qwenFile 'Qwen Code' }
|
||||||
'opencode' { Update-AgentFile $agentsFile 'opencode' }
|
'opencode' { Update-AgentFile $agentsFile 'opencode' }
|
||||||
|
'windsurf' { Update-AgentFile $windsurfFile 'Windsurf' }
|
||||||
'' {
|
'' {
|
||||||
foreach ($pair in @(
|
foreach ($pair in @(
|
||||||
@{file=$claudeFile; name='Claude Code'},
|
@{file=$claudeFile; name='Claude Code'},
|
||||||
@@ -82,16 +84,17 @@ switch ($AgentType) {
|
|||||||
@{file=$copilotFile; name='GitHub Copilot'},
|
@{file=$copilotFile; name='GitHub Copilot'},
|
||||||
@{file=$cursorFile; name='Cursor IDE'},
|
@{file=$cursorFile; name='Cursor IDE'},
|
||||||
@{file=$qwenFile; name='Qwen Code'},
|
@{file=$qwenFile; name='Qwen Code'},
|
||||||
@{file=$agentsFile; name='opencode'}
|
@{file=$agentsFile; name='opencode'},
|
||||||
|
@{file=$windsurfFile; name='Windsurf'}
|
||||||
)) {
|
)) {
|
||||||
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) -and -not (Test-Path $cursorFile) -and -not (Test-Path $qwenFile) -and -not (Test-Path $agentsFile)) {
|
if (-not (Test-Path $claudeFile) -and -not (Test-Path $geminiFile) -and -not (Test-Path $copilotFile) -and -not (Test-Path $cursorFile) -and -not (Test-Path $qwenFile) -and -not (Test-Path $agentsFile) -and -not (Test-Path $windsurfFile)) {
|
||||||
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, cursor, qwen, opencode or leave empty for all."; exit 1 }
|
Default { Write-Error "ERROR: Unknown agent type '$AgentType'. Use: claude, gemini, copilot, cursor, qwen, opencode, windsurf or leave empty for all."; exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Output ''
|
Write-Output ''
|
||||||
@@ -101,4 +104,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|cursor|qwen|opencode]'
|
Write-Output 'Usage: ./update-agent-context.ps1 [claude|gemini|copilot|cursor|qwen|opencode|windsurf]'
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ AI_CHOICES = {
|
|||||||
"gemini": "Gemini CLI",
|
"gemini": "Gemini CLI",
|
||||||
"cursor": "Cursor",
|
"cursor": "Cursor",
|
||||||
"qwen": "Qwen Code",
|
"qwen": "Qwen Code",
|
||||||
"opencode": "opencode"
|
"opencode": "opencode",
|
||||||
|
"windsurf": "Windsurf"
|
||||||
}
|
}
|
||||||
# Add script type choices
|
# Add script type choices
|
||||||
SCRIPT_TYPE_CHOICES = {"sh": "POSIX Shell (bash/zsh)", "ps": "PowerShell"}
|
SCRIPT_TYPE_CHOICES = {"sh": "POSIX Shell (bash/zsh)", "ps": "PowerShell"}
|
||||||
@@ -750,7 +751,7 @@ def ensure_executable_scripts(project_path: Path, tracker: StepTracker | None =
|
|||||||
@app.command()
|
@app.command()
|
||||||
def init(
|
def init(
|
||||||
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here)"),
|
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, cursor, qwen or opencode"),
|
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor, qwen, opencode or windsurf"),
|
||||||
script_type: str = typer.Option(None, "--script", help="Script type to use: sh or ps"),
|
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"),
|
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"),
|
no_git: bool = typer.Option(False, "--no-git", help="Skip git repository initialization"),
|
||||||
@@ -764,7 +765,7 @@ def init(
|
|||||||
|
|
||||||
This command will:
|
This command will:
|
||||||
1. Check that required tools are installed (git is optional)
|
1. Check that required tools are installed (git is optional)
|
||||||
2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, Cursor, Qwen Code or opencode)
|
2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, Cursor, Qwen Code, opencode or Windsurf)
|
||||||
3. Download the appropriate template from GitHub
|
3. Download the appropriate template from GitHub
|
||||||
4. Extract the template to a new project directory or current directory
|
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)
|
5. Initialize a fresh git repository (if not --no-git and no existing repo)
|
||||||
@@ -777,7 +778,7 @@ def init(
|
|||||||
specify init my-project --ai copilot --no-git
|
specify init my-project --ai copilot --no-git
|
||||||
specify init my-project --ai cursor
|
specify init my-project --ai cursor
|
||||||
specify init my-project --ai qwen
|
specify init my-project --ai qwen
|
||||||
specify init my-project --ai opencode
|
specify init my-project --ai windsurf
|
||||||
specify init --ignore-agent-tools my-project
|
specify init --ignore-agent-tools my-project
|
||||||
specify init --here --ai claude
|
specify init --here --ai claude
|
||||||
specify init --here
|
specify init --here
|
||||||
@@ -1002,6 +1003,7 @@ def check():
|
|||||||
tracker.add("qwen", "Qwen Code CLI")
|
tracker.add("qwen", "Qwen Code CLI")
|
||||||
tracker.add("code", "VS Code (for GitHub Copilot)")
|
tracker.add("code", "VS Code (for GitHub Copilot)")
|
||||||
tracker.add("cursor-agent", "Cursor IDE agent (optional)")
|
tracker.add("cursor-agent", "Cursor IDE agent (optional)")
|
||||||
|
tracker.add("windsurf", "Windsurf IDE (optional)")
|
||||||
tracker.add("opencode", "opencode")
|
tracker.add("opencode", "opencode")
|
||||||
|
|
||||||
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)
|
||||||
@@ -1012,6 +1014,7 @@ def check():
|
|||||||
if not code_ok:
|
if not code_ok:
|
||||||
code_ok = check_tool_for_tracker("code-insiders", "https://code.visualstudio.com/insiders/", tracker)
|
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)
|
cursor_ok = check_tool_for_tracker("cursor-agent", "https://cursor.sh/", tracker)
|
||||||
|
windsurf_ok = check_tool_for_tracker("windsurf", "https://windsurf.com/", tracker)
|
||||||
opencode_ok = check_tool_for_tracker("opencode", "https://opencode.ai/", tracker)
|
opencode_ok = check_tool_for_tracker("opencode", "https://opencode.ai/", tracker)
|
||||||
|
|
||||||
console.print(tracker.render())
|
console.print(tracker.render())
|
||||||
@@ -1020,7 +1023,7 @@ def check():
|
|||||||
|
|
||||||
if not git_ok:
|
if not git_ok:
|
||||||
console.print("[dim]Tip: Install git for repository management[/dim]")
|
console.print("[dim]Tip: Install git for repository management[/dim]")
|
||||||
if not (claude_ok or gemini_ok or cursor_ok or qwen_ok or opencode_ok):
|
if not (claude_ok or gemini_ok or cursor_ok or qwen_ok or windsurf_ok or opencode_ok):
|
||||||
console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")
|
console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user