Skip to content

Guided Buying: assistant panel trigger, staged reveal, and panel typography (Fusion demo) - #1153

Draft
petervachon wants to merge 76 commits into
mainfrom
FusionDemo
Draft

petervachon wants to merge 76 commits into
mainfrom
FusionDemo

Conversation

@petervachon

Copy link
Copy Markdown
Collaborator

Draft, for the Fusion demo. Cut from PR #1066's head, so it carries that branch's commits as
well as this one. Only the final commit is new work.

What changed

The choose phase assistant panel was only reachable from an "Ask AI" control below the fold,
arrived fully populated and then went quiet, and was set too tight to scan.

  • Claim level trigger on the headline's reason clause, opening the panel and moving focus
    into it. Reusable, and the clause comes from the recommendation data.
  • One shot attention pass over the trigger on arrival at the phase.
  • Staged reveal: findings arrive one at a time, each icon resolving after its own label and
    detail, chips last, with the results card a finding concerns highlighted as it lands.
  • Structured answer state: a labelled row set per product, a derived summary, and actions
    dispatched through the existing cart selection.
  • Typography and rhythm: regular weight lede at looser leading, emphasis moved to the
    finding label, fourfold space between findings, two hairline rules segmenting narration,
    evidence and next move.
  • Vocabulary: panel group headers are now separate from the stepper's phase names, so the
    choose group reads "Shortlist".

Design system gaps found

Audited before building. Two primitives are missing and are marked TODO(apollo-vertex):

  1. Inline trigger / annotated text: nothing in the registry marks a span of body copy as
    inspectable. hover-card, popover and tooltip are block or floating triggers, and the
    one inline precedent is evaluator specific and marked internal.
  2. One shot arrival treatment: ai-glow is the right visual family but is entirely static.
    AiChatThinking animates but loops as a busy indicator.

Partial:

  1. Staged message primitive: busy and settled states exist, no sequencer with cancellation.
  2. Motion tokens: the theme ships 12 easing tokens but no duration tokens, and
    ai-chat/animations.ts used a tuple near identical to --ease-out-quint rather than the
    token. This PR adds a duration scale there and points the easing at the token.
  3. Type and spacing scales: the theme ships neither. Sizes, weights, leading and tracking
    come from Tailwind's own default scale driven off --spacing, which is the nearest
    available scale rather than a parallel one.

StructuredTable was reused rather than rebuilt for the answer block. It is a good candidate
for promotion to the registry, since the workbench comparisons want the same shape.

Finding to report, not fixed

The headline claims the X1 Carbon is the best price after EPP. In the seed data the Carbon is
1,849 and the XPS 14 is 1,799, so the Carbon is not the cheaper unit. It carries the larger EPP
discount against the XPS, 350 to 300, but across fifteen units the XPS is 750 less. The Carbon
does not hold the largest discount either: the Yoga's is 400.

The answer block renders real numbers, so it now shows this in the open. Copy and seed prices
are unchanged, both being rulings for Gabriel.

Open rulings

  1. Does the claim trigger apply to every AI claim on the page, or only the headline reason?
  2. Does the "Ask AI" control at the foot of the results list survive alongside it?
  3. Final wording for the trigger clause and its accessible name.
  4. May the assistant recommend switching products, or only explain the pick? This decides
    whether the answer block keeps its switch action.
  5. Tier gating: none of this sits behind the P2 gate, on the reading that it modifies an
    existing surface.
  6. The lede and the "Policy applied" detail now say nearly the same thing. One should be cut.
  7. Finding label length is a content ruling: the layout gives labels their own column, which
    only pays off if they stay short.
  8. details, review and done still carry stepper vocabulary as group headers. The set needs
    naming together.
  9. The trigger no longer carries the AI mark. That reverses an earlier instruction to pair the
    mark with the label; the affordance is now the tinted ground plus dotted underline.

Provisional copy for ruling

Choose lede: "Narrowed the catalog to laptops that meet engineering spec."
Finding labels: "Catalog match", "Policy applied", "Suggested pick".
Trigger name: "Explain this claim".
Answer: "Here is how the two compare on price and spec.", "Side by side", "Metric",
"Unit price", "EPP discount", "Total for 15", "Memory", "{name} is {amount} less across
{n} units.", "Switch to {name}", "Keep {name}", "How does the {name} compare?".
Review labels: "Approval limit", "EPP savings", "Approval route".
Done labels: "Submitted", "Approver", "What happens next".

Details trimmed where they repeated their own label, for example "N laptops in the catalog
matched your request." became "N laptops matched your request."

Verification

56 checks across four browser suites, by getBoundingClientRect() and computed styles rather
than element counts. Trigger geometry and its four states, focus moving into the panel, the
reveal order and its cancellation, the answer block's derived values, the type and spacing
measurements, icon alignment, and reduced motion rendering the whole panel on the first frame.

A real bug surfaced while verifying: the reveal was replaying itself. The beats array is ordered
by index, not by time, so once a finding carried three beats, finding 0's icon was scheduled
later than finding 2's label. The monotonic counter tracking progress therefore ran backwards
and un-revealed later findings, which also let a halted sequence insert one finding into a
closing panel. Replaced with a set of fired beat indices.

Biome clean, build passes, lint unchanged from its baseline.

🤖 Generated with Claude Code

petervachon and others added 30 commits August 19, 2026 19:24
Experiment → Guided Buying docs page links to a full-screen /guided-buying
prototype, rendered in a separate React root to escape the Nextra docs layout.

Catalog "Selection" workspace:
- scan-row and card layouts (toggle) with a recommendation lead row
- product detail overlay, cart peek drawer, full-canvas compare table
- filters (brand/category/price/stock) with agent chips and price basis
- routable, deep-linkable state (?item / ?compare) and Review & submit stub

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build out the Guided Buying prototype's front-door flow and the buyer's
escalation queue, all scripted/mocked atop the Apollo AI Chat pattern.

Buy conversation (catalog/v1):
- Intake hero → in-chat Bridge: streamed restatement, then an inferred
  request envelope (cost center / ship-to / need-by / approver with
  provenance + edit affordances) and the routing consequence, revealed
  with a staggered field animation.
- Continue to selection → sourcing summary + a results carousel rendered
  inline in the thread (pick + 2 alternatives, skeleton→reveal), with the
  pick mirroring the catalog's Picked-for-you treatment.
- Add to cart confirms in-chat with amount + approval-limit status and a
  Review affordance; cart pill pulses on increment.
- ConversationProvider drives the shared thread across the Buy hero and
  the docked rail; catalog cards are fully clickable for details.

Workbench (workbench/): the off-catalog fork's escalation queue, adapted
from the Invoice Processing layout — list with stat cards + Quote (amber)
/ Contract (red) chips, and a three-region detail (queue · finding +
Approve/Counter/Reject + Autopilot composer · Activity/Details/Line
items/Source). Seeded with the standing-desks quote and mobile-lines
contract. Actions stubbed.

