From d0a21a6bbf2e432db867b40a7637c9c6039c627c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 21 Feb 2026 14:08:10 +0000 Subject: [PATCH 1/3] chore: bump version to v0.0.6 [skip ci] --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2567f0ed4..a41456108 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "specify-cli" -version = "0.1.5" +version = "0.0.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 = [ From a658341f226c4457b64f8df948a2389d5c2b81c5 Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:11:56 -0600 Subject: [PATCH 2/3] 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 --- .github/CODEOWNERS | 2 +- CHANGELOG.md | 23 +++++++++----- pyproject.toml | 2 +- src/specify_cli/__init__.py | 14 +++++++++ tests/test_ai_skills.py | 62 +++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 10 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index efb95fc0e..a60b7a030 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,3 @@ # Global code owner -* @localden +* @mnriem diff --git a/CHANGELOG.md b/CHANGELOG.md index 7163d2b89..741ce5d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,23 @@ -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) diff --git a/pyproject.toml b/pyproject.toml index a41456108..5f6a2eb7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "specify-cli" -version = "0.0.6" +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 = [ diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index f9a713999..e1ce48f12 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -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(f"[yellow]Hint:[/yellow] Did you forget to provide a value for --ai?") + console.print(f"[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(f"[yellow]Hint:[/yellow] Did you forget to provide a value for --ai-commands-dir?") + console.print(f"[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 diff --git a/tests/test_ai_skills.py b/tests/test_ai_skills.py index d4c607b64..3eec4a419 100644 --- a/tests/test_ai_skills.py +++ b/tests/test_ai_skills.py @@ -630,3 +630,65 @@ def test_ai_skills_flag_appears_in_help(self): 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 From 03abbb1a5ba619d694455fb95c243df6d380f81b Mon Sep 17 00:00:00 2001 From: Manfred Riem <15701806+mnriem@users.noreply.github.com> Date: Mon, 23 Feb 2026 13:15:20 -0600 Subject: [PATCH 3/3] Fix ruff linting errors: remove f-string prefix from strings without placeholders --- src/specify_cli/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/specify_cli/__init__.py b/src/specify_cli/__init__.py index e1ce48f12..5651ac722 100644 --- a/src/specify_cli/__init__.py +++ b/src/specify_cli/__init__.py @@ -1259,15 +1259,15 @@ def init( # 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(f"[yellow]Hint:[/yellow] Did you forget to provide a value for --ai?") - console.print(f"[yellow]Example:[/yellow] specify init --ai claude --here") + 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(f"[yellow]Hint:[/yellow] Did you forget to provide a value for --ai-commands-dir?") - console.print(f"[yellow]Example:[/yellow] specify init --ai generic --ai-commands-dir .myagent/commands/") + 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 == ".":