@12-apps/mcp 3.5.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/ai-onboarding.tsx","../../src/react/ai-landing.tsx","../../src/react/ai-capabilities.tsx","../../src/react/ai-icons.tsx","../../src/react/feature-badge.tsx","../../src/react/ai-connection-utils.ts","../../src/react/ai-flow-steps.tsx","../../src/react/host-connect-guide.tsx","../../src/react/mcp-endpoint-url.tsx","../../src/react/ai-status-board.tsx","../../src/react/host-select-step.tsx","../../src/react/ai-steps.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n GuidedSection,\n OnboardingProvider,\n useOnboarding,\n type OnboardingStateSnapshot,\n type OnboardingStore,\n} from \"@12-apps/onboarding\";\n\nimport {\n AI_CAPABILITIES,\n aiHostGuides,\n AI_PERMISSION_MODEL,\n type AiCapability,\n type AiHostGuide,\n} from \"../guide\";\nimport { AiLanding } from \"./ai-landing\";\nimport type { DisconnectHandler } from \"./ai-status-board\";\nimport {\n buildFlowSteps,\n connectedSummary,\n connectedTitle,\n StatusBoard,\n type AiConnection,\n} from \"./ai-steps\";\n\nexport type { AiConnection } from \"./ai-steps\";\n\nconst DEFAULT_FEATURE_KEY = \"ai_integration\";\n\n/** Props for the reusable AI-connect onboarding flow. */\nexport interface AiIntegrationOnboardingProps {\n /** Persistence seam — the app wires this to its own backend (server actions). */\n store: OnboardingStore;\n /** The MCP endpoint URL to paste (derived by the app from its public origin). */\n endpointUrl: string;\n /** The owner's saved progress (null → first run / landing). */\n initialState: OnboardingStateSnapshot | null;\n /** The live MCP connections (one per connected assistant; empty when none). */\n connections: readonly AiConnection[];\n /** Onboarding feature key (persistence namespace). @default \"ai_integration\" */\n featureKey?: string;\n /** Show the dev-only \"reset onboarding\" button. @default false */\n devReset?: boolean;\n /**\n * The platform operating this MCP server, as its OAuth consent button names\n * it. REQUIRED, and it is the reason `hosts` can have a default at all: one\n * ChatGPT step tells the owner which \"Sign in with …\" button to click, and\n * that button carries whoever runs the server. It used to be a hard-coded\n * name — of a single STORE on one deployment, not even the product — so every\n * other adopter pointed its owners at a button that does not exist.\n */\n platformName: string;\n /** Assistants offered in the flow. @default aiHostGuides(platformName) */\n hosts?: readonly AiHostGuide[];\n /** Capability cards on the landing. @default the shared AI_CAPABILITIES */\n capabilities?: readonly AiCapability[];\n /** Permission reassurance copy on the landing. @default AI_PERMISSION_MODEL */\n permissionModel?: string;\n /**\n * Message the owner pastes into the assistant on the Conectar step.\n *\n * REQUIRED, with no default, because the useful version of it names TOOLS —\n * one to register the connection, one to read something real — and this\n * package neither defines nor serves any. It shipped a constant naming two\n * tools from one adopter's surface, so another host handed its owner a prompt\n * that called two things that did not exist, and the confirm step then waited\n * forever for a registration that could never happen. Build it with\n * `aiConnectPrompt({ … })`.\n */\n connectPrompt: string;\n /**\n * Re-check the live connection on the verify step's \"Testar conexão\" button —\n * apps pass a router refresh (e.g. Next's `router.refresh`). @default a full\n * `window.location.reload()`.\n */\n onRetest?: () => void;\n /**\n * Revoke a connected assistant's access, from the completed status board. The\n * host ID is the board's card, NOT the connection — `claude` and\n * `claude-desktop` share one provider, so the app resolves which stored\n * connection it owns (`providerForHostId`) and revokes that. Omitted → the\n * board stays read-only, which is the pre-existing behavior.\n */\n onDisconnect?: DisconnectHandler;\n}\n\n/** Resolved (defaults-applied) props threaded to the in-provider flow body. */\ninterface FlowProps {\n endpointUrl: string;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n capabilities: readonly AiCapability[];\n permissionModel: string;\n connectPrompt: string;\n onRetest: () => void;\n onDisconnect: DisconnectHandler | undefined;\n devReset: boolean;\n}\n\n/**\n * The flow body — inside the OnboardingProvider so it can read the selected host\n * and pick the path. A host with a published `pluginUrl` gets the simplified\n * Escolher → Instalar → Confirmar flow (no URL to copy); otherwise the full\n * Escolher → Copiar URL → Configurar → Conectar → Confirmar flow.\n */\nfunction AiOnboardingFlow(props: FlowProps): React.JSX.Element {\n const {\n endpointUrl,\n connections,\n hosts,\n capabilities,\n permissionModel,\n connectPrompt,\n onRetest,\n onDisconnect,\n devReset,\n } = props;\n const { state } = useOnboarding();\n const selectedHost =\n hosts.find((h) => h.id === state.data.selectedHost) ?? hosts[0]!;\n\n const steps = buildFlowSteps({\n host: selectedHost,\n hosts,\n endpointUrl,\n connectPrompt,\n connections,\n onRetest,\n });\n const connectedHostId = (state.data.connectedHost ??\n state.data.selectedHost) as string | undefined;\n\n return (\n <GuidedSection\n steps={steps}\n title=\"Conecte assistentes de IA à sua loja\"\n startLabel=\"Ver como conectar\"\n renderLanding={(start) => (\n <AiLanding\n onStart={start}\n permissionModel={permissionModel}\n capabilities={capabilities}\n />\n )}\n configuredTitle={connectedTitle(connections, hosts, connectedHostId)}\n configuredSummary={connectedSummary(connections)}\n editLabel=\"Conectar IA\"\n completedContent={(nav) => (\n <StatusBoard\n nav={nav}\n connections={connections}\n hosts={hosts}\n onDisconnect={onDisconnect}\n />\n )}\n devReset={devReset}\n dataTestId=\"ai-onboarding\"\n />\n );\n}\n\n/**\n * URL-free, persisted onboarding for the AI/MCP integration — a five-step wizard\n * (pick an assistant, copy the store URL, configure the connector, connect, then\n * verify) whose position + chosen assistant are saved via `@12-apps/onboarding`, so\n * a refresh resumes exactly where the owner left off. The live MCP connection\n * signal drives the verify step and the completed status board.\n *\n * App-agnostic: the app supplies the persistence `store`, the `endpointUrl`, and\n * the live `connections` (one per connected assistant); content (hosts,\n * capabilities, copy) defaults to the shared guide but can be overridden per app.\n */\nexport function AiIntegrationOnboarding({\n store,\n endpointUrl,\n initialState,\n connections,\n featureKey = DEFAULT_FEATURE_KEY,\n devReset = false,\n platformName,\n hosts = aiHostGuides(platformName),\n capabilities = AI_CAPABILITIES,\n permissionModel = AI_PERMISSION_MODEL,\n connectPrompt,\n onRetest = () => {\n if (typeof window !== \"undefined\") window.location.reload();\n },\n onDisconnect,\n}: AiIntegrationOnboardingProps): React.JSX.Element {\n return (\n <OnboardingProvider\n featureKey={featureKey}\n store={store}\n initialState={initialState}\n >\n <AiOnboardingFlow\n endpointUrl={endpointUrl}\n connections={connections}\n hosts={hosts}\n capabilities={capabilities}\n permissionModel={permissionModel}\n connectPrompt={connectPrompt}\n onRetest={onRetest}\n onDisconnect={onDisconnect}\n devReset={devReset}\n />\n </OnboardingProvider>\n );\n}\n","\"use client\";\n\nimport BoltOutlinedIcon from \"@mui/icons-material/BoltOutlined\";\nimport LanguageOutlinedIcon from \"@mui/icons-material/LanguageOutlined\";\nimport LockOpenOutlinedIcon from \"@mui/icons-material/LockOpenOutlined\";\nimport VerifiedUserOutlinedIcon from \"@mui/icons-material/VerifiedUserOutlined\";\n\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport { AI_CAPABILITIES, AI_PERMISSION_MODEL, type AiCapability } from \"../guide\";\nimport { AiCapabilities } from \"./ai-capabilities\";\nimport { FeatureBadge, type FeatureBadgeItem } from \"./feature-badge\";\n\nconst FEATURES: FeatureBadgeItem[] = [\n { icon: <LockOpenOutlinedIcon />, label: \"Usa o seu próprio login\", caption: \"Sem chaves ou credenciais extras\" },\n { icon: <BoltOutlinedIcon />, label: \"Sem instalar nada\", caption: \"Conecta em poucos minutos\" },\n { icon: <VerifiedUserOutlinedIcon />, label: \"Só o que você pode\", caption: \"As suas permissões, nada além\" },\n { icon: <LanguageOutlinedIcon />, label: \"Navegador ou app\", caption: \"Claude, ChatGPT, Codex\" },\n];\n\n/** The single-column marketing hero: eyebrow + headline + description + CTA. */\nfunction Hero({ onStart }: { onStart: () => void }): React.JSX.Element {\n return (\n <Stack spacing={2.5} sx={{ maxWidth: 680 }}>\n <Box\n sx={{\n color: \"primary.main\",\n fontSize: 12,\n fontWeight: 700,\n letterSpacing: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n Integração com IA\n </Box>\n <Text variant=\"heading\" size=\"xl\" weight=\"bold\" as=\"h1\">\n Conecte{\" \"}\n <Box component=\"span\" sx={{ color: \"primary.main\" }}>\n assistentes de IA\n </Box>{\" \"}\n à sua loja\n </Text>\n <Text variant=\"body\" color=\"secondary\" as=\"p\">\n Deixe o Claude, o ChatGPT e outros assistentes responderem sobre o seu cardápio, estoque e\n pedidos — e executarem ações por você, direto na conversa. Com segurança e sem instalar\n nada.\n </Text>\n <Box sx={{ pt: 1 }}>\n <Button onClick={onStart} data-testid=\"ai-landing-start\">\n Ver como conectar\n </Button>\n </Box>\n </Stack>\n );\n}\n\n/**\n * Homepage-style marketing landing for the AI integration (shown before the\n * owner starts): a hero, the permission reassurance, a trust/feature strip, and\n * the capability highlights. `onStart` begins the guided flow. `permissionModel`\n * and `capabilities` default to the shared copy; apps can override.\n */\nexport function AiLanding({\n onStart,\n permissionModel = AI_PERMISSION_MODEL,\n capabilities = AI_CAPABILITIES,\n}: {\n onStart: () => void;\n permissionModel?: string;\n capabilities?: readonly AiCapability[];\n}): React.JSX.Element {\n return (\n <Stack spacing={6} data-testid=\"ai-landing\">\n <Hero onStart={onStart} />\n\n <Stack\n direction=\"row\"\n spacing={1.5}\n alignItems=\"flex-start\"\n data-testid=\"ai-permission-callout\"\n sx={{\n p: 2,\n borderRadius: 2,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <VerifiedUserOutlinedIcon sx={{ color: \"success.main\", mt: 0.25 }} />\n <Text variant=\"body\" as=\"p\">\n {permissionModel}\n </Text>\n </Stack>\n\n <Box\n sx={{\n p: { xs: 2.5, md: 3 },\n borderRadius: 3,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <Box\n sx={{\n display: \"grid\",\n gap: 3,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\", md: \"repeat(4, 1fr)\" },\n }}\n >\n {FEATURES.map((f) => (\n <FeatureBadge key={f.label} icon={f.icon} label={f.label} caption={f.caption} />\n ))}\n </Box>\n </Box>\n\n <Box>\n <AiCapabilities capabilities={capabilities} />\n </Box>\n </Stack>\n );\n}\n","import { Box } from \"@12-apps/ui/mui/Box\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport { AI_CAPABILITIES, type AiCapability } from \"../guide\";\nimport { CapabilityIcon } from \"./ai-icons\";\n\n/** One marketing card: an icon, a headline and an example prompt (as a bubble). */\nfunction CapabilityCard({ capability }: { capability: AiCapability }): React.JSX.Element {\n return (\n <Box\n data-testid={`ai-capability-${capability.id}`}\n sx={{\n p: 2.5,\n borderRadius: 3,\n border: 1,\n borderColor: \"divider\",\n bgcolor: \"background.paper\",\n height: \"100%\",\n // Static transition string: safe to cross the server→client boundary.\n transition: \"border-color 200ms, box-shadow 200ms, transform 200ms\",\n \"&:hover\": { borderColor: \"primary.main\", boxShadow: 3, transform: \"translateY(-3px)\" },\n }}\n >\n <Box\n sx={{\n width: 44,\n height: 44,\n borderRadius: 2,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n bgcolor: \"primary.main\",\n color: \"primary.contrastText\",\n mb: 1.5,\n }}\n >\n <CapabilityIcon id={capability.id} fontSize={26} />\n </Box>\n <Text variant=\"body\" weight=\"bold\" as=\"h3\">\n {capability.title}\n </Text>\n <Box\n data-testid={`ai-capability-prompt-${capability.id}`}\n sx={{\n mt: 1,\n px: 1.5,\n py: 1,\n borderRadius: 2,\n borderBottomLeftRadius: 4,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <Text variant=\"body\" size=\"sm\" as=\"p\" color=\"secondary\">\n {capability.detail}\n </Text>\n </Box>\n </Box>\n );\n}\n\n/**\n * Marketing block for the AI integration: a headline + a responsive grid of\n * capability cards. Shown on the onboarding landing (before the owner starts) to\n * sell the feature — \"here's what the assistant does for you\". `capabilities`\n * defaults to the shared set; apps can pass their own.\n */\nexport function AiCapabilities({\n capabilities = AI_CAPABILITIES,\n}: {\n capabilities?: readonly AiCapability[];\n}): React.JSX.Element {\n return (\n <Box data-testid=\"ai-capability-examples\" sx={{ width: \"100%\" }}>\n <Box sx={{ mb: 3 }}>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n O que o assistente faz por você\n </Text>\n <Box sx={{ mt: 0.5 }}>\n <Text variant=\"body\" size=\"sm\" as=\"p\" color=\"secondary\">\n Sem planilhas, sem cliques — é só perguntar na conversa.\n </Text>\n </Box>\n </Box>\n <Box\n sx={{\n display: \"grid\",\n gap: 3,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\", md: \"repeat(4, 1fr)\" },\n }}\n >\n {capabilities.map((capability) => (\n <CapabilityCard key={capability.id} capability={capability} />\n ))}\n </Box>\n </Box>\n );\n}\n","import AutoAwesomeIcon from \"@mui/icons-material/AutoAwesome\";\nimport CategoryIcon from \"@mui/icons-material/Category\";\nimport HubIcon from \"@mui/icons-material/Hub\";\nimport Inventory2Icon from \"@mui/icons-material/Inventory2\";\nimport QueryStatsIcon from \"@mui/icons-material/QueryStats\";\nimport ReceiptLongIcon from \"@mui/icons-material/ReceiptLong\";\n\nimport { Box } from \"@12-apps/ui/mui/Box\";\n\nimport type { AiHostBrand } from \"../guide\";\n\n/**\n * Brand accents for the host avatars. These are deliberately hardcoded (not\n * theme tokens): they are BRAND marks whose recognizability depends on the\n * vendor's own accent colour, so the \"always semantic colours\" rule doesn't\n * apply here. The glyphs are simple, original stand-ins — not the vendors'\n * proprietary logo artwork.\n */\nconst BRAND: Record<AiHostBrand, { bg: string; Icon: typeof AutoAwesomeIcon; label: string }> = {\n claude: { bg: \"#D97757\", Icon: AutoAwesomeIcon, label: \"Claude (Anthropic)\" },\n openai: { bg: \"#10A37F\", Icon: HubIcon, label: \"OpenAI\" },\n};\n\n/** A round brand chip: the vendor accent + a simple glyph. */\nexport function HostBrandAvatar({\n brand,\n size = 40,\n}: {\n brand: AiHostBrand;\n size?: number;\n}): React.JSX.Element {\n const { bg, Icon, label } = BRAND[brand];\n return (\n <Box\n aria-label={label}\n sx={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n bgcolor: bg,\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Icon sx={{ fontSize: size * 0.55 }} />\n </Box>\n );\n}\n\nconst CAPABILITY_ICON: Record<string, typeof AutoAwesomeIcon> = {\n orders: ReceiptLongIcon,\n inventory: Inventory2Icon,\n catalog: CategoryIcon,\n sales: QueryStatsIcon,\n};\n\n/** The icon for a capability card, by capability id (falls back to a sparkle). */\nexport function CapabilityIcon({\n id,\n fontSize = 24,\n}: {\n id: string;\n fontSize?: number;\n}): React.JSX.Element {\n const Icon = CAPABILITY_ICON[id] ?? AutoAwesomeIcon;\n return <Icon sx={{ fontSize }} />;\n}\n","import { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\n/** One entry of a landing's trust/feature strip. */\nexport interface FeatureBadgeItem {\n icon: React.ReactNode;\n label: string;\n caption: string;\n}\n\n/**\n * One item of an onboarding landing's trust/feature strip: a paper icon tile\n * (primary-coloured glyph) with a two-line label + caption.\n */\nexport function FeatureBadge({ icon, label, caption }: FeatureBadgeItem): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1.5} alignItems=\"flex-start\">\n <Box\n sx={{\n width: 36,\n height: 36,\n borderRadius: 2,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n bgcolor: \"background.paper\",\n color: \"primary.main\",\n border: 1,\n borderColor: \"divider\",\n flexShrink: 0,\n }}\n >\n {icon}\n </Box>\n <Box>\n <Text variant=\"body\" size=\"sm\" weight=\"bold\" as=\"p\">\n {label}\n </Text>\n <Text variant=\"caption\" color=\"secondary\" as=\"p\">\n {caption}\n </Text>\n </Box>\n </Stack>\n );\n}\n","import { providerForHostId, type AiHostGuide, type AiProvider } from \"../guide\";\n\n/**\n * Pure helpers + the connection type shared by the AI-onboarding flow steps\n * (`ai-flow-steps.tsx`) and the orchestration/status board (`ai-steps.tsx`),\n * kept here so neither JSX module has to import the other (no import cycle).\n */\n\n/** The live connection surfaced from the server (empty list when none). */\nexport interface AiConnection {\n clientName: string | null;\n /**\n * The provider this connection is attributed to (derived server-side from the\n * OAuth client's redirect URIs / confirmed by `announceAiConnection`). `null`\n * for a legacy connection recorded before attribution existed — matched\n * best-effort to whichever host the owner is connecting.\n */\n host: AiProvider | null;\n lastActiveAt: Date;\n}\n\n/** Friendly provider names for the connected-state title (\"Claude Conectado\"). */\nconst PROVIDER_LABEL: Record<AiProvider, string> = {\n claude: \"Claude\",\n chatgpt: \"ChatGPT\",\n codex: \"Codex\",\n};\n\n/** Resolve a persisted host id to its guide (falls back to the first host). */\nexport function resolveHost(hosts: readonly AiHostGuide[], hostId: unknown): AiHostGuide {\n const found = hosts.find((h) => h.id === hostId) ?? hosts[0];\n if (!found) throw new Error(\"resolveHost: hosts array must not be empty\");\n return found;\n}\n\n/** Friendly label for a persisted host id (falls back to a generic word). */\nexport function hostLabel(hosts: readonly AiHostGuide[], hostId: unknown): string {\n return hosts.find((h) => h.id === hostId)?.label ?? \"seu assistente\";\n}\n\n/**\n * The live connection for a given host, or null. A connection is matched by its\n * derived provider; a legacy `null`-host connection matches best-effort (so the\n * pre-attribution single-connection behavior still works).\n */\nexport function connectionForHost(\n connections: readonly AiConnection[],\n hostId: unknown,\n): AiConnection | null {\n const provider = typeof hostId === \"string\" ? providerForHostId(hostId) : null;\n if (!provider) return connections.find((c) => c.host === null) ?? connections[0] ?? null;\n return (\n connections.find((c) => c.host === provider) ?? connections.find((c) => c.host === null) ?? null\n );\n}\n\n/** Short pt-BR \"ativo há X\" from a timestamp (agora / min / h / dias). */\nexport function activeAgo(date: Date): string {\n const minutes = Math.max(0, Math.floor((Date.now() - date.getTime()) / 60_000));\n if (minutes < 1) return \"ativo agora\";\n if (minutes < 60) return `ativo há ${minutes} min`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `ativo há ${hours} h`;\n return `ativo há ${Math.floor(hours / 24)} dias`;\n}\n\n/** The most-recently-active connection across all providers (null when none). */\nfunction mostRecent(connections: readonly AiConnection[]): AiConnection | null {\n return connections.reduce<AiConnection | null>(\n (best, c) => (!best || c.lastActiveAt.getTime() > best.lastActiveAt.getTime() ? c : best),\n null,\n );\n}\n\n/** The configured-state TITLE, naming the connected assistant(s) — FUT req (F). */\nexport function connectedTitle(\n connections: readonly AiConnection[],\n hosts: readonly AiHostGuide[],\n connectedHostId: string | undefined,\n): string {\n const providers = [...new Set(connections.map((c) => c.host).filter((h): h is AiProvider => h !== null))];\n if (providers.length === 1) return `${PROVIDER_LABEL[providers[0]!]} Conectado`;\n if (providers.length > 1) {\n return `${providers.map((p) => PROVIDER_LABEL[p]).join(\", \")} conectados`;\n }\n // Legacy connection with no attributed provider — name the completed host.\n if (connections.length > 0) return `${hostLabel(hosts, connectedHostId)} Conectado`;\n return \"IA conectada\";\n}\n\n/** The completed summary line (second line) for the configured-state header. */\nexport function connectedSummary(connections: readonly AiConnection[]): string {\n const recent = mostRecent(connections);\n if (!recent) return \"Integração configurada\";\n return activeAgo(recent.lastActiveAt);\n}\n","\"use client\";\n\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\nimport OpenInNewIcon from \"@mui/icons-material/OpenInNew\";\nimport { useEffect, useState } from \"react\";\n\nimport { type GuidedNav } from \"@12-apps/onboarding\";\nimport { Progress } from \"@12-apps/ui/data-display/Progress\";\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostConfigureStage, AiHostGuide } from \"../guide\";\nimport { activeAgo, connectionForHost, hostLabel, type AiConnection } from \"./ai-connection-utils\";\nimport {\n EndpointCopyBlock,\n HostConnectHeader,\n HostDocsLink,\n HostOpenButton,\n HostStepList,\n PromptCopyBlock,\n} from \"./host-connect-guide\";\n\n/** The host's connect steps split across the Configurar / Conectar stages. */\nconst CONFIGURE_STEP_COUNT = 3;\n\n/** How often the Confirmar step re-checks the live connection while waiting. */\nconst POLL_INTERVAL_MS = 3000;\n\n/** A step's continue/back controls (Voltar left, primary next right). */\nfunction StepNav({\n nav,\n onNext,\n nextLabel = \"Próximo\",\n nextDisabled = false,\n nextTestId,\n}: {\n nav: GuidedNav;\n onNext: () => void;\n nextLabel?: string;\n nextDisabled?: boolean;\n nextTestId?: string;\n}): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" justifyContent=\"space-between\">\n <Button variant=\"ghost\" onClick={() => nav.back()} data-testid=\"ai-step-back\">\n Voltar\n </Button>\n <Button onClick={onNext} disabled={nextDisabled} data-testid={nextTestId}>\n {nextLabel}\n </Button>\n </Stack>\n );\n}\n\n/** Step 2 — copy the store URL; copying is the action that advances the wizard. */\nexport function CopyUrlStep({ nav, endpointUrl }: { nav: GuidedNav; endpointUrl: string }): React.JSX.Element {\n return (\n <Stack spacing={3} data-testid=\"ai-copy-step\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n Copie a URL da sua loja\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n É o único dado que você cola no assistente — ao copiar, seguimos para o próximo passo.\n </Text>\n </Box>\n <EndpointCopyBlock endpointUrl={endpointUrl} copied={false} onCopy={() => nav.next()} />\n <Box>\n <Button variant=\"ghost\" onClick={() => nav.back()} data-testid=\"ai-step-back\">\n Voltar\n </Button>\n </Box>\n </Stack>\n );\n}\n\n/** Step 3 — open the host's connectors and add + configure the custom connector. */\nexport function ConfigureStep({ nav, host }: { nav: GuidedNav; host: AiHostGuide }): React.JSX.Element {\n // Hosts with no direct link (e.g. Claude Desktop) have nothing to open, so\n // \"Próximo\" is available immediately; otherwise it unlocks on the open click.\n const [opened, setOpened] = useState(!host.link);\n return (\n <Stack spacing={2.5} data-testid=\"ai-configure-step\">\n <HostConnectHeader host={host} />\n <HostOpenButton host={host} onOpen={() => setOpened(true)} />\n <HostStepList steps={host.steps.slice(0, CONFIGURE_STEP_COUNT)} start={1} />\n <HostDocsLink host={host} />\n <StepNav nav={nav} onNext={() => nav.next()} nextDisabled={!opened} nextTestId=\"ai-configure-next\" />\n </Stack>\n );\n}\n\n/**\n * One stage of a host's per-stage configuration (e.g. ChatGPT's \"enable\n * developer mode\" then \"configurar\"). Each stage has its OWN deep link — opening\n * it unlocks \"Próximo\" — and its own instructions.\n */\nexport function ConfigureStageStep({\n nav,\n host,\n stage,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n stage: AiHostConfigureStage;\n}): React.JSX.Element {\n const [opened, setOpened] = useState(!stage.link);\n return (\n <Stack spacing={2.5} data-testid={`ai-stage-${stage.id}`}>\n <HostConnectHeader host={host} />\n {stage.link && (\n <Box>\n <Button\n onClick={() => {\n window.open(stage.link!.url, \"_blank\", \"noopener,noreferrer\");\n setOpened(true);\n }}\n data-testid={`ai-stage-link-${stage.id}`}\n >\n {stage.link.label}\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n )}\n <HostStepList steps={stage.steps} start={1} />\n <HostDocsLink host={host} />\n <StepNav\n nav={nav}\n onNext={() => nav.next()}\n nextDisabled={!opened}\n nextTestId={`ai-stage-next-${stage.id}`}\n />\n </Stack>\n );\n}\n\n/** Step 4 — connect: log in, authorize and activate the connector. */\nexport function ConnectStep({\n nav,\n host,\n connectPrompt,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n connectPrompt: string;\n}): React.JSX.Element {\n return (\n <Stack spacing={2.5} data-testid=\"ai-connect-step\">\n <HostConnectHeader host={host} />\n <HostStepList steps={host.steps.slice(CONFIGURE_STEP_COUNT)} start={CONFIGURE_STEP_COUNT + 1} />\n <PromptCopyBlock\n title=\"Cole esta mensagem no assistente\"\n caption=\"Assim ele se conecta, se identifica (Claude, ChatGPT…) e registramos a conexão.\"\n message={connectPrompt}\n />\n <HostDocsLink host={host} />\n <StepNav nav={nav} onNext={() => nav.next()} nextLabel=\"Continuar\" nextTestId=\"ai-connect-done\" />\n </Stack>\n );\n}\n\n/**\n * Simplified-flow step (host has a published `pluginUrl`): open the one-click\n * plugin (install + authorize), then paste the prompt asking the assistant to\n * connect. No URL to copy, no manual connector. The next step (Confirmar) waits.\n */\nexport function InstallStep({\n nav,\n host,\n connectPrompt,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n connectPrompt: string;\n}): React.JSX.Element {\n const [opened, setOpened] = useState(false);\n return (\n <Stack spacing={2.5} data-testid=\"ai-install-step\">\n <HostConnectHeader host={host} />\n <Text variant=\"body\" as=\"p\" color=\"secondary\">\n Abra o plugin da sua loja, clique em Instalar e autorize o acesso — sem copiar URL nem gerar\n credenciais.\n </Text>\n {host.pluginUrl && (\n <Box>\n <Button\n onClick={() => {\n window.open(host.pluginUrl!, \"_blank\", \"noopener,noreferrer\");\n setOpened(true);\n }}\n data-testid=\"ai-install-open\"\n >\n Instalar o plugin da loja\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n )}\n <PromptCopyBlock\n title=\"Peça ao assistente para conectar\"\n caption=\"Cole no assistente para ele se conectar, se identificar e confirmar o acesso.\"\n message={connectPrompt}\n />\n <HostDocsLink host={host} />\n <StepNav\n nav={nav}\n onNext={() => nav.next()}\n nextLabel=\"Continuar\"\n nextDisabled={!opened}\n nextTestId=\"ai-install-done\"\n />\n </Stack>\n );\n}\n\n/**\n * Step 5: auto-detect the live connection. While waiting it polls the server\n * (the sign-in / `announceAiConnection` tool call registers the connection\n * server-side), showing a spinner — the owner never clicks \"verify\". Completes\n * when the selected host's connection appears.\n */\nexport function ConfirmStep({\n nav,\n connections,\n hosts,\n onRetest,\n}: {\n nav: GuidedNav;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n onRetest: () => void;\n}): React.JSX.Element {\n const selectedHostId = nav.data.selectedHost as string | undefined;\n const connection = connectionForHost(connections, selectedHostId);\n const label = connection?.clientName ?? hostLabel(hosts, selectedHostId);\n\n // Auto-detect: re-check on an interval until the connection shows up. The\n // interval is cleared as soon as `connection` is non-null (and on unmount).\n useEffect(() => {\n if (connection) return undefined;\n const id = setInterval(() => onRetest(), POLL_INTERVAL_MS);\n return () => clearInterval(id);\n }, [connection, onRetest]);\n\n if (connection) {\n return (\n <Stack spacing={2} data-testid=\"ai-confirm-connected\">\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <CheckCircleIcon sx={{ color: \"success.main\" }} />\n <Box>\n <Text variant=\"body\" weight=\"bold\" as=\"p\">\n {label} está conectado à sua loja.\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {activeAgo(connection.lastActiveAt)}\n </Text>\n </Box>\n </Stack>\n <Box>\n <Button onClick={() => nav.complete({ connectedHost: selectedHostId })}>Concluir</Button>\n </Box>\n </Stack>\n );\n }\n\n return (\n <Stack spacing={2.5} data-testid=\"ai-confirm-waiting\">\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <Progress variant=\"circular\" circularSize={22} thickness={4} dataTestId=\"ai-confirm-spinner\" />\n <Box>\n <Text variant=\"body\" weight=\"bold\" as=\"p\">\n Esperando conexão\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n Assim que você autorizar o acesso no {label}, ela aparece aqui automaticamente.\n </Text>\n </Box>\n </Stack>\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"ghost\" size=\"sm\" onClick={onRetest} data-testid=\"ai-confirm-retest\">\n Testar agora\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => nav.back()}>\n Voltar\n </Button>\n </Stack>\n </Stack>\n );\n}\n","\"use client\";\n\nimport CheckIcon from \"@mui/icons-material/Check\";\nimport ContentCopyOutlinedIcon from \"@mui/icons-material/ContentCopyOutlined\";\nimport OpenInNewIcon from \"@mui/icons-material/OpenInNew\";\nimport { useState } from \"react\";\n\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\nimport { McpEndpointUrl } from \"./mcp-endpoint-url\";\n\n/**\n * The store's MCP endpoint URL with a blue \"Copiar\" button (the display-only\n * field defers the copy to this button). Controlled: `copied` flips the label to\n * \"Copiado\" and `onCopy` fires after the clipboard write — the wizard uses it to\n * unlock the \"Próximo\" button on the Copiar-URL step.\n */\nexport function EndpointCopyBlock({\n endpointUrl,\n copied,\n onCopy,\n}: {\n endpointUrl: string;\n copied: boolean;\n onCopy: () => void;\n}): React.JSX.Element {\n const handleClick = (): void => {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(endpointUrl).catch(() => undefined);\n }\n onCopy();\n };\n\n return (\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n border: 1,\n borderColor: \"primary.main\",\n bgcolor: \"action.hover\",\n }}\n >\n <Text variant=\"caption\" as=\"p\" weight=\"bold\">\n URL do servidor da sua loja\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n Copie esta URL e cole no seu assistente para conectá-lo à loja.\n </Text>\n <Box sx={{ mt: 1 }}>\n <McpEndpointUrl url={endpointUrl} copyable={false} />\n </Box>\n <Box sx={{ mt: 1.5 }}>\n <Button onClick={handleClick} data-testid=\"ai-copy-endpoint\">\n {copied ? (\n <CheckIcon sx={{ fontSize: 18, mr: 0.5 }} />\n ) : (\n <ContentCopyOutlinedIcon sx={{ fontSize: 18, mr: 0.5 }} />\n )}\n {copied ? \"Copiado\" : \"Copiar URL\"}\n </Button>\n </Box>\n </Box>\n );\n}\n\n/**\n * A copyable multi-line message block (preserves line breaks). Used on the\n * Conectar step for the prompt the owner pastes into the assistant so it\n * identifies itself and calls a tool (which registers the connection).\n */\nexport function PromptCopyBlock({\n title,\n caption,\n message,\n}: {\n title: string;\n caption: string;\n message: string;\n}): React.JSX.Element {\n const [copied, setCopied] = useState(false);\n\n const handleClick = (): void => {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(message).catch(() => undefined);\n }\n setCopied(true);\n };\n\n return (\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n border: 1,\n borderColor: \"primary.main\",\n bgcolor: \"action.hover\",\n }}\n >\n <Text variant=\"caption\" as=\"p\" weight=\"bold\">\n {title}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {caption}\n </Text>\n <Box\n sx={{\n mt: 1,\n p: 1.5,\n borderRadius: 1,\n border: 1,\n borderColor: \"divider\",\n bgcolor: \"background.paper\",\n whiteSpace: \"pre-line\",\n }}\n >\n <Text variant=\"body\" size=\"sm\" as=\"p\">\n {message}\n </Text>\n </Box>\n <Box sx={{ mt: 1.5 }}>\n <Button onClick={handleClick} data-testid=\"ai-copy-prompt\">\n {copied ? (\n <CheckIcon sx={{ fontSize: 18, mr: 0.5 }} />\n ) : (\n <ContentCopyOutlinedIcon sx={{ fontSize: 18, mr: 0.5 }} />\n )}\n {copied ? \"Copiado\" : \"Copiar mensagem\"}\n </Button>\n </Box>\n </Box>\n );\n}\n\n/** The brand mark + \"Conectar no <host>\" header shared by the connect sub-steps. */\nexport function HostConnectHeader({ host }: { host: AiHostGuide }): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <HostBrandAvatar brand={host.brand} size={36} />\n <Text variant=\"heading\" size=\"sm\" as=\"h3\">\n Conectar no {host.label}\n </Text>\n </Stack>\n );\n}\n\n/**\n * The primary direct-link button to a host's connector settings (nothing when it\n * has none). `onOpen` fires after the link opens so the Configurar step can\n * unlock its \"Próximo\" only once the owner has actually gone to the connectors.\n */\nexport function HostOpenButton({\n host,\n onOpen,\n}: {\n host: AiHostGuide;\n onOpen?: () => void;\n}): React.JSX.Element | null {\n if (!host.link) return null;\n return (\n <Box>\n <Button\n onClick={() => {\n window.open(host.link!.url, \"_blank\", \"noopener,noreferrer\");\n onOpen?.();\n }}\n data-testid={`ai-host-link-${host.id}`}\n >\n {host.link.label}\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n );\n}\n\n/** A \"Para mais informações\" reference to the host's official connector docs. */\nexport function HostDocsLink({ host }: { host: AiHostGuide }): React.JSX.Element | null {\n if (!host.docs) return null;\n return (\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n Para mais informações, consulte a{\" \"}\n <Box\n component=\"a\"\n href={host.docs.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid={`ai-host-docs-${host.id}`}\n sx={{ color: \"primary.main\", textDecoration: \"underline\" }}\n >\n {host.docs.label}\n </Box>\n .\n </Text>\n );\n}\n\n/**\n * A numbered slice of a host's connect steps. `start` keeps the numbering\n * continuous when the steps are split across wizard stages (e.g. the Conectar\n * stage continues at 4 after Configurar showed 1–3).\n */\nexport function HostStepList({\n steps,\n start = 1,\n}: {\n steps: readonly string[];\n start?: number;\n}): React.JSX.Element {\n return (\n <Box component=\"ol\" start={start} sx={{ m: 0, pl: 3 }}>\n {steps.map((step, index) => (\n <Box component=\"li\" key={index} sx={{ mb: 1 }}>\n <Text variant=\"body\" as=\"span\">\n {step}\n </Text>\n </Box>\n ))}\n </Box>\n );\n}\n","\"use client\";\n\nimport { Code } from \"@12-apps/ui/typography/Code\";\n\n/**\n * The store's MCP endpoint URL. Client component because the copy interaction\n * needs the browser clipboard — the `@12-apps/ui` Code component provides the copy\n * affordance (`copyable`). Pass `copyable={false}` for a display-only field when\n * an external control owns the copy action (e.g. the connect flow's blue Copiar\n * button, which also gates the following steps on the copy).\n */\nexport function McpEndpointUrl({\n url,\n copyable = true,\n}: {\n url: string;\n copyable?: boolean;\n}): React.JSX.Element {\n return (\n <Code variant=\"block\" copyable={copyable} data-testid=\"mcp-endpoint-url\">\n {url}\n </Code>\n );\n}\n","\"use client\";\n\nimport AddLinkOutlinedIcon from \"@mui/icons-material/AddLinkOutlined\";\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\nimport LinkOffOutlinedIcon from \"@mui/icons-material/LinkOffOutlined\";\nimport MenuBookOutlinedIcon from \"@mui/icons-material/MenuBookOutlined\";\n\nimport { ConfirmButton } from \"@12-apps/ui/feedback/ConfirmAction\";\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\n\n/**\n * Revoke a host's access. Returning a promise holds the confirmation popup in\n * its pending state until the write settles, and a rejection keeps it open\n * carrying the reason — so the owner sees the disconnect finish or fail.\n */\nexport type DisconnectHandler = (hostId: string) => void | Promise<unknown>;\n\n/** One assistant's connection state. */\nexport interface HostStatus {\n host: AiHostGuide;\n connected: boolean;\n /** Freeform activity line for a connected host (e.g. \"ativo há 3 min\"). */\n detail?: string;\n}\n\n/**\n * The right-hand side of a CONNECTED box: the green pill, then the two things\n * the pill alone left the owner unable to do.\n *\n * \"Instruções\" exists because the setup steps were reachable ONLY from a RED\n * card's \"Conectar\" — so on an all-green board there was no way to re-read how\n * any of them was connected, which is exactly when someone re-doing the setup on\n * a second machine needs them. It re-enters the same flow that button does.\n *\n * \"Desconectar\" is only drawn when the app supplies a revoke path: a board with\n * nowhere to send the revoke must not offer a button that does nothing.\n */\nfunction ConnectedControls({\n host,\n onConnect,\n onDisconnect,\n}: {\n host: AiHostGuide;\n onConnect: (hostId: string) => void;\n onDisconnect?: DisconnectHandler;\n}): React.JSX.Element {\n return (\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n justifyContent=\"flex-end\"\n // Wraps rather than squeezing: three controls do not fit a half-width\n // card at every breakpoint.\n sx={{ flexShrink: 0, flexWrap: \"wrap\", rowGap: 0.5 }}\n >\n <Box\n sx={{\n px: 1,\n py: 0.25,\n borderRadius: 999,\n bgcolor: \"success.main\",\n color: \"success.contrastText\",\n }}\n >\n <Text variant=\"caption\" weight=\"bold\" as=\"span\">\n Conectado\n </Text>\n </Box>\n <Button\n variant=\"text\"\n size=\"sm\"\n onClick={() => onConnect(host.id)}\n data-testid={`ai-status-instructions-${host.id}`}\n >\n <MenuBookOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n Instruções\n </Button>\n {onDisconnect ? (\n <ConfirmButton\n variant=\"outline\"\n color=\"danger\"\n size=\"sm\"\n onClick={() => onDisconnect(host.id)}\n confirm={{\n title: \"Desconectar o assistente?\",\n entityName: host.label,\n description:\n \"Ele perde o acesso à sua loja na hora. Para voltar a usar, será preciso conectar de novo.\",\n confirmText: \"Desconectar\",\n dataTestId: `ai-status-disconnect-confirm-${host.id}`,\n }}\n data-testid={`ai-status-disconnect-${host.id}`}\n >\n <LinkOffOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n Desconectar\n </ConfirmButton>\n ) : null}\n </Stack>\n );\n}\n\n/** A single green (connected) / red (to connect) status box for one assistant. */\nfunction StatusBox({\n status,\n onConnect,\n onDisconnect,\n}: {\n status: HostStatus;\n onConnect: (hostId: string) => void;\n onDisconnect?: DisconnectHandler;\n}): React.JSX.Element {\n const { host, connected, detail } = status;\n return (\n <Box\n data-testid={`ai-status-${host.id}`}\n data-connected={connected}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n p: 2,\n borderRadius: 3,\n border: 1,\n borderColor: connected ? \"success.main\" : \"error.main\",\n bgcolor: \"background.paper\",\n }}\n >\n <HostBrandAvatar brand={host.brand} size={36} />\n <Box sx={{ minWidth: 0, flexGrow: 1 }}>\n <Stack direction=\"row\" spacing={0.75} alignItems=\"center\">\n <Text variant=\"body\" weight=\"bold\" as=\"span\">\n {host.label}\n </Text>\n {connected ? <CheckCircleIcon sx={{ fontSize: 18, color: \"success.main\" }} /> : null}\n </Stack>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {connected ? (detail ?? \"Conectado\") : \"Ainda não conectado\"}\n </Text>\n </Box>\n {connected ? (\n <ConnectedControls host={host} onConnect={onConnect} onDisconnect={onDisconnect} />\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onConnect(host.id)}\n data-testid={`ai-status-connect-${host.id}`}\n >\n <AddLinkOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n Conectar\n </Button>\n )}\n </Box>\n );\n}\n\n/**\n * The completed-state status board for the AI integration: every assistant as a\n * box — green when connected, red when still to connect (with a \"Conectar\"\n * button that re-enters the guided flow for that host). Each connection is\n * attributed to its provider (derived from the OAuth client + confirmed by\n * `announceAiConnection`), so several assistants can show connected at once.\n *\n * A connected box carries two more controls, because the pill it used to show\n * alone was a dead end in both directions: \"Instruções\" re-enters the host's\n * setup steps (previously reachable only from a RED card, so an all-green board\n * hid them entirely), and \"Desconectar\" — when the app passes `onDisconnect` —\n * revokes access, which nothing in the UI could do at all.\n */\nexport function AiStatusBoard({\n statuses,\n onConnect,\n onDisconnect,\n}: {\n statuses: readonly HostStatus[];\n onConnect: (hostId: string) => void;\n /** Revoke this host's access. Omit to render a read-only board. */\n onDisconnect?: DisconnectHandler;\n}): React.JSX.Element {\n return (\n <Stack spacing={2} data-testid=\"ai-status-board\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n Assistentes conectados\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n Em verde os que já operam a sua loja; em vermelho os que faltam conectar.\n </Text>\n </Box>\n <Box\n sx={{\n display: \"grid\",\n gap: 2,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\n }}\n >\n {statuses.map((status) => (\n <StatusBox\n key={status.host.id}\n status={status}\n onConnect={onConnect}\n onDisconnect={onDisconnect}\n />\n ))}\n </Box>\n </Stack>\n );\n}\n","\"use client\";\n\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\n\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\n\n/** One selectable assistant card (brand mark + name + kind, checked when active). */\nfunction HostCard({\n host,\n active,\n onSelect,\n}: {\n host: AiHostGuide;\n active: boolean;\n onSelect: () => void;\n}): React.JSX.Element {\n return (\n <Box\n component=\"button\"\n type=\"button\"\n onClick={onSelect}\n aria-pressed={active}\n data-testid={`ai-host-card-${host.id}`}\n sx={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n p: 2,\n borderRadius: 3,\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n border: 2,\n borderColor: active ? \"primary.main\" : \"divider\",\n bgcolor: active ? \"action.selected\" : \"background.paper\",\n transition: (theme) => theme.transitions.create([\"border-color\", \"background-color\"]),\n \"&:hover\": { borderColor: \"primary.main\" },\n }}\n >\n <HostBrandAvatar brand={host.brand} size={40} />\n <Box sx={{ minWidth: 0 }}>\n <Text variant=\"body\" weight=\"bold\" as=\"span\">\n {host.label}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {host.kind}\n </Text>\n </Box>\n {active && (\n <CheckCircleIcon\n sx={{ position: \"absolute\", top: 10, right: 10, fontSize: 20, color: \"primary.main\" }}\n />\n )}\n </Box>\n );\n}\n\n/**\n * Step 1 of the guided AI connect flow: the owner picks a single assistant\n * (Claude.ai, Claude Desktop, ChatGPT, Codex) from a card grid. Picking a card\n * advances straight to the next step — no separate \"Próximo\" button. Selection\n * is controlled (persisted by the onboarding flow) so a refresh resumes with the\n * same assistant highlighted.\n */\nexport function HostSelectStep({\n hosts,\n selectedId,\n onSelect,\n}: {\n hosts: readonly AiHostGuide[];\n selectedId: string | null;\n onSelect: (hostId: string) => void;\n}): React.JSX.Element {\n return (\n <Stack spacing={3} data-testid=\"ai-host-select\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n Escolha o seu assistente\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n Selecione onde você usa a IA — o passo a passo é feito sob medida para ele.\n </Text>\n </Box>\n\n <Box\n sx={{\n display: \"grid\",\n gap: 2,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\n }}\n >\n {hosts.map((host) => (\n <HostCard\n key={host.id}\n host={host}\n active={host.id === selectedId}\n onSelect={() => onSelect(host.id)}\n />\n ))}\n </Box>\n </Stack>\n );\n}\n","\"use client\";\n\nimport { type GuidedNav, type GuidedStep } from \"@12-apps/onboarding\";\n\nimport { providerForHostId, type AiHostGuide } from \"../guide\";\nimport { activeAgo, resolveHost, type AiConnection } from \"./ai-connection-utils\";\nimport {\n ConfigureStageStep,\n ConfigureStep,\n ConfirmStep,\n ConnectStep,\n CopyUrlStep,\n InstallStep,\n} from \"./ai-flow-steps\";\nimport { AiStatusBoard, type DisconnectHandler, type HostStatus } from \"./ai-status-board\";\nimport { HostSelectStep } from \"./host-select-step\";\n\nexport type { AiConnection } from \"./ai-connection-utils\";\nexport { connectedSummary, connectedTitle } from \"./ai-connection-utils\";\n\n/** The completed status board: green for each connected host, red for the rest. */\nexport function StatusBoard({\n nav,\n connections,\n hosts,\n onDisconnect,\n}: {\n nav: GuidedNav;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n onDisconnect?: DisconnectHandler;\n}): React.JSX.Element {\n const legacyHostId = (nav.data.connectedHost ?? nav.data.selectedHost) as string | undefined;\n\n const statuses: HostStatus[] = hosts.map((host) => {\n const provider = providerForHostId(host.id);\n // Prefer a provider-attributed connection; fall back to a legacy null-host\n // connection only for the host the owner completed the flow with.\n const connection =\n (provider ? connections.find((c) => c.host === provider) : undefined) ??\n (host.id === legacyHostId ? connections.find((c) => c.host === null) : undefined) ??\n null;\n return {\n host,\n connected: connection !== null,\n detail: connection ? activeAgo(connection.lastActiveAt) : undefined,\n };\n });\n\n /** Re-enter this host's setup — the manual copy path, or its one-click install. */\n const goToConnect = (hostId: string): void => {\n nav.goTo(hosts.find((h) => h.id === hostId)?.pluginUrl ? \"install\" : \"copy\", {\n selectedHost: hostId,\n });\n };\n\n /**\n * Disconnecting the LAST assistant leaves the section configured with nothing\n * configured: a collapsed \"IA conectada\" summary hiding an all-red board, with\n * the setup instructions two clicks away. So when the revoke empties the\n * board, walk straight back into that host's instructions — the owner who just\n * cut an assistant off is the likeliest person to reconnect one, and the steps\n * are the only thing left worth showing.\n *\n * Cutting one of SEVERAL leaves the board meaningful, so it stays put.\n * `statuses` is the pre-revoke picture, which is what makes \"was that the last\n * one?\" answerable here without waiting for the app to re-read.\n */\n const disconnect: DisconnectHandler | undefined = onDisconnect\n ? async (hostId) => {\n await onDisconnect(hostId);\n const revoked = providerForHostId(hostId);\n const othersLive = statuses.some(\n (status) => status.connected && providerForHostId(status.host.id) !== revoked,\n );\n if (!othersLive) goToConnect(hostId);\n }\n : undefined;\n\n return (\n <AiStatusBoard statuses={statuses} onConnect={goToConnect} onDisconnect={disconnect} />\n );\n}\n\n/** The first step (host picker) — picking a card advances to the right path. */\nfunction selectStep(hosts: readonly AiHostGuide[]): GuidedStep {\n return {\n id: \"select\",\n label: \"Escolher\",\n render: (nav: GuidedNav) => (\n <HostSelectStep\n hosts={hosts}\n selectedId={(nav.data.selectedHost as string | undefined) ?? null}\n onSelect={(hostId) =>\n nav.goTo(hosts.find((h) => h.id === hostId)?.pluginUrl ? \"install\" : \"copy\", {\n selectedHost: hostId,\n })\n }\n />\n ),\n };\n}\n\n/** The Copiar-URL step, shared by every manual flow. */\nfunction copyStep(endpointUrl: string): GuidedStep {\n return {\n id: \"copy\",\n label: \"Copiar URL\",\n render: (nav: GuidedNav) => <CopyUrlStep nav={nav} endpointUrl={endpointUrl} />,\n };\n}\n\n/**\n * The middle steps for the full manual flow. A host with `configureStages`\n * (e.g. ChatGPT) gets one step per stage — each with its own deep link — after\n * Copiar URL; otherwise the default copy → configure → connect split.\n */\nfunction manualMiddle(\n host: AiHostGuide,\n hosts: readonly AiHostGuide[],\n endpointUrl: string,\n connectPrompt: string,\n): GuidedStep[] {\n if (host.configureStages && host.configureStages.length > 0) {\n return [\n copyStep(endpointUrl),\n ...host.configureStages.map((stage) => ({\n id: stage.id,\n label: stage.label,\n render: (nav: GuidedNav) => (\n <ConfigureStageStep nav={nav} host={resolveHost(hosts, nav.data.selectedHost)} stage={stage} />\n ),\n })),\n ];\n }\n return [\n copyStep(endpointUrl),\n {\n id: \"configure\",\n label: \"Configurar\",\n render: (nav: GuidedNav) => <ConfigureStep nav={nav} host={resolveHost(hosts, nav.data.selectedHost)} />,\n },\n {\n id: \"connect\",\n label: \"Conectar\",\n render: (nav: GuidedNav) => (\n <ConnectStep nav={nav} host={resolveHost(hosts, nav.data.selectedHost)} connectPrompt={connectPrompt} />\n ),\n },\n ];\n}\n\n/** The single middle step for the simplified plugin flow: install. */\nfunction simpleMiddle(hosts: readonly AiHostGuide[], connectPrompt: string): GuidedStep[] {\n return [\n {\n id: \"install\",\n label: \"Instalar\",\n render: (nav: GuidedNav) => (\n <InstallStep nav={nav} host={resolveHost(hosts, nav.data.selectedHost)} connectPrompt={connectPrompt} />\n ),\n },\n ];\n}\n\n/**\n * Build the wizard's steps for the selected host's path: the simplified\n * `install` flow when the host has a published `pluginUrl`, the per-stage flow\n * when it declares `configureStages`, otherwise the full copy → configure →\n * connect flow. `select` and `confirm` bookend all of them.\n */\nexport function buildFlowSteps(opts: {\n host: AiHostGuide;\n hosts: readonly AiHostGuide[];\n endpointUrl: string;\n connectPrompt: string;\n connections: readonly AiConnection[];\n onRetest: () => void;\n}): GuidedStep[] {\n const { host, hosts, endpointUrl, connectPrompt, connections, onRetest } = opts;\n const middle = host.pluginUrl\n ? simpleMiddle(hosts, connectPrompt)\n : manualMiddle(host, hosts, endpointUrl, connectPrompt);\n const confirm: GuidedStep = {\n id: \"confirm\",\n label: \"Confirmar\",\n render: (nav: GuidedNav) => (\n <ConfirmStep nav={nav} connections={connections} hosts={hosts} onRetest={onRetest} />\n ),\n };\n return [selectStep(hosts), ...middle, confirm];\n}\n"],"mappings":";;;;;;;;;;;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;;;ACNP,OAAO,sBAAsB;AAC7B,OAAO,0BAA0B;AACjC,OAAO,0BAA0B;AACjC,OAAO,8BAA8B;AAErC,SAAS,cAAc;AACvB,SAAS,OAAAA,YAAW;AACpB,SAAS,SAAAC,cAAa;AACtB,SAAS,QAAAC,aAAY;;;ACVrB,SAAS,OAAAC,YAAW;AACpB,SAAS,YAAY;;;ACDrB,OAAO,qBAAqB;AAC5B,OAAO,kBAAkB;AACzB,OAAO,aAAa;AACpB,OAAO,oBAAoB;AAC3B,OAAO,oBAAoB;AAC3B,OAAO,qBAAqB;AAE5B,SAAS,WAAW;AAwCd;AA7BN,IAAM,QAA0F;AAAA,EAC9F,QAAQ,EAAE,IAAI,WAAW,MAAM,iBAAiB,OAAO,qBAAqB;AAAA,EAC5E,QAAQ,EAAE,IAAI,WAAW,MAAM,SAAS,OAAO,SAAS;AAC1D;AAGO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,OAAO;AACT,GAGsB;AACpB,QAAM,EAAE,IAAI,MAAM,MAAM,IAAI,MAAM,KAAK;AACvC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAY;AAAA,MACZ,IAAI;AAAA,QACF,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,SAAS;AAAA,QACT,OAAO;AAAA,QACP,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,YAAY;AAAA,MACd;AAAA,MAEA,8BAAC,QAAK,IAAI,EAAE,UAAU,OAAO,KAAK,GAAG;AAAA;AAAA,EACvC;AAEJ;AA1BgB;AA4BhB,IAAM,kBAA0D;AAAA,EAC9D,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAGO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,WAAW;AACb,GAGsB;AACpB,QAAM,OAAO,gBAAgB,EAAE,KAAK;AACpC,SAAO,oBAAC,QAAK,IAAI,EAAE,SAAS,GAAG;AACjC;AATgB;;;ADnDZ,SA2BI,OAAAC,MA3BJ;AAFJ,SAAS,eAAe,EAAE,WAAW,GAAoD;AACvF,SACE;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,eAAa,iBAAiB,WAAW,EAAE;AAAA,MAC3C,IAAI;AAAA,QACF,GAAG;AAAA,QACH,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,SAAS;AAAA,QACT,QAAQ;AAAA;AAAA,QAER,YAAY;AAAA,QACZ,WAAW,EAAE,aAAa,gBAAgB,WAAW,GAAG,WAAW,mBAAmB;AAAA,MACxF;AAAA,MAEA;AAAA,wBAAAD;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,IAAI;AAAA,cACF,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,cAAc;AAAA,cACd,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,gBAAgB;AAAA,cAChB,SAAS;AAAA,cACT,OAAO;AAAA,cACP,IAAI;AAAA,YACN;AAAA,YAEA,0BAAAD,KAAC,kBAAe,IAAI,WAAW,IAAI,UAAU,IAAI;AAAA;AAAA,QACnD;AAAA,QACA,gBAAAA,KAAC,QAAK,SAAQ,QAAO,QAAO,QAAO,IAAG,MACnC,qBAAW,OACd;AAAA,QACA,gBAAAA;AAAA,UAACC;AAAA,UAAA;AAAA,YACC,eAAa,wBAAwB,WAAW,EAAE;AAAA,YAClD,IAAI;AAAA,cACF,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,cAAc;AAAA,cACd,wBAAwB;AAAA,cACxB,SAAS;AAAA,cACT,QAAQ;AAAA,cACR,aAAa;AAAA,YACf;AAAA,YAEA,0BAAAD,KAAC,QAAK,SAAQ,QAAO,MAAK,MAAK,IAAG,KAAI,OAAM,aACzC,qBAAW,QACd;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AArDS;AA6DF,SAAS,eAAe;AAAA,EAC7B,eAAe;AACjB,GAEsB;AACpB,SACE,qBAACC,MAAA,EAAI,eAAY,0BAAyB,IAAI,EAAE,OAAO,OAAO,GAC5D;AAAA,yBAACA,MAAA,EAAI,IAAI,EAAE,IAAI,EAAE,GACf;AAAA,sBAAAD,KAAC,QAAK,SAAQ,WAAU,MAAK,MAAK,IAAG,MAAK,gDAE1C;AAAA,MACA,gBAAAA,KAACC,MAAA,EAAI,IAAI,EAAE,IAAI,IAAI,GACjB,0BAAAD,KAAC,QAAK,SAAQ,QAAO,MAAK,MAAK,IAAG,KAAI,OAAM,aAAY,iFAExD,GACF;AAAA,OACF;AAAA,IACA,gBAAAA;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,SAAS;AAAA,UACT,KAAK;AAAA,UACL,qBAAqB,EAAE,IAAI,OAAO,IAAI,WAAW,IAAI,iBAAiB;AAAA,QACxE;AAAA,QAEC,uBAAa,IAAI,CAAC,eACjB,gBAAAD,KAAC,kBAAmC,cAAf,WAAW,EAA4B,CAC7D;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AA9BgB;;;AEpEhB,SAAS,OAAAE,YAAW;AACpB,SAAS,aAAa;AACtB,SAAS,QAAAC,aAAY;AAgBf,gBAAAC,MAiBA,QAAAC,aAjBA;AAHC,SAAS,aAAa,EAAE,MAAM,OAAO,QAAQ,GAAwC;AAC1F,SACE,gBAAAA,MAAC,SAAM,WAAU,OAAM,SAAS,KAAK,YAAW,cAC9C;AAAA,oBAAAD;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,gBAAgB;AAAA,UAChB,SAAS;AAAA,UACT,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,YAAY;AAAA,QACd;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,IACA,gBAAAD,MAACC,MAAA,EACC;AAAA,sBAAAF,KAACG,OAAA,EAAK,SAAQ,QAAO,MAAK,MAAK,QAAO,QAAO,IAAG,KAC7C,iBACH;AAAA,MACA,gBAAAH,KAACG,OAAA,EAAK,SAAQ,WAAU,OAAM,aAAY,IAAG,KAC1C,mBACH;AAAA,OACF;AAAA,KACF;AAEJ;AA9BgB;;;AHEN,gBAAAC,MAqBJ,QAAAC,aArBI;AADV,IAAM,WAA+B;AAAA,EACnC,EAAE,MAAM,gBAAAD,KAAC,wBAAqB,GAAI,OAAO,8BAA2B,SAAS,mCAAmC;AAAA,EAChH,EAAE,MAAM,gBAAAA,KAAC,oBAAiB,GAAI,OAAO,qBAAqB,SAAS,4BAA4B;AAAA,EAC/F,EAAE,MAAM,gBAAAA,KAAC,4BAAyB,GAAI,OAAO,4BAAsB,SAAS,sCAAgC;AAAA,EAC5G,EAAE,MAAM,gBAAAA,KAAC,wBAAqB,GAAI,OAAO,oBAAoB,SAAS,yBAAyB;AACjG;AAGA,SAAS,KAAK,EAAE,QAAQ,GAA+C;AACrE,SACE,gBAAAC,MAACC,QAAA,EAAM,SAAS,KAAK,IAAI,EAAE,UAAU,IAAI,GACvC;AAAA,oBAAAF;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,eAAe;AAAA,UACf,eAAe;AAAA,QACjB;AAAA,QACD;AAAA;AAAA,IAED;AAAA,IACA,gBAAAF,MAACG,OAAA,EAAK,SAAQ,WAAU,MAAK,MAAK,QAAO,QAAO,IAAG,MAAK;AAAA;AAAA,MAC9C;AAAA,MACR,gBAAAJ,KAACG,MAAA,EAAI,WAAU,QAAO,IAAI,EAAE,OAAO,eAAe,GAAG,+BAErD;AAAA,MAAO;AAAA,MAAI;AAAA,OAEb;AAAA,IACA,gBAAAH,KAACI,OAAA,EAAK,SAAQ,QAAO,OAAM,aAAY,IAAG,KAAI,0NAI9C;AAAA,IACA,gBAAAJ,KAACG,MAAA,EAAI,IAAI,EAAE,IAAI,EAAE,GACf,0BAAAH,KAAC,UAAO,SAAS,SAAS,eAAY,oBAAmB,+BAEzD,GACF;AAAA,KACF;AAEJ;AAjCS;AAyCF,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,kBAAkB;AAAA,EAClB,eAAe;AACjB,GAIsB;AACpB,SACE,gBAAAC,MAACC,QAAA,EAAM,SAAS,GAAG,eAAY,cAC7B;AAAA,oBAAAF,KAAC,QAAK,SAAkB;AAAA,IAExB,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAW;AAAA,QACX,eAAY;AAAA,QACZ,IAAI;AAAA,UACF,GAAG;AAAA,UACH,cAAc;AAAA,UACd,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,QACf;AAAA,QAEA;AAAA,0BAAAF,KAAC,4BAAyB,IAAI,EAAE,OAAO,gBAAgB,IAAI,KAAK,GAAG;AAAA,UACnE,gBAAAA,KAACI,OAAA,EAAK,SAAQ,QAAO,IAAG,KACrB,2BACH;AAAA;AAAA;AAAA,IACF;AAAA,IAEA,gBAAAJ;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,GAAG,EAAE,IAAI,KAAK,IAAI,EAAE;AAAA,UACpB,cAAc;AAAA,UACd,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,aAAa;AAAA,QACf;AAAA,QAEA,0BAAAH;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,IAAI;AAAA,cACF,SAAS;AAAA,cACT,KAAK;AAAA,cACL,qBAAqB,EAAE,IAAI,OAAO,IAAI,WAAW,IAAI,iBAAiB;AAAA,YACxE;AAAA,YAEC,mBAAS,IAAI,CAAC,MACb,gBAAAH,KAAC,gBAA2B,MAAM,EAAE,MAAM,OAAO,EAAE,OAAO,SAAS,EAAE,WAAlD,EAAE,KAAyD,CAC/E;AAAA;AAAA,QACH;AAAA;AAAA,IACF;AAAA,IAEA,gBAAAA,KAACG,MAAA,EACC,0BAAAH,KAAC,kBAAe,cAA4B,GAC9C;AAAA,KACF;AAEJ;AA3DgB;;;AI3ChB,IAAM,iBAA6C;AAAA,EACjD,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AACT;AAGO,SAAS,YAAY,OAA+B,QAA8B;AACvF,QAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,KAAK,MAAM,CAAC;AAC3D,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,4CAA4C;AACxE,SAAO;AACT;AAJgB;AAOT,SAAS,UAAU,OAA+B,QAAyB;AAChF,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,GAAG,SAAS;AACtD;AAFgB;AAST,SAAS,kBACd,aACA,QACqB;AACrB,QAAM,WAAW,OAAO,WAAW,WAAW,kBAAkB,MAAM,IAAI;AAC1E,MAAI,CAAC,SAAU,QAAO,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK,YAAY,CAAC,KAAK;AACpF,SACE,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,KAAK,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,KAAK;AAEhG;AATgB;AAYT,SAAS,UAAU,MAAoB;AAC5C,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,IAAI,IAAI,KAAK,QAAQ,KAAK,GAAM,CAAC;AAC9E,MAAI,UAAU,EAAG,QAAO;AACxB,MAAI,UAAU,GAAI,QAAO,eAAY,OAAO;AAC5C,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,MAAI,QAAQ,GAAI,QAAO,eAAY,KAAK;AACxC,SAAO,eAAY,KAAK,MAAM,QAAQ,EAAE,CAAC;AAC3C;AAPgB;AAUhB,SAAS,WAAW,aAA2D;AAC7E,SAAO,YAAY;AAAA,IACjB,CAAC,MAAM,MAAO,CAAC,QAAQ,EAAE,aAAa,QAAQ,IAAI,KAAK,aAAa,QAAQ,IAAI,IAAI;AAAA,IACpF;AAAA,EACF;AACF;AALS;AAQF,SAAS,eACd,aACA,OACA,iBACQ;AACR,QAAM,YAAY,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAuB,MAAM,IAAI,CAAC,CAAC;AACxG,MAAI,UAAU,WAAW,EAAG,QAAO,GAAG,eAAe,UAAU,CAAC,CAAE,CAAC;AACnE,MAAI,UAAU,SAAS,GAAG;AACxB,WAAO,GAAG,UAAU,IAAI,CAAC,MAAM,eAAe,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,EAC9D;AAEA,MAAI,YAAY,SAAS,EAAG,QAAO,GAAG,UAAU,OAAO,eAAe,CAAC;AACvE,SAAO;AACT;AAbgB;AAgBT,SAAS,iBAAiB,aAA8C;AAC7E,QAAM,SAAS,WAAW,WAAW;AACrC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,UAAU,OAAO,YAAY;AACtC;AAJgB;;;ACzFhB,OAAO,qBAAqB;AAC5B,OAAOK,oBAAmB;AAC1B,SAAS,WAAW,YAAAC,iBAAgB;AAGpC,SAAS,gBAAgB;AACzB,SAAS,UAAAC,eAAc;AACvB,SAAS,OAAAC,YAAW;AACpB,SAAS,SAAAC,cAAa;AACtB,SAAS,QAAAC,aAAY;;;ACTrB,OAAO,eAAe;AACtB,OAAO,6BAA6B;AACpC,OAAO,mBAAmB;AAC1B,SAAS,gBAAgB;AAEzB,SAAS,UAAAC,eAAc;AACvB,SAAS,OAAAC,YAAW;AACpB,SAAS,SAAAC,cAAa;AACtB,SAAS,QAAAC,aAAY;;;ACRrB,SAAS,YAAY;AAiBjB,gBAAAC,YAAA;AARG,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,WAAW;AACb,GAGsB;AACpB,SACE,gBAAAA,KAAC,QAAK,SAAQ,SAAQ,UAAoB,eAAY,oBACnD,eACH;AAEJ;AAZgB;;;ADqCV,gBAAAC,MAUE,QAAAC,aAVF;AA1BC,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,QAAM,cAAc,6BAAY;AAC9B,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW;AAC3D,WAAK,UAAU,UAAU,UAAU,WAAW,EAAE,MAAM,MAAM,MAAS;AAAA,IACvE;AACA,WAAO;AAAA,EACT,GALoB;AAOpB,SACE,gBAAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,IAAI;AAAA,QACF,GAAG;AAAA,QACH,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MAEA;AAAA,wBAAAF,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,QAAO,QAAO,yCAE7C;AAAA,QACA,gBAAAH,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY,mFAEjD;AAAA,QACA,gBAAAH,KAACE,MAAA,EAAI,IAAI,EAAE,IAAI,EAAE,GACf,0BAAAF,KAAC,kBAAe,KAAK,aAAa,UAAU,OAAO,GACrD;AAAA,QACA,gBAAAA,KAACE,MAAA,EAAI,IAAI,EAAE,IAAI,IAAI,GACjB,0BAAAD,MAACG,SAAA,EAAO,SAAS,aAAa,eAAY,oBACvC;AAAA,mBACC,gBAAAJ,KAAC,aAAU,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG,IAE1C,gBAAAA,KAAC,2BAAwB,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,UAEzD,SAAS,YAAY;AAAA,WACxB,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;AA/CgB;AAsDT,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,cAAc,6BAAY;AAC9B,QAAI,OAAO,cAAc,eAAe,UAAU,WAAW;AAC3D,WAAK,UAAU,UAAU,UAAU,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,IACnE;AACA,cAAU,IAAI;AAAA,EAChB,GALoB;AAOpB,SACE,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,IAAI;AAAA,QACF,GAAG;AAAA,QACH,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MAEA;AAAA,wBAAAF,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,QAAO,QACnC,iBACH;AAAA,QACA,gBAAAH,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAClC,mBACH;AAAA,QACA,gBAAAH;AAAA,UAACE;AAAA,UAAA;AAAA,YACC,IAAI;AAAA,cACF,IAAI;AAAA,cACJ,GAAG;AAAA,cACH,cAAc;AAAA,cACd,QAAQ;AAAA,cACR,aAAa;AAAA,cACb,SAAS;AAAA,cACT,YAAY;AAAA,YACd;AAAA,YAEA,0BAAAF,KAACG,OAAA,EAAK,SAAQ,QAAO,MAAK,MAAK,IAAG,KAC/B,mBACH;AAAA;AAAA,QACF;AAAA,QACA,gBAAAH,KAACE,MAAA,EAAI,IAAI,EAAE,IAAI,IAAI,GACjB,0BAAAD,MAACG,SAAA,EAAO,SAAS,aAAa,eAAY,kBACvC;AAAA,mBACC,gBAAAJ,KAAC,aAAU,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG,IAE1C,gBAAAA,KAAC,2BAAwB,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,UAEzD,SAAS,YAAY;AAAA,WACxB,GACF;AAAA;AAAA;AAAA,EACF;AAEJ;AA7DgB;AAgET,SAAS,kBAAkB,EAAE,KAAK,GAA6C;AACpF,SACE,gBAAAC,MAACI,QAAA,EAAM,WAAU,OAAM,SAAS,KAAK,YAAW,UAC9C;AAAA,oBAAAL,KAAC,mBAAgB,OAAO,KAAK,OAAO,MAAM,IAAI;AAAA,IAC9C,gBAAAC,MAACE,OAAA,EAAK,SAAQ,WAAU,MAAK,MAAK,IAAG,MAAK;AAAA;AAAA,MAC3B,KAAK;AAAA,OACpB;AAAA,KACF;AAEJ;AATgB;AAgBT,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAG6B;AAC3B,MAAI,CAAC,KAAK,KAAM,QAAO;AACvB,SACE,gBAAAH,KAACE,MAAA,EACC,0BAAAD;AAAA,IAACG;AAAA,IAAA;AAAA,MACC,SAAS,MAAM;AACb,eAAO,KAAK,KAAK,KAAM,KAAK,UAAU,qBAAqB;AAC3D,iBAAS;AAAA,MACX;AAAA,MACA,eAAa,gBAAgB,KAAK,EAAE;AAAA,MAEnC;AAAA,aAAK,KAAK;AAAA,QACX,gBAAAJ,KAAC,iBAAc,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA;AAAA,EAChD,GACF;AAEJ;AAtBgB;AAyBT,SAAS,aAAa,EAAE,KAAK,GAAoD;AACtF,MAAI,CAAC,KAAK,KAAM,QAAO;AACvB,SACE,gBAAAC,MAACE,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY;AAAA;AAAA,IACb;AAAA,IAClC,gBAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAM,KAAK,KAAK;AAAA,QAChB,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,eAAa,gBAAgB,KAAK,EAAE;AAAA,QACpC,IAAI,EAAE,OAAO,gBAAgB,gBAAgB,YAAY;AAAA,QAExD,eAAK,KAAK;AAAA;AAAA,IACb;AAAA,IAAM;AAAA,KAER;AAEJ;AAlBgB;AAyBT,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,QAAQ;AACV,GAGsB;AACpB,SACE,gBAAAF,KAACE,MAAA,EAAI,WAAU,MAAK,OAAc,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GACjD,gBAAM,IAAI,CAAC,MAAM,UAChB,gBAAAF,KAACE,MAAA,EAAI,WAAU,MAAiB,IAAI,EAAE,IAAI,EAAE,GAC1C,0BAAAF,KAACG,OAAA,EAAK,SAAQ,QAAO,IAAG,QACrB,gBACH,KAHuB,KAIzB,CACD,GACH;AAEJ;AAlBgB;;;ADjKZ,SACE,OAAAG,MADF,QAAAC,aAAA;AApBJ,IAAM,uBAAuB;AAG7B,IAAM,mBAAmB;AAGzB,SAAS,QAAQ;AAAA,EACf;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,eAAe;AAAA,EACf;AACF,GAMsB;AACpB,SACE,gBAAAA,MAACC,QAAA,EAAM,WAAU,OAAM,SAAS,GAAG,YAAW,UAAS,gBAAe,iBACpE;AAAA,oBAAAF,KAACG,SAAA,EAAO,SAAQ,SAAQ,SAAS,MAAM,IAAI,KAAK,GAAG,eAAY,gBAAe,oBAE9E;AAAA,IACA,gBAAAH,KAACG,SAAA,EAAO,SAAS,QAAQ,UAAU,cAAc,eAAa,YAC3D,qBACH;AAAA,KACF;AAEJ;AAvBS;AA0BF,SAAS,YAAY,EAAE,KAAK,YAAY,GAA+D;AAC5G,SACE,gBAAAF,MAACC,QAAA,EAAM,SAAS,GAAG,eAAY,gBAC7B;AAAA,oBAAAD,MAACG,MAAA,EACC;AAAA,sBAAAJ,KAACK,OAAA,EAAK,SAAQ,WAAU,MAAK,MAAK,IAAG,MAAK,qCAE1C;AAAA,MACA,gBAAAL,KAACK,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY,qHAEjD;AAAA,OACF;AAAA,IACA,gBAAAL,KAAC,qBAAkB,aAA0B,QAAQ,OAAO,QAAQ,MAAM,IAAI,KAAK,GAAG;AAAA,IACtF,gBAAAA,KAACI,MAAA,EACC,0BAAAJ,KAACG,SAAA,EAAO,SAAQ,SAAQ,SAAS,MAAM,IAAI,KAAK,GAAG,eAAY,gBAAe,oBAE9E,GACF;AAAA,KACF;AAEJ;AAnBgB;AAsBT,SAAS,cAAc,EAAE,KAAK,KAAK,GAA6D;AAGrG,QAAM,CAAC,QAAQ,SAAS,IAAIG,UAAS,CAAC,KAAK,IAAI;AAC/C,SACE,gBAAAL,MAACC,QAAA,EAAM,SAAS,KAAK,eAAY,qBAC/B;AAAA,oBAAAF,KAAC,qBAAkB,MAAY;AAAA,IAC/B,gBAAAA,KAAC,kBAAe,MAAY,QAAQ,MAAM,UAAU,IAAI,GAAG;AAAA,IAC3D,gBAAAA,KAAC,gBAAa,OAAO,KAAK,MAAM,MAAM,GAAG,oBAAoB,GAAG,OAAO,GAAG;AAAA,IAC1E,gBAAAA,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA,KAAC,WAAQ,KAAU,QAAQ,MAAM,IAAI,KAAK,GAAG,cAAc,CAAC,QAAQ,YAAW,qBAAoB;AAAA,KACrG;AAEJ;AAbgB;AAoBT,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,QAAM,CAAC,QAAQ,SAAS,IAAIM,UAAS,CAAC,MAAM,IAAI;AAChD,SACE,gBAAAL,MAACC,QAAA,EAAM,SAAS,KAAK,eAAa,YAAY,MAAM,EAAE,IACpD;AAAA,oBAAAF,KAAC,qBAAkB,MAAY;AAAA,IAC9B,MAAM,QACL,gBAAAA,KAACI,MAAA,EACC,0BAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,SAAS,MAAM;AACb,iBAAO,KAAK,MAAM,KAAM,KAAK,UAAU,qBAAqB;AAC5D,oBAAU,IAAI;AAAA,QAChB;AAAA,QACA,eAAa,iBAAiB,MAAM,EAAE;AAAA,QAErC;AAAA,gBAAM,KAAK;AAAA,UACZ,gBAAAH,KAACO,gBAAA,EAAc,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA;AAAA,IAChD,GACF;AAAA,IAEF,gBAAAP,KAAC,gBAAa,OAAO,MAAM,OAAO,OAAO,GAAG;AAAA,IAC5C,gBAAAA,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ,MAAM,IAAI,KAAK;AAAA,QACvB,cAAc,CAAC;AAAA,QACf,YAAY,iBAAiB,MAAM,EAAE;AAAA;AAAA,IACvC;AAAA,KACF;AAEJ;AArCgB;AAwCT,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,SACE,gBAAAC,MAACC,QAAA,EAAM,SAAS,KAAK,eAAY,mBAC/B;AAAA,oBAAAF,KAAC,qBAAkB,MAAY;AAAA,IAC/B,gBAAAA,KAAC,gBAAa,OAAO,KAAK,MAAM,MAAM,oBAAoB,GAAG,OAAO,uBAAuB,GAAG;AAAA,IAC9F,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAQ;AAAA,QACR,SAAS;AAAA;AAAA,IACX;AAAA,IACA,gBAAAA,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA,KAAC,WAAQ,KAAU,QAAQ,MAAM,IAAI,KAAK,GAAG,WAAU,aAAY,YAAW,mBAAkB;AAAA,KAClG;AAEJ;AAtBgB;AA6BT,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,QAAM,CAAC,QAAQ,SAAS,IAAIM,UAAS,KAAK;AAC1C,SACE,gBAAAL,MAACC,QAAA,EAAM,SAAS,KAAK,eAAY,mBAC/B;AAAA,oBAAAF,KAAC,qBAAkB,MAAY;AAAA,IAC/B,gBAAAA,KAACK,OAAA,EAAK,SAAQ,QAAO,IAAG,KAAI,OAAM,aAAY,4HAG9C;AAAA,IACC,KAAK,aACJ,gBAAAL,KAACI,MAAA,EACC,0BAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,SAAS,MAAM;AACb,iBAAO,KAAK,KAAK,WAAY,UAAU,qBAAqB;AAC5D,oBAAU,IAAI;AAAA,QAChB;AAAA,QACA,eAAY;AAAA,QACb;AAAA;AAAA,UAEC,gBAAAH,KAACO,gBAAA,EAAc,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA;AAAA,IAChD,GACF;AAAA,IAEF,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,SAAQ;AAAA,QACR,SAAS;AAAA;AAAA,IACX;AAAA,IACA,gBAAAA,KAAC,gBAAa,MAAY;AAAA,IAC1B,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAQ,MAAM,IAAI,KAAK;AAAA,QACvB,WAAU;AAAA,QACV,cAAc,CAAC;AAAA,QACf,YAAW;AAAA;AAAA,IACb;AAAA,KACF;AAEJ;AA9CgB;AAsDT,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKsB;AACpB,QAAM,iBAAiB,IAAI,KAAK;AAChC,QAAM,aAAa,kBAAkB,aAAa,cAAc;AAChE,QAAM,QAAQ,YAAY,cAAc,UAAU,OAAO,cAAc;AAIvE,YAAU,MAAM;AACd,QAAI,WAAY,QAAO;AACvB,UAAM,KAAK,YAAY,MAAM,SAAS,GAAG,gBAAgB;AACzD,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,YAAY,QAAQ,CAAC;AAEzB,MAAI,YAAY;AACd,WACE,gBAAAC,MAACC,QAAA,EAAM,SAAS,GAAG,eAAY,wBAC7B;AAAA,sBAAAD,MAACC,QAAA,EAAM,WAAU,OAAM,SAAS,KAAK,YAAW,UAC9C;AAAA,wBAAAF,KAAC,mBAAgB,IAAI,EAAE,OAAO,eAAe,GAAG;AAAA,QAChD,gBAAAC,MAACG,MAAA,EACC;AAAA,0BAAAH,MAACI,OAAA,EAAK,SAAQ,QAAO,QAAO,QAAO,IAAG,KACnC;AAAA;AAAA,YAAM;AAAA,aACT;AAAA,UACA,gBAAAL,KAACK,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAClC,oBAAU,WAAW,YAAY,GACpC;AAAA,WACF;AAAA,SACF;AAAA,MACA,gBAAAL,KAACI,MAAA,EACC,0BAAAJ,KAACG,SAAA,EAAO,SAAS,MAAM,IAAI,SAAS,EAAE,eAAe,eAAe,CAAC,GAAG,sBAAQ,GAClF;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAF,MAACC,QAAA,EAAM,SAAS,KAAK,eAAY,sBAC/B;AAAA,oBAAAD,MAACC,QAAA,EAAM,WAAU,OAAM,SAAS,KAAK,YAAW,UAC9C;AAAA,sBAAAF,KAAC,YAAS,SAAQ,YAAW,cAAc,IAAI,WAAW,GAAG,YAAW,sBAAqB;AAAA,MAC7F,gBAAAC,MAACG,MAAA,EACC;AAAA,wBAAAJ,KAACK,OAAA,EAAK,SAAQ,QAAO,QAAO,QAAO,IAAG,KAAI,kCAE1C;AAAA,QACA,gBAAAJ,MAACI,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY;AAAA;AAAA,UACT;AAAA,UAAM;AAAA,WAC9C;AAAA,SACF;AAAA,OACF;AAAA,IACA,gBAAAJ,MAACC,QAAA,EAAM,WAAU,OAAM,SAAS,GAC9B;AAAA,sBAAAF,KAACG,SAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,UAAU,eAAY,qBAAoB,0BAErF;AAAA,MACA,gBAAAH,KAACG,SAAA,EAAO,SAAQ,SAAQ,MAAK,MAAK,SAAS,MAAM,IAAI,KAAK,GAAG,oBAE7D;AAAA,OACF;AAAA,KACF;AAEJ;AAnEgB;;;AG5NhB,OAAO,yBAAyB;AAChC,OAAOK,sBAAqB;AAC5B,OAAO,yBAAyB;AAChC,OAAO,0BAA0B;AAEjC,SAAS,qBAAqB;AAC9B,SAAS,UAAAC,eAAc;AACvB,SAAS,OAAAC,YAAW;AACpB,SAAS,SAAAC,cAAa;AACtB,SAAS,QAAAC,aAAY;AA4Db,gBAAAC,MAIF,QAAAC,aAJE;AA5BR,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,SACE,gBAAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAW;AAAA,MACX,gBAAe;AAAA,MAGf,IAAI,EAAE,YAAY,GAAG,UAAU,QAAQ,QAAQ,IAAI;AAAA,MAEnD;AAAA,wBAAAF;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,IAAI;AAAA,cACF,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,cAAc;AAAA,cACd,SAAS;AAAA,cACT,OAAO;AAAA,YACT;AAAA,YAEA,0BAAAH,KAACI,OAAA,EAAK,SAAQ,WAAU,QAAO,QAAO,IAAG,QAAO,uBAEhD;AAAA;AAAA,QACF;AAAA,QACA,gBAAAH;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,UAAU,KAAK,EAAE;AAAA,YAChC,eAAa,0BAA0B,KAAK,EAAE;AAAA,YAE9C;AAAA,8BAAAL,KAAC,wBAAqB,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,cAAE;AAAA;AAAA;AAAA,QAEzD;AAAA,QACC,eACC,gBAAAC;AAAA,UAAC;AAAA;AAAA,YACC,SAAQ;AAAA,YACR,OAAM;AAAA,YACN,MAAK;AAAA,YACL,SAAS,MAAM,aAAa,KAAK,EAAE;AAAA,YACnC,SAAS;AAAA,cACP,OAAO;AAAA,cACP,YAAY,KAAK;AAAA,cACjB,aACE;AAAA,cACF,aAAa;AAAA,cACb,YAAY,gCAAgC,KAAK,EAAE;AAAA,YACrD;AAAA,YACA,eAAa,wBAAwB,KAAK,EAAE;AAAA,YAE5C;AAAA,8BAAAD,KAAC,uBAAoB,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,cAAE;AAAA;AAAA;AAAA,QAExD,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AA/DS;AAkET,SAAS,UAAU;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,QAAM,EAAE,MAAM,WAAW,OAAO,IAAI;AACpC,SACE,gBAAAC;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,eAAa,aAAa,KAAK,EAAE;AAAA,MACjC,kBAAgB;AAAA,MAChB,IAAI;AAAA,QACF,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,GAAG;AAAA,QACH,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,aAAa,YAAY,iBAAiB;AAAA,QAC1C,SAAS;AAAA,MACX;AAAA,MAEA;AAAA,wBAAAH,KAAC,mBAAgB,OAAO,KAAK,OAAO,MAAM,IAAI;AAAA,QAC9C,gBAAAC,MAACE,MAAA,EAAI,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,GAClC;AAAA,0BAAAF,MAACC,QAAA,EAAM,WAAU,OAAM,SAAS,MAAM,YAAW,UAC/C;AAAA,4BAAAF,KAACI,OAAA,EAAK,SAAQ,QAAO,QAAO,QAAO,IAAG,QACnC,eAAK,OACR;AAAA,YACC,YAAY,gBAAAJ,KAACM,kBAAA,EAAgB,IAAI,EAAE,UAAU,IAAI,OAAO,eAAe,GAAG,IAAK;AAAA,aAClF;AAAA,UACA,gBAAAN,KAACI,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAClC,sBAAa,UAAU,cAAe,0BACzC;AAAA,WACF;AAAA,QACC,YACC,gBAAAJ,KAAC,qBAAkB,MAAY,WAAsB,cAA4B,IAEjF,gBAAAC;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,UAAU,KAAK,EAAE;AAAA,YAChC,eAAa,qBAAqB,KAAK,EAAE;AAAA,YAEzC;AAAA,8BAAAL,KAAC,uBAAoB,IAAI,EAAE,UAAU,IAAI,IAAI,IAAI,GAAG;AAAA,cAAE;AAAA;AAAA;AAAA,QAExD;AAAA;AAAA;AAAA,EAEJ;AAEJ;AApDS;AAmEF,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAKsB;AACpB,SACE,gBAAAC,MAACC,QAAA,EAAM,SAAS,GAAG,eAAY,mBAC7B;AAAA,oBAAAD,MAACE,MAAA,EACC;AAAA,sBAAAH,KAACI,OAAA,EAAK,SAAQ,WAAU,MAAK,MAAK,IAAG,MAAK,oCAE1C;AAAA,MACA,gBAAAJ,KAACI,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY,0FAEjD;AAAA,OACF;AAAA,IACA,gBAAAJ;AAAA,MAACG;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,SAAS;AAAA,UACT,KAAK;AAAA,UACL,qBAAqB,EAAE,IAAI,OAAO,IAAI,UAAU;AAAA,QAClD;AAAA,QAEC,mBAAS,IAAI,CAAC,WACb,gBAAAH;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA;AAAA,YACA;AAAA;AAAA,UAHK,OAAO,KAAK;AAAA,QAInB,CACD;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AAtCgB;;;AC9KhB,OAAOO,sBAAqB;AAE5B,SAAS,OAAAC,YAAW;AACpB,SAAS,SAAAC,cAAa;AACtB,SAAS,QAAAC,aAAY;AAuCf,gBAAAC,MACA,QAAAC,aADA;AAjCN,SAAS,SAAS;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,SACE,gBAAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,MAAK;AAAA,MACL,SAAS;AAAA,MACT,gBAAc;AAAA,MACd,eAAa,gBAAgB,KAAK,EAAE;AAAA,MACpC,IAAI;AAAA,QACF,UAAU;AAAA,QACV,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,GAAG;AAAA,QACH,cAAc;AAAA,QACd,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa,SAAS,iBAAiB;AAAA,QACvC,SAAS,SAAS,oBAAoB;AAAA,QACtC,YAAY,wBAAC,UAAU,MAAM,YAAY,OAAO,CAAC,gBAAgB,kBAAkB,CAAC,GAAxE;AAAA,QACZ,WAAW,EAAE,aAAa,eAAe;AAAA,MAC3C;AAAA,MAEA;AAAA,wBAAAF,KAAC,mBAAgB,OAAO,KAAK,OAAO,MAAM,IAAI;AAAA,QAC9C,gBAAAC,MAACC,MAAA,EAAI,IAAI,EAAE,UAAU,EAAE,GACrB;AAAA,0BAAAF,KAACG,OAAA,EAAK,SAAQ,QAAO,QAAO,QAAO,IAAG,QACnC,eAAK,OACR;AAAA,UACA,gBAAAH,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAClC,eAAK,MACR;AAAA,WACF;AAAA,QACC,UACC,gBAAAH;AAAA,UAACI;AAAA,UAAA;AAAA,YACC,IAAI,EAAE,UAAU,YAAY,KAAK,IAAI,OAAO,IAAI,UAAU,IAAI,OAAO,eAAe;AAAA;AAAA,QACtF;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAjDS;AA0DF,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AACF,GAIsB;AACpB,SACE,gBAAAH,MAACI,QAAA,EAAM,SAAS,GAAG,eAAY,kBAC7B;AAAA,oBAAAJ,MAACC,MAAA,EACC;AAAA,sBAAAF,KAACG,OAAA,EAAK,SAAQ,WAAU,MAAK,MAAK,IAAG,MAAK,sCAE1C;AAAA,MACA,gBAAAH,KAACG,OAAA,EAAK,SAAQ,WAAU,IAAG,KAAI,OAAM,aAAY,oGAEjD;AAAA,OACF;AAAA,IAEA,gBAAAH;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,IAAI;AAAA,UACF,SAAS;AAAA,UACT,KAAK;AAAA,UACL,qBAAqB,EAAE,IAAI,OAAO,IAAI,UAAU;AAAA,QAClD;AAAA,QAEC,gBAAM,IAAI,CAAC,SACV,gBAAAF;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA,QAAQ,KAAK,OAAO;AAAA,YACpB,UAAU,MAAM,SAAS,KAAK,EAAE;AAAA;AAAA,UAH3B,KAAK;AAAA,QAIZ,CACD;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AAtCgB;;;ACUZ,gBAAAM,aAAA;AA3DG,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKsB;AACpB,QAAM,eAAgB,IAAI,KAAK,iBAAiB,IAAI,KAAK;AAEzD,QAAM,WAAyB,MAAM,IAAI,CAAC,SAAS;AACjD,UAAM,WAAW,kBAAkB,KAAK,EAAE;AAG1C,UAAM,cACH,WAAW,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ,IAAI,YAC1D,KAAK,OAAO,eAAe,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI,WACvE;AACF,WAAO;AAAA,MACL;AAAA,MACA,WAAW,eAAe;AAAA,MAC1B,QAAQ,aAAa,UAAU,WAAW,YAAY,IAAI;AAAA,IAC5D;AAAA,EACF,CAAC;AAGD,QAAM,cAAc,wBAAC,WAAyB;AAC5C,QAAI,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,GAAG,YAAY,YAAY,QAAQ;AAAA,MAC3E,cAAc;AAAA,IAChB,CAAC;AAAA,EACH,GAJoB;AAkBpB,QAAM,aAA4C,eAC9C,OAAO,WAAW;AAChB,UAAM,aAAa,MAAM;AACzB,UAAM,UAAU,kBAAkB,MAAM;AACxC,UAAM,aAAa,SAAS;AAAA,MAC1B,CAAC,WAAW,OAAO,aAAa,kBAAkB,OAAO,KAAK,EAAE,MAAM;AAAA,IACxE;AACA,QAAI,CAAC,WAAY,aAAY,MAAM;AAAA,EACrC,IACA;AAEJ,SACE,gBAAAA,MAAC,iBAAc,UAAoB,WAAW,aAAa,cAAc,YAAY;AAEzF;AA7DgB;AAgEhB,SAAS,WAAW,OAA2C;AAC7D,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,wBAAC,QACP,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,YAAa,IAAI,KAAK,gBAAuC;AAAA,QAC7D,UAAU,CAAC,WACT,IAAI,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,GAAG,YAAY,YAAY,QAAQ;AAAA,UAC3E,cAAc;AAAA,QAChB,CAAC;AAAA;AAAA,IAEL,GATM;AAAA,EAWV;AACF;AAhBS;AAmBT,SAAS,SAAS,aAAiC;AACjD,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,wBAAC,QAAmB,gBAAAA,MAAC,eAAY,KAAU,aAA0B,GAArE;AAAA,EACV;AACF;AANS;AAaT,SAAS,aACP,MACA,OACA,aACA,eACc;AACd,MAAI,KAAK,mBAAmB,KAAK,gBAAgB,SAAS,GAAG;AAC3D,WAAO;AAAA,MACL,SAAS,WAAW;AAAA,MACpB,GAAG,KAAK,gBAAgB,IAAI,CAAC,WAAW;AAAA,QACtC,IAAI,MAAM;AAAA,QACV,OAAO,MAAM;AAAA,QACb,QAAQ,wBAAC,QACP,gBAAAA,MAAC,sBAAmB,KAAU,MAAM,YAAY,OAAO,IAAI,KAAK,YAAY,GAAG,OAAc,GADvF;AAAA,MAGV,EAAE;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AAAA,IACL,SAAS,WAAW;AAAA,IACpB;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ,wBAAC,QAAmB,gBAAAA,MAAC,iBAAc,KAAU,MAAM,YAAY,OAAO,IAAI,KAAK,YAAY,GAAG,GAA9F;AAAA,IACV;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ,wBAAC,QACP,gBAAAA,MAAC,eAAY,KAAU,MAAM,YAAY,OAAO,IAAI,KAAK,YAAY,GAAG,eAA8B,GADhG;AAAA,IAGV;AAAA,EACF;AACF;AAjCS;AAoCT,SAAS,aAAa,OAA+B,eAAqC;AACxF,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ,wBAAC,QACP,gBAAAA,MAAC,eAAY,KAAU,MAAM,YAAY,OAAO,IAAI,KAAK,YAAY,GAAG,eAA8B,GADhG;AAAA,IAGV;AAAA,EACF;AACF;AAVS;AAkBF,SAAS,eAAe,MAOd;AACf,QAAM,EAAE,MAAM,OAAO,aAAa,eAAe,aAAa,SAAS,IAAI;AAC3E,QAAM,SAAS,KAAK,YAChB,aAAa,OAAO,aAAa,IACjC,aAAa,MAAM,OAAO,aAAa,aAAa;AACxD,QAAM,UAAsB;AAAA,IAC1B,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,wBAAC,QACP,gBAAAA,MAAC,eAAY,KAAU,aAA0B,OAAc,UAAoB,GAD7E;AAAA,EAGV;AACA,SAAO,CAAC,WAAW,KAAK,GAAG,GAAG,QAAQ,OAAO;AAC/C;AApBgB;;;AX/BR,gBAAAC,aAAA;AA/GR,IAAM,sBAAsB;AA8E5B,SAAS,iBAAiB,OAAqC;AAC7D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,MAAM,IAAI,cAAc;AAChC,QAAM,eACJ,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,KAAK,YAAY,KAAK,MAAM,CAAC;AAEhE,QAAM,QAAQ,eAAe;AAAA,IAC3B,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,kBAAmB,MAAM,KAAK,iBAClC,MAAM,KAAK;AAEb,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAM;AAAA,MACN,YAAW;AAAA,MACX,eAAe,CAAC,UACd,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MAEF,iBAAiB,eAAe,aAAa,OAAO,eAAe;AAAA,MACnE,mBAAmB,iBAAiB,WAAW;AAAA,MAC/C,WAAU;AAAA,MACV,kBAAkB,CAAC,QACjB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,MAEF;AAAA,MACA,YAAW;AAAA;AAAA,EACb;AAEJ;AAtDS;AAmEF,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb,WAAW;AAAA,EACX;AAAA,EACA,QAAQ,aAAa,YAAY;AAAA,EACjC,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB;AAAA,EACA,WAAW,6BAAM;AACf,QAAI,OAAO,WAAW,YAAa,QAAO,SAAS,OAAO;AAAA,EAC5D,GAFW;AAAA,EAGX;AACF,GAAoD;AAClD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MAEA,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ;AApCgB;","names":["Box","Stack","Text","Box","jsx","Box","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Stack","Box","Text","OpenInNewIcon","useState","Button","Box","Stack","Text","Button","Box","Stack","Text","jsx","jsx","jsxs","Box","Text","Button","Stack","jsx","jsxs","Stack","Button","Box","Text","useState","OpenInNewIcon","CheckCircleIcon","Button","Box","Stack","Text","jsx","jsxs","Stack","Box","Text","Button","CheckCircleIcon","CheckCircleIcon","Box","Stack","Text","jsx","jsxs","Box","Text","CheckCircleIcon","Stack","jsx","jsx"]}
1
+ {"version":3,"sources":["../../src/react/ai-onboarding.tsx","../../src/react/ai-landing.tsx","../../src/react/ai-capabilities.tsx","../../src/react/ai-icons.tsx","../../src/react/feature-badge.tsx","../../src/react/ai-connection-utils.ts","../../src/react/ai-flow-steps.tsx","../../src/react/host-connect-guide.tsx","../../src/react/mcp-endpoint-url.tsx","../../src/react/ai-status-board.tsx","../../src/react/host-select-step.tsx","../../src/react/ai-steps.tsx","../../src/react/pt-BR.ts"],"sourcesContent":["\"use client\";\n\nimport type { McpAiCopy } from \"./copy\";\nimport {\n GuidedSection,\n OnboardingProvider,\n useOnboarding,\n type OnboardingStateSnapshot,\n type OnboardingStore,\n} from \"@12-apps/onboarding\";\n\nimport {\n type AiCapability,\n type AiHostGuide,\n} from \"../guide\";\nimport { AiLanding } from \"./ai-landing\";\nimport type { DisconnectHandler } from \"./ai-status-board\";\nimport {\n buildFlowSteps,\n connectedSummary,\n connectedTitle,\n StatusBoard,\n type AiConnection,\n} from \"./ai-steps\";\n\nexport type { AiConnection } from \"./ai-steps\";\n\nconst DEFAULT_FEATURE_KEY = \"ai_integration\";\n\n/** Props for the reusable AI-connect onboarding flow. */\nexport interface AiIntegrationOnboardingProps {\n /** Persistence seam — the app wires this to its own backend (server actions). */\n store: OnboardingStore;\n /** The MCP endpoint URL to paste (derived by the app from its public origin). */\n endpointUrl: string;\n /** The owner's saved progress (null → first run / landing). */\n initialState: OnboardingStateSnapshot | null;\n /** The live MCP connections (one per connected assistant; empty when none). */\n connections: readonly AiConnection[];\n /** Onboarding feature key (persistence namespace). @default \"ai_integration\" */\n featureKey?: string;\n /** Show the dev-only \"reset onboarding\" button. @default false */\n devReset?: boolean;\n /**\n * Assistants offered in the flow, with their step-by-step instructions.\n *\n * REQUIRED since FUT-760. These used to default to this package's own pt-BR\n * walkthrough, so a host that said nothing shipped one product's Portuguese\n * and had no field to decline it. `PT_BR_AI_HOST_GUIDES(platformName)` is that\n * exact content, now chosen by name.\n */\n hosts: readonly AiHostGuide[];\n /** Capability cards on the landing. REQUIRED — see `hosts`. */\n capabilities: readonly AiCapability[];\n /** Permission reassurance copy on the landing. REQUIRED — see `hosts`. */\n permissionModel: string;\n /** Every sentence the screens render. REQUIRED — see `hosts`. */\n copy: McpAiCopy;\n /**\n * Message the owner pastes into the assistant on the Conectar step.\n *\n * REQUIRED, with no default, because the useful version of it names TOOLS —\n * one to register the connection, one to read something real — and this\n * package neither defines nor serves any. It shipped a constant naming two\n * tools from one adopter's surface, so another host handed its owner a prompt\n * that called two things that did not exist, and the confirm step then waited\n * forever for a registration that could never happen. Build it with\n * `aiConnectPrompt({ … })`.\n */\n connectPrompt: string;\n /**\n * Re-check the live connection on the verify step's \"Testar conexão\" button —\n * apps pass a router refresh (e.g. Next's `router.refresh`). @default a full\n * `window.location.reload()`.\n */\n onRetest?: () => void;\n /**\n * Revoke a connected assistant's access, from the completed status board. The\n * host ID is the board's card, NOT the connection — `claude` and\n * `claude-desktop` share one provider, so the app resolves which stored\n * connection it owns (`providerForHostId`) and revokes that. Omitted → the\n * board stays read-only, which is the pre-existing behavior.\n */\n onDisconnect?: DisconnectHandler;\n}\n\n/** Resolved (defaults-applied) props threaded to the in-provider flow body. */\ninterface FlowProps {\n endpointUrl: string;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n capabilities: readonly AiCapability[];\n permissionModel: string;\n connectPrompt: string;\n onRetest: () => void;\n onDisconnect: DisconnectHandler | undefined;\n devReset: boolean;\n copy: McpAiCopy;\n}\n\n/**\n * The flow body — inside the OnboardingProvider so it can read the selected host\n * and pick the path. A host with a published `pluginUrl` gets the simplified\n * Escolher → Instalar → Confirmar flow (no URL to copy); otherwise the full\n * Escolher → Copiar URL → Configurar → Conectar → Confirmar flow.\n */\nfunction AiOnboardingFlow(props: FlowProps): React.JSX.Element {\n const {\n endpointUrl,\n connections,\n hosts,\n capabilities,\n permissionModel,\n connectPrompt,\n onRetest,\n onDisconnect,\n devReset,\n copy,\n } = props;\n const { state } = useOnboarding();\n const selectedHost =\n hosts.find((h) => h.id === state.data.selectedHost) ?? hosts[0]!;\n\n const steps = buildFlowSteps({\n host: selectedHost,\n hosts,\n endpointUrl,\n connectPrompt,\n connections,\n onRetest,\n copy,\n });\n const connectedHostId = (state.data.connectedHost ??\n state.data.selectedHost) as string | undefined;\n\n return (\n <GuidedSection\n steps={steps}\n title={copy.onboarding.title}\n startLabel={copy.landing.start}\n renderLanding={(start) => (\n <AiLanding\n onStart={start}\n permissionModel={permissionModel}\n capabilities={capabilities}\n copy={copy.landing}\n capabilitiesCopy={copy.capabilities}\n />\n )}\n configuredTitle={connectedTitle(connections, hosts, connectedHostId, copy.summary)}\n configuredSummary={connectedSummary(connections, copy.summary)}\n editLabel={copy.onboarding.editLabel}\n completedContent={(nav) => (\n <StatusBoard\n nav={nav}\n connections={connections}\n hosts={hosts}\n onDisconnect={onDisconnect}\n copy={copy}\n />\n )}\n devReset={devReset}\n dataTestId=\"ai-onboarding\"\n />\n );\n}\n\n/**\n * URL-free, persisted onboarding for the AI/MCP integration — a five-step wizard\n * (pick an assistant, copy the store URL, configure the connector, connect, then\n * verify) whose position + chosen assistant are saved via `@12-apps/onboarding`, so\n * a refresh resumes exactly where the owner left off. The live MCP connection\n * signal drives the verify step and the completed status board.\n *\n * App-agnostic: the app supplies the persistence `store`, the `endpointUrl`, and\n * the live `connections` (one per connected assistant); content (hosts,\n * capabilities, copy) defaults to the shared guide but can be overridden per app.\n */\nexport function AiIntegrationOnboarding({\n store,\n endpointUrl,\n initialState,\n connections,\n featureKey = DEFAULT_FEATURE_KEY,\n devReset = false,\n hosts,\n capabilities,\n permissionModel,\n connectPrompt,\n onRetest = () => {\n if (typeof window !== \"undefined\") window.location.reload();\n },\n onDisconnect,\n copy,\n}: AiIntegrationOnboardingProps): React.JSX.Element {\n return (\n <OnboardingProvider\n featureKey={featureKey}\n store={store}\n initialState={initialState}\n >\n <AiOnboardingFlow\n endpointUrl={endpointUrl}\n connections={connections}\n hosts={hosts}\n capabilities={capabilities}\n permissionModel={permissionModel}\n connectPrompt={connectPrompt}\n onRetest={onRetest}\n onDisconnect={onDisconnect}\n devReset={devReset}\n copy={copy}\n />\n </OnboardingProvider>\n );\n}\n","\"use client\";\n\nimport BoltOutlinedIcon from \"@mui/icons-material/BoltOutlined\";\nimport LanguageOutlinedIcon from \"@mui/icons-material/LanguageOutlined\";\nimport LockOpenOutlinedIcon from \"@mui/icons-material/LockOpenOutlined\";\nimport VerifiedUserOutlinedIcon from \"@mui/icons-material/VerifiedUserOutlined\";\n\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiCapability } from \"../guide\";\nimport type { AiCapabilitiesCopy, AiLandingCopy } from \"./copy\";\nimport { AiCapabilities } from \"./ai-capabilities\";\nimport { FeatureBadge, type FeatureBadgeItem } from \"./feature-badge\";\n\n/**\n * The ICONS for the landing's reassurance strip, keyed by the copy's own ids.\n *\n * The package keeps the icons and the host keeps the words: an icon is not\n * copy, and a pack that had to ship React elements could not be a plain data\n * file. An id the map does not know renders without an icon rather than\n * throwing — a host adding a fifth point should get its words on screen.\n */\nconst TRUST_ICONS: Readonly<Record<string, React.JSX.Element>> = {\n login: <LockOpenOutlinedIcon />,\n install: <BoltOutlinedIcon />,\n permissions: <VerifiedUserOutlinedIcon />,\n surface: <LanguageOutlinedIcon />,\n};\n\nfunction trustBadges(trust: AiLandingCopy[\"trust\"]): FeatureBadgeItem[] {\n return trust.map((point) => ({\n icon: TRUST_ICONS[point.id],\n label: point.label,\n caption: point.caption,\n }));\n}\n\n/** The single-column marketing hero: eyebrow + headline + description + CTA. */\nfunction Hero({\n onStart,\n copy,\n}: {\n onStart: () => void;\n copy: AiLandingCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={2.5} sx={{ maxWidth: 680 }}>\n <Box\n sx={{\n color: \"primary.main\",\n fontSize: 12,\n fontWeight: 700,\n letterSpacing: 1.2,\n textTransform: \"uppercase\",\n }}\n >\n {copy.eyebrow}\n </Box>\n <Text variant=\"heading\" size=\"xl\" weight=\"bold\" as=\"h1\">\n Conecte{\" \"}\n <Box component=\"span\" sx={{ color: \"primary.main\" }}>\n assistentes de IA\n </Box>{\" \"}\n {copy.titleTail}\n </Text>\n <Text variant=\"body\" color=\"secondary\" as=\"p\">\n {copy.lede}\n </Text>\n <Box sx={{ pt: 1 }}>\n <Button onClick={onStart} data-testid=\"ai-landing-start\">\n Ver como conectar\n </Button>\n </Box>\n </Stack>\n );\n}\n\n/**\n * Homepage-style marketing landing for the AI integration (shown before the\n * owner starts): a hero, the permission reassurance, a trust/feature strip, and\n * the capability highlights. `onStart` begins the guided flow. `permissionModel`\n * and `capabilities` are REQUIRED host copy — the package ships no default\n * sentence (FUT-760).\n */\nexport function AiLanding({\n onStart,\n permissionModel,\n capabilities,\n copy,\n capabilitiesCopy,\n}: {\n onStart: () => void;\n permissionModel: string;\n capabilities: readonly AiCapability[];\n copy: AiLandingCopy;\n capabilitiesCopy: AiCapabilitiesCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={6} data-testid=\"ai-landing\">\n <Hero onStart={onStart} copy={copy} />\n\n <Stack\n direction=\"row\"\n spacing={1.5}\n alignItems=\"flex-start\"\n data-testid=\"ai-permission-callout\"\n sx={{\n p: 2,\n borderRadius: 2,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <VerifiedUserOutlinedIcon sx={{ color: \"success.main\", mt: 0.25 }} />\n <Text variant=\"body\" as=\"p\">\n {permissionModel}\n </Text>\n </Stack>\n\n <Box\n sx={{\n p: { xs: 2.5, md: 3 },\n borderRadius: 3,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <Box\n sx={{\n display: \"grid\",\n gap: 3,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\", md: \"repeat(4, 1fr)\" },\n }}\n >\n {trustBadges(copy.trust).map((f) => (\n <FeatureBadge key={f.label} icon={f.icon} label={f.label} caption={f.caption} />\n ))}\n </Box>\n </Box>\n\n <Box>\n <AiCapabilities capabilities={capabilities} copy={capabilitiesCopy} />\n </Box>\n </Stack>\n );\n}\n","import { Box } from \"@12-apps/ui/mui/Box\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiCapability } from \"../guide\";\nimport type { AiCapabilitiesCopy } from \"./copy\";\nimport { CapabilityIcon } from \"./ai-icons\";\n\n/** One marketing card: an icon, a headline and an example prompt (as a bubble). */\nfunction CapabilityCard({ capability }: { capability: AiCapability }): React.JSX.Element {\n return (\n <Box\n data-testid={`ai-capability-${capability.id}`}\n sx={{\n p: 2.5,\n borderRadius: 3,\n border: 1,\n borderColor: \"divider\",\n bgcolor: \"background.paper\",\n height: \"100%\",\n // Static transition string: safe to cross the server→client boundary.\n transition: \"border-color 200ms, box-shadow 200ms, transform 200ms\",\n \"&:hover\": { borderColor: \"primary.main\", boxShadow: 3, transform: \"translateY(-3px)\" },\n }}\n >\n <Box\n sx={{\n width: 44,\n height: 44,\n borderRadius: 2,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n bgcolor: \"primary.main\",\n color: \"primary.contrastText\",\n mb: 1.5,\n }}\n >\n <CapabilityIcon id={capability.id} fontSize={26} />\n </Box>\n <Text variant=\"body\" weight=\"bold\" as=\"h3\">\n {capability.title}\n </Text>\n <Box\n data-testid={`ai-capability-prompt-${capability.id}`}\n sx={{\n mt: 1,\n px: 1.5,\n py: 1,\n borderRadius: 2,\n borderBottomLeftRadius: 4,\n bgcolor: \"action.hover\",\n border: 1,\n borderColor: \"divider\",\n }}\n >\n <Text variant=\"body\" size=\"sm\" as=\"p\" color=\"secondary\">\n {capability.detail}\n </Text>\n </Box>\n </Box>\n );\n}\n\n/**\n * Marketing block for the AI integration: a headline + a responsive grid of\n * capability cards. Shown on the onboarding landing (before the owner starts) to\n * sell the feature — \"here's what the assistant does for you\". `capabilities`\n * and `copy` are REQUIRED host copy — the package ships no default sentence\n * (FUT-760).\n */\nexport function AiCapabilities({\n capabilities,\n copy,\n}: {\n capabilities: readonly AiCapability[];\n copy: AiCapabilitiesCopy;\n}): React.JSX.Element {\n return (\n <Box data-testid=\"ai-capability-examples\" sx={{ width: \"100%\" }}>\n <Box sx={{ mb: 3 }}>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n {copy.heading}\n </Text>\n <Box sx={{ mt: 0.5 }}>\n <Text variant=\"body\" size=\"sm\" as=\"p\" color=\"secondary\">\n {copy.subheading}\n </Text>\n </Box>\n </Box>\n <Box\n sx={{\n display: \"grid\",\n gap: 3,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\", md: \"repeat(4, 1fr)\" },\n }}\n >\n {capabilities.map((capability) => (\n <CapabilityCard key={capability.id} capability={capability} />\n ))}\n </Box>\n </Box>\n );\n}\n","import AutoAwesomeIcon from \"@mui/icons-material/AutoAwesome\";\nimport CategoryIcon from \"@mui/icons-material/Category\";\nimport HubIcon from \"@mui/icons-material/Hub\";\nimport Inventory2Icon from \"@mui/icons-material/Inventory2\";\nimport QueryStatsIcon from \"@mui/icons-material/QueryStats\";\nimport ReceiptLongIcon from \"@mui/icons-material/ReceiptLong\";\n\nimport { Box } from \"@12-apps/ui/mui/Box\";\n\nimport type { AiHostBrand } from \"../guide\";\n\n/**\n * Brand accents for the host avatars. These are deliberately hardcoded (not\n * theme tokens): they are BRAND marks whose recognizability depends on the\n * vendor's own accent colour, so the \"always semantic colours\" rule doesn't\n * apply here. The glyphs are simple, original stand-ins — not the vendors'\n * proprietary logo artwork.\n */\nconst BRAND: Record<AiHostBrand, { bg: string; Icon: typeof AutoAwesomeIcon; label: string }> = {\n claude: { bg: \"#D97757\", Icon: AutoAwesomeIcon, label: \"Claude (Anthropic)\" },\n openai: { bg: \"#10A37F\", Icon: HubIcon, label: \"OpenAI\" },\n};\n\n/** A round brand chip: the vendor accent + a simple glyph. */\nexport function HostBrandAvatar({\n brand,\n size = 40,\n}: {\n brand: AiHostBrand;\n size?: number;\n}): React.JSX.Element {\n const { bg, Icon, label } = BRAND[brand];\n return (\n <Box\n aria-label={label}\n sx={{\n width: size,\n height: size,\n borderRadius: \"50%\",\n bgcolor: bg,\n color: \"#fff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n }}\n >\n <Icon sx={{ fontSize: size * 0.55 }} />\n </Box>\n );\n}\n\nconst CAPABILITY_ICON: Record<string, typeof AutoAwesomeIcon> = {\n orders: ReceiptLongIcon,\n inventory: Inventory2Icon,\n catalog: CategoryIcon,\n sales: QueryStatsIcon,\n};\n\n/** The icon for a capability card, by capability id (falls back to a sparkle). */\nexport function CapabilityIcon({\n id,\n fontSize = 24,\n}: {\n id: string;\n fontSize?: number;\n}): React.JSX.Element {\n const Icon = CAPABILITY_ICON[id] ?? AutoAwesomeIcon;\n return <Icon sx={{ fontSize }} />;\n}\n","import { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\n/** One entry of a landing's trust/feature strip. */\nexport interface FeatureBadgeItem {\n icon: React.ReactNode;\n label: string;\n caption: string;\n}\n\n/**\n * One item of an onboarding landing's trust/feature strip: a paper icon tile\n * (primary-coloured glyph) with a two-line label + caption.\n */\nexport function FeatureBadge({ icon, label, caption }: FeatureBadgeItem): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1.5} alignItems=\"flex-start\">\n <Box\n sx={{\n width: 36,\n height: 36,\n borderRadius: 2,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n bgcolor: \"background.paper\",\n color: \"primary.main\",\n border: 1,\n borderColor: \"divider\",\n flexShrink: 0,\n }}\n >\n {icon}\n </Box>\n <Box>\n <Text variant=\"body\" size=\"sm\" weight=\"bold\" as=\"p\">\n {label}\n </Text>\n <Text variant=\"caption\" color=\"secondary\" as=\"p\">\n {caption}\n </Text>\n </Box>\n </Stack>\n );\n}\n","import type { AiConnectionSummaryCopy } from \"./copy\";\nimport { providerForHostId, type AiHostGuide, type AiProvider } from \"../guide\";\n\n/**\n * Pure helpers + the connection type shared by the AI-onboarding flow steps\n * (`ai-flow-steps.tsx`) and the orchestration/status board (`ai-steps.tsx`),\n * kept here so neither JSX module has to import the other (no import cycle).\n */\n\n/** The live connection surfaced from the server (empty list when none). */\nexport interface AiConnection {\n clientName: string | null;\n /**\n * The provider this connection is attributed to (derived server-side from the\n * OAuth client's redirect URIs / confirmed by `announceAiConnection`). `null`\n * for a legacy connection recorded before attribution existed — matched\n * best-effort to whichever host the owner is connecting.\n */\n host: AiProvider | null;\n lastActiveAt: Date;\n}\n\n/** Friendly provider names for the connected-state title (\"Claude Conectado\"). */\nconst PROVIDER_LABEL: Record<AiProvider, string> = {\n claude: \"Claude\",\n chatgpt: \"ChatGPT\",\n codex: \"Codex\",\n};\n\n/** Resolve a persisted host id to its guide (falls back to the first host). */\nexport function resolveHost(hosts: readonly AiHostGuide[], hostId: unknown): AiHostGuide {\n const found = hosts.find((h) => h.id === hostId) ?? hosts[0];\n if (!found) throw new Error(\"resolveHost: hosts array must not be empty\");\n return found;\n}\n\n/** Friendly label for a persisted host id (falls back to a generic word). */\nexport function hostLabel(hosts: readonly AiHostGuide[], hostId: unknown): string {\n return hosts.find((h) => h.id === hostId)?.label ?? \"seu assistente\";\n}\n\n/**\n * The live connection for a given host, or null. A connection is matched by its\n * derived provider; a legacy `null`-host connection matches best-effort (so the\n * pre-attribution single-connection behavior still works).\n */\nexport function connectionForHost(\n connections: readonly AiConnection[],\n hostId: unknown,\n): AiConnection | null {\n const provider = typeof hostId === \"string\" ? providerForHostId(hostId) : null;\n if (!provider) return connections.find((c) => c.host === null) ?? connections[0] ?? null;\n return (\n connections.find((c) => c.host === provider) ?? connections.find((c) => c.host === null) ?? null\n );\n}\n\n/** The recency line from a timestamp, in the host's own words. */\nexport function activeAgo(date: Date, copy: AiConnectionSummaryCopy): string {\n const minutes = Math.max(0, Math.floor((Date.now() - date.getTime()) / 60_000));\n if (minutes < 1) return copy.activeNow;\n if (minutes < 60) return copy.activeMinutes(minutes);\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return copy.activeHours(hours);\n return copy.activeDays(Math.floor(hours / 24));\n}\n\n/** The most-recently-active connection across all providers (null when none). */\nfunction mostRecent(connections: readonly AiConnection[]): AiConnection | null {\n return connections.reduce<AiConnection | null>(\n (best, c) => (!best || c.lastActiveAt.getTime() > best.lastActiveAt.getTime() ? c : best),\n null,\n );\n}\n\n/** The configured-state TITLE, naming the connected assistant(s) — FUT req (F). */\nexport function connectedTitle(\n connections: readonly AiConnection[],\n hosts: readonly AiHostGuide[],\n connectedHostId: string | undefined,\n copy: AiConnectionSummaryCopy,\n): string {\n const providers = [...new Set(connections.map((c) => c.host).filter((h): h is AiProvider => h !== null))];\n if (providers.length === 1) return `${PROVIDER_LABEL[providers[0]!]} ${copy.connectedSuffix}`;\n if (providers.length > 1) {\n return copy.connectedSeveral(providers.map((p) => PROVIDER_LABEL[p]).join(\", \"));\n }\n // Legacy connection with no attributed provider — name the completed host.\n if (connections.length > 0) return `${hostLabel(hosts, connectedHostId)} ${copy.connectedSuffix}`;\n return copy.connectedGeneric;\n}\n\n/** The completed summary line (second line) for the configured-state header. */\nexport function connectedSummary(\n connections: readonly AiConnection[],\n copy: AiConnectionSummaryCopy,\n): string {\n const recent = mostRecent(connections);\n if (!recent) return copy.configured;\n return activeAgo(recent.lastActiveAt, copy);\n}\n","\"use client\";\n\nimport type { McpAiCopy } from \"./copy\";\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\nimport OpenInNewIcon from \"@mui/icons-material/OpenInNew\";\nimport { useEffect, useState } from \"react\";\n\nimport { type GuidedNav } from \"@12-apps/onboarding\";\nimport { Progress } from \"@12-apps/ui/data-display/Progress\";\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostConfigureStage, AiHostGuide } from \"../guide\";\nimport { activeAgo, connectionForHost, hostLabel, type AiConnection } from \"./ai-connection-utils\";\nimport {\n EndpointCopyBlock,\n HostConnectHeader,\n HostDocsLink,\n HostOpenButton,\n HostStepList,\n PromptCopyBlock,\n} from \"./host-connect-guide\";\n\n/** The host's connect steps split across the Configurar / Conectar stages. */\nconst CONFIGURE_STEP_COUNT = 3;\n\n/** How often the Confirmar step re-checks the live connection while waiting. */\nconst POLL_INTERVAL_MS = 3000;\n\n/** A step's continue/back controls (Voltar left, primary next right). */\nfunction StepNav({\n nav,\n onNext,\n nextLabel,\n nextDisabled = false,\n nextTestId,\n copy,\n}: {\n nav: GuidedNav;\n onNext: () => void;\n nextLabel?: string;\n nextDisabled?: boolean;\n nextTestId?: string;\n copy: McpAiCopy;\n}): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1} alignItems=\"center\" justifyContent=\"space-between\">\n <Button variant=\"ghost\" onClick={() => nav.back()} data-testid=\"ai-step-back\">{copy.flow.back}</Button>\n <Button onClick={onNext} disabled={nextDisabled} data-testid={nextTestId}>\n {nextLabel}\n </Button>\n </Stack>\n );\n}\n\n/** Step 2 — copy the store URL; copying is the action that advances the wizard. */\nexport function CopyUrlStep({\n nav,\n endpointUrl,\n copy,\n}: {\n nav: GuidedNav;\n endpointUrl: string;\n copy: McpAiCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={3} data-testid=\"ai-copy-step\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n {copy.flow.copyUrlTitle}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.flow.urlCaption}\n </Text>\n </Box>\n <EndpointCopyBlock copy={copy.connectGuide} flowCopy={copy.flow} endpointUrl={endpointUrl} copied={false} onCopy={() => nav.next()} />\n <Box>\n <Button variant=\"ghost\" onClick={() => nav.back()} data-testid=\"ai-step-back\">{copy.flow.back}</Button>\n </Box>\n </Stack>\n );\n}\n\n/** Step 3 — open the host's connectors and add + configure the custom connector. */\nexport function ConfigureStep({\n nav,\n host,\n copy,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n copy: McpAiCopy;\n}): React.JSX.Element {\n // Hosts with no direct link (e.g. Claude Desktop) have nothing to open, so\n // \"Próximo\" is available immediately; otherwise it unlocks on the open click.\n const [opened, setOpened] = useState(!host.link);\n return (\n <Stack spacing={2.5} data-testid=\"ai-configure-step\">\n <HostConnectHeader copy={copy.connectGuide} host={host} />\n <HostOpenButton host={host} onOpen={() => setOpened(true)} />\n <HostStepList steps={host.steps.slice(0, CONFIGURE_STEP_COUNT)} start={1} />\n <HostDocsLink copy={copy.connectGuide} host={host} />\n <StepNav copy={copy} nav={nav} onNext={() => nav.next()} nextDisabled={!opened} nextTestId=\"ai-configure-next\" />\n </Stack>\n );\n}\n\n/**\n * One stage of a host's per-stage configuration (e.g. ChatGPT's \"enable\n * developer mode\" then \"configurar\"). Each stage has its OWN deep link — opening\n * it unlocks \"Próximo\" — and its own instructions.\n */\nexport function ConfigureStageStep({\n nav,\n host,\n stage,\n copy,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n stage: AiHostConfigureStage;\n copy: McpAiCopy;\n}): React.JSX.Element {\n const [opened, setOpened] = useState(!stage.link);\n return (\n <Stack spacing={2.5} data-testid={`ai-stage-${stage.id}`}>\n <HostConnectHeader copy={copy.connectGuide} host={host} />\n {stage.link && (\n <Box>\n <Button\n onClick={() => {\n window.open(stage.link!.url, \"_blank\", \"noopener,noreferrer\");\n setOpened(true);\n }}\n data-testid={`ai-stage-link-${stage.id}`}\n >\n {stage.link.label}\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n )}\n <HostStepList steps={stage.steps} start={1} />\n <HostDocsLink copy={copy.connectGuide} host={host} />\n <StepNav copy={copy}\n nav={nav}\n onNext={() => nav.next()}\n nextDisabled={!opened}\n nextTestId={`ai-stage-next-${stage.id}`}\n />\n </Stack>\n );\n}\n\n/** Step 4 — connect: log in, authorize and activate the connector. */\nexport function ConnectStep({\n nav,\n host,\n connectPrompt,\n copy,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n connectPrompt: string;\n copy: McpAiCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={2.5} data-testid=\"ai-connect-step\">\n <HostConnectHeader copy={copy.connectGuide} host={host} />\n <HostStepList steps={host.steps.slice(CONFIGURE_STEP_COUNT)} start={CONFIGURE_STEP_COUNT + 1} />\n <PromptCopyBlock flowCopy={copy.flow}\n title={copy.flow.pasteTitle}\n caption={copy.flow.promptCaption}\n message={connectPrompt}\n />\n <HostDocsLink copy={copy.connectGuide} host={host} />\n <StepNav copy={copy} nav={nav} onNext={() => nav.next()} nextLabel={copy.flow.advance} nextTestId=\"ai-connect-done\" />\n </Stack>\n );\n}\n\n/**\n * Simplified-flow step (host has a published `pluginUrl`): open the one-click\n * plugin (install + authorize), then paste the prompt asking the assistant to\n * connect. No URL to copy, no manual connector. The next step (Confirmar) waits.\n */\nexport function InstallStep({\n nav,\n host,\n connectPrompt,\n copy,\n}: {\n nav: GuidedNav;\n host: AiHostGuide;\n connectPrompt: string;\n copy: McpAiCopy;\n}): React.JSX.Element {\n const [opened, setOpened] = useState(false);\n return (\n <Stack spacing={2.5} data-testid=\"ai-install-step\">\n <HostConnectHeader copy={copy.connectGuide} host={host} />\n <Text variant=\"body\" as=\"p\" color=\"secondary\">\n {copy.flow.installBody}\n </Text>\n {host.pluginUrl && (\n <Box>\n <Button\n onClick={() => {\n window.open(host.pluginUrl!, \"_blank\", \"noopener,noreferrer\");\n setOpened(true);\n }}\n data-testid=\"ai-install-open\"\n >\n {copy.flow.installAction}\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n )}\n <PromptCopyBlock flowCopy={copy.flow}\n title={copy.flow.askTitle}\n caption={copy.flow.pasteInstallCaption}\n message={connectPrompt}\n />\n <HostDocsLink copy={copy.connectGuide} host={host} />\n <StepNav copy={copy}\n nav={nav}\n onNext={() => nav.next()}\n nextLabel={copy.flow.advance}\n nextDisabled={!opened}\n nextTestId=\"ai-install-done\"\n />\n </Stack>\n );\n}\n\n/**\n * Step 5: auto-detect the live connection. While waiting it polls the server\n * (the sign-in / `announceAiConnection` tool call registers the connection\n * server-side), showing a spinner — the owner never clicks \"verify\". Completes\n * when the selected host's connection appears.\n */\nexport function ConfirmStep({\n nav,\n connections,\n hosts,\n onRetest,\n copy,\n}: {\n nav: GuidedNav;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n onRetest: () => void;\n copy: McpAiCopy;\n}): React.JSX.Element {\n const selectedHostId = nav.data.selectedHost as string | undefined;\n const connection = connectionForHost(connections, selectedHostId);\n const label = connection?.clientName ?? hostLabel(hosts, selectedHostId);\n\n // Auto-detect: re-check on an interval until the connection shows up. The\n // interval is cleared as soon as `connection` is non-null (and on unmount).\n useEffect(() => {\n if (connection) return undefined;\n const id = setInterval(() => onRetest(), POLL_INTERVAL_MS);\n return () => clearInterval(id);\n }, [connection, onRetest]);\n\n if (connection) {\n return (\n <Stack spacing={2} data-testid=\"ai-confirm-connected\">\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <CheckCircleIcon sx={{ color: \"success.main\" }} />\n <Box>\n <Text variant=\"body\" weight=\"bold\" as=\"p\">\n {copy.flow.connectedTo(label)}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {activeAgo(connection.lastActiveAt, copy.summary)}\n </Text>\n </Box>\n </Stack>\n <Box>\n <Button onClick={() => nav.complete({ connectedHost: selectedHostId })}>{copy.flow.finish}</Button>\n </Box>\n </Stack>\n );\n }\n\n return (\n <Stack spacing={2.5} data-testid=\"ai-confirm-waiting\">\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <Progress variant=\"circular\" circularSize={22} thickness={4} dataTestId=\"ai-confirm-spinner\" />\n <Box>\n <Text variant=\"body\" weight=\"bold\" as=\"p\">\n {copy.flow.waitingTitle}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.flow.waitingBody(label)}\n </Text>\n </Box>\n </Stack>\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"ghost\" size=\"sm\" onClick={onRetest} data-testid=\"ai-confirm-retest\">\n {copy.flow.testNow}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => nav.back()}>{copy.flow.back}</Button>\n </Stack>\n </Stack>\n );\n}\n","\"use client\";\n\nimport type { AiConnectGuideCopy, AiFlowCopy } from \"./copy\";\nimport CheckIcon from \"@mui/icons-material/Check\";\nimport ContentCopyOutlinedIcon from \"@mui/icons-material/ContentCopyOutlined\";\nimport OpenInNewIcon from \"@mui/icons-material/OpenInNew\";\nimport { useState } from \"react\";\n\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\nimport { McpEndpointUrl } from \"./mcp-endpoint-url\";\n\n/**\n * The store's MCP endpoint URL with a blue \"Copiar\" button (the display-only\n * field defers the copy to this button). Controlled: `copied` flips the label to\n * \"Copiado\" and `onCopy` fires after the clipboard write — the wizard uses it to\n * unlock the \"Próximo\" button on the Copiar-URL step.\n */\nexport function EndpointCopyBlock({\n endpointUrl,\n copied,\n onCopy,\n flowCopy,\n copy,\n}: {\n endpointUrl: string;\n copied: boolean;\n onCopy: () => void;\n flowCopy: AiFlowCopy;\n copy: AiConnectGuideCopy;\n}): React.JSX.Element {\n const handleClick = (): void => {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(endpointUrl).catch(() => undefined);\n }\n onCopy();\n };\n\n return (\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n border: 1,\n borderColor: \"primary.main\",\n bgcolor: \"action.hover\",\n }}\n >\n <Text variant=\"caption\" as=\"p\" weight=\"bold\">\n {copy.urlLabel}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.urlHint}\n </Text>\n <Box sx={{ mt: 1 }}>\n <McpEndpointUrl url={endpointUrl} copyable={false} />\n </Box>\n <Box sx={{ mt: 1.5 }}>\n <Button onClick={handleClick} data-testid=\"ai-copy-endpoint\">\n {copied ? (\n <CheckIcon sx={{ fontSize: 18, mr: 0.5 }} />\n ) : (\n <ContentCopyOutlinedIcon sx={{ fontSize: 18, mr: 0.5 }} />\n )}\n {copied ? flowCopy.copied : flowCopy.copyUrl}\n </Button>\n </Box>\n </Box>\n );\n}\n\n/**\n * A copyable multi-line message block (preserves line breaks). Used on the\n * Conectar step for the prompt the owner pastes into the assistant so it\n * identifies itself and calls a tool (which registers the connection).\n */\nexport function PromptCopyBlock({\n title,\n caption,\n message,\n flowCopy,\n}: {\n title: string;\n caption: string;\n message: string;\n flowCopy: AiFlowCopy;\n}): React.JSX.Element {\n const [copied, setCopied] = useState(false);\n\n const handleClick = (): void => {\n if (typeof navigator !== \"undefined\" && navigator.clipboard) {\n void navigator.clipboard.writeText(message).catch(() => undefined);\n }\n setCopied(true);\n };\n\n return (\n <Box\n sx={{\n p: 2,\n borderRadius: 2,\n border: 1,\n borderColor: \"primary.main\",\n bgcolor: \"action.hover\",\n }}\n >\n <Text variant=\"caption\" as=\"p\" weight=\"bold\">\n {title}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {caption}\n </Text>\n <Box\n sx={{\n mt: 1,\n p: 1.5,\n borderRadius: 1,\n border: 1,\n borderColor: \"divider\",\n bgcolor: \"background.paper\",\n whiteSpace: \"pre-line\",\n }}\n >\n <Text variant=\"body\" size=\"sm\" as=\"p\">\n {message}\n </Text>\n </Box>\n <Box sx={{ mt: 1.5 }}>\n <Button onClick={handleClick} data-testid=\"ai-copy-prompt\">\n {copied ? (\n <CheckIcon sx={{ fontSize: 18, mr: 0.5 }} />\n ) : (\n <ContentCopyOutlinedIcon sx={{ fontSize: 18, mr: 0.5 }} />\n )}\n {copied ? flowCopy.copied : flowCopy.copyMessage}\n </Button>\n </Box>\n </Box>\n );\n}\n\n/** The brand mark + \"Conectar no <host>\" header shared by the connect sub-steps. */\nexport function HostConnectHeader({\n host,\n copy,\n}: {\n host: AiHostGuide;\n copy: AiConnectGuideCopy;\n}): React.JSX.Element {\n return (\n <Stack direction=\"row\" spacing={1.5} alignItems=\"center\">\n <HostBrandAvatar brand={host.brand} size={36} />\n <Text variant=\"heading\" size=\"sm\" as=\"h3\">\n {copy.connectOn(host.label)}\n </Text>\n </Stack>\n );\n}\n\n/**\n * The primary direct-link button to a host's connector settings (nothing when it\n * has none). `onOpen` fires after the link opens so the Configurar step can\n * unlock its \"Próximo\" only once the owner has actually gone to the connectors.\n */\nexport function HostOpenButton({\n host,\n onOpen,\n}: {\n host: AiHostGuide;\n onOpen?: () => void;\n}): React.JSX.Element | null {\n if (!host.link) return null;\n return (\n <Box>\n <Button\n onClick={() => {\n window.open(host.link!.url, \"_blank\", \"noopener,noreferrer\");\n onOpen?.();\n }}\n data-testid={`ai-host-link-${host.id}`}\n >\n {host.link.label}\n <OpenInNewIcon sx={{ fontSize: 16, ml: 0.5 }} />\n </Button>\n </Box>\n );\n}\n\n/** A \"Para mais informações\" reference to the host's official connector docs. */\nexport function HostDocsLink({ host,\n copy,\n}: { host: AiHostGuide;\n copy: AiConnectGuideCopy;}): React.JSX.Element | null {\n if (!host.docs) return null;\n return (\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.moreInfo}{\" \"}\n <Box\n component=\"a\"\n href={host.docs.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-testid={`ai-host-docs-${host.id}`}\n sx={{ color: \"primary.main\", textDecoration: \"underline\" }}\n >\n {host.docs.label}\n </Box>\n .\n </Text>\n );\n}\n\n/**\n * A numbered slice of a host's connect steps. `start` keeps the numbering\n * continuous when the steps are split across wizard stages (e.g. the Conectar\n * stage continues at 4 after Configurar showed 1–3).\n */\nexport function HostStepList({\n steps,\n start = 1,\n}: {\n steps: readonly string[];\n start?: number;\n}): React.JSX.Element {\n return (\n <Box component=\"ol\" start={start} sx={{ m: 0, pl: 3 }}>\n {steps.map((step, index) => (\n <Box component=\"li\" key={index} sx={{ mb: 1 }}>\n <Text variant=\"body\" as=\"span\">\n {step}\n </Text>\n </Box>\n ))}\n </Box>\n );\n}\n","\"use client\";\n\nimport { Code } from \"@12-apps/ui/typography/Code\";\n\n/**\n * The store's MCP endpoint URL. Client component because the copy interaction\n * needs the browser clipboard — the `@12-apps/ui` Code component provides the copy\n * affordance (`copyable`). Pass `copyable={false}` for a display-only field when\n * an external control owns the copy action (e.g. the connect flow's blue Copiar\n * button, which also gates the following steps on the copy).\n */\nexport function McpEndpointUrl({\n url,\n copyable = true,\n}: {\n url: string;\n copyable?: boolean;\n}): React.JSX.Element {\n return (\n <Code variant=\"block\" copyable={copyable} data-testid=\"mcp-endpoint-url\">\n {url}\n </Code>\n );\n}\n","\"use client\";\n\nimport type { AiStatusBoardCopy } from \"./copy\";\nimport AddLinkOutlinedIcon from \"@mui/icons-material/AddLinkOutlined\";\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\nimport LinkOffOutlinedIcon from \"@mui/icons-material/LinkOffOutlined\";\nimport MenuBookOutlinedIcon from \"@mui/icons-material/MenuBookOutlined\";\n\nimport { ConfirmButton } from \"@12-apps/ui/feedback/ConfirmAction\";\nimport { Button } from \"@12-apps/ui/form/Button\";\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\n\n/**\n * Revoke a host's access. Returning a promise holds the confirmation popup in\n * its pending state until the write settles, and a rejection keeps it open\n * carrying the reason — so the owner sees the disconnect finish or fail.\n */\nexport type DisconnectHandler = (hostId: string) => void | Promise<unknown>;\n\n/** One assistant's connection state. */\nexport interface HostStatus {\n host: AiHostGuide;\n connected: boolean;\n /** Freeform activity line for a connected host (e.g. \"ativo há 3 min\"). */\n detail?: string;\n}\n\n/**\n * The right-hand side of a CONNECTED box: the green pill, then the two things\n * the pill alone left the owner unable to do.\n *\n * \"{copy.instructions}\" exists because the setup steps were reachable ONLY from a RED\n * card's \"Conectar\" — so on an all-green board there was no way to re-read how\n * any of them was connected, which is exactly when someone re-doing the setup on\n * a second machine needs them. It re-enters the same flow that button does.\n *\n * \"Desconectar\" is only drawn when the app supplies a revoke path: a board with\n * nowhere to send the revoke must not offer a button that does nothing.\n */\nfunction ConnectedControls({\n host,\n onConnect,\n onDisconnect,\n copy,\n}: {\n host: AiHostGuide;\n onConnect: (hostId: string) => void;\n onDisconnect?: DisconnectHandler;\n copy: AiStatusBoardCopy;\n}): React.JSX.Element {\n return (\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n justifyContent=\"flex-end\"\n // Wraps rather than squeezing: three controls do not fit a half-width\n // card at every breakpoint.\n sx={{ flexShrink: 0, flexWrap: \"wrap\", rowGap: 0.5 }}\n >\n <Box\n sx={{\n px: 1,\n py: 0.25,\n borderRadius: 999,\n bgcolor: \"success.main\",\n color: \"success.contrastText\",\n }}\n >\n <Text variant=\"caption\" weight=\"bold\" as=\"span\">\n Conectado\n </Text>\n </Box>\n <Button\n variant=\"text\"\n size=\"sm\"\n onClick={() => onConnect(host.id)}\n data-testid={`ai-status-instructions-${host.id}`}\n >\n <MenuBookOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n {copy.instructions}\n </Button>\n {onDisconnect ? (\n <ConfirmButton\n variant=\"outline\"\n color=\"danger\"\n size=\"sm\"\n onClick={() => onDisconnect(host.id)}\n confirm={{\n title: copy.disconnectTitle,\n entityName: host.label,\n description:\n copy.disconnectBody,\n confirmText: copy.disconnectConfirm,\n dataTestId: `ai-status-disconnect-confirm-${host.id}`,\n }}\n data-testid={`ai-status-disconnect-${host.id}`}\n >\n <LinkOffOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n Desconectar\n </ConfirmButton>\n ) : null}\n </Stack>\n );\n}\n\n/** A single green (connected) / red (to connect) status box for one assistant. */\nfunction StatusBox({\n status,\n onConnect,\n onDisconnect,\n copy,\n}: {\n status: HostStatus;\n onConnect: (hostId: string) => void;\n onDisconnect?: DisconnectHandler;\n copy: AiStatusBoardCopy;\n}): React.JSX.Element {\n const { host, connected, detail } = status;\n return (\n <Box\n data-testid={`ai-status-${host.id}`}\n data-connected={connected}\n sx={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n p: 2,\n borderRadius: 3,\n border: 1,\n borderColor: connected ? \"success.main\" : \"error.main\",\n bgcolor: \"background.paper\",\n }}\n >\n <HostBrandAvatar brand={host.brand} size={36} />\n <Box sx={{ minWidth: 0, flexGrow: 1 }}>\n <Stack direction=\"row\" spacing={0.75} alignItems=\"center\">\n <Text variant=\"body\" weight=\"bold\" as=\"span\">\n {host.label}\n </Text>\n {connected ? <CheckCircleIcon sx={{ fontSize: 18, color: \"success.main\" }} /> : null}\n </Stack>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {connected ? (detail ?? copy.connected) : copy.notConnected}\n </Text>\n </Box>\n {connected ? (\n <ConnectedControls copy={copy} host={host} onConnect={onConnect} onDisconnect={onDisconnect} />\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onConnect(host.id)}\n data-testid={`ai-status-connect-${host.id}`}\n >\n <AddLinkOutlinedIcon sx={{ fontSize: 16, mr: 0.5 }} />\n Conectar\n </Button>\n )}\n </Box>\n );\n}\n\n/**\n * The completed-state status board for the AI integration: every assistant as a\n * box — green when connected, red when still to connect (with a \"Conectar\"\n * button that re-enters the guided flow for that host). Each connection is\n * attributed to its provider (derived from the OAuth client + confirmed by\n * `announceAiConnection`), so several assistants can show connected at once.\n *\n * A connected box carries two more controls, because the pill it used to show\n * alone was a dead end in both directions: \"{copy.instructions}\" re-enters the host's\n * setup steps (previously reachable only from a RED card, so an all-green board\n * hid them entirely), and \"Desconectar\" — when the app passes `onDisconnect` —\n * revokes access, which nothing in the UI could do at all.\n */\nexport function AiStatusBoard({\n statuses,\n onConnect,\n onDisconnect,\n copy,\n}: {\n statuses: readonly HostStatus[];\n onConnect: (hostId: string) => void;\n /** Revoke this host's access. Omit to render a read-only board. */\n onDisconnect?: DisconnectHandler;\n copy: AiStatusBoardCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={2} data-testid=\"ai-status-board\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n {copy.boardTitle}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.boardCaption}\n </Text>\n </Box>\n <Box\n sx={{\n display: \"grid\",\n gap: 2,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\n }}\n >\n {statuses.map((status) => (\n <StatusBox copy={copy}\n key={status.host.id}\n status={status}\n onConnect={onConnect}\n onDisconnect={onDisconnect}\n />\n ))}\n </Box>\n </Stack>\n );\n}\n","\"use client\";\n\nimport type { AiHostSelectCopy } from \"./copy\";\nimport CheckCircleIcon from \"@mui/icons-material/CheckCircle\";\n\nimport { Box } from \"@12-apps/ui/mui/Box\";\nimport { Stack } from \"@12-apps/ui/mui/Stack\";\nimport { Text } from \"@12-apps/ui/typography/Text\";\n\nimport type { AiHostGuide } from \"../guide\";\nimport { HostBrandAvatar } from \"./ai-icons\";\n\n/** One selectable assistant card (brand mark + name + kind, checked when active). */\nfunction HostCard({\n host,\n active,\n onSelect,\n}: {\n host: AiHostGuide;\n active: boolean;\n onSelect: () => void;\n}): React.JSX.Element {\n return (\n <Box\n component=\"button\"\n type=\"button\"\n onClick={onSelect}\n aria-pressed={active}\n data-testid={`ai-host-card-${host.id}`}\n sx={{\n position: \"relative\",\n display: \"flex\",\n alignItems: \"center\",\n gap: 1.5,\n p: 2,\n borderRadius: 3,\n cursor: \"pointer\",\n textAlign: \"left\",\n width: \"100%\",\n border: 2,\n borderColor: active ? \"primary.main\" : \"divider\",\n bgcolor: active ? \"action.selected\" : \"background.paper\",\n transition: (theme) => theme.transitions.create([\"border-color\", \"background-color\"]),\n \"&:hover\": { borderColor: \"primary.main\" },\n }}\n >\n <HostBrandAvatar brand={host.brand} size={40} />\n <Box sx={{ minWidth: 0 }}>\n <Text variant=\"body\" weight=\"bold\" as=\"span\">\n {host.label}\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {host.kind}\n </Text>\n </Box>\n {active && (\n <CheckCircleIcon\n sx={{ position: \"absolute\", top: 10, right: 10, fontSize: 20, color: \"primary.main\" }}\n />\n )}\n </Box>\n );\n}\n\n/**\n * Step 1 of the guided AI connect flow: the owner picks a single assistant\n * (Claude.ai, Claude Desktop, ChatGPT, Codex) from a card grid. Picking a card\n * advances straight to the next step — no separate \"Próximo\" button. Selection\n * is controlled (persisted by the onboarding flow) so a refresh resumes with the\n * same assistant highlighted.\n */\nexport function HostSelectStep({\n hosts,\n selectedId,\n onSelect,\n copy,\n}: {\n hosts: readonly AiHostGuide[];\n selectedId: string | null;\n onSelect: (hostId: string) => void;\n copy: AiHostSelectCopy;\n}): React.JSX.Element {\n return (\n <Stack spacing={3} data-testid=\"ai-host-select\">\n <Box>\n <Text variant=\"heading\" size=\"sm\" as=\"h2\">\n Escolha o seu assistente\n </Text>\n <Text variant=\"caption\" as=\"p\" color=\"secondary\">\n {copy.caption}\n </Text>\n </Box>\n\n <Box\n sx={{\n display: \"grid\",\n gap: 2,\n gridTemplateColumns: { xs: \"1fr\", sm: \"1fr 1fr\" },\n }}\n >\n {hosts.map((host) => (\n <HostCard\n key={host.id}\n host={host}\n active={host.id === selectedId}\n onSelect={() => onSelect(host.id)}\n />\n ))}\n </Box>\n </Stack>\n );\n}\n","\"use client\";\n\nimport type { McpAiCopy } from \"./copy\";\nimport { type GuidedNav, type GuidedStep } from \"@12-apps/onboarding\";\n\nimport { providerForHostId, type AiHostGuide } from \"../guide\";\nimport { activeAgo, resolveHost, type AiConnection } from \"./ai-connection-utils\";\nimport {\n ConfigureStageStep,\n ConfigureStep,\n ConfirmStep,\n ConnectStep,\n CopyUrlStep,\n InstallStep,\n} from \"./ai-flow-steps\";\nimport { AiStatusBoard, type DisconnectHandler, type HostStatus } from \"./ai-status-board\";\nimport { HostSelectStep } from \"./host-select-step\";\n\nexport type { AiConnection } from \"./ai-connection-utils\";\nexport { connectedSummary, connectedTitle } from \"./ai-connection-utils\";\n\n/** The completed status board: green for each connected host, red for the rest. */\nexport function StatusBoard({\n nav,\n connections,\n hosts,\n onDisconnect,\n copy,\n}: {\n nav: GuidedNav;\n connections: readonly AiConnection[];\n hosts: readonly AiHostGuide[];\n onDisconnect?: DisconnectHandler;\n copy: McpAiCopy;\n}): React.JSX.Element {\n const legacyHostId = (nav.data.connectedHost ?? nav.data.selectedHost) as string | undefined;\n\n const statuses: HostStatus[] = hosts.map((host) => {\n const provider = providerForHostId(host.id);\n // Prefer a provider-attributed connection; fall back to a legacy null-host\n // connection only for the host the owner completed the flow with.\n const connection =\n (provider ? connections.find((c) => c.host === provider) : undefined) ??\n (host.id === legacyHostId ? connections.find((c) => c.host === null) : undefined) ??\n null;\n return {\n host,\n connected: connection !== null,\n detail: connection ? activeAgo(connection.lastActiveAt, copy.summary) : undefined,\n };\n });\n\n /** Re-enter this host's setup — the manual copy path, or its one-click install. */\n const goToConnect = (hostId: string): void => {\n nav.goTo(hosts.find((h) => h.id === hostId)?.pluginUrl ? \"install\" : \"copy\", {\n selectedHost: hostId,\n });\n };\n\n /**\n * Disconnecting the LAST assistant leaves the section configured with nothing\n * configured: a collapsed \"IA conectada\" summary hiding an all-red board, with\n * the setup instructions two clicks away. So when the revoke empties the\n * board, walk straight back into that host's instructions — the owner who just\n * cut an assistant off is the likeliest person to reconnect one, and the steps\n * are the only thing left worth showing.\n *\n * Cutting one of SEVERAL leaves the board meaningful, so it stays put.\n * `statuses` is the pre-revoke picture, which is what makes \"was that the last\n * one?\" answerable here without waiting for the app to re-read.\n */\n const disconnect: DisconnectHandler | undefined = onDisconnect\n ? async (hostId) => {\n await onDisconnect(hostId);\n const revoked = providerForHostId(hostId);\n const othersLive = statuses.some(\n (status) => status.connected && providerForHostId(status.host.id) !== revoked,\n );\n if (!othersLive) goToConnect(hostId);\n }\n : undefined;\n\n return (\n <AiStatusBoard copy={copy.statusBoard} statuses={statuses} onConnect={goToConnect} onDisconnect={disconnect} />\n );\n}\n\n/** The first step (host picker) — picking a card advances to the right path. */\nfunction selectStep(hosts: readonly AiHostGuide[], copy: McpAiCopy): GuidedStep {\n return {\n id: \"select\",\n label: copy.flow.steps.select,\n render: (nav: GuidedNav) => (\n <HostSelectStep\n hosts={hosts}\n selectedId={(nav.data.selectedHost as string | undefined) ?? null}\n copy={copy.hostSelect}\n onSelect={(hostId) =>\n nav.goTo(hosts.find((h) => h.id === hostId)?.pluginUrl ? \"install\" : \"copy\", {\n selectedHost: hostId,\n })\n }\n />\n ),\n };\n}\n\n/** The Copiar-URL step, shared by every manual flow. */\nfunction copyStep(endpointUrl: string, copy: McpAiCopy): GuidedStep {\n return {\n id: \"copy\",\n label: copy.flow.steps.copyUrl,\n render: (nav: GuidedNav) => <CopyUrlStep copy={copy} nav={nav} endpointUrl={endpointUrl} />,\n };\n}\n\n/**\n * The middle steps for the full manual flow. A host with `configureStages`\n * (e.g. ChatGPT) gets one step per stage — each with its own deep link — after\n * Copiar URL; otherwise the default copy → configure → connect split.\n */\nfunction manualMiddle(\n host: AiHostGuide,\n hosts: readonly AiHostGuide[],\n endpointUrl: string,\n connectPrompt: string,\n copy: McpAiCopy,\n): GuidedStep[] {\n if (host.configureStages && host.configureStages.length > 0) {\n return [\n copyStep(endpointUrl, copy),\n ...host.configureStages.map((stage) => ({\n id: stage.id,\n label: stage.label,\n render: (nav: GuidedNav) => (\n <ConfigureStageStep\n nav={nav}\n host={resolveHost(hosts, nav.data.selectedHost)}\n stage={stage}\n copy={copy}\n />\n ),\n })),\n ];\n }\n return [\n copyStep(endpointUrl, copy),\n {\n id: \"configure\",\n label: copy.flow.steps.configure,\n render: (nav: GuidedNav) => (\n <ConfigureStep\n nav={nav}\n host={resolveHost(hosts, nav.data.selectedHost)}\n copy={copy}\n />\n ),\n },\n {\n id: \"connect\",\n label: copy.flow.steps.connect,\n render: (nav: GuidedNav) => (\n <ConnectStep\n nav={nav}\n host={resolveHost(hosts, nav.data.selectedHost)}\n connectPrompt={connectPrompt}\n copy={copy}\n />\n ),\n },\n ];\n}\n\n/** The single middle step for the simplified plugin flow: install. */\nfunction simpleMiddle(\n hosts: readonly AiHostGuide[],\n connectPrompt: string,\n copy: McpAiCopy,\n): GuidedStep[] {\n return [\n {\n id: \"install\",\n label: copy.flow.steps.install,\n render: (nav: GuidedNav) => (\n <InstallStep\n nav={nav}\n host={resolveHost(hosts, nav.data.selectedHost)}\n connectPrompt={connectPrompt}\n copy={copy}\n />\n ),\n },\n ];\n}\n\n/**\n * Build the wizard's steps for the selected host's path: the simplified\n * `install` flow when the host has a published `pluginUrl`, the per-stage flow\n * when it declares `configureStages`, otherwise the full copy → configure →\n * connect flow. `select` and `confirm` bookend all of them.\n */\nexport function buildFlowSteps(opts: {\n host: AiHostGuide;\n hosts: readonly AiHostGuide[];\n endpointUrl: string;\n connectPrompt: string;\n connections: readonly AiConnection[];\n onRetest: () => void;\n copy: McpAiCopy;\n}): GuidedStep[] {\n const { host, hosts, endpointUrl, connectPrompt, connections, onRetest, copy } = opts;\n const middle = host.pluginUrl\n ? simpleMiddle(hosts, connectPrompt, copy)\n : manualMiddle(host, hosts, endpointUrl, connectPrompt, copy);\n const confirm: GuidedStep = {\n id: \"confirm\",\n label: copy.flow.steps.confirm,\n render: (nav: GuidedNav) => (\n <ConfirmStep\n nav={nav}\n connections={connections}\n hosts={hosts}\n onRetest={onRetest}\n copy={copy}\n />\n ),\n };\n return [selectStep(hosts, copy), ...middle, confirm];\n}\n","import type { McpAiCopy } from \"./copy\";\n\n/**\n * The pt-BR pack for the AI-integration screens — a NAMED constant a host\n * passes by hand, never a default.\n *\n * The filename is what exempts this file from the copy-portability gate:\n * Portuguese may ship, it may not be silent. Every sentence is VERBATIM what\n * the components used to render, so a host adopting it sees no change on\n * screen — what changes is that the words are chosen in a diff.\n */\nexport const PT_BR_MCP_AI_COPY: McpAiCopy = {\n capabilities: {\n heading: \"O que o assistente faz por você\",\n subheading: \"Sem planilhas, sem cliques — é só perguntar na conversa.\",\n },\n landing: {\n eyebrow: \"Integração com IA\",\n titleTail: \"à sua loja\",\n lede:\n \"Deixe o Claude, o ChatGPT e outros assistentes responderem sobre o seu cardápio, estoque e \" +\n \"pedidos — e executarem ações por você, direto na conversa. Com segurança e sem instalar nada.\",\n trust: [\n {\n id: \"login\",\n label: \"Usa o seu próprio login\",\n caption: \"Sem chaves ou credenciais extras\",\n },\n { id: \"install\", label: \"Sem instalar nada\", caption: \"Conecta em poucos minutos\" },\n {\n id: \"permissions\",\n label: \"Só o que você pode\",\n caption: \"As suas permissões, nada além\",\n },\n { id: \"surface\", label: \"Navegador ou app\", caption: \"Claude, ChatGPT, Codex\" },\n ],\n start: \"Começar\",\n },\n flow: {\n steps: {\n select: \"Escolher\",\n copyUrl: \"Copiar URL\",\n configure: \"Configurar\",\n connect: \"Conectar\",\n install: \"Instalar\",\n confirm: \"Confirmar\",\n },\n back: \"Voltar\",\n next: \"Próximo\",\n advance: \"Continuar\",\n finish: \"Concluir\",\n copyUrl: \"Copiar URL\",\n copied: \"Copiado\",\n copyMessage: \"Copiar mensagem\",\n copyUrlTitle: \"Copie a URL da sua loja\",\n urlCaption:\n \"É o único dado que você cola no assistente — ao copiar, seguimos para o próximo passo.\",\n promptCaption:\n \"Assim ele se conecta, se identifica (Claude, ChatGPT…) e registramos a conexão.\",\n askTitle: \"Peça ao assistente para conectar\",\n installBody:\n \"Abra o plugin da sua loja, clique em Instalar e autorize o acesso — sem copiar URL nem gerar credenciais.\",\n installAction: \"Instalar o plugin da loja\",\n pasteTitle: \"Cole esta mensagem no assistente\",\n pasteInstallCaption:\n \"Cole no assistente para ele se conectar, se identificar e confirmar o acesso.\",\n connectedTo: (hostLabel) => `${hostLabel} está conectado à sua loja.`,\n waitingTitle: \"Esperando conexão\",\n waitingBody: (hostLabel) =>\n `Assim que você autorizar o acesso no ${hostLabel}, ela aparece aqui automaticamente.`,\n testNow: \"Testar agora\",\n },\n statusBoard: {\n instructions: \"Instruções\",\n connected: \"Conectado\",\n notConnected: \"Ainda não conectado\",\n connect: \"Conectar\",\n disconnect: \"Desconectar\",\n disconnectTitle: \"Desconectar o assistente?\",\n disconnectBody:\n \"Ele perde o acesso à sua loja na hora. Para voltar a usar, será preciso conectar de novo.\",\n disconnectConfirm: \"Desconectar\",\n boardTitle: \"Assistentes conectados\",\n boardCaption: \"Em verde os que já operam a sua loja; em vermelho os que faltam conectar.\",\n },\n summary: {\n activeNow: \"ativo agora\",\n activeMinutes: (minutes) => `ativo há ${minutes} min`,\n activeHours: (hours) => `ativo há ${hours} h`,\n activeDays: (days) => `ativo há ${days} dias`,\n configured: \"Integração configurada\",\n connectedSuffix: \"Conectado\",\n connectedSeveral: (names) => `${names} conectados`,\n connectedGeneric: \"IA conectada\",\n },\n hostSelect: {\n caption: \"Selecione onde você usa a IA — o passo a passo é feito sob medida para ele.\",\n },\n connectGuide: {\n urlLabel: \"URL do servidor da sua loja\",\n urlHint: \"Copie esta URL e cole no seu assistente para conectá-lo à loja.\",\n moreInfo: \"Para mais informações, consulte a\",\n connectOn: (hostLabel) => `Conectar no ${hostLabel}`,\n },\n onboarding: {\n title: \"Conecte assistentes de IA à sua loja\",\n editLabel: \"Conectar IA\",\n },\n};\n"],"mappings":"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","names":["Box","Stack","Text","Box","jsx","Box","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Stack","Box","Text","OpenInNewIcon","useState","Button","Box","Stack","Text","Button","Box","Stack","Text","jsx","jsx","jsxs","Box","Text","Button","Stack","jsx","jsxs","Stack","Button","Box","Text","useState","OpenInNewIcon","CheckCircleIcon","Button","Box","Stack","Text","jsx","jsxs","Stack","Box","Text","Button","CheckCircleIcon","CheckCircleIcon","Box","Stack","Text","jsx","jsxs","Box","Text","CheckCircleIcon","Stack","jsx","jsx","hostLabel"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/mcp",
3
- "version": "3.5.0",
3
+ "version": "3.6.0",
4
4
  "type": "module",
5
5
  "description": "App-agnostic MCP server core: generate one MCP tool per OpenAPI operation and proxy each call carrying the caller's bearer token (permission passthrough). Also ships the OAuth 2.1 authorization server (./oauth, ./hono: register/authorize/token, JWKS and both .well-known documents), the package-owned Prisma partial + migration for its three tables, the mcp:generate/mcp:check (./generate) and mcp:coverage (./coverage) gates, and the reusable AI-connect onboarding UI (./react).",
6
6
  "exports": {
@@ -42,9 +42,9 @@
42
42
  "prisma:sync:check": "node scripts/sync-mcp-schema.mjs --check"
43
43
  },
44
44
  "dependencies": {
45
- "@12-apps/onboarding": "^2.0.1",
46
- "@12-apps/rbac": "^4.1.0",
47
- "@12-apps/ui": "^6.0.1",
45
+ "@12-apps/onboarding": "^2.2.0",
46
+ "@12-apps/rbac": "^4.3.0",
47
+ "@12-apps/ui": "^6.2.0",
48
48
  "@mui/icons-material": "^6.5.0",
49
49
  "jose": "^6.1.3",
50
50
  "react": "^19.2.0"
@@ -55,8 +55,8 @@
55
55
  "zod": ">=4.0.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@12-apps/eslint-config": "^1.21.0",
59
- "@12-apps/typescript-config": "^1.20.0",
58
+ "@12-apps/eslint-config": "^1.21.1",
59
+ "@12-apps/typescript-config": "^1.20.1",
60
60
  "@mui/material": "^6.5.0",
61
61
  "@testing-library/react": "^16.1.0",
62
62
  "@types/node": "^22.15.3",