Skip to content

Add specify integration subcommand for post-init integration management#2083

Merged
mnriem merged 17 commits intomainfrom
copilot/add-specify-integration-subcommand
Apr 3, 2026
Merged

Add specify integration subcommand for post-init integration management#2083
mnriem merged 17 commits intomainfrom
copilot/add-specify-integration-subcommand

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

Integrations can currently only be configured during specify init. This adds a specify integration subcommand group for managing integrations in existing projects, following the established specify <noun> <verb> pattern used by extensions and presets.

Commands

  • specify integration list — table of available integrations with installed status from .specify/integration.json
  • specify integration install <key> — writes files + manifest, updates integration.json and init-options.json
  • specify integration uninstall [key] — hash-safe removal via IntegrationManifest; preserves modified files, reports skipped
  • specify integration switch <target> — reads current from integration.json, teardown → setup; shared infra untouched
specify integration list
specify integration install copilot
specify integration uninstall copilot
specify integration switch claude --script sh

Implementation

  • Reuses existing IntegrationManifest hash tracking and IntegrationBase.setup()/teardown() — no new install/uninstall mechanics
  • Extracted _update_init_options_for_integration() helper to deduplicate init-options update logic between install and switch
  • _resolve_script_type() falls back to init-options.json then platform default when --script is omitted
  • _parse_integration_options() handles --integration-options passthrough for integrations that declare custom options (e.g. generic's --commands-dir)

Tests

21 tests in tests/integrations/test_integration_subcommand.py covering:

  • All four commands with validation, error, and happy paths
  • Full lifecycle: install → modify file → uninstall → verify modified file preserved
  • Switch preserves shared infra (.specify/scripts/, .specify/templates/)

Implements the `specify integration` subcommand group for managing
integrations in existing projects after initial setup:

- `specify integration list` — shows available integrations and installed status
- `specify integration install <key>` — installs an integration into existing project
- `specify integration uninstall [key]` — hash-safe removal preserving modified files
- `specify integration switch <target>` — uninstalls current, installs target

Follows the established `specify <noun> <verb>` CLI pattern used by
extensions and presets. Shared infrastructure (scripts, templates) is
preserved during uninstall and switch operations.

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/1cca6c84-3e12-465d-88b8-a646d3504f63

Co-authored-by: mnriem <15701806+mnriem@users.noreply.github.com>
Copilot AI and others added 2 commits April 3, 2026 19:56
- Extract _update_init_options_for_integration() to deduplicate init-options
  update logic between install and switch commands
- Fix _parse_integration_options return type to dict[str, Any] | None

Agent-Logs-Url: https://github.com/github/spec-kit/sessions/1cca6c84-3e12-465d-88b8-a646d3504f63

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>
@mnriem mnriem requested a review from Copilot April 3, 2026 19:58
Copilot AI changed the title [WIP] Add specify integration subcommand for post-init integration management Add specify integration subcommand for post-init integration management Apr 3, 2026
Copilot AI requested a review from mnriem April 3, 2026 20:00
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 a new specify integration CLI subcommand group to manage AI agent integrations in an already-initialized spec-kit project.

Changes:

  • Added specify integration subcommands: list, install, uninstall, and switch.
  • Introduced helper utilities for reading/writing .specify/integration.json and parsing --integration-options.
  • Added a comprehensive new test suite covering the new subcommands and lifecycle behaviors.
Show a summary per file
File Description
src/specify_cli/__init__.py Implements the new integration Typer subcommands and supporting helper functions.
tests/integrations/test_integration_subcommand.py Adds end-to-end CLI tests for list/install/uninstall/switch, including manifest-safe teardown behavior.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 6

…ix metadata cleanup

- Add _normalize_script_type() to validate script type against SCRIPT_TYPE_CHOICES
- Handle --name=value syntax in _parse_integration_options()
- Clear init-options.json keys in no-manifest uninstall early-return path
- Clear stale metadata between switch teardown and install phases
- Add 5 tests covering the new edge cases
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 a new specify integration subcommand group so integrations can be managed after project initialization, using the existing integration setup/teardown + manifest hash-tracking mechanisms.

Changes:

  • Introduces specify integration list/install/uninstall/switch commands and supporting helpers.
  • Adds parsing for --integration-options passthrough to integrations that declare custom options.
  • Adds a comprehensive new test suite covering the new subcommands and lifecycle scenarios.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration Typer sub-app and implements list/install/uninstall/switch flows.
tests/integrations/test_integration_subcommand.py Adds end-to-end CLI tests for all new integration subcommands and edge cases.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 3

…-options

- --force on install now rejects overwriting a different integration; users must
  use 'specify integration switch' instead
- _update_init_options_for_integration() now accepts and persists script_type
- Fix misleading test docstring for switch metadata test
- Add test_force_blocked_with_different_integration
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 a new specify integration subcommand group to manage AI agent integrations in already-initialized spec-kit projects (list/install/uninstall/switch), reusing the existing integration setup/teardown + manifest hashing mechanics and adding dedicated CLI tests.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands and supporting helpers (integration.json read/write, script-type resolution, init-options updates, integration-options parsing).
  • Implements install/uninstall/switch flows using IntegrationManifest + IntegrationBase.setup()/teardown().
  • Adds a comprehensive test suite covering command behavior and lifecycle scenarios.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration Typer sub-app and core command implementations/helpers.
tests/integrations/test_integration_subcommand.py New tests validating all integration subcommands and lifecycle 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/init.py:1856

  • In the switch uninstall phase, if the current integration can’t be resolved (current_integration is None) but a manifest exists, the code skips teardown entirely, leaving the old integration files in place and potentially conflicting with the target integration. Consider falling back to IntegrationManifest.load(...).uninstall(...) when current_integration is missing, rather than skipping uninstall.
        current_integration = get_integration(installed_key)
        manifest_path = project_root / ".specify" / "integrations" / f"{installed_key}.manifest.json"

        if current_integration and manifest_path.exists():
            console.print(f"Uninstalling current integration: [cyan]{installed_key}[/cyan]")
            old_manifest = IntegrationManifest.load(installed_key, project_root)
            removed, skipped = current_integration.teardown(
                project_root, old_manifest, force=force,
            )
            if removed:
                console.print(f"  Removed {len(removed)} file(s)")
            if skipped:
                console.print(f"  [yellow]⚠[/yellow]  {len(skipped)} modified file(s) preserved")
        else:
            console.print(f"[dim]No manifest for '{installed_key}' — skipping uninstall phase[/dim]")

  • Files reviewed: 2/2 changed files
  • Comments generated: 4

…ll/switch

- Remove --force parameter entirely from integration install; users must
  uninstall before reinstalling to prevent orphaned files
- Auto-install shared infrastructure (.specify/scripts/, .specify/templates/)
  when missing during install or switch
- Add test for shared infra creation on bare project install
@mnriem mnriem requested a review from Copilot April 3, 2026 20:43
The == key case already returns above, so the != key guard is always true
at this point. Simplify to just 'if installed_key:'.
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 a new specify integration subcommand group to manage AI agent integrations after project initialization, enabling listing, install, uninstall (hash-safe), and switching integrations in existing spec-kit projects.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands and supporting helpers for reading/writing integration metadata and init-options updates.
  • Implements integration option passthrough via --integration-options parsing and script type resolution via CLI → init-options → platform default.
  • Adds a comprehensive test suite covering command validation, lifecycle behavior, safe uninstall preservation, and switching semantics.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds integration Typer sub-app with list/install/uninstall/switch logic and shared helpers.
tests/integrations/test_integration_subcommand.py Adds end-to-end CLI tests for the new integration subcommands and edge cases.

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/init.py:1870

  • Same issue as integration install: shared infra setup is conditioned only on .specify/scripts existing. Switching into a project where scripts exist but templates are missing will skip _install_shared_infra() and can break integrations that expect .specify/templates to be present. Recommend checking for both directories (and/or calling _install_shared_infra() unconditionally).
    # Ensure shared infrastructure exists
    if not (project_root / ".specify" / "scripts").exists():
        _install_shared_infra(project_root, selected_script)
        if os.name != "nt":
            ensure_executable_scripts(project_root)

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

- Call _install_shared_infra() unconditionally on install and switch since it
  merges without overwriting existing files
- Remove premature metadata cleanup between switch phases; metadata is now
  only updated after successful Phase 2 install
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 a new specify integration subcommand group to manage AI agent integrations after project initialization (list/install/uninstall/switch), reusing the existing integration manifest + setup/teardown mechanisms.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands with shared helpers for metadata, script-type resolution, and init-options updates.
  • Implements --integration-options parsing to pass integration-specific flags through to integrations that declare options.
  • Adds a comprehensive test suite covering command behavior and lifecycle scenarios (including preserving modified files and shared infrastructure).
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration command group and supporting helpers for install/uninstall/switch flows and metadata management.
tests/integrations/test_integration_subcommand.py Adds end-to-end CLI tests for the new integration subcommands and key edge cases.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

…ifest

- Wrap IntegrationManifest.load() in switch with ValueError/FileNotFoundError
  handling, matching the pattern used in uninstall
- Split else branch to report 'unknown integration' vs 'no manifest' separately
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 a new specify integration subcommand group to manage AI integrations after project initialization (list/install/uninstall/switch), reusing existing integration setup/teardown + manifest tracking.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands with script-type resolution and init-options updates.
  • Adds parsing for --integration-options passthrough to integrations that declare custom options.
  • Adds a comprehensive test suite covering install/uninstall/switch lifecycle behaviors and edge cases.
Show a summary per file
File Description
src/specify_cli/__init__.py Implements the new integration command group, integration metadata helpers, option parsing, and init-options synchronization.
tests/integrations/test_integration_subcommand.py Adds integration subcommand tests covering validation, lifecycle flows, and metadata/shared-infra preservation.

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/init.py:1804

  • Same init-options cleanup issue as above: this only clears keys when opts.get("integration") == key. To avoid leaving stale ai/ai_skills behind, consider clearing when opts.get("integration") == key OR opts.get("ai") == key.
    # Update init-options.json to clear the integration
    opts = load_init_options(project_root)
    if opts.get("integration") == key:
        opts.pop("integration", None)
        opts.pop("ai", None)
        opts.pop("ai_skills", None)
        save_init_options(project_root, opts)
  • Files reviewed: 2/2 changed files
  • Comments generated: 4

- Remove integration.json in install/switch rollback paths so failed installs
  don't leave stale metadata
- Match on both 'integration' and 'ai' keys when clearing init-options.json
  during uninstall to handle partially-written metadata
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 a new specify integration subcommand group to manage integrations after project initialization, enabling listing, installing, uninstalling (hash-safe), and switching integrations for existing spec-kit projects.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands and supporting helpers (script resolution, integration.json read/write, init-options updates, option parsing).
  • Reuses existing IntegrationManifest + integration setup()/teardown() for safe lifecycle operations and shared infra installation.
  • Adds a comprehensive new test suite covering command validation and end-to-end lifecycle behaviors.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds integration Typer subcommands and helpers for metadata, script type resolution, init-options updates, and integration option parsing.
tests/integrations/test_integration_subcommand.py New tests covering list/install/uninstall/switch flows, including modified-file preservation and script type validation.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

- Recovery instructions now guide users through delete manifest → uninstall →
  reinstall workflow that actually works
- Type annotations for optional CLI parameters changed from str to str | None
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 a new specify integration subcommand group to manage AI agent integrations after project initialization, aligning integration management with existing specify <noun> <verb> CLI patterns.

Changes:

  • Introduces specify integration list|install|uninstall|switch commands that reuse the existing IntegrationManifest + IntegrationBase.setup()/teardown() mechanisms.
  • Adds helpers for script-type resolution, integration metadata (.specify/integration.json) read/write, init-options updates, and --integration-options parsing.
  • Adds a comprehensive new test suite covering happy paths, validation/errors, lifecycle behaviors, and edge cases.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration Typer sub-app plus implementations for list/install/uninstall/switch and supporting helpers.
tests/integrations/test_integration_subcommand.py New tests covering all integration subcommands, lifecycle behavior, and parsing/validation edge cases.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

- Uninstall no longer requires the integration to be in the registry; falls back
  to manifest.uninstall() directly when get_integration() returns None
- Switch Phase 1 similarly uses manifest-only uninstall for unknown integrations
  instead of skipping teardown, preventing orphaned files
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 a new specify integration subcommand group to manage AI agent integrations after project initialization, enabling listing, installation, uninstallation, and switching of integrations in existing spec-kit projects.

Changes:

  • Introduces specify integration list|install|uninstall|switch commands and supporting helpers (script-type resolution, integration.json read/write, init-options updates, integration-options parsing).
  • Implements integration lifecycle behavior using existing IntegrationManifest hash tracking and IntegrationBase.setup()/teardown() patterns.
  • Adds a comprehensive test suite covering command behavior, lifecycle flows, and edge cases.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration Typer sub-app, helper utilities, and command implementations for list/install/uninstall/switch.
tests/integrations/test_integration_subcommand.py Adds 21 CLI tests covering all new integration subcommands and key edge cases.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 3

- _read_integration_json() now exits with an actionable error when
  integration.json exists but is corrupt/unreadable
- _parse_integration_options() rejects unknown options, validates flag usage,
  and requires values for non-flag options
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 a new specify integration subcommand group to manage AI integrations in already-initialized spec-kit projects (list/install/uninstall/switch), reusing existing integration setup/teardown + manifest tracking.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands and supporting helpers for integration metadata, script-type resolution, and init-options updates.
  • Adds parsing for --integration-options passthrough to integrations that declare custom options.
  • Adds a comprehensive test suite covering command behaviors and lifecycle scenarios.
Show a summary per file
File Description
src/specify_cli/__init__.py Implements the new integration Typer subcommands plus helpers for metadata, script resolution, options parsing, and init-options updates.
tests/integrations/test_integration_subcommand.py New end-to-end CLI tests for integration list/install/uninstall/switch, including lifecycle and edge cases.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

… switch

- _read_integration_json() validates parsed JSON is a dict, not a list/string
- Switch fails fast with recovery guidance when manifest is missing instead
  of silently skipping teardown and risking co-existing integration files
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 a new specify integration subcommand group to manage AI integrations after project initialization, enabling listing, installing, uninstalling, and switching integrations within existing spec-kit projects.

Changes:

  • Introduces specify integration {list,install,uninstall,switch} commands and supporting helpers (integration.json handling, script-type resolution, init-options updates, integration-options parsing).
  • Implements safe uninstall/switch workflows using IntegrationManifest (hash-based preservation of modified files) and shared-infra reuse.
  • Adds a comprehensive test suite covering command behaviors and lifecycle scenarios.
Show a summary per file
File Description
src/specify_cli/__init__.py Adds the integration command group plus helpers for metadata, script type resolution, and option parsing.
tests/integrations/test_integration_subcommand.py Adds end-to-end CLI tests for list/install/uninstall/switch, including edge cases and lifecycle preservation behavior.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new

@mnriem mnriem merged commit 94ba857 into main Apr 3, 2026
13 checks passed
@mnriem mnriem deleted the copilot/add-specify-integration-subcommand branch April 3, 2026 22:35
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.

Add specify integration subcommand for post-init integration management

3 participants