Shared Ai Chat tweaks: hover-only message actions, tighter empty-state
composer, stable scrollbar gutter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nd finish lines

Pull the buy flow back to the intended model — chat as the front door and a
tertiary escape hatch, a guided structured middle, and real finish lines.

- Intake stays conversational; once a request is made, a guided surface
  (BuyScaffold + GuidedBuy) presents the envelope/results directly, no transcript
- Constant header anchor (title + subtext) with staggered slide transitions, a
  consistent back control, and reserved bar height so the anchor never shifts
- Agentic Bridge edit: per-field pickers with reasons + cost-center→approver
  cascade; routing line indented to the card; em-dash removed
- Cart as a first-class object: persistent cart button (transitions in on
  Selection), peek with editable quantities, card-level steppers, and a primary
  "Review & submit · N · $total" that feeds the one unified Review page
- Configure + catalog submission finish lines: outcome headline, agent line
  naming the destination, dynamic recap, single primary exit, no in-flow back
- One Autopilot FAB replacing all scattered ask affordances (currently hidden
  behind a flag), with a persistent context-aware mini-chat thread
- Selection product matches shown as a 3-up grid instead of a cut-off carousel
- Shell: two demo seats (requester/buyer) with a Switch user menu item
- Buy intake composer gains attachment UI; example chips get a "Try an example" label

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mpt continuity, copy

- Bridge → Configure now reads as an expansion (rail reveals from the right,
  center fades, header anchored) instead of a horizontal swipe
- Configure rail cleaned up: sentence case, connecting-line timeline with dashed
  not-started dots, baseline-aligned header, more title→timeline space
- Carry the user's prompt through the flow: a "Request · From you" row on both
  Bridges (editable free text on catalog, read-only on contract) and the prompt
  as the Review hero for continuity
- Bridge field picker closes with the reverse of its open (a touch quicker); the
  edit pencil swaps to a check while a field is open
- Rebrand "Autopilot" → "AI Assistant" and "Picked for you" → "Best match" in
  user-facing text (code identifiers unchanged)
- Hide the Autopilot FAB behind a flag (kept fully wired for later)
- Copy: intake/Bridge/Selection headers + subtext, intake placeholder
- Fix: contract finish line "Back to Buy" now resets to a fresh Intake
  (honors resetChat) instead of returning to the in-flight Bridge

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…cles

The not-completed step markers were inline spans, so size-4 didn't apply and
they collapsed to a thin vertical sliver. Add block + a 2px ring so they match
the completed checkmark circles: solid border for the current step, dotted for
upcoming.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ed Buying

- Configure timeline dots render as proper circles (checks for done, solid ring
  current, dotted upcoming)
- Configure option cards use the card glow selectable state (glass), keeping the
  teal selected outline
- Match preview cards and both Bridge envelopes use the glass variant
- Configure step content staggers in (question, note, options, actions)
- Selection "Review & submit" transitions in like the top-bar buttons
- Soften the card selectable AI glow opacity (shared card component)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ests queue

Add the third use case (services sourcing / RFQ) and the requester's Requests
surface to the Guided Buying prototype.

Services sourcing:
- Swap the desks chip for "Hire 2 contract designers for the Q3 rebrand"; the
  services Bridge routes an RFQ to procurement.
- Workbench gains REQ-2053 with a vendor shortlist (indicative estimates, agent
  pick, provenance) and an RFQ-as-primary action that sends to the shortlist.

Requests (the requester's seat, mirror of the buyer's Workbench):
- Seat-dependent nav: requester sees Requests, buyer sees Workbench; the identity
  chip swaps both and lands on each seat's queue.
- Workbench-style list (stat cards + table); detail is a right-side slide-over
  panel with the status timeline, an AutopilotIcon lead banner, and state-fit
  actions (Message procurement / Mark urgent in-flight, Reorder / View order when
  terminal). Notes and urgent flags surface in the buyer's Workbench.
- Submitting a contract or services request lands in its Requests panel; the
  standalone routed confirmation screen is dissolved.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…at rail

Replace gradient circle + AutopilotIcon header with the AiMark (Astroid) icon
painted via SVG gradient def, and apply --ai-gradient-text clip to the wordmark.
Renames label from "AI Assistant" to "Autopilot" per project brand.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uided Buying

- Add FlowPhaseBar component: horizontal phase indicator with dot/check
  glyphs, muted connector lines, completed phases clickable as back-nav
- Wire CATALOG_PHASES (Details→Choose→Review→Done) and NON_CATALOG_PHASES
  (Details→Sent) into BuyFlow, Review, and CatalogSubmitted
- Fix B1 headline reset: replace didReset ref with __TSR_index-keyed effect
  so navigating to /buy again from the sidebar always resets to Intake
- Add fromReview HistoryState flag; Review's phase bar navigates back to Buy
  without clearing the conversation (preserves selection state)
- B2: extend RequestsContext with submittedRows/submitRequest; CatalogSubmitted
  registers REQ-2052 on mount so it appears in My Requests immediately
- B3: MatchCard title line-clamp-2 with fixed 2-line height for aligned cards
- B4: Add-button label unified to "Add N" on all three selection cards
- B5: Retire gradient fills — Best match badges and send button replaced with
  ai-gradient-start/15 soft-tint; glow effects kept at opacity-15
- B6: Date format changed from MM/DD/YYYY to DD MMM YYYY across all request rows
- B7: KPI hint copy "still with procurement" → "pending approval or sourcing"
- B8: Remove Dashboard from sidebar nav (route and page preserved)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…uying shelf build

Add a P1/P2 tier toggle to the Guided Buying prototype for CGA (now) vs V2
(next) feature comparison. Key additions:

- TierContext / TierProvider with localStorage persistence
- <P1> and <P2> gate components; useTier() only in permitted files
- TierToggle segmented control injected into ApolloShell via new headerSlot prop
- GB prototype tokens added to globals.css (--gb-tealbg, --gb-tealline, etc.)
- J1-01: chip starters copy cleanup (no trailing periods)
- J1-02: TeamsResumeCard with teal border, resume to bridge, step name "Picks up
  at Details" instead of drifting step number
- J1-04: AI reasoning strip above match grid, not-picked italic reasons on alt
  cards, AI pick badge with P1/P2 text swap, teal evidence chips on lead card,
  action chip row (Why not the XPS?, Compare all three, Ask)
- J1-05: P2 personalized strip with provenance chips (lucide icons replacing
  emoji), Ordered in May chip on lead, Yoga set-aside via setAside prop on
  MatchCard (unified component, no separate card — prevents layout drift),
  Update my preferences chip at P2
- KPI grid: auto-fit minmax(200px,1fr) — 3 tiles at P1, 4 at P2, no dead space
- Spend under management tile: teal border, +$27,735 delta, P2 only
- Chip text raised to 11px minimum

