Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ 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.0.22] - 2025-11-07
## [0.0.23] - 2026-02-03

### Added

- **Agent Skills Installation**: New `--agent-skills` CLI option to install Prompt.MD templates as agent skills following [agentskills.io specification](https://agentskills.io/specification)
- Skills are installed to `.agent/skills/<skill-name>/SKILL.md` directory structure
- Requires `--ai` flag to be specified
- Converts all 9 spec-kit command templates (specify, plan, tasks, implement, analyze, clarify, constitution, checklist, taskstoissues) to properly formatted SKILL.md files
- Each skill includes enhanced descriptions, compatibility information, and usage guidance
- Integrated into the initialize workflow with progress tracking

### Changed

- Updated `pyyaml` dependency for YAML frontmatter parsing
- Enhanced CLI help text and documentation with agent skills examples


- Support for VS Code/Copilot agents, and moving away from prompts to proper agents with hand-offs.
- Move to use `AGENTS.md` for Copilot workloads, since it's already supported out-of-the-box.
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ The `specify` command supports the following options:
| `--debug` | Flag | Enable detailed debug output for troubleshooting |
| `--github-token` | Option | GitHub token for API requests (or set GH_TOKEN/GITHUB_TOKEN env variable) |

| `--agent-skills` | Flag | Install Prompt.MD templates as agent skills in `.agent/skills/` directory (requires `--ai`) |
### Examples

```bash
Expand Down Expand Up @@ -238,6 +239,12 @@ specify init my-project --ai claude --debug
# Use GitHub token for API requests (helpful for corporate environments)
specify init my-project --ai claude --github-token ghp_your_token_here

# Install agent skills with the project
specify init my-project --ai claude --agent-skills

# Initialize in current directory with agent skills
specify init --here --ai gemini --agent-skills

# Check system requirements
specify check
```
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "specify-cli"
version = "0.0.22"
version = "0.0.23"
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
requires-python = ">=3.11"
dependencies = [
Expand All @@ -10,6 +10,7 @@ dependencies = [
"platformdirs",
"readchar",
"truststore>=0.10.4",
"pyyaml",
]

[project.scripts]
Expand Down
145 changes: 145 additions & 0 deletions src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import shutil
import shlex
import json
import yaml
from pathlib import Path
from typing import Optional, Tuple

Expand Down Expand Up @@ -942,6 +943,134 @@ def ensure_executable_scripts(project_path: Path, tracker: StepTracker | None =
for f in failures:
console.print(f" - {f}")


def install_agent_skills(project_path: Path, tracker: StepTracker = None) -> bool:
"""
Install Prompt.MD files from templates/commands/ as agent skills per agentskills.io spec.

Args:
project_path: Target project directory
tracker: Optional progress tracker

Returns:
True if installation successful, False otherwise
"""
# Find the spec-kit templates directory
# The templates are bundled with the package, so look relative to this file
script_dir = Path(__file__).parent.parent.parent # Go up from src/specify_cli/ to repo root
templates_dir = script_dir / "templates" / "commands"

if not templates_dir.exists():
if tracker:
tracker.error("agent-skills", "templates/commands not found")
else:
console.print("[yellow]Warning: templates/commands directory not found, skipping skills installation[/yellow]")
return False

# Get all markdown files
command_files = list(templates_dir.glob("*.md"))
if not command_files:
if tracker:
tracker.skip("agent-skills", "no command templates found")
else:
console.print("[yellow]No command templates found to install[/yellow]")
return False

# Create skills directory
skills_dir = project_path / ".agent" / "skills"
skills_dir.mkdir(parents=True, exist_ok=True)

if tracker:
tracker.add("agent-skills", f"Install {len(command_files)} agent skills")
tracker.start("agent-skills")

installed_count = 0
for command_file in command_files:
try:
# Read the template file
with open(command_file, 'r', encoding='utf-8') as f:
content = f.read()

# Parse YAML frontmatter
if content.startswith('---'):
parts = content.split('---', 2)
if len(parts) >= 3:
frontmatter = yaml.safe_load(parts[1])
body = parts[2].strip()
else:
frontmatter = {}
body = content
else:
frontmatter = {}
body = content

# Generate skill name: speckit-<command-name>
command_name = command_file.stem
skill_name = f"speckit-{command_name}"

# Create skill directory
skill_dir = skills_dir / skill_name
skill_dir.mkdir(parents=True, exist_ok=True)

# Generate enhanced description
original_desc = frontmatter.get('description', '')
if command_name == 'specify':
enhanced_desc = "Create or update feature specifications from natural language descriptions. Use when starting new features or refining requirements. Generates spec.md with user stories, functional requirements, and acceptance criteria following spec-driven development methodology."
elif command_name == 'plan':
enhanced_desc = "Generate technical implementation plans from feature specifications. Use after creating a spec to define architecture, tech stack, and implementation phases. Creates plan.md with detailed technical design."
elif command_name == 'tasks':
enhanced_desc = "Break down implementation plans into actionable task lists. Use after planning to create a structured task breakdown. Generates tasks.md with ordered, dependency-aware tasks."
elif command_name == 'implement':
enhanced_desc = "Execute all tasks from the task breakdown to build the feature. Use after task generation to systematically implement the planned solution following TDD approach where applicable."
elif command_name == 'analyze':
enhanced_desc = "Perform cross-artifact consistency analysis across spec.md, plan.md, and tasks.md. Use after task generation to identify gaps, duplications, and inconsistencies before implementation."
elif command_name == 'clarify':
enhanced_desc = "Structured clarification workflow for underspecified requirements. Use before planning to resolve ambiguities through coverage-based questioning. Records answers in spec clarifications section."
elif command_name == 'constitution':
enhanced_desc = "Create or update project governing principles and development guidelines. Use at project start to establish code quality, testing standards, and architectural constraints that guide all development."
elif command_name == 'checklist':
enhanced_desc = "Generate custom quality checklists for validating requirements completeness and clarity. Use to create unit tests for English that ensure spec quality before implementation."
elif command_name == 'taskstoissues':
enhanced_desc = "Convert tasks from tasks.md into GitHub issues. Use after task breakdown to track work items in GitHub project management."
else:
enhanced_desc = original_desc or f"Spec-kit workflow command: {command_name}"

# Create SKILL.md following agentskills.io spec
skill_content = f"""---
name: {skill_name}
description: {enhanced_desc}
compatibility: Requires git and spec-kit project structure with .specify/ directory
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent naming: the directory is referred to as .specify/ here but the actual skills are installed to .agent/ directory. This should be clarified or corrected to avoid confusion.

Suggested change
compatibility: Requires git and spec-kit project structure with .specify/ directory
compatibility: Requires git and spec-kit project structure with .agent/skills/ directory

Copilot uses AI. Check for mistakes.
---

# Speckit {command_name.title()} Skill

{body}
"""

# Write SKILL.md
skill_file = skill_dir / "SKILL.md"
with open(skill_file, 'w', encoding='utf-8') as f:
f.write(skill_content)

installed_count += 1

except Exception as e:
console.print(f"[yellow]Warning: Failed to install skill {command_name}: {e}[/yellow]")
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message references command_name which may not be defined if the exception occurs before line 1008. Consider using command_file.stem or wrapping in a try-except to ensure the variable is always available.

Suggested change
console.print(f"[yellow]Warning: Failed to install skill {command_name}: {e}[/yellow]")
skill_label = command_name if 'command_name' in locals() else command_file.stem
console.print(f"[yellow]Warning: Failed to install skill {skill_label}: {e}[/yellow]")

Copilot uses AI. Check for mistakes.
continue

if tracker:
if installed_count > 0:
tracker.complete("agent-skills", f"{installed_count} skills installed")
else:
tracker.error("agent-skills", "no skills installed")
else:
if installed_count > 0:
console.print(f"[green]✓[/green] Installed {installed_count} agent skills to .agent/skills/")
else:
console.print("[yellow]No skills were installed[/yellow]")

return installed_count > 0

@app.command()
def init(
project_name: str = typer.Argument(None, help="Name for your new project directory (optional if using --here, or use '.' for current directory)"),
Expand All @@ -954,6 +1083,7 @@ def init(
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"),
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)"),
agent_skills: bool = typer.Option(False, "--agent-skills", help="Install Prompt.MD templates as agent skills (requires --ai)"),
):
"""
Initialize a new Specify project from the latest template.
Expand Down Expand Up @@ -994,6 +1124,13 @@ def init(
console.print("[red]Error:[/red] Must specify either a project name, use '.' for current directory, or use --here flag")
raise typer.Exit(1)

# Validate --agent-skills requires --ai
if agent_skills and not ai_assistant:
console.print("[red]Error:[/red] --agent-skills requires --ai to be specified")
console.print("[yellow]Usage:[/yellow] specify init <project> --ai <agent> --agent-skills")
raise typer.Exit(1)


if here:
project_name = Path.cwd().name
project_path = Path.cwd()
Expand Down Expand Up @@ -1128,6 +1265,10 @@ def init(

ensure_executable_scripts(project_path, tracker=tracker)

# Install agent skills if requested
if agent_skills:
install_agent_skills(project_path, tracker=tracker)

if not no_git:
tracker.start("git")
if is_git_repo(project_path):
Expand Down Expand Up @@ -1240,6 +1381,8 @@ def init(
console.print()
console.print(enhancements_panel)



@app.command()
def check():
"""Check that all required tools are installed."""
Expand Down Expand Up @@ -1282,6 +1425,8 @@ def check():
if not any(agent_results.values()):
console.print("[dim]Tip: Install an AI assistant for the best experience[/dim]")



@app.command()
def version():
"""Display version and system information."""
Expand Down