Skip to content

Commit 64563a5

Browse files
authored
Merge branch 'main' into main
2 parents 27d96a4 + ed5dbf1 commit 64563a5

File tree

12 files changed

+394
-233
lines changed

12 files changed

+394
-233
lines changed

.github/workflows/scripts/create-release-packages.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ generate_commands() {
9393

9494
case $ext in
9595
toml)
96+
body=$(printf '%s\n' "$body" | sed 's/\\/\\\\/g')
9697
{ echo "description = \"$description\""; echo; echo "prompt = \"\"\""; echo "$body"; echo "\"\"\""; } > "$output_dir/speckit.$name.$ext" ;;
9798
md)
9899
echo "$body" > "$output_dir/speckit.$name.$ext" ;;
@@ -178,6 +179,10 @@ build_variant() {
178179
roo)
179180
mkdir -p "$base_dir/.roo/commands"
180181
generate_commands roo md "\$ARGUMENTS" "$base_dir/.roo/commands" "$script" ;;
182+
codebuddy)
183+
mkdir -p "$base_dir/.codebuddy/commands"
184+
generate_commands codebuddy md "\$ARGUMENTS" "$base_dir/.codebuddy/commands" "$script" ;;
185+
181186
q)
182187
mkdir -p "$base_dir/.amazonq/prompts"
183188
generate_commands q md "\$ARGUMENTS" "$base_dir/.amazonq/prompts" "$script" ;;
@@ -187,10 +192,9 @@ build_variant() {
187192
}
188193

189194
# Determine agent list
190-
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo q)
195+
ALL_AGENTS=(claude gemini copilot cursor qwen opencode windsurf codex kilocode auggie roo codebuddy q)
191196
ALL_SCRIPTS=(sh ps)
192197

