@burdenoff/microfe-vibecontrols 2026.520.3 → 2026.521.2

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,"file":"VibeControlsRoutes.js","names":[],"sources":["../src/VibeControlsRoutes.tsx"],"sourcesContent":["import React, { Suspense, useEffect } from 'react';\nimport { Navigate, Route, Routes, useLocation } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useTr } from './shared/hooks/useTr';\n\n// Lazy load - All pages (required for @/ alias resolution when consumed by host app)\nconst OverviewPage = React.lazy(() =>\n import('./pages/OverviewPage').then((m) => ({ default: m.OverviewPage }))\n);\n\n// Other pages\nconst AgentsLandingPage = React.lazy(() =>\n import('./pages/AgentsLandingPage').then((m) => ({ default: m.AgentsLandingPage }))\n);\nconst AgentDetailsPage = React.lazy(() =>\n import('./pages/AgentDetailsPage').then((m) => ({ default: m.AgentDetailsPage }))\n);\nconst TargetDetailsPage = React.lazy(() =>\n import('./pages/TargetDetailsPage').then((m) => ({ default: m.TargetDetailsPage }))\n);\nconst SessionsPage = React.lazy(() =>\n import('./pages/SessionsPage').then((m) => ({ default: m.SessionsPage }))\n);\nconst SessionDetailsPage = React.lazy(() =>\n import('./pages/SessionDetailsPage').then((m) => ({ default: m.SessionDetailsPage }))\n);\nconst VibesPage = React.lazy(() =>\n import('./pages/VibesPage').then((m) => ({ default: m.VibesPage }))\n);\nconst VibeDetailsPage = React.lazy(() =>\n import('./pages/VibeDetailsPage').then((m) => ({ default: m.VibeDetailsPage }))\n);\nconst NoteDetailsPage = React.lazy(() =>\n import('./pages/NoteDetailsPage').then((m) => ({ default: m.NoteDetailsPage }))\n);\nconst TunnelsLandingPage = React.lazy(() =>\n import('./pages/TunnelsLandingPage').then((m) => ({ default: m.TunnelsLandingPage }))\n);\nconst TunnelDetailsPage = React.lazy(() =>\n import('./pages/tunnels/TunnelDetailsPage').then((m) => ({ default: m.TunnelDetailsPage }))\n);\nconst TunnelCreateWizard = React.lazy(() =>\n import('./components/tunnels/TunnelCreateWizard').then((m) => ({ default: m.TunnelCreateWizard }))\n);\nconst SettingsPage = React.lazy(() =>\n import('./pages/SettingsPage').then((m) => ({ default: m.SettingsPage }))\n);\nconst HealthPage = React.lazy(() =>\n import('./pages/HealthPage').then((m) => ({ default: m.HealthPage }))\n);\nconst GettingStartedPage = React.lazy(() =>\n import('./pages/GettingStartedPage').then((m) => ({ default: m.GettingStartedPage }))\n);\nconst SharedSessionPage = React.lazy(() =>\n import('./pages/SharedSessionPage').then((m) => ({ default: m.SharedSessionPage }))\n);\nconst VibeDeckPage = React.lazy(() =>\n import('./pages/VibeDeckPage').then((m) => ({ default: m.VibeDeckPage }))\n);\nconst SharedVibeDeckPage = React.lazy(() =>\n import('./pages/SharedVibeDeckPage').then((m) => ({ default: m.SharedVibeDeckPage }))\n);\nconst VibeCalendarPage = React.lazy(() =>\n import('./pages/VibeCalendarPage').then((m) => ({ default: m.VibeCalendarPage }))\n);\nconst VibeTaskDetailPage = React.lazy(() =>\n import('./pages/VibeTaskDetailPage').then((m) => ({ default: m.VibeTaskDetailPage }))\n);\nconst ActionsPage = React.lazy(() =>\n import('./pages/ActionsPage').then((m) => ({ default: m.ActionsPage }))\n);\nconst VibeAuditPage = React.lazy(() =>\n import('./pages/VibeAuditPage').then((m) => ({ default: m.VibeAuditPage }))\n);\nconst AnalyticsPage = React.lazy(() =>\n import('./pages/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\nconst VibeDocsPage = React.lazy(() =>\n import('./pages/VibeDocsPage').then((m) => ({ default: m.VibeDocsPage }))\n);\n\n// Catalog, Components, Templates pages\nconst CatalogPage = React.lazy(() =>\n import('./pages/CatalogPage').then((m) => ({ default: m.CatalogPage }))\n);\nconst CatalogDetailPage = React.lazy(() =>\n import('./pages/CatalogDetailPage').then((m) => ({ default: m.CatalogDetailPage }))\n);\nconst CatalogDocsPage = React.lazy(() =>\n import('./pages/CatalogDocsPage').then((m) => ({ default: m.CatalogDocsPage }))\n);\nconst ComponentsPage = React.lazy(() =>\n import('./pages/ComponentsPage').then((m) => ({ default: m.ComponentsPage }))\n);\nconst ComponentDetailPage = React.lazy(() =>\n import('./pages/ComponentDetailPage').then((m) => ({ default: m.ComponentDetailPage }))\n);\nconst ComponentDocsPage = React.lazy(() =>\n import('./pages/ComponentDocsPage').then((m) => ({ default: m.ComponentDocsPage }))\n);\nconst TemplatesPage = React.lazy(() =>\n import('./pages/TemplatesPage').then((m) => ({ default: m.TemplatesPage }))\n);\nconst TemplateDetailPage = React.lazy(() =>\n import('./pages/TemplateDetailPage').then((m) => ({ default: m.TemplateDetailPage }))\n);\n\n// AI pages\nconst AIPage = React.lazy(() => import('./pages/ai/AIPage').then((m) => ({ default: m.AIPage })));\nconst AISessionDetailPage = React.lazy(() =>\n import('./pages/ai/AISessionDetailPage').then((m) => ({ default: m.AISessionDetailPage }))\n);\nconst AgentManagerPage = React.lazy(() =>\n import('./pages/ai/AgentManagerPage').then((m) => ({ default: m.AgentManagerPage }))\n);\n\n// Loading fallback component\nfunction PageLoadingFallback() {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[200px]\">\n <div className=\"animate-pulse bg-muted rounded w-full h-full\" />\n </div>\n );\n}\n\n/**\n * Internal router for the VibeControls microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes:\n * - / → Overview page (dashboard)\n * - /agents → Agents management page\n * - /agents/:id → Agent details page\n * - /sessions → Sessions management page\n * - /sessions/:id → Session details page\n * - /vibes → Vibes (projects) management page\n * - /vibes/:id → Vibe details page (includes Notes tab)\n * - /settings → Settings page\n * - /webhooks → Legacy redirect to Developer Portal webhooks\n * - /health → Health monitoring page\n * - /* → Catch-all redirects to overview\n */\nfunction ScrollToTop() {\n const { pathname } = useLocation();\n useEffect(() => {\n // The scrollable container is the <main> element with overflow-auto\n // inside AppShellLayout, not the window itself.\n const main = document.querySelector('main');\n if (main) main.scrollTop = 0;\n }, [pathname]);\n return null;\n}\n\n/**\n * Fallback shown when a feature flag is OFF.\n */\nfunction FeatureDisabledFallback() {\n const tr = useTr();\n return (\n <div className=\"flex items-center justify-center h-full min-h-[200px] text-text-secondary text-sm\">\n {tr(\n 'vibecontrols.pages.featureDisabled',\n 'This feature is currently disabled. You can enable it from Feature Previews.'\n )}\n </div>\n );\n}\n\n/**\n * Helper: wraps a page element in a FeatureGate.\n * defaultValue={true} means the feature shows by default (before flags are seeded).\n * Only hides when a flag is explicitly set to false.\n */\nfunction gated(flag: string, element: React.ReactNode, defaultValue = true): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport function VibeControlsRoutes() {\n return (\n <Suspense fallback={<PageLoadingFallback />}>\n <ScrollToTop />\n <Routes>\n {/* Default route - overview page */}\n <Route index element={gated('vibecontrols.overview', <OverviewPage />)} />\n\n {/* Core pages */}\n <Route path=\"agents\" element={gated('vibecontrols.agents', <AgentsLandingPage />)} />\n <Route path=\"agents/:id\" element={gated('vibecontrols.agents', <AgentDetailsPage />)} />\n <Route path=\"sessions\" element={gated('vibecontrols.sessions', <SessionsPage />)} />\n <Route path=\"vibes\" element={gated('vibecontrols.vibes', <VibesPage />)} />\n <Route path=\"vibes/:id\" element={gated('vibecontrols.vibes', <VibeDetailsPage />)} />\n <Route path=\"vibes/:id/docs/*\" element={gated('vibecontrols.vibes', <VibeDocsPage />)} />\n <Route path=\"notes/:id\" element={gated('vibecontrols.vibes', <NoteDetailsPage />)} />\n <Route\n path=\"sessions/:id\"\n element={gated('vibecontrols.sessions', <SessionDetailsPage />)}\n />\n {/* Agent Manager — multi-session tabbed UI (replaces old AI page) */}\n <Route path=\"ai\" element={gated('vibecontrols.ai', <AgentManagerPage />)} />\n <Route path=\"ai/:tab\" element={gated('vibecontrols.ai', <AgentManagerPage />)} />\n <Route\n path=\"ai/sessions/:sessionId\"\n element={gated('vibecontrols.ai', <AgentManagerPage />)}\n />\n {/* AI Tools — templates, contexts, prompts, stats, playground */}\n <Route path=\"ai-tools\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/:tab\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route\n path=\"ai-tools/sessions/:sessionId\"\n element={gated('vibecontrols.ai', <AISessionDetailPage />)}\n />\n\n {/* Targets list lives in the Targets & Agents landing; per-target\n detail is its own page (mirrors agents/:id). */}\n <Route path=\"targets\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"targets/:id\" element={gated('vibecontrols.agents', <TargetDetailsPage />)} />\n {/* Agent Graph is also a tab inside the Targets & Agents landing. */}\n <Route path=\"agent-graph\" element={<Navigate to=\"../agents?tab=graph\" replace />} />\n\n {/* Catalog */}\n <Route path=\"catalogs\" element={gated('vibecontrols.catalogs', <CatalogPage />)} />\n <Route\n path=\"catalogs/:id\"\n element={gated('vibecontrols.catalogs', <CatalogDetailPage />)}\n />\n <Route\n path=\"catalogs/:id/docs/*\"\n element={gated('vibecontrols.catalogs', <CatalogDocsPage />)}\n />\n <Route path=\"components\" element={gated('vibecontrols.components', <ComponentsPage />)} />\n <Route\n path=\"components/:id\"\n element={gated('vibecontrols.components', <ComponentDetailPage />)}\n />\n <Route\n path=\"components/:id/docs/*\"\n element={gated('vibecontrols.components', <ComponentDocsPage />)}\n />\n <Route path=\"templates\" element={gated('vibecontrols.templates', <TemplatesPage />)} />\n <Route\n path=\"templates/:id\"\n element={gated('vibecontrols.templates', <TemplateDetailPage />)}\n />\n\n {/* Automation */}\n <Route path=\"actions\" element={gated('vibecontrols.actions', <ActionsPage />)} />\n <Route path=\"vibedeck\" element={gated('vibecontrols.vibedeck', <VibeDeckPage />)} />\n <Route path=\"calendar\" element={gated('vibecontrols.calendar', <VibeCalendarPage />)} />\n <Route\n path=\"calendar/:viewType\"\n element={gated('vibecontrols.calendar', <VibeCalendarPage />)}\n />\n <Route\n path=\"calendar/task/:taskId\"\n element={gated('vibecontrols.calendar', <VibeTaskDetailPage />)}\n />\n <Route path=\"webhooks\" element={<Navigate to=\"/devportal/webhooks\" replace />} />\n <Route path=\"webhooks/new\" element={<Navigate to=\"/devportal/webhooks/new\" replace />} />\n <Route path=\"webhooks/:id\" element={<Navigate to=\"/devportal/webhooks\" replace />} />\n {/* GitOps consolidated into Vibe detail tab — old /gitops routes redirect to vibes list. */}\n <Route path=\"gitops\" element={<Navigate to=\"../vibes\" replace />} />\n <Route path=\"gitops/:tab\" element={<Navigate to=\"../vibes\" replace />} />\n\n {/* Infrastructure */}\n <Route path=\"tunnels\" element={gated('vibecontrols.tunnels', <TunnelsLandingPage />)} />\n <Route path=\"tunnels/new\" element={gated('vibecontrols.tunnels', <TunnelCreateWizard />)} />\n <Route\n path=\"tunnels/:tunnelId\"\n element={gated('vibecontrols.tunnels', <TunnelDetailsPage />)}\n />\n\n {/* Insights */}\n <Route path=\"health\" element={gated('vibecontrols.health', <HealthPage />)} />\n <Route path=\"analytics\" element={gated('vibecontrols.analytics', <AnalyticsPage />)} />\n <Route path=\"audit\" element={gated('vibecontrols.audit-log', <VibeAuditPage />, false)} />\n <Route path=\"logs\" element={<Navigate to=\"/vibecontrols/agents\" replace />} />\n\n {/* Settings */}\n <Route path=\"settings\" element={gated('vibecontrols.settings', <SettingsPage />)} />\n\n {/* Setup */}\n {/* Not gated — onboarding flow must always be reachable */}\n <Route path=\"getting-started\" element={<GettingStartedPage />} />\n\n {/* Shared public routes (no gating — accessible via public links) */}\n <Route path=\"share/:token\" element={<SharedSessionPage />} />\n <Route path=\"deck/:token\" element={<SharedVibeDeckPage />} />\n\n {/* Legacy redirects */}\n <Route path=\"access\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"ssh-targets\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"ssh-terminals\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n\n {/* Catch-all route - redirect to overview */}\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":";;;;;;AAMA,IAAM,IAAe,EAAM,WACzB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAC1E,EAGK,IAAoB,EAAM,WAC9B,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAmB,EAAM,WAC7B,OAAO,+BAA4B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClF,EACK,IAAoB,EAAM,WAC9B,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAe,EAAM,WACzB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAC1E,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EACK,IAAY,EAAM,WACtB,OAAO,wBAAqB,MAAM,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CACpE,EACK,IAAkB,EAAM,WAC5B,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EACK,IAAkB,EAAM,WAC5B,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EACK,IAAoB,EAAM,WAC9B,OAAO,wCAAqC,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAC5F,EACK,IAAqB,EAAM,WAC/B,OAAO,8CAA2C,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACnG,EACK,IAAe,EAAM,WACzB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAC1E,EACK,IAAa,EAAM,WACvB,OAAO,yBAAsB,MAAM,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,CACtE,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EACK,IAAoB,EAAM,WAC9B,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAe,EAAM,WACzB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAC1E,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EACK,IAAmB,EAAM,WAC7B,OAAO,+BAA4B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClF,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EACK,IAAc,EAAM,WACxB,OAAO,0BAAuB,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CACxE,EACK,IAAgB,EAAM,WAC1B,OAAO,4BAAyB,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAC5E,EACK,IAAgB,EAAM,WAC1B,OAAO,4BAAyB,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAC5E,EACK,IAAe,EAAM,WACzB,OAAO,2BAAwB,MAAM,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAC1E,EAGK,IAAc,EAAM,WACxB,OAAO,0BAAuB,MAAM,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,CACxE,EACK,IAAoB,EAAM,WAC9B,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAkB,EAAM,WAC5B,OAAO,8BAA2B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAChF,EACK,IAAiB,EAAM,WAC3B,OAAO,6BAA0B,MAAM,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAC9E,EACK,IAAsB,EAAM,WAChC,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CACxF,EACK,IAAoB,EAAM,WAC9B,OAAO,gCAA6B,MAAM,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CACpF,EACK,IAAgB,EAAM,WAC1B,OAAO,4BAAyB,MAAM,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,CAC5E,EACK,IAAqB,EAAM,WAC/B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,CACtF,EAGK,IAAS,EAAM,WAAW,OAAO,wBAAqB,MAAM,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EAC3F,IAAsB,EAAM,WAChC,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,CAC3F,EACK,IAAmB,EAAM,WAC7B,OAAO,kCAA+B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,CACrF;AAGD,SAAS,IAAsB;AAC7B,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD,EAAK,WAAU,gDAAiD,CAAA;EAC5D,CAAA;;AAqBV,SAAS,IAAc;CACrB,IAAM,EAAE,gBAAa,GAAa;AAOlC,QANA,QAAgB;EAGd,IAAM,IAAO,SAAS,cAAc,OAAO;AAC3C,EAAI,MAAM,EAAK,YAAY;IAC1B,CAAC,EAAS,CAAC,EACP;;AAMT,SAAS,IAA0B;AAEjC,QACE,kBAAC,OAAD;EAAK,WAAU;YAFN,GAAO,CAIZ,sCACA,+EACD;EACG,CAAA;;AASV,SAAS,EAAM,GAAc,GAA0B,IAAe,IAA0B;AAC9F,QACE,kBAAC,GAAD;EAAmB;EAAoB;EAAc,UAAU,kBAAC,GAAD,EAA2B,CAAA;YACvF;EACW,CAAA;;AAIlB,SAAgB,IAAqB;AACnC,QACE,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;YAA3C,CACE,kBAAC,GAAD,EAAe,CAAA,EACf,kBAAC,GAAD,EAAA,UAAA;GAEE,kBAAC,GAAD;IAAO,OAAA;IAAM,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GAG1E,kBAAC,GAAD;IAAO,MAAK;IAAS,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAAI,CAAA;GACrF,kBAAC,GAAD;IAAO,MAAK;IAAa,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GACxF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GACpF,kBAAC,GAAD;IAAO,MAAK;IAAQ,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAa,CAAA,CAAC;IAAI,CAAA;GAC3E,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAmB,CAAA,CAAC;IAAI,CAAA;GACrF,kBAAC,GAAD;IAAO,MAAK;IAAmB,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GACzF,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAmB,CAAA,CAAC;IAAI,CAAA;GACrF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAC/D,CAAA;GAEF,kBAAC,GAAD;IAAO,MAAK;IAAK,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GAC5E,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GACjF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IACvD,CAAA;GAEF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAU,CAAA,CAAC;IAAI,CAAA;GACxE,kBAAC,GAAD;IAAO,MAAK;IAAgB,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAU,CAAA,CAAC;IAAI,CAAA;GAC7E,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAuB,CAAA,CAAC;IAC1D,CAAA;GAIF,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAwB,SAAA;KAAU,CAAA;IAAI,CAAA;GAClF,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAAI,CAAA;GAE1F,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAsB,SAAA;KAAU,CAAA;IAAI,CAAA;GAGpF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAe,CAAA,CAAC;IAAI,CAAA;GACnF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAC9D,CAAA;GACF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAmB,CAAA,CAAC;IAC5D,CAAA;GACF,kBAAC,GAAD;IAAO,MAAK;IAAa,SAAS,EAAM,2BAA2B,kBAAC,GAAD,EAAkB,CAAA,CAAC;IAAI,CAAA;GAC1F,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,2BAA2B,kBAAC,GAAD,EAAuB,CAAA,CAAC;IAClE,CAAA;GACF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,2BAA2B,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAChE,CAAA;GACF,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,EAAM,0BAA0B,kBAAC,GAAD,EAAiB,CAAA,CAAC;IAAI,CAAA;GACvF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,0BAA0B,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAChE,CAAA;GAGF,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,EAAM,wBAAwB,kBAAC,GAAD,EAAe,CAAA,CAAC;IAAI,CAAA;GACjF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GACpF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAAI,CAAA;GACxF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAoB,CAAA,CAAC;IAC7D,CAAA;GACF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAC/D,CAAA;GACF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAsB,SAAA;KAAU,CAAA;IAAI,CAAA;GACjF,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,kBAAC,GAAD;KAAU,IAAG;KAA0B,SAAA;KAAU,CAAA;IAAI,CAAA;GACzF,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAsB,SAAA;KAAU,CAAA;IAAI,CAAA;GAErF,kBAAC,GAAD;IAAO,MAAK;IAAS,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAW,SAAA;KAAU,CAAA;IAAI,CAAA;GACpE,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAW,SAAA;KAAU,CAAA;IAAI,CAAA;GAGzE,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,EAAM,wBAAwB,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAAI,CAAA;GACxF,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,EAAM,wBAAwB,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAAI,CAAA;GAC5F,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,wBAAwB,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAC7D,CAAA;GAGF,kBAAC,GAAD;IAAO,MAAK;IAAS,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAc,CAAA,CAAC;IAAI,CAAA;GAC9E,kBAAC,GAAD;IAAO,MAAK;IAAY,SAAS,EAAM,0BAA0B,kBAAC,GAAD,EAAiB,CAAA,CAAC;IAAI,CAAA;GACvF,kBAAC,GAAD;IAAO,MAAK;IAAQ,SAAS,EAAM,0BAA0B,kBAAC,GAAD,EAAiB,CAAA,EAAE,GAAM;IAAI,CAAA;GAC1F,kBAAC,GAAD;IAAO,MAAK;IAAO,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAuB,SAAA;KAAU,CAAA;IAAI,CAAA;GAG9E,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GAIpF,kBAAC,GAAD;IAAO,MAAK;IAAkB,SAAS,kBAAC,GAAD,EAAsB,CAAA;IAAI,CAAA;GAGjE,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,kBAAC,GAAD,EAAqB,CAAA;IAAI,CAAA;GAC7D,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD,EAAsB,CAAA;IAAI,CAAA;GAG7D,kBAAC,GAAD;IAAO,MAAK;IAAS,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAwB,SAAA;KAAU,CAAA;IAAI,CAAA;GACjF,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAwB,SAAA;KAAU,CAAA;IAAI,CAAA;GACtF,kBAAC,GAAD;IAAO,MAAK;IAAgB,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAwB,SAAA;KAAU,CAAA;IAAI,CAAA;GAGxF,kBAAC,GAAD;IAAO,MAAK;IAAI,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAG,SAAA;KAAU,CAAA;IAAI,CAAA;GAChD,EAAA,CAAA,CACA"}
1
+ {"version":3,"file":"VibeControlsRoutes.js","names":[],"sources":["../src/VibeControlsRoutes.tsx"],"sourcesContent":["import React, { Suspense, useEffect } from 'react';\nimport { Navigate, Route, Routes, useLocation } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useTr } from './shared/hooks/useTr';\n\n// Lazy load - All pages (required for @/ alias resolution when consumed by host app)\nconst OverviewPage = React.lazy(() =>\n import('./pages/OverviewPage').then((m) => ({ default: m.OverviewPage }))\n);\n\n// Other pages\nconst AgentsLandingPage = React.lazy(() =>\n import('./pages/AgentsLandingPage').then((m) => ({ default: m.AgentsLandingPage }))\n);\nconst AgentDetailsPage = React.lazy(() =>\n import('./pages/AgentDetailsPage').then((m) => ({ default: m.AgentDetailsPage }))\n);\nconst TargetDetailsPage = React.lazy(() =>\n import('./pages/TargetDetailsPage').then((m) => ({ default: m.TargetDetailsPage }))\n);\nconst SessionsPage = React.lazy(() =>\n import('./pages/SessionsPage').then((m) => ({ default: m.SessionsPage }))\n);\nconst SessionDetailsPage = React.lazy(() =>\n import('./pages/SessionDetailsPage').then((m) => ({ default: m.SessionDetailsPage }))\n);\nconst VibesPage = React.lazy(() =>\n import('./pages/VibesPage').then((m) => ({ default: m.VibesPage }))\n);\nconst VibeDetailsPage = React.lazy(() =>\n import('./pages/VibeDetailsPage').then((m) => ({ default: m.VibeDetailsPage }))\n);\nconst NoteDetailsPage = React.lazy(() =>\n import('./pages/NoteDetailsPage').then((m) => ({ default: m.NoteDetailsPage }))\n);\nconst TunnelsLandingPage = React.lazy(() =>\n import('./pages/TunnelsLandingPage').then((m) => ({ default: m.TunnelsLandingPage }))\n);\nconst TunnelDetailsPage = React.lazy(() =>\n import('./pages/tunnels/TunnelDetailsPage').then((m) => ({ default: m.TunnelDetailsPage }))\n);\nconst TunnelCreateWizard = React.lazy(() =>\n import('./components/tunnels/TunnelCreateWizard').then((m) => ({ default: m.TunnelCreateWizard }))\n);\nconst SettingsPage = React.lazy(() =>\n import('./pages/SettingsPage').then((m) => ({ default: m.SettingsPage }))\n);\nconst HealthPage = React.lazy(() =>\n import('./pages/HealthPage').then((m) => ({ default: m.HealthPage }))\n);\nconst GettingStartedPage = React.lazy(() =>\n import('./pages/GettingStartedPage').then((m) => ({ default: m.GettingStartedPage }))\n);\nconst SharedSessionPage = React.lazy(() =>\n import('./pages/SharedSessionPage').then((m) => ({ default: m.SharedSessionPage }))\n);\nconst VibeDeckPage = React.lazy(() =>\n import('./pages/VibeDeckPage').then((m) => ({ default: m.VibeDeckPage }))\n);\nconst SharedVibeDeckPage = React.lazy(() =>\n import('./pages/SharedVibeDeckPage').then((m) => ({ default: m.SharedVibeDeckPage }))\n);\nconst VibeCalendarPage = React.lazy(() =>\n import('./pages/VibeCalendarPage').then((m) => ({ default: m.VibeCalendarPage }))\n);\nconst VibeTaskDetailPage = React.lazy(() =>\n import('./pages/VibeTaskDetailPage').then((m) => ({ default: m.VibeTaskDetailPage }))\n);\nconst ActionsPage = React.lazy(() =>\n import('./pages/ActionsPage').then((m) => ({ default: m.ActionsPage }))\n);\nconst VibeAuditPage = React.lazy(() =>\n import('./pages/VibeAuditPage').then((m) => ({ default: m.VibeAuditPage }))\n);\nconst AnalyticsPage = React.lazy(() =>\n import('./pages/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\nconst VibeDocsPage = React.lazy(() =>\n import('./pages/VibeDocsPage').then((m) => ({ default: m.VibeDocsPage }))\n);\n\n// Catalog, Components, Templates pages\nconst CatalogPage = React.lazy(() =>\n import('./pages/CatalogPage').then((m) => ({ default: m.CatalogPage }))\n);\nconst CatalogDetailPage = React.lazy(() =>\n import('./pages/CatalogDetailPage').then((m) => ({ default: m.CatalogDetailPage }))\n);\nconst CatalogDocsPage = React.lazy(() =>\n import('./pages/CatalogDocsPage').then((m) => ({ default: m.CatalogDocsPage }))\n);\nconst ComponentsPage = React.lazy(() =>\n import('./pages/ComponentsPage').then((m) => ({ default: m.ComponentsPage }))\n);\nconst ComponentDetailPage = React.lazy(() =>\n import('./pages/ComponentDetailPage').then((m) => ({ default: m.ComponentDetailPage }))\n);\nconst ComponentDocsPage = React.lazy(() =>\n import('./pages/ComponentDocsPage').then((m) => ({ default: m.ComponentDocsPage }))\n);\nconst TemplatesPage = React.lazy(() =>\n import('./pages/TemplatesPage').then((m) => ({ default: m.TemplatesPage }))\n);\nconst TemplateDetailPage = React.lazy(() =>\n import('./pages/TemplateDetailPage').then((m) => ({ default: m.TemplateDetailPage }))\n);\nconst PluginStandalonePage = React.lazy(() =>\n import('./pages/PluginStandalonePage').then((m) => ({ default: m.PluginStandalonePage }))\n);\n\n// AI pages\nconst AIPage = React.lazy(() => import('./pages/ai/AIPage').then((m) => ({ default: m.AIPage })));\nconst AISessionDetailPage = React.lazy(() =>\n import('./pages/ai/AISessionDetailPage').then((m) => ({ default: m.AISessionDetailPage }))\n);\nconst AgentManagerPage = React.lazy(() =>\n import('./pages/ai/AgentManagerPage').then((m) => ({ default: m.AgentManagerPage }))\n);\n\n// Loading fallback component\nfunction PageLoadingFallback() {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[200px]\">\n <div className=\"animate-pulse bg-muted rounded w-full h-full\" />\n </div>\n );\n}\n\n/**\n * Internal router for the VibeControls microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes:\n * - / → Overview page (dashboard)\n * - /agents → Agents management page\n * - /agents/:id → Agent details page\n * - /sessions → Sessions management page\n * - /sessions/:id → Session details page\n * - /vibes → Vibes (projects) management page\n * - /vibes/:id → Vibe details page (includes Notes tab)\n * - /settings → Settings page\n * - /webhooks → Legacy redirect to Developer Portal webhooks\n * - /health → Health monitoring page\n * - /* → Catch-all redirects to overview\n */\nfunction ScrollToTop() {\n const { pathname } = useLocation();\n useEffect(() => {\n // The scrollable container is the <main> element with overflow-auto\n // inside AppShellLayout, not the window itself.\n const main = document.querySelector('main');\n if (main) main.scrollTop = 0;\n }, [pathname]);\n return null;\n}\n\n/**\n * Fallback shown when a feature flag is OFF.\n */\nfunction FeatureDisabledFallback() {\n const tr = useTr();\n return (\n <div className=\"flex items-center justify-center h-full min-h-[200px] text-text-secondary text-sm\">\n {tr(\n 'vibecontrols.pages.featureDisabled',\n 'This feature is currently disabled. You can enable it from Feature Previews.'\n )}\n </div>\n );\n}\n\n/**\n * Helper: wraps a page element in a FeatureGate.\n * defaultValue={true} means the feature shows by default (before flags are seeded).\n * Only hides when a flag is explicitly set to false.\n */\nfunction gated(flag: string, element: React.ReactNode, defaultValue = true): React.ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nexport function VibeControlsRoutes() {\n return (\n <Suspense fallback={<PageLoadingFallback />}>\n <ScrollToTop />\n <Routes>\n {/* Default route - overview page */}\n <Route index element={gated('vibecontrols.overview', <OverviewPage />)} />\n\n {/* Core pages */}\n {/* PR-9 standalone plugin route — deep-link any contribution\n from any mount point as a full-page view. Wrapped in the\n same `gated()` envelope as every other authenticated route\n for consistent authz; the page-level\n `vibes.tabs.iframe-host` feature flag still gates rendering\n once the user is past the entitlement check. */}\n <Route\n path=\"plugin/:pluginKey\"\n element={gated('vibecontrols.vibes', <PluginStandalonePage />)}\n />\n\n <Route path=\"agents\" element={gated('vibecontrols.agents', <AgentsLandingPage />)} />\n <Route path=\"agents/:id\" element={gated('vibecontrols.agents', <AgentDetailsPage />)} />\n <Route path=\"sessions\" element={gated('vibecontrols.sessions', <SessionsPage />)} />\n <Route path=\"vibes\" element={gated('vibecontrols.vibes', <VibesPage />)} />\n <Route path=\"vibes/:id\" element={gated('vibecontrols.vibes', <VibeDetailsPage />)} />\n <Route path=\"vibes/:id/docs/*\" element={gated('vibecontrols.vibes', <VibeDocsPage />)} />\n <Route path=\"notes/:id\" element={gated('vibecontrols.vibes', <NoteDetailsPage />)} />\n <Route\n path=\"sessions/:id\"\n element={gated('vibecontrols.sessions', <SessionDetailsPage />)}\n />\n {/* Agent Manager — multi-session tabbed UI (replaces old AI page) */}\n <Route path=\"ai\" element={gated('vibecontrols.ai', <AgentManagerPage />)} />\n <Route path=\"ai/:tab\" element={gated('vibecontrols.ai', <AgentManagerPage />)} />\n <Route\n path=\"ai/sessions/:sessionId\"\n element={gated('vibecontrols.ai', <AgentManagerPage />)}\n />\n {/* AI Tools — templates, contexts, prompts, stats, playground */}\n <Route path=\"ai-tools\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/:tab\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route\n path=\"ai-tools/sessions/:sessionId\"\n element={gated('vibecontrols.ai', <AISessionDetailPage />)}\n />\n\n {/* Targets list lives in the Targets & Agents landing; per-target\n detail is its own page (mirrors agents/:id). */}\n <Route path=\"targets\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"targets/:id\" element={gated('vibecontrols.agents', <TargetDetailsPage />)} />\n {/* Agent Graph is also a tab inside the Targets & Agents landing. */}\n <Route path=\"agent-graph\" element={<Navigate to=\"../agents?tab=graph\" replace />} />\n\n {/* Catalog */}\n <Route path=\"catalogs\" element={gated('vibecontrols.catalogs', <CatalogPage />)} />\n <Route\n path=\"catalogs/:id\"\n element={gated('vibecontrols.catalogs', <CatalogDetailPage />)}\n />\n <Route\n path=\"catalogs/:id/docs/*\"\n element={gated('vibecontrols.catalogs', <CatalogDocsPage />)}\n />\n <Route path=\"components\" element={gated('vibecontrols.components', <ComponentsPage />)} />\n <Route\n path=\"components/:id\"\n element={gated('vibecontrols.components', <ComponentDetailPage />)}\n />\n <Route\n path=\"components/:id/docs/*\"\n element={gated('vibecontrols.components', <ComponentDocsPage />)}\n />\n <Route path=\"templates\" element={gated('vibecontrols.templates', <TemplatesPage />)} />\n <Route\n path=\"templates/:id\"\n element={gated('vibecontrols.templates', <TemplateDetailPage />)}\n />\n\n {/* Automation */}\n <Route path=\"actions\" element={gated('vibecontrols.actions', <ActionsPage />)} />\n <Route path=\"vibedeck\" element={gated('vibecontrols.vibedeck', <VibeDeckPage />)} />\n <Route path=\"calendar\" element={gated('vibecontrols.calendar', <VibeCalendarPage />)} />\n <Route\n path=\"calendar/:viewType\"\n element={gated('vibecontrols.calendar', <VibeCalendarPage />)}\n />\n <Route\n path=\"calendar/task/:taskId\"\n element={gated('vibecontrols.calendar', <VibeTaskDetailPage />)}\n />\n <Route path=\"webhooks\" element={<Navigate to=\"/devportal/webhooks\" replace />} />\n <Route path=\"webhooks/new\" element={<Navigate to=\"/devportal/webhooks/new\" replace />} />\n <Route path=\"webhooks/:id\" element={<Navigate to=\"/devportal/webhooks\" replace />} />\n {/* GitOps consolidated into Vibe detail tab — old /gitops routes redirect to vibes list. */}\n <Route path=\"gitops\" element={<Navigate to=\"../vibes\" replace />} />\n <Route path=\"gitops/:tab\" element={<Navigate to=\"../vibes\" replace />} />\n\n {/* Infrastructure */}\n <Route path=\"tunnels\" element={gated('vibecontrols.tunnels', <TunnelsLandingPage />)} />\n <Route path=\"tunnels/new\" element={gated('vibecontrols.tunnels', <TunnelCreateWizard />)} />\n <Route\n path=\"tunnels/:tunnelId\"\n element={gated('vibecontrols.tunnels', <TunnelDetailsPage />)}\n />\n\n {/* Insights */}\n <Route path=\"health\" element={gated('vibecontrols.health', <HealthPage />)} />\n <Route path=\"analytics\" element={gated('vibecontrols.analytics', <AnalyticsPage />)} />\n <Route path=\"audit\" element={gated('vibecontrols.audit-log', <VibeAuditPage />, false)} />\n <Route path=\"logs\" element={<Navigate to=\"/vibecontrols/agents\" replace />} />\n\n {/* Settings */}\n <Route path=\"settings\" element={gated('vibecontrols.settings', <SettingsPage />)} />\n\n {/* Setup */}\n {/* Not gated — onboarding flow must always be reachable */}\n <Route path=\"getting-started\" element={<GettingStartedPage />} />\n\n {/* Shared public routes (no gating — accessible via public links) */}\n <Route path=\"share/:token\" element={<SharedSessionPage />} />\n <Route path=\"deck/:token\" element={<SharedVibeDeckPage />} />\n\n {/* Legacy redirects */}\n <Route path=\"access\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"ssh-targets\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n <Route path=\"ssh-terminals\" element={<Navigate to=\"../agents?tab=targets\" replace />} />\n\n {/* Catch-all route - redirect to overview */}\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -3,44 +3,44 @@ import { useVibeControls as a } from "../../providers/VibeControlsProvider.js";
3
3
  import "../../constants/pluginCatalog.js";
4
4
  import { PluginGate as o } from "../shared/PluginGate.js";
5
5
  import "../shared/index.js";
6
- import { RepoStatsTab as s } from "./RepoStatsTab.js";
7
- import { CITab as c } from "./CITab.js";
8
- import { GitOpsSetup as l } from "./GitOpsSetup.js";
9
- import { appendIframeTokenParam as u, mintIframeToken as d, scheduleIframeTokenRefresh as f } from "../../services/iframeToken.js";
6
+ import { appendIframeTokenParam as s, mintIframeToken as c, scheduleIframeTokenRefresh as l } from "../../services/iframeToken.js";
7
+ import { RepoStatsTab as u } from "./RepoStatsTab.js";
8
+ import { CITab as d } from "./CITab.js";
9
+ import { GitOpsSetup as f } from "./GitOpsSetup.js";
10
10
  import { useCallback as p, useEffect as m, useState as h } from "react";
11
11
  import { BarChart3 as g, GitBranch as _, GitMerge as v, Play as y, RefreshCw as b } from "lucide-react";
12
12
  import { motion as x } from "framer-motion";
13
13
  import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
14
14
  //#region src/components/gitops/VibeGitOpsTab.tsx
15
- var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T }) => {
15
+ var T = ({ vibeId: s, agentId: c, profile: l, tunnelUrl: p, apiKey: m, tr: T }) => {
16
16
  let [D, O] = h("repo-stats"), [k, A] = h(!1), { workspaceId: j } = a(), { data: M, loading: N, refetch: P } = n({
17
17
  variables: {
18
- filter: { vibeId: u },
18
+ filter: { vibeId: s },
19
19
  pagination: { limit: 50 }
20
20
  },
21
21
  fetchPolicy: "cache-and-network"
22
22
  }), F = M?.listGitopsProviders?.items ?? [], I = F.find((e) => e.isActive)?.id || F[0]?.id || "", { data: L, loading: R, error: z } = t({
23
23
  variables: {
24
24
  providerId: I,
25
- agentId: d
25
+ agentId: c
26
26
  },
27
- skip: !I || !d || D !== "repo-stats",
27
+ skip: !I || !c || D !== "repo-stats",
28
28
  fetchPolicy: "cache-and-network"
29
29
  }), { data: B, loading: V, error: H } = e({
30
30
  variables: {
31
31
  providerId: I,
32
- agentId: d,
32
+ agentId: c,
33
33
  limit: 30
34
34
  },
35
- skip: !I || !d || D !== "ci",
35
+ skip: !I || !c || D !== "ci",
36
36
  fetchPolicy: "cache-and-network"
37
37
  }), [U, { loading: W }] = i(), [G, { loading: K }] = r(), q = async () => {
38
- !I || !d || (D === "repo-stats" ? await U({ variables: {
38
+ !I || !c || (D === "repo-stats" ? await U({ variables: {
39
39
  providerId: I,
40
- agentId: d
40
+ agentId: c
41
41
  } }) : D === "ci" && await G({ variables: {
42
42
  providerId: I,
43
- agentId: d
43
+ agentId: c
44
44
  } }));
45
45
  }, J = W || K, Y = F.length > 0, X = [
46
46
  {
@@ -84,7 +84,7 @@ var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T })
84
84
  })]
85
85
  }), /* @__PURE__ */ w("div", {
86
86
  className: "flex items-center gap-2",
87
- children: [Y && d && (D === "repo-stats" || D === "ci") && /* @__PURE__ */ w("button", {
87
+ children: [Y && c && (D === "repo-stats" || D === "ci") && /* @__PURE__ */ w("button", {
88
88
  onClick: q,
89
89
  disabled: J,
90
90
  className: "flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md border border-border-default text-text-secondary hover:text-text-primary hover:border-border-strong disabled:opacity-50 transition-colors",
@@ -117,17 +117,17 @@ var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T })
117
117
  }), /* @__PURE__ */ w("div", {
118
118
  className: "min-w-0 flex-1 space-y-4",
119
119
  children: [
120
- k && /* @__PURE__ */ C(l, {
120
+ k && /* @__PURE__ */ C(f, {
121
121
  workspaceId: j || "",
122
- agents: d ? [{
123
- id: d,
122
+ agents: c ? [{
123
+ id: c,
124
124
  name: "Active Agent"
125
125
  }] : [],
126
126
  onCreated: () => {
127
127
  A(!1), P();
128
128
  }
129
129
  }),
130
- D === "repo-stats" && !k && /* @__PURE__ */ C(S, { children: Y ? d ? /* @__PURE__ */ C(s, {
130
+ D === "repo-stats" && !k && /* @__PURE__ */ C(S, { children: Y ? c ? /* @__PURE__ */ C(u, {
131
131
  stats: L?.getRepoStats ?? null,
132
132
  loading: R || N,
133
133
  error: z?.message
@@ -152,7 +152,7 @@ var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T })
152
152
  })
153
153
  ]
154
154
  }) }),
155
- D === "ci" && !k && /* @__PURE__ */ C(S, { children: Y ? d ? /* @__PURE__ */ C(c, {
155
+ D === "ci" && !k && /* @__PURE__ */ C(S, { children: Y ? c ? /* @__PURE__ */ C(d, {
156
156
  status: B?.getCIStatus ?? null,
157
157
  loading: V || N,
158
158
  error: H?.message
@@ -170,15 +170,15 @@ var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T })
170
170
  })]
171
171
  }) }),
172
172
  D === "git-ui" && /* @__PURE__ */ C(o, {
173
- agentId: d || null,
173
+ agentId: c || null,
174
174
  required: ["@vibecontrols/vibe-plugin-tool-git"],
175
175
  mode: "all",
176
176
  eyebrow: T("gitops.ungitEyebrow", "Ungit plugin required"),
177
177
  title: T("gitops.ungitTitle", "Install the visual git client"),
178
178
  description: T("gitops.ungitDescription", "The Git UI embeds the Ungit visual git client served by your agent. Install the plugin to continue."),
179
179
  children: /* @__PURE__ */ C(E, {
180
- agentId: d,
181
- profile: f,
180
+ agentId: c,
181
+ profile: l,
182
182
  tunnelUrl: p,
183
183
  apiKey: m,
184
184
  tr: T
@@ -190,14 +190,14 @@ var T = ({ vibeId: u, agentId: d, profile: f, tunnelUrl: p, apiKey: m, tr: T })
190
190
  }, "gitops");
191
191
  };
192
192
  function E({ agentId: e, profile: t, tunnelUrl: n, apiKey: r, tr: i }) {
193
- let [a, o] = h(!1), [s, c] = h(!1), [l, g] = h(null), [v, y] = h(null);
193
+ let [a, o] = h(!1), [u, d] = h(!1), [f, g] = h(null), [v, y] = h(null);
194
194
  m(() => {
195
195
  if (!e || !a) return;
196
196
  let n = !1, r = null, i = (a) => {
197
- n || (g(a), r = f(e, t, "/ungit", a, i, (e) => y(e.message)));
197
+ n || (g(a), r = l(e, t, "/ungit", a, i, (e) => y(e.message)));
198
198
  };
199
- return d(e, t, "/ungit").then((a) => {
200
- n || (g(a), r = f(e, t, "/ungit", a, i, (e) => y(e.message)));
199
+ return c(e, t, "/ungit").then((a) => {
200
+ n || (g(a), r = l(e, t, "/ungit", a, i, (e) => y(e.message)));
201
201
  }).catch((e) => {
202
202
  n || y(e instanceof Error ? e.message : String(e));
203
203
  }), () => {
@@ -230,29 +230,29 @@ function E({ agentId: e, profile: t, tunnelUrl: n, apiKey: r, tr: i }) {
230
230
  className: "text-xs text-text-secondary",
231
231
  children: i("gitops.ungitNote", "Visual git client powered by Ungit plugin on the agent.")
232
232
  }),
233
- !a && !s && /* @__PURE__ */ C("button", {
233
+ !a && !u && /* @__PURE__ */ C("button", {
234
234
  onClick: () => {
235
235
  if (!r) return;
236
- c(!0);
236
+ d(!0);
237
237
  let e = { "Content-Type": "application/json" };
238
238
  e["x-agent-api-key"] = r, fetch(`${n}/api/profiles/${encodeURIComponent(t)}/ungit/start`, {
239
239
  method: "POST",
240
240
  headers: e,
241
241
  body: "{}"
242
242
  }).then((e) => e.json()).then(() => {
243
- o(!0), c(!1);
244
- }).catch(() => c(!1));
243
+ o(!0), d(!1);
244
+ }).catch(() => d(!1));
245
245
  },
246
246
  className: "px-3 py-1 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors",
247
247
  children: i("gitops.startUngit", "Start Ungit")
248
248
  }),
249
- s && /* @__PURE__ */ C("span", {
249
+ u && /* @__PURE__ */ C("span", {
250
250
  className: "text-xs text-text-secondary animate-pulse",
251
251
  children: i("gitops.startingUngit", "Starting...")
252
252
  })
253
253
  ]
254
- }), a ? l ? /* @__PURE__ */ C("iframe", {
255
- src: u(`${n}/ungit/`, l.token),
254
+ }), a ? f ? /* @__PURE__ */ C("iframe", {
255
+ src: s(`${n}/ungit/`, f.token),
256
256
  title: "Git UI (Ungit)",
257
257
  className: "w-full",
258
258
  style: { height: "700px" },
@@ -0,0 +1,224 @@
1
+ import { agentApiPath as e } from "../../utils/agentApiPath.js";
2
+ import { agentAiMutate as t } from "../../services/aiApi.js";
3
+ import { useCallback as n, useEffect as r, useMemo as i, useRef as a, useState as o } from "react";
4
+ import { AlertTriangle as s, CheckCircle2 as c, Loader2 as l, Plus as u, X as d } from "lucide-react";
5
+ import { AnimatePresence as f, motion as p } from "framer-motion";
6
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
7
+ //#region src/components/plugins/AddTabDialog.tsx
8
+ function _({ isOpen: _, onClose: v, mountPoint: y, agentId: b, profile: x, onInstalled: S }) {
9
+ let [C, w] = o(!1), [T, E] = o(null), [D, O] = o([]), [k, A] = o([]), [j, M] = o(null), [N, P] = o(null), [F, I] = o(/* @__PURE__ */ new Set()), L = a(!0);
10
+ r(() => (L.current = !0, () => {
11
+ L.current = !1;
12
+ }), []);
13
+ let R = a(null);
14
+ r(() => {
15
+ if (!_) return;
16
+ let e = typeof document < "u" ? document.activeElement : null, t = (e) => {
17
+ if (e.key === "Escape") {
18
+ e.preventDefault(), v();
19
+ return;
20
+ }
21
+ if (e.key !== "Tab" || !R.current) return;
22
+ let t = R.current.querySelectorAll("a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])");
23
+ if (t.length === 0) return;
24
+ let n = t[0], r = t[t.length - 1];
25
+ e.shiftKey && document.activeElement === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && document.activeElement === r && (e.preventDefault(), n.focus());
26
+ };
27
+ return document.addEventListener("keydown", t), setTimeout(() => R.current?.focus(), 0), () => {
28
+ document.removeEventListener("keydown", t), e?.focus?.();
29
+ };
30
+ }, [_, v]), r(() => {
31
+ I(/* @__PURE__ */ new Set());
32
+ }, [
33
+ b,
34
+ x,
35
+ y,
36
+ _
37
+ ]);
38
+ let z = n(async () => {
39
+ w(!0), E(null);
40
+ try {
41
+ let [n, r] = await Promise.all([t(b, e(x, "/plugins/catalog"), "GET", null), t(b, e(x, `/plugins/contributions?mountPoint=${encodeURIComponent(y)}`), "GET", null)]);
42
+ if (!L.current) return;
43
+ O(n.plugins ?? []), A(r.contributions ?? []);
44
+ } catch (e) {
45
+ if (!L.current) return;
46
+ E(e instanceof Error ? e.message : String(e));
47
+ } finally {
48
+ L.current && w(!1);
49
+ }
50
+ }, [
51
+ b,
52
+ x,
53
+ y
54
+ ]);
55
+ r(() => {
56
+ _ && z();
57
+ }, [_, z]);
58
+ let B = i(() => new Set(D.filter((e) => e.installed).map((e) => e.packageName)), [D]), V = i(() => D.filter((e) => !e.installed && !F.has(e.packageName)), [D, F]), H = i(() => k.filter((e) => e.contribution.mountPoint === y), [k, y]), U = n(async (n) => {
59
+ M(n), P(null);
60
+ try {
61
+ if (await t(b, e(x, "/plugins/install"), "POST", { packageName: n }), !L.current) return;
62
+ I((e) => new Set(e).add(n)), S?.(n), z();
63
+ } catch (e) {
64
+ if (!L.current) return;
65
+ P(e instanceof Error ? e.message : String(e));
66
+ } finally {
67
+ L.current && M(null);
68
+ }
69
+ }, [
70
+ b,
71
+ x,
72
+ S,
73
+ z
74
+ ]);
75
+ return _ ? /* @__PURE__ */ h(f, { children: /* @__PURE__ */ h(p.div, {
76
+ initial: { opacity: 0 },
77
+ animate: { opacity: 1 },
78
+ exit: { opacity: 0 },
79
+ className: "fixed inset-0 z-50 bg-bg-overlay flex items-center justify-center p-4",
80
+ onClick: v,
81
+ children: /* @__PURE__ */ g(p.div, {
82
+ ref: R,
83
+ initial: {
84
+ opacity: 0,
85
+ y: 8
86
+ },
87
+ animate: {
88
+ opacity: 1,
89
+ y: 0
90
+ },
91
+ exit: {
92
+ opacity: 0,
93
+ y: -8
94
+ },
95
+ className: "bg-bg-surface rounded-lg shadow-xl w-full max-w-2xl max-h-[80vh] overflow-hidden flex flex-col focus:outline-none",
96
+ onClick: (e) => e.stopPropagation(),
97
+ role: "dialog",
98
+ "aria-modal": "true",
99
+ "aria-labelledby": "add-tab-dialog-title",
100
+ tabIndex: -1,
101
+ children: [
102
+ /* @__PURE__ */ g("div", {
103
+ className: "flex items-center justify-between px-5 py-4 border-b border-border-default",
104
+ children: [/* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("h2", {
105
+ id: "add-tab-dialog-title",
106
+ className: "text-base font-semibold text-text-primary",
107
+ children: "Add tab"
108
+ }), /* @__PURE__ */ g("p", {
109
+ className: "text-xs text-text-secondary",
110
+ children: [
111
+ "Install a UI plugin that contributes to",
112
+ " ",
113
+ /* @__PURE__ */ h("code", {
114
+ className: "font-mono",
115
+ children: y
116
+ })
117
+ ]
118
+ })] }), /* @__PURE__ */ h("button", {
119
+ type: "button",
120
+ onClick: v,
121
+ className: "text-text-secondary hover:text-text-primary",
122
+ "aria-label": "Close",
123
+ children: /* @__PURE__ */ h(d, { className: "w-5 h-5" })
124
+ })]
125
+ }),
126
+ /* @__PURE__ */ g("div", {
127
+ className: "overflow-y-auto px-5 py-4 space-y-6",
128
+ children: [
129
+ T && /* @__PURE__ */ g("div", {
130
+ className: "flex items-start gap-2 text-sm text-status-danger-text bg-status-danger-bg px-3 py-2 rounded-md",
131
+ children: [/* @__PURE__ */ h(s, { className: "w-4 h-4 mt-0.5 shrink-0" }), /* @__PURE__ */ h("span", { children: T })]
132
+ }),
133
+ N && /* @__PURE__ */ g("div", {
134
+ className: "flex items-start gap-2 text-sm text-status-danger-text bg-status-danger-bg px-3 py-2 rounded-md",
135
+ children: [/* @__PURE__ */ h(s, { className: "w-4 h-4 mt-0.5 shrink-0" }), /* @__PURE__ */ h("span", { children: N })]
136
+ }),
137
+ C && /* @__PURE__ */ g("div", {
138
+ className: "flex items-center gap-2 text-sm text-text-secondary",
139
+ children: [/* @__PURE__ */ h(l, { className: "w-4 h-4 animate-spin" }), "Loading available plugins…"]
140
+ }),
141
+ !C && H.length > 0 && /* @__PURE__ */ g("section", { children: [/* @__PURE__ */ h("h3", {
142
+ className: "text-xs font-medium text-text-secondary uppercase tracking-wide mb-2",
143
+ children: "Already on this tab strip"
144
+ }), /* @__PURE__ */ h("ul", {
145
+ className: "space-y-1",
146
+ children: H.map((e) => /* @__PURE__ */ g("li", {
147
+ className: "flex items-center gap-2 text-sm text-text-primary",
148
+ children: [
149
+ /* @__PURE__ */ h(c, { className: "w-4 h-4 text-status-success-text" }),
150
+ /* @__PURE__ */ h("span", {
151
+ className: "font-medium",
152
+ children: e.contribution.title
153
+ }),
154
+ /* @__PURE__ */ g("span", {
155
+ className: "text-xs text-text-muted",
156
+ children: [
157
+ "(",
158
+ e.pluginKey,
159
+ ")"
160
+ ]
161
+ })
162
+ ]
163
+ }, e.contribution.id))
164
+ })] }),
165
+ !C && /* @__PURE__ */ g("section", { children: [/* @__PURE__ */ h("h3", {
166
+ className: "text-xs font-medium text-text-secondary uppercase tracking-wide mb-2",
167
+ children: "Available"
168
+ }), V.length === 0 ? /* @__PURE__ */ h("p", {
169
+ className: "text-sm text-text-muted",
170
+ children: "No additional plugins available in the catalog."
171
+ }) : /* @__PURE__ */ h("ul", {
172
+ className: "space-y-2",
173
+ children: V.map((e) => {
174
+ let t = j === e.packageName;
175
+ return /* @__PURE__ */ g("li", {
176
+ className: "flex items-center justify-between gap-3 border border-border-default rounded-md px-3 py-2",
177
+ children: [/* @__PURE__ */ g("div", {
178
+ className: "min-w-0",
179
+ children: [
180
+ /* @__PURE__ */ g("div", {
181
+ className: "text-sm font-medium text-text-primary truncate",
182
+ children: [e.name, e.category && /* @__PURE__ */ h("span", {
183
+ className: "ml-2 text-xs text-text-muted font-normal",
184
+ children: e.category
185
+ })]
186
+ }),
187
+ e.description && /* @__PURE__ */ h("div", {
188
+ className: "text-xs text-text-secondary truncate",
189
+ children: e.description
190
+ }),
191
+ /* @__PURE__ */ h("div", {
192
+ className: "text-[10px] text-text-muted font-mono mt-0.5",
193
+ children: e.packageName
194
+ })
195
+ ]
196
+ }), /* @__PURE__ */ h("button", {
197
+ type: "button",
198
+ onClick: () => void U(e.packageName),
199
+ disabled: t || B.has(e.packageName),
200
+ className: "shrink-0 inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed",
201
+ children: t ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(l, { className: "w-3.5 h-3.5 animate-spin" }), "Installing…"] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(u, { className: "w-3.5 h-3.5" }), "Add"] })
202
+ })]
203
+ }, e.packageName);
204
+ })
205
+ })] })
206
+ ]
207
+ }),
208
+ /* @__PURE__ */ h("div", {
209
+ className: "px-5 py-3 border-t border-border-default flex items-center justify-end",
210
+ children: /* @__PURE__ */ h("button", {
211
+ type: "button",
212
+ onClick: v,
213
+ className: "text-sm text-text-secondary hover:text-text-primary",
214
+ children: "Done"
215
+ })
216
+ })
217
+ ]
218
+ })
219
+ }, "overlay") }) : null;
220
+ }
221
+ //#endregion
222
+ export { _ as AddTabDialog };
223
+
224
+ //# sourceMappingURL=AddTabDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddTabDialog.js","names":[],"sources":["../../../src/components/plugins/AddTabDialog.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { X, Plus, Loader2, CheckCircle2, AlertTriangle } from 'lucide-react';\nimport { motion, AnimatePresence } from 'framer-motion';\n\nimport { agentAiMutate } from '@/services/aiApi';\nimport { agentApiPath } from '@/utils/agentApiPath';\n\ninterface CatalogEntry {\n packageName: string;\n name: string;\n description?: string;\n cliCommand?: string;\n category?: string;\n installed: boolean;\n}\n\ninterface CatalogResponse {\n plugins: CatalogEntry[];\n}\n\ninterface ContributionEntry {\n pluginKey: string;\n contribution: {\n mountPoint: string;\n id: string;\n title: string;\n };\n}\n\ninterface ContributionsResponse {\n contributions: ContributionEntry[];\n}\n\nexport interface AddTabDialogProps {\n isOpen: boolean;\n onClose: () => void;\n /** Which mount point the picker filters for (e.g. `'vibe.detailTab'`). */\n mountPoint: string;\n /** Agent id whose tunnel the picker queries. */\n agentId: string;\n /** Active profile on that agent. */\n profile: string;\n /** Called after a successful install so the host can refetch contributions. */\n onInstalled?: (packageName: string) => void;\n}\n\n/**\n * PR-10 \"+ Add tab\" picker. Lists available plugins from the agent's\n * catalog and lets the user install them inline. Once installed,\n * `onInstalled` fires and the host re-queries contributions so the new\n * tab shows up in the strip without a page refresh.\n *\n * Catalog entries are filtered down to the org-allow-list at the agent\n * boundary (the `/plugins/install` endpoint already enforces\n * `isTrustedPackage`), so this dialog can safely surface every catalog\n * entry without per-row filtering.\n */\nexport function AddTabDialog({\n isOpen,\n onClose,\n mountPoint,\n agentId,\n profile,\n onInstalled,\n}: AddTabDialogProps) {\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [catalog, setCatalog] = useState<CatalogEntry[]>([]);\n const [contributions, setContributions] = useState<ContributionEntry[]>([]);\n const [installing, setInstalling] = useState<string | null>(null);\n const [installError, setInstallError] = useState<string | null>(null);\n const [installedRecently, setInstalledRecently] = useState<Set<string>>(new Set());\n const aliveRef = useRef(true);\n\n useEffect(() => {\n aliveRef.current = true;\n return () => {\n aliveRef.current = false;\n };\n }, []);\n\n // Modal-dialog UX: bind Escape to close + trap focus inside the\n // dialog container while it's open. Without these the modal\n // violates WCAG 2.4.3 (focus order) and standard keyboard\n // expectations.\n const dialogRef = useRef<HTMLDivElement | null>(null);\n useEffect(() => {\n if (!isOpen) return undefined;\n const previouslyFocused = (\n typeof document !== 'undefined' ? document.activeElement : null\n ) as HTMLElement | null;\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n onClose();\n return;\n }\n if (e.key !== 'Tab' || !dialogRef.current) return;\n const focusables = dialogRef.current.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n );\n if (focusables.length === 0) return;\n const first = focusables[0]!;\n const last = focusables[focusables.length - 1]!;\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n };\n document.addEventListener('keydown', handleKey);\n // Focus the dialog container so subsequent Tab cycles stay inside.\n setTimeout(() => dialogRef.current?.focus(), 0);\n return () => {\n document.removeEventListener('keydown', handleKey);\n previouslyFocused?.focus?.();\n };\n }, [isOpen, onClose]);\n\n // Reset the recent-install filter when the dialog's context changes\n // (different agent / profile / mount) or when it closes. Otherwise\n // a multi-agent flow keeps filtering out packages installed for the\n // previous agent context.\n useEffect(() => {\n setInstalledRecently(new Set());\n }, [agentId, profile, mountPoint, isOpen]);\n\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const [catalogResp, contributionsResp] = await Promise.all([\n agentAiMutate<CatalogResponse>(\n agentId,\n agentApiPath(profile, '/plugins/catalog'),\n 'GET',\n null\n ),\n agentAiMutate<ContributionsResponse>(\n agentId,\n agentApiPath(\n profile,\n `/plugins/contributions?mountPoint=${encodeURIComponent(mountPoint)}`\n ),\n 'GET',\n null\n ),\n ]);\n if (!aliveRef.current) return;\n setCatalog(catalogResp.plugins ?? []);\n setContributions(contributionsResp.contributions ?? []);\n } catch (err) {\n if (!aliveRef.current) return;\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n if (aliveRef.current) setLoading(false);\n }\n }, [agentId, profile, mountPoint]);\n\n useEffect(() => {\n if (isOpen) {\n void fetchData();\n }\n }, [isOpen, fetchData]);\n\n const installedPackages = useMemo(\n () => new Set(catalog.filter((c) => c.installed).map((c) => c.packageName)),\n [catalog]\n );\n\n // Available = catalog entries that aren't yet installed. The agent\n // doesn't tell us up-front WHICH catalog entries contribute to this\n // mountPoint (manifests aren't loaded until install), so we list them\n // all; the user picks; after install the host re-queries and the new\n // tab appears in the strip if the plugin contributes here.\n const available = useMemo(\n () => catalog.filter((c) => !c.installed && !installedRecently.has(c.packageName)),\n [catalog, installedRecently]\n );\n\n // Installed plugins whose contributions ARE for this mount point. Useful\n // as a \"what's already here\" hint so the user doesn't try to install\n // duplicates.\n const installedForThisMount = useMemo(\n () => contributions.filter((c) => c.contribution.mountPoint === mountPoint),\n [contributions, mountPoint]\n );\n\n const install = useCallback(\n async (packageName: string) => {\n setInstalling(packageName);\n setInstallError(null);\n try {\n await agentAiMutate(agentId, agentApiPath(profile, '/plugins/install'), 'POST', {\n packageName,\n });\n if (!aliveRef.current) return;\n setInstalledRecently((prev) => new Set(prev).add(packageName));\n onInstalled?.(packageName);\n // Refresh both lists so the UI reflects the new state.\n void fetchData();\n } catch (err) {\n if (!aliveRef.current) return;\n setInstallError(err instanceof Error ? err.message : String(err));\n } finally {\n if (aliveRef.current) setInstalling(null);\n }\n },\n [agentId, profile, onInstalled, fetchData]\n );\n\n if (!isOpen) return null;\n\n return (\n <AnimatePresence>\n <motion.div\n key=\"overlay\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-50 bg-bg-overlay flex items-center justify-center p-4\"\n onClick={onClose}\n >\n <motion.div\n ref={dialogRef}\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -8 }}\n className=\"bg-bg-surface rounded-lg shadow-xl w-full max-w-2xl max-h-[80vh] overflow-hidden flex flex-col focus:outline-none\"\n onClick={(e) => e.stopPropagation()}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"add-tab-dialog-title\"\n tabIndex={-1}\n >\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-default\">\n <div>\n <h2 id=\"add-tab-dialog-title\" className=\"text-base font-semibold text-text-primary\">\n Add tab\n </h2>\n <p className=\"text-xs text-text-secondary\">\n Install a UI plugin that contributes to{' '}\n <code className=\"font-mono\">{mountPoint}</code>\n </p>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-text-secondary hover:text-text-primary\"\n aria-label=\"Close\"\n >\n <X className=\"w-5 h-5\" />\n </button>\n </div>\n\n <div className=\"overflow-y-auto px-5 py-4 space-y-6\">\n {error && (\n <div className=\"flex items-start gap-2 text-sm text-status-danger-text bg-status-danger-bg px-3 py-2 rounded-md\">\n <AlertTriangle className=\"w-4 h-4 mt-0.5 shrink-0\" />\n <span>{error}</span>\n </div>\n )}\n {installError && (\n <div className=\"flex items-start gap-2 text-sm text-status-danger-text bg-status-danger-bg px-3 py-2 rounded-md\">\n <AlertTriangle className=\"w-4 h-4 mt-0.5 shrink-0\" />\n <span>{installError}</span>\n </div>\n )}\n\n {loading && (\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n Loading available plugins…\n </div>\n )}\n\n {!loading && installedForThisMount.length > 0 && (\n <section>\n <h3 className=\"text-xs font-medium text-text-secondary uppercase tracking-wide mb-2\">\n Already on this tab strip\n </h3>\n <ul className=\"space-y-1\">\n {installedForThisMount.map((c) => (\n <li\n key={c.contribution.id}\n className=\"flex items-center gap-2 text-sm text-text-primary\"\n >\n <CheckCircle2 className=\"w-4 h-4 text-status-success-text\" />\n <span className=\"font-medium\">{c.contribution.title}</span>\n <span className=\"text-xs text-text-muted\">({c.pluginKey})</span>\n </li>\n ))}\n </ul>\n </section>\n )}\n\n {!loading && (\n <section>\n <h3 className=\"text-xs font-medium text-text-secondary uppercase tracking-wide mb-2\">\n Available\n </h3>\n {available.length === 0 ? (\n <p className=\"text-sm text-text-muted\">\n No additional plugins available in the catalog.\n </p>\n ) : (\n <ul className=\"space-y-2\">\n {available.map((c) => {\n const isInstallingThis = installing === c.packageName;\n return (\n <li\n key={c.packageName}\n className=\"flex items-center justify-between gap-3 border border-border-default rounded-md px-3 py-2\"\n >\n <div className=\"min-w-0\">\n <div className=\"text-sm font-medium text-text-primary truncate\">\n {c.name}\n {c.category && (\n <span className=\"ml-2 text-xs text-text-muted font-normal\">\n {c.category}\n </span>\n )}\n </div>\n {c.description && (\n <div className=\"text-xs text-text-secondary truncate\">\n {c.description}\n </div>\n )}\n <div className=\"text-[10px] text-text-muted font-mono mt-0.5\">\n {c.packageName}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => void install(c.packageName)}\n disabled={isInstallingThis || installedPackages.has(c.packageName)}\n className=\"shrink-0 inline-flex items-center gap-1 px-2.5 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isInstallingThis ? (\n <>\n <Loader2 className=\"w-3.5 h-3.5 animate-spin\" />\n Installing…\n </>\n ) : (\n <>\n <Plus className=\"w-3.5 h-3.5\" />\n Add\n </>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </section>\n )}\n </div>\n\n <div className=\"px-5 py-3 border-t border-border-default flex items-center justify-end\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-sm text-text-secondary hover:text-text-primary\"\n >\n Done\n </button>\n </div>\n </motion.div>\n </motion.div>\n </AnimatePresence>\n );\n}\n"],"mappings":"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"}