mirror of
https://github.com/github/spec-kit.git
synced 2026-03-16 18:33:07 +00:00
Fix parameter ordering issues in CLI (#1669)
* chore: bump version to v0.0.6 [skip ci] * Fix parameter ordering issues in CLI (#1641) - Add validation to detect when option flags are consumed as values - Provide clear error messages with helpful hints and examples - Add 5 comprehensive tests to prevent regressions - Update CODEOWNERS to @mnriem - Bump version to 0.1.6 with changelog entry Fixes: #1641 * Fix ruff linting errors: remove f-string prefix from strings without placeholders --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,3 +1,3 @@
|
||||
# Global code owner
|
||||
* @localden
|
||||
* @mnriem
|
||||
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -2,12 +2,23 @@
|
||||
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
All notable changes to the Specify CLI and templates are documented here.
|
||||
Recent changes to the Specify CLI and templates are documented here.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.1.5] - Unreleased
|
||||
## [0.1.6] - 2026-02-23
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Parameter Ordering Issues (#1641)**: Fixed CLI parameter parsing issue where option flags were incorrectly consumed as values for preceding options
|
||||
- Added validation to detect when `--ai` or `--ai-commands-dir` incorrectly consume following flags like `--here` or `--ai-skills`
|
||||
- Now provides clear error messages: "Invalid value for --ai: '--here'"
|
||||
- Includes helpful hints suggesting proper usage and listing available agents
|
||||
- Commands like `specify init --ai-skills --ai --here` now fail with actionable feedback instead of confusing "Must specify project name" errors
|
||||
- Added comprehensive test suite (5 new tests) to prevent regressions
|
||||
|
||||
## [0.1.5] - 2026-02-21
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -16,13 +27,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Affected agents now work correctly: copilot (`.github/agents/`), opencode (`.opencode/command/`), windsurf (`.windsurf/workflows/`), codex (`.codex/prompts/`), kilocode (`.kilocode/workflows/`), q (`.amazonq/prompts/`), and agy (`.agent/workflows/`)
|
||||
- The `install_ai_skills()` function now uses the correct path for all agents instead of assuming `commands/` for everyone
|
||||
|
||||
## [0.1.4] - Unreleased
|
||||
## [0.1.4] - 2026-02-20
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Qoder CLI detection**: Renamed `AGENT_CONFIG` key from `"qoder"` to `"qodercli"` to match the actual executable name, fixing `specify check` and `specify init --ai` detection failures
|
||||
|
||||
## [0.1.3] - Unreleased
|
||||
## [0.1.3] - 2026-02-20
|
||||
|
||||
### Added
|
||||
|
||||
@@ -69,7 +80,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
## [0.0.94] - 2026-02-11
|
||||
|
||||
- Add stale workflow for 180-day inactive issues and PRs (#1594)
|
||||
|
||||
## [0.0.93] - 2026-02-10
|
||||
|
||||
- Add modular extension system (#1551)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "specify-cli"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
|
||||
@@ -1256,6 +1256,20 @@ def init(
|
||||
|
||||
show_banner()
|
||||
|
||||
# Detect when option values are likely misinterpreted flags (parameter ordering issue)
|
||||
if ai_assistant and ai_assistant.startswith("--"):
|
||||
console.print(f"[red]Error:[/red] Invalid value for --ai: '{ai_assistant}'")
|
||||
console.print("[yellow]Hint:[/yellow] Did you forget to provide a value for --ai?")
|
||||
console.print("[yellow]Example:[/yellow] specify init --ai claude --here")
|
||||
console.print(f"[yellow]Available agents:[/yellow] {', '.join(AGENT_CONFIG.keys())}")
|
||||
raise typer.Exit(1)
|
||||
|
||||
if ai_commands_dir and ai_commands_dir.startswith("--"):
|
||||
console.print(f"[red]Error:[/red] Invalid value for --ai-commands-dir: '{ai_commands_dir}'")
|
||||
console.print("[yellow]Hint:[/yellow] Did you forget to provide a value for --ai-commands-dir?")
|
||||
console.print("[yellow]Example:[/yellow] specify init --ai generic --ai-commands-dir .myagent/commands/")
|
||||
raise typer.Exit(1)
|
||||
|
||||
if project_name == ".":
|
||||
here = True
|
||||
project_name = None # Clear project_name to use existing validation logic
|
||||
|
||||
@@ -630,3 +630,65 @@ class TestCliValidation:
|
||||
plain = re.sub(r'\x1b\[[0-9;]*m', '', result.output)
|
||||
assert "--ai-skills" in plain
|
||||
assert "agent skills" in plain.lower()
|
||||
|
||||
|
||||
class TestParameterOrderingIssue:
|
||||
"""Test fix for GitHub issue #1641: parameter ordering issues."""
|
||||
|
||||
def test_ai_flag_consuming_here_flag(self):
|
||||
"""--ai without value should not consume --here flag (issue #1641)."""
|
||||
from typer.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
# This used to fail with "Must specify project name" because --here was consumed by --ai
|
||||
result = runner.invoke(app, ["init", "--ai-skills", "--ai", "--here"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "Invalid value for --ai" in result.output
|
||||
assert "--here" in result.output # Should mention the invalid value
|
||||
|
||||
def test_ai_flag_consuming_ai_skills_flag(self):
|
||||
"""--ai without value should not consume --ai-skills flag."""
|
||||
from typer.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
# This should fail with helpful error about missing --ai value
|
||||
result = runner.invoke(app, ["init", "--here", "--ai", "--ai-skills"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "Invalid value for --ai" in result.output
|
||||
assert "--ai-skills" in result.output # Should mention the invalid value
|
||||
|
||||
def test_error_message_provides_hint(self):
|
||||
"""Error message should provide helpful hint about missing value."""
|
||||
from typer.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["init", "--ai", "--here"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "Hint:" in result.output or "hint" in result.output.lower()
|
||||
assert "forget to provide a value" in result.output.lower()
|
||||
|
||||
def test_error_message_lists_available_agents(self):
|
||||
"""Error message should list available agents."""
|
||||
from typer.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["init", "--ai", "--here"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
# Should mention some known agents
|
||||
output_lower = result.output.lower()
|
||||
assert any(agent in output_lower for agent in ["claude", "copilot", "gemini"])
|
||||
|
||||
def test_ai_commands_dir_consuming_flag(self):
|
||||
"""--ai-commands-dir without value should not consume next flag."""
|
||||
from typer.testing import CliRunner
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(app, ["init", "myproject", "--ai", "generic", "--ai-commands-dir", "--here"])
|
||||
|
||||
assert result.exit_code == 1
|
||||
assert "Invalid value for --ai-commands-dir" in result.output
|
||||
assert "--here" in result.output
|
||||
|
||||
Reference in New Issue
Block a user