From 447e0a5fa928c3502f9365e7d79796135b92045a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Angel=20Pe=C3=B1a?= Date: Sat, 8 Aug 2026 04:24:11 -0500 Subject: [PATCH] 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) --- 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 +- 8 files changed, 104 insertions(+), 3 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/README.md b/README.md index cd48ae9fe3..5c0f2a592f 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 808d0cf752..57bb46b10c 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 abaabb8ece..f3f7a7fe7f 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 29018e863a..5cc7098837 100644 --- a/src/specify_cli/_invocation_style.py +++ b/src/specify_cli/_invocation_style.py @@ -9,7 +9,7 @@ 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 e251395b72..75c2f9d0de 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 0000000000..8eef9f5579 --- /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 0000000000..5075fe7a65 --- /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 4f9cff274b..0d0a724bd8 100644 --- a/tests/integrations/test_registry.py +++ b/tests/integrations/test_registry.py @@ -28,7 +28,7 @@ "gemini", "tabnine", # Stage 5 — skills, generic & option-driven integrations "codex", "kimi", "agy", "zed", "generic", - "droid", + "droid", "command-code", ]