Browser-verified at 1440px: KPI grid auto-fit confirmed; Yoga slot height
347px at P1 and P2 (0px delta).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mit A)

Replace ad-hoc ACCENT/gb-teal Button overrides and chip constants with Apollo
toolkit primitives across the catalog flow.

- MatchCarousel: Card variant="glass" + AiGlow variant="card" for lead card
  (drops selectable="ai" collision); Badge status="ai" for AI pick badge;
  Badge variant="secondary" for evidence chips; Badge status="ai" variant="secondary"
  for memory chips; Button variant="ai-outline" for Ask chip; reasoning strip
  uses --ai-gradient + --insight-200 border
- All 10 catalog files: remove const ACCENT and every className override that
  applied it; Button default renders bg-primary already
- Remove direct bg-(--gb-teal) className from Button in ServiceBridge,
  ServicesBridge, NotInCatalogBanner, ProductCard

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tem (Commit B)

Replace all --gb-* prototype tokens with canonical Apollo tokens and delete
the --gb-* definitions from globals.css.

- --gb-teal → --primary across all 14 affected files (spans, borders, rings,
  backgrounds, text, dot indicators)
- --gb-indigo → --insight-600 (TierToggle P2 active state, TeamsResumeCard icon fill)
- --gb-indigobg → --insight-50 (TeamsResumeCard icon area background)
- WorkbenchDetail timeline dots: amber-500 → --warning, emerald-500 → --success
- Delete all 8 --gb-* custom property definitions from app/globals.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MatchCarousel: add AI disclosure line (Info icon + "The output is AI
  generated. Please review.") below the card grid
- MatchCarousel: Yoga card renders identically at both tiers on arrival;
  set-aside state reserved for stop-3 dock correction (wires in separately)
- MatchCarousel: remove "32GB min · saved Jun 12" third provenance chip
  from j1-05 P2 reasoning strip
- ServiceBridge: add AI disclosure line below the interpreted-summary
  routing line, above the CTA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…off JourneyBar

PM feedback 4 tasks: JourneyBar stage interactivity fix (Received non-button, delivery
receipt link), Details button on shelf cards via ProductDetailOverlay, CatalogSubmitted
"What happens next" JourneyBar on /track, PO record route at /po/$id with print stylesheet.

GROUP 2 cleanup: caveat moved below journey card in RequestWindow (consistent with the
other five caveat placements); yogaSetAside state renamed to correctionMade throughout
BuyFlow, GuidedBuy, MatchCarousel, ShelfDock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… tiles

Removes the P2-gated "Spend under management" tile; hub shows exactly 3 tiles at both
tiers with the auto-fit grid unchanged.

Adds an AI attention line above the tiles, derived from in-flight request data: approver
name and pending-days count parsed from REQUEST_DETAILS, item noun extracted from the
request title. P2 tier appends one inline sentence ("I sent a reminder this morning.")
without altering the P1 sentence. Follow up button routes to /requests/$id at both tiers.
AiCaveat below the attention line at both tiers. Renders nothing if no in-flight request
exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Thread userMenuAdditionalItems through ApolloShell → ShellLayout →
ShellSidebar → UserProfile → UserProfileMenuItems, replacing the
headerSlot TierToggle. TierMenuSection renders two DropdownMenuItems
with a Check icon on the active tier, grouped under a "Prototype tier"
label.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Avatar background shifts with tier: primary for P1/Now, --insight-600
for P2/Next. Thread avatarClassName through ApolloShell → ShellLayout
→ ShellSidebar → UserProfile → AvatarFallback. Add colored legend dots
(size-2 rounded-full in icon-sized containers) to the tier menu items so
they align horizontally with the Toggle theme and Language icons below.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wrap the 3-up match grid in a -mx-20 breakout div so cards have more
horizontal room without widening the surrounding content (reasoning
strip, chips, caveat stay at max-w-[720px]).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Back | stepper (absolute center) | Reset+Cart all live in one h-12 band
with a hairline border-b. Scroll area moved below the band so the chrome
is fixed while content scrolls. phaseBar no longer lives in the anchor
div — it sits in the band between the flanking controls.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oose

MatchCarousel now shows the user's original requestText (from
useConversation) as a quoted line above the AI reasoning strip —
making the human ask visually distinct from AI output. P1 strip
shortened: trailing "Here are all three matches so you can see why."
removed (already implied by the cards below).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each non-lead, non-set-aside MatchCard now gets a "Why not this?" ghost
button that opens the ShelfDock scoped to that item (Yoga or XPS).
ShelfDock gains a `subject: CatalogItem` prop; defense copy switches
between XPS_DEFENSE and YOGA_DEFENSE based on subject.id.

"Update my preferences" moves into the P2 reasoning strip (after badge
chips). The chip row below the grid is removed; the Ask button moves
beside the Review CTA in the bottom row.

BuyFlow adds shelfDockSubject state and passes it to ShelfDock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
INFERRED_REQUEST_QUANTITY corrected from 2 to 15 so "Add N" and cart
totals reflect the canonical journey (15 × $1,849 EPP). SAMPLE_REQUEST
summary and the Intake CATALOG_STARTER chip updated to match "15 laptops
for Fusion Event contractors" — keeps the requestText hero on the Choose
screen consistent with the cards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bject

At P2, the Teams resume card and the AiChatInput now share a single
continuous outline: the band provides top+left+right borders (rounded-t-xl,
border-2 border-input, insight-50 tint), the form provides left+right+bottom
(border-t-0 rounded-b-xl). No gap, no double border at the seam.

AiChatInput gains an `embedded` prop that drops the outer pt-3/px-4 padding
(aligning left/right borders with the band above), suppresses the glow, and
removes the focus box-shadow that would bleed into the band. Corner radius
changes between tiers are the deliberate, accepted consequence of attachment.

Resume demoted to ghost button — one primary action on the Intake screen.
Band background is --insight-50 so it reads as provenance, not a peer card.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Done screen: header chrome, receipt-style summary card, animated confirm
  check, and reordered action bar with the AI caveat above it
- Add consistent step-transition fades across Choose, Review, and Done
- Bridge: read-only Request row with a Revise action that reparses the
  envelope and preserves any fields the user overrode
- Fix BuyFlow's reset effect wiping conversation state on navigation to
  Review/Done, which had silently broken the header title everywhere
- Assistant panel: split the Details entry into records vs. guessed fields,
  with hover tooltips on the pencil/revise icons
- Request detail: adopt PageHeader, two-column layout with a sidebar for
  record metadata and linked records, gated to the P2 tier as before
- Split request titles into a short generated title (used as chrome) and
  the verbatim prompt (shown in full in the sidebar)
- Fix the Requests list/detail title mismatch by sourcing both from the
  same generated title instead of a separately re-derived cart summary

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tions

Request detail:
- Merge the agent line and stage bar into one AI-summary lead card: mark +
  label, a state-aware sentence with the notable fact highlighted via
  --ai-gradient, and a new ActivityTrack (bigger nodes, pulsing ring on the
  current stage, event pins for user/agent activity).
