@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.
- package/dist/VibeControlsRoutes.js +142 -146
- package/dist/VibeControlsRoutes.js.map +1 -1
- package/dist/components/agent-manager/controls/ModelSelector.js +1 -1
- package/dist/components/agent-manager/controls/ModelSelector.js.map +1 -1
- package/dist/components/agents/AgentCard.js +106 -85
- package/dist/components/agents/AgentCard.js.map +1 -1
- package/dist/components/agents/AgentStatusBadge.js +25 -24
- package/dist/components/agents/AgentStatusBadge.js.map +1 -1
- package/dist/components/shared/LinkToVibePanel.js +36 -26
- package/dist/components/shared/LinkToVibePanel.js.map +1 -1
- package/dist/components/shared/PluginGate.js +72 -68
- package/dist/components/shared/PluginGate.js.map +1 -1
- package/dist/components/shared/cardMotion.js +28 -0
- package/dist/components/shared/cardMotion.js.map +1 -0
- package/dist/components/templates/TemplateCard.js +43 -50
- package/dist/components/templates/TemplateCard.js.map +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js +57 -49
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/components/vibe/VibeLinkedEntitiesPanel.js +121 -72
- package/dist/components/vibe/VibeLinkedEntitiesPanel.js.map +1 -1
- package/dist/components/vibes/VibeCard.js +65 -72
- package/dist/components/vibes/VibeCard.js.map +1 -1
- package/dist/generated/wspace-operations.js +964 -886
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.js +10 -10
- package/dist/pages/ActionsPage.js +297 -268
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +11 -11
- package/dist/pages/AnalyticsPage.js +2 -2
- package/dist/pages/AnalyticsPage.js.map +1 -1
- package/dist/pages/TargetsPage.js +16 -16
- package/dist/pages/VibeAuditPage.js +7 -7
- package/dist/pages/VibeDeckPage.js +180 -180
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/ai/AIPage.js +2 -2
- package/dist/pages/ai/AIPage.js.map +1 -1
- package/dist/pages/ai/AgentManagerPage.js +162 -127
- package/dist/pages/ai/AgentManagerPage.js.map +1 -1
- package/dist/utils/agentHealth.js +31 -0
- package/dist/utils/agentHealth.js.map +1 -0
- package/package.json +2 -2
- package/dist/pages/PluginStandalonePage.js +0 -151
- 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":"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"}
|
|
@@ -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-
|
|
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":"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"}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { getAgentStatus as e } from "./agentStatus.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
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
|
|
10
|
-
let { t:
|
|
11
|
-
let n =
|
|
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
|
-
},
|
|
14
|
-
if (!e) return
|
|
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 ?
|
|
17
|
-
},
|
|
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
|
-
}[
|
|
22
|
-
return /* @__PURE__ */
|
|
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 ${
|
|
37
|
-
onClick: () =>
|
|
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__ */
|
|
40
|
+
/* @__PURE__ */ v("div", {
|
|
40
41
|
className: "flex items-start justify-between gap-2",
|
|
41
|
-
children: [/* @__PURE__ */
|
|
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
|
-
|
|
45
|
+
O && /* @__PURE__ */ _("button", {
|
|
45
46
|
type: "button",
|
|
46
47
|
onClick: (e) => {
|
|
47
|
-
e.stopPropagation(),
|
|
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 ${
|
|
50
|
-
children:
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
66
|
+
children: /* @__PURE__ */ _(f, { className: "size-4 sm:w-5 sm:h-5 text-text-secondary" })
|
|
66
67
|
}),
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
+
/* @__PURE__ */ v("div", {
|
|
68
69
|
className: "min-w-0 flex-1",
|
|
69
|
-
children: [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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__ */
|
|
105
|
+
}), /* @__PURE__ */ v("div", {
|
|
85
106
|
className: "flex items-center gap-1 sm:gap-2 flex-shrink-0",
|
|
86
|
-
children: [/* @__PURE__ */
|
|
87
|
-
status:
|
|
88
|
-
reason:
|
|
89
|
-
linkTo: `/vibecontrols/agents/${
|
|
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
|
-
}), (
|
|
114
|
+
}), (N || C || w) && /* @__PURE__ */ v("div", {
|
|
94
115
|
className: "relative",
|
|
95
|
-
children: [/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ _("button", {
|
|
96
117
|
type: "button",
|
|
97
118
|
onClick: (e) => {
|
|
98
|
-
e.stopPropagation(),
|
|
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__ */
|
|
103
|
-
}), /* @__PURE__ */
|
|
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
|
-
|
|
143
|
+
I === "ACTIVE" && w && /* @__PURE__ */ v(g.button, {
|
|
123
144
|
whileTap: { scale: .97 },
|
|
124
145
|
onClick: (e) => {
|
|
125
|
-
e.stopPropagation(),
|
|
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__ */
|
|
149
|
+
children: [/* @__PURE__ */ _(m, { className: "size-4" }), M("agentsPage.stopAgent", "Stop Agent")]
|
|
129
150
|
}),
|
|
130
|
-
(
|
|
151
|
+
(I === "STOPPED" || I === "OFFLINE") && C && /* @__PURE__ */ v(g.button, {
|
|
131
152
|
whileTap: { scale: .97 },
|
|
132
153
|
onClick: (e) => {
|
|
133
|
-
e.stopPropagation(),
|
|
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__ */
|
|
157
|
+
children: [/* @__PURE__ */ _(u, { className: "size-4" }), M("agentsPage.startAgent", "Start Agent")]
|
|
137
158
|
}),
|
|
138
|
-
|
|
159
|
+
I === "DEGRADED" && C && /* @__PURE__ */ v(g.button, {
|
|
139
160
|
whileTap: { scale: .97 },
|
|
140
161
|
onClick: (e) => {
|
|
141
|
-
e.stopPropagation(),
|
|
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:
|
|
145
|
-
children: [/* @__PURE__ */
|
|
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
|
-
(
|
|
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(),
|
|
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__ */
|
|
174
|
+
children: [/* @__PURE__ */ _(m, { className: "size-4" }), I === "OFFLINE" ? "Clear Connection" : "Disconnect"]
|
|
154
175
|
}),
|
|
155
|
-
|
|
176
|
+
E && /* @__PURE__ */ v(g.button, {
|
|
156
177
|
whileTap: { scale: .97 },
|
|
157
178
|
onClick: (e) => {
|
|
158
|
-
e.stopPropagation(),
|
|
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__ */
|
|
182
|
+
children: [/* @__PURE__ */ _(c, { className: "size-4" }), "Edit Tunnel"]
|
|
162
183
|
}),
|
|
163
|
-
|
|
184
|
+
N && /* @__PURE__ */ v(g.button, {
|
|
164
185
|
whileTap: { scale: .97 },
|
|
165
186
|
onClick: (e) => {
|
|
166
|
-
e.stopPropagation(),
|
|
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__ */
|
|
190
|
+
children: [/* @__PURE__ */ _(p, { className: "size-4" }), "Settings"]
|
|
170
191
|
})
|
|
171
192
|
]
|
|
172
193
|
}) })]
|
|
173
194
|
})]
|
|
174
195
|
})]
|
|
175
196
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
197
|
+
/* @__PURE__ */ v("div", {
|
|
177
198
|
className: "mt-4 grid grid-cols-2 gap-3 text-sm",
|
|
178
|
-
children: [/* @__PURE__ */
|
|
199
|
+
children: [/* @__PURE__ */ v("div", {
|
|
179
200
|
className: "flex items-center gap-2 text-text-secondary",
|
|
180
|
-
children: [/* @__PURE__ */
|
|
181
|
-
}),
|
|
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__ */
|
|
204
|
+
children: [/* @__PURE__ */ _(o, { className: "size-4" }), /* @__PURE__ */ _("span", { children: y.architecture })]
|
|
184
205
|
})]
|
|
185
206
|
}),
|
|
186
|
-
|
|
207
|
+
y.tunnelUrl && /* @__PURE__ */ v("div", {
|
|
187
208
|
className: "mt-3 flex items-center gap-2 text-sm",
|
|
188
209
|
children: [
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
-
/* @__PURE__ */
|
|
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__ */
|
|
195
|
-
href:
|
|
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:
|
|
221
|
+
children: y.tunnelUrl
|
|
201
222
|
})
|
|
202
223
|
]
|
|
203
224
|
}),
|
|
204
|
-
|
|
225
|
+
y.capabilities && y.capabilities.length > 0 && /* @__PURE__ */ v("div", {
|
|
205
226
|
className: "mt-3 flex flex-wrap gap-1",
|
|
206
|
-
children: [
|
|
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)),
|
|
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: ["+",
|
|
232
|
+
children: ["+", y.capabilities.length - 4]
|
|
212
233
|
})]
|
|
213
234
|
})
|
|
214
235
|
]
|
|
215
236
|
});
|
|
216
237
|
};
|
|
217
238
|
//#endregion
|
|
218
|
-
export {
|
|
239
|
+
export { y as AgentCard };
|
|
219
240
|
|
|
220
241
|
//# sourceMappingURL=AgentCard.js.map
|