Skip to content

feat(apollo-wind): Autopilot Chat pattern (spike)#899

Draft
dbacomputer wants to merge 4 commits into
mainfrom
spike-shadcn-autopilot-chat
Draft

feat(apollo-wind): Autopilot Chat pattern (spike)#899
dbacomputer wants to merge 4 commits into
mainfrom
spike-shadcn-autopilot-chat

Conversation

@dbacomputer

@dbacomputer dbacomputer commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Spike porting shadcn's new chat component family into apollo-wind and assembling it into a Patterns page for feedback, mirroring the legacy Material ApChat's Embedded/FullScreen layout modes and header/composer structure.

  • Primitives: Message/Bubble (already merged in a prior commit), plus new MessageScroller, Attachment, and Marker, all ported from shadcn's registry/npm package and restyled to apollo-wind's tokens.
  • InputGroup gets real block-start/block-end addon support — a genuine gap vs. shadcn's current upstream API, needed for the composer's two-row (content + toolbar) layout, fixed properly rather than worked around.
  • Patterns → Autopilot Chat page with three stories: Components (primitives in isolation), Layout Embedded, Layout Fullscreen — the last two mirror the legacy ApChat's actual mode-dependent container behavior (docked bottom-right vs. fills the page), with the header and composer restructured to match the legacy component's real structure (title + "Preview" badge, New chat/Settings/History/Expand-Collapse/Close actions; Attach/Resource/Agent-mode composer controls) rather than the generic shadcn demo this was initially scaffolded from.

Known gaps (tracked, not addressed in this PR)

  • No unit tests yet for Attachment, Marker, MessageScroller (or Message/Bubble from the prior commit) — every sibling component in packages/apollo-wind/src/components/ui/ has a .test.tsx; this breaks that pattern and should be closed before this graduates past spike status.
  • AttachmentTrigger, AttachmentActions/AttachmentAction, and BubbleReactions are exported but not demonstrated anywhere yet.
  • A config-driven "Showcase" page (like the legacy ApChat's) isn't feasible yet — the legacy version's controls drive a real AutopilotChatService; this pattern is presentation-only with a hardcoded scripted transcript. Would need a real service layer first.
  • Separately (repo-wide, not introduced here): packages/apollo-wind/vitest.config.ts's coverage thresholds are placed directly under coverage instead of coverage.thresholds, so Vitest 4 silently ignores them — confirmed live, package coverage sits at 38% and vitest run --coverage still exits 0. Worth a separate fix, but retroactively affects every package, not just this one.

Test plan

  • pnpm build, pnpm lint, pnpm format:check, tsc --noEmit all pass for apollo-wind (verified locally)
  • Review Patterns → Autopilot Chat in Storybook: Components, Layout Embedded, Layout Fullscreen
  • Add missing unit tests before merging out of draft
Screenshot 2026-07-10 at 9 48 10 AM

Part of a spike to bring shadcn's new chat component family
(MessageScroller, Message, Bubble, Attachment, Marker) into apollo-wind
for an "Autopilot chat" Patterns page.

Message and Bubble are ported and self-contained (no new dependencies).
Paused here: MessageScroller needs a new package, @shadcn/react, which
this repo's pnpm minimumReleaseAge policy currently blocks (published
2026-06-30, clears the 14-day policy window around 2026-07-14).
Attachment, Marker, MessageScroller, the Autopilot chat story, and
Patterns sidebar ordering are not yet built.
…rimitives

Completes the shadcn chat component port started with Message/Bubble:

- MessageScroller (+ Provider/Viewport/Content/Item/Button) wraps the
  newly-added @shadcn/react package with apollo-wind styling. Handles
  auto-scroll-to-latest with a fade-in "scroll to latest" button once the
  viewport is scrolled away from the live edge.
- Attachment (+ Media/Content/Title/Description/Actions/Action/Trigger/
  Group) and Marker (+ Icon/Content), ported from shadcn's registry source.
- Extends InputGroupAddon with block-start/block-end alignment (a toolbar
  row stacked below content instead of beside it), which shadcn's current
  InputGroup supports but apollo-wind's earlier port didn't. The container
  switches to a column layout via a `has-[]:` variant, forced with `!`
  since conditional variants and unconditional utilities on the same
  property aren't reconciled by class merging.
- Adds the `shimmer` and `scroll-fade-x`/`scroll-fade-y` Tailwind utilities
  these components need, scoped to only what's used (the source registry
  ships direction variants and size modifiers nothing here uses).

