Skip to content

Conversation

@mbachorik
Copy link

@mbachorik mbachorik commented Feb 3, 2026

Summary

Implement a complete extension system that allows third-party developers to extend Spec Kit functionality through plugins.

  • Extension discovery and loading from local and global directories
  • YAML-based extension manifest (extension.yml) with metadata and capabilities
  • Command extensions: custom slash commands with markdown templates
  • Hook system: pre/post hooks for generate, task, and sync operations
  • Extension catalog for discovering and installing community extensions
  • SPECKIT_CATALOG_URL environment variable for organization catalog customization

Installation Methods

  • Catalog install: specify extension add <name>
  • URL install: specify extension add <name> --from <url>
  • Dev install: specify extension add --dev <path>

Extension Management Commands

  • specify extension list - List installed extensions
  • specify extension search [query] - Search catalog for extensions
  • specify extension update [name] - Check for and update extensions
  • specify extension remove <name> - Remove an extension

Organization Catalog Customization

The default catalog is intentionally empty, allowing organizations to ship their own curated extension catalogs:

# Set organization catalog URL
export SPECKIT_CATALOG_URL="https://internal.company.com/speckit/catalog.json"

# Then use normal extension commands
specify extension search
specify extension add my-extension

Documentation Included

  • RFC with design rationale and architecture decisions
  • API reference for extension developers
  • Development guide with examples
  • User guide for installing and managing extensions (includes organization customization section)
  • Publishing guide for the extension catalog

Also Included

  • Extension template for bootstrapping new extensions
  • Comprehensive test suite (39 tests)
  • Example catalog.json structure

AI Disclosure

This PR was written primarily by AI, using GitHub Copilot and Claude.

Testing

  • Manual testing: Tested on several spec-kit driven projects
  • Automated testing with AI: Created sample projects, installed extensions from catalog/remote and local sources

Sample Extension

A sample Jira extension (also written primarily by AI, using GitHub Copilot and Claude) is available at:
https://github.com/mbachorik/spec-kit-jira

Test plan

  • Manual testing with Claude Code in VS Code
  • Manual testing with GitHub Copilot in VS Code
  • Tested extension installation from catalog
  • Tested extension installation from URL
  • Tested extension installation from local directory (--dev)
  • Tested extension update command with custom catalog URL
  • Unit tests pass (39/39)

🤖 Generated with Claude Code

Implement a complete extension system that allows third-party developers
to extend Spec Kit functionality through plugins.

## Core Features
- Extension discovery and loading from local and global directories
- YAML-based extension manifest (extension.yml) with metadata and capabilities
- Command extensions: custom slash commands with markdown templates
- Hook system: pre/post hooks for generate, task, and sync operations
- Extension catalog for discovering and installing community extensions
- SPECKIT_CATALOG_URL environment variable for catalog URL override

## Installation Methods
- Catalog install: `specify extension add <name>`
- URL install: `specify extension add <name> --from <url>`
- Dev install: `specify extension add --dev <path>`

## Implementation
- ExtensionManager class for lifecycle management (load, enable, disable)
- Support for extension dependencies and version constraints
- Configuration layering (global → project → extension)
- Hook conditions for conditional execution

## Documentation
- RFC with design rationale and architecture decisions
- API reference for extension developers
- Development guide with examples
- User guide for installing and managing extensions
- Publishing guide for the extension catalog

## Included
- Extension template for bootstrapping new extensions
- Comprehensive test suite
- Example catalog.json structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 3, 2026 15:04
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a comprehensive modular extension system for Spec Kit, enabling third-party developers to create plugins that extend functionality without bloating the core framework.

Changes:

  • Complete extension infrastructure with manifest validation, registry, installation/removal, and hook system
  • Extension catalog for discovery with search, caching, and metadata management
  • CLI commands for managing extensions (add, remove, list, search, info, update, enable, disable)
  • Multi-agent support for 16+ AI coding assistants with automatic command registration
  • Layered configuration system supporting defaults, project, local, and environment variable overrides
  • Comprehensive documentation suite (user guide, API reference, publishing guide, RFC)
  • Extension template and test suite with 39 unit tests

