Skip to content

Commit 6cf8995

Browse files
Test Userclaude
andcommitted
Merge upstream/main: Sync 10 commits from github/spec-kit (v0.0.91–v0.0.98)
Key upstream changes absorbed: - Modular extension system (PR github#1551): plugin architecture with YAML manifests, extension catalog, hook system, CLI management commands - Constitution preservation on reinit (PR github#1553): template moved to templates/constitution-template.md, user customizations preserved - .specify.specify path bug fix (PR github#1588): double-nesting resolved - Google Anti Gravity agent support (PR github#1220): new agy agent in release - Stale workflow (PR github#1594): auto-close inactive issues after 180 days - Dependabot config (PR github#1622): automated pip and Actions updates - Markdownlint fixes (PR github#1571), plan template typo (PR github#1446) - README maintainers section removed (PR github#1618) Conflict resolutions: - pyproject.toml: kept our version (0.0.20.post1) over upstream 0.1.0 - plan-template.md: kept /sp.plan prefix over upstream /speckit.plan - create-release-packages.sh: merged agy agent + kept our generate_agent_rules; updated constitutionplus/command-rules paths from memory/ to templates/ to match upstream rename - README.md: kept our SpecifyPlus content, dropped upstream maintainers section (already removed upstream), preserved contributing section - templates/command-rules.md, templates/constitutionplus.md: accepted memory/ → templates/ relocation matching upstream convention Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 parents 3f6fe49 + d410d18 commit 6cf8995

36 files changed

Lines changed: 9083 additions & 38 deletions

.github/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "pip"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
7+
8+
- package-ecosystem: "github-actions"
9+
directory: "/"
10+
schedule:
11+
interval: "weekly"

.github/workflows/lint.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ jobs:
1717
- name: Run markdownlint-cli2
1818
uses: DavidAnson/markdownlint-cli2-action@v19
1919
with:
20-
globs: '**/*.md'
20+
globs: |
21+
'**/*.md'
22+
!extensions/**/*.md

.github/workflows/scripts/create-github-release.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ gh release create "$VERSION" \
4848
.genreleases/spec-kit-template-shai-ps-"$VERSION".zip \
4949
.genreleases/spec-kit-template-q-sh-"$VERSION".zip \
5050
.genreleases/spec-kit-template-q-ps-"$VERSION".zip \
51+
.genreleases/spec-kit-template-agy-sh-"$VERSION".zip \
52+
.genreleases/spec-kit-template-agy-ps-"$VERSION".zip \
5153
.genreleases/spec-kit-template-bob-sh-"$VERSION".zip \
5254
.genreleases/spec-kit-template-bob-ps-"$VERSION".zip \
5355
--title "Spec Kit Plus Templates - $VERSION_NO_V" \

.github/workflows/scripts/create-release-packages.sh

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ rewrite_paths() {
3434
sed -E \
3535
-e 's@(/?)memory/@.specify/memory/@g' \
3636
-e 's@(/?)scripts/@.specify/scripts/@g' \
37-
-e 's@(/?)templates/@.specify/templates/@g'
37+
-e 's@(/?)templates/@.specify/templates/@g' \
38+
-e 's@\.specify\.specify/@.specify/@g'
3839
}
3940

4041
generate_commands() {
@@ -43,11 +44,14 @@ generate_commands() {
4344

4445
# Load command-rules.md for prepending (universal pre-execution rules)
4546
local command_rules_content=""
46-
if [[ -f "memory/command-rules.md" ]]; then
47-
command_rules_content=$(tr -d '\r' < "memory/command-rules.md")
47+
if [[ -f "templates/command-rules.md" ]]; then
48+
command_rules_content=$(tr -d '\r' < "templates/command-rules.md")
4849
echo "Loaded command-rules.md for universal pre-execution injection"
50+
elif [[ -f "memory/command-rules.md" ]]; then
51+
command_rules_content=$(tr -d '\r' < "memory/command-rules.md")
52+
echo "Loaded command-rules.md (legacy path) for universal pre-execution injection"
4953
else
50-
echo "Warning: memory/command-rules.md not found - commands will not have implicit behavior support" >&2
54+
echo "Warning: command-rules.md not found - commands will not have implicit behavior support" >&2
5155
fi
5256

5357
for template in templates/commands/*.md; do
@@ -158,13 +162,18 @@ build_variant() {
158162
# with an agent-specific preface, eliminating redundancy.
159163

160164
# If constitutionplus.md exists, overwrite constitution.md in release package
161-
if [[ -f memory/constitutionplus.md ]]; then
165+
if [[ -f templates/constitutionplus.md ]]; then
162166
mkdir -p "$SPEC_DIR/memory"
163-
cp memory/constitutionplus.md "$SPEC_DIR/memory/constitution.md"
167+
cp templates/constitutionplus.md "$SPEC_DIR/memory/constitution.md"
164168
echo "Injected constitutionplus.md as .specify/memory/constitution.md"
165-
# Do not ship constitutionplus.md in the archive
166-
rm -f "$SPEC_DIR/memory/constitutionplus.md" 2>/dev/null || true
169+
elif [[ -f memory/constitutionplus.md ]]; then
170+
mkdir -p "$SPEC_DIR/memory"
171+
cp memory/constitutionplus.md "$SPEC_DIR/memory/constitution.md"
172+
echo "Injected constitutionplus.md (legacy path) as .specify/memory/constitution.md"
167173
fi
174+
# Do not ship constitutionplus.md in the archive
175+
rm -f "$SPEC_DIR/memory/constitutionplus.md" 2>/dev/null || true
176+
rm -f "$SPEC_DIR/templates/constitutionplus.md" 2>/dev/null || true
168177

169178
# Only copy the relevant script variant directory
170179
if [[ -d scripts ]]; then
@@ -385,6 +394,11 @@ This file is generated during init for the selected agent.
385394
mkdir -p "$base_dir/.amazonq/prompts"
386395
generate_commands q md "\$ARGUMENTS" "$base_dir/.amazonq/prompts" "$script"
387396
generate_agent_rules q "$base_dir" ;;
397+
agy)
398+
mkdir -p "$base_dir/.agent/workflows"
399+
generate_commands agy md "\$ARGUMENTS" "$base_dir/.agent/workflows" "$script"
400+
generate_agent_rules agy "$base_dir" ;;
401+
388402
bob)
389403
mkdir -p "$base_dir/.bob/commands"
390404
generate_commands bob md "\$ARGUMENTS" "$base_dir/.bob/commands" "$script"
@@ -395,7 +409,7 @@ This file is generated during init for the selected agent.
395409
}
396410

397411
# Determine agent list
398-
ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo codebuddy amp shai q bob qoder)
412+
ALL_AGENTS=(claude gemini copilot cursor-agent qwen opencode windsurf codex kilocode auggie roo codebuddy amp shai q agy bob qoder)
399413
ALL_SCRIPTS=(sh ps)
400414

401415
norm_list() {

.github/workflows/stale.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: 'Close stale issues and PRs'
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *' # Run daily at midnight UTC
6+
workflow_dispatch: # Allow manual triggering
7+
8+
permissions:
9+
issues: write
10+
pull-requests: write
11+
12+
jobs:
13+
stale:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/stale@v10
17+
with:
18+
# Days of inactivity before an issue or PR becomes stale
19+
days-before-stale: 150
20+
# Days of inactivity before a stale issue or PR is closed (after being marked stale)
21+
days-before-close: 30
22+
23+
# Stale issue settings
24+
stale-issue-message: 'This issue has been automatically marked as stale because it has not had any activity for 150 days. It will be closed in 30 days if no further activity occurs.'
25+
close-issue-message: 'This issue has been automatically closed due to inactivity (180 days total). If you believe this issue is still relevant, please reopen it or create a new issue.'
26+
stale-issue-label: 'stale'
27+
28+
# Stale PR settings
29+
stale-pr-message: 'This pull request has been automatically marked as stale because it has not had any activity for 150 days. It will be closed in 30 days if no further activity occurs.'
30+
close-pr-message: 'This pull request has been automatically closed due to inactivity (180 days total). If you believe this PR is still relevant, please reopen it or create a new PR.'
31+
stale-pr-label: 'stale'
32+
33+
# Exempt issues and PRs with these labels from being marked as stale
34+
exempt-issue-labels: 'pinned,security'
35+
exempt-pr-labels: 'pinned,security'
36+
37+
# Only issues or PRs with all of these labels are checked
38+
# Leave empty to check all issues and PRs
39+
any-of-labels: ''
40+
41+
# Operations per run (helps avoid rate limits)
42+
operations-per-run: 100

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,9 @@ env/
4444
.genreleases/
4545
*.zip
4646
sdd-*/
47+
docs/dev
48+
49+
# Extension system
50+
.specify/extensions/.cache/
51+
.specify/extensions/.backup/
52+
.specify/extensions/*/local-config.yml

.markdownlint-cli2.jsonc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
},
2020
"MD050": {
2121
"style": "asterisk"
22-
}
22+
},
23+
"MD036": false,
24+
"MD060": false
2325
},
2426
"ignores": [
2527
".genreleases/"

CHANGELOG.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,120 @@ 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 [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
99

10+
## [0.1.0] - 2026-01-28
11+
12+
### Added
13+
14+
- **Extension System**: Introduced modular extension architecture for Spec Kit
15+
- Extensions are self-contained packages that add commands and functionality without bloating core
16+
- Extension manifest schema (`extension.yml`) with validation
17+
- Extension registry (`.specify/extensions/.registry`) for tracking installed extensions
18+
- Extension manager module (`src/specify_cli/extensions.py`) for installation/removal
19+
- New CLI commands:
20+
- `specify extension list` - List installed extensions
21+
- `specify extension add` - Install extension from local directory or URL
22+
- `specify extension remove` - Uninstall extension
23+
- `specify extension search` - Search extension catalog
24+
- `specify extension info` - Show detailed extension information
25+
- Semantic versioning compatibility checks
26+
- Support for extension configuration files
27+
- Command registration system for AI agents (Claude support initially)
28+
- Added dependencies: `pyyaml>=6.0`, `packaging>=23.0`
29+
30+
- **Extension Catalog**: Extension discovery and distribution system
31+
- Central catalog (`extensions/catalog.json`) for published extensions
32+
- Extension catalog manager (`ExtensionCatalog` class) with:
33+
- Catalog fetching from GitHub
34+
- 1-hour local caching for performance
35+
- Search by query, tag, author, or verification status
36+
- Extension info retrieval
37+
- Catalog cache stored in `.specify/extensions/.cache/`
38+
- Search and info commands with rich console output
39+
- Added 9 catalog-specific unit tests (100% pass rate)
40+
41+
- **Jira Extension**: First official extension for Jira integration
42+
- Extension ID: `jira`
43+
- Version: 1.0.0
44+
- Commands:
45+
- `/speckit.jira.specstoissues` - Create Jira hierarchy from spec and tasks
46+
- `/speckit.jira.discover-fields` - Discover Jira custom fields
47+
- `/speckit.jira.sync-status` - Sync task completion status
48+
- Comprehensive documentation (README, usage guide, examples)
49+
- MIT licensed
50+
51+
- **Hook System**: Extension lifecycle hooks for automation
52+
- `HookExecutor` class for managing extension hooks
53+
- Hooks registered in `.specify/extensions.yml`
54+
- Hook registration during extension installation
55+
- Hook unregistration during extension removal
56+
- Support for optional and mandatory hooks
57+
- Hook execution messages for AI agent integration
58+
- Condition support for conditional hook execution (placeholder)
59+
60+
- **Extension Management**: Advanced extension management commands
61+
- `specify extension update` - Check and update extensions to latest version
62+
- `specify extension enable` - Enable a disabled extension
63+
- `specify extension disable` - Disable extension without removing it
64+
- Version comparison with catalog
65+
- Update notifications
66+
- Preserve configuration during updates
67+
68+
- **Multi-Agent Support**: Extensions now work with all supported AI agents (Phase 6)
69+
- Automatic detection and registration for all agents in project
70+
- Support for 16+ AI agents (Claude, Gemini, Copilot, Cursor, Qwen, and more)
71+
- Agent-specific command formats (Markdown and TOML)
72+
- Automatic argument placeholder conversion ($ARGUMENTS → {{args}})
73+
- Commands registered for all detected agents during installation
74+
- Multi-agent command unregistration on extension removal
75+
- `CommandRegistrar.register_commands_for_agent()` method
76+
- `CommandRegistrar.register_commands_for_all_agents()` method
77+
78+
- **Configuration Layers**: Full configuration cascade system (Phase 6)
79+
- **Layer 1**: Defaults from extension manifest (`extension.yml`)
80+
- **Layer 2**: Project config (`.specify/extensions/{ext-id}/{ext-id}-config.yml`)
81+
- **Layer 3**: Local config (`.specify/extensions/{ext-id}/local-config.yml`, gitignored)
82+
- **Layer 4**: Environment variables (`SPECKIT_{EXT_ID}_{KEY}` pattern)
83+
- Recursive config merging with proper precedence
84+
- `ConfigManager` class for programmatic config access
85+
- `get_config()`, `get_value()`, `has_value()` methods
86+
- Support for nested configuration paths with dot-notation
87+
88+
- **Hook Condition Evaluation**: Smart hook execution based on runtime conditions (Phase 6)
89+
- Config conditions: `config.key.path is set`, `config.key == 'value'`, `config.key != 'value'`
90+
- Environment conditions: `env.VAR is set`, `env.VAR == 'value'`, `env.VAR != 'value'`
91+
- Automatic filtering of hooks based on condition evaluation
92+
- Safe fallback behavior on evaluation errors
93+
- Case-insensitive pattern matching
94+
95+
- **Hook Integration**: Agent-level hook checking and execution (Phase 6)
96+
- `check_hooks_for_event()` method for AI agents to query hooks after core commands
97+
- Condition-aware hook filtering before execution
98+
- `enable_hooks()` and `disable_hooks()` methods per extension
99+
- Formatted hook messages for agent display
100+
- `execute_hook()` method for hook execution information
101+
102+
- **Documentation Suite**: Comprehensive documentation for users and developers
103+
- **EXTENSION-USER-GUIDE.md**: Complete user guide with installation, usage, configuration, and troubleshooting
104+
- **EXTENSION-API-REFERENCE.md**: Technical API reference with manifest schema, Python API, and CLI commands
105+
- **EXTENSION-PUBLISHING-GUIDE.md**: Publishing guide for extension authors
106+
- **RFC-EXTENSION-SYSTEM.md**: Extension architecture design document
107+
108+
- **Extension Template**: Starter template in `extensions/template/` for creating new extensions
109+
- Fully commented `extension.yml` manifest template
110+
- Example command file with detailed explanations
111+
- Configuration template with all options
112+
- Complete project structure (README, LICENSE, CHANGELOG, .gitignore)
113+
- EXAMPLE-README.md showing final documentation format
114+
115+
- **Unit Tests**: Comprehensive test suite with 39 tests covering all extension system components
116+
- Test coverage: 83% of extension module code
117+
- Test dependencies: `pytest>=7.0`, `pytest-cov>=4.0`
118+
- Configured pytest in `pyproject.toml`
119+
120+
### Changed
121+
122+
- Version bumped to 0.1.0 (minor release for new feature)
123+
10124
## [0.0.22] - 2025-11-07
11125

12126
- Support for VS Code/Copilot agents, and moving away from prompts to proper agents with hand-offs.

README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ Use `specifyplus` or `sp` commands instead of `specify`.
7373
- [📖 Learn More](#-learn-more)
7474
- [📋 Detailed Process](#-detailed-process)
7575
- [🔍 Troubleshooting](#-troubleshooting)
76-
- [👥 Maintainers](#-maintainers)
7776
- [💬 Support](#-support)
7877
- [🙏 Acknowledgements](#-acknowledgements)
7978
- [📄 License](#-license)
@@ -227,6 +226,7 @@ Want to see Spec Kit in action? Watch our [video overview](https://www.youtube.c
227226
| [Roo Code](https://roocode.com/) || |
228227
| [SHAI (OVHcloud)](https://github.com/ovh/shai) || |
229228
| [Windsurf](https://windsurf.com/) || |
229+
| [Antigravity (agy)](https://agy.ai/) || |
230230

231231
## 🔧 Specify CLI Reference
232232

@@ -252,7 +252,7 @@ The `specify` command supports the following options:
252252
| Argument/Option | Type | Description |
253253
| ---------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
254254
| `<project-name>` | Argument | Name for your new project directory (optional if using `--here`, or use `.` for current directory) |
255-
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor-agent`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, `amp`, `shai`, `q`, `bob`, or `qoder` |
255+
| `--ai` | Option | AI assistant to use: `claude`, `gemini`, `copilot`, `cursor-agent`, `qwen`, `opencode`, `codex`, `windsurf`, `kilocode`, `auggie`, `roo`, `codebuddy`, `amp`, `shai`, `q`, `agy`, `bob`, or `qoder` |
256256
| `--script` | Option | Script variant to use: `sh` (bash/zsh) or `ps` (PowerShell) |
257257
| `--ignore-agent-tools` | Flag | Skip checks for AI agent tools like Claude Code |
258258
| `--no-git` | Flag | Skip git repository initialization |
@@ -726,11 +726,6 @@ echo "Cleaning up..."
726726
rm gcm-linux_amd64.2.6.1.deb
727727
```
728728

729-
## 👥 Maintainers
730-
731-
- Den Delimarsky ([@localden](https://github.com/localden))
732-
- John Lam ([@jflam](https://github.com/jflam))
733-
734729
## 🤝 Contributing
735730

736731
We welcome contributions from the community! SpecifyPlus uses a **test-first contribution model** where you develop and validate commands in your own projects before contributing them to the core repository.
@@ -751,8 +746,7 @@ git clone https://github.com/panaversity/spec-kit-plus.git
751746

752747
### Contribution Resources
753748

754-
- **🔧 [Contributing Guide](CONTRIBUTING.md)** - Setup, testing, and submission process
755-
- **[Quick Reference](#quick-reference)** - Common command patterns and examples
749+
- **[Contributing Guide](CONTRIBUTING.md)** - Setup, testing, and submission process
756750

757751
### Popular Contribution Areas
758752

@@ -762,6 +756,7 @@ git clone https://github.com/panaversity/spec-kit-plus.git
762756
- **Documentation** and guides
763757
- **Bug fixes** and performance improvements
764758

759+
765760
## 💬 Support
766761

767762
For support, please open a [GitHub issue](https://github.com/panaversity/spec-kit-plus/issues/new). We welcome bug reports, feature requests, and questions about using Spec-Driven Development.

0 commit comments

Comments
 (0)