@shadcn/react was vetted (provenance, publisher, release diff, integrity)
and added to minimumReleaseAgeExclude pending the 14-day quarantine window.
Assembles the ported primitives into a Patterns/Autopilot Chat page for
coworker feedback, mirroring the legacy Material ApChat's Embedded/
FullScreen layout modes and header/composer structure:

- Components: Message/Bubble, Attachment, Marker, and MessageScroller
  shown in isolation as a reference for the pieces the panel is built from.
- Layout Embedded: the panel docked bottom-right over a mock host page
  (fixed, shadow-xl), matching the legacy demo harness's exact positioning
  convention (that positioning is a host-page choice, not enforced by the
  panel itself).
- Layout Fullscreen: the same panel with its size cap and chrome stripped
  so it fills the page, matching the legacy FullScreen mode's approach of
  expanding rather than repositioning.

The header (title + "Preview" badge, New chat/Settings/History/Expand-
Collapse/Close actions) and composer (Attach/Resource/Agent-mode) mirror
the legacy ApChat's actual structure rather than the generic shadcn demo
this was initially scaffolded from. The transcript itself is a scripted,
local-state conversation (no @ai-sdk/react) since this is a static design-
system demo, not a wired chat backend.

Known gaps, tracked but not addressed here: no unit tests yet for the new
primitives (every sibling in ui/ has one), and a config-driven "Showcase"
page isn't feasible until there's a real service layer behind this pattern
— the legacy Showcase's controls drive an actual AutopilotChatService;
ours is presentation-only.
Copilot AI review requested due to automatic review settings July 10, 2026 16:40
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (PT)
apollo-design 🟢 Ready Preview, Logs Jul 10, 2026, 09:51:19 AM
apollo-docs 🟢 Ready Preview, Logs Jul 10, 2026, 09:51:19 AM
apollo-landing 🟢 Ready Preview, Logs Jul 10, 2026, 09:51:19 AM
apollo-vertex 🟢 Ready Preview, Logs Jul 10, 2026, 09:51:19 AM

@github-actions

Copy link
Copy Markdown
Contributor

Dependency License Review

  • 1949 package(s) scanned
  • ✅ No license issues found
  • ⚠️ 2 package(s) excluded (see details below)
License distribution
License Packages
MIT 1719
ISC 89
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.2.4 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

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.

Pull request overview

This PR spikes an “Autopilot Chat” pattern in apollo-wind by porting shadcn’s newer chat primitives and composing them into Storybook pattern stories that mirror the legacy ApChat embedded/fullscreen layouts.

Changes:

  • Added new chat-related UI primitives (Attachment, Marker, Message, Bubble, MessageScroller) and exported them from the package public API.
  • Added Tailwind CSS utilities for scroll-fade masks and shimmer states used by the new primitives.
  • Extended InputGroupAddon with block-start / block-end alignment to support a 2-row composer layout, and added @shadcn/react@0.2.1 as a dependency (with a workspace release-age exclusion).

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Adds @shadcn/react to minimumReleaseAgeExclude with a pinned version/reason.
pnpm-lock.yaml Locks @shadcn/react@0.2.1 resolution and snapshot entries.
packages/apollo-wind/package.json Adds runtime dependency on @shadcn/react@0.2.1.
packages/apollo-wind/src/styles/tailwind.consumer.css Introduces scroll-fade-x/y and shimmer utilities needed by the new chat primitives.
packages/apollo-wind/src/index.ts Re-exports new chat primitives and reorganizes package public exports.
packages/apollo-wind/src/components/ui/index.ts Adds barrel exports for the new primitives.
packages/apollo-wind/src/components/ui/input-group.tsx Adds block-aligned addon support to enable multi-row input groups.
packages/apollo-wind/src/components/ui/message.tsx Adds Message layout primitives (group/avatar/content/header/footer).
packages/apollo-wind/src/components/ui/bubble.tsx Adds Bubble primitives and reaction positioning variants.
packages/apollo-wind/src/components/ui/marker.tsx Adds marker/separator primitive used for “Today” dividers and similar labels.
packages/apollo-wind/src/components/ui/message-scroller.tsx Wraps @shadcn/react/message-scroller with apollo-wind styling and exports hooks/components.
packages/apollo-wind/src/components/ui/attachment.tsx Adds attachment card primitives and horizontal attachment scroller group.
packages/apollo-wind/src/components/ui/autopilot-chat.stories.tsx Adds the Storybook “Patterns/Autopilot Chat” stories (components gallery + embedded/fullscreen layouts).
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

