Repository navigation
fix(workflows): remove the catalog source shown at the listed index - #4870
Merged
Merged
Conversation
`workflow catalog remove <index>` and `workflow step catalog remove <index>` take the index from `catalog list`, which is priority-ordered, but popped that index from the raw project YAML. With priorities set, remove deleted a different source; with SPECKIT_*_CATALOG_URL set, it deleted a project source the list never showed. Parse the project config with the same validation and priority sort as the list, keep each entry's original position, and remove that entry. Refuse removal while the environment override is active, before any write. Assisted-by: Codex CLI (model: gpt-6-astra, autonomous) Assisted-by: Claude Code (model: claude-opus-5-5, autonomous)
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The implementation aligns removal with listing behavior and includes comprehensive positive, negative, and regression coverage.
0 open findings
What changed in this PR
Fixes workflow and step catalog removal so indices match priority-ordered catalog listings, consistent with the bundle catalog fix in #4533.
Changes:
- Retains original YAML positions while sorting catalog entries.
- Prevents removal while environment overrides are active.
- Adds regression coverage and clarifies documentation.
| File | Description |
|---|---|
src/specify_cli/workflows/catalog/_domain.py |
Corrects workflow catalog removal. |
src/specify_cli/workflows/step/catalog/_domain.py |
Corrects step catalog removal. |
tests/test_workflows.py |
Covers ordering, validation, bounds, and overrides. |
tests/specify_cli/workflows/catalog/test_command_remove.py |
Adds workflow CLI regressions. |
tests/specify_cli/workflows/step/catalog/test_command_remove.py |
Adds step CLI regressions. |
docs/reference/workflows.md |
Documents removal semantics. |
workflows/README.md |
Clarifies listed indices and environment sources. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Collaborator
|
Thank you! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
specify workflow catalog remove <index>andspecify workflow step catalog remove <index>take the index "from 'catalog list'" (help text anddocs/reference/workflows.md). The list is sorted by priority, withSPECKIT_*_CATALOG_URLtaking over entirely when set, butremove_catalog()pops that index from the raw project YAML. So:remove 0deletes a different source than the one listed at[0], and reports success;env-override, andremove 0deletes a project source that wasn't listed at all.The bundle catalog had a similar
catalog removemismatch, fixed in #4533. This is the same kind of bug in the workflow and step catalogs.The fix makes
remove_catalog()in both catalog modules parse the project file with the same validation and stable priority sort thatlistuses, keeping each entry's original position, then remove that entry. While the environment override is active, removal is refused before anything is written. The missing-file error is unchanged, and the range check counts listed entries. A config thatlistrejects is now rejected byremovetoo, instead of having a raw row popped. The reference docs andworkflows/README.mdnow say the index is the listed one and that environment-provided sources can't be removed this way.Repro (no catalog is downloaded;
example.invalidURLs are never fetched):main(d3ab820)workflow catalog remove 0✓ Catalog source 'team' removed,reviewleft✓ Catalog source 'review' removed,teamleftworkflow step catalog remove 0✓ Step catalog source 'team' removed,reviewleft✓ Step catalog source 'review' removed,teamleftremove 0withSPECKIT_WORKFLOW_CATALOG_URLsetWith the fix, the last row prints:
Testing
uv run specify --helpuv sync && uv run pytestNew tests: parametrized over both catalogs in
tests/test_workflows.py::TestWorkflowCatalog(listed position with priority reorder, equal-priority ties, duplicate names and skipped blank-URL rows; bounds checked against listed entries; env-override refusal with unchanged bytes; blank override ignored; configs thatlistrejects), plus a priority-reorder and an env-override CLI test in eachtest_command_remove.py, using real config files.With only
src/reverted tomain, 22 tests fail, all of them new; the other 115 pass, including the new negative-index and blank-override controls. With the fix, all 137 tests in the catalog suites pass.Full suite on Linux, Python 3.13.15: 9572 passed, 265 skipped (
uv run pytest, 5m28s).uvx ruff@0.15.0 check src testspasses, and markdownlint passes on both changed Markdown files.AI Disclosure
AI disclosure: Two agents, both autonomous. Codex CLI (model: gpt-6-astra, reasoning effort xhigh, autonomous, sandboxed and offline) found the bug while auditing the catalog removal paths, wrote the reproduction, and generated the fix, tests and docs changes. Claude Code (model: claude-opus-5-5, autonomous) picked this fix from the candidates, reviewed the diff and cut it down (it dropped new error messages for user-level and built-in sources that weren't needed for this bug), reran the tests against
mainand the fix, ran the full suite and lint, and drafted this description. Commits carryAssisted-by:trailers.