Skip to content

feat: Integration catalog — discovery, versioning, and community distribution#2130

Open
Copilot wants to merge 20 commits intomainfrom
copilot/add-integration-catalog
Open

feat: Integration catalog — discovery, versioning, and community distribution#2130
Copilot wants to merge 20 commits intomainfrom
copilot/add-integration-catalog

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

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 metadata
  • integrations/catalog.community.json — empty community catalog starter

IntegrationCatalog class (src/specify_cli/integrations/catalog.py)

  • URL validation, catalog stack resolution (env var → project → user → defaults), per-URL caching, search with query/tag/author filters
  • IntegrationDescriptor for integration.yml validation — schema version, ID format, semver, required fields, SHA-256 hashing

CLI commands

  • specify integration list --catalog — browse merged catalog (built-in + community) with source and install status
  • specify integration upgrade [key] [--force] — diff-aware reinstall via manifest hash comparison; blocks on modified files unless --force
specify integration list --catalog          # browse full catalog
specify integration upgrade                 # upgrade current integration
specify integration upgrade --force         # overwrite modified files

Documentation

  • integrations/README.md — schema reference, CLI usage
  • integrations/CONTRIBUTING.md — checklist for adding built-in and community integrations

Tests

40 tests covering catalog entries, URL validation, active catalogs, fetch/search, descriptor validation, list --catalog, and upgrade (including modified-file blocking and --force override).

Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 20:37
…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>
Copilot AI requested review from Copilot and removed request for Copilot April 8, 2026 20:48
Comment thread src/specify_cli/integrations/catalog.py Fixed
Comment thread src/specify_cli/__init__.py Fixed
Copilot AI changed the title [WIP] Add integration catalog for built-in and community integrations feat: Integration catalog — discovery, versioning, and community distribution Apr 8, 2026
Copilot AI requested a review from mnriem April 8, 2026 20:50
@mnriem mnriem marked this pull request as ready for review April 15, 2026 14:33
Copilot AI review requested due to automatic review settings April 15, 2026 14:33
Copy link
Copy Markdown
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

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 + IntegrationDescriptor for catalog fetching/search and integration.yml validation.
  • Extended the CLI with specify integration list --catalog and a new specify integration upgrade command.
  • 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_data is 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 raise TypeError and break catalog search. Add a type check for each integ_data (and optionally for the overall integrations field) and skip/raise a structured IntegrationCatalogError.
            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

Comment thread integrations/CONTRIBUTING.md Outdated
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/__init__.py Outdated
Comment thread src/specify_cli/__init__.py Outdated
mnriem added 2 commits April 15, 2026 09:46
- 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
Copy link
Copy Markdown
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

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 + IntegrationDescriptor for catalog discovery/caching/search and integration.yml validation.
  • Added CLI enhancements: specify integration list --catalog and specify 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-*.json but leaves the corresponding catalog-*-metadata.json files 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_version to 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 with packaging.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

Comment thread src/specify_cli/__init__.py Outdated
Comment thread src/specify_cli/__init__.py Outdated
Comment thread integrations/CONTRIBUTING.md Outdated
Comment thread src/specify_cli/integrations/catalog.py Outdated
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py Outdated
- 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
Comment thread src/specify_cli/__init__.py Fixed
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 15, 2026 19:35
Copy link
Copy Markdown
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

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 / IntegrationDescriptor for fetching, caching, searching catalogs and validating integration.yml.
  • Adds CLI support for specify integration list --catalog and a new specify integration upgrade command.
  • 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 a TypeError/KeyError instead of a clear IntegrationDescriptorError. Add an explicit isinstance(data, dict) check after safe_load and 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, and integrations). This can lead to invalid PRs against integrations/catalog.community.json. Update the example to show the full structure or explicitly note it’s the contents of the integrations object.
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


Comment thread integrations/CONTRIBUTING.md Outdated
Comment thread src/specify_cli/integrations/catalog.py Outdated
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py Outdated
Comment thread src/specify_cli/__init__.py Outdated
Comment thread src/specify_cli/integrations/catalog.py Outdated
- 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
Copy link
Copy Markdown
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

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 + IntegrationDescriptor for catalog resolution/fetch/cache/search and integration.yml validation.
  • Added CLI enhancements: specify integration list --catalog and specify 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

