From 73e2fdd8568444005fa473372f3803ed2b4a3c33 Mon Sep 17 00:00:00 2001 From: tt-a1i Date: Tue, 7 Jul 2026 16:20:37 +0800 Subject: [PATCH] Release 0.10.7 Expand default mco doctor checks to all supported providers while keeping run/review defaults on the audited five built-ins. Co-authored-by: Cursor --- CHANGELOG.md | 5 +++++ README.md | 2 +- README.zh-CN.md | 2 +- package.json | 2 +- pyproject.toml | 2 +- runtime/__init__.py | 2 +- runtime/cli.py | 5 +++-- runtime/mcp_server.py | 6 ++---- tests/test_cli_doctor.py | 4 ++-- tests/test_mcp_server.py | 11 ++++------- 10 files changed, 21 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a4f9df..0c30f6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht ## [Unreleased] +## [0.10.7] - 2026-07-07 +### Changed +- Expanded default `mco doctor` checks to all eight supported providers, including explicit opt-in Copilot, Hermes, and Pi. +- Kept `mco run` and `mco review` default provider set at the audited five built-ins. + ## [0.10.6] - 2026-06-28 ### Added - Added per-provider context policy with `--provider-context-json`, including explicit skills/context/plugin controls where supported. diff --git a/README.md b/README.md index 295dd49..0ff0c7c 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ The question isn't "which AI agent is best" — it's "why limit yourself to one? | OpenCode | `opencode` | Supported | | Qwen Code | `qwen` | Supported | -These five providers are the default set for `mco run`, `mco review`, and `mco doctor`. +These five providers are the default set for `mco run` and `mco review`. `mco doctor` checks all eight supported providers by default. ## Explicit Opt-in Providers diff --git a/README.zh-CN.md b/README.zh-CN.md index 51df887..f6e8c1a 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -164,7 +164,7 @@ MCO 设计为被任意编排方 Agent 或 AI IDE 调用 — Claude Code、Cursor | OpenCode | `opencode` | 已支持 | | Qwen Code | `qwen` | 已支持 | -这五个 provider 是 `mco run`、`mco review` 和 `mco doctor` 的默认集合。 +这五个 provider 是 `mco run` 和 `mco review` 的默认集合。`mco doctor` 默认检查全部八个受支持的 provider。 ## 显式选择的 Provider diff --git a/package.json b/package.json index 963ca55..5b10317 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tt-a1i/mco", - "version": "0.10.6", + "version": "0.10.7", "description": "Node wrapper for the mco CLI (Python runtime required).", "license": "MIT", "bin": { diff --git a/pyproject.toml b/pyproject.toml index a166449..923b600 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "mco" -version = "0.10.6" +version = "0.10.7" description = "Neutral multi-provider CLI orchestrator for agent-style run/review workflows." readme = "README.md" requires-python = ">=3.10" diff --git a/runtime/__init__.py b/runtime/__init__.py index 0b19d06..3c21c48 100644 --- a/runtime/__init__.py +++ b/runtime/__init__.py @@ -3,6 +3,6 @@ from .artifacts import ARTIFACT_LAYOUT_VERSION from .types import RUN_RESULT_SCHEMA_VERSION -__version__ = "0.10.6" +__version__ = "0.10.7" __all__ = ["ARTIFACT_LAYOUT_VERSION", "RUN_RESULT_SCHEMA_VERSION", "__version__"] diff --git a/runtime/cli.py b/runtime/cli.py index a4489e4..bb8400e 100644 --- a/runtime/cli.py +++ b/runtime/cli.py @@ -21,6 +21,7 @@ SUPPORTED_PROVIDERS = ("claude", "codex", "copilot", "gemini", "hermes", "opencode", "pi", "qwen") SUPPORTED_PROVIDER_LIST = ",".join(SUPPORTED_PROVIDERS) +DEFAULT_DOCTOR_PROVIDERS = SUPPORTED_PROVIDERS DEFAULT_CONFIG = ReviewConfig() DEFAULT_POLICY = DEFAULT_CONFIG.policy @@ -1070,7 +1071,7 @@ def build_parser() -> argparse.ArgumentParser: ) doctor.add_argument( "--providers", - default=",".join(DEFAULT_CONFIG.providers), + default=",".join(DEFAULT_DOCTOR_PROVIDERS), help="Comma-separated providers. Supported: {}".format(SUPPORTED_PROVIDER_LIST), ) doctor.add_argument("--json", action="store_true", help="Print machine-readable JSON output") @@ -1727,7 +1728,7 @@ def _capture_parse_error(message: str) -> None: print(err_event, flush=True) return int(exc.code) if isinstance(exc.code, int) else 2 if args.command == "doctor": - providers_str = getattr(args, "providers", ",".join(DEFAULT_CONFIG.providers)) + providers_str = getattr(args, "providers", ",".join(DEFAULT_DOCTOR_PROVIDERS)) providers = [item for item in _parse_providers(providers_str) if item in SUPPORTED_PROVIDERS] if not providers: print("No valid providers selected.", file=sys.stderr) diff --git a/runtime/mcp_server.py b/runtime/mcp_server.py index 44811a3..2658aac 100644 --- a/runtime/mcp_server.py +++ b/runtime/mcp_server.py @@ -49,8 +49,7 @@ def _validate_repo(repo: str, require_git: bool = False) -> Optional[Dict[str, A def _sync_doctor(providers_csv: Optional[str]) -> Dict[str, Any]: """Check provider installation and auth status.""" - from .cli import _doctor_provider_presence, SUPPORTED_PROVIDERS - from .config import ReviewConfig + from .cli import DEFAULT_DOCTOR_PROVIDERS, _doctor_provider_presence, SUPPORTED_PROVIDERS if providers_csv: providers = [p.strip() for p in providers_csv.split(",") if p.strip()] @@ -59,8 +58,7 @@ def _sync_doctor(providers_csv: Optional[str]) -> Dict[str, Any]: return _err("invalid_providers", "No valid providers in: {}".format(providers_csv)) providers = valid else: - # Use the same safe default as CLI doctor (ReviewConfig built-in 5). - providers = list(ReviewConfig().providers) + providers = list(DEFAULT_DOCTOR_PROVIDERS) presence_map = _doctor_provider_presence(providers) diff --git a/tests/test_cli_doctor.py b/tests/test_cli_doctor.py index 8b90014..40b45e8 100644 --- a/tests/test_cli_doctor.py +++ b/tests/test_cli_doctor.py @@ -6,7 +6,7 @@ from contextlib import redirect_stderr, redirect_stdout from unittest.mock import patch -from runtime.cli import build_parser, main +from runtime.cli import SUPPORTED_PROVIDER_LIST, build_parser, main from runtime.contracts import ProviderPresence @@ -15,7 +15,7 @@ def test_parser_accepts_doctor_subcommand(self) -> None: parser = build_parser() args = parser.parse_args(["doctor"]) self.assertEqual(args.command, "doctor") - self.assertEqual(args.providers, "claude,codex,gemini,opencode,qwen") + self.assertEqual(args.providers, SUPPORTED_PROVIDER_LIST) self.assertFalse(args.json) def test_doctor_json_payload_contract(self) -> None: diff --git a/tests/test_mcp_server.py b/tests/test_mcp_server.py index b8706b3..1c0b03b 100644 --- a/tests/test_mcp_server.py +++ b/tests/test_mcp_server.py @@ -5,6 +5,7 @@ import unittest from unittest.mock import patch, MagicMock +from runtime.cli import SUPPORTED_PROVIDERS from runtime.mcp_server import ( _ok, _err, _is_git_repo, _validate_repo, _sync_doctor, _sync_review, _sync_run, @@ -80,17 +81,13 @@ def test_invalid_provider_returns_error(self) -> None: self.assertEqual(result["error"]["code"], "invalid_providers") @patch("runtime.cli._doctor_provider_presence") - def test_default_providers_are_builtin_five(self, mock_presence) -> None: - """Default doctor (no providers arg) checks exactly the 5 built-in providers.""" + def test_default_providers_include_opt_in(self, mock_presence) -> None: + """Default doctor (no providers arg) checks all supported built-in providers.""" mock_presence.return_value = {} result = _sync_doctor(None) self.assertTrue(result["ok"]) called_providers = mock_presence.call_args[0][0] - self.assertEqual( - called_providers, - ["claude", "codex", "gemini", "opencode", "qwen"], - "Default doctor must check only the 5 built-in providers, not hermes/pi", - ) + self.assertEqual(called_providers, list(SUPPORTED_PROVIDERS)) @patch("runtime.cli._doctor_provider_presence") def test_explicit_hermes_pi_allowed(self, mock_presence) -> None: