feat(cli): --selector flag scoping lint to subtree - #127
Conversation
Adds the `--selector` building block: a `filter_snapshot` that maps a `PlumbSnapshot` through a `scraper::Selector` round-trip and returns only the matched subtrees. Lives in `plumb-cli` to keep CSS-selector parsing out of the deterministic core layer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the `--selector <CSS_SELECTOR>` flag to `plumb lint`. When set, each viewport's snapshot is filtered through `selector::filter_snapshot` between collection and rule dispatch, so rules see exactly the subtree the user asked to lint. Invalid selectors and zero-match selectors both surface as exit code 2 (CLI / infrastructure failure, PRD §13.3). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four end-to-end cases against `plumb-fake://hello`: matching `body` keeps the canned `spacing/grid-conformance` warning (exit 3); matching only `head` drops it (exit 0); an unparseable selector exits 2 with `invalid --selector` on stderr; a parseable selector that matches nothing exits 2 with `matched no elements` on stderr. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7def654 to
f095bd7
Compare
|
I now have everything I need. Here is the review: PR Review:
|
Summary
Closes #32. Adds
--selector <css-selector>toplumb lint, scoping the run to elements matching the selector and their descendants. Filtering happens between snapshot collection and rule dispatch, so rules see exactly the subtree the user asked for.plumb lint. Optional, single value. When omitted, behavior is unchanged.crates/plumb-cli/src/commands/selector.rsround-trips snapshot → tagged HTML →scraper::Selectormatcher → snapshot. Match-and-descendants kept;parent/childrenreferences rewritten consistently. Sorted-deduped match set +BTreeSetfor the kept set keep output byte-stable.scraperadded toplumb-clionly (workspace layer rule). Built withdefault-features = false+errors+deterministic.invalid --selector \`:; zero matches →--selector `` matched no elements in the snapshot`.Test plan
cargo nextest run -p plumb-cli— 12 unit tests inselector.rs+ 4 new CLI integration tests, all green.cargo clippy --workspace --all-targets --all-features -- -D warnings— clean.cargo fmt --all -- --check— clean.just determinism-check— three runs byte-identical.just validate— all gates pass.Acceptance criteria
🤖 Generated with Claude Code