diff --git a/README.md b/README.md index afca9b15a5..3eb82395c1 100644 --- a/README.md +++ b/README.md @@ -351,7 +351,7 @@ specify init . --force --integration copilot specify init --here --force --integration copilot ``` -The CLI will check if you have Claude Code, Gemini CLI, Cursor CLI, Qwen CLI, opencode, Codex CLI, Qoder CLI, Tabnine CLI, Kiro CLI, Pi, Forge, Goose, or Mistral Vibe installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command: +The CLI will check if you have Claude Code, Gemini CLI, Cursor CLI, Qwen CLI, opencode, Codex CLI, Qoder CLI, Tabnine CLI, Kiro CLI, Pi, Forge, Goose, Mistral Vibe, or ZCode installed. If you do not, or you prefer to get the templates without checking for the right tools, use `--ignore-agent-tools` with your command: ```bash specify init --integration copilot --ignore-agent-tools diff --git a/docs/reference/integrations.md b/docs/reference/integrations.md index a790389774..1fe4a53640 100644 --- a/docs/reference/integrations.md +++ b/docs/reference/integrations.md @@ -38,6 +38,7 @@ The Specify CLI supports a wide range of AI coding agents. When you run `specify | [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 | diff --git a/integrations/catalog.json b/integrations/catalog.json index 33c6ddd931..f89af37d5c 100644 --- a/integrations/catalog.json +++ b/integrations/catalog.json @@ -299,6 +299,15 @@ "author": "spec-kit-core", "repository": "https://github.com/github/spec-kit", "tags": ["cli", "skills"] + }, + "zcode": { + "id": "zcode", + "name": "ZCode", + "version": "1.0.0", + "description": "Z.AI ZCode CLI skills-based integration", + "author": "spec-kit-core", + "repository": "https://github.com/github/spec-kit", + "tags": ["cli", "skills", "z-ai"] } } } diff --git a/src/specify_cli/integrations/__init__.py b/src/specify_cli/integrations/__init__.py index 07d3cc1a6d..a81d705543 100644 --- a/src/specify_cli/integrations/__init__.py +++ b/src/specify_cli/integrations/__init__.py @@ -80,6 +80,7 @@ def _register_builtins() -> None: from .trae import TraeIntegration from .vibe import VibeIntegration from .windsurf import WindsurfIntegration + from .zcode import ZcodeIntegration from .zed import ZedIntegration # -- Registration (alphabetical) -------------------------------------- @@ -116,6 +117,7 @@ def _register_builtins() -> None: _register(TraeIntegration()) _register(VibeIntegration()) _register(WindsurfIntegration()) + _register(ZcodeIntegration()) _register(ZedIntegration()) diff --git a/src/specify_cli/integrations/zcode/__init__.py b/src/specify_cli/integrations/zcode/__init__.py new file mode 100644 index 0000000000..ea47f31555 --- /dev/null +++ b/src/specify_cli/integrations/zcode/__init__.py @@ -0,0 +1,43 @@ +"""ZCode integration — skills-based agent (Z.AI). + +ZCode uses the ``.zcode/skills/speckit-/SKILL.md`` layout, matching +the Claude Code skill format. Skills are invoked in chat with +``$speckit-``. Z.AI recommends skills (over simple ``/`` commands) +for template- and script-driven workflows such as spec-kit. +""" + +from __future__ import annotations + +from ..base import IntegrationOption, SkillsIntegration + + +class ZcodeIntegration(SkillsIntegration): + """Integration for ZCode CLI (Z.AI).""" + + key = "zcode" + config = { + "name": "ZCode", + "folder": ".zcode/", + "commands_subdir": "skills", + "install_url": "https://zcode.z.ai/", + "requires_cli": True, + } + registrar_config = { + "dir": ".zcode/skills", + "format": "markdown", + "args": "$ARGUMENTS", + "extension": "/SKILL.md", + } + context_file = "ZCODE.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 ZCode)", + ), + ] diff --git a/tests/integrations/test_integration_zcode.py b/tests/integrations/test_integration_zcode.py new file mode 100644 index 0000000000..4c54ed8ff5 --- /dev/null +++ b/tests/integrations/test_integration_zcode.py @@ -0,0 +1,11 @@ +"""Tests for ZcodeIntegration — skills-based integration (Z.AI).""" + +from .test_integration_base_skills import SkillsIntegrationTests + + +class TestZcodeIntegration(SkillsIntegrationTests): + KEY = "zcode" + FOLDER = ".zcode/" + COMMANDS_SUBDIR = "skills" + REGISTRAR_DIR = ".zcode/skills" + CONTEXT_FILE = "ZCODE.md"