Skip to content

Agentic Review: Introduce Review addon#34837

Open
yannbf wants to merge 52 commits into
nextfrom
yann/agentic-review-mcp-integration
Open

Agentic Review: Introduce Review addon#34837
yannbf wants to merge 52 commits into
nextfrom
yann/agentic-review-mcp-integration

Conversation

@yannbf
Copy link
Copy Markdown
Member

@yannbf yannbf commented May 19, 2026

What I did

This PR introduces a new @storybook/addon-review addon: an in-Storybook UI for reviewing agent-produced changes.

Flow: an ADE agent pushes a review via the MCP addon (@storybook/addon-mcp); the dev server enriches it with the current git branch, caches it, and broadcasts it over the Storybook channel; the addon's page receives it (and requests a replay on mount so late/refreshed tabs catch up) and renders it.

The review experience has two views:

  • Summary — review title and narrative, with affected stories grouped into agent-curated Collections or by Component, plus search, grouping, and expand/collapse.
  • Details — a focused full-screen story preview with previous/next navigation through the reviewed stories and a branch indicator.

Also includes a responsive CollectionGrid with lazy iframe mounting, server-side branch resolution/caching/replay for late-joining tabs, navigation + grouping utilities, stories, and unit tests.

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

Caution

This section is mandatory for all contributions. If you believe no manual test is necessary, please state so explicitly. Thanks!

  1. Select a project or run a sandbox for template, e.g. yarn task --task sandbox --start-from auto --template react-vite/default-ts
  2. Set up the MCP addon if not there already
  3. Run Storybook
  4. Open your ADE of choice, ask it to make a change e.g. "change the primary color of the button to pink"
  5. See the review URL and inspect the results

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This pull request has been released as version 0.0.0-pr-34837-sha-4d331ed6. Try it out in a new sandbox by running npx storybook@0.0.0-pr-34837-sha-4d331ed6 sandbox or in an existing project with npx storybook@0.0.0-pr-34837-sha-4d331ed6 upgrade.

More information
Published version 0.0.0-pr-34837-sha-4d331ed6
Triggered by @yannbf
Repository storybookjs/storybook
Branch yann/agentic-review-mcp-integration
Commit 4d331ed6
Datetime Tue Jun 2 12:31:00 UTC 2026 (1780403460)
Workflow run 26819809661

To request a new release of this pull request, mention the @storybookjs/core team.

core team members can create a new canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=34837

Summary by CodeRabbit

  • New Features
    • "Review changes" addon: Summary (Collections/Components) and Details views for browsing agent-produced story changes, with search, grouping, expand/collapse, and keyboard navigation.
    • Details view: story preview iframe, back/previous/next navigation, and branch indicator.
    • Collections grid with responsive layout and "Review all" behavior.
    • Server-backed replay: late-joining tabs can display the latest review and show resolved branch info.
  • Tests / Docs
    • Stories, interactive tests, and README for the addon.

Review Change Stack

New @storybook/addon-review-changes. An ADE agent pushes a review via
the MCP addon; it is broadcast over the Storybook channel; this addon's
page receives it (and requests a replay on mount for late/refreshed
tabs) and renders the raw agent state — narrative, clusters, changed
files, diff hunks, per-story metadata.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)
📝 Walkthrough

Walkthrough

This PR introduces @storybook/addon-review, a new Storybook addon that renders agent-pushed review overlays. The addon includes review-state schemas, server-side git branch enrichment, manager registration, a ReviewPage container with tabbed Summary/Details screens, a responsive CollectionGrid component, comprehensive test coverage, and full package/workspace integration.

Changes

Review Changes Addon Implementation