- Header now only carries a primary action when one is genuinely owed
  (Confirm receipt when delivered, Respond when sent back); status badge
  removed since state already reads from the summary and stage track.
- Nudge and Mark urgent moved into the lead card as real outline buttons
  with icons; completed state keeps button chrome (filled-muted, check
  icon, "today" label) instead of collapsing to plain text.
- Reference column de-carded to a plain labelled list, widened to 200px,
  aligned to the card's first content line, 8px-base vertical rhythm.

Requests list:
- Add a "delivered" status (wired end-to-end via REQ-2031: row, detail,
  and close-window data) so Confirm receipt has somewhere real to go.
- Row-level Confirm receipt action for delivered rows, plus a hover-reveal
  overflow menu for copy link / view PO.
- Attention line now summarizes count and opens a filtered view when more
  than one request needs attention, instead of only ever naming one.
… URLs, inline cart editing

Delivery receipt:
- Remove the standalone Close Window and /close/$id route; a request that
  reaches "delivered" now shows that state on its own detail page instead
  of a second page with different header chrome.
- "Confirm receipt" opens a modal (ordered qty, quantity-received stepper
  with live match/short warning, damaged-items checkbox, optional note)
  instead of committing silently or navigating away.
- Confirming plays the Done screen's check animation (extracted to a
  shared ConfirmCheck), appends a Communication entry, and — when partial
  or damaged — states that in the summary and on the stage track.
- Linked records (PO/PR chips) migrate from the removed page's data into
  the sidebar, driven by RequestDetail instead of hardcoded JSX.

Decision window — notifications and post-approval states:
- Replace the persistent "Approved" banner with a Sonner toast per the
  in-product notification guidelines; add a global Toaster host.
- Add a header Status badge + Approved date field so the state change
  stays visible once the toast dismisses.
- Every element gets a distinct approved-state instead of showing
  pre-decision copy after the fact: AI summary states the outcome (PO
  sent, expected delivery), budget/device management restate in present
  tense, the PO chip becomes a real linked record, a confirmation line +
  "View order" replaces the decision buttons, and the approval itself
  (with any note left in the composer) appends to Communication.

Real URLs:
- Switch the TanStack router from memory to browser history with a
  basepath, add a Next.js catch-all route (split into a literal page.tsx
  + sibling [...slug] since Nextra's page-map needs a literal file) so
  reloading or sharing a deep link works instead of 404ing.
- Make the Buy flow's Bridge/Selection phases addressable via
  /buy?phase=..., with instant seeding (bypassing the scripted stream) for
  deep links and reloads; Review and the Done screen seed the same way
  when reached with an empty cart.
- Fix a stray re-render (router state updates a tick before BuyFlow
  unmounts on its way to /review) that was silently resetting the
  conversation, breaking Review's Back button.

Review screen — inline cart editing:
- Remove "Edit cart" (it navigated away to change a number already on
  screen); line items become the cart itself — quantity stepper, unit
  price, remove control, live-recalculating totals.
- Add "Add items from the catalog" as a drawer over Review instead of a
  navigation; removing the last item leaves an empty state with the add
  link and disables submit, without navigating away.
- Fix the cart pricing bug: the drawer, header cart pill, and add-to-cart
  toast all priced off the browse-time list/EPP filter instead of the
  fixed EPP price the cart actually charges, so opening the cart could
  make the same order look like it got more expensive.

Bump @tanstack/react-router to 1.170.18 (apollo-vertex only).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…f to Details

New /home route: a composer identical to Buy's Intake (same AiChatInput,
Teams-resume band, starter chips), plus a tiered "Your requests" list
(P1 factual status line, P2 appends an agent-voice line and the AI
caveat) with a single uniform stage icon per row. Added above Buy in
the sidebar nav and as the app's default landing.

Submitting (typed text, Enter, or the laptops chip) seeds the
conversation via sendCatalogRequest and navigates to /buy?phase=bridge,
so Details' Request row and Need by popover reflect the real typed
text instead of the canonical demo default. The other two chips route
to a plain /buy — they don't have an addressable Details step yet.

AiChatEmptySuggestions gained additive label/value support so chips can
show a short label while still submitting the full sentence; Buy's own
chips now share the same STARTER_SUGGESTIONS constant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…g under React 19

