From 6aa9431b249375fe4b238fdcf647472b4e6bccb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Pe=C3=B1a?= Date: Mon, 10 Aug 2026 14:44:20 -0500 Subject: [PATCH] Add Command Code integration to spec-kit (#4019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Command Code integration to spec-kit Adds `command-code` as a built-in skills-based integration so Spec Kit can be installed into Command Code. Command Code loads agent skills from `.commandcode/skills/speckit-/SKILL.md` and invokes them in chat as `$speckit-`. - New `CommandCodeIntegration` (SkillsIntegration) writing to `.commandcode/skills/`; declared multi-install safe (static, isolated agent root). - Register in `_register_builtins()` and the integration catalog. - Add `command-code` to `DOLLAR_SKILLS_AGENTS` so next-steps guidance renders `$speckit-*` invocations. - Tests: reuse `SkillsIntegrationTests` mixin plus a dollar-invocation next-steps test; registry completeness updated. - Docs: README and docs/reference/integrations.md (supported agents + multi-install-safe table). Co-authored-by: CommandCodeBot Assisted-by: Command Code (autonomous) * Fix issue template agent lists to include command-code The runtime AGENT_CONFIG now includes command-code, but the GitHub issue templates and the consistency test's expected key list were not updated, failing test_issue_template_agent_lists_match_runtime_integrations. Co-authored-by: CommandCodeBot Assisted-by: Command Code (autonomous) --------- Co-authored-by: CommandCodeBot --- .github/ISSUE_TEMPLATE/agent_request.yml | 2 +- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + README.md | 2 +- docs/reference/integrations.md | 2 + integrations/catalog.json | 9 ++++ src/specify_cli/_invocation_style.py | 2 +- src/specify_cli/integrations/__init__.py | 2 + .../integrations/command_code/__init__.py | 41 ++++++++++++++++ .../test_integration_command_code.py | 47 +++++++++++++++++++ tests/integrations/test_registry.py | 2 +- tests/test_agent_config_consistency.py | 1 + 12 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/specify_cli/integrations/command_code/__init__.py create mode 100644 tests/integrations/test_integration_command_code.py diff --git a/.github/ISSUE_TEMPLATE/agent_request.yml b/.github/ISSUE_TEMPLATE/agent_request.yml index 360370165..785f9193e 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**: Alquimia AI, Amp, Antigravity, Auggie CLI, Claude Code, Cline, CodeBuddy, Codex CLI, Cursor, Devin for Terminal, Factory Droid, Firebender, Forge, Gemini CLI, GitHub Copilot, Goose, Grok Build, 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, RovoDev ACLI, SHAI, Tabnine CLI, Trae, ZCode, Zed + **Currently supported agents**: Alquimia AI, Amp, Antigravity, Auggie CLI, Claude Code, Cline, CodeBuddy, Codex CLI, Command Code, Cursor, Devin for Terminal, Factory Droid, Firebender, Forge, Gemini CLI, GitHub Copilot, Goose, Grok Build, 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, 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 03a7e9793..03fa6c124 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -70,6 +70,7 @@ body: - Cline - CodeBuddy - Codex CLI + - Command Code - Cursor - Devin for Terminal - Factory Droid diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 08e107503..4613c8eba 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -64,6 +64,7 @@ body: - Cline - CodeBuddy - Codex CLI + - Command Code - Cursor - Devin for Terminal - Factory Droid diff --git a/README.md b/README.md index cd48ae9fe..5c0f2a592 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Bare `specify self upgrade` executes immediately, matching the no-prompt behavio ### 3. Establish project principles -Launch your coding agent in the project directory. Most agents expose spec-kit as `/speckit.*` slash commands; Codex CLI in skills mode uses `$speckit-*` instead; GitHub Copilot CLI uses `/agents` to select the agent or address it directly in a prompt. +Launch your coding agent in the project directory. Most agents expose spec-kit as `/speckit.*` slash commands; Codex CLI and Command Code in skills mode use `$speckit-*` instead; GitHub Copilot CLI uses `/agents` to select the agent or address it directly in a prompt. Use the **`/speckit.constitution`** command to create your project's governing principles and development guidelines that will guide all subsequent development. diff --git a/docs/reference/integrations.md b/docs/reference/integrations.md index 808d0cf75..57bb46b10 100644 --- a/docs/reference/integrations.md +++ b/docs/reference/integrations.md @@ -14,6 +14,7 @@ The Specify CLI supports a wide range of AI coding agents. When you run `specify | [Cline](https://github.com/cline/cline) | `cline` | IDE-based agent | | [CodeBuddy CLI](https://www.codebuddy.cn/docs/cli/installation) | `codebuddy` | | | [Codex CLI](https://github.com/openai/codex) | `codex` | Skills-based integration; installs skills into `.agents/skills` and invokes them as `$speckit-` | +| [Command Code](https://commandcode.ai/docs) | `command-code` | Skills-based integration; installs skills into `.commandcode/skills/` and invokes them as `$speckit-` | | [Cursor](https://cursor.sh/) | `cursor-agent` | | | [Devin for Terminal](https://cli.devin.ai/docs) | `devin` | Skills-based integration; installs skills into `.devin/skills/` and invokes them as `/speckit-` | | [Factory Droid](https://docs.factory.ai/cli/getting-started/overview) | `droid` | Skills-based integration; installs skills into `.factory/skills/` and invokes them as `/speckit-` | @@ -279,6 +280,7 @@ The currently declared multi-install safe integrations are: | `cline` | `.clinerules/workflows` | | `codebuddy` | `.codebuddy/commands` | | `codex` | `.agents/skills` | +| `command-code` | `.commandcode/skills` | | `cursor-agent` | `.cursor/skills` | | `droid` | `.factory/skills` | | `firebender` | `.firebender/commands` | diff --git a/integrations/catalog.json b/integrations/catalog.json index abaabb8ec..f3f7a7fe7 100644 --- a/integrations/catalog.json +++ b/integrations/catalog.json @@ -84,6 +84,15 @@ "repository": "https://github.com/github/spec-kit", "tags": ["cli", "skills"] }, + "command-code": { + "id": "command-code", + "name": "Command Code", + "version": "1.0.0", + "description": "Command Code CLI skills-based integration", + "author": "spec-kit-core", + "repository": "https://github.com/github/spec-kit", + "tags": ["cli", "skills"] + }, "devin": { "id": "devin", "name": "Devin for Terminal", diff --git a/src/specify_cli/_invocation_style.py b/src/specify_cli/_invocation_style.py index 29018e863..5cc709883 100644 --- a/src/specify_cli/_invocation_style.py +++ b/src/specify_cli/_invocation_style.py @@ -9,7 +9,7 @@ and ``specify init``'s next-steps output stay consistent. from __future__ import annotations # Agents that render $speckit- (chat invocation) when in skills mode. -DOLLAR_SKILLS_AGENTS: frozenset[str] = frozenset({"codex", "zcode"}) +DOLLAR_SKILLS_AGENTS: frozenset[str] = frozenset({"codex", "zcode", "command-code"}) # Agents that always render /speckit-, regardless of ai_skills. ALWAYS_SLASH_AGENTS: frozenset[str] = frozenset({"devin", "droid", "grok", "trae", "zed"}) diff --git a/src/specify_cli/integrations/__init__.py b/src/specify_cli/integrations/__init__.py index e251395b7..75c2f9d0d 100644 --- a/src/specify_cli/integrations/__init__.py +++ b/src/specify_cli/integrations/__init__.py @@ -56,6 +56,7 @@ def _register_builtins() -> None: from .cline import ClineIntegration from .codebuddy import CodebuddyIntegration from .codex import CodexIntegration + from .command_code import CommandCodeIntegration from .copilot import CopilotIntegration from .cursor_agent import CursorAgentIntegration from .devin import DevinIntegration @@ -95,6 +96,7 @@ def _register_builtins() -> None: _register(ClineIntegration()) _register(CodebuddyIntegration()) _register(CodexIntegration()) + _register(CommandCodeIntegration()) _register(CopilotIntegration()) _register(CursorAgentIntegration()) _register(DevinIntegration()) diff --git a/src/specify_cli/integrations/command_code/__init__.py b/src/specify_cli/integrations/command_code/__init__.py new file mode 100644 index 000000000..8eef9f557 --- /dev/null +++ b/src/specify_cli/integrations/command_code/__init__.py @@ -0,0 +1,41 @@ +"""Command Code integration — skills-based agent. + +Command Code loads agent skills from ``.commandcode/skills/speckit-/SKILL.md`` +(project) or ``~/.commandcode/skills/`` (personal). Skills are invoked in chat +with ``$speckit-``. +""" + +from __future__ import annotations + +from ..base import IntegrationOption, SkillsIntegration + + +class CommandCodeIntegration(SkillsIntegration): + """Integration for Command Code CLI.""" + + key = "command-code" + config = { + "name": "Command Code", + "folder": ".commandcode/", + "commands_subdir": "skills", + "install_url": "https://commandcode.ai/docs", + "requires_cli": True, + } + registrar_config = { + "dir": ".commandcode/skills", + "format": "markdown", + "args": "$ARGUMENTS", + "extension": "/SKILL.md", + } + multi_install_safe = True + + @classmethod + def options(cls) -> list[IntegrationOption]: + return [ + IntegrationOption( + "--skills", + is_flag=True, + default=True, + help="Install as agent skills (default for Command Code)", + ), + ] diff --git a/tests/integrations/test_integration_command_code.py b/tests/integrations/test_integration_command_code.py new file mode 100644 index 000000000..5075fe7a6 --- /dev/null +++ b/tests/integrations/test_integration_command_code.py @@ -0,0 +1,47 @@ +"""Tests for CommandCodeIntegration — skills-based integration (Command Code).""" + +from .test_integration_base_skills import SkillsIntegrationTests + + +class TestCommandCodeIntegration(SkillsIntegrationTests): + KEY = "command-code" + FOLDER = ".commandcode/" + COMMANDS_SUBDIR = "skills" + REGISTRAR_DIR = ".commandcode/skills" + + +class TestCommandCodeInvocation: + """Command Code renders $speckit-* chat invocations (like Codex/ZCode).""" + + def test_next_steps_show_dollar_skill_invocation(self, tmp_path): + import os + + from typer.testing import CliRunner + + from specify_cli import app + + project = tmp_path / "command-code-next-steps" + project.mkdir() + old_cwd = os.getcwd() + try: + os.chdir(project) + runner = CliRunner() + result = runner.invoke( + app, + [ + "init", + "--here", + "--integration", + "command-code", + "--ignore-agent-tools", + "--script", + "sh", + ], + catch_exceptions=False, + ) + finally: + os.chdir(old_cwd) + + assert result.exit_code == 0 + assert "$speckit-constitution" in result.output + assert "/speckit.constitution" not in result.output diff --git a/tests/integrations/test_registry.py b/tests/integrations/test_registry.py index 4f9cff274..0d0a724bd 100644 --- a/tests/integrations/test_registry.py +++ b/tests/integrations/test_registry.py @@ -28,7 +28,7 @@ ALL_INTEGRATION_KEYS = [ "gemini", "tabnine", # Stage 5 — skills, generic & option-driven integrations "codex", "kimi", "agy", "zed", "generic", - "droid", + "droid", "command-code", ] diff --git a/tests/test_agent_config_consistency.py b/tests/test_agent_config_consistency.py index 0ccaf99aa..0cebe7bc3 100644 --- a/tests/test_agent_config_consistency.py +++ b/tests/test_agent_config_consistency.py @@ -21,6 +21,7 @@ ISSUE_TEMPLATE_AGENT_KEYS = [ "cline", "codebuddy", "codex", + "command-code", "cursor-agent", "devin", "droid",