Layer / File(s) Summary
Review state types and addon constants
code/addons/review/src/review-state.ts, code/addons/review/src/constants.ts, code/addons/review/src/index.ts
TypeScript interfaces define ReviewState, ReviewCollection, and CollectionKind; exports expose addon identifiers, route URL, session-storage key, and EVENTS object for cross-repo communication.
Navigation URL and grouping utilities
code/addons/review/src/review-navigation.ts, code/addons/review/src/review-grouping.ts
Builders and parsers for summary/detail hrefs with validation; utilities to group stories by component prefix and format component IDs for display.
Server-side preset with git branch resolution
code/addons/review/src/node/git-branch.ts, code/addons/review/src/preset.ts, code/addons/review/src/preset.test.ts
Helper to resolve git branch via execFile; experimental_serverChannel preset enriches PUSH_REVIEW payloads with resolved branchName, caches results, and replays for late-joining tabs; tests verify enrichment, cache behavior, and event handling.
Manager addon registration and page setup
code/addons/review/src/manager.tsx, code/.storybook/main.ts, code/addons/review/manager.js, code/addons/review/preset.js
Registers manager addon with sidebar restoration logic; wires DISPLAY_REVIEW to navigate; registers experimental manager page; adds top-level re-exports and Storybook main config to include the addon and story sources.
ReviewPage container and lifecycle
code/addons/review/src/ReviewPage.ts, code/addons/review/src/ReviewPage.stories.tsx
Main container managing review state, emitting REQUEST_REVIEW, parsing location for details selection, normalizing legacy URLs, managing sidebar visibility, computing storyInfo, intercepting SPA navigation; includes three story tests covering Collections, Components tabs, and deep-linked Details view.
SummaryScreen tabbed view
code/addons/review/src/screens/SummaryScreen.tsx, code/addons/review/src/screens/SummaryScreen.stories.tsx
Tabbed screen with Collections/Components views, shared search filtering, expandable lists, expand/collapse-all controls, keyboard tab navigation; six stories test minimal, full, cascade, benchmark, and atomic change fixtures.
DetailsScreen preview and navigation
code/addons/review/src/screens/DetailsScreen.tsx, code/addons/review/src/screens/DetailsScreen.stories.tsx
Full-height view with centered iframe preview, top/bottom toolbars, back/previous/next navigation, story position counter; stories test default rendering and wrap-around navigation.
CollectionGrid responsive grid component
code/addons/review/src/components/CollectionGrid.tsx, code/addons/review/src/components/CollectionGrid.stories.tsx
Responsive grid computing columns via ResizeObserver; IntersectionObserver with preload range for lazy iframe mounting; floating info overlay with query highlighting; "Review all" overflow action; stories validate layout responsiveness and height constraints.
Interactive review prototype
code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx
Demo component managing local search state and SPA navigation; four stories exercise default flow, deep-linked detail, component grouping, and search-to-navigate workflows.
Package manifest and build config
code/addons/review/package.json, code/addons/review/build-config.ts, code/addons/review/README.md, code/addons/review/tsconfig.json, code/addons/review/vitest.config.ts, code/addons/review/project.json
Package definition with ESM exports map, build targets, README documenting MCP integration, TypeScript and Vitest configs, and Nx project configuration.
Workspace build and version integration
scripts/build/entry-configs.ts, code/core/src/common/versions.ts, code/package.json, code/core/src/manager/globals/exports.ts
Wires addon build-config into workspace buildEntries; adds @storybook/addon-review to workspace version map and root package.json dependencies; updates manager-errors export list.

CSF Type-level Test Refinement

Layer / File(s) Summary
Conditional type constraint update
code/core/src/csf/csf-factories.test.ts
Two compile-time type assertions narrow conditional checks from extends Object to extends object for tags derivation in "customize tags type" test cases.

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

Possibly related PRs


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
scripts/build/entry-configs.ts (1)

4-4: ⚡ Quick win

Maintain alphabetical ordering in imports and exports.

Both the import statement and the buildEntries property for @storybook/addon-review-changes are placed out of alphabetical order. They should appear after onboarding and before themes (or before pseudo-states if sorting @storybook/addon-* packages separately).

📝 Suggested reordering

Move the import from line 4 to after line 10 (after onboardingConfig):

 // `@ts-ignore`
 import onboardingConfig from '../../../code/addons/onboarding/build-config';
+// `@ts-ignore`
+import reviewChangesConfig from '../../../code/addons/review-changes/build-config';
 // `@ts-ignore`
 import pseudoStatesConfig from '../../../code/addons/pseudo-states/build-config';

Move the buildEntries property from line 94 to after line 97 (after addon-onboarding):

   '`@storybook/addon-onboarding`': onboardingConfig,
+  '`@storybook/addon-review-changes`': reviewChangesConfig,
   'storybook-addon-pseudo-states': pseudoStatesConfig,

Remove the current lines 4 and 94.

Also applies to: 94-94

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/build/entry-configs.ts` at line 4, The import reviewChangesConfig is
out of alphabetical order; move the import statement for reviewChangesConfig
(currently importing '../../../code/addons/review-changes/build-config') to sit
after onboardingConfig (i.e., after the onboarding import) so imports remain
alphabetized; likewise find the buildEntries array where the
`@storybook/addon-review-changes` entry is added and move that entry (the
buildEntries property for `@storybook/addon-review-changes`) to appear after the
addon-onboarding entry (or between onboarding and themes / before pseudo-states
if you sort addon-* separately) so the buildEntries list remains alphabetically
ordered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/addons/review-changes/package.json`:
- Line 3: Update the version of the `@storybook/addon-review-changes` package to
match the rest of the Storybook packages: change the "version" field in
package.json for the review-changes addon from "10.4.0-alpha.17" to
"10.5.0-alpha.0" and also update the corresponding entry in the auto-generated
versions list (look for the review-changes entry in
code/core/src/common/versions.ts) so both locations are consistent; if this
addon intentionally needs a different version, add a brief comment in
package.json (or a README) explaining the separate release requirement instead
of leaving mismatched version strings.

In `@code/addons/review-changes/src/components/ReviewChangesPage.tsx`:
- Around line 253-255: The event handler for EVENTS.APPLY_REVIEW_STATE currently
assumes the payload is a valid ReviewState and directly calls setState(next);
add a runtime guard in the useChannel callback to validate the shape (e.g.,
ensure next is an object, has a clusters array and each cluster has
sampleStoryIds array, etc.) and only call setState(next) when the guard passes;
if validation fails, ignore the payload (optionally log a warning) to prevent
downstream errors in components that access state.clusters or
cluster.sampleStoryIds. Use the existing symbols useChannel,
EVENTS.APPLY_REVIEW_STATE, setState and ReviewState to locate the handler and
implement the guard at that event boundary.

