Repository navigation
Conversation
… init bundle_init called the Typer-decorated bundle_install() without refresh, so refresh kept its typer.Option(False) default, a truthy OptionInfo. A second `specify bundle init <bundle>` then took the explicit-refresh path: it replaced local edits to installed workflows and accepted a changed bundle version that a plain `bundle install` refuses without --refresh. Pass refresh=False explicitly, as github#4284 did for the workflow_add call. Assisted-by: Codex CLI (model: gpt-6-astra, autonomous) Assisted-by: Claude Code (model: claude-opus-5-5, autonomous)
There was a problem hiding this comment.
🟢 Approval recommended
The focused fix has targeted regression coverage, with only a non-blocking documentation clarification remaining.
1 open finding
What changed in this PR
Prevents repeated Specify CLI bundle initialization from unintentionally refreshing installed components and overwriting local edits.
Changes:
- Passes
refresh=Falseexplicitly during bundle initialization. - Adds regression coverage for preserved edits, changed-version rejection, and explicit refresh.
- Documents repeat-init behavior and refresh alternatives.
Tests were not rerun; regression results were assessed from the supplied evidence.
| File | Description |
|---|---|
| tests/specify_cli/bundles/test_command_init.py | Tests delegation, preservation, refresh, and version rejection. |
| src/specify_cli/bundles/command_init.py | Explicitly disables implicit refresh. |
| docs/reference/bundles.md | Explains preservation and refresh options. |
🧠 Review effort: Max
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Please address Copilot feedback |
With refresh no longer implied, a repeated `bundle init` goes through the same record check as a plain `bundle install`: a changed bundle version, or a changed or removed owned component, fails until `bundle update` or `bundle install --refresh` applies it. Assisted-by: Claude Code (model: claude-opus-5-5, autonomous)
|
Addressed Copilot's docs finding in 335d29f. The Drafted on behalf of @kartsan03 by Claude Code (model: claude-opus-5-5, autonomous), which also made the docs change. |
|
Please address Copilot feedback. If not applicable, please explain why |
…ents Assisted-by: Claude Code (model: claude-opus-5-5, autonomous)
|
Addressed Copilot's second docs finding in 2ceec75. The Drafted on behalf of @kartsan03 by Claude Code (model: claude-opus-5-5, autonomous), which also made the docs change. |

Description
Running
specify bundle init <bundle>a second time refreshes the bundle's components that are already installed, even thoughbundle inithas no--refreshoption. A local edit to an installed workflow is silently replaced, and the command exits 0.bundle_initcalls the Typer-decoratedbundle_install()directly (src/specify_cli/bundles/command_init.py:51onmain) without passingrefresh. Sorefreshkeeps its parameter default,typer.Option(False, ...), which is anOptionInfoobject and truthy.install_bundlethen takes the explicit-refresh path (installer.py:119,:175). It's the same option-default pitfall #4284 fixed for theworkflow_addcall. The same truthy value also letsbundle initaccept a changed bundle version that a plainbundle installrefuses without--refresh.This PR passes
refresh=Falseexplicitly frombundle_init. Directbundle installandbundle install --refreshare unchanged.docs/reference/bundles.mdgets one paragraph: repeatingbundle initkeeps installed components as they are, andbundle update/bundle install --refreshare the ways to refresh them.Repro with the first-party
bugfixbundle, offline: init, append a line to.specify/workflows/bugfix/workflow.yml, init again.specify bundle init bundles/bugfix --offlinemain(3238fa9)0 added, 0 already present, 2 refreshed, 0 removed0 added, 2 already presentworkflow.ymlTesting
uv run specify --helpuv sync && uv run pytestNew tests in
tests/specify_cli/bundles/test_command_init.py:bundle_initdelegates tobundle_installwithrefresh=False(and doesn't call it without a bundle).CliRunnerand the realbugfixbundle: a repeatedbundle initkeeps a local edit to the installed workflow (bytes compared, CRLF included) and leaves the registry alone; a plainbundle installdoes the same, andbundle install --refreshstill restores the bundled file.bundle initwith a changed bundle version exits 1 asking for--refresh, and leaves the bundle records and the edited workflow untouched.With only
src/reverted tomain, 3 of the 7 tests in the file fail (the delegation check, the repeated-init case and the changed-version case). With the fix, all 54 tests intest_command_init.py,test_command_install.pyandtest_commands.pypass.Full suite on Linux, Python 3.13: 12093 passed, 374 skipped (
uv sync --extra test, then pytest in that venv, 20m).Ruff 0.15.0 (
ruff check src tests) passes.AI Disclosure
AI disclosure: Two agents, both autonomous, working back and forth. Codex CLI (model: gpt-6-astra, reasoning effort max, autonomous, sandboxed and offline) found this while scouting the bundle commands, wrote the reproduction, and generated the fix, tests and docs paragraph. Claude Code (model: claude-opus-5-5, autonomous) reviewed the change, reran the tests against
mainand the fix, reran the repro with the realspecifyCLI, ran the full suite and lint, and drafted this description. Commits carryAssisted-by:trailers.