-
Notifications
You must be signed in to change notification settings - Fork 7.5k
feat(extensions,presets): add priority-based resolution ordering #1855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
mnriem
merged 12 commits into
github:main
from
mbachorik:feature/extension-priority-resolution
Mar 17, 2026
Merged
Changes from 9 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
7546a7a
feat(extensions,presets): add priority-based resolution ordering
9f12188
fix: address code review feedback
e5b1a1a
fix: address additional review feedback
e1341fc
fix: restore defensive code and RFC descriptions lost in rebase
be7edcb
fix: add defensive code to presets list_by_priority()
3ed54d3
fix: address reviewer feedback on priority resolution
a6e1d24
fix: DRY refactor and strengthen test assertions
0823ed4
fix: add isinstance(dict) checks for corrupted registry entries
adb3e59
fix: normalize priority display to match resolution behavior
9340b25
fix: repair corrupted priority values in set-priority commands
a040036
fix: harden registry update methods against corrupted entries
c5bf302
fix: use safe fallback for version in list_installed()
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| **Specify CLI** is a Python CLI tool that bootstraps projects for Spec-Driven Development (SDD). It sets up directory structures, templates, and AI agent integrations for multiple coding assistants (Claude Code, Copilot, Cursor, Gemini, etc.). | ||
|
|
||
| ## Development Commands | ||
|
|
||
| ```bash | ||
| # Install dependencies | ||
| uv sync | ||
|
|
||
| # Run CLI locally | ||
| uv run specify --help | ||
| uv run specify init <project-name> --ai claude | ||
| uv run specify check | ||
|
|
||
| # Run tests | ||
| uv run pytest # All tests | ||
| uv run pytest tests/test_extensions.py # Single file | ||
| uv run pytest -k "test_name" # Single test by name | ||
|
|
||
| # Test with coverage | ||
| uv run pytest --cov=src --cov-report=term-missing | ||
|
|
||
| # Generate release packages locally (for testing template changes) | ||
| ./.github/workflows/scripts/create-release-packages.sh v1.0.0 | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Source Structure | ||
|
|
||
| - `src/specify_cli/__init__.py` - Main CLI implementation (typer-based) | ||
| - `src/specify_cli/agents.py` - CommandRegistrar for agent-specific command formats | ||
| - `src/specify_cli/extensions.py` - Extension manager for modular packages | ||
| - `src/specify_cli/presets.py` - Preset manager for versioned template collections | ||
|
|
||
| ### Key Components | ||
|
|
||
| **AGENT_CONFIG** (in `__init__.py`): Single source of truth for all supported AI agents. Dictionary key must match the actual CLI tool name (e.g., `"cursor-agent"` not `"cursor"`). Fields: | ||
|
|
||
| - `name`: Display name | ||
| - `folder`: Agent directory (e.g., `.claude/`) | ||
| - `commands_subdir`: Where commands live (e.g., `commands`, `workflows`, `prompts`) | ||
| - `requires_cli`: Whether agent needs CLI tool check | ||
|
|
||
| **CommandRegistrar** (in `agents.py`): Handles writing command files to agent directories. Has its own `AGENT_CONFIGS` dict with format-specific details (file extension, argument placeholder style). Must stay in sync with `AGENT_CONFIG` when adding new agents. | ||
|
|
||
| **Extension System** (in `extensions.py`): | ||
|
|
||
| - `ExtensionManifest`: Validates `extension.yml` files | ||
| - `ExtensionManager`: Handles install/remove lifecycle | ||
| - `ExtensionCatalog`: Fetches from remote catalog with caching | ||
| - `HookExecutor`: Manages extension hooks | ||
|
|
||
| **Preset System** (in `presets.py`): | ||
|
|
||
| - `PresetManifest`: Validates `preset.yml` files | ||
| - `PresetManager`: Handles preset install/remove lifecycle | ||
| - `PresetCatalog`: Fetches presets from remote catalogs with priority stacking | ||
|
|
||
| ### Templates | ||
|
|
||
| - `templates/commands/` - Command templates (Markdown format with frontmatter) | ||
| - `templates/*.md` - Spec, plan, tasks, and constitution templates | ||
|
|
||
| ## Version Management | ||
|
|
||
| Changes to `__init__.py` require: | ||
|
|
||
| 1. Version bump in `pyproject.toml` | ||
| 2. Entry in `CHANGELOG.md` | ||
|
|
||
| ## Adding New Agent Support | ||
|
|
||
| 1. Add to `AGENT_CONFIG` in `__init__.py` using actual CLI tool name as key | ||
| 2. Update `--ai` help text in `init()` command | ||
| 3. Update README.md supported agents table | ||
| 4. Update release scripts in `.github/workflows/scripts/` | ||
| 5. Update context scripts in `scripts/bash/` and `scripts/powershell/` | ||
|
|
||
| See [AGENTS.md](AGENTS.md) for detailed guide. | ||
|
|
||
| ## Testing Guidelines | ||
|
|
||
| - Tests are in `tests/` using pytest | ||
| - `test_extensions.py` - Extension system tests | ||
| - `test_presets.py` - Preset system tests | ||
| - `test_ai_skills.py` - AI skills/command generation tests | ||
| - `test_agent_config_consistency.py` - Validates AGENT_CONFIG consistency | ||
| - `test_cursor_frontmatter.py` - Cursor-specific frontmatter handling | ||
|
|
||
| ## GitHub PR Reviews | ||
|
|
||
| The GraphQL API with `reviewThreads` and `isResolved` filter is the reliable way to get unresolved Copilot review comments. The REST API does not expose resolution status. | ||
|
|
||
| ```bash | ||
| # Get unresolved review comments on a PR | ||
| gh api graphql -f query=' | ||
| query { | ||
| repository(owner: "github", name: "spec-kit") { | ||
| pullRequest(number: PR_NUMBER) { | ||
| reviewThreads(first: 50) { | ||
| nodes { | ||
| isResolved | ||
| isOutdated | ||
| path | ||
| line | ||
| comments(first: 3) { | ||
| nodes { | ||
| body | ||
| author { login } | ||
| createdAt | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | {path, line, outdated: .isOutdated, comment: .comments.nodes[0].body[0:200]}' | ||
| ``` | ||
|
|
||
| Replace `PR_NUMBER` with the actual PR number. This returns only unresolved threads with their file path, line number, and whether the comment is outdated (code changed since comment). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.