Skip to content

Commit 75fe417

Browse files
committed
feat: merge upstream v0.3.0 preset system
Merged upstream commits: - 69ee7a8: feat(presets): Pluggable preset system with catalog, resolver, and skills propagation - f92d81b: chore: bump version to 0.3.0 - 4a32344: feat: Add DocGuard CDD enforcement extension to community catalog Fork-specific preservations: - Skills module (src/specify_cli/skills/) with 12+ imports - Bundled extensions (levelup, architect, quick, product) - Governance variables (TEAM_DIRECTIVES, CONSTITUTION, AD, ADR, CONTEXT) - Package name: agentic-sdlc-specify-cli - adlc.* command prefix support in extensions.py New features from upstream: - Preset CLI commands: list, add, remove, search, resolve, info - Preset catalog with priority-based stacking - --preset option on specify init - resolve_template() in bash/PowerShell scripts - CommandRegistrar moved to shared agents.py Version: 0.0.139
2 parents 8310d2b + 4a32344 commit 75fe417

35 files changed

Lines changed: 5704 additions & 622 deletions

CHANGELOG.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@ All notable changes to the Specify CLI and templates are documented here.
77
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
88
and this project adheres to to [Semantic Versioning](https://semver.org/spec/v2.0.0/).
99

10+
## [0.0.139] - 2026-03-14
11+
12+
### Added
13+
14+
- **Preset system**: Merged upstream v0.3.0 preset system with pluggable template/command overrides
15+
- New `specify preset` CLI commands: list, add, remove, search, resolve, info
16+
- Preset catalog support with priority-based stacking
17+
- `--preset` option on `specify init` for preset installation during setup
18+
- New files: `presets.py`, `agents.py`, `presets/` directory with scaffold and self-test examples
19+
- Shell scripts (`common.sh`, `common.ps1`) now include `resolve_template()` / `Resolve-Template` functions
20+
- **DocGuard extension**: Added to community catalog for CDD enforcement
21+
22+
### Changed
23+
24+
- **CommandRegistrar refactored**: Moved to shared `agents.py` module for use by both extensions and presets
25+
- **Template resolution**: Scripts now use preset-aware template resolution with priority stack
26+
27+
1028
## [0.0.138] - 2026-03-14
1129

1230
### Fixed
@@ -136,6 +154,51 @@ and this project adheres to to [Semantic Versioning](https://semver.org/spec/v2.
136154
- Migration path: All levelup commands now work directly with upstream repository
137155
- **Removed**: Redundant `TEAM_DIRECTIVES_EXISTS` flag from setup scripts - existence is now checked implicitly via `TEAM_DIRECTIVES` value
138156

157+
## [0.3.0] - 2026-03-13
158+
159+
### Changed
160+
161+
- No changes have been documented for this release yet.
162+
163+
<!-- Entries for 0.2.x and earlier releases are documented in their respective sections below. -->
164+
- make c ignores consistent with c++ (#1747)
165+
- chore: bump version to 0.1.13 (#1746)
166+
- feat: add kiro-cli and AGENT_CONFIG consistency coverage (#1690)
167+
- feat: add verify extension to community catalog (#1726)
168+
- Add Retrospective Extension to community catalog README table (#1741)
169+
- fix(scripts): add empty description validation and branch checkout error handling (#1559)
170+
- fix: correct Copilot extension command registration (#1724)
171+
- fix(implement): remove Makefile from C ignore patterns (#1558)
172+
- Add sync extension to community catalog (#1728)
173+
- fix(checklist): clarify file handling behavior for append vs create (#1556)
174+
- fix(clarify): correct conflicting question limit from 10 to 5 (#1557)
175+
- chore: bump version to 0.1.12 (#1737)
176+
- fix: use RELEASE_PAT so tag push triggers release workflow (#1736)
177+
- fix: release-trigger uses release branch + PR instead of direct push to main (#1733)
178+
- fix: Split release process to sync pyproject.toml version with git tags (#1732)
179+
180+
181+
## [Unreleased]
182+
183+
### Added
184+
185+
- feat(presets): Pluggable preset system with preset catalog and template resolver
186+
- Preset manifest (`preset.yml`) with validation for artifact, command, and script types
187+
- `PresetManifest`, `PresetRegistry`, `PresetManager`, `PresetCatalog`, `PresetResolver` classes in `src/specify_cli/presets.py`
188+
- CLI commands: `specify preset search`, `specify preset add`, `specify preset list`, `specify preset remove`, `specify preset resolve`, `specify preset info`
189+
- CLI commands: `specify preset catalog list`, `specify preset catalog add`, `specify preset catalog remove` for multi-catalog management
190+
- `PresetCatalogEntry` dataclass and multi-catalog support mirroring the extension catalog system
191+
- `--preset` option for `specify init` to install presets during initialization
192+
- Priority-based preset resolution: presets with lower priority number win (`--priority` flag)
193+
- `resolve_template()` / `Resolve-Template` helpers in bash and PowerShell common scripts
194+
- Template resolution priority stack: overrides → presets → extensions → core
195+
- Preset catalog files (`presets/catalog.json`, `presets/catalog.community.json`)
196+
- Preset scaffold directory (`presets/scaffold/`)
197+
- Scripts updated to use template resolution instead of hardcoded paths
198+
- feat(presets): Preset command overrides now propagate to agent skills when `--ai-skills` was used during init
199+
- feat: `specify init` persists CLI options to `.specify/init-options.json` for downstream operations
200+
- feat(extensions): support `.extensionignore` to exclude files/folders during `specify extension add` (#1781)
201+
139202
## [0.2.1] - 2026-03-11
140203

141204
### Changed
@@ -185,6 +248,7 @@ and this project adheres to to [Semantic Versioning](https://semver.org/spec/v2.
185248
- fix: Split release process to sync pyproject.toml version with git tags (#1732)
186249

187250

251+
188252
## [Unreleased]
189253

190254
## [0.0.123] - 2026-03-12
@@ -221,6 +285,8 @@ and this project adheres to to [Semantic Versioning](https://semver.org/spec/v2.
221285

222286
- Fix lint errors from merge conflict: duplicate imports and missing functions in extensions.py and __init__.py
223287

288+
289+
224290
## [0.2.0] - 2026-03-09
225291

226292
### Changed

extensions/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ The following community-contributed extensions are available in [`catalog.commun
7474
|-----------|---------|-----|
7575
| Azure DevOps Integration | Sync user stories and tasks to Azure DevOps work items using OAuth authentication | [spec-kit-azure-devops](https://github.com/pragya247/spec-kit-azure-devops) |
7676
| Cleanup Extension | Post-implementation quality gate that reviews changes, fixes small issues (scout rule), creates tasks for medium issues, and generates analysis for large issues | [spec-kit-cleanup](https://github.com/dsrednicki/spec-kit-cleanup) |
77+
| DocGuard — CDD Enforcement | Canonical-Driven Development enforcement. Generates, validates, scores, and traces project documentation against 92 automated checks with config-aware traceability, quality labels, and AI-ready fix prompts. Zero dependencies. | [spec-kit-docguard](https://github.com/raccioly/docguard) |
7778
| Fleet Orchestrator | Orchestrate a full feature lifecycle with human-in-the-loop gates across all SpecKit phases | [spec-kit-fleet](https://github.com/sharathsatish/spec-kit-fleet) |
7879
| Jira Integration | Create Jira Epics, Stories, and Issues from spec-kit specifications and task breakdowns with configurable hierarchy and custom field support | [spec-kit-jira](https://github.com/mbachorik/spec-kit-jira) |
7980
| Project Health Check | Diagnose a Spec Kit project and report health issues across structure, agents, features, scripts, extensions, and git | [spec-kit-doctor](https://github.com/KhawarHabibKhan/spec-kit-doctor) |

extensions/catalog.community.json

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,48 @@
7474
"created_at": "2026-02-22T00:00:00Z",
7575
"updated_at": "2026-02-22T00:00:00Z"
7676
},
77+
"docguard": {
78+
"name": "DocGuard — CDD Enforcement",
79+
"id": "docguard",
80+
"description": "Canonical-Driven Development enforcement. Generates, validates, scores, and traces project documentation against 92 automated checks. Zero dependencies.",
81+
"author": "raccioly",
82+
"version": "0.8.0",
83+
"download_url": "https://github.com/raccioly/docguard/releases/download/v0.8.0/spec-kit-docguard-v0.8.0.zip",
84+
"repository": "https://github.com/raccioly/docguard",
85+
"homepage": "https://www.npmjs.com/package/docguard-cli",
86+
"documentation": "https://github.com/raccioly/docguard/blob/main/extensions/spec-kit-docguard/README.md",
87+
"changelog": "https://github.com/raccioly/docguard/blob/main/CHANGELOG.md",
88+
"license": "MIT",
89+
"requires": {
90+
"speckit_version": ">=0.1.0",
91+
"tools": [
92+
{
93+
"name": "node",
94+
"version": ">=18.0.0",
95+
"required": true
96+
}
97+
]
98+
},
99+
"provides": {
100+
"commands": 6,
101+
"hooks": 1
102+
},
103+
"tags": [
104+
"documentation",
105+
"validation",
106+
"quality",
107+
"cdd",
108+
"traceability",
109+
"ai-agents",
110+
"enforcement",
111+
"scoring"
112+
],
113+
"verified": false,
114+
"downloads": 0,
115+
"stars": 0,
116+
"created_at": "2026-03-13T00:00:00Z",
117+
"updated_at": "2026-03-13T00:00:00Z"
118+
},
77119
"doctor": {
78120
"name": "Project Health Check",
79121
"id": "doctor",
@@ -124,7 +166,12 @@
124166
"commands": 2,
125167
"hooks": 1
126168
},
127-
"tags": ["orchestration", "workflow", "human-in-the-loop", "parallel"],
169+
"tags": [
170+
"orchestration",
171+
"workflow",
172+
"human-in-the-loop",
173+
"parallel"
174+
],
128175
"verified": false,
129176
"downloads": 0,
130177
"stars": 0,
@@ -191,7 +238,12 @@
191238
"commands": 2,
192239
"hooks": 1
193240
},
194-
"tags": ["implementation", "automation", "loop", "copilot"],
241+
"tags": [
242+
"implementation",
243+
"automation",
244+
"loop",
245+
"copilot"
246+
],
195247
"verified": false,
196248
"downloads": 0,
197249
"stars": 0,
@@ -249,7 +301,15 @@
249301
"commands": 7,
250302
"hooks": 1
251303
},
252-
"tags": ["code-review", "quality", "review", "testing", "error-handling", "type-design", "simplification"],
304+
"tags": [
305+
"code-review",
306+
"quality",
307+
"review",
308+
"testing",
309+
"error-handling",
310+
"type-design",
311+
"simplification"
312+
],
253313
"verified": false,
254314
"downloads": 0,
255315
"stars": 0,

presets/ARCHITECTURE.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Preset System Architecture
2+
3+
This document describes the internal architecture of the preset system — how template resolution, command registration, and catalog management work under the hood.
4+
5+
For usage instructions, see [README.md](README.md).
6+
7+
## Template Resolution
8+
9+
When Spec Kit needs a template (e.g. `spec-template`), the `PresetResolver` walks a priority stack and returns the first match:
10+
11+
```mermaid
12+
flowchart TD
13+
A["resolve_template('spec-template')"] --> B{Override exists?}
14+
B -- Yes --> C[".specify/templates/overrides/spec-template.md"]
15+
B -- No --> D{Preset provides it?}
16+
D -- Yes --> E[".specify/presets/‹preset-id›/templates/spec-template.md"]
17+
D -- No --> F{Extension provides it?}
18+
F -- Yes --> G[".specify/extensions/‹ext-id›/templates/spec-template.md"]
19+
F -- No --> H[".specify/templates/spec-template.md"]
20+
21+
E -- "multiple presets?" --> I["lowest priority number wins"]
22+
I --> E
23+
24+
style C fill:#4caf50,color:#fff
25+
style E fill:#2196f3,color:#fff
26+
style G fill:#ff9800,color:#fff
27+
style H fill:#9e9e9e,color:#fff
28+
```
29+
30+
| Priority | Source | Path | Use case |
31+
|----------|--------|------|----------|
32+
| 1 (highest) | Override | `.specify/templates/overrides/` | One-off project-local tweaks |
33+
| 2 | Preset | `.specify/presets/<id>/templates/` | Shareable, stackable customizations |
34+
| 3 | Extension | `.specify/extensions/<id>/templates/` | Extension-provided templates |
35+
| 4 (lowest) | Core | `.specify/templates/` | Shipped defaults |
36+
37+
When multiple presets are installed, they're sorted by their `priority` field (lower number = higher precedence). This is set via `--priority` on `specify preset add`.
38+
39+
The resolution is implemented three times to ensure consistency:
40+
- **Python**: `PresetResolver` in `src/specify_cli/presets.py`
41+
- **Bash**: `resolve_template()` in `scripts/bash/common.sh`
42+
- **PowerShell**: `Resolve-Template` in `scripts/powershell/common.ps1`
43+
44+
## Command Registration
45+
46+
When a preset is installed with `type: "command"` entries, the `PresetManager` registers them into all detected agent directories using the shared `CommandRegistrar` from `src/specify_cli/agents.py`.
47+
48+
```mermaid
49+
flowchart TD
50+
A["specify preset add my-preset"] --> B{Preset has type: command?}
51+
B -- No --> Z["done (templates only)"]
52+
B -- Yes --> C{Extension command?}
53+
C -- "speckit.myext.cmd\n(3+ dot segments)" --> D{Extension installed?}
54+
D -- No --> E["skip (extension not active)"]
55+
D -- Yes --> F["register command"]
56+
C -- "speckit.specify\n(core command)" --> F
57+
F --> G["detect agent directories"]
58+
G --> H[".claude/commands/"]
59+
G --> I[".gemini/commands/"]
60+
G --> J[".github/agents/"]
61+
G --> K["... (17+ agents)"]
62+
H --> L["write .md (Markdown format)"]
63+
I --> M["write .toml (TOML format)"]
64+
J --> N["write .agent.md + .prompt.md"]
65+
66+
style E fill:#ff5722,color:#fff
67+
style L fill:#4caf50,color:#fff
68+
style M fill:#4caf50,color:#fff
69+
style N fill:#4caf50,color:#fff
70+
```
71+
72+
### Extension safety check
73+
74+
Command names follow the pattern `speckit.<ext-id>.<cmd-name>`. When a command has 3+ dot segments, the system extracts the extension ID and checks if `.specify/extensions/<ext-id>/` exists. If the extension isn't installed, the command is skipped — preventing orphan files referencing non-existent extensions.
75+
76+
Core commands (e.g. `speckit.specify`, with only 2 segments) are always registered.
77+
78+
### Agent format rendering
79+
80+
The `CommandRegistrar` renders commands differently per agent:
81+
82+
| Agent | Format | Extension | Arg placeholder |
83+
|-------|--------|-----------|-----------------|
84+
| Claude, Cursor, opencode, Windsurf, etc. | Markdown | `.md` | `$ARGUMENTS` |
85+
| Copilot | Markdown | `.agent.md` + `.prompt.md` | `$ARGUMENTS` |
86+
| Gemini, Qwen, Tabnine | TOML | `.toml` | `{{args}}` |
87+
88+
### Cleanup on removal
89+
90+
When `specify preset remove` is called, the registered commands are read from the registry metadata and the corresponding files are deleted from each agent directory, including Copilot companion `.prompt.md` files.
91+
92+
## Catalog System
93+
94+
```mermaid
95+
flowchart TD
96+
A["specify preset search"] --> B["PresetCatalog.get_active_catalogs()"]
97+
B --> C{SPECKIT_PRESET_CATALOG_URL set?}
98+
C -- Yes --> D["single custom catalog"]
99+
C -- No --> E{.specify/preset-catalogs.yml exists?}
100+
E -- Yes --> F["project-level catalog stack"]
101+
E -- No --> G{"~/.specify/preset-catalogs.yml exists?"}
102+
G -- Yes --> H["user-level catalog stack"]
103+
G -- No --> I["built-in defaults"]
104+
I --> J["default (install allowed)"]
105+
I --> K["community (discovery only)"]
106+
107+
style D fill:#ff9800,color:#fff
108+
style F fill:#2196f3,color:#fff
109+
style H fill:#2196f3,color:#fff
110+
style J fill:#4caf50,color:#fff
111+
style K fill:#9e9e9e,color:#fff
112+
```
113+
114+
Catalogs are fetched with a 1-hour cache (per-URL, SHA256-hashed cache files). Each catalog entry has a `priority` (for merge ordering) and `install_allowed` flag.
115+
116+
## Repository Layout
117+
118+
```
119+
presets/
120+
├── ARCHITECTURE.md # This file
121+
├── PUBLISHING.md # Guide for submitting presets to the catalog
122+
├── README.md # User guide
123+
├── catalog.json # Official preset catalog
124+
├── catalog.community.json # Community preset catalog
125+
├── scaffold/ # Scaffold for creating new presets
126+
│ ├── preset.yml # Example manifest
127+
│ ├── README.md # Guide for customizing the scaffold
128+
│ ├── commands/
129+
│ │ ├── speckit.specify.md # Core command override example
130+
│ │ └── speckit.myext.myextcmd.md # Extension command override example
131+
│ └── templates/
132+
│ ├── spec-template.md # Core template override example
133+
│ └── myext-template.md # Extension template override example
134+
└── self-test/ # Self-test preset (overrides all core templates)
135+
├── preset.yml
136+
├── commands/
137+
│ └── speckit.specify.md
138+
└── templates/
139+
├── spec-template.md
140+
├── plan-template.md
141+
├── tasks-template.md
142+
├── checklist-template.md
143+
├── constitution-template.md
144+
└── agent-file-template.md
145+
```
146+
147+
## Module Structure
148+
149+
```
150+
src/specify_cli/
151+
├── agents.py # CommandRegistrar — shared infrastructure for writing
152+
│ # command files to agent directories
153+
├── presets.py # PresetManifest, PresetRegistry, PresetManager,
154+
│ # PresetCatalog, PresetCatalogEntry, PresetResolver
155+
└── __init__.py # CLI commands: specify preset list/add/remove/search/
156+
# resolve/info, specify preset catalog list/add/remove
157+
```

0 commit comments

Comments
 (0)