framer-motion registers every motion.* component via a useInsertionEffect
that can end up scheduling a state update; React 19 warns on that timing
regardless of effect. This is an open upstream issue (react/react#24160,
motiondivision/motion#2668), not something in our own code, and every
animation/interaction tested behaves correctly despite it.

Adds a dev-only console.error filter for that one exact message, mounted
once at the root layout, guarded against double-patching under Fast
Refresh. Everything else still logs normally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… to Decision Window

Request Window's header overflow menu gets an "Approver view (demo)"
action for in-flight requests with a named approver — jumps to
/decision/$id with the same request id so the two screens agree on
which request is open. Decision Window's own header/menu structure was
reworked alongside it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…emory-write receipt

Shelf's thread gets a new "note" entry kind rendering a receipt chip
("Saved to Design Contractor spec · preferences updated") through
AiChatMessage, same treatment as the dock's own P2 correction save.
AiChatMessage gained an assistantMarkdownClassName override to support
it, and Alert gained a "success" status variant (outline + tinted).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
petervachon and others added 19 commits August 20, 2026 09:16
@tanstack/react-router@1.170.20 requires @tanstack/router-core@1.171.17
internally, but this package pinned router-core to 1.171.15 directly,
so pnpm installed two copies side by side. TypeScript treats the two
copies' route types as structurally similar but nominally distinct,
which collapsed RoutePaths<typeof routeTree> down to just "/" and broke
every literal route path checked against it in personas.ts. Surfaced by
rebasing onto main rather than introduced by it — personas.ts is the
first code on this branch to exercise that type deeply enough to hit
the skew.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Collapses Priya onto Marcus's shared nav array, /home route, and Home
component instead of a second surface per person: priyaNavItems and
/start retire, ?as=priya disambiguates a cold load on the shared route,
and /requests scopes by persona (requesterPersonaId) the same way
/approvals already scopes by approverPersonaId. Seeds 3 requests for
Priya (REQ-10482 fully real, two bracketed pending a content ruling).
RequestWindow's and DecisionWindow's message composer reused the
recipient's own name/avatar (approver or requester) for the sender too,
correct for the placeholder naming who receives it, wrong for whose
message it actually is. Both now resolve the active persona via
usePersona() instead.

Also part of the same cleanup pass: personas.ts/route-tree.tsx/
HomeRoute.tsx broadened cold-load persona resolution (?as=priya) to
every shared requester surface, not just /home, and fixed a chip-count
mismatch on Priya's home mini-list — already folded into the parity
commit above since both landed in the same working tree before either
was committed.
ConnectMeet showed as Selected before the requester acted. Vendor
selection now requires an explicit click (vendorConfirmed, separate
from the pre-filled selectedVendor default Review/Submitted still fall
back to), clicking the selected row again un-selects it, and Continue
to Data & Info stays disabled until a selection is confirmed.
Adds the identity row (vendor, what's being bought, extraction
provenance) that was missing entirely, collapses three identical
per-year rows into one commitment line with the schedule disclosed
rather than always-equal, and reuses Marcus's prose treatment for the
second card instead of bare label/value pairs. BrandMark now takes a
vendor name directly (it only ever read that field off CatalogItem),
so the identity row can reuse it without a fabricated cart item.

Also sweeps British spellings to US English throughout the guided-buying
templates (licence -> license, centre -> center) in every rendered
string, resolving the Chunk C1 escalation on that spelling. REQ-10482's
requester-parity row and identity/order-summary/second-card wording
(from the parity commits above) already carried some of this file's
other edits before any of tonight's work was committed separately.
The stage list was a card inside a card inside a dashed box: removes
the inner card entirely (the outer request card already provides one),
and replaces the dashed Legal/Security pair with the solid rail the
timeline variant already used for the identical data, extending to a
third concurrent stage instead of needing a wider box. System chips
now only show for stages actually leaving this tool (Jira/DocuSign/
Coupa), driven by the stage's own owner field. The first pending stage
renders as next with a filled bullet and a bracketed state line; every
other stage stays hollow.

Also fixes the card's summary row clipping behind the sticky footer:
the scroll container's bottom buffer (pb-10, 40px) was shorter than
the footer's own rendered height (~64px). Sentence-cases stage labels
(Procurement Validation -> Procurement validation, etc.) and PR / PO ->
PR and PO, single-sourced in journeys.ts.
…letion state

- Details pane: two-column label-above-value grid, section headings
  removed (grouping still carried by spacing), commodity/vendor/term/
  money facts derived from the seed instead of a flat admin-only list
- Placeholder register: each entry can carry a provisional display
  value alongside its ruling description, with a dev-only reveal mode
  that marks provisional strings without touching layout
- Completion state leads with the outcome (contract value and elapsed
  duration) instead of the automation claim, adds terms/price outcome
  cards, and reads resolution rows in first person for the buyer
- Workbench header: record-level disposition slot removed until its
  behaviour is ruled on; queue card gets a primary ring at 8px radius
- Exception evidence metric column renders its unit beneath the value
  instead of inline

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… view

Copies the card grid, glow, prompt bar and insight renderers verbatim
from PR 616's dashboard experiment, strips the scripted demo pieces and
dev control panels, and repoints the data layer at Elena's own
analytics module instead of the experiment's hardcoded datasets.

Restores the background glow after an earlier pass wrongly dropped it,
guards the KPI badge against rendering empty, wires her sub findings
into the card expand state, and fixes a height cascade bug that kept
expanding cards from actually growing in the grid.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… states

Builds out the four insight cards ported in 86055ee into real, data-backed
visuals: donut/proportion-bar/stage-duration chart types, per-card icons,
and a designed expanded state for each card that adds detail rather than
replacing the face (stage bars gain the commodity breakdown beneath them
with a connecting line, intake quality gains its return-reason breakdown,
off contract spend gains its supporting facts column).

Adds the underlying data (return reasons, commodity cycle time, on/off
contract split) to analytics.ts and registers the new provisional copy in
placeholders.ts. Adds a fade-to-skeleton-to-content reveal sequence on
expand, a width-only growth path for cards that don't need more height,
and assorted page-header and hero-trend polish.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds an AI mark to each insight card's corner (only where a scripted
answer is registered), opening the existing composer grounded to that
card: it auto-asks on click, shows the answer as a right-aligned bubble
with suggested follow ups, and dims the other cards while active.

Also fixes a truncation tooltip that could get stuck open under quick,
repeated hovering (replaced with a native title attribute), aligns KPI
numbers across cards regardless of whether they show an expand control,
swaps two KPI numbers to the shared ai-gradient-text token, removes the
stage list's rail now that it read as too busy, and nudges the page
header's glow and Share button.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…page

Adds a P2 recommendation to the "where the time goes" card that Elena can
send to a new CoE queue, splits the stage and commodity breakdowns into
two columns so the recommendation fits without clipping, and adds Ravi
Mehta as a P2-only persona with a queue and finding detail page where he
can review evidence, run a summary test, and publish. Publishing updates
the same seeded record Elena's card reads, so her card picks up a
published state without a second block. Also fixes a stale re-render on
"Send to CoE" caused by the React Compiler memoizing a mutable module
level lookup, and nudges two chart faces up 8px to align with their
headers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…App previews

Next.js basePath doesn't rewrite plain <img> src attributes, only its own
next/image, next/link, and next/script, so every hardcoded root relative
asset path (the shell's own UiPath logo, and the Autopilot icon used in
three outcomes components) 404'd once served from a Coded App preview's
sub-path. Adds a shared assetPath() helper, the same fix app/layout.tsx's
navbar logo already used, and applies it everywhere else the same bug
was reachable.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…enus

Splits the flat persona list into "Journey 1: Catalog" (Marcus, Alex) and
"Journey 3: Software" (Priya, Sam, Dana, Elena, Ravi under P2), each its
own DropdownMenuSub flyout matching the existing Toggle theme/Language
treatment, rather than two labeled but flat sections.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Update the '15 laptops · Fusion Event' starter chip on the guided
buying /home screen to '15 laptops · Contractors', and update the
text it autofills into the composer on click to '15 laptops for
contractors for an upcoming dev project'.

Scoped to just the chip label and /home's autocomplete text; /buy's
own copy of the chip, the deep-link default scenario, and the
quantity-inference constant still reference the old Fusion Event
scenario text, intentionally left untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sion keynote

The Marcus Webb "Choose" step timeline read "3 met the 32GB minimum," a raw
count that undersells why laptops were filtered. For the Fusion keynote demo,
reword it to "Policy checked: Only showing laptops that meet engineering
spec," with "Policy checked:" bolded, so the narrowing reads as a deliberate
policy check rather than an arbitrary number.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ion keynote