---

Nitpick comments:
In `@scripts/build/entry-configs.ts`:
- Line 4: The import reviewChangesConfig is out of alphabetical order; move the
import statement for reviewChangesConfig (currently importing
'../../../code/addons/review-changes/build-config') to sit after
onboardingConfig (i.e., after the onboarding import) so imports remain
alphabetized; likewise find the buildEntries array where the
`@storybook/addon-review-changes` entry is added and move that entry (the
buildEntries property for `@storybook/addon-review-changes`) to appear after the
addon-onboarding entry (or between onboarding and themes / before pseudo-states
if you sort addon-* separately) so the buildEntries list remains alphabetically
ordered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dd7cacb6-4f1f-41f2-85bd-dcf5d02ce4fa

📥 Commits

Reviewing files that changed from the base of the PR and between b15652a and 8454f12.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (14)
  • code/.storybook/main.ts
  • code/addons/review-changes/build-config.ts
  • code/addons/review-changes/manager.js
  • code/addons/review-changes/package.json
  • code/addons/review-changes/project.json
  • code/addons/review-changes/src/components/ReviewChangesPage.tsx
  • code/addons/review-changes/src/components/ReviewChangesView.stories.tsx
  • code/addons/review-changes/src/constants.ts
  • code/addons/review-changes/src/index.ts
  • code/addons/review-changes/src/manager.tsx
  • code/addons/review-changes/src/review-state.ts
  • code/addons/review-changes/tsconfig.json
  • code/core/src/common/versions.ts
  • scripts/build/entry-configs.ts

Comment thread code/addons/review-changes/package.json Outdated
Comment thread code/addons/review-changes/src/components/ReviewChangesPage.tsx Outdated
@yannbf yannbf added the ci:normal Run our default set of CI jobs (choose this for most PRs). label May 19, 2026
@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented May 19, 2026

Package Benchmarks

Commit: 00094e5, ran on 3 June 2026 at 12:20:19 UTC

The following packages have significant changes to their size or dependencies:

@storybook/addon-review

Before After Difference
Dependency count 0 0 0
Self size 0 B 53 KB 🚨 +53 KB 🚨
Dependency size 0 B 654 B 🚨 +654 B 🚨
Bundle Size Analyzer Link Link

storybook

Before After Difference
Dependency count 74 72 🎉 -2 🎉
Self size 20.40 MB 20.42 MB 🚨 +25 KB 🚨
Dependency size 36.65 MB 36.11 MB 🎉 -539 KB 🎉
Bundle Size Analyzer Link Link

@storybook/cli

Before After Difference
Dependency count 205 203 🎉 -2 🎉
Self size 908 KB 908 KB 0 B
Dependency size 89.13 MB 88.61 MB 🎉 -513 KB 🎉
Bundle Size Analyzer Link Link

@storybook/codemod

Before After Difference
Dependency count 198 196 🎉 -2 🎉
Self size 32 KB 32 KB 0 B
Dependency size 87.62 MB 87.10 MB 🎉 -513 KB 🎉
Bundle Size Analyzer Link Link

create-storybook

Before After Difference
Dependency count 75 73 🎉 -2 🎉
Self size 1.08 MB 1.08 MB 🎉 -66 B 🎉
Dependency size 57.05 MB 56.53 MB 🎉 -513 KB 🎉
Bundle Size Analyzer node node

ghengeveld and others added 11 commits May 21, 2026 20:51
…nused files

- Updated import path for ReviewChangesPage component.
- Deleted unused ReviewChangesDetailsScreen, ReviewChangesPage, ReviewChangesScreen, and ReviewCollectionGrid components along with their associated stories.
- Streamlined the codebase by removing obsolete files to enhance maintainability.
This reverts commit e3fcd45.
…handling and add stories

- Added location search handling to ReviewChangesPage to parse collection and story parameters.
- Introduced ReviewChangesPage stories to demonstrate various states and interactions.
- Updated CollectionGrid and SummaryScreen components for improved naming consistency and functionality.
Review Changes: Implement review changes screen based on latest designs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/addons/review-changes/src/screens/SummaryScreen.tsx`:
- Line 324: The two SearchInput instances in SummaryScreen.tsx currently rely on
placeholder text for identification; add explicit accessible names by supplying
either an aria-label (e.g., aria-label="Search stories") or connecting a
visible/visually-hidden <label> via id/for to each SearchInput component
(reference the SearchInput elements in SummaryScreen.tsx for both occurrences).
Ensure the labels are unique and descriptive for each input (e.g., "Find
stories" and any other context-specific label) so assistive technologies receive
a programmatic name.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 218101ef-b8c6-49d0-a5b9-9b3d9976a917

📥 Commits

Reviewing files that changed from the base of the PR and between 8454f12 and 67d85aa.

📒 Files selected for processing (12)
  • code/addons/review-changes/src/ReviewChangesPage.stories.tsx
  • code/addons/review-changes/src/ReviewChangesPage.tsx
  • code/addons/review-changes/src/components/CollectionGrid.stories.tsx
  • code/addons/review-changes/src/components/CollectionGrid.tsx
  • code/addons/review-changes/src/index.ts
  • code/addons/review-changes/src/manager.tsx
  • code/addons/review-changes/src/review-navigation.ts
  • code/addons/review-changes/src/review-state.ts
  • code/addons/review-changes/src/screens/DetailsScreen.stories.tsx
  • code/addons/review-changes/src/screens/DetailsScreen.tsx
  • code/addons/review-changes/src/screens/SummaryScreen.stories.tsx
  • code/addons/review-changes/src/screens/SummaryScreen.tsx
✅ Files skipped from review due to trivial changes (1)
  • code/addons/review-changes/src/review-navigation.ts

Comment thread code/addons/review-changes/src/screens/SummaryScreen.tsx Outdated
yannbf and others added 10 commits May 23, 2026 10:28
… navigation logic, and enhance URL handling for review states. Add new ReviewPage component and associated stories for improved review flow.
…tate` to `request-review`. Update related references in the codebase for consistency.
… and TabButton styled components, and update layout for improved tab functionality and accessibility.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
code/addons/review/src/preset.test.ts (1)

70-78: ⚡ Quick win

Add a regression case for unresolved-branch payload sanitization.

Please add a test where incoming PUSH_REVIEW contains branchName and resolveBranch returns undefined; expected emitted payload should omit branchName. This locks in the server-resolved contract and prevents spoofed branch display.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/addons/review/src/preset.test.ts` around lines 70 - 78, Add a new test
that sends a PUSH_REVIEW containing branchName while mocking resolveBranch to
return undefined, call experimental_serverChannel with that mock, fire
EVENTS.PUSH_REVIEW with a sampleReview that includes branchName, and assert that
the emitted payload for EVENTS.DISPLAY_REVIEW omits the branchName (i.e.,
emitted equals [{ event: EVENTS.DISPLAY_REVIEW, payload: <sampleReview without
branchName> }]); use the same helpers in the file (createMockChannel,
experimental_serverChannel, resolveBranch, sampleReview, emitted,
EVENTS.DISPLAY_REVIEW) so the test verifies server-side sanitization when
resolveBranch returns undefined.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/addons/review/src/manager.tsx`:
- Around line 22-28: When booting outside the review route the code only handles
the 'restore' marker and leaves a lingering 'keep' value; update the block that
checks path.startsWith(REVIEW_CHANGES_URL) to read const val =
sessionStorage.getItem(RESTORE_NAV_SESSION_KEY) and then: if (val === 'restore')
call api.toggleNav(true), and if (val === 'restore' || val === 'keep') call
sessionStorage.removeItem(RESTORE_NAV_SESSION_KEY) so both markers are cleared;
refer to RESTORE_NAV_SESSION_KEY, REVIEW_CHANGES_URL, path, and api.toggleNav in
manager.tsx to locate and change the logic.

In `@code/addons/review/src/node/git-branch.test.ts`:
- Around line 3-52: The tests currently mock node:child_process by hoisting
mockExecFile and calling mockImplementation directly; change to use Vitest
spy-mocking and vi.mocked typing: mock 'node:child_process' with { spy: true }
so execFile is a spy, then obtain the typed mock via vi.mocked(importedExecFile)
(or vi.mocked(require('node:child_process').execFile)) in beforeEach, reset it
there, and move per-test mockImplementation setups into the shared beforeEach or
nested beforeEach blocks for each it; keep the test assertions and the
currentGitBranch import as-is but reference the execFile mock via vi.mocked
instead of the hoisted mockExecFile symbol.

In `@code/addons/review/src/preset.ts`:
- Around line 21-27: The function enrichWithBranch must prevent agent-supplied
branchName from persisting when local resolution fails: first create a sanitized
copy of the incoming ReviewState with any existing branchName removed (e.g.,
clone payload and delete branchName) then call resolveBranch(process.cwd()); if
a branchName is returned, return a new ReviewState that spreads the sanitized
payload and sets branchName, otherwise return the sanitized payload; update the
function enrichWithBranch and reference ReviewState and resolveBranch
accordingly.

---

Nitpick comments:
In `@code/addons/review/src/preset.test.ts`:
- Around line 70-78: Add a new test that sends a PUSH_REVIEW containing
branchName while mocking resolveBranch to return undefined, call
experimental_serverChannel with that mock, fire EVENTS.PUSH_REVIEW with a
sampleReview that includes branchName, and assert that the emitted payload for
EVENTS.DISPLAY_REVIEW omits the branchName (i.e., emitted equals [{ event:
EVENTS.DISPLAY_REVIEW, payload: <sampleReview without branchName> }]); use the
same helpers in the file (createMockChannel, experimental_serverChannel,
resolveBranch, sampleReview, emitted, EVENTS.DISPLAY_REVIEW) so the test
verifies server-side sanitization when resolveBranch returns undefined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a5aed8d5-a254-4ef1-b764-35a2d601ed0d

