feat(init): support extension install during initialization#2180
feat(init): support extension install during initialization#2180officialasishkumar wants to merge 2 commits intogithub:mainfrom
Conversation
Add repeatable --extension support to specify init for bundled extension IDs, local extension directories, and archive URLs. Persist requested extensions in init options and install them before the default git-extension auto-install so explicit git opt-in does not double-install. Warn when legacy --ai and --no-git flags are used, and show a visible notice when the git extension is still auto-enabled by default ahead of the v1.0.0 opt-in change. Update README init option docs and add CLI regression coverage for init-time extension installation and deprecation messaging.
There was a problem hiding this comment.
Pull request overview
Adds support for installing extensions during specify init, including a transition path away from legacy init flags and toward explicit extension opt-in.
Changes:
- Introduces repeatable
specify init --extension <value>for bundled IDs, local extension directories, and archive URLs, and persists selected extensions in.specify/init-options.json. - Ensures init-time extension installs occur before the default git-extension auto-install, and adds user-visible notices/deprecation warnings (
--ai,--no-git). - Expands CLI integration tests and updates README init documentation/examples.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Adds init-time extension installation flow (name/path/URL), persistence of init options, and deprecation/notice messaging. |
tests/integrations/test_cli.py |
Adds integration tests covering local extension install, repeatable --extension, explicit --extension git with --no-git, and new warnings/notices. |
README.md |
Updates init option docs to include --extension and deprecations; adjusts headings and examples. |
Comments suppressed due to low confidence (1)
README.md:424
- The examples section mixes the new recommended
--integrationflag with several--aiexamples (e.g. qodercli/windsurf/kiro-cli/etc.), even though--aiis now documented as deprecated above. To avoid encouraging deprecated usage, update these remaining examples to use--integration <key>(or explicitly label--aiexamples as legacy/deprecated).
# Initialize with Cursor support
specify init my-project --integration cursor-agent
# Initialize with Qoder support
specify init my-project --ai qodercli
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Adds init-time extension installation support to specify init, including persistence of requested extensions and updated user-facing messaging around upcoming deprecations/default behavior changes.
Changes:
- Added repeatable
specify init --extension ...support (bundled IDs, local extension dirs, and archive URLs) and persisted selections in.specify/init-options.json. - Installed requested extensions during init ahead of default git-extension auto-install, plus added deprecation warnings for
--aiand--no-gitand a post-init notice about the git extension default changing in v1.0.0. - Updated CLI integration tests and README documentation to cover the new init/extension workflow.
Show a summary per file
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Implements init-time extension install flow, URL/archive handling, deprecation warnings, and git-default notice. |
tests/integrations/test_cli.py |
Adds CLI/integration tests for --extension (local dirs, repeatable values, explicit git, TAR safety, bounded URL downloads) and deprecation output assertions. |
README.md |
Documents --integration as primary, adds --extension flag docs/examples, and adjusts related init documentation. |
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)
README.md:424
- In the Examples section, most agent examples still use
--ai ...even though the README now introduces--integrationas the recommended flag and--aias a deprecated alias. Consider switching these examples to--integrationto align with the new guidance (keeping one--aiexample only if you want to explicitly demonstrate the deprecated alias).
# Initialize with Cursor support
specify init my-project --integration cursor-agent
# Initialize with Qoder support
specify init my-project --ai qodercli
- Files reviewed: 3/3 changed files
- Comments generated: 4
| specify init my-project --integration claude # Claude installs skills by default | ||
| specify init --here --integration gemini | ||
| specify init my-project --integration generic --integration-options="--commands-dir .myagent/commands/" # Unsupported agent | ||
| specify init my-project --offline # Use bundled assets (no network access) |
There was a problem hiding this comment.
The init command examples still include --offline, but --offline is now marked as deprecated (no-op) and is hidden. This example is misleading; consider removing it or updating the comment to clarify it’s deprecated/no-op (or replacing with a network-free example that reflects current default behavior).
| specify init my-project --offline # Use bundled assets (no network access) | |
| specify init my-project --force # Reinitialize without confirmation prompts |
| console.print("[yellow]Warning:[/yellow] Installing extension from external URL.") | ||
| console.print("Only install extensions from sources you trust.") | ||
| console.print(f"Downloading from {source_url}...") | ||
|
|
There was a problem hiding this comment.
The URL installer prints the full download URL to the console. If users pass pre-signed URLs or URLs containing credentials/tokens in the query string, this can leak secrets into terminal logs/CI artifacts. Consider redacting the query/credentials portion (e.g., print scheme/host/path only) or omitting the URL from output.
| | [Windsurf](https://windsurf.com/) | ✅ | | | ||
| | [Junie](https://junie.jetbrains.com/) | ✅ | | | ||
| | [Antigravity (agy)](https://antigravity.google/) | ✅ | Requires `--ai-skills` | | ||
| | [Trae](https://www.trae.ai/) | ✅ | | | ||
| | Generic | ✅ | Bring your own agent — use `--ai generic --ai-commands-dir <path>` for unsupported agents | | ||
|
|
There was a problem hiding this comment.
The Supported AI Agents table still says Antigravity "Requires --ai-skills" and Generic suggests --ai generic --ai-commands-dir ..., but this section now positions --integration as the primary path and --ai* as deprecated aliases. Updating these notes to the --integration equivalents (and Antigravity’s default skills behavior) would prevent conflicting guidance.
This issue also appears on line 419 of the same file.
See below for a potential fix:
| [Antigravity (agy)](https://antigravity.google/) | ✅ | Uses skills by default |
| [Trae](https://www.trae.ai/) | ✅ | |
| Generic | ✅ | Bring your own agent — use `--integration generic --commands-dir <path>` for unsupported agents |
| | `--skip-tls` | Flag | Skip SSL/TLS verification (not recommended) | | ||
| | `--debug` | Flag | Enable detailed debug output for troubleshooting | | ||
| | `--github-token` | Option | GitHub token for API requests (or set GH_TOKEN/GITHUB_TOKEN env variable) | |
There was a problem hiding this comment.
The init options table describes --skip-tls, --debug, and --github-token as active behaviors, but in the CLI they are marked as deprecated no-ops and hidden. The README should match current behavior (either remove these options from the table or mark them as deprecated/no-op).
| | `--skip-tls` | Flag | Skip SSL/TLS verification (not recommended) | | |
| | `--debug` | Flag | Enable detailed debug output for troubleshooting | | |
| | `--github-token` | Option | GitHub token for API requests (or set GH_TOKEN/GITHUB_TOKEN env variable) | | |
| | `--skip-tls` | Flag | Deprecated no-op retained for compatibility; SSL/TLS verification behavior is unaffected | | |
| | `--debug` | Flag | Deprecated no-op retained for compatibility; does not enable additional debug output | | |
| | `--github-token` | Option | Deprecated no-op retained for compatibility; does not affect initialization behavior | |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback. If not applicable, please explain why
Description
Closes #2165
Closes #2166
Closes #2167
Closes #2169
Adds the init-time extension transition path:
specify init --extension <value>support for bundled extension IDs, local extension directories, and extension archive URLs..specify/init-options.jsonand installs them before the default git-extension auto-install, so explicit--extension gitdoes not double-install.--aiand--no-gitwhile preserving current behavior.--extension gitorspecify extension add git.Testing
.venv/bin/specify --help(uvis not installed in this environment).venv/bin/python -m pytest -q--extension git, and default git auto-install)Additional checks:
.venv/bin/ruff check src/npx --yes markdownlint-cli2 README.mdgit diff --checkAI Disclosure
I used AI assistance for codebase analysis, implementation support, test updates, and PR drafting. I reviewed the resulting changes and validated them locally with the commands listed above.