Commit 94ba857
Add
* Initial plan
* Add specify integration subcommand (list, install, uninstall, switch)
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>
* Address review feedback: extract helper, fix return type annotation
- 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>
* Potential fix for pull request finding 'Unused import'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
* Address review feedback: validate script type, handle --flag=value, fix 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
* Block --force with different integration, persist script type in init-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
* Remove --force from integration install, ensure shared infra on install/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
* Remove redundant installed_key != key check
The == key case already returns above, so the != key guard is always true
at this point. Simplify to just 'if installed_key:'.
* Run shared infra unconditionally, defer metadata removal in switch
- 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
* Add install rollback, graceful manifest errors, clear switch metadata
- Attempt teardown rollback on install/switch failure to avoid orphaned files
- Catch ValueError/FileNotFoundError on IntegrationManifest.load() in uninstall
with user-friendly recovery guidance
- Clear metadata immediately after switch teardown so failed Phase 2 doesn't
leave stale references to the removed integration
* Log rollback failures instead of silently suppressing them
* Handle corrupt manifest in switch, distinguish unknown vs missing manifest
- 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
* Clean up metadata on rollback, broaden init-options match in uninstall
- 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
* Fix recovery guidance for unreadable manifests, fix type annotations
- 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
* Allow manifest-only uninstall for unknown/removed integrations
- 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
* Fail fast on corrupt integration.json, validate integration options
- _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
* Validate integration.json is a dict, fail fast on missing manifest in 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
---------
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>specify integration subcommand for post-init integration management (#2083)1 parent e1ab4f0 commit 94ba857
File tree
2 files changed
+1027
-0
lines changed- src/specify_cli
- tests/integrations
2 files changed
+1027
-0
lines changed
0 commit comments