📥 Commits

Reviewing files that changed from the base of the PR and between 5a0bf2b and 9c4ac02.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (32)
  • code/.storybook/main.ts
  • code/addons/review/README.md
  • code/addons/review/build-config.ts
  • code/addons/review/manager.js
  • code/addons/review/package.json
  • code/addons/review/preset.js
  • code/addons/review/project.json
  • code/addons/review/src/ReviewPage.stories.tsx
  • code/addons/review/src/ReviewPage.ts
  • code/addons/review/src/components/CollectionGrid.stories.tsx
  • code/addons/review/src/components/CollectionGrid.tsx
  • code/addons/review/src/constants.ts
  • code/addons/review/src/index.ts
  • code/addons/review/src/manager.tsx
  • code/addons/review/src/node/git-branch.test.ts
  • code/addons/review/src/node/git-branch.ts
  • code/addons/review/src/preset.test.ts
  • code/addons/review/src/preset.ts
  • code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx
  • code/addons/review/src/review-grouping.ts
  • code/addons/review/src/review-navigation.ts
  • code/addons/review/src/review-state.ts
  • code/addons/review/src/screens/DetailsScreen.stories.tsx
  • code/addons/review/src/screens/DetailsScreen.tsx
  • code/addons/review/src/screens/SummaryScreen.stories.tsx
  • code/addons/review/src/screens/SummaryScreen.tsx
  • code/addons/review/tsconfig.json
  • code/addons/review/vitest.config.ts
  • code/core/src/common/versions.ts
  • code/core/src/manager/globals/exports.ts
  • code/package.json
  • scripts/build/entry-configs.ts
💤 Files with no reviewable changes (4)
  • code/addons/review/tsconfig.json
  • code/addons/review/manager.js
  • code/addons/review/src/screens/SummaryScreen.stories.tsx
  • code/addons/review/src/components/CollectionGrid.stories.tsx
✅ Files skipped from review due to trivial changes (10)
  • code/addons/review/preset.js
  • code/addons/review/project.json
  • code/addons/review/README.md
  • code/addons/review/src/constants.ts
  • code/core/src/manager/globals/exports.ts
  • scripts/build/entry-configs.ts
  • code/addons/review/src/index.ts
  • code/addons/review/src/review-state.ts
  • code/addons/review/vitest.config.ts
  • code/core/src/common/versions.ts

Comment thread code/addons/review/src/manager.tsx Outdated
Comment thread code/addons/review/src/node/git-branch.test.ts Outdated
Comment thread code/addons/review/src/preset.ts
@ghengeveld ghengeveld changed the title UI: Base Review pages structure Addon Review: Introduce Review addon May 28, 2026
@ghengeveld ghengeveld changed the title Addon Review: Introduce Review addon Agentic Review: Introduce Review addon May 28, 2026
@ghengeveld ghengeveld self-assigned this May 28, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

ghengeveld and others added 11 commits May 28, 2026 16:21
- Introduced `ReviewViewState` context for managing review state across components.
- Implemented `useReviewViewStore` hook to handle expanded collections and components.
- Integrated `StandaloneReviewView` for consistent state management in review screens.
- Added `useScrollRestore` hook to manage scroll position restoration during component updates.
- Updated `ReviewPage`, `SummaryScreen`, and `CollectionGrid` to utilize the new state management and scroll restoration features.
- Added transform effects to the CollectionGrid for improved hover and focus visibility.
- Updated SearchBox component to handle focus and blur events, revealing thumbnail info bars during search.
- Integrated state management for search focus in SummaryScreen to enhance user experience while filtering.
The detail-route prefix encodes the detail kind, not the active tab.
Passing `activeTab` into buildReviewChangesDetailHref made the inactive
panel's links drop the collection index, breaking navigation. Hardcode
the prefix to the link's own kind ('collections' / 'components') so both
panels always produce valid hrefs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ghengeveld ghengeveld added the qa:needed Pull Requests that will need manual QA prior to release. label Jun 2, 2026
ghengeveld and others added 3 commits June 2, 2026 23:56
The detail header "Guide Page / Default" renders inside the aria-hidden
route-transition layer and "Guide Page" also appears as collection-cell
labels, so findByText('Guide Page') matched multiple elements. Assert on
the detail-only "2/3" nav button and branch footer instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix failing Minimal story: drop stale branchName assertion (the branch
  is only rendered in the details footer, not the summary)
- preset: strip agent-supplied branchName before server-side enrichment so
  an unresolvable local branch can't leave a spoofed branch (+ regression test)
- manager: clear both 'restore' and 'keep' nav markers on non-review loads
- git-branch.test: use vi.mocked() + beforeEach mock setup
- Rename reviewChangesConfig import to reviewConfig
- Set addon displayName to "Review"; refresh README to match the shipped UI
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
code/addons/review/src/screens/DetailsScreen.tsx (1)

