* Add modular extension system for Spec Kit 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> * Update Jira extension to v2.1.0 in catalog Adds 2-level mode support (Epic → Stories only). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address PR review feedback - 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> * Add comprehensive organization catalog customization docs - 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> * Fix test assertions for extension system data structures - 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> * Address Copilot review feedback - 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> * Add catalog.example.json as reference for organizations The main catalog.json is intentionally empty so organizations can ship their own curated catalogs. This example file shows the expected schema and structure for creating organization-specific catalogs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Address remaining Copilot security and logic review feedback - Fix Zip Slip vulnerability by using relative_to() for safe path validation - Add HTTPS validation for extension download URLs - Backup both *-config.yml and *-config.local.yml files on remove - Normalize boolean values to lowercase for hook condition comparisons - Show non-default catalog warning only once per instance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Ignoring linter for extensions directory --------- Co-authored-by: iamaeroplane <michal.bachorik@gmail.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Manfred Riem <manfred.riem@microsoft.com>
4.3 KiB
description, tools
| description | tools | |
|---|---|---|
| Example command that demonstrates extension functionality |
|
Example Command
This is an example command that demonstrates how to create commands for Spec Kit extensions.
Purpose
Describe what this command does and when to use it.
Prerequisites
List requirements before using this command:
- Prerequisite 1 (e.g., "MCP server configured")
- Prerequisite 2 (e.g., "Configuration file exists")
- Prerequisite 3 (e.g., "Valid API credentials")
User Input
$ARGUMENTS
Steps
Step 1: Load Configuration
Load extension configuration from the project:
``bash config_file=".specify/extensions/my-extension/my-extension-config.yml"
if [ ! -f "$config_file" ]; then echo "❌ Error: Configuration not found at $config_file" echo "Run 'specify extension add my-extension' to install and configure" exit 1 fi
Read configuration values
setting_value=$(yq eval '.settings.key' "$config_file")
Apply environment variable overrides
setting_value="${SPECKIT_MY_EXTENSION_KEY:-$setting_value}"
Validate configuration
if [ -z "$setting_value" ]; then echo "❌ Error: Configuration value not set" echo "Edit $config_file and set 'settings.key'" exit 1 fi
echo "📋 Configuration loaded: $setting_value" ``
Step 2: Perform Main Action
Describe what this step does:
``markdown Use MCP tools to perform the main action:
- Tool: example-mcp-server example_tool
- Parameters: { "key": "$setting_value" }
This calls the MCP server tool to execute the operation. ``
Step 3: Process Results
Process the results and provide output:
bash echo "" echo "✅ Command completed successfully!" echo "" echo "Results:" echo " • Item 1: Value" echo " • Item 2: Value" echo ""
Step 4: Save Output (Optional)
Save results to a file if needed:
``bash output_file=".specify/my-extension-output.json"
cat > "$output_file" <<EOF { "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")", "setting": "$setting_value", "results": [] } EOF
echo "💾 Output saved to $output_file" ``
Configuration Reference
This command uses the following configuration from my-extension-config.yml:
-
settings.key: Description of what this setting does
- Type: string
- Required: Yes
- Example:
"example-value"
-
settings.another_key: Description of another setting
- Type: boolean
- Required: No
- Default:
false - Example:
true
Environment Variables
Configuration can be overridden with environment variables:
SPECKIT_MY_EXTENSION_KEY- Overridessettings.keySPECKIT_MY_EXTENSION_ANOTHER_KEY- Overridessettings.another_key
Example:
bash export SPECKIT_MY_EXTENSION_KEY="override-value"
Troubleshooting
"Configuration not found"
Solution: Install the extension and create configuration:
bash specify extension add my-extension cp .specify/extensions/my-extension/config-template.yml \ .specify/extensions/my-extension/my-extension-config.yml
"MCP tool not available"
Solution: Ensure MCP server is configured in your AI agent settings.
"Permission denied"
Solution: Check credentials and permissions in the external service.
Notes
- This command requires an active connection to the external service
- Results are cached for performance
- Re-run the command to refresh data
Examples
Example 1: Basic Usage
``bash
Run with default configuration
/speckit.my-extension.example ``
Example 2: With Environment Override
``bash
Override configuration with environment variable
export SPECKIT_MY_EXTENSION_KEY="custom-value"
/speckit.my-extension.example ``
Example 3: After Core Command
``bash
Use as part of a workflow
/speckit.tasks /speckit.my-extension.example ``
For more information, see the extension README or run specify extension info my-extension