feat(vulns): add close and reopen commands and --status filter
Adds close and reopen for vulns, matching detail bugs. The commands' API ships in usedetail/detail #19512, with trackerStateName from #19513.
Do not merge until those PRs have deployed. state is a new required field on Vuln, so this CLI should fail to parse vulns list and vulns show from an older backend. This is a draft for that reason. cargo xtask check fails on openapi.json until then, which is expected because it compares against production's spec.
What changed
detail vulns close <id>:--state,--dismissal-reason,--notesand--format, with the same prompts and non-interactive validation asbugs close.detail vulns reopen <id>: takes only the ID.vulns list --status: one value. Without it the API defaults topending, so closed vulns are hidden unless you ask.- Display:
listadds State and Dismissal.showalso adds Notes, State Source and State Updated, which explain a tracker dismissal with no reason. openapi.json: regenerated from a local backend's spec (165 additions, no removals). xtask is unchanged.- Docs:
docs/HELP.mdand the bundleddetail-bugsskill. bugs.rs:prompt_notesbecomespub(crate). No other bugs change.
--status takes one value where bugs list takes several, because the API takes one. Reason flags are kebab-case, like not-a-bug.
After the backend deploys
- Run
cargo xtask generate-openapiand confirm the diff is empty or expected. - Run
cargo xtask check, which should then pass. - Mark ready and merge. A version bump and release are separate.
Testing
Against the backend stack on a fork of prod, with a debug binary and an isolated config:
- Every state and reason, table and JSON output, and interactive prompts in a real pty.
- Non-interactive errors, with 0 rows written.
- Another org's vuln gets a 403 on show, close and reopen, with 0 rows written.
bugsclose, reopen, show and list unchanged.cargo fmt, clippy, check and test pass. Live-API integration tests return early without a key, so those don't all really run.
Not run: this CLI against a backend without the new API, and show on a tracker-set state name (unit test only).
š¤ Generated with Claude Code