diff --git a/.github/workflows/scripts/create-github-release.sh b/.github/workflows/scripts/create-github-release.sh index 0257520f..63343d03 100644 --- a/.github/workflows/scripts/create-github-release.sh +++ b/.github/workflows/scripts/create-github-release.sh @@ -38,5 +38,7 @@ gh release create "$VERSION" \ .genreleases/spec-kit-template-auggie-ps-"$VERSION".zip \ .genreleases/spec-kit-template-roo-sh-"$VERSION".zip \ .genreleases/spec-kit-template-roo-ps-"$VERSION".zip \ + .genreleases/spec-kit-template-codebuddy-sh-"$VERSION".zip \ + .genreleases/spec-kit-template-codebuddy-ps-"$VERSION".zip \ --title "Spec Kit Templates - $VERSION_NO_V" \ --notes-file release_notes.md \ No newline at end of file diff --git a/.github/workflows/scripts/create-release-packages.sh b/.github/workflows/scripts/create-release-packages.sh index 1a12e558..0d551602 100644 --- a/.github/workflows/scripts/create-release-packages.sh +++ b/.github/workflows/scripts/create-release-packages.sh @@ -172,13 +172,16 @@ build_variant() { roo) mkdir -p "$base_dir/.roo/commands" generate_commands roo md "\$ARGUMENTS" "$base_dir/.roo/commands" "$script" ;; + codebuddy) + mkdir -p "$base_dir/.codebuddy/commands" + generate_commands codebuddy md "\$ARGUMENTS" "$base_dir/.codebuddy/commands" "$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) +ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo codebuddy) ALL_SCRIPTS=(sh ps) diff --git a/AGENTS.md b/AGENTS.md index 59b99566..247744a5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,6 +38,7 @@ Specify supports multiple AI agents by generating agent-specific command files a | **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 | +| **CodeBuddy** | `.codebuddy/commands/` | Markdown | `codebuddy` | CodeBuddy CLI | ### Step-by-Step Integration Guide @@ -55,7 +56,8 @@ AI_CHOICES = { "cursor": "Cursor", "qwen": "Qwen Code", "opencode": "opencode", - "windsurf": "Windsurf" # Add new agent here + "windsurf": "Windsurf", + "codebuddy": "CodeBuddy" # Add new agent here } ``` @@ -69,10 +71,11 @@ agent_folder_map = { "qwen": ".qwen/", "opencode": ".opencode/", "codex": ".codex/", - "windsurf": ".windsurf/", # Add new agent folder here + "windsurf": ".windsurf/", "kilocode": ".kilocode/", "auggie": ".auggie/", - "copilot": ".github/" + "copilot": ".github/", + "codebuddy": ".codebuddy/" # Add new agent folder here } ``` @@ -197,6 +200,7 @@ Require a command-line tool to be installed: - **Cursor**: `cursor-agent` CLI - **Qwen Code**: `qwen` CLI - **opencode**: `opencode` CLI +- **CodeBuddy**: `codebuddy` CLI ### IDE-Based Agents Work within integrated development environments: diff --git a/README.md b/README.md index 079e6738..13ced74c 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,7 @@ specify init --ai qwen specify init --ai opencode specify init --ai codex specify init --ai windsurf +specify init --ai codebuddy # Or in current directory: specify init --here --ai claude specify init --here --ai codex diff --git a/scripts/bash/update-agent-context.sh b/scripts/bash/update-agent-context.sh index d3cc422e..ea467647 100644 --- a/scripts/bash/update-agent-context.sh +++ b/scripts/bash/update-agent-context.sh @@ -69,6 +69,7 @@ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md" KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md" 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" # Template file TEMPLATE_FILE="$REPO_ROOT/.specify/templates/agent-file-template.md" @@ -580,9 +581,12 @@ update_specific_agent() { roo) update_agent_file "$ROO_FILE" "Roo Code" ;; + codebuddy) + update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI" + ;; *) log_error "Unknown agent type '$agent_type'" - log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo" + log_error "Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy" exit 1 ;; esac @@ -641,6 +645,11 @@ update_all_existing_agents() { update_agent_file "$ROO_FILE" "Roo Code" found_agent=true fi + + if [[ -f "$CODEBUDDY_FILE" ]]; then + update_agent_file "$CODEBUDDY_FILE" "CodeBuddy CLI" + found_agent=true + fi # If no agent files exist, create a default Claude file if [[ "$found_agent" == false ]]; then @@ -665,7 +674,7 @@ print_summary() { fi echo - log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo]" + log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy]" } #============================================================================== diff --git a/scripts/powershell/update-agent-context.ps1 b/scripts/powershell/update-agent-context.ps1 index 8f4830a9..17fa9b44 100644 --- a/scripts/powershell/update-agent-context.ps1 +++ b/scripts/powershell/update-agent-context.ps1 @@ -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')] + [ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo','codebuddy')] [string]$AgentType ) @@ -54,6 +54,7 @@ $WINDSURF_FILE = Join-Path $REPO_ROOT '.windsurf/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' $ROO_FILE = Join-Path $REPO_ROOT '.roo/rules/specify-rules.md' +$CODEBUDDY_FILE = Join-Path $REPO_ROOT '.codebuddy/rules/specify-rules.md' $TEMPLATE_FILE = Join-Path $REPO_ROOT '.specify/templates/agent-file-template.md' @@ -376,7 +377,8 @@ function Update-SpecificAgent { 'kilocode' { Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code' } 'auggie' { Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI' } '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 } + 'codebuddy' { Update-AgentFile -TargetFile $CODEBUDDY_FILE -AgentName 'CodeBuddy CLI' } + default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy'; return $false } } } @@ -393,6 +395,7 @@ function Update-AllExistingAgents { 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 $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 CLI')) { $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 } @@ -407,7 +410,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]' + Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy]' } function Main { diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index 14b9b0d3..068e8563 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -74,7 +74,7 @@ AI_CHOICES = { "windsurf": "Windsurf", "kilocode": "Kilo Code", "auggie": "Auggie CLI", - "codebuddy": "CodeBuddy Code", + "codebuddy": "CodeBuddy CLI", "roo": "Roo Code", } # Add script type choices @@ -749,7 +749,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, cursor, qwen, opencode, codex, windsurf, kilocode, or auggie"), + ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor, qwen, opencode, codex, windsurf, kilocode, auggie, roo, or codebuddy"), 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"), @@ -763,7 +763,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, Cursor, Qwen Code, opencode, Codex CLI, Windsurf, Kilo Code, or Auggie CLI) + 2. Let you choose your AI assistant (Claude Code, Gemini CLI, GitHub Copilot, Cursor, Qwen Code, opencode, Codex CLI, Windsurf, Kilo Code, Auggie CLI, Roo Code, or CodeBuddy CLI) 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) @@ -1103,7 +1103,8 @@ def check(): tracker.add("opencode", "opencode") tracker.add("codex", "Codex CLI") tracker.add("auggie", "Auggie CLI") - tracker.add("codebuddy", "CodeBuddy Code") + tracker.add("roo", "Roo Code") + tracker.add("codebuddy", "CodeBuddy CLI") git_ok = check_tool_for_tracker("git", tracker) claude_ok = check_tool_for_tracker("claude", tracker) @@ -1117,6 +1118,7 @@ def check(): opencode_ok = check_tool_for_tracker("opencode", tracker) codex_ok = check_tool_for_tracker("codex", tracker) auggie_ok = check_tool_for_tracker("auggie", tracker) + roo_ok = check_tool_for_tracker("roo", tracker) codebuddy_ok = check_tool_for_tracker("codebuddy", tracker) console.print(tracker.render()) @@ -1125,7 +1127,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): + 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 roo_ok or codebuddy_ok): console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")