Reviewed changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/specify_cli/extensions.py Core extension system implementation (1714 lines): manifest validation, registry, manager, catalog, config, hooks
src/specify_cli/init.py CLI integration with 7 extension commands
tests/test_extensions.py Comprehensive test suite with 984 lines covering all components
pyproject.toml Version bump to 0.1.0, added dependencies (pyyaml, packaging), test configuration
extensions/template/* Complete extension template with examples and documentation
extensions/*.md Documentation suite (user guide, API reference, publishing guide, RFC)
extensions/catalog.json Initial catalog with Jira extension
CHANGELOG.md Detailed changelog documenting all new features
.gitignore Extension cache and local config exclusions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Adds 2-level mode support (Epic → Stories only).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mnriem mnriem self-requested a review February 3, 2026 17:18
@mnriem
Copy link
Collaborator

mnriem commented Feb 3, 2026

@mbachorik Can you make it so the catalog.json is empty and it gets populated when adding a specific extension. For organizations they could then ship their own vetted version of catalog.json? Also can you address the markdown linter errors?

- Fix Zip Slip vulnerability in ZIP extraction with path validation
- Fix keep_config option to actually preserve config files on removal
- Add URL validation for SPECKIT_CATALOG_URL (HTTPS required, localhost exception)
- Add security warning when installing from custom URLs (--from flag)
- Empty catalog.json so organizations can ship their own catalogs
- Fix markdown linter errors (MD040: add language to code blocks)
- Remove redundant import and fix unused variables in tests
- Add comment explaining empty except clause for backwards compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 3, 2026 20:56
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

iamaeroplane and others added 2 commits February 3, 2026 22:02
- Explain why default catalog is empty (org control)
- Document how to create and host custom catalogs
- Add catalog JSON schema reference
- Include use cases: private extensions, curated catalogs, air-gapped environments
- Add examples for combining catalog with direct installation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update test_config_backup_on_remove to use new subdirectory structure
  (.backup/test-ext/file.yml instead of .backup/test-ext-file.yml)
- Update test_full_install_and_remove_workflow to handle registered_commands
  being a dict keyed by agent name instead of a flat list

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 3, 2026 21:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@mbachorik
Copy link
Author

Updates in this push

Test Fixes

Fixed two test assertions that were failing due to data structure changes:

  1. test_config_backup_on_remove: Updated to use new subdirectory structure (.backup/test-ext/file.yml instead of .backup/test-ext-file.yml)

  2. test_full_install_and_remove_workflow: Updated to handle registered_commands being a dict keyed by agent name instead of a flat list

All Tests Passing

============================== 39 passed in 0.23s ==============================

Extension Update Command Tested

Verified specify extension update works correctly:

  • Detects newer versions in catalog
  • Shows "up to date" when versions match
  • Provides manual update instructions (automatic download is TODO for future version)
  • Respects SPECKIT_CATALOG_URL environment variable for organization catalogs

- Fix localhost URL check to use parsed.hostname instead of netloc.startswith()
  This correctly handles URLs with ports like localhost:8080
- Fix YAML indentation error in config-template.yml (line 57)
- Fix double space typo in example.md (line 172)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@mbachorik
Copy link
Author

Copilot Review Feedback - Status

Addressed in this push (352bd80)

Comment Status Notes
Localhost check using netloc.startswith() ✅ Fixed Now uses parsed.hostname in ("localhost", "127.0.0.1", "::1") to correctly handle ports
YAML indentation error (config-template.yml:57) ✅ Fixed Changed from 1 space to 2 spaces
Double space typo (example.md:172) ✅ Fixed Removed extra space

Already addressed in previous commits

Comment Status Notes
Empty except clause without comment ✅ Already fixed Has explanatory comment
SPECKIT_CATALOG_URL URL injection ✅ Already fixed Validates HTTPS and shows warning for non-default catalogs
--from URL validation ✅ Already fixed Validates HTTPS and shows warning

Design decisions (not changing)

Comment Notes
Zip Slip validation The current logic is correct - validation happens for ALL paths before extractall() is called. If any path is unsafe, ValidationError is raised before extraction.
keep_config parameter Current behavior is intentional - when keep_config=True, the entire extension directory is preserved to allow seamless reinstall. The parameter name reflects user intent ("keep my config") rather than internal behavior.
Backup *-config.local.yml files Local config files are gitignored and typically contain machine-specific overrides. Backing them up could cause confusion when restoring on different machines. Users who need to preserve local configs should manually copy them.
download_extension HTTPS validation The catalog itself is already HTTPS-validated. Extension download URLs in the catalog are trusted as they come from the verified catalog source. Adding another check would be redundant for catalog installs, and --from URL installs already have HTTPS validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants