mirror of
https://github.com/github/spec-kit.git
synced 2026-03-17 10:53:08 +00:00
* Initial plan * feat(templates): add pluggable template system with packs, catalog, resolver, and CLI commands Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * test(templates): add comprehensive unit tests for template pack system Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * feat(presets): pluggable preset system with template/command overrides, catalog, and resolver - Rename 'template packs' to 'presets' to avoid naming collision with core templates - PresetManifest, PresetRegistry, PresetManager, PresetCatalog, PresetResolver in presets.py - Extract CommandRegistrar to agents.py as shared infrastructure - CLI: specify preset list/add/remove/search/resolve/info - CLI: specify preset catalog list/add/remove - --preset option on specify init - Priority-based preset stacking (--priority, lower = higher precedence) - Command overrides registered into all detected agent directories (17+ agents) - Extension command safety: skip registration if target extension not installed - Multi-catalog support: env var, project config, user config, built-in defaults - resolve_template() / Resolve-Template in bash/PowerShell scripts - Self-test preset: overrides all 6 core templates + 1 command - Scaffold with 4 examples: core/extension template and command overrides - Preset catalog (catalog.json, catalog.community.json) - Documentation: README.md, ARCHITECTURE.md, PUBLISHING.md - 110 preset tests, 253 total tests passing * feat(presets): propagate command overrides to skills via init-options - Add save_init_options() / load_init_options() helpers that persist CLI flags from 'specify init' to .specify/init-options.json - PresetManager._register_skills() overwrites SKILL.md files when --ai-skills was used during init and corresponding skill dirs exist - PresetManager._unregister_skills() restores core template content on preset removal - registered_skills stored in preset registry metadata - 8 new tests covering skill override, skip conditions, and restore * fix: address PR check failures (ruff F541, CodeQL URL substring) - Remove extraneous f-prefix from two f-strings without placeholders - Replace substring URL check in test with startswith/endswith assertions to satisfy CodeQL incomplete URL substring sanitization rule * fix: address Copilot PR review comments - Move save_init_options() before preset install so skills propagation works during 'specify init --preset --ai-skills' - Clean up downloaded ZIP after successful preset install during init - Validate --from URL scheme (require HTTPS, HTTP only for localhost) - Expose unregister_commands() on extensions.py CommandRegistrar wrapper instead of reaching into private _registrar field - Use _get_merged_packs() for search() and get_pack_info() so all active catalogs are searched, not just the highest-priority one - Fix fetch_catalog() cache to verify cached URL matches current URL - Fix PresetResolver: script resolution uses .sh extension, consistent file extensions throughout resolve(), and resolve_with_source() delegates to resolve() to honor template_type parameter - Fix bash common.sh: fall through to directory scan when python3 returns empty preset list - Fix PowerShell Resolve-Template: filter out dot-folders and sort extensions deterministically * fix: narrow empty except blocks and add explanatory comments * fix: address Copilot PR review comments (round 2) - Fix init --preset error masking: distinguish "not found" from real errors - Fix bash resolve_template: skip hidden dirs in extensions (match Python/PS) - Fix temp dir leaks in tests: use temp_dir fixture instead of mkdtemp - Fix self-test catalog entry: add note that it's local-only (no download_url) - Fix Windows path issue in resolve_with_source: use Path.relative_to() - Fix skill restore path: use project's .specify/templates/commands/ not source tree - Add encoding="utf-8" to all file read/write in agents.py - Update test to set up core command templates for skill restoration * fix: remove self-test from catalog.json (local-only preset) * fix: address Copilot PR review comments (round 3) - Fix PS Resolve-Template fallback to skip dot-prefixed dirs (.cache) - Rename _catalog to _catalog_name for consistency with extension system - Enforce install_allowed policy in CLI preset add and download_pack() - Fix shell injection: pass registry path via env var instead of string interpolation * fix: correct PresetError docstring from template to preset * Removed CHANGELOG requirement * Applying review recommendations * Applying review recommendations * Applying review recommendations * Applying review recommendations --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
420 lines
16 KiB
Markdown
420 lines
16 KiB
Markdown
# 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/agents/` | Markdown | N/A (IDE-based) | GitHub Copilot in VS Code |
|
|
| **Cursor** | `.cursor/commands/` | Markdown | `cursor-agent` | Cursor CLI |
|
|
| **Qwen Code** | `.qwen/commands/` | Markdown | `qwen` | Alibaba's Qwen Code CLI |
|
|
| **opencode** | `.opencode/command/` | Markdown | `opencode` | opencode CLI |
|
|
| **Codex CLI** | `.codex/commands/` | Markdown | `codex` | Codex CLI |
|
|
| **Windsurf** | `.windsurf/workflows/` | Markdown | N/A (IDE-based) | Windsurf IDE workflows |
|
|
| **Kilo Code** | `.kilocode/rules/` | Markdown | N/A (IDE-based) | Kilo Code IDE |
|
|
| **Auggie CLI** | `.augment/rules/` | Markdown | `auggie` | Auggie CLI |
|
|
| **Roo Code** | `.roo/rules/` | Markdown | N/A (IDE-based) | Roo Code IDE |
|
|
| **CodeBuddy CLI** | `.codebuddy/commands/` | Markdown | `codebuddy` | CodeBuddy CLI |
|
|
| **Qoder CLI** | `.qoder/commands/` | Markdown | `qodercli` | Qoder CLI |
|
|
| **Kiro CLI** | `.kiro/prompts/` | Markdown | `kiro-cli` | Kiro CLI |
|
|
| **Amp** | `.agents/commands/` | Markdown | `amp` | Amp CLI |
|
|
| **SHAI** | `.shai/commands/` | Markdown | `shai` | SHAI CLI |
|
|
| **Tabnine CLI** | `.tabnine/agent/commands/` | TOML | `tabnine` | Tabnine CLI |
|
|
| **Kimi Code** | `.kimi/skills/` | Markdown | `kimi` | Kimi Code CLI (Moonshot AI) |
|
|
| **IBM Bob** | `.bob/commands/` | Markdown | N/A (IDE-based) | IBM Bob IDE |
|
|
| **Generic** | User-specified via `--ai-commands-dir` | Markdown | N/A | Bring your own agent |
|
|
|
|
### Step-by-Step Integration Guide
|
|
|
|
Follow these steps to add a new agent (using a hypothetical new agent as an example):
|
|
|
|
#### 1. Add to AGENT_CONFIG
|
|
|
|
**IMPORTANT**: Use the actual CLI tool name as the key, not a shortened version.
|
|
|
|
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
|
|
AGENT_CONFIG = {
|
|
# ... existing agents ...
|
|
"new-agent-cli": { # Use the ACTUAL CLI tool name (what users type in terminal)
|
|
"name": "New Agent Display Name",
|
|
"folder": ".newagent/", # Directory for agent files
|
|
"commands_subdir": "commands", # Subdirectory name for command files (default: "commands")
|
|
"install_url": "https://example.com/install", # URL for installation docs (or None if IDE-based)
|
|
"requires_cli": True, # True if CLI tool required, False for IDE-based agents
|
|
},
|
|
}
|
|
```
|
|
|
|
**Key Design Principle**: The dictionary key should match the actual executable name that users install. For example:
|
|
|
|
- ✅ 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`
|
|
|
|
This eliminates the need for special-case mappings throughout the codebase.
|
|
|
|
**Field Explanations**:
|
|
|
|
- `name`: Human-readable display name shown to users
|
|
- `folder`: Directory where agent-specific files are stored (relative to project root)
|
|
- `commands_subdir`: Subdirectory name within the agent folder where command/prompt files are stored (default: `"commands"`)
|
|
- Most agents use `"commands"` (e.g., `.claude/commands/`)
|
|
- Some agents use alternative names: `"agents"` (copilot), `"workflows"` (windsurf, kilocode), `"prompts"` (codex, kiro-cli), `"command"` (opencode - singular)
|
|
- This field enables `--ai-skills` to locate command templates correctly for skill generation
|
|
- `install_url`: Installation documentation URL (set to `None` for IDE-based agents)
|
|
- `requires_cli`: Whether the agent requires a CLI tool check during initialization
|
|
|
|
#### 2. Update CLI Help Text
|
|
|
|
Update the `--ai` parameter help text in the `init()` command to include the new agent:
|
|
|
|
```python
|
|
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 kiro-cli"),
|
|
```
|
|
|
|
Also update any function docstrings, examples, and error messages that list available agents.
|
|
|
|
#### 3. Update README Documentation
|
|
|
|
Update the **Supported AI Agents** section in `README.md` to include the new agent:
|
|
|
|
- Add the new agent to the table with appropriate support level (Full/Partial)
|
|
- Include the agent's official website link
|
|
- Add any relevant notes about the agent's implementation
|
|
- Ensure the table formatting remains aligned and consistent
|
|
|
|
#### 4. Update Release Package Script
|
|
|
|
Modify `.github/workflows/scripts/create-release-packages.sh`:
|
|
|
|
##### Add to ALL_AGENTS array
|
|
|
|
```bash
|
|
ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf kiro-cli)
|
|
```
|
|
|
|
##### 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 GitHub Release Script
|
|
|
|
Modify `.github/workflows/scripts/create-github-release.sh` to include the new agent's packages:
|
|
|
|
```bash
|
|
gh release create "$VERSION" \
|
|
# ... existing packages ...
|
|
.genreleases/spec-kit-template-windsurf-sh-"$VERSION".zip \
|
|
.genreleases/spec-kit-template-windsurf-ps-"$VERSION".zip \
|
|
# Add new agent packages here
|
|
```
|
|
|
|
#### 5. 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
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 6. 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**: 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.
|
|
|
|
## Important Design Decisions
|
|
|
|
### Using Actual CLI Tool Names as Keys
|
|
|
|
**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.
|
|
|
|
**Why this matters:**
|
|
|
|
- The `check_tool()` function uses `shutil.which(tool)` to find executables in the system PATH
|
|
- If the key doesn't match the actual CLI tool name, you'll need special-case mappings throughout the codebase
|
|
- This creates unnecessary complexity and maintenance burden
|
|
|
|
**Example - The Cursor Lesson:**
|
|
|
|
❌ **Wrong approach** (requires special-case mapping):
|
|
|
|
```python
|
|
AGENT_CONFIG = {
|
|
"cursor": { # Shorthand that doesn't match the actual tool
|
|
"name": "Cursor",
|
|
# ...
|
|
}
|
|
}
|
|
|
|
# Then you need special cases everywhere:
|
|
cli_tool = agent_key
|
|
if agent_key == "cursor":
|
|
cli_tool = "cursor-agent" # Map to the real tool name
|
|
```
|
|
|
|
✅ **Correct approach** (no mapping needed):
|
|
|
|
```python
|
|
AGENT_CONFIG = {
|
|
"cursor-agent": { # Matches the actual executable name
|
|
"name": "Cursor",
|
|
# ...
|
|
}
|
|
}
|
|
|
|
# No special cases needed - just use agent_key directly!
|
|
```
|
|
|
|
**Benefits of this approach:**
|
|
|
|
- Eliminates special-case logic scattered throughout the codebase
|
|
- Makes the code more maintainable and easier to understand
|
|
- Reduces the chance of bugs when adding new agents
|
|
- Tool checking "just works" without additional mappings
|
|
|
|
#### 7. Update Devcontainer files (Optional)
|
|
|
|
For agents that have VS Code extensions or require CLI installation, update the devcontainer configuration files:
|
|
|
|
##### VS Code Extension-based Agents
|
|
|
|
For agents available as VS Code extensions, add them to `.devcontainer/devcontainer.json`:
|
|
|
|
```json
|
|
{
|
|
"customizations": {
|
|
"vscode": {
|
|
"extensions": [
|
|
// ... existing extensions ...
|
|
// [New Agent Name]
|
|
"[New Agent Extension ID]"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
##### CLI-based Agents
|
|
|
|
For agents that require CLI tools, add installation commands to `.devcontainer/post-create.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
# Existing installations...
|
|
|
|
echo -e "\n🤖 Installing [New Agent Name] CLI..."
|
|
# run_command "npm install -g [agent-cli-package]@latest" # Example for node-based CLI
|
|
# or other installation instructions (must be non-interactive and compatible with Linux Debian "Trixie" or later)...
|
|
echo "✅ Done"
|
|
|
|
```
|
|
|
|
**Quick Tips:**
|
|
|
|
- **Extension-based agents**: Add to the `extensions` array in `devcontainer.json`
|
|
- **CLI-based agents**: Add installation scripts to `post-create.sh`
|
|
- **Hybrid agents**: May require both extension and CLI installation
|
|
- **Test thoroughly**: Ensure installations work in the devcontainer environment
|
|
|
|
## 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
|
|
- **Kiro CLI**: `kiro-cli` CLI
|
|
- **CodeBuddy CLI**: `codebuddy` CLI
|
|
- **Qoder CLI**: `qodercli` CLI
|
|
- **Amp**: `amp` CLI
|
|
- **SHAI**: `shai` CLI
|
|
- **Tabnine CLI**: `tabnine` CLI
|
|
- **Kimi Code**: `kimi` CLI
|
|
|
|
### IDE-Based Agents
|
|
|
|
Work within integrated development environments:
|
|
|
|
- **GitHub Copilot**: Built into VS Code/compatible editors
|
|
- **Windsurf**: Built into Windsurf IDE
|
|
- **IBM Bob**: Built into IBM Bob IDE
|
|
|
|
## Command File Formats
|
|
|
|
### Markdown Format
|
|
|
|
Used by: Claude, Cursor, opencode, Windsurf, Kiro CLI, Amp, SHAI, IBM Bob, Kimi Code, Qwen
|
|
|
|
**Standard format:**
|
|
|
|
```markdown
|
|
---
|
|
description: "Command description"
|
|
---
|
|
|
|
Command content with {SCRIPT} and $ARGUMENTS placeholders.
|
|
```
|
|
|
|
**GitHub Copilot Chat Mode format:**
|
|
|
|
```markdown
|
|
---
|
|
description: "Command description"
|
|
mode: speckit.command-name
|
|
---
|
|
|
|
Command content with {SCRIPT} and $ARGUMENTS placeholders.
|
|
```
|
|
|
|
### TOML Format
|
|
|
|
Used by: Gemini, Tabnine
|
|
|
|
```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/agents/`
|
|
- 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. **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.
|
|
2. **Forgetting update scripts**: Both bash and PowerShell scripts must be updated when adding new agents.
|
|
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.
|
|
4. **Wrong argument format**: Use correct placeholder format for each agent type (`$ARGUMENTS` for Markdown, `{{args}}` for TOML).
|
|
5. **Directory naming**: Follow agent-specific conventions exactly (check existing agents for patterns).
|
|
6. **Help text inconsistency**: Update all user-facing text consistently (help strings, docstrings, README, error messages).
|
|
|
|
## 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
|
|
- Verify the actual CLI tool name before adding to AGENT_CONFIG
|
|
|
|
---
|
|
|
|
*This documentation should be updated whenever new agents are added to maintain accuracy and completeness.*
|