Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 2 additions & 0 deletions docs/reference/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -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>` |
| [Command Code](https://commandcode.ai/docs) | `command-code` | Skills-based integration; installs skills into `.commandcode/skills/` and invokes them as `$speckit-<command>` |
| [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-<command>` |
| [Factory Droid](https://docs.factory.ai/cli/getting-started/overview) | `droid` | Skills-based integration; installs skills into `.factory/skills/` and invokes them as `/speckit-<command>` |
Expand Down Expand Up @@ -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` |
Expand Down
9 changes: 9 additions & 0 deletions integrations/catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/specify_cli/_invocation_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from __future__ import annotations

# Agents that render $speckit-<name> (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-<name>, regardless of ai_skills.
ALWAYS_SLASH_AGENTS: frozenset[str] = frozenset({"devin", "droid", "grok", "trae", "zed"})
Expand Down
2 changes: 2 additions & 0 deletions src/specify_cli/integrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -95,6 +96,7 @@ def _register_builtins() -> None:
_register(ClineIntegration())
_register(CodebuddyIntegration())
_register(CodexIntegration())
_register(CommandCodeIntegration())
_register(CopilotIntegration())
_register(CursorAgentIntegration())
_register(DevinIntegration())
Expand Down
41 changes: 41 additions & 0 deletions src/specify_cli/integrations/command_code/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Command Code integration — skills-based agent.

Command Code loads agent skills from ``.commandcode/skills/speckit-<name>/SKILL.md``
(project) or ``~/.commandcode/skills/`` (personal). Skills are invoked in chat
with ``$speckit-<name>``.
"""

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)",
),
]
47 changes: 47 additions & 0 deletions tests/integrations/test_integration_command_code.py
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/integrations/test_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"gemini", "tabnine",
# Stage 5 — skills, generic & option-driven integrations
"codex", "kimi", "agy", "zed", "generic",
"droid",
"droid", "command-code",
]


Expand Down