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.
|
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:
|
A quick version check is also available via:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -1155,15 +1155,59 @@ def check():
|
|||||||
if not any(agent_results.values()):
|
if not any(agent_results.values()):
|
||||||
console.print("[dim]Tip: Install a coding agent for the best experience[/dim]")
|
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()
|
@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."""
|
"""Display version and system information."""
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
show_banner()
|
|
||||||
|
|
||||||
cli_version = get_speckit_version()
|
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 = Table(show_header=False, box=None, padding=(0, 2))
|
||||||
info_table.add_column("Key", style="cyan", justify="right")
|
info_table.add_column("Key", style="cyan", justify="right")
|
||||||
info_table.add_column("Value", style="white")
|
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 unittest.mock import patch
|
||||||
|
|
||||||
from typer.testing import CliRunner
|
from typer.testing import CliRunner
|
||||||
@@ -33,3 +34,46 @@ class TestVersionFlag:
|
|||||||
result = runner.invoke(app, ["--version", "init"])
|
result = runner.invoke(app, ["--version", "init"])
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert "specify 0.7.2" in result.output
|
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