Components
The components that matter when adding a new agent or building admin UI.
AgentCard
src/components/AgentCard.tsx
<AgentCard
agent={agent} // Agent (display type)
variant="featured" | "default" // "featured" = 160px hero, "default" = 96px
layoutIdPrefix="featured-" // prevents Framer Motion ID collisions
index={i} // optional for stagger
/>
Renders the icon chip, status pill (Featured / New / Coming Soon), gradient hero band, name, tagline, pricing badge, install count.
comingSoon: true→ card is non-navigable; click opensNotifyDialog.- Otherwise routes to
/agent/:slugwith a Framer Motion shared-element transition.
Always pass a unique layoutIdPrefix if the same agent might appear in multiple grids on the same page.
BrowseAgents
src/components/BrowseAgents.tsx
<BrowseAgents
limit={12} // optional cap with "Show more"
title="Browse all agents"
kicker="MARKETPLACE"
footer={() => <BookDemoButton />}
/>
Renders the catalog grid. Internal:
- Fetches the full catalog (
useAgents()). - Derives available tags from the unfiltered set so the chip bar always shows everything.
- Filters by
?tag=query param +SearchContext.query. - Uses
placeholderData: keepPreviousDataso the grid doesn't flash on tag change. - Fires
agents_tag_filteredto PostHog. - Scrolls into view on tag change.
NotifyDialog
src/components/NotifyDialog.tsx
<NotifyDialog
open={isOpen}
onOpenChange={setOpen}
agentName="MyAgent"
agentId="ag_..."
/>
Email capture for coming-soon agents. Pre-fills from useMe(). Validates via Zod. On success, sets the React Query cache key waitlistKey(agentId) so all "Notify me" CTAs for this agent flip to "On the list."
ScrollBgController
src/components/ScrollBgController.tsx
Monitors sections tagged data-bg="light" | "dark" | "teal". Uses RAF to find the section occupying the largest fraction of the viewport (50%+ activation) and sets --current-bg + data-page-bg on <html>. Transition: 0.7s cubic-bezier.
Honors data-page-bg-lock to allow modal overlays to freeze the background.
Currently all BG_MAP values resolve to white (enterprise mode). Section tags are preserved but the controller is effectively a no-op. To re-enable the dark / teal variants, edit BG_MAP in the file.
SearchContext (src/context/SearchContext.tsx)
type SearchCtx = {
query: string;
setQuery: (q: string) => void;
};
Provider wraps the whole app inside BrowserRouter. The header <SiteHeader> has the input; BrowseAgents reads query to filter. No debounce. No multi-field state.
SiteHeader and SiteFooter
src/components/SiteHeader.tsx — logo, search input (controlled by SearchContext), auth menu (Sign In / user dropdown), mobile hamburger.
src/components/SiteFooter.tsx — links, legal, company info.
LucideDynamicIcon
<LucideDynamicIcon iconSlug="shield-check" className="size-5" />
Looks up Lucide icons by string. Used to render agent_capabilities.icon server-stored values. Falls back to an emoji if the slug isn't found.
Hero animations
HeroFlowField— dot-particle field.HeroConstellation— graph-style nodes + edges.TextRotator— cycles a phrase array on an interval.
Decorative. Avoid putting LCP-critical content inside them.
Dashboard widgets
UsageBreakdown— chart of quota consumed per metric for the active subscription.LiveMetricsRibbon,LiveTelemetry,DotField— decorative.ScreenshotLightbox— modal gallery for agent screenshots on the detail page.
Admin
AdminLayout— sidebar + nav + outlet. User profile menu top right.- Form components for AgentSubmit / AgentEdit use shadcn/ui form primitives.
Component conventions
- New components go in
src/components/. Per-route screens insrc/pages/. - Use shadcn/ui primitives from
src/components/ui/— do not hand-edit them; add new ones via the shadcn CLI. - Path alias
@/resolves tosrc/. - Always pair
themeFor(category)withdefaultsFor(category)when rendering any agent UI.