chore: deprecate --ai flag in favor of --integration on specify init (#2218)

* chore: deprecate --ai flag in favor of --integration on specify init

- Adds deprecation warning when --ai is used
- Shows equivalent --integration command replacement
- Handles generic integration with --commands-dir mapping
- Adds comprehensive test coverage for deprecation behavior
- Warning displays as prominent red panel above Next Steps
- --ai flag continues to function (non-breaking change)

Fixes #2169

* Address PR review feedback for issue #2169

- Use existing strip_ansi helper from conftest instead of duplicating ANSI escape pattern
- Properly escape ai_commands_dir with shlex.quote() to handle paths with spaces
- Add shlex import to support proper command-line argument escaping
This commit is contained in:
Manfred Riem
2026-04-14 15:12:27 -05:00
committed by GitHub
parent 3467d26b1c
commit 39c7b04e5e
2 changed files with 107 additions and 0 deletions

View File

@@ -5,6 +5,14 @@ import os
import yaml
from tests.conftest import strip_ansi
def _normalize_cli_output(output: str) -> str:
output = strip_ansi(output)
output = " ".join(output.split())
return output.strip()
class TestInitIntegrationFlag:
def test_integration_and_ai_mutually_exclusive(self, tmp_path):
@@ -77,6 +85,59 @@ class TestInitIntegrationFlag:
assert result.exit_code == 0
assert (project / ".github" / "agents" / "speckit.plan.agent.md").exists()
def test_ai_emits_deprecation_warning_with_integration_replacement(self, tmp_path):
from typer.testing import CliRunner
from specify_cli import app
project = tmp_path / "warn-ai"
project.mkdir()
old_cwd = os.getcwd()
try:
os.chdir(project)
runner = CliRunner()
result = runner.invoke(app, [
"init", "--here", "--ai", "copilot", "--script", "sh", "--no-git",
], catch_exceptions=False)
finally:
os.chdir(old_cwd)
normalized_output = _normalize_cli_output(result.output)
assert result.exit_code == 0, result.output
assert "Deprecation Warning" in normalized_output
assert "--ai" in normalized_output
assert "deprecated" in normalized_output
assert "no longer be available" in normalized_output
assert "1.0.0" in normalized_output
assert "--integration copilot" in normalized_output
assert normalized_output.index("Deprecation Warning") < normalized_output.index("Next Steps")
assert (project / ".github" / "agents" / "speckit.plan.agent.md").exists()
def test_ai_generic_warning_suggests_integration_options_equivalent(self, tmp_path):
from typer.testing import CliRunner
from specify_cli import app
project = tmp_path / "warn-generic"
project.mkdir()
old_cwd = os.getcwd()
try:
os.chdir(project)
runner = CliRunner()
result = runner.invoke(app, [
"init", "--here", "--ai", "generic", "--ai-commands-dir", ".myagent/commands",
"--script", "sh", "--no-git",
], catch_exceptions=False)
finally:
os.chdir(old_cwd)
normalized_output = _normalize_cli_output(result.output)
assert result.exit_code == 0, result.output
assert "Deprecation Warning" in normalized_output
assert "--integration generic" in normalized_output
assert "--integration-options" in normalized_output
assert ".myagent/commands" in normalized_output
assert normalized_output.index("Deprecation Warning") < normalized_output.index("Next Steps")
assert (project / ".myagent" / "commands" / "speckit.plan.md").exists()
def test_ai_claude_here_preserves_preexisting_commands(self, tmp_path):
from typer.testing import CliRunner
from specify_cli import app