Comment thread src/specify_cli/__init__.py Outdated
Copy link
Copy Markdown
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

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 / IntegrationDescriptor for catalog resolution, fetching+cache, searching, and integration.yml validation.
  • Extends the CLI with specify integration list --catalog and adds specify 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-empty Path(script_entry).drive / anchor as 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

Comment thread src/specify_cli/integrations/catalog.py
Comment thread src/specify_cli/integrations/catalog.py
- 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
Copy link
Copy Markdown
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

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) and IntegrationDescriptor (integration.yml validation + hashing).
  • Extended CLI with specify integration list --catalog and new specify 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 --force is 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

Comment thread src/specify_cli/integrations/catalog.py Outdated
Comment thread tests/integrations/test_integration_catalog.py
Copy link
Copy Markdown
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

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 / IntegrationDescriptor for catalog resolution, URL validation, caching, search, and integration.yml validation.
  • Extends CLI with specify integration list --catalog and adds specify 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

Comment thread integrations/CONTRIBUTING.md Outdated
Copy link
Copy Markdown
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

Adds an integration catalog system (mirroring existing catalog patterns in the repo) plus CLI support to browse the catalog and perform a diff-aware integration upgrade.

Changes:

  • Introduces IntegrationCatalog (fetch/cache/merge/search) and IntegrationDescriptor (integration.yml validation + hashing).
  • Adds CLI support for specify integration list --catalog and specify integration upgrade [key] [--force].
  • Adds built-in + community catalog JSON files, documentation, and a new test suite for catalog/descriptor/CLI behavior.
Show a summary per file
File Description
tests/integrations/test_integration_catalog.py New tests covering catalog URL validation, catalog resolution, fetch/search, descriptor validation, and CLI list/upgrade flows.
src/specify_cli/integrations/catalog.py New implementation of integration catalog resolution + fetching/caching and integration.yml descriptor validation.
src/specify_cli/init.py Extends integration CLI with list --catalog and adds integration upgrade command.
integrations/catalog.json Adds built-in integration catalog metadata.
integrations/catalog.community.json Adds starter community catalog file.
integrations/README.md Documents catalog system, configuration, CLI usage, and schemas.
integrations/CONTRIBUTING.md Documents how to add built-in/community integrations and update versions.

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: 3

Comment thread src/specify_cli/__init__.py Outdated
Comment thread tests/integrations/test_integration_catalog.py
Comment thread tests/integrations/test_integration_catalog.py
- 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
Copy link
Copy Markdown
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

Adds an integration catalog system (mirroring existing extension/preset catalog patterns) to support discovery, metadata validation, and a diff-aware upgrade flow for installed integrations.

Changes:

  • Introduces IntegrationCatalog + IntegrationDescriptor for resolving catalog stacks, fetching/caching catalogs, searching, and validating integration.yml.
  • Extends CLI with specify integration list --catalog and a new specify integration upgrade command (blocks on modified files unless --force).
  • Adds 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 resolution/fetch/search logic and integration.yml descriptor validation.
src/specify_cli/__init__.py Adds integration list --catalog output and implements integration upgrade command.
tests/integrations/test_integration_catalog.py New tests covering catalog resolution, fetch/search, descriptor validation, and CLI commands.
integrations/catalog.json Built-in integration catalog metadata.
integrations/catalog.community.json Starter community catalog file (empty).
integrations/README.md User-facing docs for catalog configuration, CLI usage, and schemas.
integrations/CONTRIBUTING.md Contributor guide for adding built-in/community catalog entries and descriptor requirements.

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

Comment thread src/specify_cli/__init__.py Outdated
Comment thread src/specify_cli/integrations/catalog.py Outdated
Copy link
Copy Markdown
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

Adds an integration catalog subsystem to the Specify CLI, aligning integrations with the existing catalog/discovery patterns used elsewhere in the codebase and introducing CLI support for catalog browsing and integration upgrades.

Changes:

  • Introduces IntegrationCatalog (URL validation, catalog stack resolution, per-URL caching, search) and IntegrationDescriptor (integration.yml validation + hashing).
  • Extends the CLI with specify integration list --catalog and a new specify integration upgrade [key] [--force].
  • Adds built-in/community catalog JSON files, documentation, and a comprehensive test suite for the new behavior.
