mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
feat: add version feature reporting (#2548)
This commit is contained in:
@@ -77,6 +77,16 @@ specify version
|
||||
|
||||
Displays the Spec Kit CLI version, Python version, platform, and architecture.
|
||||
|
||||
To inspect local CLI capabilities without checking the network:
|
||||
|
||||
```bash
|
||||
specify version --features
|
||||
specify version --features --json
|
||||
```
|
||||
|
||||
The JSON form is intended for scripts and coding agents that need to choose a
|
||||
workflow based on the installed CLI's supported features.
|
||||
|
||||
A quick version check is also available via:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1155,15 +1155,59 @@ def check():
|
||||
if not any(agent_results.values()):
|
||||
console.print("[dim]Tip: Install a coding agent for the best experience[/dim]")
|
||||
|
||||
|
||||
def _feature_capabilities() -> dict[str, bool]:
|
||||
"""Return stable local CLI capability flags for humans and agents."""
|
||||
return {
|
||||
"controlled_multi_install_integrations": True,
|
||||
"integration_use_command": True,
|
||||
"multi_install_safe_registry_metadata": True,
|
||||
"integration_upgrade_command": True,
|
||||
"self_check_command": True,
|
||||
"workflow_catalog": True,
|
||||
"bundled_templates": True,
|
||||
}
|
||||
|
||||
|
||||
@app.command()
|
||||
def version():
|
||||
def version(
|
||||
features: bool = typer.Option(
|
||||
False,
|
||||
"--features",
|
||||
help="Show local CLI feature capabilities.",
|
||||
),
|
||||
json_output: bool = typer.Option(
|
||||
False,
|
||||
"--json",
|
||||
help="Emit feature capabilities as JSON. Requires --features.",
|
||||
),
|
||||
):
|
||||
"""Display version and system information."""
|
||||
import platform
|
||||
|
||||
show_banner()
|
||||
|
||||
cli_version = get_speckit_version()
|
||||
|
||||
if json_output and not features:
|
||||
console.print("[red]Error:[/red] --json requires --features.")
|
||||
raise typer.Exit(1)
|
||||
|
||||
if features:
|
||||
capabilities = _feature_capabilities()
|
||||
if json_output:
|
||||
payload = {"version": cli_version, "features": capabilities}
|
||||
console.print(json.dumps(payload, indent=2))
|
||||
return
|
||||
|
||||
console.print(f"Spec Kit CLI: {cli_version}")
|
||||
console.print()
|
||||
console.print("Features:")
|
||||
for key, enabled in capabilities.items():
|
||||
label = key.replace("_", " ")
|
||||
console.print(f"- {label}: {'yes' if enabled else 'no'}")
|
||||
return
|
||||
|
||||
show_banner()
|
||||
|
||||
info_table = Table(show_header=False, box=None, padding=(0, 2))
|
||||
info_table.add_column("Key", style="cyan", justify="right")
|
||||
info_table.add_column("Value", style="white")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Tests for the --version CLI flag."""
|
||||
"""Tests for CLI version reporting."""
|
||||
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from typer.testing import CliRunner
|
||||
@@ -33,3 +34,46 @@ class TestVersionFlag:
|
||||
result = runner.invoke(app, ["--version", "init"])
|
||||
assert result.exit_code == 0
|
||||
assert "specify 0.7.2" in result.output
|
||||
|
||||
|
||||
class TestVersionCommand:
|
||||
"""Test the `specify version` subcommand."""
|
||||
|
||||
def test_version_features_text(self):
|
||||
"""specify version --features prints local capability flags."""
|
||||
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
|
||||
result = runner.invoke(app, ["version", "--features"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Spec Kit CLI: 1.2.3" in result.output
|
||||
assert "Features:" in result.output
|
||||
assert "- controlled multi install integrations: yes" in result.output
|
||||
assert "- integration use command: yes" in result.output
|
||||
assert "- self check command: yes" in result.output
|
||||
|
||||
def test_version_features_json(self):
|
||||
"""specify version --features --json prints machine-readable capabilities."""
|
||||
with patch("specify_cli.get_speckit_version", return_value="1.2.3"):
|
||||
result = runner.invoke(app, ["version", "--features", "--json"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
payload = json.loads(result.output)
|
||||
assert payload == {
|
||||
"version": "1.2.3",
|
||||
"features": {
|
||||
"controlled_multi_install_integrations": True,
|
||||
"integration_use_command": True,
|
||||
"multi_install_safe_registry_metadata": True,
|
||||
"integration_upgrade_command": True,
|
||||
"self_check_command": True,
|
||||
"workflow_catalog": True,
|
||||
"bundled_templates": True,
|
||||
},
|
||||
}
|
||||
|
||||
def test_version_json_requires_features(self):
|
||||
"""specify version --json is rejected until a JSON surface exists."""
|
||||
result = runner.invoke(app, ["version", "--json"])
|
||||
|
||||
assert result.exit_code != 0
|
||||
assert "--json requires --features" in result.output
|
||||
|
||||
Reference in New Issue
Block a user