PPLT-5844: add IntelliStory storybook affected-story filtering#2339
PPLT-5844: add IntelliStory storybook affected-story filtering#2339RaghavsBrowserStack wants to merge 18 commits into
Conversation
…iltering Introduces IntelliStory: given a Storybook build, it diffs against a baseline (explicit or API-predicted) and filters the snapshot set down to the stories a change actually affects, bailing to a full run whenever it can't reason about the change. - cli-command: intelliStory.js (applyIntelliStory, IntelliStoryBailError), lockfileDiff.js and graphTrace.js, exported via the ./intelliStory subpath; adds glob-to-regexp, stream-json and optional snyk-nodejs-lockfile-parser. - client: getStatus() accepts the intelli_story_graph job type, plus getIntelliStorySnapshotNameToCommit() and generateIntelliStoryGraph() hitting the /intelli_story endpoints. Binds createRequire to cjsRequire (not `require`) in intelliStory.js and lockfileDiff.js so the CommonJS-transpiled packaged binary doesn't crash with "_require is not a function", and adds noRequireBinding.test.js as a static regression guard (with the matching .semgrepignore rationale).
| // applies, without exporting the module-private helpers it delegates to. | ||
| function embeddedJson(html, name) { | ||
| // test-only helper; name is a hardcoded literal ('vertices'/'edges') from the test, not external input (reviewed, approved by security) | ||
| let match = html.match(new RegExp(`const ${name} = (.*);`)); // nosemgrep |
…trim comments - intelliStory.js: read the enriched stats file with a single JSON.parse(fs.readFileSync(...)) instead of streaming it with stream-json. The stats payload is only a few MB, so in-memory parsing is simpler and removes the stream-json dependency (and, with it, the last createRequire binding in this file — the packaged-binary footgun now only exists in lockfileDiff.js for the optional snyk parser). - Remove stream-json from cli-command dependencies and the lockfile. - Strip explanatory comments introduced with the feature across the IntelliStory source, tests and trace template. Coverage directives (istanbul ignore), semgrep suppressions (nosemgrep) and the cjsRequire / loadSnyk rationale in lockfileDiff.js are kept — removing them would break the 100% coverage gate and the semgrep scan.
Add tests for the graceful-bail paths added in "apply suggested fixed": - malformed stats-file JSON (validateAndReadStats) - unreadable current lockfile (getAffectedPackages) - unreadable package.json (getAffectedPackages) These run on Node 14 (they bail before the Node>=18 snyk path), fixing the lines/statements coverage-threshold failure on the Node 14 test job. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GLOB_CHARS only detected * and ? so brace ({a,b}) and bracket ([abc])
patterns fell through to exact-match, silently disabling the intended
glob semantics for these documented config options.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude Code PR ReviewPR: #2339 • Head: 001c036 • Reviewers: stack:code-reviewer SummaryAdds IntelliStory — an affected-story graph feature for Review Table
Findings
Verdict: PASS |
What
Adds IntelliStory: for a Storybook build, it diffs against a baseline (explicit or API-predicted) and filters the snapshot set down to only the stories a change actually affects, bailing to a full snapshot run whenever it can't safely reason about the change.
This restores the functionality previously reverted in #2310, under the IntelliStory name.
cli-command
src/intelliStory.js—applyIntelliStory()andIntelliStoryBailError, exported via the new./intelliStorysubpath.src/lockfileDiff.js,src/graphTrace.js(+graphTraceTemplate.html).glob-to-regexp,stream-json, and optionalsnyk-nodejs-lockfile-parserdependencies.client
getStatus()accepts theintelli_story_graphjob type (sync response carries the graph payload).getIntelliStorySnapshotNameToCommit()andgenerateIntelliStoryGraph()hit the/intelli_storyendpoints.Binary-crash fix (folds in #2306)
intelliStory.jsandlockfileDiff.jsbindcreateRequiretocjsRequire(notrequire). When transpiled to CommonJS for the packaged binary, naming itrequirecollides with Babel's preset-env + transform-import-meta and crashes on startup withTypeError: _require is not a function. A new static regression guard,test/noRequireBinding.test.js, scans allpackages/*/srcfor the footgun (with a matching.semgrepignorerationale).Testing
proxy.test.jsfailures are unrelated — a Node 22Invalid URLmessage-format difference in files this PR does not touch.)yarn buildcompiles cleanly;dist/intelliStory.jsemitscjsRequire.Follow-up
The external
@percy/storybookconsumer will need the matching@percy/cli-command/intelliStory/applyIntelliStoryupdate.