From bdb24c1dbd3390d919e9617a7aa695894d3d5535 Mon Sep 17 00:00:00 2001 From: yxshee <84263676+yxshee@users.noreply.github.com> Date: Sun, 18 Oct 2026 00:06:24 +0530 Subject: [PATCH] fix(integrations): drop unsupported --model flag from ZCode dispatch The ZCode CLI has no --model option, and it parses its arguments with node:util parseArgs in strict mode. The inherited SkillsIntegration.build_exec_args() appends --model whenever a workflow step or workflow default sets model:, so the dispatched step exits 1 with "Unknown option '--model'" before ZCode runs. Keep -p and --output-format json, which ZCode accepts, and drop model: ZCode has no per-invocation model flag and switches models in-session with /model. Assisted-by: Claude Code (model: Claude Opus 5.5, autonomous) Co-Authored-By: Claude Opus 5.5 --- .../integrations/zcode/__init__.py | 30 ++++++++++ tests/integrations/test_integration_zcode.py | 57 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/src/specify_cli/integrations/zcode/__init__.py b/src/specify_cli/integrations/zcode/__init__.py index 46d93c5ca2..9d6802d436 100644 --- a/src/specify_cli/integrations/zcode/__init__.py +++ b/src/specify_cli/integrations/zcode/__init__.py @@ -8,6 +8,10 @@ from __future__ import annotations +from collections.abc import Mapping, Sequence +from pathlib import Path +from typing import Any + from ..base import IntegrationOption, SkillsIntegration @@ -40,3 +44,29 @@ def options(cls) -> list[IntegrationOption]: help="Install as agent skills (default for ZCode)", ), ] + + def build_exec_args( + self, + prompt: str, + *, + model: str | None = None, + output_json: bool = True, + integration_args: Sequence[str] | None = None, + integration_options: Mapping[str, Any] | None = None, + project_root: Path | None = None, + ) -> list[str] | None: + """Build CLI arguments for non-interactive ``zcode`` execution. + + ``SkillsIntegration``'s default appends ``--model``, which the ZCode + CLI does not define. Its argument parser is strict, so a dispatched + step exits 1 with ``Unknown option '--model'`` whenever a ``model`` + is configured. ``model`` is deliberately dropped: ZCode has no + per-invocation model flag and switches models in-session with + ``/model``. ``-p`` and ``--output-format json`` are both valid. + """ + self.validate_runtime_config(integration_args, integration_options) + args = [self._resolve_executable(), "-p", prompt] + self._apply_extra_args_env_var(args) + if output_json: + args.extend(["--output-format", "json"]) + return args diff --git a/tests/integrations/test_integration_zcode.py b/tests/integrations/test_integration_zcode.py index 57abaedffe..f792e1d8f5 100644 --- a/tests/integrations/test_integration_zcode.py +++ b/tests/integrations/test_integration_zcode.py @@ -1,5 +1,7 @@ """Tests for ZcodeIntegration — skills-based integration (Z.AI).""" +from specify_cli.integrations import get_integration + from .test_integration_base_skills import SkillsIntegrationTests @@ -9,6 +11,61 @@ class TestZcodeIntegration(SkillsIntegrationTests): COMMANDS_SUBDIR = "skills" REGISTRAR_DIR = ".zcode/skills" + def test_build_exec_args_uses_prompt_flag(self): + integration = get_integration("zcode") + + args = integration.build_exec_args( + "$speckit-specify build a login page", + output_json=False, + ) + + assert args == ["zcode", "-p", "$speckit-specify build a login page"] + + def test_build_exec_args_requests_json_output(self): + integration = get_integration("zcode") + + args = integration.build_exec_args("$speckit-plan add OAuth", output_json=True) + + assert args == [ + "zcode", + "-p", + "$speckit-plan add OAuth", + "--output-format", + "json", + ] + + def test_build_exec_args_omits_model_flag(self): + """ZCode has no model flag; its strict parser rejects `--model` and exits 1.""" + integration = get_integration("zcode") + + args = integration.build_exec_args( + "$speckit-specify build a login page", + model="glm-5", + output_json=False, + ) + + assert args == ["zcode", "-p", "$speckit-specify build a login page"] + assert "--model" not in args + assert "glm-5" not in args + + def test_build_exec_args_applies_extra_args(self, monkeypatch): + monkeypatch.setenv("SPECKIT_INTEGRATION_ZCODE_EXTRA_ARGS", "--mode build") + integration = get_integration("zcode") + + args = integration.build_exec_args( + "check the build", model="glm-5", output_json=True + ) + + assert args == [ + "zcode", + "-p", + "check the build", + "--mode", + "build", + "--output-format", + "json", + ] + class TestZcodeInvocation: """ZCode renders $speckit-* chat invocations (like Codex)."""