-
Notifications
You must be signed in to change notification settings - Fork 6.1k
Add generic agent support (bring your own agent) #1639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -48,6 +48,7 @@ Specify supports multiple AI agents by generating agent-specific command files a | |||||||
| | **Amp** | `.agents/commands/` | Markdown | `amp` | Amp CLI | | ||||||||
| | **SHAI** | `.shai/commands/` | Markdown | `shai` | SHAI CLI | | ||||||||
| | **IBM Bob** | `.bob/commands/` | Markdown | N/A (IDE-based) | IBM Bob IDE | | ||||||||
|
||||||||
| | **IBM Bob** | `.bob/commands/` | Markdown | N/A (IDE-based) | IBM Bob IDE | | |
| | **IBM Bob** | `.bob/commands/` | Markdown | N/A (IDE-based) | IBM Bob IDE | | |
| | **Antigravity** | `.agent/` | Markdown | N/A (IDE-based) | Antigravity IDE | |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,7 +8,7 @@ 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.1] - 2026-02-13 | ||||||||||||||
| ## [0.1.1] - 2026-02-17 | ||||||||||||||
|
|
||||||||||||||
| ### Added | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -22,6 +22,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||||||||||||
| - **Existing repos** (`--here`): pre-existing command files are preserved — no breaking changes | ||||||||||||||
| - `pyyaml` dependency (already present) used for YAML frontmatter parsing | ||||||||||||||
| - **Unit tests** for `install_ai_skills`, `_get_skills_dir`, and `--ai-skills` CLI validation (51 test cases covering all 18 supported agents) | ||||||||||||||
| - **Generic Agent Support**: Added `--ai generic` option for unsupported AI agents ("bring your own agent") | ||||||||||||||
| - Requires `--ai-commands-dir <path>` to specify where the agent reads commands from | ||||||||||||||
| - Generates Markdown commands with `$ARGUMENTS` format (compatible with most agents) | ||||||||||||||
| - Example: `specify init my-project --ai generic --ai-commands-dir .myagent/commands/` | ||||||||||||||
| - Enables users to start with Spec Kit immediately while their agent awaits formal support | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| - **Antigravity Agent (`agy`) Support**: Added first-class support for the Antigravity agent | |
| - Use via `--ai agy` to generate commands tailored for the Antigravity agent | |
| - Integrated into agent configuration, release scripts, and agent context handling | |
| - Recognized as a fully supported AI agent alongside existing agents |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -233,6 +233,12 @@ def _format_rate_limit_error(status_code: int, headers: httpx.Headers, url: str) | |||||||||||||||||||||||||
| "install_url": None, # IDE-based | ||||||||||||||||||||||||||
| "requires_cli": False, | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| "generic": { | ||||||||||||||||||||||||||
| "name": "Generic (bring your own agent)", | ||||||||||||||||||||||||||
| "folder": None, # Set dynamically via --ai-commands-dir | ||||||||||||||||||||||||||
| "install_url": None, | ||||||||||||||||||||||||||
| "requires_cli": False, | ||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| SCRIPT_TYPE_CHOICES = {"sh": "POSIX Shell (bash/zsh)", "ps": "PowerShell"} | ||||||||||||||||||||||||||
|
|
@@ -1188,7 +1194,8 @@ def install_ai_skills(project_path: Path, selected_ai: str, tracker: StepTracker | |||||||||||||||||||||||||
| @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)"), | ||||||||||||||||||||||||||
| ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor-agent, qwen, opencode, codex, windsurf, kilocode, auggie, codebuddy, amp, shai, q, agy, bob, or qoder "), | ||||||||||||||||||||||||||
| ai_assistant: str = typer.Option(None, "--ai", help="AI assistant to use: claude, gemini, copilot, cursor-agent, qwen, opencode, codex, windsurf, kilocode, auggie, codebuddy, amp, shai, q, agy, bob, qoder, or generic (requires --ai-commands-dir)"), | ||||||||||||||||||||||||||
| ai_commands_dir: str = typer.Option(None, "--ai-commands-dir", help="Directory for agent command files (required with --ai generic, e.g. .myagent/commands/)"), | ||||||||||||||||||||||||||
| script_type: str = typer.Option(None, "--script", help="Script type to use: sh or ps"), | ||||||||||||||||||||||||||
| ignore_agent_tools: bool = typer.Option(False, "--ignore-agent-tools", help="Skip checks for AI agent tools like Claude Code"), | ||||||||||||||||||||||||||
| no_git: bool = typer.Option(False, "--no-git", help="Skip git repository initialization"), | ||||||||||||||||||||||||||
|
|
@@ -1224,6 +1231,7 @@ def init( | |||||||||||||||||||||||||
| specify init --here --force # Skip confirmation when current directory not empty | ||||||||||||||||||||||||||
| specify init my-project --ai claude --ai-skills # Install agent skills | ||||||||||||||||||||||||||
| specify init --here --ai gemini --ai-skills | ||||||||||||||||||||||||||
| specify init my-project --ai generic --ai-commands-dir .myagent/commands/ # Unsupported agent | ||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| show_banner() | ||||||||||||||||||||||||||
|
|
@@ -1308,6 +1316,16 @@ def init( | |||||||||||||||||||||||||
| "copilot" | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # Validate --ai-commands-dir usage | ||||||||||||||||||||||||||
| if selected_ai == "generic": | ||||||||||||||||||||||||||
| if not ai_commands_dir: | ||||||||||||||||||||||||||
| console.print("[red]Error:[/red] --ai-commands-dir is required when using --ai generic") | ||||||||||||||||||||||||||
| console.print("[dim]Example: specify init my-project --ai generic --ai-commands-dir .myagent/commands/[/dim]") | ||||||||||||||||||||||||||
| raise typer.Exit(1) | ||||||||||||||||||||||||||
| elif ai_commands_dir: | ||||||||||||||||||||||||||
| console.print(f"[red]Error:[/red] --ai-commands-dir can only be used with --ai generic (not '{selected_ai}')") | ||||||||||||||||||||||||||
| raise typer.Exit(1) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| if not ignore_agent_tools: | ||||||||||||||||||||||||||
| agent_config = AGENT_CONFIG.get(selected_ai) | ||||||||||||||||||||||||||
| if agent_config and agent_config["requires_cli"]: | ||||||||||||||||||||||||||
|
|
@@ -1383,6 +1401,18 @@ def init( | |||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| download_and_extract_template(project_path, selected_ai, selected_script, here, verbose=False, tracker=tracker, client=local_client, debug=debug, github_token=github_token) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| # For generic agent, rename placeholder directory to user-specified path | ||||||||||||||||||||||||||
| if selected_ai == "generic" and ai_commands_dir: | ||||||||||||||||||||||||||
| placeholder_dir = project_path / ".speckit" / "commands" | ||||||||||||||||||||||||||
| target_dir = project_path / ai_commands_dir | ||||||||||||||||||||||||||
|
Comment on lines
+1406
to
+1407
|
||||||||||||||||||||||||||
| placeholder_dir = project_path / ".speckit" / "commands" | |
| target_dir = project_path / ai_commands_dir | |
| # Ensure ai_commands_dir is a safe, relative path inside the project directory | |
| ai_path = Path(ai_commands_dir) | |
| if ai_path.is_absolute() or ".." in ai_path.parts: | |
| raise ValueError("ai_commands_dir must be a relative path without '..' components.") | |
| project_root = project_path.resolve() | |
| target_dir = (project_root / ai_path).resolve() | |
| # Ensure the target directory is inside the project directory | |
| if target_dir != project_root and project_root not in target_dir.parents: | |
| raise ValueError("ai_commands_dir must point inside the project directory.") | |
| placeholder_dir = project_path / ".speckit" / "commands" |
Copilot
AI
Feb 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new generic agent functionality, including --ai-commands-dir validation and directory renaming logic, lacks test coverage. Consider adding tests that verify: 1) --ai-commands-dir is required when using --ai generic, 2) --ai-commands-dir is rejected with other agents, 3) the placeholder directory is correctly renamed to the user-specified path, 4) proper cleanup of empty .speckit directory, and 5) edge cases like invalid paths or existing target directories.
This issue also appears on line 1100 of the same file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PowerShell release packaging script is missing the 'agy' (Antigravity) agent that was added to the bash version (create-release-packages.sh line 233). This inconsistency means the PowerShell script cannot build agy template packages. The 'agy' agent should be added to the $AllAgents array, and a corresponding case should be added to the Build-Variant switch statement (similar to lines 218-220 in the bash version).