Continues the Fusion keynote copy pass: the summary headline now reads as an
engineering-requirements assessment ("Identified that the laptops are for
engineering and assessed engineering laptop requirements to narrow the
search.") instead of citing raw counts and the RAM threshold directly. The
picked-laptop detail line changes from "Picked" to "Suggested" to match the
softer, recommendation-toned voice used elsewhere in the flow, with
"Suggested Lenovo ThinkPad X1 Carbon:" bolded via the existing **bold**
detail-line convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… Fusion keynote

Continues the Fusion keynote copy pass: the lead-card subhead ("Best price
after EPP, and it clears your 32GB minimum.") named the raw RAM threshold
directly. Reworded to "Best price after EPP, and it meets engineering laptop
specs." to match the engineering-specs framing used elsewhere in the flow.
Also updated winningReasonParts, the shared reason-builder behind the
dynamic re-ranked subhead, so both the default and re-ranked states read
consistently.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds deliberate waiting time at three points in the catalog journey so
loading no longer reads as instant/faked for the Fusion keynote demo:
submit prompt to request envelope (1.5s), confirm to dashboard product
cards (3s), and Review's Submit request to the submitted screen (3s).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… and scannable

The choose phase assistant panel was only reachable from an "Ask AI" control below the fold,
and once open it arrived fully populated and went quiet, reading as a log rather than as work
in progress. Its content was also set too tight to scan.

Reachability and arrival:
- Add a reusable inline claim trigger on the headline's reason clause, which opens the panel
  and moves focus into it. The clause comes from the recommendation data, not from a string
  in the component, so the same treatment can carry the card level claims later.
- Add a one shot attention pass over that trigger on arrival at the phase.
- Reveal the findings one at a time on open, each with its status icon resolving after its own
  text, and highlight the results card a finding concerns as it lands.
- Add a structured answer state: a labelled row set per product, a derived summary, and actions
  that dispatch through the existing cart selection rather than a parallel path.

Typography and rhythm:
- Drop the lede to regular weight at looser leading, emphasise the finding label instead, open
  the space between findings fourfold, and segment the panel into narration, evidence and next
  move with two hairline rules.
- Split findings in the data layer into a label and a detail, replacing a bold prefix
  convention that left the component nothing to lay out.

Vocabulary and copy:
- Give panel group headers their own vocabulary, separate from the stepper's phase names, so
  the choose group reads "Shortlist" rather than repeating the stepper word above it.
- Replace every bracketed placeholder with provisional copy, held in the data layer.

Motion comes from one place: a duration scale added to the ai-chat motion module, whose easing
now points at the theme's --ease-out-quint token instead of a near identical tuple of its own.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 10, 2026 23:59
@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Apollo Coded App preview deployments are ready.

Project Status Preview Updated (PT)
apollo-design Ready Preview · Logs Sep 15, 2026, 06:50:00 AM
apollo-docs Ready Preview · Logs Sep 15, 2026, 06:50:00 AM
apollo-landing Ready Preview · Logs Sep 15, 2026, 06:50:00 AM
apollo-vertex Ready Preview · Logs Sep 15, 2026, 06:50:00 AM

Comment on lines +223 to +226
([entry]) => {
if (entry) setToolbarStuck(!entry.isIntersecting);
},
{ root, threshold: 0 },
@@ -0,0 +1,70 @@
import { motion } from "framer-motion";
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";
@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1936 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1707
ISC 88
Apache-2.0 55
BSD-3-Clause 27
BSD-2-Clause 23
BlueOak-1.0.0 8
MPL-2.0 4
MIT-0 3
CC0-1.0 3
MIT OR Apache-2.0 2
(MIT OR Apache-2.0) 2
Unlicense 2
LGPL-3.0-or-later 1
Python-2.0 1
CC-BY-4.0 1
(MPL-2.0 OR Apache-2.0) 1
Unknown 1
Artistic-2.0 1
(WTFPL OR MIT) 1
(BSD-2-Clause OR MIT OR Apache-2.0) 1
CC-BY-3.0 1
0BSD 1
(MIT OR CC0-1.0) 1
MIT AND ISC 1
Excluded packages
Package Version License Reason
@img/sharp-libvips-linux-x64 1.3.2 LGPL-3.0-or-later LGPL pre-built binary, not linked
khroma 2.1.0 Unknown MIT per GitHub repo, missing license field in package.json

Comment on lines +223 to +226
([entry]) => {
if (entry) setToolbarStuck(!entry.isIntersecting);
},
{ root, threshold: 0 },
@@ -0,0 +1,70 @@
import { motion } from "framer-motion";
import type { ReactNode } from "react";
import { cn } from "@/lib/utils";
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package bundle size on this PR (no JS/TS source changes detected under packages/* or web-packages/*).

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core 42.01 MB 50.12 MB ±0
@uipath/apollo-react 7.56 MB 29.14 MB ±0
@uipath/apollo-ui-icons 2.85 MB 6.91 MB ±0
@uipath/apollo-wind 451.0 KB 2.87 MB +5 B
@uipath/ap-chat 43.92 MB 56.68 MB ±0

"Coverage" is each package's own coverage.include scope (e.g. apollo-core instruments only scripts/). "Packed"/"Unpacked" come from npm pack --dry-run and only cover built packages — "—" means not measured this run (package not affected / not built). "vs main" is the packed (gzipped) delta against the last successful main build (the package-sizes artifact from the Release workflow); "—" there means no main baseline was available this run. The baseline is main's latest build, not this PR's exact merge-base, so it includes any drift since the branch diverged. Packages with no vitest config are omitted.

@github-actions

github-actions Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Storybook visual diff

✅ No stories are affected by this PR's changes; nothing to compare. Logs

Updated (PT): Sep 15, 2026, 06:51:10 AM

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved moderate issues affect accessibility, state synchronization, keyboard gating, data correctness, routing, and UI behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This pull request expands the Guided Buying Fusion demo with claim-level assistant interactions, staged findings, structured comparisons, catalog workflows, request surfaces, and supporting shell/AI infrastructure.

Changes:

  • Adds assistant triggers, staged reveals, attention effects, and comparison answers.
  • Extends catalog, intake, request, workbench, CoE, outcomes, persona, and tier flows.
  • Updates shared AI chat, shell, routing, styling, seed data, and warning handling.
File summaries
File Summary
apps/apollo-vertex/templates/guided-buying/workbench/CorrectionDraftModal.tsx Correction email draft modal
apps/apollo-vertex/templates/guided-buying/use-attachment-gate.ts Attachment gating hook
apps/apollo-vertex/templates/guided-buying/TierToggle.tsx P1/P2 tier selector
apps/apollo-vertex/templates/guided-buying/tier-context.tsx Persisted tier state
apps/apollo-vertex/templates/guided-buying/requests/TruncatedSubtitle.tsx Responsive subtitle truncation
apps/apollo-vertex/templates/guided-buying/requests/SendBackDialog.tsx Send-back form
apps/apollo-vertex/templates/guided-buying/requests/ReceiptModal.tsx Receipt confirmation modal
apps/apollo-vertex/templates/guided-buying/requests/MyRequests.tsx Requests list wrapper
apps/apollo-vertex/templates/guided-buying/requests/DecisionChecks.tsx Decision checks
apps/apollo-vertex/templates/guided-buying/requests/DecisionActionGroup.tsx Decision actions
apps/apollo-vertex/templates/guided-buying/requests/CommunicationCard.tsx Communication card
apps/apollo-vertex/templates/guided-buying/requests/avatar-color.ts Avatar color mapping
apps/apollo-vertex/templates/guided-buying/ReasonDialog.tsx Reusable reason dialog
apps/apollo-vertex/templates/guided-buying/persona-context.tsx Persona context
apps/apollo-vertex/templates/guided-buying/panel-type.ts Panel typography tokens
apps/apollo-vertex/templates/guided-buying/P2.tsx P2 gate
apps/apollo-vertex/templates/guided-buying/P1.tsx P1 gate
apps/apollo-vertex/templates/guided-buying/outcomes/use-view-mode.ts Responsive view mode
apps/apollo-vertex/templates/guided-buying/outcomes/use-recommendation-sent.ts Recommendation state
apps/apollo-vertex/templates/guided-buying/outcomes/StageDurationRecommendation.tsx Recommendation card
apps/apollo-vertex/templates/guided-buying/outcomes/Outcomes.tsx Outcomes page
apps/apollo-vertex/templates/guided-buying/outcomes/hero-trend.tsx Trend visualization
apps/apollo-vertex/templates/guided-buying/outcomes/drilldown-tabs.ts Drilldown tabs
apps/apollo-vertex/templates/guided-buying/outcomes/DashboardGlow.tsx Dashboard glow
apps/apollo-vertex/templates/guided-buying/outcomes/DashboardDataProvider.tsx Dashboard data provider
apps/apollo-vertex/templates/guided-buying/outcomes/dashboard-data-context.ts Dashboard context
apps/apollo-vertex/templates/guided-buying/outcomes/chart-stubs.tsx Chart placeholders
apps/apollo-vertex/templates/guided-buying/outcomes/AutopilotInsight.tsx Assistant insight panel
apps/apollo-vertex/templates/guided-buying/intake/SubmittedStep.tsx Submitted state
apps/apollo-vertex/templates/guided-buying/intake/routing.ts Intake routing
apps/apollo-vertex/templates/guided-buying/intake/IntakeStateProvider.tsx Intake state provider
apps/apollo-vertex/templates/guided-buying/intake/intake-state-context.tsx Intake state model
apps/apollo-vertex/templates/guided-buying/home/HomeRoute.tsx Persona-scoped home
apps/apollo-vertex/templates/guided-buying/GuidedBuyingShell.tsx Guided Buying shell
apps/apollo-vertex/templates/guided-buying/DecisionActionRow.tsx Shared action row
apps/apollo-vertex/templates/guided-buying/data/people.ts People fixtures
apps/apollo-vertex/templates/guided-buying/data/index.ts Data exports
apps/apollo-vertex/templates/guided-buying/ConfirmCheck.tsx Completion animation
apps/apollo-vertex/templates/guided-buying/coe/findings-data.ts CoE findings state
apps/apollo-vertex/templates/guided-buying/coe/CoeQueue.tsx CoE queue
apps/apollo-vertex/templates/guided-buying/ClaimTrigger.tsx Inline claim trigger
apps/apollo-vertex/templates/guided-buying/catalog/variants.ts Catalog variant registry
apps/apollo-vertex/templates/guided-buying/catalog/v1/useRail.ts Rail state
apps/apollo-vertex/templates/guided-buying/catalog/v1/use-content-overflow.ts Overflow detection
apps/apollo-vertex/templates/guided-buying/catalog/v1/types.ts Catalog types
apps/apollo-vertex/templates/guided-buying/catalog/v1/TeamsResumeCard.tsx Resume card
apps/apollo-vertex/templates/guided-buying/catalog/v1/StepIndicator.tsx Progress indicator
apps/apollo-vertex/templates/guided-buying/catalog/v1/RecommendationCard.tsx Recommendation card
apps/apollo-vertex/templates/guided-buying/catalog/v1/RailDock.tsx Assistant rail
apps/apollo-vertex/templates/guided-buying/catalog/v1/QuantityStepper.tsx Quantity control
apps/apollo-vertex/templates/guided-buying/catalog/v1/ProductImage.tsx Product imagery
apps/apollo-vertex/templates/guided-buying/catalog/v1/ProductDetailOverlay.tsx Product details dialog
apps/apollo-vertex/templates/guided-buying/catalog/v1/ProductCard.tsx Product tile
apps/apollo-vertex/templates/guided-buying/catalog/v1/price-basis-context.ts Pricing context
apps/apollo-vertex/templates/guided-buying/catalog/v1/NotInCatalogBanner.tsx Off-catalog banner
apps/apollo-vertex/templates/guided-buying/catalog/v1/IntentHeader.tsx Intent header
apps/apollo-vertex/templates/guided-buying/catalog/v1/GuidedBuy.tsx Buy surface
apps/apollo-vertex/templates/guided-buying/catalog/v1/FlowPhaseBar.tsx Phase bar
apps/apollo-vertex/templates/guided-buying/catalog/v1/FlowFooter.tsx Flow footer
apps/apollo-vertex/templates/guided-buying/catalog/v1/flow-phases.ts Flow phase constants
apps/apollo-vertex/templates/guided-buying/catalog/v1/FilterChips.tsx Filter chips
apps/apollo-vertex/templates/guided-buying/catalog/v1/CartSummary.tsx Cart totals
apps/apollo-vertex/templates/guided-buying/catalog/v1/CartProvider.tsx Cart provider
apps/apollo-vertex/templates/guided-buying/catalog/v1/CartLine.tsx Cart line
apps/apollo-vertex/templates/guided-buying/catalog/v1/CartDrawer.tsx Cart drawer
apps/apollo-vertex/templates/guided-buying/catalog/v1/cart-context.ts Cart context
apps/apollo-vertex/templates/guided-buying/catalog/v1/AddItemsDrawer.tsx Add-items drawer
apps/apollo-vertex/templates/guided-buying/catalog/CatalogV2.tsx Logo catalog variant
apps/apollo-vertex/templates/guided-buying/catalog/CatalogV1.tsx Photo catalog variant
apps/apollo-vertex/templates/guided-buying/catalog/Catalog.tsx Catalog host
apps/apollo-vertex/templates/guided-buying/AutopilotChatProvider.tsx Persistent chat state
apps/apollo-vertex/templates/guided-buying/autopilot-chat-context.ts Chat context
apps/apollo-vertex/templates/guided-buying/asset-prefix.ts Asset path helper
apps/apollo-vertex/templates/guided-buying/AiAttention.tsx Arrival attention effect
apps/apollo-vertex/registry/shell/shell.tsx Shell identity and header props
apps/apollo-vertex/registry/shell/shell-user-provider.tsx User override support
apps/apollo-vertex/registry/shell/shell-user-profile.tsx Profile menu props
apps/apollo-vertex/registry/shell/shell-user-profile-menu-items.tsx Profile menu items
apps/apollo-vertex/registry/shell/shell-sidebar.tsx Sidebar prop forwarding
apps/apollo-vertex/registry/shell/shell-layout.tsx Header and sidebar slots
apps/apollo-vertex/registry/shell/group-membership-guard.tsx Group membership guard
apps/apollo-vertex/registry/card/card.tsx Selected glow opacity
apps/apollo-vertex/registry/bar-chart/bar-chart-view.tsx Chart layout options
apps/apollo-vertex/registry/alert/alert.tsx Success alert variants
apps/apollo-vertex/registry/ai-glow/ai-glow.tsx Glow opacity
apps/apollo-vertex/registry/ai-chat/hooks/use-pending-files.ts Document attachments
apps/apollo-vertex/registry/ai-chat/components/ai-chat.tsx Chat spacing and mask
apps/apollo-vertex/registry/ai-chat/components/ai-chat-message.tsx Markdown styling
apps/apollo-vertex/registry/ai-chat/components/ai-chat-message-actions.tsx Message actions
apps/apollo-vertex/registry/ai-chat/components/ai-chat-input.tsx Send gating and attachments
apps/apollo-vertex/registry/ai-chat/components/ai-chat-empty-suggestions.tsx Labeled suggestions
apps/apollo-vertex/registry/ai-chat/animations.ts Motion constants
apps/apollo-vertex/package.json Router dependencies
apps/apollo-vertex/app/preview/onboarding-tour/page.tsx Onboarding preview
apps/apollo-vertex/app/layout.tsx Warning filter mounting
apps/apollo-vertex/app/guided-buying/page.tsx Guided Buying route
apps/apollo-vertex/app/guided-buying/guided-buying-mount.tsx Client root
apps/apollo-vertex/app/guided-buying/[...slug]/page.tsx Deep-link route
apps/apollo-vertex/app/experiment/guided-buying/page.mdx Prototype launch page
apps/apollo-vertex/app/experiment/_meta.ts Experiment navigation
apps/apollo-vertex/app/_meta.ts Route visibility
apps/apollo-vertex/app/_components/suppress-known-warnings.tsx Console warning suppression
Review details

Suppressed comments (7)

apps/apollo-vertex/app/_components/suppress-known-warnings.tsx:34

  • This replaces console.error globally for the lifetime of the page and filters solely on the warning text. That suppresses the same React warning if it originates from application code, contrary to the comment's claim that owned misuse will still surface, and it also affects unrelated pages/components. Avoid a global patch or scope the suppression to the known dependency/source.
    apps/apollo-vertex/templates/guided-buying/catalog/v1/FilterChips.tsx:28
  • Selection marks the In stock and EPP chips with isAgent: true, and the interface documents that flag as carrying the Autopilot sparkle, but this renderer never reads it. Agent-applied filters therefore look identical to user-applied filters; render the agent treatment when chip.isAgent is true.
    apps/apollo-vertex/templates/guided-buying/catalog/v1/MatchCarousel.tsx:1144
  • For the seeded recommendation this interpolates the X1 Carbon, whose EPP price is $1,849, while the XPS 14 is $1,799; the Yoga also has the larger EPP saving ($400 versus Carbon's $350). The finding therefore makes a false "best price after EPP" claim even though the comparison answer renders the real values. Replace this with a data-backed claim or derive the price comparison before shipping.
    apps/apollo-vertex/templates/guided-buying/catalog/v1/ProductCard.tsx:52
  • The card is exposed as a role="button" with keyboard activation while it contains a real Add <Button>. This creates nested interactive controls, so assistive technologies see a button inside a button and keyboard activation has competing targets. Make only the details affordance interactive (or use a non-interactive card with a separate details button) while keeping Add as its own control.
    apps/apollo-vertex/templates/guided-buying/catalog/v1/data.ts:457
  • RECOMMENDATION_REASON still labels the Carbon as the “Best price after EPP”, but the seed values make that false: Carbon is $1,849 after EPP, XPS is $1,799, and Yoga's $400 discount exceeds Carbon's $350. The newly rendered answer block exposes those values, so the claim and evidence contradict each other in the demo; update the copy or the seed data before shipping.
    apps/apollo-vertex/templates/guided-buying/catalog/v1/use-staged-reveal.ts:169
  • The completion callback is documented and used as the moment the final finding icon resolves, but this condition fires on the chips beat (3 * count) instead. The final card highlight is therefore delayed until after the chips appear; complete on the final icon index (3 * count - 1) instead.
    apps/apollo-vertex/templates/guided-buying/home/Home.tsx:67
  • The home surface only uses requestStatusOverrides for the approved copy/icon; this action gate still reads the static detail's sentBack. After a live Send back, the requester's home row therefore does not show the Respond action even though the provider records that state. Pass the effective override into this helper and derive the owed action from it.
  • Files reviewed: 115/180 changed files
  • Comments generated: 11
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +152 to +155
if (!value.trim() && pendingFiles.length === 0) {
textareaRef.current?.focus();
return;
}
Comment on lines +45 to +48
/** Override the sidebar identity (e.g. a demo "seat"). */
user?: ShellUser;
/** Make the identity chip a button (e.g. switch seats) instead of a menu. */
onUserClick?: () => void;
Comment on lines +11 to +34
<button
type="button"
onClick={() => setTier("p1")}
className={cn(
"px-3 py-1.5 transition-colors",
tier === "p1"
? "bg-(--primary) text-white"
: "bg-background text-muted-foreground hover:bg-muted",
)}
>
P1 · Now (CGA)
</button>
<button
type="button"
onClick={() => setTier("p2")}
className={cn(
"px-3 py-1.5 transition-colors",
tier === "p2"
? "bg-(--insight-600) text-white"
: "bg-background text-muted-foreground hover:bg-muted",
)}
>
P2 · Next (V2)
</button>
Comment on lines +13 to +16
export function Catalog() {
const { hasResolved } = useConversation();
const reduceMotion = useReducedMotion();
const ActiveVariant = CATALOG_VARIANTS[0].Component;
Comment on lines +17 to +21
const check = () => setOverflowing(el.scrollHeight > el.clientHeight + 1);
check();
const observer = new ResizeObserver(check);
observer.observe(el);
return () => observer.disconnect();
Comment on lines +243 to +245
if (pathname.startsWith("/decision") || pathname.startsWith("/approvals")) {
return "approver";
}
Comment on lines +54 to +61
const handleOpenChange = (next: boolean) => {
if (next) {
setQtyReceived(qtyOrdered);
setDamaged(false);
setNote("");
}
onOpenChange(next);
};
Comment on lines +38 to +44
const handleOpenChange = (next: boolean) => {
if (next) {
setReason(undefined);
setNote("");
}
onOpenChange(next);
};
Comment on lines +35 to +38
useLayoutEffect(() => {
const el = ref.current;
setIsTruncated(el != null && el.scrollWidth > el.clientWidth);
}, [text]);
Comment on lines +61 to +65
<input
value={draft.to}
readOnly
className="min-w-0 flex-1 rounded-md border border-border bg-muted/30 px-2 py-1 text-xs text-foreground focus:outline-none"
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app:apollo-vertex size:XXL 1,000+ changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants