@burdenoff/microfe-vibecontrols 2026.623.1 → 2026.623.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/components/actions/ActionCard.js +2 -2
- package/dist/components/actions/ActionCard.js.map +1 -1
- package/dist/components/actions/ExecutionHistory.js +1 -1
- package/dist/components/actions/ExecutionHistory.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerAdminBar.js +1 -1
- package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerChatPane.js +2 -2
- package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerInputArea.js +4 -4
- package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerLayout.js +1 -1
- package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerMessageItem.js +1 -1
- package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerSidebar.js +5 -5
- package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTab.js +1 -1
- package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTabBar.js +1 -1
- package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
- package/dist/components/agent-manager/BridleConfigPanel.js +23 -23
- package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/PluginInstallModal.js +1 -1
- package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
- package/dist/components/agent-manager/ProfilesPanel.js +5 -5
- package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
- package/dist/components/agent-manager/controls/AutonomySelector.js +1 -1
- package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
- package/dist/components/agent-manager/controls/SdkSelector.js +1 -1
- package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
- package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
- package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionConfigPanel.js +6 -6
- package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionLogsPanel.js +5 -5
- package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionToolsPanel.js +1 -1
- package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js +2 -2
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +1 -1
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
- package/dist/components/agents/AgentCard.js +14 -11
- package/dist/components/agents/AgentCard.js.map +1 -1
- package/dist/components/ai/AIContextsTab.js +1 -1
- package/dist/components/ai/AIContextsTab.js.map +1 -1
- package/dist/components/ai/AIOverviewTab.js +4 -4
- package/dist/components/ai/AIOverviewTab.js.map +1 -1
- package/dist/components/ai/AIPlanPanel.js +4 -4
- package/dist/components/ai/AIPlanPanel.js.map +1 -1
- package/dist/components/ai/AIPlaygroundTab.js +1 -1
- package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
- package/dist/components/ai/AIPromptsTab.js +2 -2
- package/dist/components/ai/AIPromptsTab.js.map +1 -1
- package/dist/components/ai/AIProviderCredentialsCard.js +4 -4
- package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
- package/dist/components/ai/AIQueueTab.js +4 -4
- package/dist/components/ai/AIQueueTab.js.map +1 -1
- package/dist/components/ai/AISessionsTab.js +4 -4
- package/dist/components/ai/AISessionsTab.js.map +1 -1
- package/dist/components/ai/AITasksTab.js +1 -1
- package/dist/components/ai/AITasksTab.js.map +1 -1
- package/dist/components/ai/ClaudeCredentialsCard.js +3 -3
- package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
- package/dist/components/ai/PluginHarnessPicker.js +3 -3
- package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
- package/dist/components/analytics/AnalyticsBreakdownChart.js +8 -8
- package/dist/components/analytics/AnalyticsBreakdownChart.js.map +1 -1
- package/dist/components/analytics/AnalyticsTimeSeriesChart.js +5 -5
- package/dist/components/analytics/AnalyticsTimeSeriesChart.js.map +1 -1
- package/dist/components/audit/AuditDeleteDialog.js +2 -2
- package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
- package/dist/components/audit/AuditExportButton.js +5 -5
- package/dist/components/audit/AuditExportButton.js.map +1 -1
- package/dist/components/audit/AuditLogDetail.js +9 -9
- package/dist/components/audit/AuditLogDetail.js.map +1 -1
- package/dist/components/audit/AuditLogFilters.js +1 -1
- package/dist/components/audit/AuditLogFilters.js.map +1 -1
- package/dist/components/audit/AuditLogStats.js +1 -1
- package/dist/components/audit/AuditLogStats.js.map +1 -1
- package/dist/components/audit/AuditLogTable.js +28 -28
- package/dist/components/audit/AuditLogTable.js.map +1 -1
- package/dist/components/catalog/CatalogCard.js +3 -3
- package/dist/components/catalog/CatalogCard.js.map +1 -1
- package/dist/components/catalog/CatalogForm.js +1 -1
- package/dist/components/catalog/CatalogForm.js.map +1 -1
- package/dist/components/common/ActionAgentTargetNotice.js +6 -6
- package/dist/components/common/ActionAgentTargetNotice.js.map +1 -1
- package/dist/components/common/CommandEditor.js +1 -1
- package/dist/components/common/CommandEditor.js.map +1 -1
- package/dist/components/docs/DocsPageTree.js +1 -1
- package/dist/components/docs/DocsPageTree.js.map +1 -1
- package/dist/components/docs/DocsPreviewPanel.js +1 -1
- package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
- package/dist/components/docs/DocsRevisionHistory.js +4 -4
- package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
- package/dist/components/docs/DocsSettingsPanel.js +7 -7
- package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
- package/dist/components/docs/DocsTabPanel.js +1 -1
- package/dist/components/docs/DocsTabPanel.js.map +1 -1
- package/dist/components/graph/ConnectionPermissionsDialog.js +2 -2
- package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
- package/dist/components/graph/MeshDeployWizard.js +3 -3
- package/dist/components/graph/MeshDeployWizard.js.map +1 -1
- package/dist/components/graph/MeshRequestPanel.js +2 -2
- package/dist/components/graph/MeshRequestPanel.js.map +1 -1
- package/dist/components/idp-components/ComponentCard.js +5 -5
- package/dist/components/idp-components/ComponentCard.js.map +1 -1
- package/dist/components/idp-components/ComponentForm.js +1 -1
- package/dist/components/idp-components/ComponentForm.js.map +1 -1
- package/dist/components/idp-components/DependencyGraphTab.js +7 -7
- package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
- package/dist/components/logs/LogViewer.js +14 -14
- package/dist/components/logs/LogViewer.js.map +1 -1
- package/dist/components/notes/NoteCard.js +1 -1
- package/dist/components/notes/NoteCard.js.map +1 -1
- package/dist/components/notes/NoteEditor.js +2 -2
- package/dist/components/notes/NoteEditor.js.map +1 -1
- package/dist/components/notes/NoteList.js +1 -1
- package/dist/components/notes/NoteList.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +1 -1
- package/dist/components/notes/NotesTabPanel.js.map +1 -1
- package/dist/components/scorecard/ScorecardEmptyState.js +1 -1
- package/dist/components/scorecard/ScorecardEmptyState.js.map +1 -1
- package/dist/components/scorecard/ScorecardPanel.js +3 -3
- package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
- package/dist/components/security/SecurityScanList.js +11 -11
- package/dist/components/security/SecurityScanList.js.map +1 -1
- package/dist/components/sessions/SessionCard.js +26 -19
- package/dist/components/sessions/SessionCard.js.map +1 -1
- package/dist/components/sessions/SessionStatusBadge.js +7 -7
- package/dist/components/sessions/SessionStatusBadge.js.map +1 -1
- package/dist/components/shared/AgentSelector.js +4 -4
- package/dist/components/shared/AgentSelector.js.map +1 -1
- package/dist/components/shared/AgentSetupBanner.js +3 -3
- package/dist/components/shared/AgentSetupBanner.js.map +1 -1
- package/dist/components/shared/Card.js +4 -4
- package/dist/components/shared/Card.js.map +1 -1
- package/dist/components/shared/ErrorState.js +15 -9
- package/dist/components/shared/ErrorState.js.map +1 -1
- package/dist/components/shared/FilterDropdown.js +2 -2
- package/dist/components/shared/FilterDropdown.js.map +1 -1
- package/dist/components/shared/PageSkeleton.js +6 -6
- package/dist/components/shared/PageSkeleton.js.map +1 -1
- package/dist/components/shared/SearchInput.js +1 -1
- package/dist/components/shared/SearchInput.js.map +1 -1
- package/dist/components/shared/StatCard.js +7 -7
- package/dist/components/shared/StatCard.js.map +1 -1
- package/dist/components/templates/PublishTemplateForm.js +2 -2
- package/dist/components/templates/PublishTemplateForm.js.map +1 -1
- package/dist/components/templates/TemplateCard.js +5 -5
- package/dist/components/templates/TemplateCard.js.map +1 -1
- package/dist/components/templates/TemplateWizard.js +2 -2
- package/dist/components/templates/TemplateWizard.js.map +1 -1
- package/dist/components/tunnels/DomainVerificationBadge.js +4 -4
- package/dist/components/tunnels/DomainVerificationBadge.js.map +1 -1
- package/dist/components/tunnels/ProviderBadge.js +1 -1
- package/dist/components/tunnels/ProviderBadge.js.map +1 -1
- package/dist/components/tunnels/TunnelCard.js +16 -16
- package/dist/components/tunnels/TunnelCard.js.map +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/components/tunnels/TunnelPublicAccessPanel.js +1 -1
- package/dist/components/tunnels/TunnelPublicAccessPanel.js.map +1 -1
- package/dist/components/tunnels/TunnelStatusBadge.js +4 -4
- package/dist/components/tunnels/TunnelStatusBadge.js.map +1 -1
- package/dist/components/vibecalendar/LogsDrawer.js +2 -2
- package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
- package/dist/components/vibecalendar/ScheduleTaskModal.js +5 -5
- package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalAgendaView.js +2 -2
- package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalDayView.js +3 -3
- package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalMonthView.js +1 -1
- package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalWeekView.js +4 -4
- package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalendarHeader.js +4 -4
- package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
- package/dist/components/vibecalendar/VibeTaskBlock.js +2 -2
- package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
- package/dist/components/vibecalendar/types.js +6 -6
- package/dist/components/vibecalendar/types.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonForm.js +9 -9
- package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonTile.js +6 -6
- package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckExecutionLog.js +10 -10
- package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckForm.js +8 -8
- package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
- package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +2 -2
- package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -8
- package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
- package/dist/components/vibes/VibeCard.js +22 -18
- package/dist/components/vibes/VibeCard.js.map +1 -1
- package/dist/components/vibes/VibeList.js +16 -12
- package/dist/components/vibes/VibeList.js.map +1 -1
- package/dist/pages/ActionsPage.js +4 -3
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +9 -9
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/dist/pages/AgentsLandingPage.js +4 -4
- package/dist/pages/AgentsLandingPage.js.map +1 -1
- package/dist/pages/AgentsPage.js +14 -14
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/AnalyticsPage.js +8 -8
- package/dist/pages/AnalyticsPage.js.map +1 -1
- package/dist/pages/CatalogDetailPage.js +11 -11
- package/dist/pages/CatalogDetailPage.js.map +1 -1
- package/dist/pages/CatalogPage.js +12 -9
- package/dist/pages/CatalogPage.js.map +1 -1
- package/dist/pages/ComponentDetailPage.js +7 -7
- package/dist/pages/ComponentDetailPage.js.map +1 -1
- package/dist/pages/ComponentsPage.js +12 -9
- package/dist/pages/ComponentsPage.js.map +1 -1
- package/dist/pages/EnvTopologyPage.js +2 -2
- package/dist/pages/EnvTopologyPage.js.map +1 -1
- package/dist/pages/GettingStartedPage.js +12 -12
- package/dist/pages/GettingStartedPage.js.map +1 -1
- package/dist/pages/HealthPage.js +12 -12
- package/dist/pages/HealthPage.js.map +1 -1
- package/dist/pages/LogsPage.js +4 -4
- package/dist/pages/LogsPage.js.map +1 -1
- package/dist/pages/NoteDetailsPage.js +5 -5
- package/dist/pages/NoteDetailsPage.js.map +1 -1
- package/dist/pages/OverviewPage.js +74 -41
- package/dist/pages/OverviewPage.js.map +1 -1
- package/dist/pages/PluginsCatalogPage.js +6 -3
- package/dist/pages/PluginsCatalogPage.js.map +1 -1
- package/dist/pages/ScheduledJobDetailPage.js +7 -7
- package/dist/pages/ScheduledJobDetailPage.js.map +1 -1
- package/dist/pages/SessionDetailsPage.js +21 -21
- package/dist/pages/SessionDetailsPage.js.map +1 -1
- package/dist/pages/SessionsPage.js +20 -20
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/pages/SettingsPage.js +64 -52
- package/dist/pages/SettingsPage.js.map +1 -1
- package/dist/pages/SharedSessionPage.js +21 -21
- package/dist/pages/SharedSessionPage.js.map +1 -1
- package/dist/pages/SharedVibeDeckPage.js +5 -5
- package/dist/pages/SharedVibeDeckPage.js.map +1 -1
- package/dist/pages/TargetDetailsPage.js +56 -65
- package/dist/pages/TargetDetailsPage.js.map +1 -1
- package/dist/pages/TargetsPage.js +4 -4
- package/dist/pages/TargetsPage.js.map +1 -1
- package/dist/pages/TemplateDetailPage.js +10 -10
- package/dist/pages/TemplateDetailPage.js.map +1 -1
- package/dist/pages/TemplatesPage.js +6 -5
- package/dist/pages/TemplatesPage.js.map +1 -1
- package/dist/pages/VibeAuditPage.js +3 -3
- package/dist/pages/VibeAuditPage.js.map +1 -1
- package/dist/pages/VibeCalendarPage.js +3 -3
- package/dist/pages/VibeCalendarPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +3 -3
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +15 -15
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/VibeTaskDetailPage.js +5 -5
- package/dist/pages/VibeTaskDetailPage.js.map +1 -1
- package/dist/pages/VibesPage.js +18 -18
- package/dist/pages/VibesPage.js.map +1 -1
- package/dist/pages/WebhooksPage.js +11 -11
- package/dist/pages/WebhooksPage.js.map +1 -1
- package/dist/pages/ai/AIBookmarksPage.js +1 -1
- package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
- package/dist/pages/ai/AISessionDetailPage.js +6 -6
- package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
- package/dist/pages/tunnels/AuditTab.js +1 -1
- package/dist/pages/tunnels/AuditTab.js.map +1 -1
- package/dist/pages/tunnels/DomainsTab.js +1 -1
- package/dist/pages/tunnels/DomainsTab.js.map +1 -1
- package/dist/pages/tunnels/ProvidersTab.js +1 -1
- package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
- package/dist/pages/tunnels/SessionsTab.js +1 -1
- package/dist/pages/tunnels/SessionsTab.js.map +1 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js +3 -3
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/UsageTab.js +1 -1
- package/dist/pages/tunnels/UsageTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +16 -16
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelOverviewTab.js +1 -1
- package/dist/pages/tunnels/tabs/TunnelOverviewTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelSessionsTab.js +52 -49
- package/dist/pages/tunnels/tabs/TunnelSessionsTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelSettingsTab.js +9 -9
- package/dist/pages/tunnels/tabs/TunnelSettingsTab.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerLayout.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerLayout.tsx"],"sourcesContent":["/**\n * Three-pane layout for the Agent Manager.\n *\n * Left: session sidebar (280px, collapsible)\n * Center: main content area (flex-1)\n * Right: detail panel (320px, collapsible)\n */\n\nimport type { ReactNode } from 'react';\nimport { PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen } from 'lucide-react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerLayoutProps {\n sidebar: ReactNode;\n children: ReactNode;\n detailPanel?: ReactNode;\n}\n\nexport function AgentManagerLayout({ sidebar, children, detailPanel }: AgentManagerLayoutProps) {\n const sidebarOpen = useAgentManagerStore((s) => s.sidebarOpen);\n const detailPanelOpen = useAgentManagerStore((s) => s.detailPanelOpen);\n const toggleSidebar = useAgentManagerStore((s) => s.toggleSidebar);\n const toggleDetailPanel = useAgentManagerStore((s) => s.toggleDetailPanel);\n const isFullscreen = useAgentManagerStore((s) => s.isFullscreen);\n const tr = useTr();\n\n return (\n <div className=\"flex h-full min-h-0 overflow-hidden\">\n {/* Sidebar toggle (visible when sidebar is closed, hidden in fullscreen) */}\n {!sidebarOpen && !isFullscreen && (\n <div className=\"flex-shrink-0 border-r border-border-default bg-bg-surface\">\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"p-2 m-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr('vibecontrols.agentManager.layout.openSidebar', 'Open sidebar')}\n >\n <PanelLeftOpen className=\"size-4\" />\n </button>\n </div>\n )}\n\n {/* Left sidebar — hidden in fullscreen */}\n <AnimatePresence initial={false}>\n {sidebarOpen && !isFullscreen && (\n <>\n {/* Mobile overlay backdrop */}\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"fixed inset-0 bg-bg-overlay z-30 md:hidden\"\n onClick={toggleSidebar}\n />\n <motion.aside\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 280, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className=\"fixed md:relative z-40 md:z-auto inset-y-0 left-0 md:inset-auto flex-shrink-0 border-r border-border-default bg-bg-surface overflow-hidden w-full md:w-[280px]\"\n >\n <div className=\"flex flex-col h-full w-[280px]\">\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border-default\">\n <span className=\"text-xs font-semibold uppercase tracking-wider text-text-secondary\">\n {tr('vibecontrols.agentManager.layout.sessions', 'Sessions')}\n </span>\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr('vibecontrols.agentManager.layout.closeSidebar', 'Close sidebar')}\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden\">{sidebar}</div>\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n\n {/* Center content */}\n <main className=\"flex flex-col flex-1 min-w-0 overflow-hidden bg-bg-
|
|
1
|
+
{"version":3,"file":"AgentManagerLayout.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerLayout.tsx"],"sourcesContent":["/**\n * Three-pane layout for the Agent Manager.\n *\n * Left: session sidebar (280px, collapsible)\n * Center: main content area (flex-1)\n * Right: detail panel (320px, collapsible)\n */\n\nimport type { ReactNode } from 'react';\nimport { PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen } from 'lucide-react';\nimport { motion, AnimatePresence } from 'framer-motion';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerLayoutProps {\n sidebar: ReactNode;\n children: ReactNode;\n detailPanel?: ReactNode;\n}\n\nexport function AgentManagerLayout({ sidebar, children, detailPanel }: AgentManagerLayoutProps) {\n const sidebarOpen = useAgentManagerStore((s) => s.sidebarOpen);\n const detailPanelOpen = useAgentManagerStore((s) => s.detailPanelOpen);\n const toggleSidebar = useAgentManagerStore((s) => s.toggleSidebar);\n const toggleDetailPanel = useAgentManagerStore((s) => s.toggleDetailPanel);\n const isFullscreen = useAgentManagerStore((s) => s.isFullscreen);\n const tr = useTr();\n\n return (\n <div className=\"flex h-full min-h-0 overflow-hidden\">\n {/* Sidebar toggle (visible when sidebar is closed, hidden in fullscreen) */}\n {!sidebarOpen && !isFullscreen && (\n <div className=\"flex-shrink-0 border-r border-border-default bg-bg-surface\">\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"p-2 m-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr('vibecontrols.agentManager.layout.openSidebar', 'Open sidebar')}\n >\n <PanelLeftOpen className=\"size-4\" />\n </button>\n </div>\n )}\n\n {/* Left sidebar — hidden in fullscreen */}\n <AnimatePresence initial={false}>\n {sidebarOpen && !isFullscreen && (\n <>\n {/* Mobile overlay backdrop */}\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"fixed inset-0 bg-bg-overlay z-30 md:hidden\"\n onClick={toggleSidebar}\n />\n <motion.aside\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 280, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className=\"fixed md:relative z-40 md:z-auto inset-y-0 left-0 md:inset-auto flex-shrink-0 border-r border-border-default bg-bg-surface overflow-hidden w-full md:w-[280px]\"\n >\n <div className=\"flex flex-col h-full w-[280px]\">\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border-default\">\n <span className=\"text-xs font-semibold uppercase tracking-wider text-text-secondary\">\n {tr('vibecontrols.agentManager.layout.sessions', 'Sessions')}\n </span>\n <button\n type=\"button\"\n onClick={toggleSidebar}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr('vibecontrols.agentManager.layout.closeSidebar', 'Close sidebar')}\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden\">{sidebar}</div>\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n\n {/* Center content */}\n <main className=\"flex flex-col flex-1 min-w-0 overflow-hidden bg-bg-surface\">{children}</main>\n\n {/* Detail panel toggle (visible when panel is closed, hidden on mobile, hidden in fullscreen) */}\n {!detailPanelOpen && detailPanel && !isFullscreen && (\n <div className=\"hidden md:block flex-shrink-0 border-l border-border-default bg-bg-surface\">\n <button\n type=\"button\"\n onClick={toggleDetailPanel}\n className=\"p-2 m-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr('vibecontrols.agentManager.layout.openDetailPanel', 'Open detail panel')}\n >\n <PanelRightOpen className=\"size-4\" />\n </button>\n </div>\n )}\n\n {/* Right detail panel (hidden on mobile, hidden in fullscreen) */}\n <AnimatePresence initial={false}>\n {detailPanelOpen && detailPanel && !isFullscreen && (\n <motion.aside\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: 320, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className=\"hidden md:block flex-shrink-0 border-l border-border-default bg-bg-surface overflow-hidden\"\n >\n <div className=\"flex flex-col h-full w-[320px]\">\n <div className=\"flex items-center justify-between px-3 py-2 border-b border-border-default\">\n <span className=\"text-xs font-semibold uppercase tracking-wider text-text-secondary\">\n {tr('vibecontrols.agentManager.layout.details', 'Details')}\n </span>\n <button\n type=\"button\"\n onClick={toggleDetailPanel}\n className=\"p-1 rounded hover:bg-bg-elevated transition-colors text-text-secondary hover:text-text-primary\"\n title={tr(\n 'vibecontrols.agentManager.layout.closeDetailPanel',\n 'Close detail panel'\n )}\n >\n <PanelRightClose className=\"size-4\" />\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto overflow-x-hidden\">{detailPanel}</div>\n </div>\n </motion.aside>\n )}\n </AnimatePresence>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ function h(e, t) {
|
|
|
13
13
|
if (!t) return e;
|
|
14
14
|
let n = e.toLowerCase(), r = t.toLowerCase(), i = [], a = 0, o = n.indexOf(r, a);
|
|
15
15
|
for (; o !== -1;) o > a && i.push(e.slice(a, o)), i.push(/* @__PURE__ */ d("mark", {
|
|
16
|
-
className: "bg-status-warning-bg text-status-warning-text rounded-sm px-0.5",
|
|
16
|
+
className: "bg-status-warning-bg-subtle text-status-warning-text rounded-sm px-0.5",
|
|
17
17
|
children: e.slice(o, o + t.length)
|
|
18
18
|
}, o)), a = o + t.length, o = n.indexOf(r, a);
|
|
19
19
|
return a < e.length && i.push(e.slice(a)), i.length > 0 ? /* @__PURE__ */ d(u, { children: i }) : e;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerMessageItem.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerMessageItem.tsx"],"sourcesContent":["/**\n * Single message bubble for the Agent Manager chat.\n *\n * User messages are right-aligned; assistant messages are left-aligned.\n * Uses AssistantMarkdownRenderer for rich content in assistant messages.\n * Supports optional search query highlighting.\n */\n\nimport { useState, type FC, type ReactNode } from 'react';\nimport { Bot, Bookmark, BookmarkCheck, Copy, Check, User } from 'lucide-react';\nimport { AssistantMarkdownRenderer } from '@/components/assistant/AssistantMarkdownRenderer';\nimport { relativeTime } from '@/utils/relativeTime';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\nconst ANSI_ESCAPE_RE = new RegExp(\n `${String.fromCharCode(27)}(?:[@-Z\\\\-_]|\\\\[[0-?]*[ -/]*[@-~])`,\n 'g'\n);\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_ESCAPE_RE, '');\n}\n\n/** Highlight occurrences of `query` within `text`. */\nfunction highlightText(text: string, query: string): ReactNode {\n if (!query) return text;\n\n const lowerText = text.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const parts: ReactNode[] = [];\n let lastIndex = 0;\n let matchIndex = lowerText.indexOf(lowerQuery, lastIndex);\n\n while (matchIndex !== -1) {\n if (matchIndex > lastIndex) {\n parts.push(text.slice(lastIndex, matchIndex));\n }\n parts.push(\n <mark\n key={matchIndex}\n className=\"bg-status-warning-bg text-status-warning-text rounded-sm px-0.5\"\n >\n {text.slice(matchIndex, matchIndex + query.length)}\n </mark>\n );\n lastIndex = matchIndex + query.length;\n matchIndex = lowerText.indexOf(lowerQuery, lastIndex);\n }\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? <>{parts}</> : text;\n}\n\ninterface AgentManagerMessageItemProps {\n message: AgentManagerMessage;\n searchQuery?: string;\n isBookmarked?: boolean;\n onToggleBookmark?: (messageId: string) => void;\n flashMessageId?: string | null;\n}\n\nexport const AgentManagerMessageItem: FC<AgentManagerMessageItemProps> = ({\n message,\n searchQuery = '',\n isBookmarked = false,\n onToggleBookmark,\n flashMessageId,\n}) => {\n const [copied, setCopied] = useState(false);\n const [hovered, setHovered] = useState(false);\n const isUser = message.role === 'user';\n const tr = useTr();\n const displayContent = stripAnsi(message.content);\n const isFlashing = flashMessageId === message.id;\n\n const handleCopy = () => {\n navigator.clipboard.writeText(displayContent);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const handleToggleBookmark = () => {\n if (onToggleBookmark) onToggleBookmark(message.id);\n };\n\n const totalTokens = message.tokens ? message.tokens.input + message.tokens.output : null;\n\n return (\n <div\n data-message-id={message.id}\n className={`flex gap-2.5 scroll-mt-16 transition-shadow duration-300 ${\n isUser ? 'flex-row-reverse' : 'flex-row'\n } ${isFlashing ? 'ring-2 ring-status-warning-bg/60 rounded-lg' : ''}`}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n {/* Avatar */}\n <div\n className={`flex-shrink-0 size-6 rounded-full flex items-center justify-center mt-0.5 ${\n isUser ? 'bg-action-primary-bg' : 'bg-bg-elevated border border-border-default'\n }`}\n >\n {isUser ? (\n <User className=\"size-3.5 text-action-primary-text\" />\n ) : (\n <Bot className=\"size-3.5 text-text-secondary\" />\n )}\n </div>\n\n {/* Message bubble */}\n <div\n className={`relative max-w-[85%] rounded-lg px-3 py-2 ${\n isUser\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-elevated border border-border-subtle'\n }`}\n >\n {/* Content */}\n {isUser ? (\n <p className=\"text-xs whitespace-pre-wrap leading-relaxed break-words\">\n {searchQuery ? highlightText(displayContent, searchQuery) : displayContent}\n </p>\n ) : searchQuery ? (\n <p className=\"text-xs whitespace-pre-wrap leading-relaxed break-words text-text-primary\">\n {highlightText(displayContent, searchQuery)}\n </p>\n ) : (\n <AssistantMarkdownRenderer content={displayContent} />\n )}\n\n {/* Footer: timestamp, tokens, bookmark, copy */}\n <div\n className={`flex items-center gap-2 text-[10px] mt-1 ${\n isUser ? 'text-action-primary-text/60' : 'text-text-muted'\n }`}\n >\n <span>{relativeTime(message.timestamp)}</span>\n\n {totalTokens !== null && !isUser && (\n <span>\n {totalTokens} {tr('vibecontrols.agentManager.messageItem.tokens', 'tokens')}\n </span>\n )}\n\n {message.sdk && (\n <span className=\"px-1 py-0.5 rounded bg-bg-elevated text-text-muted uppercase font-mono text-[9px]\">\n {message.sdk}\n </span>\n )}\n\n {message.model && !isUser && <span>{message.model}</span>}\n\n {/* Bookmark + Copy buttons on hover (or when bookmarked) */}\n {(hovered || isBookmarked) && onToggleBookmark && (\n <button\n type=\"button\"\n onClick={handleToggleBookmark}\n className={`ml-auto p-0.5 rounded transition-colors ${\n isUser ? 'hover:bg-action-primary-bg-hover' : 'hover:bg-bg-sunken'\n }`}\n aria-label={\n isBookmarked\n ? tr('vibecontrols.agentManager.messageItem.removeBookmark', 'Remove bookmark')\n : tr('vibecontrols.agentManager.messageItem.bookmarkMessage', 'Bookmark message')\n }\n title={\n isBookmarked\n ? tr('vibecontrols.agentManager.messageItem.removeBookmark', 'Remove bookmark')\n : tr('vibecontrols.agentManager.messageItem.bookmarkMessage', 'Bookmark message')\n }\n data-testid=\"agent-manager-bookmark-toggle\"\n >\n {isBookmarked ? (\n <BookmarkCheck className=\"size-3 text-status-warning-text\" />\n ) : (\n <Bookmark className=\"size-3\" />\n )}\n </button>\n )}\n\n {hovered && (\n <button\n type=\"button\"\n onClick={handleCopy}\n className={`${onToggleBookmark ? '' : 'ml-auto'} p-0.5 rounded transition-colors ${\n isUser ? 'hover:bg-action-primary-bg-hover' : 'hover:bg-bg-sunken'\n }`}\n aria-label={tr('vibecontrols.agentManager.messageItem.copyMessage', 'Copy message')}\n title={tr('vibecontrols.agentManager.messageItem.copyMessage', 'Copy message')}\n >\n {copied ? (\n <Check className=\"size-3 text-status-success-text\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentManagerMessageItem.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerMessageItem.tsx"],"sourcesContent":["/**\n * Single message bubble for the Agent Manager chat.\n *\n * User messages are right-aligned; assistant messages are left-aligned.\n * Uses AssistantMarkdownRenderer for rich content in assistant messages.\n * Supports optional search query highlighting.\n */\n\nimport { useState, type FC, type ReactNode } from 'react';\nimport { Bot, Bookmark, BookmarkCheck, Copy, Check, User } from 'lucide-react';\nimport { AssistantMarkdownRenderer } from '@/components/assistant/AssistantMarkdownRenderer';\nimport { relativeTime } from '@/utils/relativeTime';\nimport type { AgentManagerMessage } from '@/types/agentManager';\nimport { useTr } from '../../shared/hooks/useTr';\n\nconst ANSI_ESCAPE_RE = new RegExp(\n `${String.fromCharCode(27)}(?:[@-Z\\\\-_]|\\\\[[0-?]*[ -/]*[@-~])`,\n 'g'\n);\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_ESCAPE_RE, '');\n}\n\n/** Highlight occurrences of `query` within `text`. */\nfunction highlightText(text: string, query: string): ReactNode {\n if (!query) return text;\n\n const lowerText = text.toLowerCase();\n const lowerQuery = query.toLowerCase();\n const parts: ReactNode[] = [];\n let lastIndex = 0;\n let matchIndex = lowerText.indexOf(lowerQuery, lastIndex);\n\n while (matchIndex !== -1) {\n if (matchIndex > lastIndex) {\n parts.push(text.slice(lastIndex, matchIndex));\n }\n parts.push(\n <mark\n key={matchIndex}\n className=\"bg-status-warning-bg-subtle text-status-warning-text rounded-sm px-0.5\"\n >\n {text.slice(matchIndex, matchIndex + query.length)}\n </mark>\n );\n lastIndex = matchIndex + query.length;\n matchIndex = lowerText.indexOf(lowerQuery, lastIndex);\n }\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? <>{parts}</> : text;\n}\n\ninterface AgentManagerMessageItemProps {\n message: AgentManagerMessage;\n searchQuery?: string;\n isBookmarked?: boolean;\n onToggleBookmark?: (messageId: string) => void;\n flashMessageId?: string | null;\n}\n\nexport const AgentManagerMessageItem: FC<AgentManagerMessageItemProps> = ({\n message,\n searchQuery = '',\n isBookmarked = false,\n onToggleBookmark,\n flashMessageId,\n}) => {\n const [copied, setCopied] = useState(false);\n const [hovered, setHovered] = useState(false);\n const isUser = message.role === 'user';\n const tr = useTr();\n const displayContent = stripAnsi(message.content);\n const isFlashing = flashMessageId === message.id;\n\n const handleCopy = () => {\n navigator.clipboard.writeText(displayContent);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const handleToggleBookmark = () => {\n if (onToggleBookmark) onToggleBookmark(message.id);\n };\n\n const totalTokens = message.tokens ? message.tokens.input + message.tokens.output : null;\n\n return (\n <div\n data-message-id={message.id}\n className={`flex gap-2.5 scroll-mt-16 transition-shadow duration-300 ${\n isUser ? 'flex-row-reverse' : 'flex-row'\n } ${isFlashing ? 'ring-2 ring-status-warning-bg/60 rounded-lg' : ''}`}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n >\n {/* Avatar */}\n <div\n className={`flex-shrink-0 size-6 rounded-full flex items-center justify-center mt-0.5 ${\n isUser ? 'bg-action-primary-bg' : 'bg-bg-elevated border border-border-default'\n }`}\n >\n {isUser ? (\n <User className=\"size-3.5 text-action-primary-text\" />\n ) : (\n <Bot className=\"size-3.5 text-text-secondary\" />\n )}\n </div>\n\n {/* Message bubble */}\n <div\n className={`relative max-w-[85%] rounded-lg px-3 py-2 ${\n isUser\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-elevated border border-border-subtle'\n }`}\n >\n {/* Content */}\n {isUser ? (\n <p className=\"text-xs whitespace-pre-wrap leading-relaxed break-words\">\n {searchQuery ? highlightText(displayContent, searchQuery) : displayContent}\n </p>\n ) : searchQuery ? (\n <p className=\"text-xs whitespace-pre-wrap leading-relaxed break-words text-text-primary\">\n {highlightText(displayContent, searchQuery)}\n </p>\n ) : (\n <AssistantMarkdownRenderer content={displayContent} />\n )}\n\n {/* Footer: timestamp, tokens, bookmark, copy */}\n <div\n className={`flex items-center gap-2 text-[10px] mt-1 ${\n isUser ? 'text-action-primary-text/60' : 'text-text-muted'\n }`}\n >\n <span>{relativeTime(message.timestamp)}</span>\n\n {totalTokens !== null && !isUser && (\n <span>\n {totalTokens} {tr('vibecontrols.agentManager.messageItem.tokens', 'tokens')}\n </span>\n )}\n\n {message.sdk && (\n <span className=\"px-1 py-0.5 rounded bg-bg-elevated text-text-muted uppercase font-mono text-[9px]\">\n {message.sdk}\n </span>\n )}\n\n {message.model && !isUser && <span>{message.model}</span>}\n\n {/* Bookmark + Copy buttons on hover (or when bookmarked) */}\n {(hovered || isBookmarked) && onToggleBookmark && (\n <button\n type=\"button\"\n onClick={handleToggleBookmark}\n className={`ml-auto p-0.5 rounded transition-colors ${\n isUser ? 'hover:bg-action-primary-bg-hover' : 'hover:bg-bg-sunken'\n }`}\n aria-label={\n isBookmarked\n ? tr('vibecontrols.agentManager.messageItem.removeBookmark', 'Remove bookmark')\n : tr('vibecontrols.agentManager.messageItem.bookmarkMessage', 'Bookmark message')\n }\n title={\n isBookmarked\n ? tr('vibecontrols.agentManager.messageItem.removeBookmark', 'Remove bookmark')\n : tr('vibecontrols.agentManager.messageItem.bookmarkMessage', 'Bookmark message')\n }\n data-testid=\"agent-manager-bookmark-toggle\"\n >\n {isBookmarked ? (\n <BookmarkCheck className=\"size-3 text-status-warning-text\" />\n ) : (\n <Bookmark className=\"size-3\" />\n )}\n </button>\n )}\n\n {hovered && (\n <button\n type=\"button\"\n onClick={handleCopy}\n className={`${onToggleBookmark ? '' : 'ml-auto'} p-0.5 rounded transition-colors ${\n isUser ? 'hover:bg-action-primary-bg-hover' : 'hover:bg-bg-sunken'\n }`}\n aria-label={tr('vibecontrols.agentManager.messageItem.copyMessage', 'Copy message')}\n title={tr('vibecontrols.agentManager.messageItem.copyMessage', 'Copy message')}\n >\n {copied ? (\n <Check className=\"size-3 text-status-success-text\" />\n ) : (\n <Copy className=\"size-3\" />\n )}\n </button>\n )}\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -96,7 +96,7 @@ function v({ agent: v, onDeleteSession: y, onDeleteSelected: b }) {
|
|
|
96
96
|
children: [/* @__PURE__ */ h("button", {
|
|
97
97
|
type: "button",
|
|
98
98
|
onClick: () => z(!R),
|
|
99
|
-
className: "flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-
|
|
99
|
+
className: "flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-secondary hover:bg-bg-elevated text-xs transition-colors",
|
|
100
100
|
children: [
|
|
101
101
|
/* @__PURE__ */ m("span", {
|
|
102
102
|
className: "text-text-tertiary",
|
|
@@ -129,7 +129,7 @@ function v({ agent: v, onDeleteSession: y, onDeleteSelected: b }) {
|
|
|
129
129
|
/* @__PURE__ */ h("button", {
|
|
130
130
|
type: "button",
|
|
131
131
|
onClick: () => V(!B),
|
|
132
|
-
className: "flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-
|
|
132
|
+
className: "flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-secondary hover:bg-bg-elevated text-xs transition-colors",
|
|
133
133
|
children: [
|
|
134
134
|
/* @__PURE__ */ m("span", {
|
|
135
135
|
className: "text-text-tertiary",
|
|
@@ -162,7 +162,7 @@ function v({ agent: v, onDeleteSession: y, onDeleteSelected: b }) {
|
|
|
162
162
|
value: O,
|
|
163
163
|
onChange: (e) => k(e.target.value),
|
|
164
164
|
placeholder: x("vibecontrols.agentManager.sidebar.filterByTags", "Filter by tags..."),
|
|
165
|
-
className: "w-full px-2 py-1 text-xs rounded border border-border-default bg-bg-
|
|
165
|
+
className: "w-full px-2 py-1 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong transition-colors"
|
|
166
166
|
})
|
|
167
167
|
}),
|
|
168
168
|
/* @__PURE__ */ h("div", {
|
|
@@ -173,7 +173,7 @@ function v({ agent: v, onDeleteSession: y, onDeleteSelected: b }) {
|
|
|
173
173
|
type: "date",
|
|
174
174
|
value: A,
|
|
175
175
|
onChange: (e) => j(e.target.value),
|
|
176
|
-
className: "flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-
|
|
176
|
+
className: "flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-surface text-text-primary"
|
|
177
177
|
}),
|
|
178
178
|
/* @__PURE__ */ m("span", {
|
|
179
179
|
className: "text-[10px] text-text-tertiary",
|
|
@@ -184,7 +184,7 @@ function v({ agent: v, onDeleteSession: y, onDeleteSelected: b }) {
|
|
|
184
184
|
type: "date",
|
|
185
185
|
value: M,
|
|
186
186
|
onChange: (e) => N(e.target.value),
|
|
187
|
-
className: "flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-
|
|
187
|
+
className: "flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-surface text-text-primary"
|
|
188
188
|
})
|
|
189
189
|
]
|
|
190
190
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerSidebar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerSidebar.tsx"],"sourcesContent":["/**\n * Session list sidebar for the Agent Manager.\n *\n * Includes a \"New Session\" button, search input, filter dropdown,\n * group-by selector, the session list, and bulk action bar.\n */\n\nimport { useCallback, useState } from 'react';\nimport { Plus, ListFilter, ChevronDown, SlidersHorizontal } from 'lucide-react';\nimport { AnimatePresence } from 'framer-motion';\nimport { SearchInput } from '@/components/shared';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport type { SidebarGroupBy } from '@/types/agentManager';\nimport { AgentManagerSessionList } from './AgentManagerSessionList';\nimport { AgentManagerBulkActions } from './AgentManagerBulkActions';\nimport { NewSessionDialog } from './dialogs/NewSessionDialog';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerSidebarProps {\n agent: AgentRef;\n onDeleteSession: (sessionId: string) => void;\n onDeleteSelected: (sessionIds: string[]) => void;\n}\n\nconst GROUP_BY_OPTIONS = [\n { value: 'date', label: 'Date' },\n { value: 'model', label: 'Model' },\n { value: 'status', label: 'Status' },\n { value: 'sdk', label: 'SDK' },\n { value: 'none', label: 'None' },\n];\n\nconst STATUS_OPTIONS = [\n { value: 'active', label: 'Active' },\n { value: 'idle', label: 'Idle' },\n { value: 'processing', label: 'Processing' },\n { value: 'error', label: 'Error' },\n { value: 'terminated', label: 'Terminated' },\n];\n\nexport function AgentManagerSidebar({\n agent,\n onDeleteSession,\n onDeleteSelected,\n}: AgentManagerSidebarProps) {\n const tr = useTr();\n const sidebarSearchQuery = useAgentManagerStore((s) => s.sidebarSearchQuery);\n const setSidebarSearchQuery = useAgentManagerStore((s) => s.setSidebarSearchQuery);\n const sidebarGroupBy = useAgentManagerStore((s) => s.sidebarGroupBy);\n const setSidebarGroupBy = useAgentManagerStore((s) => s.setSidebarGroupBy);\n const [filterStatus, setFilterStatus] = useState<string | null>(null);\n const [tagFilter, setTagFilter] = useState('');\n const [dateFrom, setDateFrom] = useState('');\n const [dateTo, setDateTo] = useState('');\n const [showNewDialog, setShowNewDialog] = useState(false);\n const [showFilters, setShowFilters] = useState(false);\n const [statusDropdownOpen, setStatusDropdownOpen] = useState(false);\n const [groupDropdownOpen, setGroupDropdownOpen] = useState(false);\n\n const filterTags = tagFilter\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n\n const handleGroupByChange = useCallback(\n (value: string) => {\n setSidebarGroupBy(value as SidebarGroupBy);\n setGroupDropdownOpen(false);\n },\n [setSidebarGroupBy]\n );\n\n const handleStatusFilterChange = useCallback((value: string) => {\n setFilterStatus(value === 'all' ? null : value);\n setStatusDropdownOpen(false);\n }, []);\n\n const statusLabel = filterStatus\n ? (STATUS_OPTIONS.find((o) => o.value === filterStatus)?.label ?? 'All')\n : 'All';\n\n const groupLabel = GROUP_BY_OPTIONS.find((o) => o.value === sidebarGroupBy)?.label ?? 'Date';\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* New session button */}\n <div className=\"px-3 py-2\">\n <button\n type=\"button\"\n onClick={() => setShowNewDialog(true)}\n className=\"flex items-center justify-center gap-1.5 w-full px-3 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('vibecontrols.agentManager.sidebar.newSession', 'New Session')}\n </button>\n </div>\n\n {/* Search + filter toggle */}\n <div className=\"flex items-center gap-1.5 px-3 pb-2\">\n <div className=\"flex-1 min-w-0\">\n <SearchInput\n value={sidebarSearchQuery}\n onChange={setSidebarSearchQuery}\n placeholder={tr(\n 'vibecontrols.agentManager.sidebar.searchSessions',\n 'Search sessions...'\n )}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => setShowFilters((p) => !p)}\n title={\n showFilters\n ? tr('vibecontrols.agentManager.sidebar.hideFilters', 'Hide filters')\n : tr('vibecontrols.agentManager.sidebar.showFilters', 'Show filters')\n }\n className={`flex-shrink-0 p-1.5 rounded transition-colors ${\n showFilters\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-elevated'\n }`}\n >\n <SlidersHorizontal className=\"size-3.5\" />\n </button>\n </div>\n\n {/* Collapsible filters */}\n {showFilters && (\n <>\n {/* Status + Group By row */}\n <div className=\"flex items-center gap-2 px-3 pb-2 text-xs\">\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setStatusDropdownOpen(!statusDropdownOpen)}\n className=\"flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-primary text-text-secondary hover:bg-bg-elevated text-xs transition-colors\"\n >\n <span className=\"text-text-tertiary\">Status:</span>\n <span className=\"font-medium text-text-primary\">{statusLabel}</span>\n <ChevronDown\n className={`size-3 transition-transform ${statusDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n {statusDropdownOpen && (\n <div className=\"absolute z-50 mt-1 w-36 bg-bg-surface border border-border-default rounded-md shadow-lg py-1\">\n <button\n type=\"button\"\n onClick={() => handleStatusFilterChange('all')}\n className=\"block w-full px-3 py-1.5 text-left text-xs text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n All\n </button>\n {STATUS_OPTIONS.map((opt) => (\n <button\n type=\"button\"\n key={opt.value}\n onClick={() => handleStatusFilterChange(opt.value)}\n className={`block w-full px-3 py-1.5 text-left text-xs hover:bg-bg-sunken transition-colors ${\n filterStatus === opt.value\n ? 'text-action-primary-bg font-medium'\n : 'text-text-primary'\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"relative ml-auto flex items-center gap-1\">\n <ListFilter className=\"size-3.5 text-text-secondary flex-shrink-0\" />\n <button\n type=\"button\"\n onClick={() => setGroupDropdownOpen(!groupDropdownOpen)}\n className=\"flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-primary text-text-secondary hover:bg-bg-elevated text-xs transition-colors\"\n >\n <span className=\"text-text-tertiary\">Group:</span>\n <span className=\"font-medium text-text-primary\">{groupLabel}</span>\n <ChevronDown\n className={`size-3 transition-transform ${groupDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n {groupDropdownOpen && (\n <div className=\"absolute right-0 z-50 mt-1 top-full w-32 bg-bg-surface border border-border-default rounded-md shadow-lg py-1\">\n {GROUP_BY_OPTIONS.map((opt) => (\n <button\n type=\"button\"\n key={opt.value}\n onClick={() => handleGroupByChange(opt.value)}\n className={`block w-full px-3 py-1.5 text-left text-xs hover:bg-bg-sunken transition-colors ${\n sidebarGroupBy === opt.value\n ? 'text-action-primary-bg font-medium'\n : 'text-text-primary'\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Tag filter */}\n <div className=\"px-3 pb-2\">\n <input\n aria-label=\"control\"\n type=\"text\"\n value={tagFilter}\n onChange={(e) => setTagFilter(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.sidebar.filterByTags',\n 'Filter by tags...'\n )}\n className=\"w-full px-2 py-1 text-xs rounded border border-border-default bg-bg-primary text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong transition-colors\"\n />\n </div>\n\n {/* Date range filter */}\n <div className=\"flex gap-1 items-center px-3 pb-2\">\n <input\n aria-label=\"control\"\n type=\"date\"\n value={dateFrom}\n onChange={(e) => setDateFrom(e.target.value)}\n className=\"flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-primary text-text-primary\"\n />\n <span className=\"text-[10px] text-text-tertiary\">to</span>\n <input\n aria-label=\"control\"\n type=\"date\"\n value={dateTo}\n onChange={(e) => setDateTo(e.target.value)}\n className=\"flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-primary text-text-primary\"\n />\n </div>\n </>\n )}\n\n {/* Session list */}\n <div className=\"flex-1 overflow-y-auto\">\n <AgentManagerSessionList\n agent={agent}\n onDeleteSession={onDeleteSession}\n filterTags={filterTags}\n dateFrom={dateFrom}\n dateTo={dateTo}\n />\n </div>\n\n {/* Bulk actions */}\n <AnimatePresence>\n <AgentManagerBulkActions onDeleteSelected={onDeleteSelected} />\n </AnimatePresence>\n\n {/* New session dialog */}\n <NewSessionDialog\n agent={agent}\n isOpen={showNewDialog}\n onClose={() => setShowNewDialog(false)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentManagerSidebar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerSidebar.tsx"],"sourcesContent":["/**\n * Session list sidebar for the Agent Manager.\n *\n * Includes a \"New Session\" button, search input, filter dropdown,\n * group-by selector, the session list, and bulk action bar.\n */\n\nimport { useCallback, useState } from 'react';\nimport { Plus, ListFilter, ChevronDown, SlidersHorizontal } from 'lucide-react';\nimport { AnimatePresence } from 'framer-motion';\nimport { SearchInput } from '@/components/shared';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport type { SidebarGroupBy } from '@/types/agentManager';\nimport { AgentManagerSessionList } from './AgentManagerSessionList';\nimport { AgentManagerBulkActions } from './AgentManagerBulkActions';\nimport { NewSessionDialog } from './dialogs/NewSessionDialog';\nimport { useTr } from '../../shared/hooks/useTr';\nimport type { AgentRef } from '@/services/aiApi';\n\ninterface AgentManagerSidebarProps {\n agent: AgentRef;\n onDeleteSession: (sessionId: string) => void;\n onDeleteSelected: (sessionIds: string[]) => void;\n}\n\nconst GROUP_BY_OPTIONS = [\n { value: 'date', label: 'Date' },\n { value: 'model', label: 'Model' },\n { value: 'status', label: 'Status' },\n { value: 'sdk', label: 'SDK' },\n { value: 'none', label: 'None' },\n];\n\nconst STATUS_OPTIONS = [\n { value: 'active', label: 'Active' },\n { value: 'idle', label: 'Idle' },\n { value: 'processing', label: 'Processing' },\n { value: 'error', label: 'Error' },\n { value: 'terminated', label: 'Terminated' },\n];\n\nexport function AgentManagerSidebar({\n agent,\n onDeleteSession,\n onDeleteSelected,\n}: AgentManagerSidebarProps) {\n const tr = useTr();\n const sidebarSearchQuery = useAgentManagerStore((s) => s.sidebarSearchQuery);\n const setSidebarSearchQuery = useAgentManagerStore((s) => s.setSidebarSearchQuery);\n const sidebarGroupBy = useAgentManagerStore((s) => s.sidebarGroupBy);\n const setSidebarGroupBy = useAgentManagerStore((s) => s.setSidebarGroupBy);\n const [filterStatus, setFilterStatus] = useState<string | null>(null);\n const [tagFilter, setTagFilter] = useState('');\n const [dateFrom, setDateFrom] = useState('');\n const [dateTo, setDateTo] = useState('');\n const [showNewDialog, setShowNewDialog] = useState(false);\n const [showFilters, setShowFilters] = useState(false);\n const [statusDropdownOpen, setStatusDropdownOpen] = useState(false);\n const [groupDropdownOpen, setGroupDropdownOpen] = useState(false);\n\n const filterTags = tagFilter\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n\n const handleGroupByChange = useCallback(\n (value: string) => {\n setSidebarGroupBy(value as SidebarGroupBy);\n setGroupDropdownOpen(false);\n },\n [setSidebarGroupBy]\n );\n\n const handleStatusFilterChange = useCallback((value: string) => {\n setFilterStatus(value === 'all' ? null : value);\n setStatusDropdownOpen(false);\n }, []);\n\n const statusLabel = filterStatus\n ? (STATUS_OPTIONS.find((o) => o.value === filterStatus)?.label ?? 'All')\n : 'All';\n\n const groupLabel = GROUP_BY_OPTIONS.find((o) => o.value === sidebarGroupBy)?.label ?? 'Date';\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* New session button */}\n <div className=\"px-3 py-2\">\n <button\n type=\"button\"\n onClick={() => setShowNewDialog(true)}\n className=\"flex items-center justify-center gap-1.5 w-full px-3 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('vibecontrols.agentManager.sidebar.newSession', 'New Session')}\n </button>\n </div>\n\n {/* Search + filter toggle */}\n <div className=\"flex items-center gap-1.5 px-3 pb-2\">\n <div className=\"flex-1 min-w-0\">\n <SearchInput\n value={sidebarSearchQuery}\n onChange={setSidebarSearchQuery}\n placeholder={tr(\n 'vibecontrols.agentManager.sidebar.searchSessions',\n 'Search sessions...'\n )}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => setShowFilters((p) => !p)}\n title={\n showFilters\n ? tr('vibecontrols.agentManager.sidebar.hideFilters', 'Hide filters')\n : tr('vibecontrols.agentManager.sidebar.showFilters', 'Show filters')\n }\n className={`flex-shrink-0 p-1.5 rounded transition-colors ${\n showFilters\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-elevated'\n }`}\n >\n <SlidersHorizontal className=\"size-3.5\" />\n </button>\n </div>\n\n {/* Collapsible filters */}\n {showFilters && (\n <>\n {/* Status + Group By row */}\n <div className=\"flex items-center gap-2 px-3 pb-2 text-xs\">\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setStatusDropdownOpen(!statusDropdownOpen)}\n className=\"flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-secondary hover:bg-bg-elevated text-xs transition-colors\"\n >\n <span className=\"text-text-tertiary\">Status:</span>\n <span className=\"font-medium text-text-primary\">{statusLabel}</span>\n <ChevronDown\n className={`size-3 transition-transform ${statusDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n {statusDropdownOpen && (\n <div className=\"absolute z-50 mt-1 w-36 bg-bg-surface border border-border-default rounded-md shadow-lg py-1\">\n <button\n type=\"button\"\n onClick={() => handleStatusFilterChange('all')}\n className=\"block w-full px-3 py-1.5 text-left text-xs text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n All\n </button>\n {STATUS_OPTIONS.map((opt) => (\n <button\n type=\"button\"\n key={opt.value}\n onClick={() => handleStatusFilterChange(opt.value)}\n className={`block w-full px-3 py-1.5 text-left text-xs hover:bg-bg-sunken transition-colors ${\n filterStatus === opt.value\n ? 'text-action-primary-bg font-medium'\n : 'text-text-primary'\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n\n <div className=\"relative ml-auto flex items-center gap-1\">\n <ListFilter className=\"size-3.5 text-text-secondary flex-shrink-0\" />\n <button\n type=\"button\"\n onClick={() => setGroupDropdownOpen(!groupDropdownOpen)}\n className=\"flex items-center gap-1 px-2 py-1 rounded border border-border-default bg-bg-surface text-text-secondary hover:bg-bg-elevated text-xs transition-colors\"\n >\n <span className=\"text-text-tertiary\">Group:</span>\n <span className=\"font-medium text-text-primary\">{groupLabel}</span>\n <ChevronDown\n className={`size-3 transition-transform ${groupDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n {groupDropdownOpen && (\n <div className=\"absolute right-0 z-50 mt-1 top-full w-32 bg-bg-surface border border-border-default rounded-md shadow-lg py-1\">\n {GROUP_BY_OPTIONS.map((opt) => (\n <button\n type=\"button\"\n key={opt.value}\n onClick={() => handleGroupByChange(opt.value)}\n className={`block w-full px-3 py-1.5 text-left text-xs hover:bg-bg-sunken transition-colors ${\n sidebarGroupBy === opt.value\n ? 'text-action-primary-bg font-medium'\n : 'text-text-primary'\n }`}\n >\n {opt.label}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Tag filter */}\n <div className=\"px-3 pb-2\">\n <input\n aria-label=\"control\"\n type=\"text\"\n value={tagFilter}\n onChange={(e) => setTagFilter(e.target.value)}\n placeholder={tr(\n 'vibecontrols.agentManager.sidebar.filterByTags',\n 'Filter by tags...'\n )}\n className=\"w-full px-2 py-1 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong transition-colors\"\n />\n </div>\n\n {/* Date range filter */}\n <div className=\"flex gap-1 items-center px-3 pb-2\">\n <input\n aria-label=\"control\"\n type=\"date\"\n value={dateFrom}\n onChange={(e) => setDateFrom(e.target.value)}\n className=\"flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-surface text-text-primary\"\n />\n <span className=\"text-[10px] text-text-tertiary\">to</span>\n <input\n aria-label=\"control\"\n type=\"date\"\n value={dateTo}\n onChange={(e) => setDateTo(e.target.value)}\n className=\"flex-1 px-1.5 py-1 text-[11px] rounded border border-border-default bg-bg-surface text-text-primary\"\n />\n </div>\n </>\n )}\n\n {/* Session list */}\n <div className=\"flex-1 overflow-y-auto\">\n <AgentManagerSessionList\n agent={agent}\n onDeleteSession={onDeleteSession}\n filterTags={filterTags}\n dateFrom={dateFrom}\n dateTo={dateTo}\n />\n </div>\n\n {/* Bulk actions */}\n <AnimatePresence>\n <AgentManagerBulkActions onDeleteSelected={onDeleteSelected} />\n </AnimatePresence>\n\n {/* New session dialog */}\n <NewSessionDialog\n agent={agent}\n isOpen={showNewDialog}\n onClose={() => setShowNewDialog(false)}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -21,7 +21,7 @@ var o = ({ sessionId: o, name: s, isActive: c, isPinned: l, isProcessing: u, onA
|
|
|
21
21
|
className: `
|
|
22
22
|
group relative flex items-center gap-1.5 pl-3 pr-6 py-1.5 text-xs font-medium
|
|
23
23
|
whitespace-nowrap select-none w-[160px] border-b-2 border-r transition-colors
|
|
24
|
-
${c ? "bg-bg-surface text-text-primary border-b-action-primary-bg border-r-border-default" : "bg-bg-
|
|
24
|
+
${c ? "bg-bg-surface text-text-primary border-b-action-primary-bg border-r-border-default" : "bg-bg-surface text-text-secondary border-b-transparent border-r-border-subtle hover:text-text-primary hover:bg-bg-elevated"}
|
|
25
25
|
`,
|
|
26
26
|
children: [
|
|
27
27
|
u && /* @__PURE__ */ i("span", { className: "flex-shrink-0 size-2 rounded-full bg-status-info-text animate-pulse" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerTab.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerTab.tsx"],"sourcesContent":["/**\n * Individual tab component for the Agent Manager tab bar.\n *\n * Visual states: active (highlighted bg), inactive, pinned (pin icon),\n * processing (animated dot). Close button hidden on pinned tabs unless hovered.\n */\n\nimport { useState, type FC, type MouseEvent } from 'react';\nimport { Pin, X } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerTabProps {\n sessionId: string;\n name: string;\n isActive: boolean;\n isPinned: boolean;\n isProcessing: boolean;\n onActivate: () => void;\n onClose: () => void;\n onRename?: (sessionId: string) => void;\n}\n\nexport const AgentManagerTab: FC<AgentManagerTabProps> = ({\n sessionId,\n name,\n isActive,\n isPinned,\n isProcessing,\n onActivate,\n onClose,\n onRename,\n}) => {\n const [hovered, setHovered] = useState(false);\n const tr = useTr();\n\n const truncatedName = name.length > 20 ? `${name.slice(0, 20)}...` : name;\n\n const handleClose = (e: MouseEvent) => {\n e.stopPropagation();\n onClose();\n };\n\n const handleAuxClick = (e: MouseEvent) => {\n // Middle-click to close\n if (e.button === 1) {\n e.preventDefault();\n onClose();\n }\n };\n\n return (\n <button\n type=\"button\"\n data-session-id={sessionId}\n title={name}\n onClick={onActivate}\n onDoubleClick={() => onRename?.(sessionId)}\n onAuxClick={handleAuxClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n className={`\n group relative flex items-center gap-1.5 pl-3 pr-6 py-1.5 text-xs font-medium\n whitespace-nowrap select-none w-[160px] border-b-2 border-r transition-colors\n ${\n isActive\n ? 'bg-bg-surface text-text-primary border-b-action-primary-bg border-r-border-default'\n : 'bg-bg-
|
|
1
|
+
{"version":3,"file":"AgentManagerTab.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerTab.tsx"],"sourcesContent":["/**\n * Individual tab component for the Agent Manager tab bar.\n *\n * Visual states: active (highlighted bg), inactive, pinned (pin icon),\n * processing (animated dot). Close button hidden on pinned tabs unless hovered.\n */\n\nimport { useState, type FC, type MouseEvent } from 'react';\nimport { Pin, X } from 'lucide-react';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerTabProps {\n sessionId: string;\n name: string;\n isActive: boolean;\n isPinned: boolean;\n isProcessing: boolean;\n onActivate: () => void;\n onClose: () => void;\n onRename?: (sessionId: string) => void;\n}\n\nexport const AgentManagerTab: FC<AgentManagerTabProps> = ({\n sessionId,\n name,\n isActive,\n isPinned,\n isProcessing,\n onActivate,\n onClose,\n onRename,\n}) => {\n const [hovered, setHovered] = useState(false);\n const tr = useTr();\n\n const truncatedName = name.length > 20 ? `${name.slice(0, 20)}...` : name;\n\n const handleClose = (e: MouseEvent) => {\n e.stopPropagation();\n onClose();\n };\n\n const handleAuxClick = (e: MouseEvent) => {\n // Middle-click to close\n if (e.button === 1) {\n e.preventDefault();\n onClose();\n }\n };\n\n return (\n <button\n type=\"button\"\n data-session-id={sessionId}\n title={name}\n onClick={onActivate}\n onDoubleClick={() => onRename?.(sessionId)}\n onAuxClick={handleAuxClick}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n className={`\n group relative flex items-center gap-1.5 pl-3 pr-6 py-1.5 text-xs font-medium\n whitespace-nowrap select-none w-[160px] border-b-2 border-r transition-colors\n ${\n isActive\n ? 'bg-bg-surface text-text-primary border-b-action-primary-bg border-r-border-default'\n : 'bg-bg-surface text-text-secondary border-b-transparent border-r-border-subtle hover:text-text-primary hover:bg-bg-elevated'\n }\n `}\n >\n {/* Processing indicator */}\n {isProcessing && (\n <span className=\"flex-shrink-0 size-2 rounded-full bg-status-info-text animate-pulse\" />\n )}\n\n {/* Pin icon */}\n {isPinned && <Pin className=\"flex-shrink-0 size-3 text-text-muted\" />}\n\n {/* Tab name */}\n <span className=\"truncate\">{truncatedName}</span>\n\n {/* Close button: absolutely positioned at top-right corner */}\n {(!isPinned || hovered) && (\n <span\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n (handleClose as (...a: unknown[]) => unknown)();\n }\n }}\n role=\"button\"\n tabIndex={-1}\n onClick={handleClose}\n className={`\n absolute right-1 top-1/2 -translate-y-1/2 p-0.5 rounded hover:bg-bg-sunken transition-colors\n ${hovered ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'}\n `}\n aria-label={`${tr('vibecontrols.agentManager.tab.close', 'Close')} ${name}`}\n >\n <X className=\"size-3\" />\n </span>\n )}\n </button>\n );\n};\n"],"mappings":";;;;;AAsBA,IAAa,KAA6C,EACxD,cACA,SACA,aACA,aACA,iBACA,eACA,YACA,kBACI;CACJ,IAAM,CAAC,GAAS,KAAc,EAAS,GAAM,EACvC,IAAK,GAAO,EAEZ,IAAgB,EAAK,SAAS,KAAK,GAAG,EAAK,MAAM,GAAG,GAAG,CAAC,OAAO,GAE/D,KAAe,MAAkB;AAErC,EADA,EAAE,iBAAiB,EACnB,GAAS;;AAWX,QACE,kBAAC,UAAD;EACE,MAAK;EACL,mBAAiB;EACjB,OAAO;EACP,SAAS;EACT,qBAAqB,IAAW,EAAU;EAC1C,aAfoB,MAAkB;AAExC,GAAI,EAAE,WAAW,MACf,EAAE,gBAAgB,EAClB,GAAS;;EAYT,oBAAoB,EAAW,GAAK;EACpC,oBAAoB,EAAW,GAAM;EACrC,WAAW;;;UAIP,IACI,uFACA,6HACL;;YAhBL;GAoBG,KACC,kBAAC,QAAD,EAAM,WAAU,uEAAwE,CAAA;GAIzF,KAAY,kBAAC,GAAD,EAAK,WAAU,wCAAyC,CAAA;GAGrE,kBAAC,QAAD;IAAM,WAAU;cAAY;IAAqB,CAAA;IAG/C,CAAC,KAAY,MACb,kBAAC,QAAD;IACE,YAAY,MAAM;AAChB,MAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,gBAAgB,EACjB,GAA8C;;IAGnD,MAAK;IACL,UAAU;IACV,SAAS;IACT,WAAW;;cAEP,IAAU,gBAAgB,oCAAoC;;IAElE,cAAY,GAAG,EAAG,uCAAuC,QAAQ,CAAC,GAAG;cAErE,kBAAC,GAAD,EAAG,WAAU,UAAW,CAAA;IACnB,CAAA;GAEF"}
|
|
@@ -67,7 +67,7 @@ var x = ({ agent: x, onSearch: S, onShowShortcuts: C }) => {
|
|
|
67
67
|
} catch {}
|
|
68
68
|
}, [x, j]), te = R ? w.find((e) => e.sessionId === R) : null;
|
|
69
69
|
return /* @__PURE__ */ b("div", {
|
|
70
|
-
className: "flex items-stretch bg-bg-
|
|
70
|
+
className: "flex items-stretch bg-bg-surface border-b border-border-default w-full",
|
|
71
71
|
children: [
|
|
72
72
|
H && /* @__PURE__ */ y("button", {
|
|
73
73
|
type: "button",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentManagerTabBar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerTabBar.tsx"],"sourcesContent":["/**\n * Browser-style tab bar for the Agent Manager.\n *\n * Horizontal scrolling tabs with a \"+\" button to create new sessions.\n * Supports drag-to-reorder via simple index swap.\n */\n\nimport { useRef, useState, useCallback, useEffect, type FC, type DragEvent } from 'react';\nimport {\n Plus,\n Download,\n ChevronLeft,\n ChevronRight,\n Search,\n HelpCircle,\n Maximize2,\n Minimize2,\n} from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { renameSession, createSession, type AgentRef } from '@/services/aiApi';\nimport { AgentManagerTab } from './AgentManagerTab';\nimport { RenameSessionDialog } from './dialogs/RenameSessionDialog';\nimport { ExportSessionDialog } from './dialogs/ExportSessionDialog';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerTabBarProps {\n agent: AgentRef;\n onSearch?: () => void;\n onShowShortcuts?: () => void;\n}\n\nexport const AgentManagerTabBar: FC<AgentManagerTabBarProps> = ({\n agent,\n onSearch,\n onShowShortcuts,\n}) => {\n const tabs = useAgentManagerStore((s) => s.tabs);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n const sessionStates = useAgentManagerStore((s) => s.sessionStates);\n const setActiveTab = useAgentManagerStore((s) => s.setActiveTab);\n const closeTab = useAgentManagerStore((s) => s.closeTab);\n const reorderTabs = useAgentManagerStore((s) => s.reorderTabs);\n const openSession = useAgentManagerStore((s) => s.openSession);\n const renameTab = useAgentManagerStore((s) => s.renameTab);\n const isFullscreen = useAgentManagerStore((s) => s.isFullscreen);\n const toggleFullscreen = useAgentManagerStore((s) => s.toggleFullscreen);\n const scrollRef = useRef<HTMLDivElement>(null);\n const tr = useTr();\n const [dragIndex, setDragIndex] = useState<number | null>(null);\n const [renamingSessionId, setRenamingSessionId] = useState<string | null>(null);\n const [exportOpen, setExportOpen] = useState(false);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n setShowLeftArrow(el.scrollLeft > 0);\n setShowRightArrow(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);\n }, []);\n\n const scrollTabs = useCallback(\n (direction: 'left' | 'right') => {\n const el = scrollRef.current;\n if (!el) return;\n el.scrollBy({ left: direction === 'left' ? -200 : 200, behavior: 'smooth' });\n // Update arrow visibility after scroll animation\n setTimeout(checkScroll, 300);\n },\n [checkScroll]\n );\n\n useEffect(() => {\n checkScroll();\n }, [tabs.length, checkScroll]);\n\n // Re-check scroll whenever the container is resized\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n return () => ro.disconnect();\n }, [checkScroll]);\n\n const bumpSessionsRefresh = useAgentManagerStore((s) => s.bumpSessionsRefresh);\n const handleNewSession = useCallback(async () => {\n try {\n const session = await createSession(agent, {\n name: `Session ${tabs.length + 1}`,\n agentType: 'claude',\n config: { model: 'default', mode: 'cli', tags: [] },\n });\n openSession(session.id, session.name);\n bumpSessionsRefresh();\n } catch (err) {\n console.error('[AgentManagerTabBar] createSession failed:', err);\n }\n }, [agent, tabs.length, openSession, bumpSessionsRefresh]);\n\n const handleDragStart = (e: DragEvent, index: number) => {\n setDragIndex(index);\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', String(index));\n };\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n };\n\n const handleDrop = (e: DragEvent, dropIndex: number) => {\n e.preventDefault();\n if (dragIndex === null || dragIndex === dropIndex) return;\n\n const reordered = [...tabs];\n const [moved] = reordered.splice(dragIndex, 1);\n reordered.splice(dropIndex, 0, moved);\n\n // Update order values\n const updated = reordered.map((tab, i) => ({ ...tab, order: i }));\n reorderTabs(updated);\n setDragIndex(null);\n };\n\n const handleDragEnd = () => {\n setDragIndex(null);\n };\n\n const handleRename = useCallback(\n async (sessionId: string, newName: string) => {\n renameTab(sessionId, newName);\n try {\n await renameSession(agent, sessionId, newName);\n } catch {\n // Best-effort API sync -- local rename already applied\n }\n },\n [agent, renameTab]\n );\n\n const renamingTab = renamingSessionId\n ? tabs.find((t) => t.sessionId === renamingSessionId)\n : null;\n\n return (\n <div className=\"flex items-stretch bg-bg-primary border-b border-border-default w-full\">\n {showLeftArrow && (\n <button\n type=\"button\"\n onClick={() => scrollTabs('left')}\n className=\"flex-shrink-0 p-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-r border-border-default\"\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeft className=\"size-3.5\" />\n </button>\n )}\n {/* Clip wrapper hides the browser scrollbar while keeping scroll functional */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <div\n ref={scrollRef}\n onScroll={checkScroll}\n className=\"flex items-stretch overflow-x-auto h-full\"\n style={{ scrollbarWidth: 'none' }}\n >\n {tabs.map((tab, index) => {\n const sessionState = sessionStates[tab.sessionId];\n const isProcessing =\n sessionState?.status === 'streaming' || sessionState?.status === 'processing';\n\n return (\n <div\n key={tab.sessionId}\n draggable\n onDragStart={(e) => handleDragStart(e, index)}\n onDragOver={handleDragOver}\n onDrop={(e) => handleDrop(e, index)}\n onDragEnd={handleDragEnd}\n className={`flex-shrink-0${dragIndex === index ? ' opacity-50' : ''}`}\n >\n <AgentManagerTab\n sessionId={tab.sessionId}\n name={tab.name}\n isActive={tab.sessionId === activeTabSessionId}\n isPinned={tab.pinned}\n isProcessing={isProcessing}\n onActivate={() => setActiveTab(tab.sessionId)}\n onClose={() => closeTab(tab.sessionId)}\n onRename={setRenamingSessionId}\n />\n </div>\n );\n })}\n </div>\n </div>\n {showRightArrow && (\n <button\n type=\"button\"\n onClick={() => scrollTabs('right')}\n className=\"flex-shrink-0 p-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRight className=\"size-3.5\" />\n </button>\n )}\n\n {/* Export session button */}\n {activeTabSessionId && (\n <button\n type=\"button\"\n onClick={() => setExportOpen(true)}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.exportSession', 'Export session')}\n aria-label={tr('vibecontrols.agentManager.tabBar.exportSession', 'Export session')}\n >\n <Download className=\"size-4\" />\n </button>\n )}\n\n {/* New session button */}\n <button\n type=\"button\"\n onClick={handleNewSession}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.newSession', 'New session (Ctrl/Cmd+Shift+N)')}\n aria-label={tr('vibecontrols.agentManager.tabBar.createNewSession', 'Create new session')}\n >\n <Plus className=\"size-4\" />\n </button>\n\n {/* Search sessions */}\n {onSearch && (\n <button\n type=\"button\"\n onClick={onSearch}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr(\n 'vibecontrols.agentManager.tabBar.searchSessions',\n 'Search sessions (Ctrl/Cmd+Shift+K)'\n )}\n aria-label={tr('vibecontrols.agentManager.tabBar.searchSessions', 'Search sessions')}\n >\n <Search className=\"size-4\" />\n </button>\n )}\n\n {/* Keyboard shortcuts */}\n {onShowShortcuts && (\n <button\n type=\"button\"\n onClick={onShowShortcuts}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.keyboardShortcuts', 'Keyboard shortcuts')}\n aria-label={tr(\n 'vibecontrols.agentManager.tabBar.keyboardShortcuts',\n 'Keyboard shortcuts'\n )}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n\n {/* Fullscreen toggle */}\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={\n isFullscreen\n ? tr('vibecontrols.agentManager.tabBar.exitFullscreen', 'Exit fullscreen')\n : tr('vibecontrols.agentManager.tabBar.enterFullscreen', 'Enter fullscreen')\n }\n aria-label={\n isFullscreen\n ? tr('vibecontrols.agentManager.tabBar.exitFullscreen', 'Exit fullscreen')\n : tr('vibecontrols.agentManager.tabBar.enterFullscreen', 'Enter fullscreen')\n }\n >\n {isFullscreen ? <Minimize2 className=\"size-4\" /> : <Maximize2 className=\"size-4\" />}\n </button>\n\n {/* Export session dialog */}\n <ExportSessionDialog\n isOpen={exportOpen}\n onClose={() => setExportOpen(false)}\n sessionId={activeTabSessionId ?? ''}\n agent={agent}\n />\n\n {/* Rename session dialog */}\n <RenameSessionDialog\n isOpen={renamingSessionId !== null}\n sessionId={renamingSessionId ?? ''}\n currentName={renamingTab?.name ?? ''}\n onClose={() => setRenamingSessionId(null)}\n onRename={(sessionId, newName) => void handleRename(sessionId, newName)}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AgentManagerTabBar.js","names":[],"sources":["../../../src/components/agent-manager/AgentManagerTabBar.tsx"],"sourcesContent":["/**\n * Browser-style tab bar for the Agent Manager.\n *\n * Horizontal scrolling tabs with a \"+\" button to create new sessions.\n * Supports drag-to-reorder via simple index swap.\n */\n\nimport { useRef, useState, useCallback, useEffect, type FC, type DragEvent } from 'react';\nimport {\n Plus,\n Download,\n ChevronLeft,\n ChevronRight,\n Search,\n HelpCircle,\n Maximize2,\n Minimize2,\n} from 'lucide-react';\nimport { useAgentManagerStore } from '@/store/agentManagerStore';\nimport { renameSession, createSession, type AgentRef } from '@/services/aiApi';\nimport { AgentManagerTab } from './AgentManagerTab';\nimport { RenameSessionDialog } from './dialogs/RenameSessionDialog';\nimport { ExportSessionDialog } from './dialogs/ExportSessionDialog';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface AgentManagerTabBarProps {\n agent: AgentRef;\n onSearch?: () => void;\n onShowShortcuts?: () => void;\n}\n\nexport const AgentManagerTabBar: FC<AgentManagerTabBarProps> = ({\n agent,\n onSearch,\n onShowShortcuts,\n}) => {\n const tabs = useAgentManagerStore((s) => s.tabs);\n const activeTabSessionId = useAgentManagerStore((s) => s.activeTabSessionId);\n const sessionStates = useAgentManagerStore((s) => s.sessionStates);\n const setActiveTab = useAgentManagerStore((s) => s.setActiveTab);\n const closeTab = useAgentManagerStore((s) => s.closeTab);\n const reorderTabs = useAgentManagerStore((s) => s.reorderTabs);\n const openSession = useAgentManagerStore((s) => s.openSession);\n const renameTab = useAgentManagerStore((s) => s.renameTab);\n const isFullscreen = useAgentManagerStore((s) => s.isFullscreen);\n const toggleFullscreen = useAgentManagerStore((s) => s.toggleFullscreen);\n const scrollRef = useRef<HTMLDivElement>(null);\n const tr = useTr();\n const [dragIndex, setDragIndex] = useState<number | null>(null);\n const [renamingSessionId, setRenamingSessionId] = useState<string | null>(null);\n const [exportOpen, setExportOpen] = useState(false);\n const [showLeftArrow, setShowLeftArrow] = useState(false);\n const [showRightArrow, setShowRightArrow] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n setShowLeftArrow(el.scrollLeft > 0);\n setShowRightArrow(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);\n }, []);\n\n const scrollTabs = useCallback(\n (direction: 'left' | 'right') => {\n const el = scrollRef.current;\n if (!el) return;\n el.scrollBy({ left: direction === 'left' ? -200 : 200, behavior: 'smooth' });\n // Update arrow visibility after scroll animation\n setTimeout(checkScroll, 300);\n },\n [checkScroll]\n );\n\n useEffect(() => {\n checkScroll();\n }, [tabs.length, checkScroll]);\n\n // Re-check scroll whenever the container is resized\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n return () => ro.disconnect();\n }, [checkScroll]);\n\n const bumpSessionsRefresh = useAgentManagerStore((s) => s.bumpSessionsRefresh);\n const handleNewSession = useCallback(async () => {\n try {\n const session = await createSession(agent, {\n name: `Session ${tabs.length + 1}`,\n agentType: 'claude',\n config: { model: 'default', mode: 'cli', tags: [] },\n });\n openSession(session.id, session.name);\n bumpSessionsRefresh();\n } catch (err) {\n console.error('[AgentManagerTabBar] createSession failed:', err);\n }\n }, [agent, tabs.length, openSession, bumpSessionsRefresh]);\n\n const handleDragStart = (e: DragEvent, index: number) => {\n setDragIndex(index);\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', String(index));\n };\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect = 'move';\n };\n\n const handleDrop = (e: DragEvent, dropIndex: number) => {\n e.preventDefault();\n if (dragIndex === null || dragIndex === dropIndex) return;\n\n const reordered = [...tabs];\n const [moved] = reordered.splice(dragIndex, 1);\n reordered.splice(dropIndex, 0, moved);\n\n // Update order values\n const updated = reordered.map((tab, i) => ({ ...tab, order: i }));\n reorderTabs(updated);\n setDragIndex(null);\n };\n\n const handleDragEnd = () => {\n setDragIndex(null);\n };\n\n const handleRename = useCallback(\n async (sessionId: string, newName: string) => {\n renameTab(sessionId, newName);\n try {\n await renameSession(agent, sessionId, newName);\n } catch {\n // Best-effort API sync -- local rename already applied\n }\n },\n [agent, renameTab]\n );\n\n const renamingTab = renamingSessionId\n ? tabs.find((t) => t.sessionId === renamingSessionId)\n : null;\n\n return (\n <div className=\"flex items-stretch bg-bg-surface border-b border-border-default w-full\">\n {showLeftArrow && (\n <button\n type=\"button\"\n onClick={() => scrollTabs('left')}\n className=\"flex-shrink-0 p-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-r border-border-default\"\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeft className=\"size-3.5\" />\n </button>\n )}\n {/* Clip wrapper hides the browser scrollbar while keeping scroll functional */}\n <div className=\"flex-1 min-w-0 overflow-hidden\">\n <div\n ref={scrollRef}\n onScroll={checkScroll}\n className=\"flex items-stretch overflow-x-auto h-full\"\n style={{ scrollbarWidth: 'none' }}\n >\n {tabs.map((tab, index) => {\n const sessionState = sessionStates[tab.sessionId];\n const isProcessing =\n sessionState?.status === 'streaming' || sessionState?.status === 'processing';\n\n return (\n <div\n key={tab.sessionId}\n draggable\n onDragStart={(e) => handleDragStart(e, index)}\n onDragOver={handleDragOver}\n onDrop={(e) => handleDrop(e, index)}\n onDragEnd={handleDragEnd}\n className={`flex-shrink-0${dragIndex === index ? ' opacity-50' : ''}`}\n >\n <AgentManagerTab\n sessionId={tab.sessionId}\n name={tab.name}\n isActive={tab.sessionId === activeTabSessionId}\n isPinned={tab.pinned}\n isProcessing={isProcessing}\n onActivate={() => setActiveTab(tab.sessionId)}\n onClose={() => closeTab(tab.sessionId)}\n onRename={setRenamingSessionId}\n />\n </div>\n );\n })}\n </div>\n </div>\n {showRightArrow && (\n <button\n type=\"button\"\n onClick={() => scrollTabs('right')}\n className=\"flex-shrink-0 p-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRight className=\"size-3.5\" />\n </button>\n )}\n\n {/* Export session button */}\n {activeTabSessionId && (\n <button\n type=\"button\"\n onClick={() => setExportOpen(true)}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.exportSession', 'Export session')}\n aria-label={tr('vibecontrols.agentManager.tabBar.exportSession', 'Export session')}\n >\n <Download className=\"size-4\" />\n </button>\n )}\n\n {/* New session button */}\n <button\n type=\"button\"\n onClick={handleNewSession}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.newSession', 'New session (Ctrl/Cmd+Shift+N)')}\n aria-label={tr('vibecontrols.agentManager.tabBar.createNewSession', 'Create new session')}\n >\n <Plus className=\"size-4\" />\n </button>\n\n {/* Search sessions */}\n {onSearch && (\n <button\n type=\"button\"\n onClick={onSearch}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr(\n 'vibecontrols.agentManager.tabBar.searchSessions',\n 'Search sessions (Ctrl/Cmd+Shift+K)'\n )}\n aria-label={tr('vibecontrols.agentManager.tabBar.searchSessions', 'Search sessions')}\n >\n <Search className=\"size-4\" />\n </button>\n )}\n\n {/* Keyboard shortcuts */}\n {onShowShortcuts && (\n <button\n type=\"button\"\n onClick={onShowShortcuts}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={tr('vibecontrols.agentManager.tabBar.keyboardShortcuts', 'Keyboard shortcuts')}\n aria-label={tr(\n 'vibecontrols.agentManager.tabBar.keyboardShortcuts',\n 'Keyboard shortcuts'\n )}\n >\n <HelpCircle className=\"size-4\" />\n </button>\n )}\n\n {/* Fullscreen toggle */}\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n className=\"flex-shrink-0 px-2 py-1.5 text-text-secondary hover:text-text-primary hover:bg-bg-elevated transition-colors border-l border-border-default\"\n title={\n isFullscreen\n ? tr('vibecontrols.agentManager.tabBar.exitFullscreen', 'Exit fullscreen')\n : tr('vibecontrols.agentManager.tabBar.enterFullscreen', 'Enter fullscreen')\n }\n aria-label={\n isFullscreen\n ? tr('vibecontrols.agentManager.tabBar.exitFullscreen', 'Exit fullscreen')\n : tr('vibecontrols.agentManager.tabBar.enterFullscreen', 'Enter fullscreen')\n }\n >\n {isFullscreen ? <Minimize2 className=\"size-4\" /> : <Maximize2 className=\"size-4\" />}\n </button>\n\n {/* Export session dialog */}\n <ExportSessionDialog\n isOpen={exportOpen}\n onClose={() => setExportOpen(false)}\n sessionId={activeTabSessionId ?? ''}\n agent={agent}\n />\n\n {/* Rename session dialog */}\n <RenameSessionDialog\n isOpen={renamingSessionId !== null}\n sessionId={renamingSessionId ?? ''}\n currentName={renamingTab?.name ?? ''}\n onClose={() => setRenamingSessionId(null)}\n onRename={(sessionId, newName) => void handleRename(sessionId, newName)}\n />\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -14,19 +14,19 @@ var h = [
|
|
|
14
14
|
name: "OpenCode",
|
|
15
15
|
id: "opencode",
|
|
16
16
|
config: "~/.config/opencode/",
|
|
17
|
-
color: "bg-status-info-bg text-status-info-text"
|
|
17
|
+
color: "bg-status-info-bg-subtle text-status-info-text"
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
name: "Goose",
|
|
21
21
|
id: "goose",
|
|
22
22
|
config: "~/.config/goose/",
|
|
23
|
-
color: "bg-status-success-bg text-status-success-text"
|
|
23
|
+
color: "bg-status-success-bg-subtle text-status-success-text"
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
name: "Amp",
|
|
27
27
|
id: "amp",
|
|
28
28
|
config: "~/.amp/",
|
|
29
|
-
color: "bg-status-warning-bg text-status-warning-text"
|
|
29
|
+
color: "bg-status-warning-bg-subtle text-status-warning-text"
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
name: "Copilot",
|
|
@@ -38,7 +38,7 @@ var h = [
|
|
|
38
38
|
name: "Crush",
|
|
39
39
|
id: "crush",
|
|
40
40
|
config: "~/.config/crush/",
|
|
41
|
-
color: "bg-status-error-bg text-status-error-text"
|
|
41
|
+
color: "bg-status-error-bg-subtle text-status-error-text"
|
|
42
42
|
}
|
|
43
43
|
];
|
|
44
44
|
function g({ agent: g }) {
|
|
@@ -86,7 +86,7 @@ function g({ agent: g }) {
|
|
|
86
86
|
children: I.map(({ key: e, label: t, icon: n }) => /* @__PURE__ */ m("button", {
|
|
87
87
|
type: "button",
|
|
88
88
|
onClick: () => y(e),
|
|
89
|
-
className: `flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${v === e ? "bg-
|
|
89
|
+
className: `flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium rounded transition-colors ${v === e ? "bg-[var(--color-accent-soft)] text-action-primary-bg" : "text-text-secondary hover:text-text-primary hover:bg-bg-elevated"}`,
|
|
90
90
|
children: [/* @__PURE__ */ p(n, { className: "size-3.5" }), t]
|
|
91
91
|
}, e))
|
|
92
92
|
}),
|
|
@@ -105,7 +105,7 @@ function g({ agent: g }) {
|
|
|
105
105
|
onClick: () => {
|
|
106
106
|
x(e.id), y("profiles");
|
|
107
107
|
},
|
|
108
|
-
className: "px-3 py-2.5 rounded-md border border-border-default bg-bg-
|
|
108
|
+
className: "px-3 py-2.5 rounded-md border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
|
|
109
109
|
children: [/* @__PURE__ */ p("span", {
|
|
110
110
|
className: "text-xs font-medium text-text-primary",
|
|
111
111
|
children: e.name
|
|
@@ -122,7 +122,7 @@ function g({ agent: g }) {
|
|
|
122
122
|
children: [/* @__PURE__ */ m("button", {
|
|
123
123
|
type: "button",
|
|
124
124
|
onClick: () => F("bridle status"),
|
|
125
|
-
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
125
|
+
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
|
|
126
126
|
children: [
|
|
127
127
|
/* @__PURE__ */ p(c, { className: "size-3" }),
|
|
128
128
|
" ",
|
|
@@ -131,7 +131,7 @@ function g({ agent: g }) {
|
|
|
131
131
|
}), /* @__PURE__ */ m("button", {
|
|
132
132
|
type: "button",
|
|
133
133
|
onClick: () => F("bridle init"),
|
|
134
|
-
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
134
|
+
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors flex items-center gap-1.5",
|
|
135
135
|
children: [
|
|
136
136
|
/* @__PURE__ */ p(s, { className: "size-3" }),
|
|
137
137
|
" ",
|
|
@@ -151,7 +151,7 @@ function g({ agent: g }) {
|
|
|
151
151
|
id: "bridleconfigpanel-5",
|
|
152
152
|
value: b,
|
|
153
153
|
onChange: (e) => x(e.target.value),
|
|
154
|
-
className: "w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-
|
|
154
|
+
className: "w-full px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary",
|
|
155
155
|
children: h.map((e) => /* @__PURE__ */ p("option", {
|
|
156
156
|
value: e.id,
|
|
157
157
|
children: e.name
|
|
@@ -162,12 +162,12 @@ function g({ agent: g }) {
|
|
|
162
162
|
children: [/* @__PURE__ */ p("button", {
|
|
163
163
|
type: "button",
|
|
164
164
|
onClick: () => F(`bridle profile list ${b}`),
|
|
165
|
-
className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-
|
|
165
|
+
className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
|
|
166
166
|
children: _("vibecontrols.agentManager.bridle.listProfiles", "List Profiles")
|
|
167
167
|
}), /* @__PURE__ */ p("button", {
|
|
168
168
|
type: "button",
|
|
169
169
|
onClick: () => F(`bridle profile show ${b} ${S || "<name>"}`),
|
|
170
|
-
className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-
|
|
170
|
+
className: "px-3 py-2 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated transition-colors text-left",
|
|
171
171
|
children: _("vibecontrols.agentManager.bridle.showProfile", "Show Profile")
|
|
172
172
|
})]
|
|
173
173
|
}),
|
|
@@ -184,7 +184,7 @@ function g({ agent: g }) {
|
|
|
184
184
|
value: S,
|
|
185
185
|
onChange: (e) => C(e.target.value),
|
|
186
186
|
placeholder: "e.g., work, personal, minimal",
|
|
187
|
-
className: "flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
187
|
+
className: "flex-1 px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
|
|
188
188
|
})
|
|
189
189
|
}),
|
|
190
190
|
/* @__PURE__ */ m("div", {
|
|
@@ -201,21 +201,21 @@ function g({ agent: g }) {
|
|
|
201
201
|
type: "button",
|
|
202
202
|
onClick: () => F(`bridle profile create ${b} ${S} --from-current`),
|
|
203
203
|
disabled: !S,
|
|
204
|
-
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
204
|
+
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
|
|
205
205
|
children: [/* @__PURE__ */ p(a, { className: "size-3" }), " From Current"]
|
|
206
206
|
}),
|
|
207
207
|
/* @__PURE__ */ m("button", {
|
|
208
208
|
type: "button",
|
|
209
209
|
onClick: () => F(`bridle profile switch ${b} ${S}`),
|
|
210
210
|
disabled: !S,
|
|
211
|
-
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
211
|
+
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50 flex items-center gap-1",
|
|
212
212
|
children: [/* @__PURE__ */ p(r, { className: "size-3" }), " Switch"]
|
|
213
213
|
}),
|
|
214
214
|
/* @__PURE__ */ m("button", {
|
|
215
215
|
type: "button",
|
|
216
216
|
onClick: () => F(`bridle profile delete ${b} ${S}`),
|
|
217
217
|
disabled: !S,
|
|
218
|
-
className: "px-3 py-1.5 text-xs rounded border border-status-error-
|
|
218
|
+
className: "px-3 py-1.5 text-xs rounded-button border border-status-error-border text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-50 flex items-center gap-1",
|
|
219
219
|
children: [/* @__PURE__ */ p(d, { className: "size-3" }), " Delete"]
|
|
220
220
|
})
|
|
221
221
|
]
|
|
@@ -242,7 +242,7 @@ function g({ agent: g }) {
|
|
|
242
242
|
value: w,
|
|
243
243
|
onChange: (e) => T(e.target.value),
|
|
244
244
|
placeholder: "owner/repo or full GitHub URL",
|
|
245
|
-
className: "flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-
|
|
245
|
+
className: "flex-1 px-3 py-2 text-sm rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
|
|
246
246
|
}), /* @__PURE__ */ m("button", {
|
|
247
247
|
type: "button",
|
|
248
248
|
onClick: () => F(`bridle install ${w}`),
|
|
@@ -283,7 +283,7 @@ function g({ agent: g }) {
|
|
|
283
283
|
value: E,
|
|
284
284
|
onChange: (e) => D(e.target.value),
|
|
285
285
|
placeholder: "e.g., editor, default_harness, profile_marker",
|
|
286
|
-
className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
286
|
+
className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
|
|
287
287
|
})] }),
|
|
288
288
|
/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
|
|
289
289
|
htmlFor: "bridleconfigpanel-3",
|
|
@@ -296,7 +296,7 @@ function g({ agent: g }) {
|
|
|
296
296
|
value: O,
|
|
297
297
|
onChange: (e) => k(e.target.value),
|
|
298
298
|
placeholder: "value",
|
|
299
|
-
className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
299
|
+
className: "w-full px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface text-text-primary placeholder:text-text-tertiary focus:outline-none focus:border-border-strong"
|
|
300
300
|
})] }),
|
|
301
301
|
/* @__PURE__ */ m("div", {
|
|
302
302
|
className: "flex gap-2",
|
|
@@ -304,7 +304,7 @@ function g({ agent: g }) {
|
|
|
304
304
|
type: "button",
|
|
305
305
|
onClick: () => F(`bridle config get ${E}`),
|
|
306
306
|
disabled: !E,
|
|
307
|
-
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-
|
|
307
|
+
className: "px-3 py-1.5 text-xs rounded border border-border-default bg-bg-surface hover:bg-bg-elevated disabled:opacity-50",
|
|
308
308
|
children: "Get"
|
|
309
309
|
}), /* @__PURE__ */ p("button", {
|
|
310
310
|
type: "button",
|
|
@@ -322,19 +322,19 @@ function g({ agent: g }) {
|
|
|
322
322
|
className: "space-y-1 text-xs text-text-secondary",
|
|
323
323
|
children: [
|
|
324
324
|
/* @__PURE__ */ m("div", {
|
|
325
|
-
className: "flex justify-between px-2 py-1 rounded bg-bg-
|
|
325
|
+
className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
|
|
326
326
|
children: [/* @__PURE__ */ p("code", { children: "profile_marker" }), /* @__PURE__ */ p("span", { children: "Enable debug marker files" })]
|
|
327
327
|
}),
|
|
328
328
|
/* @__PURE__ */ m("div", {
|
|
329
|
-
className: "flex justify-between px-2 py-1 rounded bg-bg-
|
|
329
|
+
className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
|
|
330
330
|
children: [/* @__PURE__ */ p("code", { children: "editor" }), /* @__PURE__ */ p("span", { children: "Default text editor" })]
|
|
331
331
|
}),
|
|
332
332
|
/* @__PURE__ */ m("div", {
|
|
333
|
-
className: "flex justify-between px-2 py-1 rounded bg-bg-
|
|
333
|
+
className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
|
|
334
334
|
children: [/* @__PURE__ */ p("code", { children: "tui.view" }), /* @__PURE__ */ p("span", { children: "Initial TUI view" })]
|
|
335
335
|
}),
|
|
336
336
|
/* @__PURE__ */ m("div", {
|
|
337
|
-
className: "flex justify-between px-2 py-1 rounded bg-bg-
|
|
337
|
+
className: "flex justify-between px-2 py-1 rounded bg-bg-surface",
|
|
338
338
|
children: [/* @__PURE__ */ p("code", { children: "default_harness" }), /* @__PURE__ */ p("span", { children: "Startup harness tab" })]
|
|
339
339
|
})
|
|
340
340
|
]
|