@burdenoff/microfe-vibecontrols 2026.531.16 → 2026.601.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.
Files changed (44) hide show
  1. package/dist/VibeControlsRoutes.js +142 -146
  2. package/dist/VibeControlsRoutes.js.map +1 -1
  3. package/dist/components/agent-manager/controls/ModelSelector.js +1 -1
  4. package/dist/components/agent-manager/controls/ModelSelector.js.map +1 -1
  5. package/dist/components/agents/AgentCard.js +106 -85
  6. package/dist/components/agents/AgentCard.js.map +1 -1
  7. package/dist/components/agents/AgentStatusBadge.js +25 -24
  8. package/dist/components/agents/AgentStatusBadge.js.map +1 -1
  9. package/dist/components/shared/LinkToVibePanel.js +36 -26
  10. package/dist/components/shared/LinkToVibePanel.js.map +1 -1
  11. package/dist/components/shared/PluginGate.js +72 -68
  12. package/dist/components/shared/PluginGate.js.map +1 -1
  13. package/dist/components/shared/cardMotion.js +28 -0
  14. package/dist/components/shared/cardMotion.js.map +1 -0
  15. package/dist/components/templates/TemplateCard.js +43 -50
  16. package/dist/components/templates/TemplateCard.js.map +1 -1
  17. package/dist/components/tunnels/TunnelCreateWizard.js +57 -49
  18. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  19. package/dist/components/vibe/VibeLinkedEntitiesPanel.js +121 -72
  20. package/dist/components/vibe/VibeLinkedEntitiesPanel.js.map +1 -1
  21. package/dist/components/vibes/VibeCard.js +65 -72
  22. package/dist/components/vibes/VibeCard.js.map +1 -1
  23. package/dist/generated/wspace-operations.js +964 -886
  24. package/dist/generated/wspace-operations.js.map +1 -1
  25. package/dist/generated/wspace-types.js.map +1 -1
  26. package/dist/index.js +10 -10
  27. package/dist/pages/ActionsPage.js +297 -268
  28. package/dist/pages/ActionsPage.js.map +1 -1
  29. package/dist/pages/AgentDetailsPage.js +11 -11
  30. package/dist/pages/AnalyticsPage.js +2 -2
  31. package/dist/pages/AnalyticsPage.js.map +1 -1
  32. package/dist/pages/TargetsPage.js +16 -16
  33. package/dist/pages/VibeAuditPage.js +7 -7
  34. package/dist/pages/VibeDeckPage.js +180 -180
  35. package/dist/pages/VibeDeckPage.js.map +1 -1
  36. package/dist/pages/ai/AIPage.js +2 -2
  37. package/dist/pages/ai/AIPage.js.map +1 -1
  38. package/dist/pages/ai/AgentManagerPage.js +162 -127
  39. package/dist/pages/ai/AgentManagerPage.js.map +1 -1
  40. package/dist/utils/agentHealth.js +31 -0
  41. package/dist/utils/agentHealth.js.map +1 -0
  42. package/package.json +2 -2
  43. package/dist/pages/PluginStandalonePage.js +0 -151
  44. package/dist/pages/PluginStandalonePage.js.map +0 -1
