Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 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
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ uvx --from git+https://github.com/github/spec-kit.git specify init --here --ai c

### 2. Establish project principles

Launch your AI assistant in the project directory. The `/speckit.*` commands are available in the assistant.
Launch your AI assistant in the project directory. Most agents expose spec-kit as `/speckit.*` slash commands; Codex CLI in skills mode uses `$speckit.*` instead.

Use the **`/speckit.constitution`** command to create your project's governing principles and development guidelines that will guide all subsequent development.

Expand Down Expand Up @@ -173,7 +173,7 @@ See Spec-Driven Development in action across different scenarios with these comm
| [Auggie CLI](https://docs.augmentcode.com/cli/overview) | ✅ | |
| [Claude Code](https://www.anthropic.com/claude-code) | ✅ | |
| [CodeBuddy CLI](https://www.codebuddy.ai/cli) | ✅ | |
| [Codex CLI](https://github.com/openai/codex) | ✅ | |
| [Codex CLI](https://github.com/openai/codex) | ✅ | Requires `--ai-skills`. Codex recommends [skills](https://developers.openai.com/codex/skills) and treats [custom prompts](https://developers.openai.com/codex/custom-prompts) as deprecated. Spec-kit installs Codex skills into `.agents/skills` and invokes them as `$speckit.<command>`. |
| [Cursor](https://cursor.sh/) | ✅ | |
| [Gemini CLI](https://github.com/google-gemini/gemini-cli) | ✅ | |
| [GitHub Copilot](https://code.visualstudio.com/) | ✅ | |
Expand Down Expand Up @@ -257,6 +257,9 @@ specify init my-project --ai bob
# Initialize with Pi Coding Agent support
specify init my-project --ai pi

# Initialize with Codex CLI support
specify init my-project --ai codex --ai-skills

# Initialize with Antigravity support
specify init my-project --ai agy --ai-skills

Expand Down Expand Up @@ -297,7 +300,9 @@ specify check

### Available Slash Commands

After running `specify init`, your AI coding agent will have access to these slash commands for structured development:
After running `specify init`, your AI coding agent will have access to these slash commands for structured development.

For Codex CLI, `--ai-skills` installs spec-kit as agent skills instead of slash-command prompt files. In Codex skills mode, invoke spec-kit as `$speckit.constitution`, `$speckit.specify`, `$speckit.plan`, `$speckit.tasks`, and `$speckit.implement`.

#### Core Commands

Expand Down Expand Up @@ -483,11 +488,11 @@ specify init <project_name> --ai copilot

# Or in current directory:
specify init . --ai claude
specify init . --ai codex
specify init . --ai codex --ai-skills

# or use --here flag
specify init --here --ai claude
specify init --here --ai codex
specify init --here --ai codex --ai-skills

# Force merge into a non-empty current directory
specify init . --force --ai claude
Expand Down
95 changes: 55 additions & 40 deletions src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1409,20 +1409,35 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker
return installed_count > 0 or skipped_count > 0


def _handle_agy_deprecation(console: Console) -> None:
"""
Print the deprecation error for the Antigravity (agy) agent and exit.

Context for future AI reviewers (e.g., GitHub Copilot):
- Prior to Antigravity v1.20.5, users could rely on explicit agent command definitions generated by this tool.
- v1.20.5 removed this "command support" in favor of "Agent Skills".
- `specify_cli` handles this by throwing a fail-fast deprecation error if `--ai agy` is
invoked without the accompanying `--ai-skills` flag. Users are instructed to add
the skills flag to generate agent skills templates instead.
"""
console.print("\n[red]Error:[/red] Explicit command support was deprecated in Antigravity version 1.20.5.")
AGENT_SKILLS_MIGRATIONS = {
"agy": {
"error": "Explicit command support was deprecated in Antigravity version 1.20.5.",
"usage": "specify init <project> --ai agy --ai-skills",
"interactive_note": (
"'agy' was selected interactively; enabling [cyan]--ai-skills[/cyan] "
"automatically for compatibility (explicit .agent/commands usage is deprecated)."
),
},
"codex": {
"error": (
"Custom prompt-based spec-kit initialization is deprecated for Codex CLI; "
"use agent skills instead."
),
"usage": "specify init <project> --ai codex --ai-skills",
"interactive_note": (
"'codex' was selected interactively; enabling [cyan]--ai-skills[/cyan] "
"automatically for compatibility (.agents/skills is the recommended Codex layout)."
),
},
}


def _handle_agent_skills_migration(console: Console, agent_key: str) -> None:
"""Print a fail-fast migration error for agents that now require skills."""
migration = AGENT_SKILLS_MIGRATIONS[agent_key]
console.print(f"\n[red]Error:[/red] {migration['error']}")
console.print("Please use [cyan]--ai-skills[/cyan] when initializing to install templates as agent skills instead.")
console.print("[yellow]Usage:[/yellow] specify init <project> --ai agy --ai-skills")
console.print(f"[yellow]Usage:[/yellow] {migration['usage']}")
raise typer.Exit(1)

@app.command()
Expand Down Expand Up @@ -1460,7 +1475,7 @@ def init(
specify init . --ai claude # Initialize in current directory
specify init . # Initialize in current directory (interactive AI selection)
specify init --here --ai claude # Alternative syntax for current directory
specify init --here --ai codex
specify init --here --ai codex --ai-skills
specify init --here --ai codebuddy
specify init --here --ai vibe # Initialize with Mistral Vibe support
specify init --here
Expand Down Expand Up @@ -1550,24 +1565,16 @@ def init(
"copilot"
)

# [DEPRECATION NOTICE: Antigravity (agy)]
# As of Antigravity v1.20.5, traditional CLI "command" support was fully removed
# in favor of "Agent Skills" (SKILL.md files under <agent_folder>/skills/<skill_name>/).
# Because 'specify_cli' historically populated .agent/commands/, we now must explicitly
# enforce the `--ai-skills` flag for `agy` to ensure valid template generation.
if selected_ai == "agy" and not ai_skills:
# If agy was selected interactively (no --ai provided), automatically enable
# Agents that have moved from explicit commands/prompts to agent skills.
if selected_ai in AGENT_SKILLS_MIGRATIONS and not ai_skills:
# If selected interactively (no --ai provided), automatically enable
# ai_skills so the agent remains usable without requiring an extra flag.
# Preserve deprecation behavior only for explicit '--ai agy' without skills.
# Preserve fail-fast behavior only for explicit '--ai <agent>' without skills.
if ai_assistant:
_handle_agy_deprecation(console)
_handle_agent_skills_migration(console, selected_ai)
else:
ai_skills = True
console.print(
"\n[yellow]Note:[/yellow] 'agy' was selected interactively; "
"enabling [cyan]--ai-skills[/cyan] automatically for compatibility "
"(explicit .agent/commands usage is deprecated)."
)
console.print(f"\n[yellow]Note:[/yellow] {AGENT_SKILLS_MIGRATIONS[selected_ai]['interactive_note']}")

# Validate --ai-commands-dir usage
if selected_ai == "generic":
Expand Down Expand Up @@ -1836,8 +1843,8 @@ def init(
steps_lines.append("1. You're already in the project directory!")
step_num = 2

# Add Codex-specific setup step if needed
if selected_ai == "codex":
# Add Codex-specific setup step when prompt-based Codex templates are in use.
if selected_ai == "codex" and not ai_skills:
codex_path = project_path / ".codex"
quoted_path = shlex.quote(str(codex_path))
if os.name == "nt": # Windows
Expand All @@ -1847,14 +1854,21 @@ def init(

steps_lines.append(f"{step_num}. Set [cyan]CODEX_HOME[/cyan] environment variable before running Codex: [cyan]{cmd}[/cyan]")
step_num += 1
elif selected_ai == "codex" and ai_skills:
steps_lines.append(f"{step_num}. Start Codex in this project directory; spec-kit skills were installed to [cyan].agents/skills[/cyan]")
step_num += 1

codex_skill_mode = selected_ai == "codex" and ai_skills
command_prefix = "$" if codex_skill_mode else "/"
usage_label = "skills" if codex_skill_mode else "slash commands"

steps_lines.append(f"{step_num}. Start using slash commands with your AI agent:")
steps_lines.append(f"{step_num}. Start using {usage_label} with your AI agent:")

steps_lines.append(" 2.1 [cyan]/speckit.constitution[/] - Establish project principles")
steps_lines.append(" 2.2 [cyan]/speckit.specify[/] - Create baseline specification")
steps_lines.append(" 2.3 [cyan]/speckit.plan[/] - Create implementation plan")
steps_lines.append(" 2.4 [cyan]/speckit.tasks[/] - Generate actionable tasks")
steps_lines.append(" 2.5 [cyan]/speckit.implement[/] - Execute implementation")
steps_lines.append(f" {step_num}.1 [cyan]{command_prefix}speckit.constitution[/] - Establish project principles")
steps_lines.append(f" {step_num}.2 [cyan]{command_prefix}speckit.specify[/] - Create baseline specification")
steps_lines.append(f" {step_num}.3 [cyan]{command_prefix}speckit.plan[/] - Create implementation plan")
steps_lines.append(f" {step_num}.4 [cyan]{command_prefix}speckit.tasks[/] - Generate actionable tasks")
steps_lines.append(f" {step_num}.5 [cyan]{command_prefix}speckit.implement[/] - Execute implementation")

steps_panel = Panel("\n".join(steps_lines), title="Next Steps", border_style="cyan", padding=(1,2))
console.print()
Expand All @@ -1863,11 +1877,12 @@ def init(
enhancement_lines = [
"Optional commands that you can use for your specs [bright_black](improve quality & confidence)[/bright_black]",
Comment thread
RbBtSn0w marked this conversation as resolved.
Outdated
"",
"○ [cyan]/speckit.clarify[/] [bright_black](optional)[/bright_black] - Ask structured questions to de-risk ambiguous areas before planning (run before [cyan]/speckit.plan[/] if used)",
"○ [cyan]/speckit.analyze[/] [bright_black](optional)[/bright_black] - Cross-artifact consistency & alignment report (after [cyan]/speckit.tasks[/], before [cyan]/speckit.implement[/])",
"○ [cyan]/speckit.checklist[/] [bright_black](optional)[/bright_black] - Generate quality checklists to validate requirements completeness, clarity, and consistency (after [cyan]/speckit.plan[/])"
f"○ [cyan]{command_prefix}speckit.clarify[/] [bright_black](optional)[/bright_black] - Ask structured questions to de-risk ambiguous areas before planning (run before [cyan]{command_prefix}speckit.plan[/] if used)",
f"○ [cyan]{command_prefix}speckit.analyze[/] [bright_black](optional)[/bright_black] - Cross-artifact consistency & alignment report (after [cyan]{command_prefix}speckit.tasks[/], before [cyan]{command_prefix}speckit.implement[/])",
f"○ [cyan]{command_prefix}speckit.checklist[/] [bright_black](optional)[/bright_black] - Generate quality checklists to validate requirements completeness, clarity, and consistency (after [cyan]{command_prefix}speckit.plan[/])"
]
enhancements_panel = Panel("\n".join(enhancement_lines), title="Enhancement Commands", border_style="cyan", padding=(1,2))
enhancements_title = "Enhancement Skills" if codex_skill_mode else "Enhancement Commands"
enhancements_panel = Panel("\n".join(enhancement_lines), title=enhancements_title, border_style="cyan", padding=(1,2))
console.print()
console.print(enhancements_panel)

Expand Down
45 changes: 45 additions & 0 deletions tests/test_ai_skills.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,17 @@ def test_agy_without_ai_skills_fails(self):
assert "Explicit command support was deprecated in Antigravity version 1.20.5." in result.output
assert "--ai-skills" in result.output

def test_codex_without_ai_skills_fails(self):
"""--ai codex without --ai-skills should fail with exit code 1."""
from typer.testing import CliRunner

runner = CliRunner()
result = runner.invoke(app, ["init", "test-proj", "--ai", "codex"])

assert result.exit_code == 1
assert "Custom prompt-based spec-kit initialization is deprecated for Codex CLI" in result.output
assert "--ai-skills" in result.output

def test_interactive_agy_without_ai_skills_prompts_skills(self, monkeypatch):
"""Interactive selector returning agy without --ai-skills should automatically enable --ai-skills."""
from typer.testing import CliRunner
Expand Down Expand Up @@ -879,6 +890,40 @@ def _fake_select_with_arrows(*args, **kwargs):
assert result.exit_code == 0
assert "Explicit command support was deprecated" not in result.output

def test_interactive_codex_without_ai_skills_enables_skills(self, monkeypatch):
"""Interactive selector returning codex without --ai-skills should automatically enable --ai-skills."""
from typer.testing import CliRunner

def _fake_select_with_arrows(*args, **kwargs):
options = kwargs.get("options")
if options is None and len(args) >= 1:
options = args[0]

if isinstance(options, dict) and "codex" in options:
return "codex"
if isinstance(options, (list, tuple)) and "codex" in options:
return "codex"

if isinstance(options, dict) and options:
return next(iter(options.keys()))
if isinstance(options, (list, tuple)) and options:
return options[0]

return None

monkeypatch.setattr("specify_cli.select_with_arrows", _fake_select_with_arrows)
monkeypatch.setattr("specify_cli.download_and_extract_template", lambda *args, **kwargs: None)

runner = CliRunner()
with runner.isolated_filesystem():
result = runner.invoke(app, ["init", "test-proj", "--no-git", "--ignore-agent-tools"])

assert result.exit_code == 0
assert "Custom prompt-based spec-kit initialization is deprecated for Codex CLI" not in result.output
assert ".agents/skills" in result.output
Comment thread
RbBtSn0w marked this conversation as resolved.
assert "$speckit.constitution" in result.output
assert "/speckit.constitution" not in result.output

def test_ai_skills_flag_appears_in_help(self):
"""--ai-skills should appear in init --help output."""
from typer.testing import CliRunner
Expand Down
Loading