Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions .github/workflows/scripts/create-github-release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,7 @@ gh release create "$VERSION" \
.genreleases/spec-kit-template-codebuddy-ps-"$VERSION".zip \
.genreleases/spec-kit-template-q-sh-"$VERSION".zip \
.genreleases/spec-kit-template-q-ps-"$VERSION".zip \
.genreleases/spec-kit-template-trae-sh-"$VERSION".zip \
.genreleases/spec-kit-template-trae-ps-"$VERSION".zip \
--title "Spec Kit Templates - $VERSION_NO_V" \
--notes-file release_notes.md
5 changes: 4 additions & 1 deletion .github/workflows/scripts/create-release-packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,16 @@ build_variant() {
q)
mkdir -p "$base_dir/.amazonq/prompts"
generate_commands q md "\$ARGUMENTS" "$base_dir/.amazonq/prompts" "$script" ;;
trae)
mkdir -p "$base_dir/.trae/workflows"
generate_commands trae md "\$ARGUMENTS" "$base_dir/.trae/workflows" "$script" ;;
esac
( cd "$base_dir" && zip -r "../spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" . )
echo "Created $GENRELEASES_DIR/spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
}

# Determine agent list
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo codebuddy q)
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo codebuddy q trae)
ALL_SCRIPTS=(sh ps)

norm_list() {
Expand Down
36 changes: 34 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Specify supports multiple AI agents by generating agent-specific command files a
| **Roo Code** | `.roo/rules/` | Markdown | N/A (IDE-based) | Roo Code IDE |
| **CodeBuddy** | `.codebuddy/commands/` | Markdown | `codebuddy` | CodeBuddy |
| **Amazon Q Developer CLI** | `.amazonq/prompts/` | Markdown | `q` | Amazon Q Developer CLI |
| **Trae AI** | `.trae/workflows/` | Markdown | `trae` | Trae AI IDE-based Agent |

### Step-by-Step Integration Guide

Expand All @@ -56,6 +57,16 @@ Follow these steps to add a new agent (using a hypothetical new agent as an exam
Add the new agent to the `AGENT_CONFIG` dictionary in `src/specify_cli/__init__.py`. This is the **single source of truth** for all agent metadata:

```python
AI_CHOICES = {
"copilot": "GitHub Copilot",
"claude": "Claude Code",
"gemini": "Gemini CLI",
"cursor": "Cursor",
"qwen": "Qwen Code",
"opencode": "opencode",
"windsurf": "Windsurf",
"q": "Amazon Q Developer CLI",
"trae": "Trae AI" # Add new agent here
AGENT_CONFIG = {
# ... existing agents ...
"new-agent-cli": { # Use the ACTUAL CLI tool name (what users type in terminal)
Expand All @@ -71,6 +82,22 @@ AGENT_CONFIG = {
- ✅ Use `"cursor-agent"` because the CLI tool is literally called `cursor-agent`
- ❌ Don't use `"cursor"` as a shortcut if the tool is `cursor-agent`

```python
agent_folder_map = {
"claude": ".claude/",
"gemini": ".gemini/",
"cursor": ".cursor/",
"qwen": ".qwen/",
"opencode": ".opencode/",
"codex": ".codex/",
"windsurf": ".windsurf/",
"kilocode": ".kilocode/",
"auggie": ".auggie/",
"copilot": ".github/",
"q": ".amazonq/",
"trae": ".trae/" # Add new agent folder here
}
```
This eliminates the need for special-case mappings throughout the codebase.

**Field Explanations**:
Expand Down Expand Up @@ -104,7 +131,7 @@ Modify `.github/workflows/scripts/create-release-packages.sh`:

##### Add to ALL_AGENTS array:
```bash
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf q)
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf q trae)
```

##### Add case statement for directory structure:
Expand All @@ -113,7 +140,10 @@ case $agent in
# ... existing cases ...
windsurf)
mkdir -p "$base_dir/.windsurf/workflows"
generate_commands windsurf md "\$ARGUMENTS" "$base_dir/.windsurf/workflows" "$script" ;;
generate_commands windsurf md "$ARGUMENTS" "$base_dir/.windsurf/workflows" "$script" ;;
trae)
mkdir -p "$base_dir/.trae/workflows"
generate_commands trae md "$ARGUMENTS" "$base_dir/.trae/workflows" "$script" ;;
esac
```

Expand All @@ -126,6 +156,8 @@ gh release create "$VERSION" \
# ... existing packages ...
.genreleases/spec-kit-template-windsurf-sh-"$VERSION".zip \
.genreleases/spec-kit-template-windsurf-ps-"$VERSION".zip \
.genreleases/spec-kit-template-trae-sh-"$VERSION".zip \
.genreleases/spec-kit-template-trae-ps-"$VERSION".zip \
# Add new agent packages here
```

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.c
| [Roo Code](https://roocode.com/) | ✅ | |
| [Codex CLI](https://github.com/openai/codex) | ✅ | |
| [Amazon Q Developer CLI](https://aws.amazon.com/developer/learning/q-developer-cli/) | ⚠️ | Amazon Q Developer CLI [does not support](https://github.com/aws/amazon-q-developer-cli/issues/3064) custom arguments for slash commands. |
| [Trae AI](https://trae.ai/) | ✅ | |

## 🔧 Specify CLI Reference

Expand All @@ -157,14 +158,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`, `windsurf`, `qwen`, `opencode`, `codex`) |
| `check` | Check for installed tools (`git`, `claude`, `gemini`, `code`/`code-insiders`, `cursor-agent`, `windsurf`, `qwen`, `opencode`, `codex`, `trae`) |