@@ -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, useParams } 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 ScheduledJobDetailPage = React.lazy(() =>\n import('./pages/ScheduledJobDetailPage').then((m) => ({ default: m.ScheduledJobDetailPage }))\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);\nconst LogsPage = React.lazy(() =>\n import('./pages/LogsPage').then((m) => ({ default: m.LogsPage }))\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);\nconst PluginsCatalogPage = React.lazy(() =>\n import('./pages/PluginsCatalogPage').then((m) => ({ default: m.PluginsCatalogPage }))\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);\nconst AIBookmarksPage = React.lazy(() =>\n import('./pages/ai/AIBookmarksPage').then((m) => ({ default: m.AIBookmarksPage }))\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 * Legacy redirect: /ai-tools/<tab> → /ai-tools/ai/<tab>.\n *\n * Before the Plan / AI mode toggle the page was reachable directly at\n * /ai-tools/<tab>. New shape is /ai-tools/<mode>/<tab>. We keep the\n * legacy links working by mapping the captured `:tab` param: if it\n * resolves to a known AI sub-tab, redirect there; if it's literally\n * \"plan\", route to the Plan page; otherwise fall back to AI overview.\n */\nconst VALID_AI_TABS = new Set<string>([\n 'overview',\n 'templates',\n 'contexts',\n 'prompts',\n 'sessions',\n 'tasks',\n 'stats',\n 'playground',\n 'config',\n]);\n\nfunction LegacyAIToolsRedirect() {\n const { tab } = useParams<{ tab?: string }>();\n if (tab === 'plan') {\n return <Navigate to=\"/vibecontrols/ai-tools/plan\" replace />;\n }\n if (tab && VALID_AI_TABS.has(tab)) {\n return <Navigate to={`/vibecontrols/ai-tools/ai/${tab}`} replace />;\n }\n return <Navigate to=\"/vibecontrols/ai-tools/ai/overview\" replace />;\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 {/* Plugins catalog — searchable grid of every published plugin. */}\n <Route path=\"plugins\" element={gated('vibecontrols.vibes', <PluginsCatalogPage />)} />\n\n <Route path=\"agents\" element={gated('vibecontrols.agents', <AgentsLandingPage />)} />\n <Route path=\"agents/new\" element={<Navigate to=\"../agents?create=true\" replace />} />\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/new\" element={<Navigate to=\"../vibes?create=true\" replace />} />\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 {/* Saved messages — listed BEFORE ai/:tab so \"bookmarks\" is not consumed as a tab. */}\n <Route path=\"ai/bookmarks\" element={gated('vibecontrols.ai', <AIBookmarksPage />)} />\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 — Plan / AI modes:\n /ai-tools → /ai-tools/ai/overview (redirect)\n /ai-tools/plan → Plan mode (plannotator iframe)\n /ai-tools/ai → /ai-tools/ai/overview (redirect)\n /ai-tools/ai/:tab → AI mode with active sub-tab\n Legacy /ai-tools/<tab> URLs from before the Plan mode rollout\n redirect into the new shape via LegacyAIToolsRedirect. */}\n <Route path=\"ai-tools\" element={<Navigate to=\"ai/overview\" replace />} />\n <Route path=\"ai-tools/plan\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/ai\" element={<Navigate to=\"overview\" replace />} />\n <Route path=\"ai-tools/ai/:tab\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/:tab\" element={<LegacyAIToolsRedirect />} />\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 {/* ScheduledJob (wspace-scheduler-svc) — separate id space\n from VibeCalendarTask above, so it needs its own route. */}\n <Route\n path=\"calendar/scheduled-job/:jobId\"\n element={gated('vibecontrols.calendar', <ScheduledJobDetailPage />)}\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={gated('vibecontrols.agents', <LogsPage />)} />\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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"}
1
+ {"version":3,"file":"VibeControlsRoutes.js","names":[],"sources":["../src/VibeControlsRoutes.tsx"],"sourcesContent":["import React, { Suspense, useEffect } from 'react';\nimport { Navigate, Route, Routes, useLocation, useParams } 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 ScheduledJobDetailPage = React.lazy(() =>\n import('./pages/ScheduledJobDetailPage').then((m) => ({ default: m.ScheduledJobDetailPage }))\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);\nconst LogsPage = React.lazy(() =>\n import('./pages/LogsPage').then((m) => ({ default: m.LogsPage }))\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 PluginsCatalogPage = React.lazy(() =>\n import('./pages/PluginsCatalogPage').then((m) => ({ default: m.PluginsCatalogPage }))\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);\nconst AIBookmarksPage = React.lazy(() =>\n import('./pages/ai/AIBookmarksPage').then((m) => ({ default: m.AIBookmarksPage }))\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 * Legacy redirect: /ai-tools/<tab> → /ai-tools/ai/<tab>.\n *\n * Before the Plan / AI mode toggle the page was reachable directly at\n * /ai-tools/<tab>. New shape is /ai-tools/<mode>/<tab>. We keep the\n * legacy links working by mapping the captured `:tab` param: if it\n * resolves to a known AI sub-tab, redirect there; if it's literally\n * \"plan\", route to the Plan page; otherwise fall back to AI overview.\n */\nconst VALID_AI_TABS = new Set<string>([\n 'overview',\n 'templates',\n 'contexts',\n 'prompts',\n 'sessions',\n 'tasks',\n 'stats',\n 'playground',\n 'config',\n]);\n\nfunction LegacyAIToolsRedirect() {\n const { tab } = useParams<{ tab?: string }>();\n if (tab === 'plan') {\n return <Navigate to=\"/vibecontrols/ai-tools/plan\" replace />;\n }\n if (tab && VALID_AI_TABS.has(tab)) {\n return <Navigate to={`/vibecontrols/ai-tools/ai/${tab}`} replace />;\n }\n return <Navigate to=\"/vibecontrols/ai-tools/ai/overview\" replace />;\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 {/* Plugins catalog — searchable grid of every published plugin. */}\n <Route path=\"plugins\" element={gated('vibecontrols.vibes', <PluginsCatalogPage />)} />\n\n <Route path=\"agents\" element={gated('vibecontrols.agents', <AgentsLandingPage />)} />\n <Route path=\"agents/new\" element={<Navigate to=\"../agents?create=true\" replace />} />\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/new\" element={<Navigate to=\"../vibes?create=true\" replace />} />\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 {/* Saved messages — listed BEFORE ai/:tab so \"bookmarks\" is not consumed as a tab. */}\n <Route path=\"ai/bookmarks\" element={gated('vibecontrols.ai', <AIBookmarksPage />)} />\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 — Plan / AI modes:\n /ai-tools → /ai-tools/ai/overview (redirect)\n /ai-tools/plan → Plan mode (plannotator iframe)\n /ai-tools/ai → /ai-tools/ai/overview (redirect)\n /ai-tools/ai/:tab → AI mode with active sub-tab\n Legacy /ai-tools/<tab> URLs from before the Plan mode rollout\n redirect into the new shape via LegacyAIToolsRedirect. */}\n <Route path=\"ai-tools\" element={<Navigate to=\"ai/overview\" replace />} />\n <Route path=\"ai-tools/plan\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/ai\" element={<Navigate to=\"overview\" replace />} />\n <Route path=\"ai-tools/ai/:tab\" element={gated('vibecontrols.ai', <AIPage />)} />\n <Route path=\"ai-tools/:tab\" element={<LegacyAIToolsRedirect />} />\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 {/* ScheduledJob (wspace-scheduler-svc) — separate id space\n from VibeCalendarTask above, so it needs its own route. */}\n <Route\n path=\"calendar/scheduled-job/:jobId\"\n element={gated('vibecontrols.calendar', <ScheduledJobDetailPage />)}\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={gated('vibecontrols.agents', <LogsPage />)} />\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,KAAyB,EAAM,WACnC,OAAO,qCAAkC,MAAM,OAAO,EAAE,SAAS,EAAE,wBAAwB,EAAE,CAC9F,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,EACK,IAAW,EAAM,WACrB,OAAO,uBAAoB,MAAM,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,CAClE,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,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,EACK,IAAkB,EAAM,WAC5B,OAAO,iCAA8B,MAAM,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,CACnF;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;;AAYT,IAAM,IAAgB,IAAI,IAAY;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,SAAS,IAAwB;CAC/B,IAAM,EAAE,WAAQ,GAA6B;AAO7C,QANI,MAAQ,SACH,kBAAC,GAAD;EAAU,IAAG;EAA8B,SAAA;EAAU,CAAA,GAE1D,KAAO,EAAc,IAAI,EAAI,GACxB,kBAAC,GAAD;EAAU,IAAI,6BAA6B;EAAO,SAAA;EAAU,CAAA,GAE9D,kBAAC,GAAD;EAAU,IAAG;EAAqC,SAAA;EAAU,CAAA;;AAMrE,SAAS,KAA0B;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,IAAD,EAA2B,CAAA;YACvF;EACW,CAAA;;AAIlB,SAAgB,KAAqB;AACnC,QACE,kBAAC,GAAD;EAAU,UAAU,kBAAC,GAAD,EAAuB,CAAA;YAA3C,CACE,kBAAC,GAAD,EAAe,CAAA,EACf,kBAAC,IAAD,EAAA,UAAA;GAEE,kBAAC,GAAD;IAAO,OAAA;IAAM,SAAS,EAAM,yBAAyB,kBAAC,GAAD,EAAgB,CAAA,CAAC;IAAI,CAAA;GAI1E,kBAAC,GAAD;IAAO,MAAK;IAAU,SAAS,EAAM,sBAAsB,kBAAC,GAAD,EAAsB,CAAA,CAAC;IAAI,CAAA;GAEtF,kBAAC,GAAD;IAAO,MAAK;IAAS,SAAS,EAAM,uBAAuB,kBAAC,GAAD,EAAqB,CAAA,CAAC;IAAI,CAAA;GACrF,kBAAC,GAAD;IAAO,MAAK;IAAa,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAwB,SAAA;KAAU,CAAA;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,kBAAC,GAAD;KAAU,IAAG;KAAuB,SAAA;KAAU,CAAA;IAAI,CAAA;GACnF,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;GAE5E,kBAAC,GAAD;IAAO,MAAK;IAAe,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAmB,CAAA,CAAC;IAAI,CAAA;GACrF,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;GAQF,kBAAC,GAAD;IAAO,MAAK;IAAW,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAc,SAAA;KAAU,CAAA;IAAI,CAAA;GACzE,kBAAC,GAAD;IAAO,MAAK;IAAgB,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAU,CAAA,CAAC;IAAI,CAAA;GAC7E,kBAAC,GAAD;IAAO,MAAK;IAAc,SAAS,kBAAC,GAAD;KAAU,IAAG;KAAW,SAAA;KAAU,CAAA;IAAI,CAAA;GACzE,kBAAC,GAAD;IAAO,MAAK;IAAmB,SAAS,EAAM,mBAAmB,kBAAC,GAAD,EAAU,CAAA,CAAC;IAAI,CAAA;GAChF,kBAAC,GAAD;IAAO,MAAK;IAAgB,SAAS,kBAAC,GAAD,EAAyB,CAAA;IAAI,CAAA;GAClE,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;GAGF,kBAAC,GAAD;IACE,MAAK;IACL,SAAS,EAAM,yBAAyB,kBAAC,IAAD,EAA0B,CAAA,CAAC;IACnE,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,EAAM,uBAAuB,kBAAC,GAAD,EAAY,CAAA,CAAC;IAAI,CAAA;GAG1E,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"}
@@ -151,7 +151,7 @@ function m({ value: m, onChange: h, provider: g, agentId: _, profile: v }) {
151
151
  className: "w-full px-3 py-1.5 text-xs border-b border-border-default bg-transparent text-text-primary placeholder:text-text-tertiary focus:outline-none sticky top-0 bg-bg-surface"
152
152
  }),
153
153
  N.map((e) => /* @__PURE__ */ c("div", { children: e.models.length > 0 && /* @__PURE__ */ l(s, { children: [/* @__PURE__ */ c("div", {
154
- className: "px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-text-tertiary bg-bg-sunken",
154
+ className: "px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-text-secondary bg-bg-sunken",
155
155
  children: e.label
156
156
  }), e.models.map((e) => /* @__PURE__ */ c("button", {
157
157
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"file":"ModelSelector.js","names":[],"sources":["../../../../src/components/agent-manager/controls/ModelSelector.tsx"],"sourcesContent":["/**\n * Model selector dropdown.\n *\n * Displays a compact button with the current model name that opens a\n * grouped dropdown of models filtered by SDK provider.\n */\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { fetchModels } from '@/services/aiApi';\nimport type { AgentSdkType } from '@/types/agentManager';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface ModelSelectorProps {\n value: string;\n onChange: (model: string) => void;\n provider?: AgentSdkType;\n agentId?: string;\n /** Canonical CLI profile name on the remote agent. */\n profile?: string;\n}\n\ninterface ModelGroup {\n label: string;\n sdk: AgentSdkType;\n models: string[];\n}\n\nconst MODEL_GROUPS: ModelGroup[] = [\n { label: 'Claude', sdk: 'claude', models: [] },\n { label: 'Codex', sdk: 'codex', models: [] },\n { label: 'Gemini', sdk: 'gemini', models: [] },\n { label: 'OpenCode', sdk: 'opencode', models: [] },\n { label: 'OpenAI-compatible', sdk: 'openai-compat', models: [] },\n { label: 'Goose', sdk: 'goose', models: [] },\n { label: 'Amp', sdk: 'amp', models: [] },\n { label: 'Copilot', sdk: 'copilot', models: [] },\n { label: 'Crush', sdk: 'crush', models: [] },\n { label: 'Pi', sdk: 'pi', models: [] },\n { label: 'Aider', sdk: 'aider', models: [] },\n { label: 'Plandex', sdk: 'plandex', models: [] },\n];\n\n/** Truncate model name for compact display */\nfunction displayName(model: string): string {\n // Remove common prefixes for compact display\n return model\n .replace(/^opencode\\//, '')\n .replace('claude-', '')\n .replace('-20250514', '')\n .replace('-20251001', '');\n}\n\nfunction modelGroupLabel(provider: AgentSdkType): string {\n return MODEL_GROUPS.find((group) => group.sdk === provider)?.label ?? provider;\n}\n\nfunction uniqueModels(models: string[], currentValue: string): string[] {\n return Array.from(new Set([currentValue, ...models].filter(Boolean)));\n}\n\nexport function ModelSelector({ value, onChange, provider, agentId, profile }: ModelSelectorProps) {\n const tr = useTr();\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [agentModels, setAgentModels] = useState<string[] | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState({ bottom: 0, left: 0 });\n\n const filteredGroups =\n provider && agentModels\n ? [\n {\n label: modelGroupLabel(provider),\n sdk: provider,\n models: uniqueModels(agentModels, value),\n },\n ]\n : provider\n ? MODEL_GROUPS.filter((g) => g.sdk === provider)\n : MODEL_GROUPS;\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [open, handleClickOutside]);\n\n useEffect(() => {\n if (!open) setSearch('');\n }, [open]);\n\n useEffect(() => {\n if (!open || !agentId || !provider) return;\n\n let cancelled = false;\n setAgentModels(null);\n void fetchModels({ id: agentId, profile: profile ?? 'default' }, provider)\n .then((models) => {\n if (cancelled) return;\n const modelIds = models.map((model) => model.id).filter(Boolean);\n setAgentModels(modelIds);\n })\n .catch(() => {\n if (!cancelled) setAgentModels([]);\n });\n\n return () => {\n cancelled = true;\n };\n }, [agentId, open, profile, provider]);\n\n const searchLower = search.toLowerCase();\n const searchedGroups = filteredGroups.map((g) => ({\n ...g,\n models: search ? g.models.filter((m) => m.toLowerCase().includes(searchLower)) : g.models,\n }));\n\n const handleToggle = () => {\n if (!open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setPos({ bottom: window.innerHeight - rect.top + 4, left: rect.left });\n }\n setOpen((prev) => !prev);\n };\n\n return (\n <div ref={containerRef} className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n className=\"flex items-center gap-1 px-2 py-1 text-xs font-medium rounded border border-border-default bg-bg-surface text-text-primary hover:bg-bg-elevated hover:border-border-strong transition-colors max-w-[160px]\"\n title={value}\n >\n <span className=\"truncate\">{displayName(value)}</span>\n <ChevronDown className=\"size-3 flex-shrink-0\" />\n </button>\n\n {open && (\n <div\n className=\"fixed w-64 max-h-72 overflow-y-auto rounded-lg border border-border-default bg-bg-surface shadow-lg z-[100]\"\n style={{ bottom: pos.bottom, left: pos.left }}\n >\n <input\n aria-label=\"Search...\"\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search...\"\n className=\"w-full px-3 py-1.5 text-xs border-b border-border-default bg-transparent text-text-primary placeholder:text-text-tertiary focus:outline-none sticky top-0 bg-bg-surface\"\n />\n {searchedGroups.map((group) => (\n <div key={group.sdk}>\n {group.models.length > 0 && (\n <>\n <div className=\"px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-text-tertiary bg-bg-sunken\">\n {group.label}\n </div>\n {group.models.map((model) => (\n <button\n key={model}\n type=\"button\"\n onClick={() => {\n onChange(model);\n setOpen(false);\n }}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-bg-elevated transition-colors ${\n model === value\n ? 'text-text-primary bg-bg-sunken font-medium'\n : 'text-text-primary'\n }`}\n >\n {model}\n </button>\n ))}\n </>\n )}\n </div>\n ))}\n {searchedGroups.every((g) => g.models.length === 0) && (\n <div className=\"px-3 py-4 text-sm text-text-tertiary text-center\">\n {tr('vibecontrols.agentManager.controls.noModelsAvailable', 'No models available')}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ModelSelector.js","names":[],"sources":["../../../../src/components/agent-manager/controls/ModelSelector.tsx"],"sourcesContent":["/**\n * Model selector dropdown.\n *\n * Displays a compact button with the current model name that opens a\n * grouped dropdown of models filtered by SDK provider.\n */\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { fetchModels } from '@/services/aiApi';\nimport type { AgentSdkType } from '@/types/agentManager';\nimport { useTr } from '../../../shared/hooks/useTr';\n\ninterface ModelSelectorProps {\n value: string;\n onChange: (model: string) => void;\n provider?: AgentSdkType;\n agentId?: string;\n /** Canonical CLI profile name on the remote agent. */\n profile?: string;\n}\n\ninterface ModelGroup {\n label: string;\n sdk: AgentSdkType;\n models: string[];\n}\n\nconst MODEL_GROUPS: ModelGroup[] = [\n { label: 'Claude', sdk: 'claude', models: [] },\n { label: 'Codex', sdk: 'codex', models: [] },\n { label: 'Gemini', sdk: 'gemini', models: [] },\n { label: 'OpenCode', sdk: 'opencode', models: [] },\n { label: 'OpenAI-compatible', sdk: 'openai-compat', models: [] },\n { label: 'Goose', sdk: 'goose', models: [] },\n { label: 'Amp', sdk: 'amp', models: [] },\n { label: 'Copilot', sdk: 'copilot', models: [] },\n { label: 'Crush', sdk: 'crush', models: [] },\n { label: 'Pi', sdk: 'pi', models: [] },\n { label: 'Aider', sdk: 'aider', models: [] },\n { label: 'Plandex', sdk: 'plandex', models: [] },\n];\n\n/** Truncate model name for compact display */\nfunction displayName(model: string): string {\n // Remove common prefixes for compact display\n return model\n .replace(/^opencode\\//, '')\n .replace('claude-', '')\n .replace('-20250514', '')\n .replace('-20251001', '');\n}\n\nfunction modelGroupLabel(provider: AgentSdkType): string {\n return MODEL_GROUPS.find((group) => group.sdk === provider)?.label ?? provider;\n}\n\nfunction uniqueModels(models: string[], currentValue: string): string[] {\n return Array.from(new Set([currentValue, ...models].filter(Boolean)));\n}\n\nexport function ModelSelector({ value, onChange, provider, agentId, profile }: ModelSelectorProps) {\n const tr = useTr();\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [agentModels, setAgentModels] = useState<string[] | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [pos, setPos] = useState({ bottom: 0, left: 0 });\n\n const filteredGroups =\n provider && agentModels\n ? [\n {\n label: modelGroupLabel(provider),\n sdk: provider,\n models: uniqueModels(agentModels, value),\n },\n ]\n : provider\n ? MODEL_GROUPS.filter((g) => g.sdk === provider)\n : MODEL_GROUPS;\n\n const handleClickOutside = useCallback((e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }, []);\n\n useEffect(() => {\n if (open) {\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }\n }, [open, handleClickOutside]);\n\n useEffect(() => {\n if (!open) setSearch('');\n }, [open]);\n\n useEffect(() => {\n if (!open || !agentId || !provider) return;\n\n let cancelled = false;\n setAgentModels(null);\n void fetchModels({ id: agentId, profile: profile ?? 'default' }, provider)\n .then((models) => {\n if (cancelled) return;\n const modelIds = models.map((model) => model.id).filter(Boolean);\n setAgentModels(modelIds);\n })\n .catch(() => {\n if (!cancelled) setAgentModels([]);\n });\n\n return () => {\n cancelled = true;\n };\n }, [agentId, open, profile, provider]);\n\n const searchLower = search.toLowerCase();\n const searchedGroups = filteredGroups.map((g) => ({\n ...g,\n models: search ? g.models.filter((m) => m.toLowerCase().includes(searchLower)) : g.models,\n }));\n\n const handleToggle = () => {\n if (!open && buttonRef.current) {\n const rect = buttonRef.current.getBoundingClientRect();\n setPos({ bottom: window.innerHeight - rect.top + 4, left: rect.left });\n }\n setOpen((prev) => !prev);\n };\n\n return (\n <div ref={containerRef} className=\"relative\">\n <button\n ref={buttonRef}\n type=\"button\"\n onClick={handleToggle}\n className=\"flex items-center gap-1 px-2 py-1 text-xs font-medium rounded border border-border-default bg-bg-surface text-text-primary hover:bg-bg-elevated hover:border-border-strong transition-colors max-w-[160px]\"\n title={value}\n >\n <span className=\"truncate\">{displayName(value)}</span>\n <ChevronDown className=\"size-3 flex-shrink-0\" />\n </button>\n\n {open && (\n <div\n className=\"fixed w-64 max-h-72 overflow-y-auto rounded-lg border border-border-default bg-bg-surface shadow-lg z-[100]\"\n style={{ bottom: pos.bottom, left: pos.left }}\n >\n <input\n aria-label=\"Search...\"\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search...\"\n className=\"w-full px-3 py-1.5 text-xs border-b border-border-default bg-transparent text-text-primary placeholder:text-text-tertiary focus:outline-none sticky top-0 bg-bg-surface\"\n />\n {searchedGroups.map((group) => (\n <div key={group.sdk}>\n {group.models.length > 0 && (\n <>\n <div className=\"px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-text-secondary bg-bg-sunken\">\n {group.label}\n </div>\n {group.models.map((model) => (\n <button\n key={model}\n type=\"button\"\n onClick={() => {\n onChange(model);\n setOpen(false);\n }}\n className={`w-full text-left px-3 py-2 text-sm hover:bg-bg-elevated transition-colors ${\n model === value\n ? 'text-text-primary bg-bg-sunken font-medium'\n : 'text-text-primary'\n }`}\n >\n {model}\n </button>\n ))}\n </>\n )}\n </div>\n ))}\n {searchedGroups.every((g) => g.models.length === 0) && (\n <div className=\"px-3 py-4 text-sm text-text-tertiary text-center\">\n {tr('vibecontrols.agentManager.controls.noModelsAvailable', 'No models available')}\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AA4BA,IAAM,IAA6B;CACjC;EAAE,OAAO;EAAU,KAAK;EAAU,QAAQ,EAAE;EAAE;CAC9C;EAAE,OAAO;EAAS,KAAK;EAAS,QAAQ,EAAE;EAAE;CAC5C;EAAE,OAAO;EAAU,KAAK;EAAU,QAAQ,EAAE;EAAE;CAC9C;EAAE,OAAO;EAAY,KAAK;EAAY,QAAQ,EAAE;EAAE;CAClD;EAAE,OAAO;EAAqB,KAAK;EAAiB,QAAQ,EAAE;EAAE;CAChE;EAAE,OAAO;EAAS,KAAK;EAAS,QAAQ,EAAE;EAAE;CAC5C;EAAE,OAAO;EAAO,KAAK;EAAO,QAAQ,EAAE;EAAE;CACxC;EAAE,OAAO;EAAW,KAAK;EAAW,QAAQ,EAAE;EAAE;CAChD;EAAE,OAAO;EAAS,KAAK;EAAS,QAAQ,EAAE;EAAE;CAC5C;EAAE,OAAO;EAAM,KAAK;EAAM,QAAQ,EAAE;EAAE;CACtC;EAAE,OAAO;EAAS,KAAK;EAAS,QAAQ,EAAE;EAAE;CAC5C;EAAE,OAAO;EAAW,KAAK;EAAW,QAAQ,EAAE;EAAE;CACjD;AAGD,SAAS,EAAY,GAAuB;AAE1C,QAAO,EACJ,QAAQ,eAAe,GAAG,CAC1B,QAAQ,WAAW,GAAG,CACtB,QAAQ,aAAa,GAAG,CACxB,QAAQ,aAAa,GAAG;;AAG7B,SAAS,EAAgB,GAAgC;AACvD,QAAO,EAAa,MAAM,MAAU,EAAM,QAAQ,EAAS,EAAE,SAAS;;AAGxE,SAAS,EAAa,GAAkB,GAAgC;AACtE,QAAO,MAAM,KAAK,IAAI,IAAI,CAAC,GAAc,GAAG,EAAO,CAAC,OAAO,QAAQ,CAAC,CAAC;;AAGvE,SAAgB,EAAc,EAAE,UAAO,aAAU,aAAU,YAAS,cAA+B;CACjG,IAAM,IAAK,GAAO,EACZ,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,CAAC,GAAQ,KAAa,EAAS,GAAG,EAClC,CAAC,GAAa,KAAkB,EAA0B,KAAK,EAC/D,IAAe,EAAuB,KAAK,EAC3C,IAAY,EAA0B,KAAK,EAC3C,CAAC,GAAK,KAAU,EAAS;EAAE,QAAQ;EAAG,MAAM;EAAG,CAAC,EAEhD,IACJ,KAAY,IACR,CACE;EACE,OAAO,EAAgB,EAAS;EAChC,KAAK;EACL,QAAQ,EAAa,GAAa,EAAM;EACzC,CACF,GACD,IACE,EAAa,QAAQ,MAAM,EAAE,QAAQ,EAAS,GAC9C,GAEF,IAAqB,GAAa,MAAkB;AACxD,EAAI,EAAa,WAAW,CAAC,EAAa,QAAQ,SAAS,EAAE,OAAe,IAC1E,EAAQ,GAAM;IAEf,EAAE,CAAC;AAaN,CAXA,QAAgB;AACd,MAAI,EAEF,QADA,SAAS,iBAAiB,aAAa,EAAmB,QAC7C,SAAS,oBAAoB,aAAa,EAAmB;IAE3E,CAAC,GAAM,EAAmB,CAAC,EAE9B,QAAgB;AACd,EAAK,KAAM,EAAU,GAAG;IACvB,CAAC,EAAK,CAAC,EAEV,QAAgB;AACd,MAAI,CAAC,KAAQ,CAAC,KAAW,CAAC,EAAU;EAEpC,IAAI,IAAY;AAYhB,SAXA,EAAe,KAAK,EACf,EAAY;GAAE,IAAI;GAAS,SAAS,KAAW;GAAW,EAAE,EAAS,CACvE,MAAM,MAAW;AACZ,QAEJ,EADiB,EAAO,KAAK,MAAU,EAAM,GAAG,CAAC,OAAO,QAAQ,CACxC;IACxB,CACD,YAAY;AACX,GAAK,KAAW,EAAe,EAAE,CAAC;IAClC,QAES;AACX,OAAY;;IAEb;EAAC;EAAS;EAAM;EAAS;EAAS,CAAC;CAEtC,IAAM,IAAc,EAAO,aAAa,EAClC,IAAiB,EAAe,KAAK,OAAO;EAChD,GAAG;EACH,QAAQ,IAAS,EAAE,OAAO,QAAQ,MAAM,EAAE,aAAa,CAAC,SAAS,EAAY,CAAC,GAAG,EAAE;EACpF,EAAE;AAUH,QACE,kBAAC,OAAD;EAAK,KAAK;EAAc,WAAU;YAAlC,CACE,kBAAC,UAAD;GACE,KAAK;GACL,MAAK;GACL,eAbqB;AACzB,QAAI,CAAC,KAAQ,EAAU,SAAS;KAC9B,IAAM,IAAO,EAAU,QAAQ,uBAAuB;AACtD,OAAO;MAAE,QAAQ,OAAO,cAAc,EAAK,MAAM;MAAG,MAAM,EAAK;MAAM,CAAC;;AAExE,OAAS,MAAS,CAAC,EAAK;;GASpB,WAAU;GACV,OAAO;aALT,CAOE,kBAAC,QAAD;IAAM,WAAU;cAAY,EAAY,EAAM;IAAQ,CAAA,EACtD,kBAAC,GAAD,EAAa,WAAU,wBAAyB,CAAA,CACzC;MAER,KACC,kBAAC,OAAD;GACE,WAAU;GACV,OAAO;IAAE,QAAQ,EAAI;IAAQ,MAAM,EAAI;IAAM;aAF/C;IAIE,kBAAC,SAAD;KACE,cAAW;KACX,MAAK;KACL,OAAO;KACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;KAC1C,aAAY;KACZ,WAAU;KACV,CAAA;IACD,EAAe,KAAK,MACnB,kBAAC,OAAD,EAAA,UACG,EAAM,OAAO,SAAS,KACrB,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAM;KACH,CAAA,EACL,EAAM,OAAO,KAAK,MACjB,kBAAC,UAAD;KAEE,MAAK;KACL,eAAe;AAEb,MADA,EAAS,EAAM,EACf,EAAQ,GAAM;;KAEhB,WAAW,6EACT,MAAU,IACN,+CACA;eAGL;KACM,EAbF,EAaE,CACT,CACD,EAAA,CAAA,EAED,EAzBI,EAAM,IAyBV,CACN;IACD,EAAe,OAAO,MAAM,EAAE,OAAO,WAAW,EAAE,IACjD,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAG,wDAAwD,sBAAsB;KAC9E,CAAA;IAEJ;KAEJ"}
@@ -1,25 +1,26 @@
1
1
  import { getAgentStatus as e } from "./agentStatus.js";
2
- import { AgentStatusBadge as t } from "./AgentStatusBadge.js";
3
- import { useState as n } from "react";
4
- import { useI18n as r } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
- import { Clock as i, Cpu as a, Globe as o, Link as s, MoreVertical as c, Play as l, RefreshCw as u, Server as d, Settings as f, Square as p } from "lucide-react";
6
- import { AnimatePresence as m, motion as h } from "framer-motion";
7
- import { jsx as g, jsxs as _ } from "react/jsx-runtime";
2
+ import { classifyAgentHealth as t } from "../../utils/agentHealth.js";
3
+ import { AgentStatusBadge as n } from "./AgentStatusBadge.js";
4
+ import { useState as r } from "react";
5
+ import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { Clock as a, Cpu as o, Globe as s, Link as c, MoreVertical as l, Play as u, RefreshCw as d, Server as f, Settings as p, Square as m } from "lucide-react";
7
+ import { AnimatePresence as h, motion as g } from "framer-motion";
8
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
8
9
  //#region src/components/agents/AgentCard.tsx
9
- var v = ({ agent: v, onSelect: y, onConfigure: b, onSettings: x, onStart: S, onStop: C, onDisconnect: w, onEditTunnelUrl: T, selected: E = !1, onToggleSelect: D, className: O = "", healthErrorMessage: k }) => {
10
- let { t: A } = r(), j = (e, t) => {
11
- let n = A(e);
10
+ var y = ({ agent: y, onSelect: b, onConfigure: x, onSettings: S, onStart: C, onStop: w, onDisconnect: T, onEditTunnelUrl: E, selected: D = !1, onToggleSelect: O, className: k = "", healthErrorMessage: A }) => {
11
+ let { t: j } = i(), M = (e, t) => {
12
+ let n = j(e);
12
13
  return n === e ? t : n;
13
- }, M = b || x, [N, P] = n(!1), F = e(v), I = (e) => {
14
- if (!e) return j("agentsPage.never", "Never");
14
+ }, N = x || S, [P, F] = r(!1), I = e(y), L = (e) => {
15
+ if (!e) return M("agentsPage.never", "Never");
15
16
  let t = Date.now() - new Date(e).getTime();
16
- return t < 6e4 ? j("agentsPage.justNow", "Just now") : t < 36e5 ? `${Math.floor(t / 6e4)}m ago` : t < 864e5 ? `${Math.floor(t / 36e5)}h ago` : `${Math.floor(t / 864e5)}d ago`;
17
- }, L = {
17
+ return t < 6e4 ? M("agentsPage.justNow", "Just now") : t < 36e5 ? `${Math.floor(t / 6e4)}m ago` : t < 864e5 ? `${Math.floor(t / 36e5)}h ago` : `${Math.floor(t / 864e5)}d ago`;
18
+ }, R = {
18
19
  darwin: "🍎",
19
20
  linux: "🐧",
20
21
  windows: "🪟"
21
- }[v.platform || ""] || "💻";
22
- return /* @__PURE__ */ _(h.div, {
22
+ }[y.platform || ""] || "💻";
23
+ return /* @__PURE__ */ v(g.div, {
23
24
  whileHover: {
24
25
  y: -2,
25
26
  transition: {
@@ -33,74 +34,94 @@ var v = ({ agent: v, onSelect: y, onConfigure: b, onSettings: x, onStart: S, onS
33
34
  }
34
35
  },
35
36
  whileTap: { scale: .98 },
36
- className: `bg-bg-surface border rounded-lg p-4 h-full hover:border-border-strong hover:shadow-md transition-all cursor-pointer ${E ? "border-action-primary-bg ring-1 ring-action-primary-bg/30" : "border-border-default"} ${O}`,
37
- onClick: () => y?.(v),
37
+ className: `bg-bg-surface border rounded-lg p-4 h-full hover:border-border-strong hover:shadow-md transition-all cursor-pointer ${D ? "border-action-primary-bg ring-1 ring-action-primary-bg/30" : "border-border-default"} ${k}`,
38
+ onClick: () => b?.(y),
38
39
  children: [
39
- /* @__PURE__ */ _("div", {
40
+ /* @__PURE__ */ v("div", {
40
41
  className: "flex items-start justify-between gap-2",
41
- children: [/* @__PURE__ */ _("div", {
42
+ children: [/* @__PURE__ */ v("div", {
42
43
  className: "flex items-start gap-2 sm:gap-3 min-w-0 flex-1",
43
44
  children: [
44
- D && /* @__PURE__ */ g("button", {
45
+ O && /* @__PURE__ */ _("button", {
45
46
  type: "button",
46
47
  onClick: (e) => {
47
- e.stopPropagation(), D();
48
+ e.stopPropagation(), O();
48
49
  },
49
- className: `flex-shrink-0 size-5 min-w-[1.25rem] min-h-[1.25rem] rounded border transition-colors mt-0.5 ${E ? "bg-action-primary-bg border-action-primary-bg text-action-primary-text" : "border-border-default hover:border-border-strong bg-bg-surface"} flex items-center justify-center`,
50
- children: E && /* @__PURE__ */ g("svg", {
50
+ className: `flex-shrink-0 size-5 min-w-[1.25rem] min-h-[1.25rem] rounded border transition-colors mt-0.5 ${D ? "bg-action-primary-bg border-action-primary-bg text-action-primary-text" : "border-border-default hover:border-border-strong bg-bg-surface"} flex items-center justify-center`,
51
+ children: D && /* @__PURE__ */ _("svg", {
51
52
  className: "size-3",
52
53
  fill: "none",
53
54
  viewBox: "0 0 24 24",
54
55
  stroke: "currentColor",
55
56
  strokeWidth: 3,
56
- children: /* @__PURE__ */ g("path", {
57
+ children: /* @__PURE__ */ _("path", {
57
58
  strokeLinecap: "round",
58
59
  strokeLinejoin: "round",
59
60
  d: "M5 13l4 4L19 7"
60
61
  })
61
62
  })
62
63
  }),
63
- /* @__PURE__ */ g("div", {
64
+ /* @__PURE__ */ _("div", {
64
65
  className: "flex-shrink-0 size-8 sm:w-10 sm:h-10 rounded-lg bg-bg-sunken flex items-center justify-center",
65
- children: /* @__PURE__ */ g(d, { className: "size-4 sm:w-5 sm:h-5 text-text-secondary" })
66
+ children: /* @__PURE__ */ _(f, { className: "size-4 sm:w-5 sm:h-5 text-text-secondary" })
66
67
  }),
67
- /* @__PURE__ */ _("div", {
68
+ /* @__PURE__ */ v("div", {
68
69
  className: "min-w-0 flex-1",
69
- children: [/* @__PURE__ */ _("div", {
70
- className: "flex items-center gap-1.5 sm:gap-2 min-w-0",
71
- children: [/* @__PURE__ */ g("h3", {
72
- className: "font-semibold text-text-primary truncate min-w-0 max-w-[120px] sm:max-w-none text-sm sm:text-base",
73
- children: v.name
74
- }), /* @__PURE__ */ g("span", {
75
- className: "text-base sm:text-lg flex-shrink-0",
76
- children: L
77
- })]
78
- }), /* @__PURE__ */ g("p", {
79
- className: "text-xs sm:text-sm text-text-secondary truncate",
80
- children: v.hostname || `ID: ${v.id}`
81
- })]
70
+ children: [
71
+ /* @__PURE__ */ v("div", {
72
+ className: "flex items-center gap-1.5 sm:gap-2 min-w-0",
73
+ children: [/* @__PURE__ */ _("h3", {
74
+ className: "font-semibold text-text-primary truncate min-w-0 max-w-[120px] sm:max-w-none text-sm sm:text-base",
75
+ children: y.name
76
+ }), /* @__PURE__ */ _("span", {
77
+ className: "text-base sm:text-lg flex-shrink-0",
78
+ children: R
79
+ })]
80
+ }),
81
+ /* @__PURE__ */ _("p", {
82
+ className: "text-xs sm:text-sm text-text-secondary truncate",
83
+ children: y.hostname || `ID: ${y.id}`
84
+ }),
85
+ (() => {
86
+ let e = t(I, A ?? null);
87
+ return e.phase === "none" ? null : /* @__PURE__ */ v("p", {
88
+ className: `mt-1 flex items-start gap-1 text-xs ${e.phase === "attention" ? "text-status-warning-text" : "text-text-tertiary"}`,
89
+ children: [e.inProgress && /* @__PURE__ */ _(d, {
90
+ className: "size-3 mt-0.5 flex-shrink-0 animate-spin",
91
+ "aria-hidden": "true"
92
+ }), /* @__PURE__ */ v("span", { children: [
93
+ /* @__PURE__ */ v("span", {
94
+ className: "font-medium",
95
+ children: [e.label, "."]
96
+ }),
97
+ " ",
98
+ e.actionHint
99
+ ] })]
100
+ });
101
+ })()
102
+ ]
82
103
  })
83
104
  ]
84
- }), /* @__PURE__ */ _("div", {
105
+ }), /* @__PURE__ */ v("div", {
85
106
  className: "flex items-center gap-1 sm:gap-2 flex-shrink-0",
86
- children: [/* @__PURE__ */ g(t, {
87
- status: F,
88
- reason: k ?? null,
89
- linkTo: `/vibecontrols/agents/${v.id}?tab=connection`,
107
+ children: [/* @__PURE__ */ _(n, {
108
+ status: I,
109
+ reason: A ?? null,
110
+ linkTo: `/vibecontrols/agents/${y.id}?tab=connection`,
90
111
  onClick: (e) => {
91
112
  e.stopPropagation();
92
113
  }
93
- }), (M || S || C) && /* @__PURE__ */ _("div", {
114
+ }), (N || C || w) && /* @__PURE__ */ v("div", {
94
115
  className: "relative",
95
- children: [/* @__PURE__ */ g("button", {
116
+ children: [/* @__PURE__ */ _("button", {
96
117
  type: "button",
97
118
  onClick: (e) => {
98
- e.stopPropagation(), P(!N);
119
+ e.stopPropagation(), F(!P);
99
120
  },
100
121
  className: "p-1 sm:p-1.5 rounded hover:bg-bg-sunken transition-colors flex items-center justify-center",
101
122
  "aria-label": "Agent actions menu",
102
- children: /* @__PURE__ */ g(c, { className: "size-4 text-text-primary opacity-70 hover:opacity-100" })
103
- }), /* @__PURE__ */ g(m, { children: N && /* @__PURE__ */ _(h.div, {
123
+ children: /* @__PURE__ */ _(l, { className: "size-4 text-text-primary opacity-70 hover:opacity-100" })
124
+ }), /* @__PURE__ */ _(h, { children: P && /* @__PURE__ */ v(g.div, {
104
125
  initial: {
105
126
  opacity: 0,
106
127
  scale: .95,
@@ -119,102 +140,102 @@ var v = ({ agent: v, onSelect: y, onConfigure: b, onSettings: x, onStart: S, onS
119
140
  transition: { duration: .15 },
120
141
  className: "absolute right-0 mt-1 w-40 bg-bg-surface border border-border-default rounded-lg shadow-lg z-10",
121
142
  children: [
122
- F === "ACTIVE" && C && /* @__PURE__ */ _(h.button, {
143
+ I === "ACTIVE" && w && /* @__PURE__ */ v(g.button, {
123
144
  whileTap: { scale: .97 },
124
145
  onClick: (e) => {
125
- e.stopPropagation(), C(v), P(!1);
146
+ e.stopPropagation(), w(y), F(!1);
126
147
  },
127
148
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken rounded-t-lg",
128
- children: [/* @__PURE__ */ g(p, { className: "size-4" }), j("agentsPage.stopAgent", "Stop Agent")]
149
+ children: [/* @__PURE__ */ _(m, { className: "size-4" }), M("agentsPage.stopAgent", "Stop Agent")]
129
150
  }),
130
- (F === "STOPPED" || F === "OFFLINE") && S && /* @__PURE__ */ _(h.button, {
151
+ (I === "STOPPED" || I === "OFFLINE") && C && /* @__PURE__ */ v(g.button, {
131
152
  whileTap: { scale: .97 },
132
153
  onClick: (e) => {
133
- e.stopPropagation(), S(v), P(!1);
154
+ e.stopPropagation(), C(y), F(!1);
134
155
  },
135
156
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken rounded-t-lg",
136
- children: [/* @__PURE__ */ g(l, { className: "size-4" }), j("agentsPage.startAgent", "Start Agent")]
157
+ children: [/* @__PURE__ */ _(u, { className: "size-4" }), M("agentsPage.startAgent", "Start Agent")]
137
158
  }),
138
- F === "DEGRADED" && S && /* @__PURE__ */ _(h.button, {
159
+ I === "DEGRADED" && C && /* @__PURE__ */ v(g.button, {
139
160
  whileTap: { scale: .97 },
140
161
  onClick: (e) => {
141
- e.stopPropagation(), S(v), P(!1);
162
+ e.stopPropagation(), C(y), F(!1);
142
163
  },
143
164
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken rounded-t-lg",
144
- title: k ? `Retry lifecycle/start — last error: ${k}` : "Retry lifecycle/start",
145
- children: [/* @__PURE__ */ g(u, { className: "size-4" }), j("agentsPage.reconnectAgent", "Reconnect")]
165
+ title: A ? `Retry lifecycle/start — last error: ${A}` : "Retry lifecycle/start",
166
+ children: [/* @__PURE__ */ _(d, { className: "size-4" }), M("agentsPage.reconnectAgent", "Reconnect")]
146
167
  }),
147
- (F === "ACTIVE" || F === "STOPPED" || F === "OFFLINE" || F === "DEGRADED") && w && /* @__PURE__ */ _(h.button, {
168
+ (I === "ACTIVE" || I === "STOPPED" || I === "OFFLINE" || I === "DEGRADED") && T && /* @__PURE__ */ v(g.button, {
148
169
  whileTap: { scale: .97 },
149
170
  onClick: (e) => {
150
- e.stopPropagation(), w(v), P(!1);
171
+ e.stopPropagation(), T(y), F(!1);
151
172
  },
152
173
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-action-danger-text hover:bg-bg-sunken",
153
- children: [/* @__PURE__ */ g(p, { className: "size-4" }), F === "OFFLINE" ? "Clear Connection" : "Disconnect"]
174
+ children: [/* @__PURE__ */ _(m, { className: "size-4" }), I === "OFFLINE" ? "Clear Connection" : "Disconnect"]
154
175
  }),
155
- T && /* @__PURE__ */ _(h.button, {
176
+ E && /* @__PURE__ */ v(g.button, {
156
177
  whileTap: { scale: .97 },
157
178
  onClick: (e) => {
158
- e.stopPropagation(), T(v), P(!1);
179
+ e.stopPropagation(), E(y), F(!1);
159
180
  },
160
181
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken",
161
- children: [/* @__PURE__ */ g(s, { className: "size-4" }), "Edit Tunnel"]
182
+ children: [/* @__PURE__ */ _(c, { className: "size-4" }), "Edit Tunnel"]
162
183
  }),
163
- M && /* @__PURE__ */ _(h.button, {
184
+ N && /* @__PURE__ */ v(g.button, {
164
185
  whileTap: { scale: .97 },
165
186
  onClick: (e) => {
166
- e.stopPropagation(), M(v), P(!1);
187
+ e.stopPropagation(), N(y), F(!1);
167
188
  },
168
189
  className: "flex items-center gap-2 w-full px-3 py-2 text-sm text-text-primary hover:bg-bg-sunken rounded-b-lg",
169
- children: [/* @__PURE__ */ g(f, { className: "size-4" }), "Settings"]
190
+ children: [/* @__PURE__ */ _(p, { className: "size-4" }), "Settings"]
170
191
  })
171
192
  ]
172
193
  }) })]
173
194
  })]
174
195
  })]
175
196
  }),
176
- /* @__PURE__ */ _("div", {
197
+ /* @__PURE__ */ v("div", {
177
198
  className: "mt-4 grid grid-cols-2 gap-3 text-sm",
178
- children: [/* @__PURE__ */ _("div", {
199
+ children: [/* @__PURE__ */ v("div", {
179
200
  className: "flex items-center gap-2 text-text-secondary",
180
- children: [/* @__PURE__ */ g(i, { className: "size-4" }), /* @__PURE__ */ g("span", { children: I(v.lastHeartbeat) })]
181
- }), v.architecture && /* @__PURE__ */ _("div", {
201
+ children: [/* @__PURE__ */ _(a, { className: "size-4" }), /* @__PURE__ */ _("span", { children: L(y.lastHeartbeat) })]
202
+ }), y.architecture && /* @__PURE__ */ v("div", {
182
203
  className: "flex items-center gap-2 text-text-secondary",
183
- children: [/* @__PURE__ */ g(a, { className: "size-4" }), /* @__PURE__ */ g("span", { children: v.architecture })]
204
+ children: [/* @__PURE__ */ _(o, { className: "size-4" }), /* @__PURE__ */ _("span", { children: y.architecture })]
184
205
  })]
185
206
  }),
186
- v.tunnelUrl && /* @__PURE__ */ _("div", {
207
+ y.tunnelUrl && /* @__PURE__ */ v("div", {
187
208
  className: "mt-3 flex items-center gap-2 text-sm",
188
209
  children: [
189
- /* @__PURE__ */ g(o, { className: "size-4 flex-shrink-0 text-text-secondary" }),
190
- /* @__PURE__ */ g("span", {
210
+ /* @__PURE__ */ _(s, { className: "size-4 flex-shrink-0 text-text-secondary" }),
211
+ /* @__PURE__ */ _("span", {
191
212
  className: "text-text-secondary flex-shrink-0",
192
213
  children: "Tunnel:"
193
214
  }),
194
- /* @__PURE__ */ g("a", {
195
- href: v.tunnelUrl,
215
+ /* @__PURE__ */ _("a", {
216
+ href: y.tunnelUrl,
196
217
  target: "_blank",
197
218
  rel: "noopener noreferrer",
198
219
  onClick: (e) => e.stopPropagation(),
199
220
  className: "text-action-primary-text hover:underline truncate",
200
- children: v.tunnelUrl
221
+ children: y.tunnelUrl
201
222
  })
202
223
  ]
203
224
  }),
204
- v.capabilities && v.capabilities.length > 0 && /* @__PURE__ */ _("div", {
225
+ y.capabilities && y.capabilities.length > 0 && /* @__PURE__ */ v("div", {
205
226
  className: "mt-3 flex flex-wrap gap-1",
206
- children: [v.capabilities.slice(0, 4).map((e) => /* @__PURE__ */ g("span", {
227
+ children: [y.capabilities.slice(0, 4).map((e) => /* @__PURE__ */ _("span", {
207
228
  className: "px-2 py-0.5 text-xs bg-bg-sunken text-text-secondary rounded",
208
229
  children: e
209
- }, e)), v.capabilities.length > 4 && /* @__PURE__ */ _("span", {
230
+ }, e)), y.capabilities.length > 4 && /* @__PURE__ */ v("span", {
210
231
  className: "px-2 py-0.5 text-xs bg-bg-sunken text-text-secondary rounded",
211
- children: ["+", v.capabilities.length - 4]
232
+ children: ["+", y.capabilities.length - 4]
212
233
  })]
213
234
  })
214
235
  ]
215
236
  });
216
237
  };
217
238
  //#endregion
218
- export { v as AgentCard };
239
+ export { y as AgentCard };
219
240
 
220
241
  //# sourceMappingURL=AgentCard.js.map