Fix #1658: Add commands_subdir field to support non-standard agent directory structures (#1660)

- Added commands_subdir field to AGENT_CONFIG for all agents
- Updated install_ai_skills() to use commands_subdir instead of hardcoded 'commands'
- Fixed --ai-skills flag for copilot, opencode, windsurf, codex, kilocode, q, and agy
- Bumped version to 0.1.5
- Updated AGENTS.md documentation with new field

Affected agents now correctly locate their command templates:
- copilot: .github/agents/
- opencode: .opencode/command/ (singular)
- windsurf: .windsurf/workflows/
- codex: .codex/prompts/
- kilocode: .kilocode/workflows/
- q: .amazonq/prompts/
- agy: .agent/workflows/

All 51 tests pass.
This commit is contained in:
Manfred Riem
2026-02-21 08:05:58 -06:00
committed by GitHub
parent 68d1d3a0fc
commit 6f523ede22
4 changed files with 38 additions and 4 deletions

View File

@@ -66,6 +66,7 @@ AGENT_CONFIG = {
"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
},
@@ -83,6 +84,10 @@ This eliminates the need for special-case mappings throughout the codebase.
- `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, agy), `"prompts"` (codex, q), `"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

View File

@@ -7,6 +7,15 @@ All notable changes to the Specify CLI and templates are documented here.
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).
## [0.1.5] - Unreleased
### Fixed
- **AI Skills Installation Bug (#1658)**: Fixed `--ai-skills` flag not generating skill files for GitHub Copilot and other agents with non-standard command directory structures
- Added `commands_subdir` field to `AGENT_CONFIG` to explicitly specify the subdirectory name for each agent
- Affected agents now work correctly: copilot (`.github/agents/`), opencode (`.opencode/command/`), windsurf (`.windsurf/workflows/`), codex (`.codex/prompts/`), kilocode (`.kilocode/workflows/`), q (`.amazonq/prompts/`), and agy (`.agent/workflows/`)
- The `install_ai_skills()` function now uses the correct path for all agents instead of assuming `commands/` for everyone
## [0.1.4] - Unreleased
### Fixed

View File

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

View File

@@ -123,119 +123,138 @@ def _format_rate_limit_error(status_code: int, headers: httpx.Headers, url: str)
return "\n".join(lines)
# Agent configuration with name, folder, install URL, and CLI tool requirement
# Agent configuration with name, folder, install URL, CLI tool requirement, and commands subdirectory
AGENT_CONFIG = {
"copilot": {
"name": "GitHub Copilot",
"folder": ".github/",
"commands_subdir": "agents", # Special: uses agents/ not commands/
"install_url": None, # IDE-based, no CLI check needed
"requires_cli": False,
},
"claude": {
"name": "Claude Code",
"folder": ".claude/",
"commands_subdir": "commands",
"install_url": "https://docs.anthropic.com/en/docs/claude-code/setup",
"requires_cli": True,
},
"gemini": {
"name": "Gemini CLI",
"folder": ".gemini/",
"commands_subdir": "commands",
"install_url": "https://github.com/google-gemini/gemini-cli",
"requires_cli": True,
},
"cursor-agent": {
"name": "Cursor",
"folder": ".cursor/",
"commands_subdir": "commands",
"install_url": None, # IDE-based
"requires_cli": False,
},
"qwen": {
"name": "Qwen Code",
"folder": ".qwen/",
"commands_subdir": "commands",
"install_url": "https://github.com/QwenLM/qwen-code",
"requires_cli": True,
},
"opencode": {
"name": "opencode",
"folder": ".opencode/",
"commands_subdir": "command", # Special: singular 'command' not 'commands'
"install_url": "https://opencode.ai",
"requires_cli": True,
},
"codex": {
"name": "Codex CLI",
"folder": ".codex/",
"commands_subdir": "prompts", # Special: uses prompts/ not commands/
"install_url": "https://github.com/openai/codex",
"requires_cli": True,
},
"windsurf": {
"name": "Windsurf",
"folder": ".windsurf/",
"commands_subdir": "workflows", # Special: uses workflows/ not commands/
"install_url": None, # IDE-based
"requires_cli": False,
},
"kilocode": {
"name": "Kilo Code",
"folder": ".kilocode/",
"commands_subdir": "workflows", # Special: uses workflows/ not commands/
"install_url": None, # IDE-based
"requires_cli": False,
},
"auggie": {
"name": "Auggie CLI",
"folder": ".augment/",
"commands_subdir": "commands",
"install_url": "https://docs.augmentcode.com/cli/setup-auggie/install-auggie-cli",
"requires_cli": True,
},
"codebuddy": {
"name": "CodeBuddy",
"folder": ".codebuddy/",
"commands_subdir": "commands",
"install_url": "https://www.codebuddy.ai/cli",
"requires_cli": True,
},
"qodercli": {
"name": "Qoder CLI",
"folder": ".qoder/",
"commands_subdir": "commands",
"install_url": "https://qoder.com/cli",
"requires_cli": True,
},
"roo": {
"name": "Roo Code",
"folder": ".roo/",
"commands_subdir": "commands",
"install_url": None, # IDE-based
"requires_cli": False,
},
"q": {
"name": "Amazon Q Developer CLI",
"folder": ".amazonq/",
"commands_subdir": "prompts", # Special: uses prompts/ not commands/
"install_url": "https://aws.amazon.com/developer/learning/q-developer-cli/",
"requires_cli": True,
},
"amp": {
"name": "Amp",
"folder": ".agents/",
"commands_subdir": "commands",
"install_url": "https://ampcode.com/manual#install",
"requires_cli": True,
},
"shai": {
"name": "SHAI",
"folder": ".shai/",
"commands_subdir": "commands",
"install_url": "https://github.com/ovh/shai",
"requires_cli": True,
},
"agy": {
"name": "Antigravity",
"folder": ".agent/",
"commands_subdir": "workflows", # Special: uses workflows/ not commands/
"install_url": None, # IDE-based
"requires_cli": False,
},
"bob": {
"name": "IBM Bob",
"folder": ".bob/",
"commands_subdir": "commands",
"install_url": None, # IDE-based
"requires_cli": False,
},
"generic": {
"name": "Generic (bring your own agent)",
"folder": None, # Set dynamically via --ai-commands-dir
"commands_subdir": "commands",
"install_url": None,
"requires_cli": False,
},
@@ -1056,10 +1075,11 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
# download_and_extract_template() already placed the .md files here.
agent_config = AGENT_CONFIG.get(selected_ai, {})
agent_folder = agent_config.get("folder", "")
commands_subdir = agent_config.get("commands_subdir", "commands")
if agent_folder:
templates_dir = project_path / agent_folder.rstrip("/") / "commands"
templates_dir = project_path / agent_folder.rstrip("/") / commands_subdir
else:
templates_dir = project_path / "commands"
templates_dir = project_path / commands_subdir
if not templates_dir.exists() or not any(templates_dir.glob("*.md")):
# Fallback: try the repo-relative path (for running from source checkout)