diff --git a/.github/ISSUE_TEMPLATE/agent_request.yml b/.github/ISSUE_TEMPLATE/agent_request.yml index 15f3f10c28..4a750bc23c 100644 --- a/.github/ISSUE_TEMPLATE/agent_request.yml +++ b/.github/ISSUE_TEMPLATE/agent_request.yml @@ -8,7 +8,7 @@ body: value: | Thanks for requesting a new agent! Before submitting, please check if the agent is already supported. - **Currently supported agents**: Amp, Antigravity, Auggie CLI, Claude Code, Cline, CodeBuddy, Codex CLI, Cursor, Devin for Terminal, Firebender, Forge, Gemini CLI, GitHub Copilot, Goose, Hermes Agent, IBM Bob, Junie, Kilo Code, Kimi Code, Kiro CLI, Lingma, Mistral Vibe, Oh My Pi, opencode, Pi Coding Agent, Qoder CLI, Qwen Code, Roo Code, RovoDev ACLI, SHAI, Tabnine CLI, Trae, Windsurf, ZCode, Zed + **Currently supported agents**: Amp, Antigravity, Auggie CLI, Claude Code, Cline, CodeBuddy, Codex CLI, Cursor, Devin for Terminal, Firebender, Forge, Gemini CLI, GitHub Copilot, Goose, Hermes Agent, IBM Bob, Junie, Kilo Code, Kimi Code, Kiro CLI, Lingma, Mistral Vibe, Oh My Pi, opencode, Pi Coding Agent, Qoder CLI, Qwen Code, Roo Code, RovoDev ACLI, SHAI, Tabnine CLI, Trae, ZCode, Zed - type: input id: agent-name diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1e3d5f14cb..193f0105ed 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -94,7 +94,6 @@ body: - SHAI - Tabnine CLI - Trae - - Windsurf - ZCode - Zed - Not applicable diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 83f3169c37..a9766bca58 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -88,7 +88,6 @@ body: - SHAI - Tabnine CLI - Trae - - Windsurf - ZCode - Zed - Not applicable diff --git a/AGENTS.md b/AGENTS.md index 68d8641e4d..8b5afd4e82 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -23,7 +23,7 @@ src/specify_cli/integrations/ │ └── __init__.py # ClaudeIntegration class ├── gemini/ # Example: TomlIntegration subclass │ └── __init__.py -├── windsurf/ # Example: MarkdownIntegration subclass +├── kilocode/ # Example: MarkdownIntegration subclass │ └── __init__.py ├── copilot/ # Example: IntegrationBase subclass (custom setup) │ └── __init__.py @@ -52,25 +52,25 @@ Most agents only need `MarkdownIntegration` — a minimal subclass with zero met Create `src/specify_cli/integrations//__init__.py`, where `` is the Python-safe directory name derived from ``: use the key as-is when it contains no hyphens (e.g., key `"gemini"` → `gemini/`), or replace hyphens with underscores when it does (e.g., key `"kiro-cli"` → `kiro_cli/`). The `IntegrationBase.key` class attribute always retains the original hyphenated value, since that is what the CLI and registry use. For CLI-based integrations (`requires_cli: True`), the `key` should match the actual CLI tool name (the executable users install and run) so CLI checks can resolve it correctly. For IDE-based integrations (`requires_cli: False`), use the canonical integration identifier instead. -**Minimal example — Markdown agent (Windsurf):** +**Minimal example — Markdown agent (Kilo Code):** ```python -"""Windsurf IDE integration.""" +"""Kilo Code IDE integration.""" from ..base import MarkdownIntegration -class WindsurfIntegration(MarkdownIntegration): - key = "windsurf" +class KilocodeIntegration(MarkdownIntegration): + key = "kilocode" config = { - "name": "Windsurf", - "folder": ".windsurf/", + "name": "Kilo Code", + "folder": ".kilocode/", "commands_subdir": "workflows", "install_url": None, "requires_cli": False, } registrar_config = { - "dir": ".windsurf/workflows", + "dir": ".kilocode/workflows", "format": "markdown", "args": "$ARGUMENTS", "extension": ".md", @@ -148,7 +148,7 @@ class CodexIntegration(SkillsIntegration): | `config` | Class attribute (dict) | Agent metadata: `name`, `folder`, `commands_subdir`, `install_url`, `requires_cli` | | `registrar_config` | Class attribute (dict) | Command output config: `dir`, `format`, `args` placeholder, file `extension` | -**Key design rule:** For CLI-based integrations (`requires_cli: True`), `key` must be the actual executable name (e.g., `"cursor-agent"` not `"cursor"`). This ensures `shutil.which(key)` works for CLI-tool checks without special-case mappings. IDE-based integrations (`requires_cli: False`) should use their canonical identifier (e.g., `"windsurf"`, `"copilot"`). +**Key design rule:** For CLI-based integrations (`requires_cli: True`), `key` must be the actual executable name (e.g., `"cursor-agent"` not `"cursor"`). This ensures `shutil.which(key)` works for CLI-tool checks without special-case mappings. IDE-based integrations (`requires_cli: False`) should use their canonical identifier (e.g., `"kilocode"`, `"copilot"`). ### 3. Register it @@ -201,8 +201,8 @@ Only add custom setup logic when the agent needs non-standard behavior. Integrat specify init my-project --integration # Verify files were created in the commands directory configured by -# config["folder"] + config["commands_subdir"] (for example, .windsurf/workflows/) -ls -R my-project/.windsurf/workflows/ +# config["folder"] + config["commands_subdir"] (for example, .kilocode/workflows/) +ls -R my-project/.kilocode/workflows/ # Uninstall cleanly cd my-project && specify integration uninstall diff --git a/docs/index.md b/docs/index.md index 5772d6cc9a..13d5e049ac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,7 +31,7 @@ Define what to build before building it. Rich templates, quality checklists, and ### Use any coding agent -30+ integrations — Copilot, Gemini, Codex, Windsurf, Zed, Claude, Forge, Kiro, and more. Switch freely between agents with a single command. No lock-in. +30+ integrations — Copilot, Gemini, Codex, Kilo Code, Zed, Claude, Forge, Kiro, and more. Switch freely between agents with a single command. No lock-in. Run `specify init` with your agent of choice and Spec Kit sets up the right command files, context rules, and directory structures automatically. If your agent isn't listed, the `generic` integration is an escape hatch for any tool. diff --git a/docs/reference/integrations.md b/docs/reference/integrations.md index 9a567d1d35..3c48c5a486 100644 --- a/docs/reference/integrations.md +++ b/docs/reference/integrations.md @@ -38,7 +38,6 @@ The Specify CLI supports a wide range of AI coding agents. When you run `specify | [SHAI (OVHcloud)](https://github.com/ovh/shai) | `shai` | | | [Tabnine CLI](https://docs.tabnine.com/main/getting-started/tabnine-cli) | `tabnine` | | | [Trae](https://www.trae.ai/) | `trae` | Skills-based integration; skills are installed automatically | -| [Windsurf](https://windsurf.com/) | `windsurf` | | | [ZCode](https://zcode.z.ai/) | `zcode` | Skills-based integration; installs skills into `.zcode/skills/` and invokes them as `$speckit-` | | [Zed](https://zed.dev/) | `zed` | Skills-based integration; installs skills into `.agents/skills` and invokes them as `/speckit-` | | Generic | `generic` | Bring your own agent — use `--integration generic --integration-options="--commands-dir "` for AI coding agents not listed above | @@ -272,7 +271,6 @@ The currently declared multi-install safe integrations are: | `shai` | `.shai/commands`, `SHAI.md` | | `tabnine` | `.tabnine/agent/commands`, `TABNINE.md` | | `trae` | `.trae/skills`, `.trae/rules/project_rules.md` | -| `windsurf` | `.windsurf/workflows`, `.windsurf/rules/specify-rules.md` | | `zcode` | `.zcode/skills`, `ZCODE.md` | Integrations that share a context file or command directory with another integration, require dynamic install paths such as `--commands-dir`, or merge shared tool settings are not declared safe by default. They can still be installed alongside another integration with `--force`. @@ -287,7 +285,7 @@ Run `specify integration list` to see all available integrations with their keys ### Do I need the AI coding agent installed to use an integration? -CLI-based integrations (like Claude Code, Gemini CLI) require the tool to be installed. IDE-based integrations (like Windsurf, Cursor) work through the IDE itself. Some agents like GitHub Copilot support both IDE and CLI usage. `specify integration list` shows which type each integration is. +CLI-based integrations (like Claude Code, Gemini CLI) require the tool to be installed. IDE-based integrations (like Cursor) work through the IDE itself. Some agents like GitHub Copilot support both IDE and CLI usage. `specify integration list` shows which type each integration is. ### When should I use `upgrade` vs `switch`? diff --git a/docs/upgrade.md b/docs/upgrade.md index c28daf396a..6c5f8a6c0f 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -185,7 +185,7 @@ cp -r .specify/scripts .specify/scripts-backup ### 3. Duplicate slash commands (IDE-based agents) -Some IDE-based agents (like Kilo Code, Windsurf) may show **duplicate slash commands** after upgrading—both old and new versions appear. +Some IDE-based agents (like Kilo Code, Roo Code) may show **duplicate slash commands** after upgrading—both old and new versions appear. **Solution:** Manually delete the old command files from your agent's folder. @@ -193,7 +193,7 @@ Some IDE-based agents (like Kilo Code, Windsurf) may show **duplicate slash comm ```bash # Navigate to the agent's commands folder -cd .kilocode/rules/ +cd .kilocode/workflows/ # List files and identify duplicates ls -la @@ -242,11 +242,11 @@ mv /tmp/constitution-backup.md .specify/memory/constitution.md ### Scenario 3: "I see duplicate slash commands in my IDE" -This happens with IDE-based agents (Kilo Code, Windsurf, Roo Code, etc.). +This happens with IDE-based agents (Kilo Code, Roo Code, Cline, etc.). ```bash -# Find the agent folder (example: .kilocode/rules/) -cd .kilocode/rules/ +# Find the agent folder (example: .kilocode/workflows/) +cd .kilocode/workflows/ # List all files ls -la diff --git a/integrations/catalog.json b/integrations/catalog.json index 8167924cca..435020772a 100644 --- a/integrations/catalog.json +++ b/integrations/catalog.json @@ -48,15 +48,6 @@ "repository": "https://github.com/github/spec-kit", "tags": ["ide"] }, - "windsurf": { - "id": "windsurf", - "name": "Windsurf", - "version": "1.0.0", - "description": "Windsurf IDE workflow integration", - "author": "spec-kit-core", - "repository": "https://github.com/github/spec-kit", - "tags": ["ide"] - }, "amp": { "id": "amp", "name": "Amp", diff --git a/presets/ARCHITECTURE.md b/presets/ARCHITECTURE.md index 3a119cbd5f..fc043143bb 100644 --- a/presets/ARCHITECTURE.md +++ b/presets/ARCHITECTURE.md @@ -99,7 +99,7 @@ The `CommandRegistrar` renders commands differently per agent: | Agent | Format | Extension | Arg placeholder | |-------|--------|-----------|-----------------| -| Claude, Cursor, opencode, Windsurf, etc. | Markdown | `.md` | `$ARGUMENTS` | +| Claude, Kilo Code, opencode, Roo Code, etc. | Markdown | `.md` | `$ARGUMENTS` | | Copilot | Markdown | `.agent.md` + `.prompt.md` | `$ARGUMENTS` | | Gemini, Qwen, Tabnine | TOML | `.toml` | `{{args}}` | diff --git a/src/specify_cli/integrations/__init__.py b/src/specify_cli/integrations/__init__.py index 374d9479f5..9b643b4ee5 100644 --- a/src/specify_cli/integrations/__init__.py +++ b/src/specify_cli/integrations/__init__.py @@ -80,7 +80,6 @@ def _register_builtins() -> None: from .tabnine import TabnineIntegration from .trae import TraeIntegration from .vibe import VibeIntegration - from .windsurf import WindsurfIntegration from .zcode import ZcodeIntegration from .zed import ZedIntegration @@ -118,7 +117,6 @@ def _register_builtins() -> None: _register(TabnineIntegration()) _register(TraeIntegration()) _register(VibeIntegration()) - _register(WindsurfIntegration()) _register(ZcodeIntegration()) _register(ZedIntegration()) diff --git a/src/specify_cli/integrations/windsurf/__init__.py b/src/specify_cli/integrations/windsurf/__init__.py deleted file mode 100644 index eba38fd1e5..0000000000 --- a/src/specify_cli/integrations/windsurf/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -"""Windsurf IDE integration.""" - -from ..base import MarkdownIntegration - - -class WindsurfIntegration(MarkdownIntegration): - key = "windsurf" - config = { - "name": "Windsurf", - "folder": ".windsurf/", - "commands_subdir": "workflows", - "install_url": None, - "requires_cli": False, - } - registrar_config = { - "dir": ".windsurf/workflows", - "format": "markdown", - "args": "$ARGUMENTS", - "extension": ".md", - } - multi_install_safe = True diff --git a/tests/integrations/test_integration_devin.py b/tests/integrations/test_integration_devin.py index 52c2981bf1..9e20f2f419 100644 --- a/tests/integrations/test_integration_devin.py +++ b/tests/integrations/test_integration_devin.py @@ -28,7 +28,7 @@ def test_returns_args_not_none_for_dispatch(self): assert args is not None, ( "DevinIntegration.build_exec_args must not return None. " "None is the codebase sentinel for IDE-only integrations " - "(see WindsurfIntegration); Devin is dispatchable via 'devin -p'." + "(see KilocodeIntegration); Devin is dispatchable via 'devin -p'." ) assert args[:3] == ["devin", "-p", "test prompt"] diff --git a/tests/integrations/test_integration_forge.py b/tests/integrations/test_integration_forge.py index 26ac7a9931..e7e9ec0e3f 100644 --- a/tests/integrations/test_integration_forge.py +++ b/tests/integrations/test_integration_forge.py @@ -403,7 +403,7 @@ def test_registrar_does_not_affect_other_agents(self, tmp_path): encoding="utf-8" ) - # Register with Windsurf (standard markdown agent without inject_name) + # Register with Kilo Code (standard markdown agent without inject_name) registrar = CommandRegistrar() commands = [ { @@ -413,22 +413,22 @@ def test_registrar_does_not_affect_other_agents(self, tmp_path): ] registrar.register_commands( - "windsurf", + "kilocode", commands, "test-extension", ext_dir, tmp_path ) - # Windsurf uses standard markdown format without name injection. + # Kilo Code uses standard markdown format without name injection. # The format_name callback should not be invoked for non-Forge agents. - windsurf_cmd = tmp_path / ".windsurf" / "workflows" / "speckit.my-extension.example.md" - assert windsurf_cmd.exists() + kilocode_cmd = tmp_path / ".kilocode" / "workflows" / "speckit.my-extension.example.md" + assert kilocode_cmd.exists() - content = windsurf_cmd.read_text(encoding="utf-8") - # Windsurf should NOT have a name field injected + content = kilocode_cmd.read_text(encoding="utf-8") + # Kilo Code should NOT have a name field injected assert "name:" not in content, ( - "Windsurf should not inject name field - format_name callback should be Forge-only" + "Kilo Code should not inject name field - format_name callback should be Forge-only" ) def test_git_extension_command_uses_hyphen_notation(self, tmp_path): diff --git a/tests/integrations/test_integration_windsurf.py b/tests/integrations/test_integration_windsurf.py deleted file mode 100644 index 4cdfaa94a3..0000000000 --- a/tests/integrations/test_integration_windsurf.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Tests for WindsurfIntegration.""" - -from .test_integration_base_markdown import MarkdownIntegrationTests - - -class TestWindsurfIntegration(MarkdownIntegrationTests): - KEY = "windsurf" - FOLDER = ".windsurf/" - COMMANDS_SUBDIR = "workflows" - REGISTRAR_DIR = ".windsurf/workflows" diff --git a/tests/integrations/test_registry.py b/tests/integrations/test_registry.py index 478bc54f5b..983912197e 100644 --- a/tests/integrations/test_registry.py +++ b/tests/integrations/test_registry.py @@ -23,7 +23,7 @@ # Stage 3 — standard markdown integrations "claude", "qwen", "opencode", "junie", "kilocode", "auggie", "roo", "rovodev", "codebuddy", "qodercli", "amp", "shai", "bob", "trae", - "pi", "kiro-cli", "windsurf", "vibe", "cursor-agent", "firebender", + "pi", "kiro-cli", "vibe", "cursor-agent", "firebender", # Stage 4 — TOML integrations "gemini", "tabnine", # Stage 5 — skills, generic & option-driven integrations diff --git a/tests/test_agent_config_consistency.py b/tests/test_agent_config_consistency.py index d35154e86c..cd1e91b7fd 100644 --- a/tests/test_agent_config_consistency.py +++ b/tests/test_agent_config_consistency.py @@ -43,7 +43,6 @@ "shai", "tabnine", "trae", - "windsurf", "zcode", "zed", ] diff --git a/tests/test_workflows.py b/tests/test_workflows.py index eebc89fadd..0b4bfe4063 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -650,8 +650,8 @@ def test_copilot_new_env_var_takes_precedence(self, monkeypatch): assert "--yolo" in args def test_ide_only_returns_none(self): - from specify_cli.integrations.windsurf import WindsurfIntegration - impl = WindsurfIntegration() + from specify_cli.integrations.kilocode import KilocodeIntegration + impl = KilocodeIntegration() assert impl.build_exec_args("test") is None def test_no_model_omits_flag(self):