<span
data-slot="marker-content"
className={cn(
'min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground',
<div
data-slot="attachment-group"
className={cn(
'flex min-w-0 scroll-fade-x snap-x snap-mandatory scroll-px-1 scrollbar-none gap-3 overflow-x-auto overscroll-x-contain py-1 *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start',
Comment on lines +71 to +74
className={cn(
'absolute bottom-3 left-1/2 z-10 flex -translate-x-1/2 items-center justify-center gap-1.5 rounded-full border border-border-subtle bg-card px-3 py-1.5 text-xs font-medium text-foreground shadow-md transition-opacity hover:bg-surface-overlay data-[active=false]:opacity-0',
className
)}
Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib';
Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/lib';

Comment on lines +1 to +5
import * as React from 'react';
import { cn } from '@/lib';

const MessageGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/lib';

Comment on lines +1 to +6
'use client';

import { MessageScroller as MessageScrollerPrimitive } from '@shadcn/react/message-scroller';
import { ChevronDown } from 'lucide-react';
import * as React from 'react';
import { cn } from '@/lib';
Comment on lines +22 to 28
// Block-aligned addons (toolbar rows) stack the group into a column instead of
// sitting inline. `!` is required: these must win over the unconditional height/
// items-center utilities below regardless of Tailwind's generated rule order,
// since has-[]: variants and plain utilities aren't reconciled by class merging.
'has-[>[data-align=block-start]]:!h-auto has-[>[data-align=block-start]]:!flex-col has-[>[data-align=block-start]]:!items-stretch',
'has-[>[data-align=block-end]]:!h-auto has-[>[data-align=block-end]]:!flex-col has-[>[data-align=block-end]]:!items-stretch',
// Size (mirrors Input's own size scale, since Input's box chrome moves up to this wrapper)
@github-actions

Copy link
Copy Markdown
Contributor

📊 Coverage + size by package

Per-package coverage and bundle size on this PR. New-line coverage = of the source lines this PR adds or changes, the % hit by tests.

Package Coverage New-line coverage Packed (gzip) Unpacked vs main
@uipath/apollo-core 9.0% 43.82 MB 57.31 MB ±0
@uipath/apollo-react 34.5% 7.27 MB 27.63 MB +398 B
@uipath/apollo-wind 39.8% 0.0% (0/65) 407.6 KB 2.66 MB +12.7 KB
@uipath/ap-chat 85.8% 43.41 MB 55.85 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.

Adds a "Wind vs Material" page to Patterns/Autopilot Chat clarifying when
to use each: apollo-wind's primitives for presentational work (mockups,
custom chat UIs, no MUI/Emotion dependency), Material's ApChat for fully
wired product integration (real AutopilotChatService backing models,
agent modes, resources, streaming, history, mode switching). Includes a
capability comparison table and links to where each lives.
Copilot AI review requested due to automatic review settings July 10, 2026 16:46

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.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

Comment on lines +74 to +81
<div
ref={ref}
className={cn(
'flex max-w-full min-w-0 items-center px-3 text-xs font-medium text-muted-foreground group-data-[align=end]/message:justify-end',
className
)}
{...props}
/>
<span
data-slot="marker-content"
className={cn(
'min-w-0 wrap-break-word group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground',
<div
data-slot="attachment-group"
className={cn(
'flex min-w-0 scroll-fade-x snap-x snap-mandatory scroll-px-1 scrollbar-none gap-3 overflow-x-auto overscroll-x-contain py-1 *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start',
Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { Button } from '@/components/ui/button';
import { cn } from '@/lib';
Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/lib';

Comment on lines +1 to +5
import { Slot } from '@radix-ui/react-slot';
import { cva, type VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/lib';

Comment on lines +1 to +5
import * as React from 'react';
import { cn } from '@/lib';

const MessageGroup = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
Comment on lines +1 to +12
'use client';

import { MessageScroller as MessageScrollerPrimitive } from '@shadcn/react/message-scroller';
import { ChevronDown } from 'lucide-react';
import * as React from 'react';
import { cn } from '@/lib';

export {
useMessageScroller,
useMessageScrollerScrollable,
useMessageScrollerVisibility,
} from '@shadcn/react/message-scroller';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:apollo-wind size:XXL 1,000+ changed lines.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants