Skip to content

feat(init): support scaffolding without an integration - #5030

Open
mnriem wants to merge 3 commits into
github:mainfrom
mnriem:mnriem-integration-free-scaffolding
Open

mnriem wants to merge 3 commits into
github:mainfrom
mnriem:mnriem-integration-free-scaffolding

Conversation

@mnriem

@mnriem mnriem commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Description

Allow teams to initialize shared Spec Kit infrastructure without committing agent-specific commands, skills, settings, or integration metadata:

specify init my-project --integration none
cd my-project
specify integration install copilot
specify integration uninstall copilot

none is an init-only opt-out, not a registered integration. Omitted --integration retains the existing interactive picker and non-interactive Copilot default.

The new mode installs shared templates, scripts, constitution, workflow, configuration, and the shared infrastructure manifest. It skips agent setup, tool checks, external adapter lookup/loading, native events, per-agent manifests, and integration.json. Init options record no active agent, so optional presets and extensions do not emit agent-specific command artifacts.

Installing the first integration later refreshes unmodified managed shared files for its invocation syntax while preserving customized files. Removing the last integration retains the existing behavior: clear active integration metadata and preserve shared infrastructure and modified/unmanaged agent files.

Reject integration-specific options with none, and require explicit uninstall before using this mode in a project with installed integrations; init does not silently delete agent files.

Update the CLI help, core/integration reference, and integration design documentation. No issue is linked; this is a contributor-requested capability.

Testing

  • Tested locally with uv run specify --help
  • Ran existing tests with uv sync && uv run pytest
  • Tested with a sample project (if applicable)

Used this worktree's own virtual environment instead of bare uv run pytest, as recommended in CONTRIBUTING.md. The full suite was not run.

  • uv sync --extra test — passed; created this worktree's test environment.
  • .venv/bin/python -m pytest tests/specify_cli/test_command_init.py -q — before implementation: 15 passed, 7 new cases failed, demonstrating the unsupported none selection.
  • .venv/bin/python -m pytest tests/specify_cli/test_command_init.py tests/specify_cli/integrations/test_command_install.py tests/specify_cli/integrations/test_command_uninstall.py tests/integrations/test_cli.py tests/test_agent_config_consistency.py -q — passed, 170 tests.
  • .venv/bin/python -m pytest tests/specify_cli/integrations/test_lifecycle.py tests/specify_cli/test_file_policy.py -q — passed, 193 tests.
  • uv run specify --help — passed.
  • git diff --check — passed.

The new tests verify all three script types, no generated agent artifacts, invalid options/script rejection, corrupt-state reporting, preservation on re-init, refusal to remove existing integrations, optional preset/extension installation, and the init/install/uninstall/re-init round trip. The install round trip also checks invocation-syntax refresh and preservation of customized templates.

Separately exercised the actual .venv/bin/specify executable in separate subprocesses against a disposable dummy project, with all four commands succeeding: init with --integration none --non-interactive, integration install copilot, integration uninstall copilot, and re-init with --here --integration none --force --non-interactive. Assertions checked real generated files, active-agent metadata, and preservation of shared scaffolding. The temporary project was removed afterward.

AI Disclosure

  • I did not use AI assistance for this contribution
  • I did use AI assistance (fill in the disclosure below)

AI disclosure: GitHub Copilot, powered by GPT-6.1 Sol (model ID: gpt-6.1-sol), performed autonomous implementation within mnriem's requested and approved scope. Reasoning effort was not exposed in the session metadata. Assistance included code investigation, implementation, automated tests, subprocess-based dummy-project validation, documentation, and authoring the commit and this PR description. This does not claim human line-by-line review.

Add the init-only --integration none opt-out while preserving shared infrastructure and existing defaults. Support later integration installation and cover the complete install/uninstall lifecycle.

Assisted-by: GitHub Copilot (model: GPT-6.1 Sol, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings October 19, 2026 20:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Optional-component installation can still load adapters despite the integration-free contract.

3 open issues
What changed in this PR

Adds an init-only --integration none mode so teams can scaffold shared Spec Kit infrastructure before choosing an agent.

Changes:

  • Skips agent setup and records no active integration.
  • Refreshes unmodified shared files when installing the first integration.
  • Adds lifecycle tests and documents the new initialization flow.

AI review for the requester: GitHub Copilot; model/settings unavailable; automated source review and focused verification.

File Description
tests/​specify_cli/​test_command_init.py Tests shared-only scaffolding, validation, preservation, and lifecycle transitions.
src/​specify_cli/​integrations/​command_install.py Enables shared-file refresh on first integration installation.
src/​specify_cli/​integrations/​_lifecycle.py Bypasses adapter preparation for none.
src/​specify_cli/​command_init.py Implements integration-free initialization and next-step guidance.
docs/​reference/​integrations.md Introduces the shared-only initialization option.
docs/​reference/​core.md Documents usage, restrictions, and later integration installation.
design/​integration.md Defines the integration-free lifecycle contract.

Review effort: Max

Comment on lines +816 to +817
else:
tracker.skip("integration", "none selected")
Comment on lines +439 to +440
if key == "none":
return handler(*args, **kwargs)
Comment thread src/specify_cli/integrations/command_install.py
Recognize integration-free status while checking shared manifests, prevent adapter loading during optional component installs, and register existing contributions when installing the first integration. Add before-and-after regressions and preserve secondary-install deferral.

Assisted-by: GitHub Copilot (model: GPT-6.1 Sol, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings October 19, 2026 21:21
@mnriem

mnriem commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed all three findings from review 5577740091 in commit ef8faab.

  • Integration status now accepts initialized projects with no active agent, including cleared active keys after the last uninstall, while still checking the shared manifest. Integrated projects with missing selection metadata continue to fail; missing or modified shared files are reported.
  • Optional preset and extension installation checks active-agent state before entering command/skill registration. Event refresh skips adapter loading when there are no installed integrations. Regression coverage includes a loader sentinel and a corrupt leftover package registry.
  • Installing the first integration registers enabled extension and preset contributions after saving active metadata, then resynchronizes managed-file hashes. Secondary installs still defer contribution registration until selected.

Regression evidence: the initial review-focused selection produced 6 failures and 1 pass before the fixes, then 7 passes afterward. Additional last-uninstall status variants are included in the final targeted run.

Validation:

.venv/bin/python -m pytest tests/specify_cli/test_command_init.py tests/specify_cli/integrations/test_command_install.py tests/specify_cli/integrations/test_command_uninstall.py tests/specify_cli/integrations/test_command_status.py tests/specify_cli/integrations/test_installed_adapters.py tests/specify_cli/integrations/test_lifecycle.py tests/specify_cli/presets/test_manager.py tests/specify_cli/presets/test_manager_commands.py tests/specify_cli/presets/test_manager_skills.py tests/specify_cli/events/test_events.py tests/test_extensions.py tests/test_presets.py tests/integrations/test_cli.py -q --tb=short
Result: 1,749 passed, 3 warnings.

.venv/bin/python -m pytest tests/specify_cli/test_command_init.py tests/specify_cli/integrations/test_command_status.py tests/specify_cli/test_file_policy.py tests/test_agent_config_consistency.py -q --tb=short
Result: 294 passed on the final changes, including the additional last-uninstall status cases.

git diff --check
Result: passed.

Also ran the actual .venv/bin/specify executable in separate subprocesses against a disposable dummy project: init without an integration plus the Git extension and a team preset, status, install Copilot, status, uninstall Copilot, status, re-init without an integration, and status. All commands succeeded. Assertions verified real extension/preset artifacts, the preset's plan override, synchronized managed-file hashes, and preservation of shared scaffolding. The dummy project was removed.

AI disclosure: posted on behalf of mnriem by GitHub Copilot using GPT-6.1 Sol (gpt-6.1-sol), autonomous execution within the user-approved scope; reasoning effort was not exposed in session metadata. AI assistance covered investigation, implementation, tests, documentation, commit authorship, and this review response. No human line-by-line review is claimed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread src/specify_cli/integration_status.py
Comment thread src/specify_cli/integrations/command_install.py Outdated
Comment thread src/specify_cli/integrations/command_install.py
Keep integration-free recovery guidance explicit, preserve existing extension skills, and track newly generated contributions for hash-aware cleanup. Retain ownership through upgrade and avoid adapter loading in inactive registration helpers.

Assisted-by: GitHub Copilot (model: GPT-6.1 Sol, autonomous)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI max review requested due to automatic review settings October 19, 2026 22:10
@mnriem

mnriem commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed review 5578115557 in c0a68e9.

Integration-free shared-manifest recovery now consistently recommends specify init --here --force --integration none, with a warning to review customized files first. First-install extension registration no longer forces replacement of existing skills, including customized outputs retained by an earlier uninstall.

Newly generated contribution files are recorded with hashes using observed registration writes, without adopting pre-existing files or shared metadata. Uninstall removes unchanged extension and preset outputs while preserving edits. Upgrade captures regenerated contributions too, and extension layout reconciliation now clears stale skill tracking when manifest cleanup has already removed those outputs.

Also strengthened the earlier adapter-loading fix: direct inactive registration helpers skip adapter-loading contexts and return before constructing registrars. Existing integration-free status and optional-component regressions remain covered.

Automated validation:

.venv/bin/python -m pytest tests/specify_cli/test_command_init.py tests/specify_cli/integrations/test_command_status.py tests/specify_cli/integrations/test_helpers.py -q -k 'first_integration or inactive_registration_helpers or status_checks_shared_manifest_without_integration or registration_ownership' --tb=short
Result: 21 passed. The initial review-regression selection reproduced 11 failures before the fixes.

.venv/bin/python -m pytest tests/specify_cli/test_command_init.py tests/specify_cli/integrations/test_helpers.py tests/specify_cli/integrations/test_registration.py tests/specify_cli/integrations/test_command_install.py tests/specify_cli/integrations/test_command_uninstall.py tests/specify_cli/integrations/test_command_upgrade.py tests/specify_cli/integrations/test_command_status.py tests/specify_cli/integrations/test_lifecycle.py tests/specify_cli/presets/test_manager.py tests/specify_cli/presets/test_manager_commands.py tests/specify_cli/presets/test_manager_skills.py tests/specify_cli/events/test_events.py tests/test_extensions.py tests/test_presets.py tests/test_extension_registration.py tests/specify_cli/test_file_policy.py tests/test_agent_config_consistency.py -q --tb=short
Result: 1,313 passed, 15 warnings (legacy layouts and deliberately simulated composition/registration failures).

.venv/bin/python -m pytest tests/specify_cli/integrations/test_installed_adapters.py -q -k 'registration or skill_directory_uses_pinned or contributions_follow_active' --tb=short
Result: 33 passed.

git diff --check
Result: passed.

Separately exercised the standalone .venv/bin/specify executable in a disposable project: init without an integration plus Git extension and local team preset, first Copilot install, verification of every recorded SHA-256 hash, uninstall, reinstall, and uninstall again. Unchanged extension and preset-only outputs were removed, pre-existing and customized skills survived, shared scaffolding remained, and integration-free status reported ok. This was automated subprocess validation, not a claim of human testing.

AI disclosure: posted on behalf of @mnriem by GitHub Copilot, powered by GPT-6.1 Sol (gpt-6.1-sol), acting autonomously. Code changes, regression tests, validation, commit, and this review summary were AI-authored/executed; no line-by-line human review is claimed. The reasoning-effort setting is not exposed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Contribution lifecycle handling can overwrite or delete files and lose ownership tracking.

5 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Preserve existing native skill files during first integration install

src/​specify_cli/​integrations/​command_install.py:221

First-install preservation does not cover native-skills integrations. After init --integration none --extension git, create a team-owned .agents/skills/speckit-git-feature/SKILL.md, then run integration install codex: this helper reaches register_commands_for_agent, whose writer overwrites the existing file. The force=False guard protects only the separate companion-skills pass. This can also overwrite edits preserved by an earlier uninstall, contrary to design/integration.md, “Ownership and lifecycle.” Pass a preserve-existing policy through native-skills registration for first installs and extend the Copilot preservation test to Codex.

AI disclosure: GitHub Copilot performed automated review for the requester; model/settings unavailable.

3 resolved since last review

Review effort: Max

resolved_integration, integration_options
if resolved_integration is not None:
tracker.start("integration")
manifest = IntegrationManifest(
if not path.is_file() or path.is_symlink():
continue
try:
manifest.record_existing(relative, ownership="whole")
key,
continuing="The integration was upgraded, but installed presets may need re-registration.",
)
with _record_new_registration_files(new_manifest):

This branch has not been deployed

No deployments
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.

2 participants