Skip to content

Commit 5a903c7

Browse files
authored
Merge branch 'main' into main
2 parents d903f17 + f444ccb commit 5a903c7

File tree

7 files changed

+139
-16
lines changed

7 files changed

+139
-16
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Global code owner
2-
* @localden
2+
* @mnriem
33

CHANGELOG.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22

33
<!-- markdownlint-disable MD024 -->
44

5-
All notable changes to the Specify CLI and templates are documented here.
5+
Recent changes to the Specify CLI and templates are documented here.
66

77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10-
## [0.1.5] - Unreleased
10+
## [0.1.6] - 2026-02-23
11+
12+
### Fixed
13+
14+
- **Parameter Ordering Issues (#1641)**: Fixed CLI parameter parsing issue where option flags were incorrectly consumed as values for preceding options
15+
- Added validation to detect when `--ai` or `--ai-commands-dir` incorrectly consume following flags like `--here` or `--ai-skills`
16+
- Now provides clear error messages: "Invalid value for --ai: '--here'"
17+
- Includes helpful hints suggesting proper usage and listing available agents
18+
- Commands like `specify init --ai-skills --ai --here` now fail with actionable feedback instead of confusing "Must specify project name" errors
19+
- Added comprehensive test suite (5 new tests) to prevent regressions
20+
21+
## [0.1.5] - 2026-02-21
1122

1223
### Fixed
1324

@@ -16,13 +27,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1627
- 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/`)
1728
- The `install_ai_skills()` function now uses the correct path for all agents instead of assuming `commands/` for everyone
1829

19-
## [0.1.4] - Unreleased
30+
## [0.1.4] - 2026-02-20
2031

2132
### Fixed
2233

2334
- **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
2435

25-
## [0.1.3] - Unreleased
36+
## [0.1.3] - 2026-02-20
2637

2738
### Added
2839

@@ -69,7 +80,3 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6980
## [0.0.94] - 2026-02-11
7081

7182
- Add stale workflow for 180-day inactive issues and PRs (#1594)
72-
73-
## [0.0.93] - 2026-02-10
74-
75-
- Add modular extension system (#1551)

docs/quickstart.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ Then, use the `/speckit.implement` slash command to execute the plan.
8181
/speckit.implement
8282
```
8383

84+
> [!TIP]
85+
> **Phased Implementation**: For complex projects, implement in phases to avoid overwhelming the agent's context. Start with core functionality, validate it works, then add features incrementally.
86+
8487
## Detailed Example: Building Taskify
8588

8689
Here's a complete example of building a team productivity platform:
@@ -135,7 +138,15 @@ Be specific about your tech stack and technical requirements:
135138
/speckit.plan We are going to generate this using .NET Aspire, using Postgres as the database. The frontend should use Blazor server with drag-and-drop task boards, real-time updates. There should be a REST API created with a projects API, tasks API, and a notifications API.
136139
```
137140
138-
### Step 6: Validate and Implement
141+
### Step 6: Define Tasks
142+
143+
Generate an actionable task list using the `/speckit.tasks` command:
144+
145+
```bash
146+
/speckit.tasks
147+
```
148+
149+
### Step 7: Validate and Implement
139150
140151
Have your AI agent audit the implementation plan using `/speckit.analyze`:
141152
@@ -149,6 +160,9 @@ Finally, implement the solution:
149160
/speckit.implement
150161
```
151162
163+
> [!TIP]
164+
> **Phased Implementation**: For large projects like Taskify, consider implementing in phases (e.g., Phase 1: Basic project/task structure, Phase 2: Kanban functionality, Phase 3: Comments and assignments). This prevents context saturation and allows for validation at each stage.
165+
152166
## Key Principles
153167
154168
- **Be explicit** about what you're building and why

extensions/catalog.community.json

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
11
{
22
"schema_version": "1.0",
3-
"updated_at": "2026-02-20T00:00:00Z",
3+
"updated_at": "2026-02-22T00:00:00Z",
44
"catalog_url": "https://raw.githubusercontent.com/github/spec-kit/main/extensions/catalog.community.json",
55
"extensions": {
6+
"cleanup": {
7+
"name": "Cleanup Extension",
8+
"id": "cleanup",
9+
"description": "Post-implementation quality gate that reviews changes, fixes small issues (scout rule), creates tasks for medium issues, and generates analysis for large issues.",
10+
"author": "dsrednicki",
11+
"version": "1.0.0",
12+
"download_url": "https://github.com/dsrednicki/spec-kit-cleanup/archive/refs/tags/v1.0.0.zip",
13+
"repository": "https://github.com/dsrednicki/spec-kit-cleanup",
14+
"homepage": "https://github.com/dsrednicki/spec-kit-cleanup",
15+
"documentation": "https://github.com/dsrednicki/spec-kit-cleanup/blob/main/README.md",
16+
"changelog": "https://github.com/dsrednicki/spec-kit-cleanup/blob/main/CHANGELOG.md",
17+
"license": "MIT",
18+
"requires": {
19+
"speckit_version": ">=0.1.0"
20+
},
21+
"provides": {
22+
"commands": 1,
23+
"hooks": 1
24+
},
25+
"tags": ["quality", "tech-debt", "review", "cleanup", "scout-rule"],
26+
"verified": false,
27+
"downloads": 0,
28+
"stars": 0,
29+
"created_at": "2026-02-22T00:00:00Z",
30+
"updated_at": "2026-02-22T00:00:00Z"
31+
},
632
"v-model": {
733
"name": "V-Model Extension Pack",
834
"id": "v-model",
935
"description": "Enforces V-Model paired generation of development specs and test specs with full traceability.",
1036
"author": "leocamello",
11-
"version": "0.2.0",
12-
"download_url": "https://github.com/leocamello/spec-kit-v-model/archive/refs/tags/v0.2.0.zip",
37+
"version": "0.4.0",
38+
"download_url": "https://github.com/leocamello/spec-kit-v-model/archive/refs/tags/v0.4.0.zip",
1339
"repository": "https://github.com/leocamello/spec-kit-v-model",
1440
"homepage": "https://github.com/leocamello/spec-kit-v-model",
1541
"documentation": "https://github.com/leocamello/spec-kit-v-model/blob/main/README.md",
@@ -19,15 +45,15 @@
1945
"speckit_version": ">=0.1.0"
2046
},
2147
"provides": {
22-
"commands": 5,
48+
"commands": 9,
2349
"hooks": 1
2450
},
2551
"tags": ["v-model", "traceability", "testing", "compliance", "safety-critical"],
2652
"verified": false,
2753
"downloads": 0,
2854
"stars": 0,
2955
"created_at": "2026-02-20T00:00:00Z",
30-
"updated_at": "2026-02-20T00:00:00Z"
56+
"updated_at": "2026-02-22T00:00:00Z"
3157
}
3258
}
3359
}

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "specify-cli"
3-
version = "0.0.1"
3+
version = "0.1.6"
44
description = "Specify CLI, part of GitHub Spec Kit. A tool to bootstrap your projects for Spec-Driven Development (SDD)."
55
requires-python = ">=3.11"
66
dependencies = [

src/specify_cli/__init__.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,20 @@ def init(
12561256

12571257
show_banner()
12581258

1259+
# Detect when option values are likely misinterpreted flags (parameter ordering issue)
1260+
if ai_assistant and ai_assistant.startswith("--"):
1261+
console.print(f"[red]Error:[/red] Invalid value for --ai: '{ai_assistant}'")
1262+
console.print("[yellow]Hint:[/yellow] Did you forget to provide a value for --ai?")
1263+
console.print("[yellow]Example:[/yellow] specify init --ai claude --here")
1264+
console.print(f"[yellow]Available agents:[/yellow] {', '.join(AGENT_CONFIG.keys())}")
1265+
raise typer.Exit(1)
1266+
1267+
if ai_commands_dir and ai_commands_dir.startswith("--"):
1268+
console.print(f"[red]Error:[/red] Invalid value for --ai-commands-dir: '{ai_commands_dir}'")
1269+
console.print("[yellow]Hint:[/yellow] Did you forget to provide a value for --ai-commands-dir?")
1270+
console.print("[yellow]Example:[/yellow] specify init --ai generic --ai-commands-dir .myagent/commands/")
1271+
raise typer.Exit(1)
1272+
12591273
if project_name == ".":
12601274
here = True
12611275
project_name = None # Clear project_name to use existing validation logic

tests/test_ai_skills.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,65 @@ def test_ai_skills_flag_appears_in_help(self):
630630
plain = re.sub(r'\x1b\[[0-9;]*m', '', result.output)
631631
assert "--ai-skills" in plain
632632
assert "agent skills" in plain.lower()
633+
634+
635+
class TestParameterOrderingIssue:
636+
"""Test fix for GitHub issue #1641: parameter ordering issues."""
637+
638+
def test_ai_flag_consuming_here_flag(self):
639+
"""--ai without value should not consume --here flag (issue #1641)."""
640+
from typer.testing import CliRunner
641+
642+
runner = CliRunner()
643+
# This used to fail with "Must specify project name" because --here was consumed by --ai
644+
result = runner.invoke(app, ["init", "--ai-skills", "--ai", "--here"])
645+
646+
assert result.exit_code == 1
647+
assert "Invalid value for --ai" in result.output
648+
assert "--here" in result.output # Should mention the invalid value
649+
650+
def test_ai_flag_consuming_ai_skills_flag(self):
651+
"""--ai without value should not consume --ai-skills flag."""
652+
from typer.testing import CliRunner
653+
654+
runner = CliRunner()
655+
# This should fail with helpful error about missing --ai value
656+
result = runner.invoke(app, ["init", "--here", "--ai", "--ai-skills"])
657+
658+
assert result.exit_code == 1
659+
assert "Invalid value for --ai" in result.output
660+
assert "--ai-skills" in result.output # Should mention the invalid value
661+
662+
def test_error_message_provides_hint(self):
663+
"""Error message should provide helpful hint about missing value."""
664+
from typer.testing import CliRunner
665+
666+
runner = CliRunner()
667+
result = runner.invoke(app, ["init", "--ai", "--here"])
668+
669+
assert result.exit_code == 1
670+
assert "Hint:" in result.output or "hint" in result.output.lower()
671+
assert "forget to provide a value" in result.output.lower()
672+
673+
def test_error_message_lists_available_agents(self):
674+
"""Error message should list available agents."""
675+
from typer.testing import CliRunner
676+
677+
runner = CliRunner()
678+
result = runner.invoke(app, ["init", "--ai", "--here"])
679+
680+
assert result.exit_code == 1
681+
# Should mention some known agents
682+
output_lower = result.output.lower()
683+
assert any(agent in output_lower for agent in ["claude", "copilot", "gemini"])
684+
685+
def test_ai_commands_dir_consuming_flag(self):
686+
"""--ai-commands-dir without value should not consume next flag."""
687+
from typer.testing import CliRunner
688+
689+
runner = CliRunner()
690+
result = runner.invoke(app, ["init", "myproject", "--ai", "generic", "--ai-commands-dir", "--here"])
691+
692+
assert result.exit_code == 1
693+
assert "Invalid value for --ai-commands-dir" in result.output
694+
assert "--here" in result.output

0 commit comments

Comments
 (0)