Compare commits

..

7 Commits

Author SHA1 Message Date
den (work)
9319f0425e Update with --force flag 2025-09-22 14:45:35 -07:00
Den Delimarsky
5d764e8364 Merge pull request #477 from spboyer/fix/add-uv-tool-install-instructions
Add uv tool install instructions to README
2025-09-22 09:20:04 -07:00
Shayne Boyer
1db65aa6aa feat: add uv tool install instructions to README
- Add persistent installation option using 'uv tool install'
- Keep existing 'uvx' one-time usage option
- Add benefits section explaining advantages of persistent installation
- Reorganize installation section with clear option headers

Fixes #476
2025-09-22 11:08:25 -04:00
Den Delimarsky 🌺
9348c45f9e Update with Roo Code support 2025-09-21 19:56:17 -07:00
Den Delimarsky 🌺
ad746ce35d Update generate-release-notes.sh 2025-09-21 13:16:15 -07:00
Den Delimarsky 🌺
14ac43ba41 Update error messages 2025-09-21 13:12:49 -07:00
Den Delimarsky 🌺
0857f83de8 Auggie folder fix 2025-09-21 13:01:04 -07:00
9 changed files with 129 additions and 56 deletions

View File

@@ -36,5 +36,7 @@ gh release create "$VERSION" \
.genreleases/spec-kit-template-kilocode-ps-"$VERSION".zip \ .genreleases/spec-kit-template-kilocode-ps-"$VERSION".zip \
.genreleases/spec-kit-template-auggie-sh-"$VERSION".zip \ .genreleases/spec-kit-template-auggie-sh-"$VERSION".zip \
.genreleases/spec-kit-template-auggie-ps-"$VERSION".zip \ .genreleases/spec-kit-template-auggie-ps-"$VERSION".zip \
.genreleases/spec-kit-template-roo-sh-"$VERSION".zip \
.genreleases/spec-kit-template-roo-ps-"$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

View File

@@ -169,13 +169,16 @@ build_variant() {
auggie) auggie)
mkdir -p "$base_dir/.augment/commands" mkdir -p "$base_dir/.augment/commands"
generate_commands auggie md "\$ARGUMENTS" "$base_dir/.augment/commands" "$script" ;; generate_commands auggie md "\$ARGUMENTS" "$base_dir/.augment/commands" "$script" ;;
roo)
mkdir -p "$base_dir/.roo/commands"
generate_commands roo md "\$ARGUMENTS" "$base_dir/.roo/commands" "$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 $GENRELEASES_DIR/spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip" echo "Created $GENRELEASES_DIR/spec-kit-template-${agent}-${script}-${NEW_VERSION}.zip"
} }
# Determine agent list # Determine agent list
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie) ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo)
ALL_SCRIPTS=(sh ps) ALL_SCRIPTS=(sh ps)

View File

@@ -28,29 +28,8 @@ fi
# Create release notes # Create release notes
cat > release_notes.md << EOF cat > release_notes.md << EOF
Template release $NEW_VERSION This is the latest set of releases that you can use with your agent of choice. We recommend using the Specify CLI to scaffold your projects, however you can download these independently and manage them yourself.
Updated specification-driven development templates for GitHub Copilot, Claude Code, Gemini CLI, Cursor, Qwen, opencode, Windsurf, and Codex.
Now includes per-script variants for POSIX shell (sh) and PowerShell (ps).
Download the template for your preferred AI assistant + script type:
- spec-kit-template-copilot-sh-$NEW_VERSION.zip
- spec-kit-template-copilot-ps-$NEW_VERSION.zip
- spec-kit-template-claude-sh-$NEW_VERSION.zip
- spec-kit-template-claude-ps-$NEW_VERSION.zip
- spec-kit-template-gemini-sh-$NEW_VERSION.zip
- spec-kit-template-gemini-ps-$NEW_VERSION.zip
- spec-kit-template-cursor-sh-$NEW_VERSION.zip
- spec-kit-template-cursor-ps-$NEW_VERSION.zip
- spec-kit-template-opencode-sh-$NEW_VERSION.zip
- spec-kit-template-opencode-ps-$NEW_VERSION.zip
- spec-kit-template-qwen-sh-$NEW_VERSION.zip
- spec-kit-template-qwen-ps-$NEW_VERSION.zip
- spec-kit-template-windsurf-sh-$NEW_VERSION.zip
- spec-kit-template-windsurf-ps-$NEW_VERSION.zip
- spec-kit-template-codex-sh-$NEW_VERSION.zip
- spec-kit-template-codex-ps-$NEW_VERSION.zip
EOF EOF
echo "Generated release notes:" echo "Generated release notes:"

