@burdenoff/microfe-vibecontrols 2026.527.11 → 2026.527.13
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 +6 -0
- package/dist/components/actions/ActionCard.js.map +1 -1
- package/dist/components/actions/ActionForm.js +17 -1
- package/dist/components/actions/ActionForm.js.map +1 -1
- package/dist/components/actions/ActionSchedulesList.js +4 -1
- package/dist/components/actions/ActionSchedulesList.js.map +1 -1
- package/dist/components/actions/ExecutionHistory.js +2 -1
- package/dist/components/actions/ExecutionHistory.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerAdminBar.js +8 -3
- package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +9 -9
- package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerBulkActions.js +6 -3
- package/dist/components/agent-manager/AgentManagerBulkActions.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerCenter.js +8 -2
- package/dist/components/agent-manager/AgentManagerCenter.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerChatPane.js +6 -6
- package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerDetailPanel.js +1 -1
- package/dist/components/agent-manager/AgentManagerDetailPanel.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerInputArea.js +7 -5
- package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerLayout.js +8 -4
- package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerMessageItem.js +6 -4
- package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerMessageList.js +3 -3
- package/dist/components/agent-manager/AgentManagerMessageList.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerSessionItem.js +29 -21
- package/dist/components/agent-manager/AgentManagerSessionItem.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerSessionList.js +4 -2
- package/dist/components/agent-manager/AgentManagerSessionList.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerSidebar.js +15 -5
- package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerStreamingIndicator.js +5 -4
- package/dist/components/agent-manager/AgentManagerStreamingIndicator.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTab.js +11 -7
- package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
- package/dist/components/agent-manager/AgentManagerTabBar.js +14 -9
- package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
- package/dist/components/agent-manager/BridleConfigPanel.js +34 -10
- package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/PluginInstallModal.js +3 -3
- package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
- package/dist/components/agent-manager/ProfilesPanel.js +15 -10
- package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
- package/dist/components/agent-manager/controls/AutonomySelector.js +4 -4
- package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
- package/dist/components/agent-manager/controls/ContextLevelToggle.js +3 -3
- package/dist/components/agent-manager/controls/ContextLevelToggle.js.map +1 -1
- package/dist/components/agent-manager/controls/FileAttachButton.js +2 -1
- package/dist/components/agent-manager/controls/FileAttachButton.js.map +1 -1
- package/dist/components/agent-manager/controls/McpServerSelector.js +7 -7
- package/dist/components/agent-manager/controls/McpServerSelector.js.map +1 -1
- package/dist/components/agent-manager/controls/ModelSelector.js +3 -3
- package/dist/components/agent-manager/controls/ModelSelector.js.map +1 -1
- package/dist/components/agent-manager/controls/SdkSelector.js +5 -5
- 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 +7 -2
- package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionLogsPanel.js +1 -1
- package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
- package/dist/components/agent-manager/detail/SessionToolsPanel.js +3 -3
- package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
- package/dist/components/agent-manager/dialogs/ExportSessionDialog.js +4 -2
- package/dist/components/agent-manager/dialogs/ExportSessionDialog.js.map +1 -1
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js +4 -3
- package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +3 -3
- package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
- package/dist/components/agent-manager/dialogs/SessionSearchDialog.js +4 -3
- package/dist/components/agent-manager/dialogs/SessionSearchDialog.js.map +1 -1
- package/dist/components/agents/AgentCard.js +16 -14
- package/dist/components/agents/AgentCard.js.map +1 -1
- package/dist/components/agents/AgentForm.js +29 -24
- package/dist/components/agents/AgentForm.js.map +1 -1
- package/dist/components/agents/AgentList.js +38 -20
- package/dist/components/agents/AgentList.js.map +1 -1
- package/dist/components/agents/AgentStatusBadge.js +1 -1
- package/dist/components/agents/AgentStatusBadge.js.map +1 -1
- package/dist/components/agents/OpenInBrowserEditorButton.js +3 -2
- package/dist/components/agents/OpenInBrowserEditorButton.js.map +1 -1
- package/dist/components/agents/OpenInEditorMenu.js +7 -7
- package/dist/components/agents/OpenInEditorMenu.js.map +1 -1
- package/dist/components/agents/PluginUIPanel.js +28 -14
- package/dist/components/agents/PluginUIPanel.js.map +1 -1
- package/dist/components/agents/backup/AgentBackupTab.js +30 -20
- package/dist/components/agents/backup/AgentBackupTab.js.map +1 -1
- package/dist/components/ai/AIContextsTab.js +26 -7
- package/dist/components/ai/AIContextsTab.js.map +1 -1
- package/dist/components/ai/AIModeToggle.js +2 -1
- package/dist/components/ai/AIModeToggle.js.map +1 -1
- package/dist/components/ai/AIOverviewTab.js +5 -4
- package/dist/components/ai/AIOverviewTab.js.map +1 -1
- package/dist/components/ai/AIPlanPanel.js +21 -15
- package/dist/components/ai/AIPlanPanel.js.map +1 -1
- package/dist/components/ai/AIPlaygroundTab.js +6 -3
- package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
- package/dist/components/ai/AIPromptsTab.js +10 -4
- package/dist/components/ai/AIPromptsTab.js.map +1 -1
- package/dist/components/ai/AIProviderCredentialsCard.js +9 -8
- package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
- package/dist/components/ai/AISessionsTab.js +16 -6
- package/dist/components/ai/AISessionsTab.js.map +1 -1
- package/dist/components/ai/AIStatsTab.js +7 -6
- package/dist/components/ai/AIStatsTab.js.map +1 -1
- package/dist/components/ai/AITasksTab.js +30 -9
- package/dist/components/ai/AITasksTab.js.map +1 -1
- package/dist/components/ai/AITemplatesTab.js +51 -9
- package/dist/components/ai/AITemplatesTab.js.map +1 -1
- package/dist/components/ai/ClaudeCredentialsCard.js +6 -5
- package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
- package/dist/components/ai/PluginHarnessPicker.js +6 -6
- package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
- package/dist/components/aliases/AliasManager.js +32 -13
- package/dist/components/aliases/AliasManager.js.map +1 -1
- package/dist/components/analytics/AnalyticsBreakdownTable.js +9 -9
- package/dist/components/analytics/AnalyticsBreakdownTable.js.map +1 -1
- package/dist/components/analytics/AnalyticsFilterBar.js +4 -3
- package/dist/components/analytics/AnalyticsFilterBar.js.map +1 -1
- package/dist/components/analytics/AnalyticsKpiGrid.js +12 -12
- package/dist/components/analytics/AnalyticsKpiGrid.js.map +1 -1
- package/dist/components/assistant/AIAssistantPanel.js +6 -3
- package/dist/components/assistant/AIAssistantPanel.js.map +1 -1
- package/dist/components/assistant/AssistantChatInput.js +2 -1
- package/dist/components/assistant/AssistantChatInput.js.map +1 -1
- package/dist/components/assistant/AssistantConversationList.js +18 -7
- package/dist/components/assistant/AssistantConversationList.js.map +1 -1
- package/dist/components/assistant/AssistantExportMenu.js +6 -3
- package/dist/components/assistant/AssistantExportMenu.js.map +1 -1
- package/dist/components/assistant/AssistantMarkdownRenderer.js +2 -1
- package/dist/components/assistant/AssistantMarkdownRenderer.js.map +1 -1
- package/dist/components/assistant/AssistantMessageItem.js +2 -2
- package/dist/components/assistant/AssistantMessageItem.js.map +1 -1
- package/dist/components/assistant/AssistantMessageList.js +1 -1
- package/dist/components/assistant/AssistantMessageList.js.map +1 -1
- package/dist/components/assistant/AssistantModeSelector.js +5 -3
- package/dist/components/assistant/AssistantModeSelector.js.map +1 -1
- package/dist/components/assistant/AssistantWelcome.js +4 -3
- package/dist/components/assistant/AssistantWelcome.js.map +1 -1
- package/dist/components/audit/AuditDeleteDialog.js +4 -2
- package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
- package/dist/components/audit/AuditLogDetail.js +4 -1
- package/dist/components/audit/AuditLogDetail.js.map +1 -1
- package/dist/components/audit/AuditLogFilters.js +1 -0
- package/dist/components/audit/AuditLogFilters.js.map +1 -1
- package/dist/components/catalog/CatalogCard.js +10 -9
- package/dist/components/catalog/CatalogCard.js.map +1 -1
- package/dist/components/catalog/CatalogForm.js +8 -1
- package/dist/components/catalog/CatalogForm.js.map +1 -1
- package/dist/components/docs/DocsCompileStatus.js +6 -5
- package/dist/components/docs/DocsCompileStatus.js.map +1 -1
- package/dist/components/docs/DocsEditPanel.js +10 -5
- package/dist/components/docs/DocsEditPanel.js.map +1 -1
- package/dist/components/docs/DocsEmptyState.js +4 -2
- package/dist/components/docs/DocsEmptyState.js.map +1 -1
- package/dist/components/docs/DocsFullScreenViewer.js +15 -8
- package/dist/components/docs/DocsFullScreenViewer.js.map +1 -1
- package/dist/components/docs/DocsPageEditor.js +7 -4
- package/dist/components/docs/DocsPageEditor.js.map +1 -1
- package/dist/components/docs/DocsPageTree.js +13 -4
- package/dist/components/docs/DocsPageTree.js.map +1 -1
- package/dist/components/docs/DocsPreviewPanel.js +18 -8
- package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
- package/dist/components/docs/DocsRevisionHistory.js +8 -7
- package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
- package/dist/components/docs/DocsSettingsPanel.js +43 -10
- package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
- package/dist/components/docs/DocsTabPanel.js +3 -2
- package/dist/components/docs/DocsTabPanel.js.map +1 -1
- package/dist/components/gitops/CIDurationChart.js +1 -1
- package/dist/components/gitops/CIDurationChart.js.map +1 -1
- package/dist/components/gitops/CIFailedRuns.js +3 -3
- package/dist/components/gitops/CIFailedRuns.js.map +1 -1
- package/dist/components/gitops/CIPipelineRunsTable.js +2 -2
- package/dist/components/gitops/CIPipelineRunsTable.js.map +1 -1
- package/dist/components/gitops/CISuccessRateChart.js +1 -1
- package/dist/components/gitops/CISuccessRateChart.js.map +1 -1
- package/dist/components/gitops/CITab.js +1 -1
- package/dist/components/gitops/CITab.js.map +1 -1
- package/dist/components/gitops/CIWorkflowList.js +1 -1
- package/dist/components/gitops/CIWorkflowList.js.map +1 -1
- package/dist/components/gitops/GitOpsSetup.js +5 -3
- package/dist/components/gitops/GitOpsSetup.js.map +1 -1
- package/dist/components/gitops/GitOpsStatusBadge.js +1 -1
- package/dist/components/gitops/GitOpsStatusBadge.js.map +1 -1
- package/dist/components/gitops/RepoActivityCard.js +3 -3
- package/dist/components/gitops/RepoActivityCard.js.map +1 -1
- package/dist/components/gitops/RepoIssuesCard.js +1 -1
- package/dist/components/gitops/RepoIssuesCard.js.map +1 -1
- package/dist/components/gitops/RepoLanguagesCard.js +3 -3
- package/dist/components/gitops/RepoLanguagesCard.js.map +1 -1
- package/dist/components/gitops/RepoOverviewCard.js +8 -8
- package/dist/components/gitops/RepoOverviewCard.js.map +1 -1
- package/dist/components/gitops/RepoPullRequestsCard.js +1 -1
- package/dist/components/gitops/RepoPullRequestsCard.js.map +1 -1
- package/dist/components/gitops/RepoSecurityCard.js +1 -1
- package/dist/components/gitops/RepoSecurityCard.js.map +1 -1
- package/dist/components/gitops/RepoStatsTab.js +1 -1
- package/dist/components/gitops/RepoStatsTab.js.map +1 -1
- package/dist/components/gitops/VibeGitOpsTab.js +11 -6
- package/dist/components/gitops/VibeGitOpsTab.js.map +1 -1
- package/dist/components/graph/AgentNode.js +1 -1
- package/dist/components/graph/AgentNode.js.map +1 -1
- package/dist/components/graph/ConnectionPermissionsDialog.js +10 -0
- package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
- package/dist/components/graph/TargetNode.js +1 -1
- package/dist/components/graph/TargetNode.js.map +1 -1
- package/dist/components/idp-components/ComponentCard.js +7 -6
- package/dist/components/idp-components/ComponentCard.js.map +1 -1
- package/dist/components/idp-components/ComponentForm.js +17 -3
- package/dist/components/idp-components/ComponentForm.js.map +1 -1
- package/dist/components/idp-components/DependencyGraphTab.js +1 -1
- package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
- package/dist/components/logs/LogViewer.js +2 -1
- package/dist/components/logs/LogViewer.js.map +1 -1
- package/dist/components/notes/NoteCard.js +15 -14
- package/dist/components/notes/NoteCard.js.map +1 -1
- package/dist/components/notes/NoteEditor.js +19 -14
- package/dist/components/notes/NoteEditor.js.map +1 -1
- package/dist/components/notes/NoteList.js +23 -15
- package/dist/components/notes/NoteList.js.map +1 -1
- package/dist/components/notes/NotesTabPanel.js +19 -10
- package/dist/components/notes/NotesTabPanel.js.map +1 -1
- package/dist/components/plugins/AddTabDialog.js +6 -6
- package/dist/components/plugins/AddTabDialog.js.map +1 -1
- package/dist/components/scorecard/ScorecardPanel.js +19 -9
- package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
- package/dist/components/security/SecurityEmptyState.js +1 -1
- package/dist/components/security/SecurityEmptyState.js.map +1 -1
- package/dist/components/security/SecurityFindingsTable.js +1 -1
- package/dist/components/security/SecurityFindingsTable.js.map +1 -1
- package/dist/components/security/SecurityHeaderStrip.js +1 -1
- package/dist/components/security/SecurityHeaderStrip.js.map +1 -1
- package/dist/components/security/SecurityProviderDrawer.js +1 -1
- package/dist/components/security/SecurityProviderDrawer.js.map +1 -1
- package/dist/components/sessions/CollaboratorsList.js +15 -12
- package/dist/components/sessions/CollaboratorsList.js.map +1 -1
- package/dist/components/sessions/ControlStatusBar.js +11 -9
- package/dist/components/sessions/ControlStatusBar.js.map +1 -1
- package/dist/components/sessions/SessionCard.js +13 -11
- package/dist/components/sessions/SessionCard.js.map +1 -1
- package/dist/components/sessions/SessionList.js +23 -13
- package/dist/components/sessions/SessionList.js.map +1 -1
- package/dist/components/sessions/SessionShareDialog.js +31 -19
- package/dist/components/sessions/SessionShareDialog.js.map +1 -1
- package/dist/components/sessions/SharedTerminalPanel.js +4 -2
- package/dist/components/sessions/SharedTerminalPanel.js.map +1 -1
- package/dist/components/sessions/TerminalPanel.js +287 -235
- package/dist/components/sessions/TerminalPanel.js.map +1 -1
- package/dist/components/settings/AdvancedSection.js +12 -4
- package/dist/components/settings/AdvancedSection.js.map +1 -1
- package/dist/components/settings/IdePreferencesSection.js +1 -1
- package/dist/components/settings/IdePreferencesSection.js.map +1 -1
- package/dist/components/settings/SettingsForm.js +3 -1
- package/dist/components/settings/SettingsForm.js.map +1 -1
- package/dist/components/shared/AgentSelector.js +6 -6
- package/dist/components/shared/AgentSelector.js.map +1 -1
- package/dist/components/shared/AgentSetupBanner.js +14 -10
- package/dist/components/shared/AgentSetupBanner.js.map +1 -1
- package/dist/components/shared/Card.js.map +1 -1
- package/dist/components/shared/ConfirmDialog.js +4 -3
- package/dist/components/shared/ConfirmDialog.js.map +1 -1
- package/dist/components/shared/EmptyState.js +4 -4
- package/dist/components/shared/EmptyState.js.map +1 -1
- package/dist/components/shared/EntityTagPicker.js +9 -10
- package/dist/components/shared/EntityTagPicker.js.map +1 -1
- package/dist/components/shared/ErrorState.js +7 -6
- package/dist/components/shared/ErrorState.js.map +1 -1
- package/dist/components/shared/FilterDropdown.js +6 -3
- package/dist/components/shared/FilterDropdown.js.map +1 -1
- package/dist/components/shared/GetHelpButton.js +1 -1
- package/dist/components/shared/GetHelpButton.js.map +1 -1
- package/dist/components/shared/InstallTabs.js +2 -2
- package/dist/components/shared/InstallTabs.js.map +1 -1
- package/dist/components/shared/LoadingState.js +3 -3
- package/dist/components/shared/LoadingState.js.map +1 -1
- package/dist/components/shared/NotificationToast.js +3 -3
- package/dist/components/shared/NotificationToast.js.map +1 -1
- package/dist/components/shared/PageSkeleton.js +1 -1
- package/dist/components/shared/PageSkeleton.js.map +1 -1
- package/dist/components/shared/PluginGate.js +12 -8
- package/dist/components/shared/PluginGate.js.map +1 -1
- package/dist/components/shared/RequireAgentReachable.js +4 -4
- package/dist/components/shared/RequireAgentReachable.js.map +1 -1
- package/dist/components/shared/SearchInput.js +3 -2
- package/dist/components/shared/SearchInput.js.map +1 -1
- package/dist/components/shared/SearchableSelect.js +10 -5
- package/dist/components/shared/SearchableSelect.js.map +1 -1
- package/dist/components/shared/SelectionCheckbox.js +2 -2
- package/dist/components/shared/SelectionCheckbox.js.map +1 -1
- package/dist/components/shared/SessionNotificationBanner.js +8 -6
- package/dist/components/shared/SessionNotificationBanner.js.map +1 -1
- package/dist/components/shared/StatCard.js +2 -2
- package/dist/components/shared/StatCard.js.map +1 -1
- package/dist/components/shared/StatusBadge.js +1 -1
- package/dist/components/shared/StatusBadge.js.map +1 -1
- package/dist/components/targets/TargetCard.js +24 -11
- package/dist/components/targets/TargetCard.js.map +1 -1
- package/dist/components/templates/PublishTemplateForm.js +27 -7
- package/dist/components/templates/PublishTemplateForm.js.map +1 -1
- package/dist/components/templates/TemplateCard.js +6 -6
- package/dist/components/templates/TemplateCard.js.map +1 -1
- package/dist/components/templates/TemplateVariableEditor.js +21 -3
- package/dist/components/templates/TemplateVariableEditor.js.map +1 -1
- package/dist/components/templates/TemplateWizard.js +38 -15
- package/dist/components/templates/TemplateWizard.js.map +1 -1
- package/dist/components/tunnels/TunnelCard.js +5 -5
- package/dist/components/tunnels/TunnelCard.js.map +1 -1
- package/dist/components/tunnels/TunnelCreateWizard.js +8 -0
- package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
- package/dist/components/vibe/VibeAgentEmptyState.js +9 -5
- package/dist/components/vibe/VibeAgentEmptyState.js.map +1 -1
- package/dist/components/vibe/VibeAgentSwitcher.js +20 -16
- package/dist/components/vibe/VibeAgentSwitcher.js.map +1 -1
- package/dist/components/vibe/VibeLlmContextAdminPanel.js +5 -4
- package/dist/components/vibe/VibeLlmContextAdminPanel.js.map +1 -1
- package/dist/components/vibe/VibeLlmContextTabPanel.js +35 -18
- package/dist/components/vibe/VibeLlmContextTabPanel.js.map +1 -1
- package/dist/components/vibecalendar/LogsDrawer.js +6 -0
- package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
- package/dist/components/vibecalendar/ScheduleTaskModal.js +19 -0
- package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalAgendaView.js +7 -0
- package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalDayView.js +7 -0
- package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalMonthView.js +2 -2
- package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalWeekView.js +8 -1
- package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
- package/dist/components/vibecalendar/VibeCalendarHeader.js +5 -0
- package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
- package/dist/components/vibecalendar/VibeTaskBlock.js +8 -0
- package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonForm.js +20 -0
- package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckButtonTile.js +12 -4
- package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckExecutionLog.js +6 -0
- package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckForm.js +5 -0
- package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckGrid.js +1 -0
- package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckShareDialog.js +18 -1
- package/dist/components/vibedeck/VibeDeckShareDialog.js.map +1 -1
- package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -0
- package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
- package/dist/components/vibes/VibeCard.js +10 -9
- package/dist/components/vibes/VibeCard.js.map +1 -1
- package/dist/components/vibes/VibeList.js +30 -16
- package/dist/components/vibes/VibeList.js.map +1 -1
- package/dist/pages/ActionsPage.js +12 -0
- package/dist/pages/ActionsPage.js.map +1 -1
- package/dist/pages/AgentDetailsPage.js +125 -68
- package/dist/pages/AgentDetailsPage.js.map +1 -1
- package/dist/pages/AgentGraphPage.js +5 -5
- package/dist/pages/AgentGraphPage.js.map +1 -1
- package/dist/pages/AgentsPage.js +37 -12
- package/dist/pages/AgentsPage.js.map +1 -1
- package/dist/pages/AnalyticsPage.js +1 -1
- package/dist/pages/AnalyticsPage.js.map +1 -1
- package/dist/pages/CatalogDetailPage.js +34 -20
- package/dist/pages/CatalogDetailPage.js.map +1 -1
- package/dist/pages/CatalogPage.js +9 -5
- package/dist/pages/CatalogPage.js.map +1 -1
- package/dist/pages/ComponentDetailPage.js +40 -23
- package/dist/pages/ComponentDetailPage.js.map +1 -1
- package/dist/pages/ComponentsPage.js +9 -5
- package/dist/pages/ComponentsPage.js.map +1 -1
- package/dist/pages/GettingStartedPage.js +6 -5
- package/dist/pages/GettingStartedPage.js.map +1 -1
- package/dist/pages/HealthPage.js +16 -15
- package/dist/pages/HealthPage.js.map +1 -1
- package/dist/pages/LogsPage.js +2 -2
- package/dist/pages/LogsPage.js.map +1 -1
- package/dist/pages/NoteDetailsPage.js +12 -7
- package/dist/pages/NoteDetailsPage.js.map +1 -1
- package/dist/pages/OverviewPage.js +26 -15
- package/dist/pages/OverviewPage.js.map +1 -1
- package/dist/pages/SessionDetailsPage.js +73 -50
- package/dist/pages/SessionDetailsPage.js.map +1 -1
- package/dist/pages/SessionsPage.js +49 -22
- package/dist/pages/SessionsPage.js.map +1 -1
- package/dist/pages/SettingsPage.js +4 -4
- package/dist/pages/SettingsPage.js.map +1 -1
- package/dist/pages/SharedSessionPage.js +36 -29
- package/dist/pages/SharedSessionPage.js.map +1 -1
- package/dist/pages/SharedVibeDeckPage.js +8 -6
- package/dist/pages/SharedVibeDeckPage.js.map +1 -1
- package/dist/pages/TargetDetailsPage.js +7 -6
- package/dist/pages/TargetDetailsPage.js.map +1 -1
- package/dist/pages/TargetsPage.js +84 -11
- package/dist/pages/TargetsPage.js.map +1 -1
- package/dist/pages/TemplateDetailPage.js +33 -23
- package/dist/pages/TemplateDetailPage.js.map +1 -1
- package/dist/pages/TemplatesPage.js +5 -3
- package/dist/pages/TemplatesPage.js.map +1 -1
- package/dist/pages/VibeCalendarPage.js +1 -0
- package/dist/pages/VibeCalendarPage.js.map +1 -1
- package/dist/pages/VibeDeckPage.js +256 -239
- package/dist/pages/VibeDeckPage.js.map +1 -1
- package/dist/pages/VibeDetailsPage.js +657 -619
- package/dist/pages/VibeDetailsPage.js.map +1 -1
- package/dist/pages/VibeTaskDetailPage.js +3 -0
- package/dist/pages/VibeTaskDetailPage.js.map +1 -1
- package/dist/pages/VibesPage.js +21 -8
- package/dist/pages/VibesPage.js.map +1 -1
- package/dist/pages/ai/AIBookmarksPage.js +8 -8
- package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
- package/dist/pages/ai/AIPage.js +4 -2
- package/dist/pages/ai/AIPage.js.map +1 -1
- package/dist/pages/ai/AISessionDetailPage.js +19 -10
- package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
- package/dist/pages/ai/AgentManagerPage.js +2 -1
- package/dist/pages/ai/AgentManagerPage.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/TunnelDetailsPage.js +2 -1
- package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelCliTab.js +1 -1
- package/dist/pages/tunnels/tabs/TunnelCliTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +1 -0
- package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
- package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js +1 -1
- package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js.map +1 -1
- package/dist/providers/AgentEventsProvider.js +5 -5
- package/dist/providers/AgentEventsProvider.js.map +1 -1
- package/dist/providers/VibeControlsProvider.js +3 -3
- package/dist/providers/VibeControlsProvider.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeAgentEmptyState.js","names":[],"sources":["../../../src/components/vibe/VibeAgentEmptyState.tsx"],"sourcesContent":["/**\n * VibeAgentEmptyState — shown on the Vibe details page when the vibe has no\n * agent attached. Tabs that depend on an agent (sessions, gitops, GraphQL\n * playground, git) are hidden, and the user is invited to attach an agent.\n *\n * UX: opens an in-place modal listing the workspace's existing agents so the\n * user can attach one without leaving the vibe detail page. Falls back to\n * navigating to the agents page only if no agents exist in the workspace\n * (so the user can register their first one).\n */\nimport { useCallback, useMemo, useState } from 'react';\nimport type { FC } from 'react';\nimport { ArrowRight, Plus, Server } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { EmptyState } from '@/components/shared';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListAgentsQuery,\n useAttachAgentToVibeMutation,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\nexport interface VibeAgentEmptyStateProps {\n vibeId: string;\n tr: (key: string, fallback: string) => string;\n /** Optional: called after a successful attach so the parent can refetch. */\n onAttached?: () => void;\n}\n\nexport const VibeAgentEmptyState: FC<VibeAgentEmptyStateProps> = ({ vibeId, tr, onAttached }) => {\n const navigate = useVibeNavigate();\n const apolloClient = useApolloClient();\n const [open, setOpen] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [busyAgentId, setBusyAgentId] = useState<string | null>(null);\n\n const { data, loading } = useListAgentsQuery({\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const agents = useMemo<ListAgentsQuery['vibecontrolsAgents']>(\n () => data?.vibecontrolsAgents ?? [],\n [data]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setErrorMessage(null);\n setBusyAgentId(agentId);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n onAttached?.();\n } catch (err) {\n setErrorMessage(err instanceof Error ? err.message : String(err));\n } finally {\n setBusyAgentId(null);\n }\n },\n [attach, vibeId, onAttached, apolloClient]\n );\n\n const handleRegisterNew = useCallback(() => {\n // Deep-link to the agents page with vibeId so the agents UI can offer\n // a \"register and attach to this vibe\" affordance.\n const query = vibeId ? `?attachToVibe=${encodeURIComponent(vibeId)}` : '';\n navigate(`/agents${query}`);\n }, [navigate, vibeId]);\n\n return (\n <>\n <div className=\"rounded-lg border border-border-default bg-bg-surface\">\n <EmptyState\n icon={<Server className=\"w-8 h-8 text-text-secondary\" />}\n title={tr('vibeDetails.noAgentTitle', 'No agent attached')}\n description={tr(\n 'vibeDetails.noAgentDescription',\n 'This vibe is not attached to an agent yet. Sessions, GitOps, GraphQL playground, and git tooling all run through an agent — connect one to unlock those tabs.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibeDetails.connectAnAgent', 'Connect an agent to this vibe')}\n <ArrowRight className=\"w-4 h-4\" />\n </button>\n }\n />\n </div>\n\n {open && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"vibe-attach-agent-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2\n id=\"vibe-attach-agent-title\"\n className=\"text-base font-semibold text-text-primary\"\n >\n {tr('vibeDetails.attachAgentTitle', 'Attach an agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-text-secondary hover:text-text-primary transition-colors\"\n aria-label={tr('common.close', 'Close')}\n >\n ✕\n </button>\n </div>\n\n <div className=\"px-5 py-4 max-h-[60vh] overflow-y-auto\">\n {loading && agents.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">{tr('common.loading', 'Loading…')}</p>\n ) : agents.length === 0 ? (\n <div className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {tr(\n 'vibeDetails.noWorkspaceAgents',\n 'No agents in this workspace yet. Register one first, then attach it to this vibe.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('vibeDetails.registerAgent', 'Register an agent')}\n </button>\n </div>\n ) : (\n <ul className=\"space-y-2\">\n {agents.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busyAgentId !== null}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover transition-colors text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}{' '}\n {a.isActive\n ? `· ${tr('agents.active', 'Active')}`\n : `· ${tr('agents.inactive', 'Inactive')}`}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {busyAgentId === a.id\n ? tr('common.attaching', 'Attaching…')\n : tr('vibeDetails.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {errorMessage && (\n <p className=\"mt-3 text-sm text-status-error-text\">{errorMessage}</p>\n )}\n </div>\n\n {agents.length > 0 && (\n <div className=\"flex items-center justify-between px-5 py-3 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"text-xs text-text-secondary hover:text-text-primary inline-flex items-center gap-1\"\n >\n <Plus className=\"w-3.5 h-3.5\" />\n {tr('vibeDetails.registerAgent', 'Register a new agent')}\n </button>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-sm px-3 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-action-ghost-bg-hover\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeAgentEmptyState.js","names":[],"sources":["../../../src/components/vibe/VibeAgentEmptyState.tsx"],"sourcesContent":["/**\n * VibeAgentEmptyState — shown on the Vibe details page when the vibe has no\n * agent attached. Tabs that depend on an agent (sessions, gitops, GraphQL\n * playground, git) are hidden, and the user is invited to attach an agent.\n *\n * UX: opens an in-place modal listing the workspace's existing agents so the\n * user can attach one without leaving the vibe detail page. Falls back to\n * navigating to the agents page only if no agents exist in the workspace\n * (so the user can register their first one).\n */\nimport { useCallback, useMemo, useState } from 'react';\nimport type { FC } from 'react';\nimport { ArrowRight, Plus, Server } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { EmptyState } from '@/components/shared';\nimport { useVibeNavigate } from '@/providers/VibeControlsProvider';\nimport {\n useListAgentsQuery,\n useAttachAgentToVibeMutation,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\nexport interface VibeAgentEmptyStateProps {\n vibeId: string;\n tr: (key: string, fallback: string) => string;\n /** Optional: called after a successful attach so the parent can refetch. */\n onAttached?: () => void;\n}\n\nexport const VibeAgentEmptyState: FC<VibeAgentEmptyStateProps> = ({ vibeId, tr, onAttached }) => {\n const navigate = useVibeNavigate();\n const apolloClient = useApolloClient();\n const [open, setOpen] = useState(false);\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const [busyAgentId, setBusyAgentId] = useState<string | null>(null);\n\n const { data, loading } = useListAgentsQuery({\n skip: !open,\n fetchPolicy: 'cache-and-network',\n });\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const agents = useMemo<ListAgentsQuery['vibecontrolsAgents']>(\n () => data?.vibecontrolsAgents ?? [],\n [data]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setErrorMessage(null);\n setBusyAgentId(agentId);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n onAttached?.();\n } catch (err) {\n setErrorMessage(err instanceof Error ? err.message : String(err));\n } finally {\n setBusyAgentId(null);\n }\n },\n [attach, vibeId, onAttached, apolloClient]\n );\n\n const handleRegisterNew = useCallback(() => {\n // Deep-link to the agents page with vibeId so the agents UI can offer\n // a \"register and attach to this vibe\" affordance.\n const query = vibeId ? `?attachToVibe=${encodeURIComponent(vibeId)}` : '';\n navigate(`/agents${query}`);\n }, [navigate, vibeId]);\n\n return (\n <>\n <div className=\"rounded-lg border border-border-default bg-bg-surface\">\n <EmptyState\n icon={<Server className=\"size-8 text-text-secondary\" />}\n title={tr('vibeDetails.noAgentTitle', 'No agent attached')}\n description={tr(\n 'vibeDetails.noAgentDescription',\n 'This vibe is not attached to an agent yet. Sessions, GitOps, GraphQL playground, and git tooling all run through an agent — connect one to unlock those tabs.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('vibeDetails.connectAnAgent', 'Connect an agent to this vibe')}\n <ArrowRight className=\"size-4\" />\n </button>\n }\n />\n </div>\n\n {open && (\n <div tabIndex={0} onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); setOpen(false); } }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"vibe-attach-agent-title\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2\n id=\"vibe-attach-agent-title\"\n className=\"text-base font-semibold text-text-primary\"\n >\n {tr('vibeDetails.attachAgentTitle', 'Attach an agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-text-secondary hover:text-text-primary transition-colors\"\n aria-label={tr('common.close', 'Close')}\n >\n ✕\n </button>\n </div>\n\n <div className=\"px-5 py-4 max-h-[60vh] overflow-y-auto\">\n {loading && agents.length === 0 ? (\n <p className=\"text-sm text-text-secondary\">{tr('common.loading', 'Loading…')}</p>\n ) : agents.length === 0 ? (\n <div className=\"text-sm text-text-secondary space-y-3\">\n <p>\n {tr(\n 'vibeDetails.noWorkspaceAgents',\n 'No agents in this workspace yet. Register one first, then attach it to this vibe.'\n )}\n </p>\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"inline-flex items-center gap-1.5 px-3 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('vibeDetails.registerAgent', 'Register an agent')}\n </button>\n </div>\n ) : (\n <ul className=\"space-y-2\">\n {agents.map((a) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busyAgentId !== null}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover transition-colors text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}{' '}\n {a.isActive\n ? `· ${tr('agents.active', 'Active')}`\n : `· ${tr('agents.inactive', 'Inactive')}`}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {busyAgentId === a.id\n ? tr('common.attaching', 'Attaching…')\n : tr('vibeDetails.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {errorMessage && (\n <p className=\"mt-3 text-sm text-status-error-text\">{errorMessage}</p>\n )}\n </div>\n\n {agents.length > 0 && (\n <div className=\"flex items-center justify-between px-5 py-3 border-t border-border-subtle\">\n <button\n type=\"button\"\n onClick={handleRegisterNew}\n className=\"text-xs text-text-secondary hover:text-text-primary inline-flex items-center gap-1\"\n >\n <Plus className=\"size-3.5\" />\n {tr('vibeDetails.registerAgent', 'Register a new agent')}\n </button>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"text-sm px-3 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-action-ghost-bg-hover\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n </>\n );\n};\n"],"mappings":"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"}
|
|
@@ -70,13 +70,13 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
70
70
|
className: "p-4 border-b border-border-default flex items-center justify-between",
|
|
71
71
|
children: [/* @__PURE__ */ y("h3", {
|
|
72
72
|
className: "font-semibold text-text-primary flex items-center gap-2",
|
|
73
|
-
children: [/* @__PURE__ */ v(h, { className: "
|
|
73
|
+
children: [/* @__PURE__ */ v(h, { className: "size-5" }), C("vibeAgentSwitcher.title", "Active agent for this vibe")]
|
|
74
74
|
}), /* @__PURE__ */ y("button", {
|
|
75
75
|
type: "button",
|
|
76
76
|
onClick: () => j(!0),
|
|
77
77
|
className: "inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken",
|
|
78
78
|
disabled: I,
|
|
79
|
-
children: [/* @__PURE__ */ v(p, { className: "
|
|
79
|
+
children: [/* @__PURE__ */ v(p, { className: "size-3.5" }), C("vibeAgentSwitcher.attachAnother", "Attach another")]
|
|
80
80
|
})]
|
|
81
81
|
}),
|
|
82
82
|
/* @__PURE__ */ y("div", {
|
|
@@ -89,7 +89,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
89
89
|
"aria-expanded": E,
|
|
90
90
|
children: [/* @__PURE__ */ y("span", {
|
|
91
91
|
className: "flex items-center gap-3 min-w-0",
|
|
92
|
-
children: [/* @__PURE__ */ v(h, { className: "
|
|
92
|
+
children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
|
|
93
93
|
className: "min-w-0 text-left",
|
|
94
94
|
children: [/* @__PURE__ */ v("span", {
|
|
95
95
|
className: "block text-sm font-medium text-text-primary truncate",
|
|
@@ -99,18 +99,18 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
99
99
|
children: [R?.hostname ?? "—", R && (R.isActive ? " · active" : " · offline")]
|
|
100
100
|
})]
|
|
101
101
|
})]
|
|
102
|
-
}), /* @__PURE__ */ v(f, { className: `
|
|
102
|
+
}), /* @__PURE__ */ v(f, { className: `size-4 text-text-secondary transition-transform ${E ? "rotate-180" : ""}` })]
|
|
103
103
|
}), E && /* @__PURE__ */ y("div", {
|
|
104
104
|
className: "absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg",
|
|
105
105
|
children: [/* @__PURE__ */ y("div", {
|
|
106
106
|
className: "flex items-center gap-2 px-3 py-2 border-b border-border-subtle",
|
|
107
|
-
children: [/* @__PURE__ */ v(m, { className: "
|
|
107
|
+
children: [/* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
|
|
108
|
+
"aria-label": "control",
|
|
108
109
|
type: "text",
|
|
109
110
|
value: O,
|
|
110
111
|
onChange: (e) => k(e.target.value),
|
|
111
112
|
placeholder: C("vibeAgentSwitcher.searchPlaceholder", "Search agents…"),
|
|
112
|
-
className: "w-full bg-transparent text-sm text-text-primary outline-none"
|
|
113
|
-
autoFocus: !0
|
|
113
|
+
className: "w-full bg-transparent text-sm text-text-primary outline-none"
|
|
114
114
|
})]
|
|
115
115
|
}), /* @__PURE__ */ v("ul", {
|
|
116
116
|
role: "listbox",
|
|
@@ -130,7 +130,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
130
130
|
className: `flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${t ? "bg-bg-sunken" : ""}`,
|
|
131
131
|
children: [/* @__PURE__ */ y("span", {
|
|
132
132
|
className: "flex items-center gap-2 min-w-0",
|
|
133
|
-
children: [/* @__PURE__ */ v(h, { className: "
|
|
133
|
+
children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
|
|
134
134
|
className: "min-w-0",
|
|
135
135
|
children: [/* @__PURE__ */ v("span", {
|
|
136
136
|
className: "block text-text-primary truncate",
|
|
@@ -144,14 +144,14 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
144
144
|
]
|
|
145
145
|
})]
|
|
146
146
|
})]
|
|
147
|
-
}), t && /* @__PURE__ */ v(d, { className: "
|
|
147
|
+
}), t && /* @__PURE__ */ v(d, { className: "size-4 text-action-primary-bg" })]
|
|
148
148
|
}), /* @__PURE__ */ v("button", {
|
|
149
149
|
type: "button",
|
|
150
150
|
onClick: () => J(e.id),
|
|
151
151
|
disabled: I,
|
|
152
152
|
title: C("vibeAgentSwitcher.detach", "Detach from vibe"),
|
|
153
153
|
className: "px-2 text-text-secondary hover:text-status-error-text",
|
|
154
|
-
children: /* @__PURE__ */ v(g, { className: "
|
|
154
|
+
children: /* @__PURE__ */ v(g, { className: "size-4" })
|
|
155
155
|
})]
|
|
156
156
|
}, e.id);
|
|
157
157
|
})
|
|
@@ -159,6 +159,10 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
159
159
|
})]
|
|
160
160
|
}),
|
|
161
161
|
A && /* @__PURE__ */ v("div", {
|
|
162
|
+
tabIndex: 0,
|
|
163
|
+
onKeyDown: (e) => {
|
|
164
|
+
e.key === "Escape" && (e.preventDefault(), j(!1));
|
|
165
|
+
},
|
|
162
166
|
role: "dialog",
|
|
163
167
|
"aria-modal": "true",
|
|
164
168
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4",
|
|
@@ -178,25 +182,25 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
178
182
|
onClick: () => j(!1),
|
|
179
183
|
className: "text-text-secondary hover:text-text-primary",
|
|
180
184
|
"aria-label": C("common.close", "Close"),
|
|
181
|
-
children: /* @__PURE__ */ v(g, { className: "
|
|
185
|
+
children: /* @__PURE__ */ v(g, { className: "size-4" })
|
|
182
186
|
})]
|
|
183
187
|
}),
|
|
184
188
|
/* @__PURE__ */ v("div", {
|
|
185
189
|
className: "px-5 py-3 border-b border-border-subtle",
|
|
186
190
|
children: /* @__PURE__ */ y("div", {
|
|
187
191
|
className: "flex items-center gap-2",
|
|
188
|
-
children: [/* @__PURE__ */ v(m, { className: "
|
|
192
|
+
children: [/* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" }), /* @__PURE__ */ v("input", {
|
|
193
|
+
"aria-label": "control",
|
|
189
194
|
type: "text",
|
|
190
195
|
value: M,
|
|
191
196
|
onChange: (e) => N(e.target.value),
|
|
192
197
|
placeholder: C("vibeAgentSwitcher.searchPlaceholder", "Search agents…"),
|
|
193
|
-
className: "w-full bg-transparent text-sm text-text-primary outline-none"
|
|
194
|
-
autoFocus: !0
|
|
198
|
+
className: "w-full bg-transparent text-sm text-text-primary outline-none"
|
|
195
199
|
})]
|
|
196
200
|
})
|
|
197
201
|
}),
|
|
198
202
|
/* @__PURE__ */ y("div", {
|
|
199
|
-
className: "
|
|
203
|
+
className: "p-2 max-h-[60vh] overflow-y-auto",
|
|
200
204
|
children: [U.length === 0 ? /* @__PURE__ */ v("p", {
|
|
201
205
|
className: "text-sm text-text-secondary px-3 py-2",
|
|
202
206
|
children: C("vibeAgentSwitcher.noCandidates", "No unattached agents available. Register a new agent first.")
|
|
@@ -209,7 +213,7 @@ function b({ vibeId: b, attachedAgents: x, effectiveAgentId: S }) {
|
|
|
209
213
|
className: "w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60",
|
|
210
214
|
children: [/* @__PURE__ */ y("span", {
|
|
211
215
|
className: "flex items-center gap-3 min-w-0",
|
|
212
|
-
children: [/* @__PURE__ */ v(h, { className: "
|
|
216
|
+
children: [/* @__PURE__ */ v(h, { className: "size-4 text-text-secondary flex-shrink-0" }), /* @__PURE__ */ y("span", {
|
|
213
217
|
className: "min-w-0",
|
|
214
218
|
children: [/* @__PURE__ */ v("span", {
|
|
215
219
|
className: "block text-sm font-medium text-text-primary truncate",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeAgentSwitcher.js","names":[],"sources":["../../../src/components/vibe/VibeAgentSwitcher.tsx"],"sourcesContent":["/**\n * VibeAgentSwitcher — inline switcher + attach-more affordance shown on the\n * Vibe detail Overview tab once at least one agent is attached.\n *\n * Why this exists: a vibe can carry many agents (every collaborator brings\n * their own host/dev VM alongside shared env agents). Without a top-level\n * switcher, the \"effective agent\" chosen by the auto-pick heuristic is\n * invisible and unswitchable from the detail page, and there's no way to\n * attach a *second* agent without leaving for the agents tab. This card:\n *\n * 1. Names the active agent for the current user on this vibe.\n * 2. Lists every attached agent in a searchable dropdown — choosing one\n * writes to the per-vibe default store slot, persisted across reloads.\n * 3. Surfaces \"Attach another agent\" so users discover the multi-attach\n * flow without bouncing tabs.\n * 4. Surfaces \"Detach\" per agent (owner-scoped, no peer detaches).\n */\nimport { useMemo, useState, useCallback } from 'react';\nimport { Check, ChevronDown, Plus, Search, Server, X } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Card } from '@/components/shared';\nimport {\n useAttachAgentToVibeMutation,\n useDetachAgentFromVibeMutation,\n useListAgentsQuery,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\ntype ListAgent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useTr } from '@/shared/hooks/useTr';\n\nexport interface AttachedAgent {\n id: string;\n name: string;\n hostname?: string | null;\n isActive: boolean;\n ownerUserId?: string | null;\n tunnelUrl?: string | null;\n}\n\ninterface Props {\n vibeId: string;\n attachedAgents: ReadonlyArray<AttachedAgent>;\n effectiveAgentId: string | null;\n}\n\nexport function VibeAgentSwitcher({ vibeId, attachedAgents, effectiveAgentId }: Props) {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const setDefault = useVibeControlsStore((s) => s.setDefaultAgentForVibe);\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [attachOpen, setAttachOpen] = useState(false);\n const [attachQuery, setAttachQuery] = useState('');\n const [attachError, setAttachError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n\n const active = attachedAgents.find((a) => a.id === effectiveAgentId) ?? attachedAgents[0] ?? null;\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return attachedAgents;\n return attachedAgents.filter(\n (a) =>\n a.name.toLowerCase().includes(q) ||\n (a.hostname ?? '').toLowerCase().includes(q) ||\n a.id.toLowerCase().includes(q)\n );\n }, [attachedAgents, query]);\n\n const { data: agentsData, refetch: refetchAgents } = useListAgentsQuery({\n skip: !attachOpen,\n fetchPolicy: 'cache-and-network',\n });\n const attachedIds = useMemo(() => new Set(attachedAgents.map((a) => a.id)), [attachedAgents]);\n const candidates = useMemo(() => {\n const all = agentsData?.vibecontrolsAgents ?? [];\n const q = attachQuery.trim().toLowerCase();\n return all\n .filter((a: ListAgent) => !attachedIds.has(a.id))\n .filter((a: ListAgent) =>\n q ? a.name.toLowerCase().includes(q) || (a.hostname ?? '').toLowerCase().includes(q) : true\n );\n }, [agentsData, attachedIds, attachQuery]);\n\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n const [detach] = useDetachAgentFromVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const handlePick = useCallback(\n (agentId: string) => {\n setDefault(vibeId, agentId);\n setOpen(false);\n },\n [setDefault, vibeId]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setBusy(true);\n setAttachError(null);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n await refetchAgents();\n setAttachOpen(false);\n } catch (err) {\n setAttachError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n },\n [attach, refetchAgents, vibeId, apolloClient]\n );\n\n const handleDetach = useCallback(\n async (agentId: string) => {\n if (!confirm(tr('vibeAgentSwitcher.detachConfirm', 'Detach this agent from the vibe?'))) {\n return;\n }\n setBusy(true);\n try {\n await detach({ variables: { input: { vibeId, agentId } } });\n // Evict the vibe from cache so the parent GetVibe query re-renders immediately\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n } finally {\n setBusy(false);\n }\n },\n [detach, tr, vibeId, apolloClient]\n );\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <h3 className=\"font-semibold text-text-primary flex items-center gap-2\">\n <Server className=\"w-5 h-5\" />\n {tr('vibeAgentSwitcher.title', 'Active agent for this vibe')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(true)}\n className=\"inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken\"\n disabled={busy}\n >\n <Plus className=\"w-3.5 h-3.5\" />\n {tr('vibeAgentSwitcher.attachAnother', 'Attach another')}\n </button>\n </div>\n\n <div className=\"p-4 space-y-2 relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-default bg-bg-sunken hover:border-action-primary-bg\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {active?.name ?? tr('vibeAgentSwitcher.none', 'No active agent')}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {active?.hostname ?? '—'}\n {active && (active.isActive ? ' · active' : ' · offline')}\n </span>\n </span>\n </span>\n <ChevronDown\n className={`w-4 h-4 text-text-secondary transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n\n {open && (\n <div className=\"absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border-subtle\">\n <Search className=\"w-4 h-4 text-text-secondary\" />\n <input\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n autoFocus\n />\n </div>\n <ul role=\"listbox\" className=\"max-h-64 overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <li className=\"px-3 py-2 text-xs text-text-secondary\">\n {tr('vibeAgentSwitcher.noMatch', 'No agents match your search.')}\n </li>\n ) : (\n filtered.map((a) => {\n const isActive = a.id === effectiveAgentId;\n return (\n <li key={a.id} className=\"flex items-center\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => handlePick(a.id)}\n className={`flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${isActive ? 'bg-bg-sunken' : ''}`}\n >\n <span className=\"flex items-center gap-2 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-text-primary truncate\">{a.name}</span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname ?? '—'} {a.isActive ? '· active' : '· offline'}\n </span>\n </span>\n </span>\n {isActive && <Check className=\"w-4 h-4 text-action-primary-bg\" />}\n </button>\n <button\n type=\"button\"\n onClick={() => handleDetach(a.id)}\n disabled={busy}\n title={tr('vibeAgentSwitcher.detach', 'Detach from vibe')}\n className=\"px-2 text-text-secondary hover:text-status-error-text\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>\n )}\n </div>\n\n {attachOpen && (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setAttachOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('vibeAgentSwitcher.attachTitle', 'Attach an additional agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(false)}\n className=\"text-text-secondary hover:text-text-primary\"\n aria-label={tr('common.close', 'Close')}\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n <div className=\"px-5 py-3 border-b border-border-subtle\">\n <div className=\"flex items-center gap-2\">\n <Search className=\"w-4 h-4 text-text-secondary\" />\n <input\n type=\"text\"\n value={attachQuery}\n onChange={(e) => setAttachQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n autoFocus\n />\n </div>\n </div>\n <div className=\"px-2 py-2 max-h-[60vh] overflow-y-auto\">\n {candidates.length === 0 ? (\n <p className=\"text-sm text-text-secondary px-3 py-2\">\n {tr(\n 'vibeAgentSwitcher.noCandidates',\n 'No unattached agents available. Register a new agent first.'\n )}\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {candidates.map((a: ListAgent) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busy}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"w-4 h-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}\n {a.isActive ? ' · active' : ' · inactive'}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {tr('vibeAgentSwitcher.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {attachError && (\n <p className=\"mt-2 px-3 text-sm text-status-error-text\">{attachError}</p>\n )}\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeAgentSwitcher.js","names":[],"sources":["../../../src/components/vibe/VibeAgentSwitcher.tsx"],"sourcesContent":["/**\n * VibeAgentSwitcher — inline switcher + attach-more affordance shown on the\n * Vibe detail Overview tab once at least one agent is attached.\n *\n * Why this exists: a vibe can carry many agents (every collaborator brings\n * their own host/dev VM alongside shared env agents). Without a top-level\n * switcher, the \"effective agent\" chosen by the auto-pick heuristic is\n * invisible and unswitchable from the detail page, and there's no way to\n * attach a *second* agent without leaving for the agents tab. This card:\n *\n * 1. Names the active agent for the current user on this vibe.\n * 2. Lists every attached agent in a searchable dropdown — choosing one\n * writes to the per-vibe default store slot, persisted across reloads.\n * 3. Surfaces \"Attach another agent\" so users discover the multi-attach\n * flow without bouncing tabs.\n * 4. Surfaces \"Detach\" per agent (owner-scoped, no peer detaches).\n */\nimport { useMemo, useState, useCallback } from 'react';\nimport { Check, ChevronDown, Plus, Search, Server, X } from 'lucide-react';\nimport { useApolloClient } from '@apollo/client/react';\nimport { Card } from '@/components/shared';\nimport {\n useAttachAgentToVibeMutation,\n useDetachAgentFromVibeMutation,\n useListAgentsQuery,\n GetVibeDocument,\n ListVibesDocument,\n type ListAgentsQuery,\n} from '@/generated/wspace-operations';\n\ntype ListAgent = NonNullable<ListAgentsQuery['vibecontrolsAgents']>[number];\nimport { useVibeControlsStore } from '@/store/vibeControlsStore';\nimport { useTr } from '@/shared/hooks/useTr';\n\nexport interface AttachedAgent {\n id: string;\n name: string;\n hostname?: string | null;\n isActive: boolean;\n ownerUserId?: string | null;\n tunnelUrl?: string | null;\n}\n\ninterface Props {\n vibeId: string;\n attachedAgents: ReadonlyArray<AttachedAgent>;\n effectiveAgentId: string | null;\n}\n\nexport function VibeAgentSwitcher({ vibeId, attachedAgents, effectiveAgentId }: Props) {\n const tr = useTr();\n const apolloClient = useApolloClient();\n const setDefault = useVibeControlsStore((s) => s.setDefaultAgentForVibe);\n\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [attachOpen, setAttachOpen] = useState(false);\n const [attachQuery, setAttachQuery] = useState('');\n const [attachError, setAttachError] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n\n const active = attachedAgents.find((a) => a.id === effectiveAgentId) ?? attachedAgents[0] ?? null;\n\n const filtered = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return attachedAgents;\n return attachedAgents.filter(\n (a) =>\n a.name.toLowerCase().includes(q) ||\n (a.hostname ?? '').toLowerCase().includes(q) ||\n a.id.toLowerCase().includes(q)\n );\n }, [attachedAgents, query]);\n\n const { data: agentsData, refetch: refetchAgents } = useListAgentsQuery({\n skip: !attachOpen,\n fetchPolicy: 'cache-and-network',\n });\n const attachedIds = useMemo(() => new Set(attachedAgents.map((a) => a.id)), [attachedAgents]);\n const candidates = useMemo(() => {\n const all = agentsData?.vibecontrolsAgents ?? [];\n const q = attachQuery.trim().toLowerCase();\n return all\n .filter((a: ListAgent) => !attachedIds.has(a.id))\n .filter((a: ListAgent) =>\n q ? a.name.toLowerCase().includes(q) || (a.hostname ?? '').toLowerCase().includes(q) : true\n );\n }, [agentsData, attachedIds, attachQuery]);\n\n const [attach] = useAttachAgentToVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n const [detach] = useDetachAgentFromVibeMutation({\n refetchQueries: [GetVibeDocument, ListVibesDocument],\n awaitRefetchQueries: true,\n });\n\n const handlePick = useCallback(\n (agentId: string) => {\n setDefault(vibeId, agentId);\n setOpen(false);\n },\n [setDefault, vibeId]\n );\n\n const handleAttach = useCallback(\n async (agentId: string) => {\n setBusy(true);\n setAttachError(null);\n try {\n await attach({ variables: { input: { vibeId, agentId } } });\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n await refetchAgents();\n setAttachOpen(false);\n } catch (err) {\n setAttachError(err instanceof Error ? err.message : String(err));\n } finally {\n setBusy(false);\n }\n },\n [attach, refetchAgents, vibeId, apolloClient]\n );\n\n const handleDetach = useCallback(\n async (agentId: string) => {\n if (!confirm(tr('vibeAgentSwitcher.detachConfirm', 'Detach this agent from the vibe?'))) {\n return;\n }\n setBusy(true);\n try {\n await detach({ variables: { input: { vibeId, agentId } } });\n // Evict the vibe from cache so the parent GetVibe query re-renders immediately\n apolloClient.cache.evict({ id: `Vibe:${vibeId}` });\n apolloClient.cache.gc();\n setOpen(false);\n } finally {\n setBusy(false);\n }\n },\n [detach, tr, vibeId, apolloClient]\n );\n\n return (\n <Card>\n <div className=\"p-4 border-b border-border-default flex items-center justify-between\">\n <h3 className=\"font-semibold text-text-primary flex items-center gap-2\">\n <Server className=\"size-5\" />\n {tr('vibeAgentSwitcher.title', 'Active agent for this vibe')}\n </h3>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(true)}\n className=\"inline-flex items-center gap-1.5 text-xs px-2.5 py-1.5 rounded-md border border-border-default text-text-primary hover:bg-bg-sunken\"\n disabled={busy}\n >\n <Plus className=\"size-3.5\" />\n {tr('vibeAgentSwitcher.attachAnother', 'Attach another')}\n </button>\n </div>\n\n <div className=\"p-4 space-y-2 relative\">\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-default bg-bg-sunken hover:border-action-primary-bg\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {active?.name ?? tr('vibeAgentSwitcher.none', 'No active agent')}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {active?.hostname ?? '—'}\n {active && (active.isActive ? ' · active' : ' · offline')}\n </span>\n </span>\n </span>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${open ? 'rotate-180' : ''}`}\n />\n </button>\n\n {open && (\n <div className=\"absolute left-4 right-4 z-30 mt-1 rounded-md border border-border-default bg-bg-elevated shadow-lg\">\n <div className=\"flex items-center gap-2 px-3 py-2 border-b border-border-subtle\">\n <Search className=\"size-4 text-text-secondary\" />\n <input aria-label=\"control\"\n type=\"text\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n\n />\n </div>\n <ul role=\"listbox\" className=\"max-h-64 overflow-y-auto py-1\">\n {filtered.length === 0 ? (\n <li className=\"px-3 py-2 text-xs text-text-secondary\">\n {tr('vibeAgentSwitcher.noMatch', 'No agents match your search.')}\n </li>\n ) : (\n filtered.map((a) => {\n const isActive = a.id === effectiveAgentId;\n return (\n <li key={a.id} className=\"flex items-center\">\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n onClick={() => handlePick(a.id)}\n className={`flex-1 flex items-center justify-between gap-3 px-3 py-2 text-left text-sm hover:bg-bg-sunken ${isActive ? 'bg-bg-sunken' : ''}`}\n >\n <span className=\"flex items-center gap-2 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-text-primary truncate\">{a.name}</span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname ?? '—'} {a.isActive ? '· active' : '· offline'}\n </span>\n </span>\n </span>\n {isActive && <Check className=\"size-4 text-action-primary-bg\" />}\n </button>\n <button\n type=\"button\"\n onClick={() => handleDetach(a.id)}\n disabled={busy}\n title={tr('vibeAgentSwitcher.detach', 'Detach from vibe')}\n className=\"px-2 text-text-secondary hover:text-status-error-text\"\n >\n <X className=\"size-4\" />\n </button>\n </li>\n );\n })\n )}\n </ul>\n </div>\n )}\n </div>\n\n {attachOpen && (\n <div tabIndex={0} onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); setAttachOpen(false); } }}\n role=\"dialog\"\n aria-modal=\"true\"\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\"\n onClick={(e) => {\n if (e.target === e.currentTarget) setAttachOpen(false);\n }}\n >\n <div className=\"w-full max-w-md rounded-lg bg-bg-elevated border border-border-default shadow-xl\">\n <div className=\"flex items-center justify-between px-5 py-4 border-b border-border-subtle\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('vibeAgentSwitcher.attachTitle', 'Attach an additional agent')}\n </h2>\n <button\n type=\"button\"\n onClick={() => setAttachOpen(false)}\n className=\"text-text-secondary hover:text-text-primary\"\n aria-label={tr('common.close', 'Close')}\n >\n <X className=\"size-4\" />\n </button>\n </div>\n <div className=\"px-5 py-3 border-b border-border-subtle\">\n <div className=\"flex items-center gap-2\">\n <Search className=\"size-4 text-text-secondary\" />\n <input aria-label=\"control\"\n type=\"text\"\n value={attachQuery}\n onChange={(e) => setAttachQuery(e.target.value)}\n placeholder={tr('vibeAgentSwitcher.searchPlaceholder', 'Search agents…')}\n className=\"w-full bg-transparent text-sm text-text-primary outline-none\"\n\n />\n </div>\n </div>\n <div className=\"p-2 max-h-[60vh] overflow-y-auto\">\n {candidates.length === 0 ? (\n <p className=\"text-sm text-text-secondary px-3 py-2\">\n {tr(\n 'vibeAgentSwitcher.noCandidates',\n 'No unattached agents available. Register a new agent first.'\n )}\n </p>\n ) : (\n <ul className=\"space-y-1\">\n {candidates.map((a: ListAgent) => (\n <li key={a.id}>\n <button\n type=\"button\"\n onClick={() => handleAttach(a.id)}\n disabled={busy}\n className=\"w-full flex items-center justify-between gap-3 px-3 py-2.5 rounded-md border border-border-subtle hover:border-border-default hover:bg-action-ghost-bg-hover text-left disabled:opacity-60\"\n >\n <span className=\"flex items-center gap-3 min-w-0\">\n <Server className=\"size-4 text-text-secondary flex-shrink-0\" />\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-medium text-text-primary truncate\">\n {a.name}\n </span>\n <span className=\"block text-xs text-text-secondary truncate\">\n {a.hostname || '—'}\n {a.isActive ? ' · active' : ' · inactive'}\n </span>\n </span>\n </span>\n <span className=\"text-xs text-text-tertiary\">\n {tr('vibeAgentSwitcher.attach', 'Attach')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n {attachError && (\n <p className=\"mt-2 px-3 text-sm text-status-error-text\">{attachError}</p>\n )}\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n"],"mappings":"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"}
|
|
@@ -58,7 +58,7 @@ function p({ vibeId: a }) {
|
|
|
58
58
|
children: [
|
|
59
59
|
/* @__PURE__ */ l("header", {
|
|
60
60
|
className: "flex items-start gap-3",
|
|
61
|
-
children: [/* @__PURE__ */ c(r, { className: "
|
|
61
|
+
children: [/* @__PURE__ */ c(r, { className: "size-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h3", {
|
|
62
62
|
className: "text-base font-semibold text-text-primary",
|
|
63
63
|
children: "Admin · all URLs for this vibe"
|
|
64
64
|
}), /* @__PURE__ */ c("p", {
|
|
@@ -72,7 +72,7 @@ function p({ vibeId: a }) {
|
|
|
72
72
|
}),
|
|
73
73
|
y.length === 0 && !m && /* @__PURE__ */ l("div", {
|
|
74
74
|
className: "text-sm text-text-secondary py-3 flex items-center gap-2",
|
|
75
|
-
children: [/* @__PURE__ */ c(n, { className: "
|
|
75
|
+
children: [/* @__PURE__ */ c(n, { className: "size-4" }), "No URLs minted for this vibe by any user."]
|
|
76
76
|
}),
|
|
77
77
|
y.length > 0 && /* @__PURE__ */ c("div", {
|
|
78
78
|
className: "overflow-x-auto",
|
|
@@ -151,7 +151,7 @@ function p({ vibeId: a }) {
|
|
|
151
151
|
className: "py-2 pr-3 text-xs text-text-secondary",
|
|
152
152
|
children: /* @__PURE__ */ l("span", {
|
|
153
153
|
className: "inline-flex items-center gap-1",
|
|
154
|
-
children: [/* @__PURE__ */ c(t, { className: "
|
|
154
|
+
children: [/* @__PURE__ */ c(t, { className: "size-3" }), f(e.expiresAt)]
|
|
155
155
|
})
|
|
156
156
|
}),
|
|
157
157
|
/* @__PURE__ */ c("td", {
|
|
@@ -163,6 +163,7 @@ function p({ vibeId: a }) {
|
|
|
163
163
|
children: e.status === "ACTIVE" ? /* @__PURE__ */ l("div", {
|
|
164
164
|
className: "flex items-center gap-1",
|
|
165
165
|
children: [/* @__PURE__ */ c("input", {
|
|
166
|
+
"aria-label": "reason",
|
|
166
167
|
type: "text",
|
|
167
168
|
value: _[e.id] ?? "",
|
|
168
169
|
onChange: (t) => v((n) => ({
|
|
@@ -177,7 +178,7 @@ function p({ vibeId: a }) {
|
|
|
177
178
|
title: "Admin revoke",
|
|
178
179
|
"aria-label": "Admin revoke URL",
|
|
179
180
|
className: "p-1.5 text-status-error-text hover:opacity-80",
|
|
180
|
-
children: /* @__PURE__ */ c(i, { className: "
|
|
181
|
+
children: /* @__PURE__ */ c(i, { className: "size-4" })
|
|
181
182
|
})]
|
|
182
183
|
}) : /* @__PURE__ */ c("span", {
|
|
183
184
|
className: "text-xs text-text-secondary",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VibeLlmContextAdminPanel.js","names":[],"sources":["../../../src/components/vibe/VibeLlmContextAdminPanel.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Clock, Info, Shield, Trash2 } from 'lucide-react';\n\ninterface AdminTokenRow {\n id: string;\n vibeId: string;\n userId: string;\n label: string | null;\n tokenFingerprint: string;\n includeCredentials: boolean;\n includes: string[];\n status: 'ACTIVE' | 'REVOKED';\n expiresAt: string;\n lastFetchedAt: string | null;\n fetchCount: number;\n createdAt: string;\n revokedAt: string | null;\n revokedReason: string | null;\n}\n\nconst ALL_TOKENS = gql`\n query AllVibeLlmContextTokens($vibeId: ID, $userId: ID) {\n allVibeLlmContextTokens(vibeId: $vibeId, userId: $userId) {\n id\n vibeId\n userId\n label\n tokenFingerprint\n includeCredentials\n includes\n status\n expiresAt\n lastFetchedAt\n fetchCount\n createdAt\n revokedAt\n revokedReason\n }\n }\n`;\n\nconst ADMIN_REVOKE = gql`\n mutation AdminRevokeVibeLlmContextToken($tokenId: ID!, $reason: String) {\n adminRevokeVibeLlmContextToken(tokenId: $tokenId, reason: $reason) {\n id\n status\n revokedAt\n revokedReason\n }\n }\n`;\n\nfunction formatExpiry(expiresAt: string): string {\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return 'expired';\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n if (hours > 24) return `${Math.floor(hours / 24)}d`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\ninterface VibeLlmContextAdminPanelProps {\n vibeId: string;\n}\n\nexport function VibeLlmContextAdminPanel({ vibeId }: VibeLlmContextAdminPanelProps): ReactElement {\n const { data, loading, refetch } = useQuery<{ allVibeLlmContextTokens: AdminTokenRow[] }>(\n ALL_TOKENS,\n {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'ignore',\n }\n );\n const [adminRevoke] = useMutation<\n { adminRevokeVibeLlmContextToken: AdminTokenRow },\n { tokenId: string; reason?: string | null }\n >(ADMIN_REVOKE, { refetchQueries: ['AllVibeLlmContextTokens'] });\n\n const [reasonDraft, setReasonDraft] = useState<Record<string, string>>({});\n const tokens = data?.allVibeLlmContextTokens ?? [];\n\n const onRevoke = async (tokenId: string) => {\n await adminRevoke({\n variables: {\n tokenId,\n reason: (reasonDraft[tokenId] ?? '').trim() || null,\n },\n });\n setReasonDraft((prev) => {\n const next = { ...prev };\n delete next[tokenId];\n return next;\n });\n await refetch();\n };\n\n return (\n <section className=\"bg-bg-surface border border-status-warning-border rounded-lg p-5 space-y-3\">\n <header className=\"flex items-start gap-3\">\n <Shield className=\"w-5 h-5 text-status-warning-text mt-0.5\" />\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">\n Admin · all URLs for this vibe\n </h3>\n <p className=\"text-sm text-text-secondary\">\n Visible only to workspace admins. Lists every user's signed URLs for this vibe. Use\n revoke to immediately invalidate any URL — takes effect on the next fetch.\n </p>\n </div>\n </header>\n\n {loading && tokens.length === 0 && (\n <div className=\"text-sm text-text-secondary py-3\">Loading…</div>\n )}\n {tokens.length === 0 && !loading && (\n <div className=\"text-sm text-text-secondary py-3 flex items-center gap-2\">\n <Info className=\"w-4 h-4\" />\n No URLs minted for this vibe by any user.\n </div>\n )}\n {tokens.length > 0 && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-default text-left text-xs text-text-secondary\">\n <th className=\"py-2 pr-3\">User</th>\n <th className=\"py-2 pr-3\">Label</th>\n <th className=\"py-2 pr-3\">Fingerprint</th>\n <th className=\"py-2 pr-3\">Creds</th>\n <th className=\"py-2 pr-3\">Status</th>\n <th className=\"py-2 pr-3\">Expires</th>\n <th className=\"py-2 pr-3\">Fetches</th>\n <th className=\"py-2 pr-3\">Revoke</th>\n </tr>\n </thead>\n <tbody>\n {tokens.map((t) => (\n <tr key={t.id} className=\"border-b border-border-subtle align-top\">\n <td\n className=\"py-2 pr-3 font-mono text-xs text-text-secondary truncate max-w-[120px]\"\n title={t.userId}\n >\n {t.userId}\n </td>\n <td className=\"py-2 pr-3 text-text-primary\">{t.label ?? '—'}</td>\n <td className=\"py-2 pr-3 font-mono text-xs text-text-secondary\">\n {t.tokenFingerprint}\n </td>\n <td className=\"py-2 pr-3\">\n {t.includeCredentials ? (\n <span className=\"text-xs text-status-warning-text\">on</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">off</span>\n )}\n </td>\n <td className=\"py-2 pr-3\">\n <span\n className={`text-xs px-1.5 py-0.5 rounded ${\n t.status === 'ACTIVE'\n ? 'bg-status-success-bg/20 text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {t.status}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"w-3 h-3\" />\n {formatExpiry(t.expiresAt)}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">{t.fetchCount}</td>\n <td className=\"py-2 pr-3\">\n {t.status === 'ACTIVE' ? (\n <div className=\"flex items-center gap-1\">\n <input\n type=\"text\"\n value={reasonDraft[t.id] ?? ''}\n onChange={(e) =>\n setReasonDraft((prev) => ({ ...prev, [t.id]: e.target.value }))\n }\n placeholder=\"reason\"\n className=\"w-28 px-1.5 py-1 text-xs bg-bg-sunken border border-border-default rounded text-text-primary\"\n />\n <button\n type=\"button\"\n onClick={() => onRevoke(t.id)}\n title=\"Admin revoke\"\n aria-label=\"Admin revoke URL\"\n className=\"p-1.5 text-status-error-text hover:opacity-80\"\n >\n <Trash2 className=\"w-4 h-4\" />\n </button>\n </div>\n ) : (\n <span className=\"text-xs text-text-secondary\" title={t.revokedReason ?? ''}>\n {t.revokedReason ?? '—'}\n </span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VibeLlmContextAdminPanel.js","names":[],"sources":["../../../src/components/vibe/VibeLlmContextAdminPanel.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport { Clock, Info, Shield, Trash2 } from 'lucide-react';\n\ninterface AdminTokenRow {\n id: string;\n vibeId: string;\n userId: string;\n label: string | null;\n tokenFingerprint: string;\n includeCredentials: boolean;\n includes: string[];\n status: 'ACTIVE' | 'REVOKED';\n expiresAt: string;\n lastFetchedAt: string | null;\n fetchCount: number;\n createdAt: string;\n revokedAt: string | null;\n revokedReason: string | null;\n}\n\nconst ALL_TOKENS = gql`\n query AllVibeLlmContextTokens($vibeId: ID, $userId: ID) {\n allVibeLlmContextTokens(vibeId: $vibeId, userId: $userId) {\n id\n vibeId\n userId\n label\n tokenFingerprint\n includeCredentials\n includes\n status\n expiresAt\n lastFetchedAt\n fetchCount\n createdAt\n revokedAt\n revokedReason\n }\n }\n`;\n\nconst ADMIN_REVOKE = gql`\n mutation AdminRevokeVibeLlmContextToken($tokenId: ID!, $reason: String) {\n adminRevokeVibeLlmContextToken(tokenId: $tokenId, reason: $reason) {\n id\n status\n revokedAt\n revokedReason\n }\n }\n`;\n\nfunction formatExpiry(expiresAt: string): string {\n const diff = new Date(expiresAt).getTime() - Date.now();\n if (diff < 0) return 'expired';\n const hours = Math.floor(diff / (1000 * 60 * 60));\n const mins = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));\n if (hours > 24) return `${Math.floor(hours / 24)}d`;\n if (hours > 0) return `${hours}h ${mins}m`;\n return `${mins}m`;\n}\n\ninterface VibeLlmContextAdminPanelProps {\n vibeId: string;\n}\n\nexport function VibeLlmContextAdminPanel({ vibeId }: VibeLlmContextAdminPanelProps): ReactElement {\n const { data, loading, refetch } = useQuery<{ allVibeLlmContextTokens: AdminTokenRow[] }>(\n ALL_TOKENS,\n {\n variables: { vibeId },\n fetchPolicy: 'cache-and-network',\n errorPolicy: 'ignore',\n }\n );\n const [adminRevoke] = useMutation<\n { adminRevokeVibeLlmContextToken: AdminTokenRow },\n { tokenId: string; reason?: string | null }\n >(ADMIN_REVOKE, { refetchQueries: ['AllVibeLlmContextTokens'] });\n\n const [reasonDraft, setReasonDraft] = useState<Record<string, string>>({});\n const tokens = data?.allVibeLlmContextTokens ?? [];\n\n const onRevoke = async (tokenId: string) => {\n await adminRevoke({\n variables: {\n tokenId,\n reason: (reasonDraft[tokenId] ?? '').trim() || null,\n },\n });\n setReasonDraft((prev) => {\n const next = { ...prev };\n delete next[tokenId];\n return next;\n });\n await refetch();\n };\n\n return (\n <section className=\"bg-bg-surface border border-status-warning-border rounded-lg p-5 space-y-3\">\n <header className=\"flex items-start gap-3\">\n <Shield className=\"size-5 text-status-warning-text mt-0.5\" />\n <div>\n <h3 className=\"text-base font-semibold text-text-primary\">\n Admin · all URLs for this vibe\n </h3>\n <p className=\"text-sm text-text-secondary\">\n Visible only to workspace admins. Lists every user's signed URLs for this vibe. Use\n revoke to immediately invalidate any URL — takes effect on the next fetch.\n </p>\n </div>\n </header>\n\n {loading && tokens.length === 0 && (\n <div className=\"text-sm text-text-secondary py-3\">Loading…</div>\n )}\n {tokens.length === 0 && !loading && (\n <div className=\"text-sm text-text-secondary py-3 flex items-center gap-2\">\n <Info className=\"size-4\" />\n No URLs minted for this vibe by any user.\n </div>\n )}\n {tokens.length > 0 && (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-default text-left text-xs text-text-secondary\">\n <th className=\"py-2 pr-3\">User</th>\n <th className=\"py-2 pr-3\">Label</th>\n <th className=\"py-2 pr-3\">Fingerprint</th>\n <th className=\"py-2 pr-3\">Creds</th>\n <th className=\"py-2 pr-3\">Status</th>\n <th className=\"py-2 pr-3\">Expires</th>\n <th className=\"py-2 pr-3\">Fetches</th>\n <th className=\"py-2 pr-3\">Revoke</th>\n </tr>\n </thead>\n <tbody>\n {tokens.map((t) => (\n <tr key={t.id} className=\"border-b border-border-subtle align-top\">\n <td\n className=\"py-2 pr-3 font-mono text-xs text-text-secondary truncate max-w-[120px]\"\n title={t.userId}\n >\n {t.userId}\n </td>\n <td className=\"py-2 pr-3 text-text-primary\">{t.label ?? '—'}</td>\n <td className=\"py-2 pr-3 font-mono text-xs text-text-secondary\">\n {t.tokenFingerprint}\n </td>\n <td className=\"py-2 pr-3\">\n {t.includeCredentials ? (\n <span className=\"text-xs text-status-warning-text\">on</span>\n ) : (\n <span className=\"text-xs text-text-secondary\">off</span>\n )}\n </td>\n <td className=\"py-2 pr-3\">\n <span\n className={`text-xs px-1.5 py-0.5 rounded ${\n t.status === 'ACTIVE'\n ? 'bg-status-success-bg/20 text-status-success-text'\n : 'bg-bg-sunken text-text-secondary'\n }`}\n >\n {t.status}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1\">\n <Clock className=\"size-3\" />\n {formatExpiry(t.expiresAt)}\n </span>\n </td>\n <td className=\"py-2 pr-3 text-xs text-text-secondary\">{t.fetchCount}</td>\n <td className=\"py-2 pr-3\">\n {t.status === 'ACTIVE' ? (\n <div className=\"flex items-center gap-1\">\n <input aria-label=\"reason\"\n type=\"text\"\n value={reasonDraft[t.id] ?? ''}\n onChange={(e) =>\n setReasonDraft((prev) => ({ ...prev, [t.id]: e.target.value }))\n }\n placeholder=\"reason\"\n className=\"w-28 px-1.5 py-1 text-xs bg-bg-sunken border border-border-default rounded text-text-primary\"\n />\n <button\n type=\"button\"\n onClick={() => onRevoke(t.id)}\n title=\"Admin revoke\"\n aria-label=\"Admin revoke URL\"\n className=\"p-1.5 text-status-error-text hover:opacity-80\"\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n ) : (\n <span className=\"text-xs text-text-secondary\" title={t.revokedReason ?? ''}>\n {t.revokedReason ?? '—'}\n </span>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n );\n}\n"],"mappings":"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"}
|
|
@@ -202,7 +202,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
202
202
|
className: "rounded-lg border border-status-warning-border bg-status-warning-bg/30 p-4",
|
|
203
203
|
children: /* @__PURE__ */ g("div", {
|
|
204
204
|
className: "flex items-start gap-3",
|
|
205
|
-
children: [/* @__PURE__ */ h(ie, { className: "
|
|
205
|
+
children: [/* @__PURE__ */ h(ie, { className: "size-5 text-status-warning-text mt-0.5" }), /* @__PURE__ */ g("div", {
|
|
206
206
|
className: "text-sm text-text-primary",
|
|
207
207
|
children: [/* @__PURE__ */ h("p", {
|
|
208
208
|
className: "font-medium mb-1",
|
|
@@ -241,10 +241,11 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
241
241
|
},
|
|
242
242
|
disabled: w.loading,
|
|
243
243
|
className: "inline-flex items-center gap-1.5 px-3 py-1.5 text-sm bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50",
|
|
244
|
-
children: [K && !w.loading && /* @__PURE__ */ h(s, { className: "
|
|
244
|
+
children: [K && !w.loading && /* @__PURE__ */ h(s, { className: "size-4" }), w.loading ? "Saving…" : K ? "Saved" : "Save settings"]
|
|
245
245
|
})]
|
|
246
246
|
}),
|
|
247
247
|
/* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
|
|
248
|
+
htmlFor: "vibellmcontexttabpanel-44",
|
|
248
249
|
className: "block text-sm font-medium text-text-primary mb-2",
|
|
249
250
|
children: "URL expiry"
|
|
250
251
|
}), /* @__PURE__ */ g("div", {
|
|
@@ -261,6 +262,8 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
261
262
|
children: "or custom hours:"
|
|
262
263
|
}),
|
|
263
264
|
/* @__PURE__ */ h("input", {
|
|
265
|
+
id: "vibellmcontexttabpanel-44",
|
|
266
|
+
"aria-label": "control",
|
|
264
267
|
type: "number",
|
|
265
268
|
min: 1,
|
|
266
269
|
max: 168,
|
|
@@ -274,26 +277,28 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
274
277
|
className: "flex items-center gap-2 text-sm text-text-primary",
|
|
275
278
|
children: [
|
|
276
279
|
/* @__PURE__ */ h("input", {
|
|
280
|
+
"aria-label": "control",
|
|
277
281
|
type: "checkbox",
|
|
278
282
|
checked: N,
|
|
279
283
|
onChange: (e) => P(e.target.checked),
|
|
280
|
-
className: "
|
|
284
|
+
className: "size-4"
|
|
281
285
|
}),
|
|
282
286
|
/* @__PURE__ */ h("span", { children: "Include credentials (tunnel URLs + agent API keys)" }),
|
|
283
287
|
N ? /* @__PURE__ */ h(a, {
|
|
284
|
-
className: "
|
|
288
|
+
className: "size-4 text-status-warning-text",
|
|
285
289
|
"aria-label": "Credentials will be exposed in the snapshot"
|
|
286
290
|
}) : /* @__PURE__ */ h(re, {
|
|
287
|
-
className: "
|
|
291
|
+
className: "size-4 text-text-secondary",
|
|
288
292
|
"aria-label": "Credentials redacted"
|
|
289
293
|
})
|
|
290
294
|
]
|
|
291
295
|
}), N && /* @__PURE__ */ g("p", {
|
|
292
296
|
className: "mt-1.5 text-xs text-status-warning-text flex items-start gap-1.5",
|
|
293
|
-
children: [/* @__PURE__ */ h(a, { className: "
|
|
297
|
+
children: [/* @__PURE__ */ h(a, { className: "size-3.5 mt-0.5 flex-shrink-0" }), /* @__PURE__ */ h("span", { children: "Anyone with a URL minted while this is on can read live agent tunnel URLs and API keys. Only enable for trusted recipients." })]
|
|
294
298
|
})] }),
|
|
295
299
|
/* @__PURE__ */ g("div", { children: [
|
|
296
300
|
/* @__PURE__ */ h("label", {
|
|
301
|
+
htmlFor: "vibellmcontexttabpanel-43",
|
|
297
302
|
className: "block text-sm font-medium text-text-primary mb-2",
|
|
298
303
|
children: "Sections to include"
|
|
299
304
|
}),
|
|
@@ -317,9 +322,11 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
317
322
|
})
|
|
318
323
|
] }),
|
|
319
324
|
y.length > 0 && /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
|
|
325
|
+
htmlFor: "vibellmcontexttabpanel-43",
|
|
320
326
|
className: "block text-sm font-medium text-text-primary mb-2",
|
|
321
327
|
children: "Default agent for context fetch"
|
|
322
328
|
}), /* @__PURE__ */ g("select", {
|
|
329
|
+
id: "vibellmcontexttabpanel-43",
|
|
323
330
|
value: z,
|
|
324
331
|
onChange: (e) => B(e.target.value),
|
|
325
332
|
className: "w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary",
|
|
@@ -333,10 +340,13 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
333
340
|
})] }),
|
|
334
341
|
/* @__PURE__ */ g("div", { children: [
|
|
335
342
|
/* @__PURE__ */ h("label", {
|
|
343
|
+
htmlFor: "vibellmcontexttabpanel-42",
|
|
336
344
|
className: "block text-sm font-medium text-text-primary mb-2",
|
|
337
345
|
children: "Custom context text"
|
|
338
346
|
}),
|
|
339
347
|
/* @__PURE__ */ h("textarea", {
|
|
348
|
+
id: "vibellmcontexttabpanel-42",
|
|
349
|
+
"aria-label": "Free-form notes embedded in every snapshot you mint AFTER saving (existing tokens keep their original copy).",
|
|
340
350
|
value: L,
|
|
341
351
|
onChange: (e) => R(e.target.value.slice(0, 8192)),
|
|
342
352
|
rows: 5,
|
|
@@ -366,9 +376,12 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
366
376
|
/* @__PURE__ */ g("div", {
|
|
367
377
|
className: "flex-1 min-w-[200px]",
|
|
368
378
|
children: [/* @__PURE__ */ h("label", {
|
|
379
|
+
htmlFor: "vibellmcontexttabpanel-41",
|
|
369
380
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
370
381
|
children: "Label (optional)"
|
|
371
382
|
}), /* @__PURE__ */ h("input", {
|
|
383
|
+
id: "vibellmcontexttabpanel-41",
|
|
384
|
+
"aria-label": "e.g. Claude desktop",
|
|
372
385
|
type: "text",
|
|
373
386
|
value: V,
|
|
374
387
|
onChange: (e) => H(e.target.value.slice(0, 120)),
|
|
@@ -381,7 +394,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
381
394
|
onClick: Te,
|
|
382
395
|
disabled: $.loading,
|
|
383
396
|
className: "px-4 py-2 text-sm bg-bg-sunken text-text-primary border border-border-default rounded-md hover:bg-action-primary-bg-hover disabled:opacity-50 inline-flex items-center gap-1.5",
|
|
384
|
-
children: [/* @__PURE__ */ h(ne, { className: "
|
|
397
|
+
children: [/* @__PURE__ */ h(ne, { className: "size-4" }), $.loading ? "Loading…" : "Preview"]
|
|
385
398
|
}),
|
|
386
399
|
/* @__PURE__ */ h("button", {
|
|
387
400
|
type: "button",
|
|
@@ -409,7 +422,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
409
422
|
children: [/* @__PURE__ */ g("div", {
|
|
410
423
|
className: "flex items-center gap-2 text-sm mb-2",
|
|
411
424
|
children: [
|
|
412
|
-
/* @__PURE__ */ h(s, { className: "
|
|
425
|
+
/* @__PURE__ */ h(s, { className: "size-4 text-status-success-text" }),
|
|
413
426
|
/* @__PURE__ */ h("span", {
|
|
414
427
|
className: "font-medium text-text-primary",
|
|
415
428
|
children: "URL generated"
|
|
@@ -433,7 +446,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
433
446
|
},
|
|
434
447
|
className: "px-2 py-1.5 text-xs bg-bg-sunken border border-border-default rounded text-text-primary",
|
|
435
448
|
"aria-label": "Copy URL",
|
|
436
|
-
children: Se ? /* @__PURE__ */ h(s, { className: "
|
|
449
|
+
children: Se ? /* @__PURE__ */ h(s, { className: "size-4 text-status-success-text" }) : /* @__PURE__ */ h(te, { className: "size-4" })
|
|
437
450
|
})]
|
|
438
451
|
})]
|
|
439
452
|
})
|
|
@@ -457,16 +470,16 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
457
470
|
},
|
|
458
471
|
disabled: A.every((e) => e.status !== "ACTIVE"),
|
|
459
472
|
className: "flex items-center gap-1 px-3 py-1.5 text-sm bg-status-error-bg/10 text-status-error-text border border-status-error-border rounded-md hover:bg-status-error-bg/20 disabled:opacity-40 disabled:cursor-not-allowed",
|
|
460
|
-
children: [/* @__PURE__ */ h(u, { className: "
|
|
473
|
+
children: [/* @__PURE__ */ h(u, { className: "size-4" }), "Revoke all"]
|
|
461
474
|
})]
|
|
462
475
|
}),
|
|
463
476
|
C.loading && A.length === 0 && /* @__PURE__ */ g("div", {
|
|
464
477
|
className: "text-sm text-text-secondary py-4 flex items-center gap-2",
|
|
465
|
-
children: [/* @__PURE__ */ h(ae, { className: "
|
|
478
|
+
children: [/* @__PURE__ */ h(ae, { className: "size-4 animate-spin" }), "Loading tokens…"]
|
|
466
479
|
}),
|
|
467
480
|
A.length === 0 && !C.loading && /* @__PURE__ */ g("div", {
|
|
468
481
|
className: "text-sm text-text-secondary py-4 flex items-center gap-2",
|
|
469
|
-
children: [/* @__PURE__ */ h(c, { className: "
|
|
482
|
+
children: [/* @__PURE__ */ h(c, { className: "size-4" }), "No URLs minted yet for this vibe."]
|
|
470
483
|
}),
|
|
471
484
|
A.length > 0 && /* @__PURE__ */ h("div", {
|
|
472
485
|
className: "overflow-x-auto",
|
|
@@ -547,7 +560,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
547
560
|
className: "py-2 pr-3 text-xs text-text-secondary",
|
|
548
561
|
children: /* @__PURE__ */ g("span", {
|
|
549
562
|
className: "inline-flex items-center gap-1",
|
|
550
|
-
children: [/* @__PURE__ */ h(ee, { className: "
|
|
563
|
+
children: [/* @__PURE__ */ h(ee, { className: "size-3" }), x(e.expiresAt)]
|
|
551
564
|
})
|
|
552
565
|
}),
|
|
553
566
|
/* @__PURE__ */ h("td", {
|
|
@@ -564,7 +577,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
564
577
|
title: "Show fetch history",
|
|
565
578
|
"aria-label": "Show fetch history",
|
|
566
579
|
className: "p-1.5 text-text-secondary hover:text-text-primary",
|
|
567
|
-
children: /* @__PURE__ */ h(c, { className: "
|
|
580
|
+
children: /* @__PURE__ */ h(c, { className: "size-4" })
|
|
568
581
|
}), e.status === "ACTIVE" && /* @__PURE__ */ g(ce, { children: [/* @__PURE__ */ h("button", {
|
|
569
582
|
type: "button",
|
|
570
583
|
onClick: async () => {
|
|
@@ -574,14 +587,14 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
574
587
|
title: "Rotate (revoke + mint a new one with same settings)",
|
|
575
588
|
"aria-label": "Rotate URL",
|
|
576
589
|
className: "p-1.5 text-text-secondary hover:text-text-primary",
|
|
577
|
-
children: /* @__PURE__ */ h(l, { className: "
|
|
590
|
+
children: /* @__PURE__ */ h(l, { className: "size-4" })
|
|
578
591
|
}), /* @__PURE__ */ h("button", {
|
|
579
592
|
type: "button",
|
|
580
593
|
onClick: () => E({ variables: { tokenId: e.id } }),
|
|
581
594
|
title: "Revoke",
|
|
582
595
|
"aria-label": "Revoke URL",
|
|
583
596
|
className: "p-1.5 text-status-error-text hover:opacity-80",
|
|
584
|
-
children: /* @__PURE__ */ h(u, { className: "
|
|
597
|
+
children: /* @__PURE__ */ h(u, { className: "size-4" })
|
|
585
598
|
})] })]
|
|
586
599
|
})
|
|
587
600
|
})
|
|
@@ -599,7 +612,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
599
612
|
/* @__PURE__ */ g("p", {
|
|
600
613
|
className: "text-xs text-text-secondary flex items-center gap-1",
|
|
601
614
|
children: [
|
|
602
|
-
/* @__PURE__ */ h(o, { className: "
|
|
615
|
+
/* @__PURE__ */ h(o, { className: "size-3" }),
|
|
603
616
|
"Tip: pipe the URL to any LLM with",
|
|
604
617
|
" ",
|
|
605
618
|
/* @__PURE__ */ h("code", {
|
|
@@ -617,6 +630,10 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
617
630
|
]
|
|
618
631
|
}),
|
|
619
632
|
Y && /* @__PURE__ */ h("div", {
|
|
633
|
+
tabIndex: 0,
|
|
634
|
+
onKeyDown: (e) => {
|
|
635
|
+
e.key === "Escape" && (e.preventDefault(), X(!1));
|
|
636
|
+
},
|
|
620
637
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay p-4",
|
|
621
638
|
role: "dialog",
|
|
622
639
|
"aria-modal": "true",
|
|
@@ -655,7 +672,7 @@ function S({ vibeId: f, attachedAgents: y = [] }) {
|
|
|
655
672
|
onClick: () => X(!1),
|
|
656
673
|
"aria-label": "Close preview",
|
|
657
674
|
className: "text-text-secondary hover:text-text-primary",
|
|
658
|
-
children: /* @__PURE__ */ h(d, { className: "
|
|
675
|
+
children: /* @__PURE__ */ h(d, { className: "size-4" })
|
|
659
676
|
})
|
|
660
677
|
]
|
|
661
678
|
}), /* @__PURE__ */ h("div", {
|