Show a summary per file
File Description
src/specify_cli/integrations/catalog.py Implements integration catalog discovery/caching/search and integration.yml descriptor validation.
src/specify_cli/__init__.py Adds --catalog mode to integration listing and introduces integration upgrade command.
tests/integrations/test_integration_catalog.py Adds unit/integration tests for catalog resolution, fetch/search, descriptor validation, list --catalog, and upgrade flows.
integrations/catalog.json Adds built-in catalog metadata for shipped integrations.
integrations/catalog.community.json Adds a starter (empty) community catalog file.
integrations/README.md Documents catalog usage, configuration, CLI commands, and schemas.
integrations/CONTRIBUTING.md Documents contribution workflow for built-in/community integration catalog entries and integration.yml expectations.

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

Comment thread src/specify_cli/integrations/catalog.py
Copy link
Copy Markdown
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

Adds an integration catalog system (mirroring the existing extension/preset catalog patterns) to enable integration discovery, basic descriptor validation, and a diff-aware upgrade flow via the CLI.

Changes:

  • Introduces IntegrationCatalog (+ config resolution, URL validation, fetch/cache, merged search) and IntegrationDescriptor validation for integration.yml.
  • Extends the CLI with specify integration list --catalog and a new specify integration upgrade [key] [--force] command.
  • Adds 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 Implements integration catalog stack resolution, fetch+cache, search, and integration.yml descriptor validation.
src/specify_cli/__init__.py Adds --catalog listing mode and a new diff-aware integration upgrade command.
tests/integrations/test_integration_catalog.py New tests covering catalog resolution/validation, fetch/search, descriptor validation, list --catalog, and upgrade behavior.
integrations/catalog.json Adds the built-in integration catalog entries shipped with Spec Kit.
integrations/catalog.community.json Adds the community catalog starter (discovery-only).
integrations/README.md Documents catalog config, CLI usage, and schema.
integrations/CONTRIBUTING.md Documents contribution workflow for built-in/community catalogs and upgrade behavior expectations.

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

Comment on lines +1818 to +1822
cat_name = entry.get("_catalog_name", "")
if eid == installed_key:
status = "[green]installed[/green]"
elif eid in INTEGRATION_REGISTRY:
status = "built-in"
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

In integration list --catalog, entries from discovery-only catalogs (where _install_allowed is false, e.g. the community catalog) are shown with an empty Status, which makes it hard to tell they aren’t directly installable.

Consider using the _install_allowed annotation from IntegrationCatalog to display a status like “discovery-only” (and/or a hint on how to install) for those entries, similar to how extension/preset catalog UIs communicate install restrictions.

Suggested change
cat_name = entry.get("_catalog_name", "")
if eid == installed_key:
status = "[green]installed[/green]"
elif eid in INTEGRATION_REGISTRY:
status = "built-in"
cat_name = entry.get("_catalog_name", "")
install_allowed = entry.get("_install_allowed", True)
if eid == installed_key:
status = "[green]installed[/green]"
elif eid in INTEGRATION_REGISTRY:
status = "built-in"
elif install_allowed is False:
status = "discovery-only"

Copilot uses AI. Check for mistakes.
def clear_cache(self) -> None:
"""Remove all cached catalog files."""
if self.cache_dir.exists():
for f in self.cache_dir.glob("catalog-*.json"):
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

IntegrationCatalog.clear_cache() only removes catalog-*.json but leaves the corresponding catalog-*-metadata.json files behind. That makes the cache directory accumulate stale metadata and diverges from the behavior in ExtensionCatalog.clear_cache().

Consider deleting both the JSON and metadata files (and optionally handling any legacy cache filenames if you add them later).

Suggested change
for f in self.cache_dir.glob("catalog-*.json"):
cache_files = {
f
for pattern in ("catalog-*.json", "catalog-*-metadata.json")
for f in self.cache_dir.glob(pattern)
}
for f in cache_files:

Copilot uses AI. Check for mistakes.
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.

Integration catalog — built-in and community integration discovery and distribution

3 participants