### `specify init` Arguments & Options

| Argument/Option | Type | Description |
|------------------------|----------|------------------------------------------------------------------------------|
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`, or use `.` for current directory) |
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, or `q` |
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `trae`,`codebuddy`, or `q` |
| `--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 |
Expand Down
3 changes: 2 additions & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Prerequisites

- **Linux/macOS** (or Windows; PowerShell scripts now supported without WSL)
- AI coding agent: [Claude Code](https://www.anthropic.com/claude-code), [GitHub Copilot](https://code.visualstudio.com/), or [Gemini CLI](https://github.com/google-gemini/gemini-cli)
- 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 [Trae AI](https://trae.ai/)
- [uv](https://docs.astral.sh/uv/) for package management
- [Python 3.11+](https://www.python.org/downloads/)
- [Git](https://git-scm.com/downloads)
Expand Down Expand Up @@ -34,6 +34,7 @@ You can proactively specify your AI agent during initialization:
uvx --from git+https://github.com/github/spec-kit.git specify init <project_name> --ai claude
uvx --from git+https://github.com/github/spec-kit.git specify init <project_name> --ai gemini
uvx --from git+https://github.com/github/spec-kit.git specify init <project_name> --ai copilot
uvx --from git+https://github.com/github/spec-kit.git specify init <project_name> --ai trae
```

### Specify Script Type (Shell vs PowerShell)
Expand Down
14 changes: 12 additions & 2 deletions scripts/bash/update-agent-context.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
CODEBUDDY_FILE="$REPO_ROOT/.codebuddy/rules/specify-rules.md"
Q_FILE="$REPO_ROOT/AGENTS.md"
TRAE_FILE="$REPO_ROOT/.trae/rules/specify-rules.md"

# Template file
TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
Expand Down Expand Up @@ -582,15 +583,19 @@ update_specific_agent() {
roo)
update_agent_file "$ROO_FILE" "Roo Code"
;;
q)
codebuddy)
update_agent_file "$CODEBUDDY_FILE" "CodeBuddy"
;;
q)
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
;;
trae)
update_agent_file "$TRAE_FILE" "Trae AI"
;;
*)
log_error "Unknown agent type '$agent_type'"
log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q"
log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q|trae"
exit 1
;;
esac
Expand Down Expand Up @@ -660,6 +665,11 @@ update_all_existing_agents() {
found_agent=true
fi

if [[ -f "$TRAE_FILE" ]]; then
update_agent_file "$TRAE_FILE" "Trae AI"
found_agent=true
fi

# If no agent files exist, create a default Claude file
if [[ "$found_agent" == false ]]; then
log_info "No existing agent files found, creating default Claude file..."
Expand All @@ -684,7 +694,7 @@ print_summary() {

echo

log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|codebuddy|q]"
log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|codebuddy|q|trae]"
}

#==============================================================================
Expand Down
8 changes: 5 additions & 3 deletions scripts/powershell/update-agent-context.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Relies on common helper functions in common.ps1
#>
param(
[Parameter(Position=0)]
[ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo','codebuddy','q')]
[ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo','codebuddy','q','trae')]
[string]$AgentType
)

Expand Down Expand Up @@ -56,6 +56,7 @@ $AUGGIE_FILE = Join-Path $REPO_ROOT '.augment/rules/specify-rules.md'
$ROO_FILE = Join-Path $REPO_ROOT '.roo/rules/specify-rules.md'
$CODEBUDDY_FILE = Join-Path $REPO_ROOT '.codebuddy/rules/specify-rules.md'
$Q_FILE = Join-Path $REPO_ROOT 'AGENTS.md'
$TRAE_FILE = Join-Path $REPO_ROOT '.trae/rules/specify-rules.md'

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

Expand Down Expand Up @@ -380,7 +381,7 @@ function Update-SpecificAgent {
'roo' { Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code' }
'codebuddy' { Update-AgentFile -TargetFile $CODEBUDDY_FILE -AgentName 'CodeBuddy' }
'q' { Update-AgentFile -TargetFile $Q_FILE -AgentName 'Amazon Q Developer CLI' }
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|q'; return $false }
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|trae|codebuddy|q'; return $false }
}
}

Expand All @@ -399,6 +400,7 @@ function Update-AllExistingAgents {
if (Test-Path $ROO_FILE) { if (-not (Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code')) { $ok = $false }; $found = $true }
if (Test-Path $CODEBUDDY_FILE) { if (-not (Update-AgentFile -TargetFile $CODEBUDDY_FILE -AgentName 'CodeBuddy')) { $ok = $false }; $found = $true }
if (Test-Path $Q_FILE) { if (-not (Update-AgentFile -TargetFile $Q_FILE -AgentName 'Amazon Q Developer CLI')) { $ok = $false }; $found = $true }
if (Test-Path $TRAE_FILE) { if (-not (Update-AgentFile -TargetFile $TRAE_FILE -AgentName 'Trae AI')) { $ok = $false }; $found = $true }
if (-not $found) {
Write-Info 'No existing agent files found, creating default Claude file...'
if (-not (Update-AgentFile -TargetFile $CLAUDE_FILE -AgentName 'Claude Code')) { $ok = $false }
Expand All @@ -413,7 +415,7 @@ function Print-Summary {
if ($NEW_FRAMEWORK) { Write-Host " - Added framework: $NEW_FRAMEWORK" }
if ($NEW_DB -and $NEW_DB -ne 'N/A') { Write-Host " - Added database: $NEW_DB" }
Write-Host ''
Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|q]'
Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|trae|codebuddy|q]'
}

function Main {
Expand Down
59 changes: 58 additions & 1 deletion src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,20 @@ def _github_auth_headers(cli_token: str | None = None) -> dict:
token = _github_token(cli_token)
return {"Authorization": f"Bearer {token}"} if token else {}

AI_CHOICES = {
"copilot": "GitHub Copilot",
"claude": "Claude Code",
"gemini": "Gemini CLI",
"cursor": "Cursor",
"qwen": "Qwen Code",
"opencode": "opencode",
"codex": "Codex CLI",
"windsurf": "Windsurf",
"kilocode": "Kilo Code",
"auggie": "Auggie CLI",
"roo": "Roo Code",
"q": "Amazon Q Developer CLI",
"trae": "Trae AI",
# Agent configuration with name, folder, install URL, and CLI tool requirement
AGENT_CONFIG = {
"copilot": {
Expand Down Expand Up @@ -788,7 +802,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, or use '.' for current directory)"),
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor-agent, qwen, opencode, codex, windsurf, kilocode, auggie, codebuddy, or q"),
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor-agent, qwen, opencode, codex, windsurf, kilocode, auggie, trae,codebuddy, or q"),
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"),
Expand Down Expand Up @@ -1027,6 +1041,24 @@ def init(
console.print(git_error_panel)

# Agent folder security notice
agent_folder_map = {
"claude": ".claude/",
"gemini": ".gemini/",
"cursor": ".cursor/",
"qwen": ".qwen/",
"opencode": ".opencode/",
"codex": ".codex/",
"windsurf": ".windsurf/",
"kilocode": ".kilocode/",
"auggie": ".augment/",
"copilot": ".github/",
"roo": ".roo/",
"q": ".amazonq/",
"trae": ".trae/"
}

if selected_ai in agent_folder_map:
agent_folder = agent_folder_map[selected_ai]
agent_config = AGENT_CONFIG.get(selected_ai)
if agent_config:
agent_folder = agent_config["folder"]
Expand Down Expand Up @@ -1106,6 +1138,30 @@ def check():
code_ok = check_tool("code", tracker=tracker)

tracker.add("code-insiders", "Visual Studio Code Insiders")
tracker.add("cursor-agent", "Cursor IDE agent")
tracker.add("windsurf", "Windsurf IDE")
tracker.add("kilocode", "Kilo Code IDE")
tracker.add("opencode", "opencode")
tracker.add("codex", "Codex CLI")
tracker.add("auggie", "Auggie CLI")
tracker.add("q", "Amazon Q Developer CLI")
tracker.add("trae", "Trae AI")


git_ok = check_tool_for_tracker("git", tracker)
claude_ok = check_tool_for_tracker("claude", tracker)
gemini_ok = check_tool_for_tracker("gemini", tracker)
qwen_ok = check_tool_for_tracker("qwen", tracker)
code_ok = check_tool_for_tracker("code", tracker)
code_insiders_ok = check_tool_for_tracker("code-insiders", tracker)
cursor_ok = check_tool_for_tracker("cursor-agent", tracker)
windsurf_ok = check_tool_for_tracker("windsurf", tracker)
kilocode_ok = check_tool_for_tracker("kilocode", tracker)
opencode_ok = check_tool_for_tracker("opencode", tracker)
codex_ok = check_tool_for_tracker("codex", tracker)
auggie_ok = check_tool_for_tracker("auggie", tracker)
q_ok = check_tool_for_tracker("q", tracker)
trae_ok = check_tool_for_tracker("trae", tracker)
code_insiders_ok = check_tool("code-insiders", tracker=tracker)

console.print(tracker.render())
Expand All @@ -1114,6 +1170,7 @@ def check():

if not git_ok:
console.print("[dim]Tip: Install git for repository management[/dim]")
if not (claude_ok or gemini_ok or cursor_ok or qwen_ok or windsurf_ok or kilocode_ok or opencode_ok or codex_ok or auggie_ok or q_ok or trae_ok):

if not any(agent_results.values()):
console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")
Expand Down