mirror of
https://github.com/github/spec-kit.git
synced 2026-07-03 12:28:06 +08:00
* Initial plan * feat: add integration catalog system with catalog files, IntegrationCatalog class, list --catalog flag, upgrade command, integration.yml descriptor, and tests Agent-Logs-Url: https://github.com/github/spec-kit/sessions/bbcd44e8-c69c-4735-adc1-bdf1ce109184 Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> * fix: address PR review feedback - Replace empty except with cache cleanup in _fetch_single_catalog - Log teardown failure warning instead of silent pass in upgrade - Validate catalog_data and integrations are dicts before use - Catch OSError/UnicodeError in IntegrationDescriptor._load - Add isinstance checks for integration/requires/provides/commands - Enforce semver (X.Y.Z) instead of PEP 440 for descriptor versions - Fix docstring and CONTRIBUTING.md to match actual block-on-modified behavior - Restore old manifest on upgrade failure for transactional safety * refactor: address second round of PR review feedback - Remove dead cache_file/cache_metadata_file attributes from IntegrationCatalog - Deduplicate non-default catalog warning (show once per process) - Anchor version regex to reject partial matches like 1.0.0beta - Fix 'Preserved modified' message to 'Skipped' for accuracy - Make upgrade transactional: install new files first, then remove stale old-only files, so a failed setup leaves old integration intact - Update CONTRIBUTING.md: speckit_version validates presence only * Potential fix for pull request finding 'Empty except' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * fix: address third round of PR review feedback - Fix CONTRIBUTING.md JSON examples to show full catalog structure with schema_version and integrations wrapper - Wrap cache writes in try/except OSError for read-only project dirs - Validate _load_catalog_config YAML root is a dict - Skip non-dict integ_data entries in merged catalog - Normalize tags to list-of-strings before filtering/searching - Add path traversal containment check for stale file deletion - Clarify docstring: lower numeric priority = higher precedence * fix: address fourth round of PR review feedback - Remove unused _write_catalog helper from test file - Fix comment: tests use monkeypatched urlopen, not file:// URLs - Wrap cache unlink calls in OSError handler - Add explicit encoding='utf-8' to all cache read_text/write_text calls - Restore packaging.version.Version for descriptor version validation to align with extension/preset validators - Add missing goose entry to integrations/catalog.json * fix: remove unused Path import, add comment to empty except * fix: validate descriptor root is dict, add shared infra to upgrade - Add isinstance(self.data, dict) check at start of _validate() so non-mapping YAML roots raise IntegrationDescriptorError - Run _install_shared_infra() and ensure_executable_scripts() in upgrade command to match install/switch behavior * fix: address sixth round of PR review feedback - Validate integration.id/name/version/description are strings - Catch TypeError in pkg_version.Version() for non-string versions - Swap validation order: check catalogs type before emptiness - Isolate TestActiveCatalogs from user ~/.specify/ via monkeypatch * fix: address seventh round of PR review feedback - Update docs: version field uses PEP 440, not semver - Harden search() against non-string author/name/description fields - Validate requires.speckit_version is a non-empty string - Validate command name/file are non-empty strings, file is safe relative path - Handle stale symlinks in upgrade cleanup - Document catalog configuration stack in README.md * fix: validate script entries, remove destructive teardown from upgrade rollback - Validate provides.scripts entries are non-empty strings with safe relative paths - Remove teardown from upgrade rollback since setup overwrites in-place — teardown would delete files that were working before the upgrade * fix: use consistent resolved root for stale-file cleanup paths * fix: validate redirect URL and reject drive-qualified paths - Validate final URL after redirects with _validate_catalog_url() - Reject paths with Path.drive or Path.anchor for Windows safety - Update FakeResponse mocks with geturl() method * fix: fix docstring backticks, assert file modification in upgrade tests * docs: clarify directory naming convention for hyphenated integration keys * fix: correct key type hint, isolate all catalog tests from env - Fix key parameter type to str | None (defaults to None) - Add HOME/USERPROFILE monkeypatch and clear SPECKIT_INTEGRATION_CATALOG_URL in all TestCatalogFetch tests for full environment isolation * fix: neutralize catalog table title, handle non-dict cache metadata * fix: validate requires.tools entries in descriptor * fix: show discovery-only status, clear metadata files in clear_cache * fix: catch OSError/UnicodeError in cache read path * refactor: reuse IntegrationManifest.uninstall for stale-file cleanup * fix: normalize null tools to empty list in descriptor accessor --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
4.6 KiB
4.6 KiB
Contributing to the Integration Catalog
This guide covers adding integrations to both the built-in and community catalogs.
Adding a Built-In Integration
Built-in integrations are maintained by the Spec Kit core team and ship with the CLI.
Checklist
- Create the integration subpackage under
src/specify_cli/integrations/<package_dir>/—<package_dir>matches the integration key when it contains no hyphens (e.g.,gemini), or replaces hyphens with underscores when it does (e.g., keycursor-agent→ directorycursor_agent/, keykiro-cli→ directorykiro_cli/). Python package names cannot use hyphens. - Implement the integration class extending
MarkdownIntegration,TomlIntegration, orSkillsIntegration - Register the integration in
src/specify_cli/integrations/__init__.py - Add tests under
tests/integrations/test_integration_<package_dir>.py - Add a catalog entry in
integrations/catalog.json - Update documentation in
AGENTS.mdandREADME.md
Catalog Entry Format
Add your integration under the top-level integrations key in integrations/catalog.json:
{
"schema_version": "1.0",
"integrations": {
"my-agent": {
"id": "my-agent",
"name": "My Agent",
"version": "1.0.0",
"description": "Integration for My Agent",
"author": "spec-kit-core",
"repository": "https://github.com/github/spec-kit",
"tags": ["cli"]
}
}
}
Adding a Community Integration
Community integrations are contributed by external developers and listed in integrations/catalog.community.json for discovery.
Prerequisites
- Working integration — tested with
specify integration install - Public repository — hosted on GitHub or similar
integration.ymldescriptor — valid descriptor file (see below)- Documentation — README with usage instructions
- License — open source license file
integration.yml Descriptor
Every community integration must include an integration.yml:
schema_version: "1.0"
integration:
id: "my-agent"
name: "My Agent"
version: "1.0.0"
description: "Integration for My Agent"
author: "your-name"
repository: "https://github.com/your-name/speckit-my-agent"
license: "MIT"
requires:
speckit_version: ">=0.6.0"
tools:
- name: "my-agent"
version: ">=1.0.0"
required: true
provides:
commands:
- name: "speckit.specify"
file: "templates/speckit.specify.md"
scripts:
- update-context.sh
Descriptor Validation Rules
| Field | Rule |
|---|---|
schema_version |
Must be "1.0" |
integration.id |
Lowercase alphanumeric + hyphens (^[a-z0-9-]+$) |
integration.version |
Valid PEP 440 version (parsed with packaging.version.Version()) |
requires.speckit_version |
Required field; specify a version constraint such as >=0.6.0 (current validation checks presence only) |
provides |
Must include at least one command or script |
provides.commands[].name |
String identifier |
provides.commands[].file |
Relative path to template file |
Submitting to the Community Catalog
- Fork the spec-kit repository
- Add your entry under the
integrationskey inintegrations/catalog.community.json:
{
"schema_version": "1.0",
"integrations": {
"my-agent": {
"id": "my-agent",
"name": "My Agent",
"version": "1.0.0",
"description": "Integration for My Agent",
"author": "your-name",
"repository": "https://github.com/your-name/speckit-my-agent",
"tags": ["cli"]
}
}
}
- Open a pull request with:
- Your catalog entry
- Link to your integration repository
- Confirmation that
integration.ymlis valid
Version Updates
To update your integration version in the catalog:
- Release a new version of your integration
- Open a PR updating the
versionfield incatalog.community.json - Ensure backward compatibility or document breaking changes
Upgrade Workflow
The specify integration upgrade command supports diff-aware upgrades:
- Hash comparison — the manifest records SHA-256 hashes of all installed files
- Modified file detection — files changed since installation are flagged
- Safe default — the upgrade blocks if any installed files were modified since installation
- Forced reinstall — passing
--forceoverwrites modified files with the latest version
# Upgrade current integration (blocks if files are modified)
specify integration upgrade
# Force upgrade (overwrites modified files)
specify integration upgrade --force