View File

@@ -1,10 +1,30 @@
# Changelog # Changelog
<!-- markdownlint-disable MD024 -->
All notable changes to the Specify CLI will be documented in this file. 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/), 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). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.0.16] - 2025-09-22
### Added
- `--force` flag for `init` command to bypass confirmation when using `--here` in a non-empty directory and proceed with merging/overwriting files.
## [0.0.15] - 2025-09-21
### Added
- Support for Roo Code.
## [0.0.14] - 2025-09-21
### Changed
- Error messages are now shown consistently.
## [0.0.13] - 2025-09-21 ## [0.0.13] - 2025-09-21
### Added ### Added

View File

@@ -39,12 +39,38 @@ Spec-Driven Development **flips the script** on traditional software development
### 1. Install Specify ### 1. Install Specify
Initialize your project depending on the coding agent you're using: Choose your preferred installation method:
#### Option 1: Persistent Installation (Recommended)
Install once and use everywhere:
```bash
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git
```
Then use the tool directly:
```bash
specify init <PROJECT_NAME>
specify check
```
#### Option 2: One-time Usage
Run directly without installing:
```bash ```bash
uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME> uvx --from git+https://github.com/github/spec-kit.git specify init <PROJECT_NAME>
``` ```
**Benefits of persistent installation:**
- Tool stays installed and available in PATH
- No need to create shell aliases
- Better tool management with `uv tool list`, `uv tool upgrade`, `uv tool uninstall`
- Cleaner shell configuration
### 2. Establish project principles ### 2. Establish project principles
Use the **`/constitution`** command to create your project's governing principles and development guidelines that will guide all subsequent development. Use the **`/constitution`** command to create your project's governing principles and development guidelines that will guide all subsequent development.
@@ -106,6 +132,7 @@ Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.c
| [Windsurf](https://windsurf.com/) | ✅ | | | [Windsurf](https://windsurf.com/) | ✅ | |
| [Kilo Code](https://github.com/Kilo-Org/kilocode) | ✅ | | | [Kilo Code](https://github.com/Kilo-Org/kilocode) | ✅ | |
| [Auggie CLI](https://docs.augmentcode.com/cli/overview) | ✅ | | | [Auggie CLI](https://docs.augmentcode.com/cli/overview) | ✅ | |
| [Roo Code](https://roocode.com/) | ✅ | |
| [Codex CLI](https://github.com/openai/codex) | ⚠️ | Codex [does not support](https://github.com/openai/codex/issues/2890) custom arguments for slash commands. | | [Codex CLI](https://github.com/openai/codex) | ⚠️ | Codex [does not support](https://github.com/openai/codex/issues/2890) custom arguments for slash commands. |
## 🔧 Specify CLI Reference ## 🔧 Specify CLI Reference
@@ -124,11 +151,12 @@ The `specify` command supports the following options:
| Argument/Option | Type | Description | | Argument/Option | Type | Description |
|------------------------|----------|------------------------------------------------------------------------------| |------------------------|----------|------------------------------------------------------------------------------|
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`) | | `<project-name>` | Argument | Name for your new project directory (optional if using `--here`) |
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, or `auggie` | | `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, or `roo` |
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) | | `--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 | | `--ignore-agent-tools` | Flag | Skip checks for AI agent tools like Claude Code |
| `--no-git` | Flag | Skip git repository initialization | | `--no-git` | Flag | Skip git repository initialization |
| `--here` | Flag | Initialize project in the current directory instead of creating a new one | | `--here` | Flag | Initialize project in the current directory instead of creating a new one |
| `--force` | Flag | Force merge/overwrite when using `--here` in a non-empty directory (skip confirmation) |
| `--skip-tls` | Flag | Skip SSL/TLS verification (not recommended) | | `--skip-tls` | Flag | Skip SSL/TLS verification (not recommended) |
| `--debug` | Flag | Enable detailed debug output for troubleshooting | | `--debug` | Flag | Enable detailed debug output for troubleshooting |
| `--github-token` | Option | GitHub token for API requests (or set GH_TOKEN/GITHUB_TOKEN env variable) | | `--github-token` | Option | GitHub token for API requests (or set GH_TOKEN/GITHUB_TOKEN env variable) |
@@ -154,6 +182,9 @@ specify init my-project --ai copilot --script ps
# Initialize in current directory # Initialize in current directory
specify init --here --ai copilot specify init --here --ai copilot
# Force merge into current (non-empty) directory without confirmation
specify init --here --force --ai copilot
# Skip git initialization # Skip git initialization
specify init my-project --ai gemini --no-git specify init my-project --ai gemini --no-git
@@ -260,6 +291,8 @@ Or initialize in the current directory:
```bash ```bash
specify init --here specify init --here
# Skip confirmation when the directory already has files
specify init --here --force
``` ```
![Specify CLI bootstrapping a new project in the terminal](./media/specify_cli.gif) ![Specify CLI bootstrapping a new project in the terminal](./media/specify_cli.gif)
@@ -278,6 +311,8 @@ specify init <project_name> --ai windsurf
# Or in current directory: # Or in current directory:
specify init --here --ai claude specify init --here --ai claude
specify init --here --ai codex specify init --here --ai codex
# Force merge into a non-empty current directory
specify init --here --force --ai claude
``` ```
The CLI will check if you have Claude Code, Gemini CLI, Cursor CLI, Qwen CLI, opencode, or Codex 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, Cursor CLI, Qwen CLI, opencode, or Codex 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:

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "specify-cli" name = "specify-cli"
version = "0.0.14" version = "0.0.16"
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)." description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
requires-python = ">=3.11" requires-python = ">=3.11"
dependencies = [ dependencies = [

View File

@@ -68,6 +68,7 @@ AGENTS_FILE="$REPO_ROOT/AGENTS.md"
WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md" WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md" KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md" AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
# Template file # Template file
TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md" TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md"
@@ -576,9 +577,12 @@ update_specific_agent() {
auggie) auggie)
update_agent_file "$AUGGIE_FILE" "Auggie CLI" update_agent_file "$AUGGIE_FILE" "Auggie CLI"
;; ;;
roo)
update_agent_file "$ROO_FILE" "Roo Code"
;;
*) *)
log_error "Unknown agent type '$agent_type'" log_error "Unknown agent type '$agent_type'"
log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie" log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo"
exit 1 exit 1
;; ;;
esac esac
@@ -633,6 +637,11 @@ update_all_existing_agents() {
found_agent=true found_agent=true
fi fi
if [[ -f "$ROO_FILE" ]]; then
update_agent_file "$ROO_FILE" "Roo Code"
found_agent=true
fi
# If no agent files exist, create a default Claude file # If no agent files exist, create a default Claude file
if [[ "$found_agent" == false ]]; then if [[ "$found_agent" == false ]]; then
log_info "No existing agent files found, creating default Claude file..." log_info "No existing agent files found, creating default Claude file..."
@@ -656,7 +665,7 @@ print_summary() {
fi fi
echo echo
log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie]" log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo]"
} }
#============================================================================== #==============================================================================

View File

@@ -25,7 +25,7 @@ Relies on common helper functions in common.ps1
#> #>
param( param(
[Parameter(Position=0)] [Parameter(Position=0)]
[ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie')] [ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo')]
[string]$AgentType [string]$AgentType
) )
@@ -53,6 +53,7 @@ $AGENTS_FILE = Join-Path $REPO_ROOT 'AGENTS.md'
$WINDSURF_FILE = Join-Path $REPO_ROOT '.windsurf/rules/specify-rules.md' $WINDSURF_FILE = Join-Path $REPO_ROOT '.windsurf/rules/specify-rules.md'
$KILOCODE_FILE = Join-Path $REPO_ROOT '.kilocode/rules/specify-rules.md' $KILOCODE_FILE = Join-Path $REPO_ROOT '.kilocode/rules/specify-rules.md'
$AUGGIE_FILE = Join-Path $REPO_ROOT '.augment/rules/specify-rules.md' $AUGGIE_FILE = Join-Path $REPO_ROOT '.augment/rules/specify-rules.md'
$ROO_FILE = Join-Path $REPO_ROOT '.roo/rules/specify-rules.md'
$TEMPLATE_FILE = Join-Path $REPO_ROOT '.specify/templates/agent-file-template.md' $TEMPLATE_FILE = Join-Path $REPO_ROOT '.specify/templates/agent-file-template.md'
@@ -374,7 +375,8 @@ function Update-SpecificAgent {
'windsurf' { Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf' } 'windsurf' { Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf' }
'kilocode' { Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code' } 'kilocode' { Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code' }
'auggie' { Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI' } 'auggie' { Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI' }
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie'; return $false } 'roo' { Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code' }
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo'; return $false }
} }
} }
@@ -390,6 +392,7 @@ function Update-AllExistingAgents {
if (Test-Path $WINDSURF_FILE) { if (-not (Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf')) { $ok = $false }; $found = $true } if (Test-Path $WINDSURF_FILE) { if (-not (Update-AgentFile -TargetFile $WINDSURF_FILE -AgentName 'Windsurf')) { $ok = $false }; $found = $true }
if (Test-Path $KILOCODE_FILE) { if (-not (Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code')) { $ok = $false }; $found = $true } if (Test-Path $KILOCODE_FILE) { if (-not (Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code')) { $ok = $false }; $found = $true }
if (Test-Path $AUGGIE_FILE) { if (-not (Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI')) { $ok = $false }; $found = $true } if (Test-Path $AUGGIE_FILE) { if (-not (Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI')) { $ok = $false }; $found = $true }
if (Test-Path $ROO_FILE) { if (-not (Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code')) { $ok = $false }; $found = $true }
if (-not $found) { if (-not $found) {
Write-Info 'No existing agent files found, creating default Claude file...' Write-Info 'No existing agent files found, creating default Claude file...'
if (-not (Update-AgentFile -TargetFile $CLAUDE_FILE -AgentName 'Claude Code')) { $ok = $false } if (-not (Update-AgentFile -TargetFile $CLAUDE_FILE -AgentName 'Claude Code')) { $ok = $false }
@@ -404,7 +407,7 @@ function Print-Summary {
if ($NEW_FRAMEWORK) { Write-Host " - Added framework: $NEW_FRAMEWORK" } if ($NEW_FRAMEWORK) { Write-Host " - Added framework: $NEW_FRAMEWORK" }
if ($NEW_DB -and $NEW_DB -ne 'N/A') { Write-Host " - Added database: $NEW_DB" } if ($NEW_DB -and $NEW_DB -ne 'N/A') { Write-Host " - Added database: $NEW_DB" }
Write-Host '' Write-Host ''
Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie]' Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo]'
} }
function Main { function Main {

View File

@@ -74,6 +74,7 @@ AI_CHOICES = {
"windsurf": "Windsurf", "windsurf": "Windsurf",
"kilocode": "Kilo Code", "kilocode": "Kilo Code",
"auggie": "Auggie CLI", "auggie": "Auggie CLI",
"roo": "Roo Code",
} }
# 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"}
@@ -382,8 +383,6 @@ def check_tool(tool: str, install_hint: str) -> bool:
if shutil.which(tool): if shutil.which(tool):
return True return True
else: else:
console.print(f"[yellow]⚠️ {tool} not found[/yellow]")
console.print(f" Install with: [cyan]{install_hint}[/cyan]")
return False return False
@@ -754,6 +753,7 @@ def init(
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"),
here: bool = typer.Option(False, "--here", help="Initialize project in the current directory instead of creating a new one"), here: bool = typer.Option(False, "--here", help="Initialize project in the current directory instead of creating a new one"),
force: bool = typer.Option(False, "--force", help="Force merge/overwrite when using --here (skip confirmation)"),
skip_tls: bool = typer.Option(False, "--skip-tls", help="Skip SSL/TLS verification (not recommended)"), skip_tls: bool = typer.Option(False, "--skip-tls", help="Skip SSL/TLS verification (not recommended)"),
debug: bool = typer.Option(False, "--debug", help="Show verbose diagnostic output for network and extraction failures"), debug: bool = typer.Option(False, "--debug", help="Show verbose diagnostic output for network and extraction failures"),
github_token: str = typer.Option(None, "--github-token", help="GitHub token to use for API requests (or set GH_TOKEN or GITHUB_TOKEN environment variable)"), github_token: str = typer.Option(None, "--github-token", help="GitHub token to use for API requests (or set GH_TOKEN or GITHUB_TOKEN environment variable)"),
@@ -784,6 +784,7 @@ def init(
specify init --here --ai claude specify init --here --ai claude
specify init --here --ai codex specify init --here --ai codex
specify init --here specify init --here
specify init --here --force # Skip confirmation when current directory not empty
""" """
# Show banner first # Show banner first
show_banner() show_banner()
@@ -807,17 +808,27 @@ def init(
if existing_items: if existing_items:
console.print(f"[yellow]Warning:[/yellow] Current directory is not empty ({len(existing_items)} items)") console.print(f"[yellow]Warning:[/yellow] Current directory is not empty ({len(existing_items)} items)")
console.print("[yellow]Template files will be merged with existing content and may overwrite existing files[/yellow]") console.print("[yellow]Template files will be merged with existing content and may overwrite existing files[/yellow]")
if force:
# Ask for confirmation console.print("[cyan]--force supplied: skipping confirmation and proceeding with merge[/cyan]")
response = typer.confirm("Do you want to continue?") else:
if not response: # Ask for confirmation
console.print("[yellow]Operation cancelled[/yellow]") response = typer.confirm("Do you want to continue?")
raise typer.Exit(0) if not response:
console.print("[yellow]Operation cancelled[/yellow]")
raise typer.Exit(0)
else: else:
project_path = Path(project_name).resolve() project_path = Path(project_name).resolve()
# Check if project directory already exists # Check if project directory already exists
if project_path.exists(): if project_path.exists():
console.print(f"[red]Error:[/red] Directory '{project_name}' already exists") error_panel = Panel(
f"Directory '[cyan]{project_name}[/cyan]' already exists\n"
"Please choose a different project name or remove the existing directory.",
title="[red]Directory Conflict[/red]",
border_style="red",
padding=(1, 2)
)
console.print()
console.print(error_panel)
raise typer.Exit(1) raise typer.Exit(1)
# Create formatted setup info with column alignment # Create formatted setup info with column alignment
@@ -861,35 +872,45 @@ def init(
# Check agent tools unless ignored # Check agent tools unless ignored
if not ignore_agent_tools: if not ignore_agent_tools:
agent_tool_missing = False agent_tool_missing = False
install_url = ""
if selected_ai == "claude": if selected_ai == "claude":
if not check_tool("claude", "Install from: https://docs.anthropic.com/en/docs/claude-code/setup"): if not check_tool("claude", "https://docs.anthropic.com/en/docs/claude-code/setup"):
console.print("[red]Error:[/red] Claude CLI is required for Claude Code projects") install_url = "https://docs.anthropic.com/en/docs/claude-code/setup"
agent_tool_missing = True agent_tool_missing = True
elif selected_ai == "gemini": elif selected_ai == "gemini":
if not check_tool("gemini", "Install from: https://github.com/google-gemini/gemini-cli"): if not check_tool("gemini", "https://github.com/google-gemini/gemini-cli"):
console.print("[red]Error:[/red] Gemini CLI is required for Gemini projects") install_url = "https://github.com/google-gemini/gemini-cli"
agent_tool_missing = True agent_tool_missing = True
elif selected_ai == "qwen": elif selected_ai == "qwen":
if not check_tool("qwen", "Install from: https://github.com/QwenLM/qwen-code"): if not check_tool("qwen", "https://github.com/QwenLM/qwen-code"):
console.print("[red]Error:[/red] Qwen CLI is required for Qwen Code projects") install_url = "https://github.com/QwenLM/qwen-code"
agent_tool_missing = True agent_tool_missing = True
elif selected_ai == "opencode": elif selected_ai == "opencode":
if not check_tool("opencode", "Install from: https://opencode.ai"): if not check_tool("opencode", "https://opencode.ai"):
console.print("[red]Error:[/red] opencode CLI is required for opencode projects") install_url = "https://opencode.ai"
agent_tool_missing = True agent_tool_missing = True
elif selected_ai == "codex": elif selected_ai == "codex":
if not check_tool("codex", "Install from: https://github.com/openai/codex"): if not check_tool("codex", "https://github.com/openai/codex"):
console.print("[red]Error:[/red] Codex CLI is required for Codex projects") install_url = "https://github.com/openai/codex"
agent_tool_missing = True agent_tool_missing = True
elif selected_ai == "auggie": elif selected_ai == "auggie":
if not check_tool("auggie", "Install from: https://docs.augmentcode.com/cli/setup-auggie/install-auggie-cli"): if not check_tool("auggie", "https://docs.augmentcode.com/cli/setup-auggie/install-auggie-cli"):
console.print("[red]Error:[/red] Auggie CLI is required for Auggie CLI projects") install_url = "https://docs.augmentcode.com/cli/setup-auggie/install-auggie-cli"
agent_tool_missing = True agent_tool_missing = True
# GitHub Copilot and Cursor checks are not needed as they're typically available in supported IDEs # GitHub Copilot and Cursor checks are not needed as they're typically available in supported IDEs
if agent_tool_missing: if agent_tool_missing:
console.print("\n[red]Required AI tool is missing![/red]") error_panel = Panel(
console.print("[yellow]Tip:[/yellow] Use --ignore-agent-tools to skip this check") f"[cyan]{selected_ai}[/cyan] not found\n"
f"Install with: [cyan]{install_url}[/cyan]\n"
f"{AI_CHOICES[selected_ai]} is required to continue with this project type.\n\n"
"Tip: Use [cyan]--ignore-agent-tools[/cyan] to skip this check",
title="[red]Agent Detection Error[/red]",
border_style="red",
padding=(1, 2)
)
console.print()
console.print(error_panel)
raise typer.Exit(1) raise typer.Exit(1)
# Determine script type (explicit, interactive, or OS default) # Determine script type (explicit, interactive, or OS default)
@@ -998,8 +1019,9 @@ def init(
"codex": ".codex/", "codex": ".codex/",
"windsurf": ".windsurf/", "windsurf": ".windsurf/",
"kilocode": ".kilocode/", "kilocode": ".kilocode/",
"auggie": ".auggie/", "auggie": ".augment/",
"copilot": ".github/" "copilot": ".github/",
"roo": ".roo/"
} }
if selected_ai in agent_folder_map: if selected_ai in agent_folder_map: