Add opinionated MCP modes for workspace workflows

Introduce explicit repro-fix, inspect, cold-start, and review-eval modes across the MCP server, CLI, and host helpers, with canonical mode-to-tool mappings, narrowed schemas, and mode-specific tool descriptions on top of the existing workspace runtime.

Reposition the docs, host onramps, and use-case recipes so named modes are the primary user-facing startup story while the generic no-mode workspace-core path remains the escape hatch, and update the shared smoke runner to validate repro-fix and cold-start through mode-backed servers.

Validation: UV_OFFLINE=1 UV_CACHE_DIR=.uv-cache uv run pytest --no-cov tests/test_api.py tests/test_server.py tests/test_host_helpers.py tests/test_public_contract.py tests/test_cli.py tests/test_workspace_use_case_smokes.py; UV_OFFLINE=1 UV_CACHE_DIR=.uv-cache make check; UV_OFFLINE=1 UV_CACHE_DIR=.uv-cache make dist-check; real guest-backed make smoke-repro-fix-loop smoke-cold-start-validation outside the sandbox.
This commit is contained in:
Thales Maciel 2026-03-13 20:00:35 -03:00
parent dc86d84e96
commit d0cf6d8f21
33 changed files with 1034 additions and 274 deletions

View file

@ -131,6 +131,16 @@ def test_canonical_server_command_validates_and_renders_variants() -> None:
"--repo-ref",
"main",
]
assert _canonical_server_command(HostServerConfig(mode="repro-fix")) == [
"uvx",
"--from",
"pyro-mcp",
"pyro",
"mcp",
"serve",
"--mode",
"repro-fix",
]
assert _canonical_server_command(HostServerConfig(no_project_source=True)) == [
"uvx",
"--from",
@ -149,6 +159,10 @@ def test_canonical_server_command_validates_and_renders_variants() -> None:
_canonical_server_command(HostServerConfig(project_path="/repo", no_project_source=True))
with pytest.raises(ValueError, match="requires --repo-url"):
_canonical_server_command(HostServerConfig(repo_ref="main"))
with pytest.raises(ValueError, match="mutually exclusive"):
_canonical_server_command(
HostServerConfig(profile="workspace-full", mode="repro-fix")
)
def test_repair_command_and_command_matches_cover_edge_cases() -> None:
@ -167,6 +181,9 @@ def test_repair_command_and_command_matches_cover_edge_cases() -> None:
assert _repair_command("codex", HostServerConfig(no_project_source=True)) == (
"pyro host repair codex --no-project-source"
)
assert _repair_command("codex", HostServerConfig(mode="inspect")) == (
"pyro host repair codex --mode inspect"
)
assert _command_matches(
"pyro: uvx --from pyro-mcp pyro mcp serve",
["uvx", "--from", "pyro-mcp", "pyro", "mcp", "serve"],