193-
194198
norm_list() {
195199
# convert comma+space separated -> space separated unique while preserving order of first occurrence
196200
tr ',\n' ' ' | awk '{for(i=1;i<=NF;i++){if(!seen[$i]++){printf((out?" ":"") $i)}}}END{printf("\n")}'

AGENTS.md

Lines changed: 92 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -37,56 +37,57 @@ Specify supports multiple AI agents by generating agent-specific command files a
3737
| **Cursor** | `.cursor/commands/` | Markdown | `cursor-agent` | Cursor CLI |
3838
| **Qwen Code** | `.qwen/commands/` | TOML | `qwen` | Alibaba's Qwen Code CLI |
3939
| **opencode** | `.opencode/command/` | Markdown | `opencode` | opencode CLI |
40+
| **Codex CLI** | `.codex/commands/` | Markdown | `codex` | Codex CLI |
4041
| **Windsurf** | `.windsurf/workflows/` | Markdown | N/A (IDE-based) | Windsurf IDE workflows |
42+
| **Kilo Code** | `.kilocode/rules/` | Markdown | N/A (IDE-based) | Kilo Code IDE |
43+
| **Auggie CLI** | `.augment/rules/` | Markdown | `auggie` | Auggie CLI |
44+
| **Roo Code** | `.roo/rules/` | Markdown | N/A (IDE-based) | Roo Code IDE |
45+
| **CodeBuddy** | `.codebuddy/commands/` | Markdown | `codebuddy` | CodeBuddy |
4146
| **Amazon Q Developer CLI** | `.amazonq/prompts/` | Markdown | `q` | Amazon Q Developer CLI |
4247

43-
4448
### Step-by-Step Integration Guide
4549

46-
Follow these steps to add a new agent (using Windsurf as an example):
50+
Follow these steps to add a new agent (using a hypothetical new agent as an example):
51+
52+
#### 1. Add to AGENT_CONFIG
4753

48-
#### 1. Update AI_CHOICES Constant
54+
**IMPORTANT**: Use the actual CLI tool name as the key, not a shortened version.
4955

50-
Add the new agent to the `AI_CHOICES` dictionary in `src/specify_cli/__init__.py`:
56+
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:
5157

5258
```python
53-
AI_CHOICES = {
54-
"copilot": "GitHub Copilot",
55-
"claude": "Claude Code",
56-
"gemini": "Gemini CLI",
57-
"cursor": "Cursor",
58-
"qwen": "Qwen Code",
59-
"opencode": "opencode",
60-
"windsurf": "Windsurf",
61-
"q": "Amazon Q Developer CLI" # Add new agent here
59+
AGENT_CONFIG = {
60+
# ... existing agents ...
61+
"new-agent-cli": { # Use the ACTUAL CLI tool name (what users type in terminal)
62+
"name": "New Agent Display Name",
63+
"folder": ".newagent/", # Directory for agent files
64+
"install_url": "https://example.com/install", # URL for installation docs (or None if IDE-based)
65+
"requires_cli": True, # True if CLI tool required, False for IDE-based agents
66+
},
6267
}
6368
```
6469

65-
Also update the `agent_folder_map` in the same file to include the new agent's folder for the security notice:
70+
**Key Design Principle**: The dictionary key should match the actual executable name that users install. For example:
71+
- ✅ Use `"cursor-agent"` because the CLI tool is literally called `cursor-agent`
72+
- ❌ Don't use `"cursor"` as a shortcut if the tool is `cursor-agent`
6673

67-
```python
68-
agent_folder_map = {
69-
"claude": ".claude/",
70-
"gemini": ".gemini/",
71-
"cursor": ".cursor/",
72-
"qwen": ".qwen/",
73-
"opencode": ".opencode/",
74-
"codex": ".codex/",
75-
"windsurf": ".windsurf/",
76-
"kilocode": ".kilocode/",
77-
"auggie": ".auggie/",
78-
"copilot": ".github/",
79-
"q": ".amazonq/" # Add new agent folder here
80-
}
81-
```
74+
This eliminates the need for special-case mappings throughout the codebase.
75+
76+
**Field Explanations**:
77+
- `name`: Human-readable display name shown to users
78+
- `folder`: Directory where agent-specific files are stored (relative to project root)
79+
- `install_url`: Installation documentation URL (set to `None` for IDE-based agents)
80+
- `requires_cli`: Whether the agent requires a CLI tool check during initialization
8281

8382
#### 2. Update CLI Help Text
8483

85-
Update all help text and examples to include the new agent:
84+
Update the `--ai` parameter help text in the `init()` command to include the new agent:
8685

87-
- Command option help: `--ai` parameter description
88-
- Function docstrings and examples
89-
- Error messages with agent lists
86+
```python
87+
ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor-agent, qwen, opencode, codex, windsurf, kilocode, auggie, codebuddy, new-agent-cli, or q"),
88+
```
89+
90+
Also update any function docstrings, examples, and error messages that list available agents.
9091

9192
#### 3. Update README Documentation
9293

@@ -190,17 +191,65 @@ elif selected_ai == "windsurf":
190191
agent_tool_missing = True
191192
```
192193

193-
**Note**: Skip CLI checks for IDE-based agents (Copilot, Windsurf).
194+
**Note**: CLI tool checks are now handled automatically based on the `requires_cli` field in AGENT_CONFIG. No additional code changes needed in the `check()` or `init()` commands - they automatically loop through AGENT_CONFIG and check tools as needed.
195+
196+
## Important Design Decisions
197+
198+
### Using Actual CLI Tool Names as Keys
199+
200+
**CRITICAL**: When adding a new agent to AGENT_CONFIG, always use the **actual executable name** as the dictionary key, not a shortened or convenient version.
201+
202+
**Why this matters:**
203+
- The `check_tool()` function uses `shutil.which(tool)` to find executables in the system PATH
204+
- If the key doesn't match the actual CLI tool name, you'll need special-case mappings throughout the codebase
205+
- This creates unnecessary complexity and maintenance burden
206+
207+
**Example - The Cursor Lesson:**
208+
209+
**Wrong approach** (requires special-case mapping):
210+
```python
211+
AGENT_CONFIG = {
212+
"cursor": { # Shorthand that doesn't match the actual tool
213+
"name": "Cursor",
214+
# ...
215+
}
216+
}
217+
218+
# Then you need special cases everywhere:
219+
cli_tool = agent_key
220+
if agent_key == "cursor":
221+
cli_tool = "cursor-agent" # Map to the real tool name
222+
```
223+
224+
**Correct approach** (no mapping needed):
225+
```python
226+
AGENT_CONFIG = {
227+
"cursor-agent": { # Matches the actual executable name
228+
"name": "Cursor",
229+
# ...
230+
}
231+
}
232+
233+
# No special cases needed - just use agent_key directly!
234+
```
235+
236+
**Benefits of this approach:**
237+
- Eliminates special-case logic scattered throughout the codebase
238+
- Makes the code more maintainable and easier to understand
239+
- Reduces the chance of bugs when adding new agents
240+
- Tool checking "just works" without additional mappings
194241

195242
## Agent Categories
196243

197244
### CLI-Based Agents
245+
198246
Require a command-line tool to be installed:
199247
- **Claude Code**: `claude` CLI
200248
- **Gemini CLI**: `gemini` CLI
201249
- **Cursor**: `cursor-agent` CLI
202250
- **Qwen Code**: `qwen` CLI
203251
- **opencode**: `opencode` CLI
252+
- **CodeBuddy**: `codebuddy` CLI
204253

205254
### IDE-Based Agents
206255
Work within integrated development environments:
@@ -257,20 +306,23 @@ Different agents use different argument placeholders:
257306

258307
## Common Pitfalls
259308

260-
1. **Forgetting update scripts**: Both bash and PowerShell scripts must be updated
261-
2. **Missing CLI checks**: Only add for agents that actually have CLI tools
262-
3. **Wrong argument format**: Use correct placeholder format for each agent type
263-
4. **Directory naming**: Follow agent-specific conventions exactly
264-
5. **Help text inconsistency**: Update all user-facing text consistently
309+
1. **Using shorthand keys instead of actual CLI tool names**: Always use the actual executable name as the AGENT_CONFIG key (e.g., `"cursor-agent"` not `"cursor"`). This prevents the need for special-case mappings throughout the codebase.
310+
2. **Forgetting update scripts**: Both bash and PowerShell scripts must be updated when adding new agents.
311+
3. **Incorrect `requires_cli` value**: Set to `True` only for agents that actually have CLI tools to check; set to `False` for IDE-based agents.
312+
4. **Wrong argument format**: Use correct placeholder format for each agent type (`$ARGUMENTS` for Markdown, `{{args}}` for TOML).
313+
5. **Directory naming**: Follow agent-specific conventions exactly (check existing agents for patterns).
314+
6. **Help text inconsistency**: Update all user-facing text consistently (help strings, docstrings, README, error messages).
265315

266316
## Future Considerations
267317

268318
When adding new agents:
319+
269320
- Consider the agent's native command/workflow patterns
270321
- Ensure compatibility with the Spec-Driven Development process
271322
- Document any special requirements or limitations
272323
- Update this guide with lessons learned
324+
- Verify the actual CLI tool name before adding to AGENT_CONFIG
273325

274326
---
275327

276-
*This documentation should be updated whenever new agents are added to maintain accuracy and completeness.*
328+
*This documentation should be updated whenever new agents are added to maintain accuracy and completeness.*

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ All notable changes to the Specify CLI and templates are documented here.
77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10+
## [0.0.19] - 2025-10-10
11+
12+
### Added
13+
14+
- Support for CodeBuddy (thank you to [@lispking](https://github.com/lispking) for the contribution).
15+
- You can now see Git-sourced errors in the Specify CLI.
16+
17+
### Changed
18+
19+
- Fixed the path to the constitution in `plan.md` (thank you to [@lyzno1](https://github.com/lyzno1) for spotting).
20+
- Fixed backslash escapes in generated TOML files for Gemini (thank you to [@hsin19](https://github.com/hsin19) for the contribution).
21+
- Implementation command now ensures that the correct ignore files are added (thank you to [@sigent-amazon](https://github.com/sigent-amazon) for the contribution).
22+
1023
## [0.0.18] - 2025-10-06
1124

1225
### Added

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ specify init <PROJECT_NAME>
6161
specify check
6262
```
6363

64+
To upgrade specify run:
65+
66+
```bash
67+
uv tool install specify-cli --force --from git+https://github.com/github/spec-kit.git
68+
```
69+
6470
#### Option 2: One-time Usage
6571

6672
Run directly without installing:
@@ -137,6 +143,7 @@ Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.c
137143
| [Windsurf](https://windsurf.com/) || |
138144
| [Kilo Code](https://github.com/Kilo-Org/kilocode) || |
139145
| [Auggie CLI](https://docs.augmentcode.com/cli/overview) || |
146+
| [CodeBuddy](https://www.codebuddy.ai/) || |
140147
| [Roo Code](https://roocode.com/) || |
141148
| [Codex CLI](https://github.com/openai/codex) || |
142149
| [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. |
@@ -157,7 +164,7 @@ The `specify` command supports the following options:
157164
| Argument/Option | Type | Description |
158165
|------------------------|----------|------------------------------------------------------------------------------|
159166
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`, or use `.` for current directory) |
160-
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, or `q` |
167+
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, or `q` |
161168
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) |
162169
| `--ignore-agent-tools` | Flag | Skip checks for AI agent tools like Claude Code |
163170
| `--no-git` | Flag | Skip git repository initialization |
@@ -177,7 +184,7 @@ specify init my-project
177184
specify init my-project --ai claude
178185

179186
# Initialize with Cursor support
180-
specify init my-project --ai cursor
187+
specify init my-project --ai cursor-agent
181188

182189
# Initialize with Windsurf support
183190
specify init my-project --ai windsurf

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
2-
name = "specify-cli"
3-
version = "0.0.18"
4-
description = "Specify CLI, part of Agentic SDLC Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
2+
name = "agentic-sdlc-specify-cli"
3+
version = "0.0.19"
4+
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
55
requires-python = ">=3.11"
66
dependencies = [
77
"typer",

scripts/bash/update-agent-context.sh

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ WINDSURF_FILE="$REPO_ROOT/.windsurf/rules/specify-rules.md"
6969
KILOCODE_FILE="$REPO_ROOT/.kilocode/rules/specify-rules.md"
7070
AUGGIE_FILE="$REPO_ROOT/.augment/rules/specify-rules.md"
7171
ROO_FILE="$REPO_ROOT/.roo/rules/specify-rules.md"
72+
CODEBUDDY_FILE="$REPO_ROOT/.codebuddy/rules/specify-rules.md"
7273
Q_FILE="$REPO_ROOT/AGENTS.md"
7374

7475
# Template file
@@ -581,6 +582,9 @@ update_specific_agent() {
581582
roo)
582583
update_agent_file "$ROO_FILE" "Roo Code"
583584
;;
585+
codebuddy)
586+
update_agent_file "$CODEBUDDY_FILE" "CodeBuddy"
587+
;;
584588
q)
585589
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
586590
;;
@@ -646,6 +650,11 @@ update_all_existing_agents() {
646650
found_agent=true
647651
fi
648652

653+
if [[ -f "$CODEBUDDY_FILE" ]]; then
654+
update_agent_file "$CODEBUDDY_FILE" "CodeBuddy"
655+
found_agent=true
656+
fi
657+
649658
if [[ -f "$Q_FILE" ]]; then
650659
update_agent_file "$Q_FILE" "Amazon Q Developer CLI"
651660
found_agent=true
@@ -674,7 +683,8 @@ print_summary() {
674683
fi
675684

676685
echo
677-
log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|q]"
686+
687+
log_info "Usage: $0 [claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|codebuddy|q]"
678688
}
679689

680690
#==============================================================================

scripts/powershell/update-agent-context.ps1

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Relies on common helper functions in common.ps1
2525
#>
2626
param(
2727
[Parameter(Position=0)]
28-
[ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo','q')]
28+
[ValidateSet('claude','gemini','copilot','cursor','qwen','opencode','codex','windsurf','kilocode','auggie','roo','codebuddy','q')]
2929
[string]$AgentType
3030
)
3131

@@ -54,6 +54,7 @@ $WINDSURF_FILE = Join-Path $REPO_ROOT '.windsurf/rules/specify-rules.md'
5454
$KILOCODE_FILE = Join-Path $REPO_ROOT '.kilocode/rules/specify-rules.md'
5555
$AUGGIE_FILE = Join-Path $REPO_ROOT '.augment/rules/specify-rules.md'
5656
$ROO_FILE = Join-Path $REPO_ROOT '.roo/rules/specify-rules.md'
57+
$CODEBUDDY_FILE = Join-Path $REPO_ROOT '.codebuddy/rules/specify-rules.md'
5758
$Q_FILE = Join-Path $REPO_ROOT 'AGENTS.md'
5859

5960
$TEMPLATE_FILE = Join-Path $REPO_ROOT '.specify/templates/agent-file-template.md'
@@ -377,8 +378,9 @@ function Update-SpecificAgent {
377378
'kilocode' { Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code' }
378379
'auggie' { Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI' }
379380
'roo' { Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code' }
381+
'codebuddy' { Update-AgentFile -TargetFile $CODEBUDDY_FILE -AgentName 'CodeBuddy' }
380382
'q' { Update-AgentFile -TargetFile $Q_FILE -AgentName 'Amazon Q Developer CLI' }
381-
default { Write-Err "Unknown agent type '$Type'"; Write-Err 'Expected: claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q'; return $false }
383+
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 }
382384
}
383385
}
384386

@@ -395,6 +397,7 @@ function Update-AllExistingAgents {
395397
if (Test-Path $KILOCODE_FILE) { if (-not (Update-AgentFile -TargetFile $KILOCODE_FILE -AgentName 'Kilo Code')) { $ok = $false }; $found = $true }
396398
if (Test-Path $AUGGIE_FILE) { if (-not (Update-AgentFile -TargetFile $AUGGIE_FILE -AgentName 'Auggie CLI')) { $ok = $false }; $found = $true }
397399
if (Test-Path $ROO_FILE) { if (-not (Update-AgentFile -TargetFile $ROO_FILE -AgentName 'Roo Code')) { $ok = $false }; $found = $true }
400+
if (Test-Path $CODEBUDDY_FILE) { if (-not (Update-AgentFile -TargetFile $CODEBUDDY_FILE -AgentName 'CodeBuddy')) { $ok = $false }; $found = $true }
398401
if (Test-Path $Q_FILE) { if (-not (Update-AgentFile -TargetFile $Q_FILE -AgentName 'Amazon Q Developer CLI')) { $ok = $false }; $found = $true }
399402
if (-not $found) {
400403
Write-Info 'No existing agent files found, creating default Claude file...'
@@ -410,7 +413,7 @@ function Print-Summary {
410413
if ($NEW_FRAMEWORK) { Write-Host " - Added framework: $NEW_FRAMEWORK" }
411414
if ($NEW_DB -and $NEW_DB -ne 'N/A') { Write-Host " - Added database: $NEW_DB" }
412415
Write-Host ''
413-
Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|q]'
416+
Write-Info 'Usage: ./update-agent-context.ps1 [-AgentType claude|gemini|copilot|cursor|qwen|opencode|codex|windsurf|kilocode|auggie|roo|codebuddy|q]'
414417
}
415418

416419
function Main {

0 commit comments

Comments
 (0)