feat: Integration catalog — discovery, versioning, and community distribution#2130
feat: Integration catalog — discovery, versioning, and community distribution#2130
Conversation
…atalog 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>
There was a problem hiding this comment.
Pull request overview
Introduces an integration catalog system (built-in + community) to enable discovery and upgrades of Spec Kit integrations, mirroring existing extension/preset catalog patterns.
Changes:
- Added
IntegrationCatalog+IntegrationDescriptorfor catalog fetching/search andintegration.ymlvalidation. - Extended the CLI with
specify integration list --catalogand a newspecify integration upgradecommand. - Added integration catalog JSON files, documentation, and a comprehensive new test suite for the catalog/CLI behavior.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
Implements catalog resolution/fetch/cache/search and descriptor loading/validation. |
src/specify_cli/__init__.py |
Adds integration list --catalog and integration upgrade CLI commands. |
tests/integrations/test_integration_catalog.py |
Adds tests for URL validation, active catalogs, fetch/search, descriptor validation, and CLI flows. |
integrations/catalog.json |
Adds built-in integration catalog entries. |
integrations/catalog.community.json |
Adds community catalog starter file. |
integrations/README.md |
Documents catalog files, CLI usage, and schemas. |
integrations/CONTRIBUTING.md |
Adds contribution and upgrade workflow guidance. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/catalog.py:315
integ_datais assumed to be a mapping and is expanded with**integ_data. If a catalog contains a non-object entry (e.g., string/null), this will raiseTypeErrorand break catalog search. Add a type check for eachinteg_data(and optionally for the overallintegrationsfield) and skip/raise a structuredIntegrationCatalogError.
for integ_id, integ_data in data.get("integrations", {}).items():
if integ_id not in merged:
merged[integ_id] = {
**integ_data,
"id": integ_id,
"_catalog_name": entry.name,
"_install_allowed": entry.install_allowed,
}
- Files reviewed: 7/7 changed files
- Comments generated: 7
- 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
There was a problem hiding this comment.
Pull request overview
Introduces an integrations catalog system (built-in + community) that mirrors existing catalog patterns, and adds CLI support for catalog browsing and integration upgrades.
Changes:
- Added
IntegrationCatalog+IntegrationDescriptorfor catalog discovery/caching/search andintegration.ymlvalidation. - Added CLI enhancements:
specify integration list --catalogandspecify integration upgrade [--force]. - Added initial built-in/community catalog JSON files plus documentation and a comprehensive new test suite.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog/discovery + descriptor validation implementation. |
src/specify_cli/__init__.py |
Adds --catalog listing mode and new integration upgrade command. |
tests/integrations/test_integration_catalog.py |
New tests covering catalog resolution/fetch/search, descriptor validation, list --catalog, and upgrade flows. |
integrations/catalog.json |
Seeds built-in integrations catalog metadata. |
integrations/catalog.community.json |
Adds empty community catalog starter. |
integrations/README.md |
Documents catalog files, schema, and CLI usage. |
integrations/CONTRIBUTING.md |
Contributor checklist and submission guidance for built-in/community entries. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (2)
src/specify_cli/integrations/catalog.py:380
- clear_cache() only deletes
catalog-*.jsonbut leaves the correspondingcatalog-*-metadata.jsonfiles behind, which can accumulate and makes cache cleanup incomplete. Consider removing both the cached payload and metadata files (and optionally the legacy cache files if you keep them).
def clear_cache(self) -> None:
"""Remove all cached catalog files."""
if self.cache_dir.exists():
for f in self.cache_dir.glob("catalog-*.json"):
f.unlink(missing_ok=True)
src/specify_cli/integrations/catalog.py:476
- IntegrationDescriptor requires
requires.speckit_versionto exist but does not validate that it’s a valid version specifier. Since the docs describe this as a PEP 440 specifier, consider validating it withpackaging.specifiers.SpecifierSet(raising IntegrationDescriptorError on InvalidSpecifier) to ensure bad descriptors fail fast.
requires = self.data["requires"]
if not isinstance(requires, dict):
raise IntegrationDescriptorError(
"'requires' must be a mapping"
)
if "speckit_version" not in requires:
raise IntegrationDescriptorError(
"Missing requires.speckit_version"
)
- Files reviewed: 7/7 changed files
- Comments generated: 6
- 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
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds an integration catalog system (built-in + community) to enable discovery/versioning, and extends the CLI with catalog browsing and diff-aware integration upgrades.
Changes:
- Introduces
IntegrationCatalog/IntegrationDescriptorfor fetching, caching, searching catalogs and validatingintegration.yml. - Adds CLI support for
specify integration list --catalogand a newspecify integration upgradecommand. - Adds initial catalog JSON files plus integration catalog documentation and tests.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog/descriptor implementation: config resolution, fetch/cache, search, and descriptor validation. |
src/specify_cli/__init__.py |
CLI wiring for integration list --catalog and new integration upgrade command. |
tests/integrations/test_integration_catalog.py |
New test coverage for catalog stack resolution, fetch/search, descriptor validation, and CLI behavior. |
integrations/catalog.json |
Adds the built-in integration catalog metadata. |
integrations/catalog.community.json |
Adds the community catalog “starter” file (empty integrations map). |
integrations/README.md |
Documents catalog purpose, CLI usage, and schema/descriptor examples. |
integrations/CONTRIBUTING.md |
Contributing guide for built-in/community integration catalog entries and upgrade workflow. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (2)
src/specify_cli/integrations/catalog.py:420
_load()can return a non-dict YAML root (e.g., a list). In that case_validate()will later raise aTypeError/KeyErrorinstead of a clearIntegrationDescriptorError. Add an explicitisinstance(data, dict)check aftersafe_loadand raise a friendly validation error when the root is not a mapping.
try:
with open(path, "r", encoding="utf-8") as fh:
return yaml.safe_load(fh) or {}
integrations/CONTRIBUTING.md:105
- Similarly, the community submission example omits the required top-level fields (
schema_version,updated_at, andintegrations). This can lead to invalid PRs againstintegrations/catalog.community.json. Update the example to show the full structure or explicitly note it’s the contents of theintegrationsobject.
1. **Fork** the [spec-kit repository](https://github.com/github/spec-kit)
2. **Add your entry** to `integrations/catalog.community.json`:
```json
{
"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"]
}
}
</details>
- **Files reviewed:** 7/7 changed files
- **Comments generated:** 7
- 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
There was a problem hiding this comment.
Pull request overview
Introduces an integrations catalog system (similar to existing extension/preset catalogs) to enable discovery of built-in + community integrations, plus a CLI upgrade flow based on manifest hash diffs.
Changes:
- Added
IntegrationCatalog+IntegrationDescriptorfor catalog fetch/search/caching andintegration.ymlvalidation. - Added CLI support for
specify integration list --catalogandspecify integration upgrade [key] [--force]. - Added initial built-in/community catalog JSON files and accompanying documentation + tests.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog fetch/merge/search logic and integration.yml descriptor validation. |
src/specify_cli/__init__.py |
Adds --catalog flag to integration listing and new integration upgrade command. |
tests/integrations/test_integration_catalog.py |
New unit/integration tests covering catalog behavior, descriptor validation, list --catalog, and upgrade. |
integrations/catalog.json |
Adds built-in integrations catalog metadata. |
integrations/catalog.community.json |
Adds empty starter community catalog file. |
integrations/README.md |
Documents catalog purpose, schema, and CLI usage. |
integrations/CONTRIBUTING.md |
Documents contribution workflow and descriptor expectations for community entries. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 7/7 changed files
- Comments generated: 4
- 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
There was a problem hiding this comment.
Pull request overview
Introduces an integration catalog system (built-in + community) to enable discovery and upgrades of Spec Kit integrations, aligning integrations with existing extension/preset/workflow catalog patterns.
Changes:
- Added
IntegrationCatalog(fetch/cache/merge/search) andIntegrationDescriptorvalidation forintegration.yml. - Extended CLI with
specify integration list --catalogand a diff-awarespecify integration upgrade [key] [--force]. - Added integration catalog JSON files plus new documentation and a comprehensive test suite.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog + descriptor validation implementation (fetch/cache/search, YAML validation, hashing). |
src/specify_cli/__init__.py |
Adds integration list --catalog output path and new integration upgrade command workflow. |
tests/integrations/test_integration_catalog.py |
New tests covering URL validation, active catalogs, fetch/search behavior, descriptor validation, list/upgrade CLI flows. |
integrations/catalog.json |
Adds built-in integration catalog entries and metadata. |
integrations/catalog.community.json |
Adds an empty community catalog starter file. |
integrations/README.md |
Documents catalog purpose, CLI usage, and schema/descriptor examples. |
integrations/CONTRIBUTING.md |
Adds contributor guidance for built-in/community integrations and upgrade behavior. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/catalog.py:379
- Building the query
haystackuses" ".join([...])with values pulled directly from catalog JSON. If any ofname/description/idare non-strings,joinwill raiseTypeError. To avoid CLI crashes from bad catalog entries, coerce these fields to strings (or validate/skip invalid entries) before joining.
raw_tags = item.get("tags", [])
tags_list = raw_tags if isinstance(raw_tags, list) else []
haystack = " ".join(
[
item.get("name", ""),
item.get("description", ""),
item.get("id", ""),
]
+ [t for t in tags_list if isinstance(t, str)]
).lower()
if query.lower() not in haystack:
continue
- Files reviewed: 7/7 changed files
- Comments generated: 7
- 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
There was a problem hiding this comment.
Pull request overview
Introduces an integrations catalog system (mirroring existing extension/preset catalogs) to enable discovery and metadata validation of integrations, and adds CLI support for browsing the catalog and upgrading an installed integration with modified-file protection.
Changes:
- Added
IntegrationCatalog(fetch/cache/merge/search) andIntegrationDescriptor(integration.yml loading + validation + hashing). - Added CLI enhancements:
specify integration list --catalogandspecify integration upgrade [key] [--force]. - Added built-in/community integration catalog JSON files plus new integrations documentation and tests.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
Implements integration catalog fetching/caching/search and integration.yml descriptor validation. |
src/specify_cli/__init__.py |
Adds integration list --catalog output and new integration upgrade command flow. |
tests/integrations/test_integration_catalog.py |
Adds coverage for catalog URL validation, catalog resolution, fetch/search, descriptor validation, and CLI behaviors. |
integrations/catalog.json |
Adds built-in integration catalog metadata used for discovery. |
integrations/catalog.community.json |
Adds starter community catalog file (empty integrations map). |
integrations/README.md |
Documents catalog configuration/CLI usage and the catalog + descriptor schemas. |
integrations/CONTRIBUTING.md |
Adds contributor guidance for adding built-in/community integrations and using integration.yml. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 7/7 changed files
- Comments generated: 2
…e 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
There was a problem hiding this comment.
Pull request overview
Introduces an integration catalog system (built-in + community) to enable discovery and versioning of integrations, and adds CLI support for catalog browsing and diff-aware upgrades.
Changes:
- Added
IntegrationCatalog+IntegrationDescriptorfor catalog resolution/fetch/cache/search andintegration.ymlvalidation. - Added CLI enhancements:
specify integration list --catalogandspecify integration upgrade [--force]with manifest-hash modified-file blocking. - Added initial catalog JSON files plus documentation and a comprehensive new test suite.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog + descriptor implementation (resolution order, URL validation, caching, search, descriptor validation). |
src/specify_cli/__init__.py |
Adds integration list --catalog and new integration upgrade command with modified-file detection and stale-file cleanup. |
tests/integrations/test_integration_catalog.py |
New tests covering catalog entry/config, fetch/search, descriptor validation, and CLI list/upgrade flows. |
integrations/catalog.json |
Adds built-in integration catalog entries. |
integrations/catalog.community.json |
Adds empty starter community catalog. |
integrations/README.md |
Documents catalog config, CLI usage, descriptor format, and schema. |
integrations/CONTRIBUTING.md |
Adds contribution guidance for built-in/community catalogs and upgrade workflow notes. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 7/7 changed files
- Comments generated: 1
There was a problem hiding this comment.
Pull request overview
Adds an integration catalog system to Spec Kit (mirroring existing extension/preset catalog patterns) to support discovery + metadata validation, and introduces CLI support for catalog browsing and diff-aware integration upgrades.
Changes:
- Introduces
IntegrationCatalog/IntegrationDescriptorfor catalog resolution, fetching+cache, searching, andintegration.ymlvalidation. - Extends the CLI with
specify integration list --catalogand addsspecify integration upgrade [key] [--force]. - Adds built-in/community integration catalog JSON files plus contributor-facing documentation and a dedicated test suite.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New integration catalog + descriptor loader/validator + caching/search logic |
src/specify_cli/__init__.py |
Adds integration list --catalog and new integration upgrade command |
integrations/catalog.json |
Built-in integrations catalog metadata |
integrations/catalog.community.json |
Starter community catalog metadata |
integrations/README.md |
Integration catalog + descriptor schema/usage documentation |
integrations/CONTRIBUTING.md |
Contribution guide for built-in/community integration entries |
tests/integrations/test_integration_catalog.py |
Tests for catalog resolution/fetch/search, descriptor validation, CLI list/upgrade behaviors |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
src/specify_cli/integrations/catalog.py:565
- Same issue as command file paths:
os.path.isabs()doesn’t catch Windows drive-qualified relative paths (e.g.,C:foo\bar). If these script paths are later used for file operations, they may escape the intended relative-path constraint. Consider rejecting entries with a non-emptyPath(script_entry).drive/anchoras well.
if os.path.isabs(script_entry) or ".." in Path(script_entry).parts:
raise IntegrationDescriptorError(
f"Script entry must be a relative path without '..': {script_entry}"
- Files reviewed: 7/7 changed files
- Comments generated: 2
- 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
There was a problem hiding this comment.
Pull request overview
Introduces an integration catalog system (similar to existing extension/preset catalogs) to support discovery, validation, and upgrades of Spec Kit integrations, along with CLI surfacing and documentation.
Changes:
- Added
IntegrationCatalog(catalog resolution, URL validation, fetch/cache/merge, search) andIntegrationDescriptor(integration.yml validation + hashing). - Extended CLI with
specify integration list --catalogand newspecify integration upgrade [key] [--force]. - Added built-in/community integration catalog JSON files, contributor/docs guides, and a dedicated test suite.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/integrations/catalog.py |
New catalog + descriptor implementation (fetch/cache/search + integration.yml validation). |
src/specify_cli/__init__.py |
Adds integration list --catalog output and new integration upgrade command flow. |
tests/integrations/test_integration_catalog.py |
New tests covering catalog behavior, descriptor validation, CLI list/upgrade paths. |
integrations/catalog.json |
Seeds the built-in integration catalog entries. |
integrations/catalog.community.json |
Adds an empty starter community catalog file. |
integrations/README.md |
Documents catalog config, schema, and CLI usage. |
integrations/CONTRIBUTING.md |
Contributor guidance for adding/updating catalog entries and descriptors. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
tests/integrations/test_integration_catalog.py:596
- Same issue as the modified-files blocking test: the guarded modification means this test may not actually create a modified tracked file (manifest empty / target missing), reducing confidence that
--forceis exercising the intended overwrite path. Consider asserting the precondition (a tracked file was modified) before running the upgrade.
manifest_data = json.loads(manifest_path.read_text())
tracked_files = manifest_data.get("files", {})
if tracked_files:
first_rel = next(iter(tracked_files))
target_file = project / first_rel
if target_file.exists():
target_file.write_text("MODIFIED CONTENT\n")
- Files reviewed: 7/7 changed files
- Comments generated: 2
There was a problem hiding this comment.
Pull request overview
Adds an integration catalog subsystem to Spec Kit, enabling discovery/browsing of built-in + community integrations and introducing a diff-aware integration upgrade workflow aligned with existing catalog patterns.
Changes:
- Introduces
IntegrationCatalog/IntegrationDescriptorfor catalog resolution, URL validation, caching, search, andintegration.ymlvalidation. - Extends CLI with
specify integration list --catalogand addsspecify integration upgrade [key] [--force]. - Adds integration catalog JSON files + documentation and a new test suite covering catalog/descriptor behavior and CLI flows.
Show a summary per file
| File | Description |
|---|---|
tests/integrations/test_integration_catalog.py |
New tests for catalog resolution/validation, fetch/search behavior, descriptor validation, and CLI list --catalog / upgrade. |
src/specify_cli/integrations/catalog.py |
Implements integration catalog stack resolution, URL validation, per-URL caching, merged search, and integration.yml descriptor validation. |
src/specify_cli/__init__.py |
Adds --catalog flag to integration list and introduces integration upgrade command with manifest-based modified-file blocking and stale-file cleanup. |
integrations/catalog.json |
Adds built-in integration catalog metadata entries. |
integrations/catalog.community.json |
Adds starter community catalog file (empty integrations map). |
integrations/README.md |
Documents catalog configuration, CLI usage, and catalog/descriptor schema. |
integrations/CONTRIBUTING.md |
Adds contribution instructions for built-in and community integration catalog entries. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 7/7 changed files
- Comments generated: 1
Adds a catalog system for integrations mirroring the established extension and preset catalog patterns, enabling discovery and community-contributed integrations.
Catalog files
integrations/catalog.json— 27 built-in integrations metadataintegrations/catalog.community.json— empty community catalog starterIntegrationCatalogclass (src/specify_cli/integrations/catalog.py)IntegrationDescriptorforintegration.ymlvalidation — schema version, ID format, semver, required fields, SHA-256 hashingCLI commands
specify integration list --catalog— browse merged catalog (built-in + community) with source and install statusspecify integration upgrade [key] [--force]— diff-aware reinstall via manifest hash comparison; blocks on modified files unless--forceDocumentation
integrations/README.md— schema reference, CLI usageintegrations/CONTRIBUTING.md— checklist for adding built-in and community integrationsTests
40 tests covering catalog entries, URL validation, active catalogs, fetch/search, descriptor validation,
list --catalog, and upgrade (including modified-file blocking and--forceoverride).