164-166: 💤 Low value

Consider adding ariaLabel={false} to the position counter button.

Per the codebase convention, buttons with visible text content that serves as the accessible name should explicitly set ariaLabel={false} to indicate this is intentional rather than an oversight.

Suggested fix
-        <Button variant="ghost" size="small" readOnly>
+        <Button variant="ghost" size="small" readOnly ariaLabel={false}>
           {storyIndex + 1}/{totalStories}
         </Button>

Based on learnings: "set ariaLabel=false when the button's children already serve as the accessible name."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/addons/review/src/screens/DetailsScreen.tsx` around lines 164 - 166, The
position counter Button in DetailsScreen (rendering "{storyIndex +
1}/{totalStories}") should explicitly opt out of automatic aria labeling; add
the prop ariaLabel={false} to the Button component instance so its visible
children are used as the accessible name (update the Button element that
currently shows "{storyIndex + 1}/{totalStories}" to include ariaLabel={false}).
code/addons/review/src/screens/SummaryScreen.tsx (2)

614-628: 💤 Low value

groupStoriesByComponent is called multiple times per render.

When state is truthy, groupStoriesByComponent(state.collections) is called in the effect (line 624) and again in the render body (line 636). Consider memoizing the result to avoid redundant computation on every render.

Also applies to: 636-636

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/addons/review/src/screens/SummaryScreen.tsx` around lines 614 - 628, The
effect and render both call groupStoriesByComponent(state.collections), causing
duplicate work; memoize the grouping once (e.g., create const grouped =
useMemo(() => groupStoriesByComponent(state?.collections || []),
[state?.collections]) and then replace calls in the useEffect and the render
with grouped, and update setExpandedComponents to use new Set(grouped.map(g =>
g.componentId)); this keeps useEffect, setExpandedComponents,
groupStoriesByComponent, and state.collections intact while avoiding repeated
computation.

224-232: ⚡ Quick win

Hardcoded color values bypass theming.

CollectionLabel, CollectionRationale, and CollectionCount use hardcoded hex colors (#2E3338, #5C6570) instead of theme tokens. These won't adapt to dark mode or custom themes.

Suggested fix using theme tokens
 const CollectionLabel = styled.strong({
   minWidth: 0,
   overflow: 'hidden',
   textOverflow: 'ellipsis',
   whiteSpace: 'nowrap',
   fontWeight: 700,
   lineHeight: '20px',
-  color: '`#2E3338`',
+  color: theme.color.defaultText,
 });

Similarly for CollectionRationale and CollectionCount, consider using theme.textMutedColor instead of #5C6570.

Also applies to: 261-264, 266-276

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/addons/review/src/screens/SummaryScreen.tsx` around lines 224 - 232,
CollectionLabel, CollectionRationale, and CollectionCount use hardcoded hex
colors which bypass theming and won't adapt to dark/custom themes; update their
styled definitions to pull colors from the theme object (e.g., use
theme.textColor or theme.textMutedColor) instead of '`#2E3338`' and '`#5C6570`',
ensuring the styled callback receives the theme parameter (or uses the
theme-aware styled utility already in project) so colors respond to dark
mode/custom themes; modify CollectionLabel to use the primary text token
(theme.textColor) and CollectionRationale/CollectionCount to use the muted text
token (theme.textMutedColor).
code/addons/review/src/preset.test.ts (1)

61-152: ⚡ Quick win

Move resolveBranch mock behavior setup into beforeEach (or nested describe beforeEach).

vi.fn().mockResolvedValue(...) is repeatedly configured inside it(...) blocks; this breaks the repo’s Vitest mock setup convention and makes scenarios harder to scan.

As per coding guidelines: "Implement mock behaviors in beforeEach blocks in Vitest tests" and "Avoid inline mock implementations within test cases in Vitest tests."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@code/addons/review/src/preset.test.ts` around lines 61 - 152, The test suite
repeatedly creates resolveBranch mocks inside individual it blocks; move the
resolveBranch vi.fn().mockResolvedValue(...) setup into a beforeEach (or a
nested describe+beforeEach) so all tests reuse the mocked behavior and follow
Vitest conventions—create the resolveBranch variable at top-level of the test
file, assign it in beforeEach, and then pass it into
experimental_serverChannel(...) in each test; for cases requiring different
return values (e.g., resolved string vs undefined) override the
resolveBranch.mockResolvedValue(...) inside the specific test or a nested
describe's beforeEach to keep per-scenario setup organized while avoiding inline
mock creation inside it blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@code/addons/review/src/review-navigation.ts`:
- Around line 25-27: The early-return when input is only whitespace currently
returns the original untrimmed value (return value;) which preserves
spaces/URL-encoded `%20`; change that to return the trimmed string instead
(return trimmed;) so whitespace-only IDs normalize to an empty string. Update
the conditional around trimmed in the function handling story IDs (the block
using the variables trimmed and value) to return trimmed rather than value.
- Line 106: Replace direct calls to decodeURIComponent in the detail parsing
with the safe decoder helper (e.g., safeDecodeURIComponent) to avoid runtime
exceptions from malformed URIs: change the expression that sets storyId
(currently using decodeURIComponent(storySegment) passed to
normalizeReviewStoryId) to use the safe decoder and do the same for the other
occurrence at the parse location around line 121; ensure you import or reference
the existing safe decoder function and preserve the conditional fallback to
undefined.

---

Nitpick comments:
In `@code/addons/review/src/preset.test.ts`:
- Around line 61-152: The test suite repeatedly creates resolveBranch mocks
inside individual it blocks; move the resolveBranch
vi.fn().mockResolvedValue(...) setup into a beforeEach (or a nested
describe+beforeEach) so all tests reuse the mocked behavior and follow Vitest
conventions—create the resolveBranch variable at top-level of the test file,
assign it in beforeEach, and then pass it into experimental_serverChannel(...)
in each test; for cases requiring different return values (e.g., resolved string
vs undefined) override the resolveBranch.mockResolvedValue(...) inside the
specific test or a nested describe's beforeEach to keep per-scenario setup
organized while avoiding inline mock creation inside it blocks.

In `@code/addons/review/src/screens/DetailsScreen.tsx`:
- Around line 164-166: The position counter Button in DetailsScreen (rendering
"{storyIndex + 1}/{totalStories}") should explicitly opt out of automatic aria
labeling; add the prop ariaLabel={false} to the Button component instance so its
visible children are used as the accessible name (update the Button element that
currently shows "{storyIndex + 1}/{totalStories}" to include ariaLabel={false}).

In `@code/addons/review/src/screens/SummaryScreen.tsx`:
- Around line 614-628: The effect and render both call
groupStoriesByComponent(state.collections), causing duplicate work; memoize the
grouping once (e.g., create const grouped = useMemo(() =>
groupStoriesByComponent(state?.collections || []), [state?.collections]) and
then replace calls in the useEffect and the render with grouped, and update
setExpandedComponents to use new Set(grouped.map(g => g.componentId)); this
keeps useEffect, setExpandedComponents, groupStoriesByComponent, and
state.collections intact while avoiding repeated computation.
- Around line 224-232: CollectionLabel, CollectionRationale, and CollectionCount
use hardcoded hex colors which bypass theming and won't adapt to dark/custom
themes; update their styled definitions to pull colors from the theme object
(e.g., use theme.textColor or theme.textMutedColor) instead of '`#2E3338`' and
'`#5C6570`', ensuring the styled callback receives the theme parameter (or uses
the theme-aware styled utility already in project) so colors respond to dark
mode/custom themes; modify CollectionLabel to use the primary text token
(theme.textColor) and CollectionRationale/CollectionCount to use the muted text
token (theme.textMutedColor).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 617854aa-461e-46ce-ae01-52b1a0121245

📥 Commits

Reviewing files that changed from the base of the PR and between 9c4ac02 and 1a1558d.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (20)
  • code/.storybook/main.ts
  • code/addons/review/README.md
  • code/addons/review/package.json
  • code/addons/review/src/ReviewPage.stories.tsx
  • code/addons/review/src/ReviewPage.ts
  • code/addons/review/src/components/CollectionGrid.tsx
  • code/addons/review/src/manager.tsx
  • code/addons/review/src/node/git-branch.test.ts
  • code/addons/review/src/preset.test.ts
  • code/addons/review/src/preset.ts
  • code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx
  • code/addons/review/src/review-navigation.ts
  • code/addons/review/src/review-state.ts
  • code/addons/review/src/screens/DetailsScreen.stories.tsx
  • code/addons/review/src/screens/DetailsScreen.tsx
  • code/addons/review/src/screens/SummaryScreen.stories.tsx
  • code/addons/review/src/screens/SummaryScreen.tsx
  • code/core/src/common/versions.ts
  • code/package.json
  • scripts/build/entry-configs.ts
✅ Files skipped from review due to trivial changes (2)
  • code/core/src/common/versions.ts
  • code/addons/review/README.md
🚧 Files skipped from review as they are similar to previous changes (12)
  • scripts/build/entry-configs.ts
  • code/addons/review/src/review-state.ts
  • code/package.json
  • code/addons/review/src/screens/DetailsScreen.stories.tsx
  • code/.storybook/main.ts
  • code/addons/review/src/preset.ts
  • code/addons/review/src/manager.tsx
  • code/addons/review/package.json
  • code/addons/review/src/components/CollectionGrid.tsx
  • code/addons/review/src/ReviewPage.stories.tsx
  • code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx
  • code/addons/review/src/ReviewPage.ts

Comment thread code/addons/review/src/review-navigation.ts
Comment thread code/addons/review/src/review-navigation.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new @storybook/addon-review addon that surfaces an agent-pushed “review changes” experience inside the Storybook manager. It adds a dedicated Review page (summary + detail views), server-side channel handling to cache/enrich the review payload, and supporting UI components/stories/tests, plus wires the addon into the repo build and local Storybook setup.

Changes:

  • Add new @storybook/addon-review package (manager page UI, navigation helpers, server preset, git-branch enrichment, and tests).
  • Wire the addon into build entry configs, workspace deps, and the local code/ Storybook config.
  • Add Storybook stories/interactive tests for the new UI components and screens.

Reviewed changes

Copilot reviewed 32 out of 33 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
yarn.lock Adds workspace lock entries for the new addon package.
scripts/build/entry-configs.ts Registers @storybook/addon-review build entry for packaging.
code/package.json Adds @storybook/addon-review to code/ workspace dependencies.
code/core/src/csf/csf-factories.test.ts Updates type-level tests (Objectobject).
code/core/src/common/versions.ts Updates generated versions map to include the new addon.
code/addons/review/vitest.config.ts Adds Vitest config for the new addon package.
code/addons/review/tsconfig.json Adds TS config for the new addon package.
code/addons/review/src/screens/SummaryScreen.tsx Implements the review summary UI (tabs, search, grouping, expand/collapse).
code/addons/review/src/screens/SummaryScreen.stories.tsx Adds stories + play tests for Summary screen states.
code/addons/review/src/screens/DetailsScreen.tsx Implements the review detail UI with story iframe + prev/next navigation.
code/addons/review/src/screens/DetailsScreen.stories.tsx Adds stories + play tests for Details screen behavior.
code/addons/review/src/ReviewPage.ts Adds manager-page router integration + channel wiring to render summary/details.
code/addons/review/src/ReviewPage.stories.tsx Adds stories + play tests for ReviewPage routing and channel interactions.
code/addons/review/src/review-state.ts Defines the review payload shape used by the UI/preset.
code/addons/review/src/review-navigation.ts Adds URL building + parsing helpers for review summary/detail routes.
code/addons/review/src/review-grouping.ts Adds grouping helper for component-based clustering of stories.
code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx Prototype story to exercise end-to-end navigation in preview.
code/addons/review/src/preset.ts Adds serverChannel preset to enrich/cache/broadcast review payloads.
code/addons/review/src/preset.test.ts Adds unit tests for serverChannel caching/enrichment behavior.
code/addons/review/src/node/git-branch.ts Implements best-effort git-branch resolution.
code/addons/review/src/node/git-branch.test.ts Adds unit tests for git-branch resolution behavior.
code/addons/review/src/manager.tsx Registers the Review page + auto-navigation behavior on review display.
code/addons/review/src/index.ts Exposes addon constants + types.
code/addons/review/src/constants.ts Defines addon IDs, route, session keys, and channel event names.
code/addons/review/src/components/CollectionGrid.tsx Implements the story thumbnail grid with lazy iframe mounting and “Review all”.
code/addons/review/src/components/CollectionGrid.stories.tsx Adds stories + play tests for grid layout behavior.
code/addons/review/README.md Adds package README describing flow + channel contract.
code/addons/review/project.json Adds Nx project definition for the addon package.
code/addons/review/preset.js Adds ESM export shim for the built preset.
code/addons/review/package.json Adds new package manifest/exports metadata for publishing/build.
code/addons/review/manager.js Adds ESM export shim for the built manager entry.
code/addons/review/build-config.ts Defines build entries for browser/node outputs.
code/.storybook/main.ts Adds review addon stories directory + enables the addon in local Storybook.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread code/addons/review/src/ReviewPage.ts
Comment thread code/addons/review/src/prototype/ReviewFlowDemo.stories.tsx
Comment thread code/addons/review/src/review-navigation.ts
Comment thread code/addons/review/src/review-navigation.ts
Comment thread code/addons/review/src/screens/SummaryScreen.tsx Outdated
Comment thread code/addons/review/src/components/CollectionGrid.tsx
Comment thread code/addons/review/src/components/CollectionGrid.tsx Outdated
Comment thread code/addons/review/src/components/CollectionGrid.tsx Outdated
Comment thread code/addons/review/src/screens/SummaryScreen.tsx
Comment thread code/addons/review/src/screens/SummaryScreen.tsx
- review-navigation: trim whitespace-only story ids, use safe URI
  decoding at both detail-route sites, and reject trailing path segments
  on the collections route
- ReviewPage / ReviewFlowDemo: guard non-Element click targets before
  calling closest('a')
- SummaryScreen: use theme tokens for text colors and make the
  collection/component header a real <button> with aria-expanded
- CollectionGrid: source the grid min width from GRID_MIN_CELL_WIDTH,
  use theme tokens for the focus ring and info-bar colors, make the
  info-bar background theme-aware, and drop its top border
Revert the summary header to a non-semantic clickable row (a pointer
affordance only) and move the accessible toggle back to the chevron
<Button>, which carries the aria-label and now aria-expanded state for
assistive tech. This also restores the chevron's column alignment under
the toolbar's expand/collapse-all button without the manual margin hack.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:normal Run our default set of CI jobs (choose this for most PRs). feature request qa:needed Pull Requests that will need manual QA prior to release. ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants