Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Global code owner
* @localden
* @mnriem

23 changes: 15 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment on lines +10 to +21
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHANGELOG no longer includes an "Unreleased" section (it now jumps straight into dated releases). If any tooling/docs expect Keep a Changelog structure, this makes it harder to stage changes before a release. Consider reintroducing an "Unreleased" section at the top and moving the 0.1.6 notes under a released heading only when cutting the release.

Copilot uses AI. Check for mistakes.

### Fixed

Expand All @@ -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

Expand Down Expand Up @@ -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)
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes older changelog history (e.g., the 0.0.93 entry and anything below it). Changelogs are typically append-only; please restore the removed sections so historical release notes remain available.

Suggested change
- Add stale workflow for 180-day inactive issues and PRs (#1594)
- Add stale workflow for 180-day inactive issues and PRs (#1594)
## [0.0.93] - 2026-02-10
- Historical changelog entry for version 0.0.93 was previously present and is preserved in the project’s git history (tag `v0.0.93`).
- Refer to the `CHANGELOG.md` content from that tag or the corresponding GitHub release page for the full list of changes.
## Earlier releases (0.0.1–0.0.92)
- Detailed release notes for versions 0.0.1 through 0.0.92 are also available in version control history.
- To view them, check out an earlier revision of `CHANGELOG.md` (before this truncation) or consult the project’s tagged releases.

Copilot uses AI. Check for mistakes.

## [0.0.93] - 2026-02-10

- Add modular extension system (#1551)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -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 = [
Expand Down
14 changes: 14 additions & 0 deletions src/specify_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Comment on lines +1259 to +1265
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new validation block duplicates agent-list rendering and error formatting that already exists later in init() (e.g., the "Invalid AI assistant" path). To reduce drift and keep messaging consistent, consider factoring the shared "available agents" string / rendering into a small helper or constant and reusing it in both places.

Copilot uses AI. Check for mistakes.

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
Expand Down
62 changes: 62 additions & 0 deletions tests/test_ai_skills.py
Original file line number Diff line number Diff line change
Expand Up @@ -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