@burdenoff/microfe-vibecontrols 2026.527.10 → 2026.527.12
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 +339 -301
- 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
|
@@ -43,6 +43,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
43
43
|
className: "flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0",
|
|
44
44
|
children: [
|
|
45
45
|
E && /* @__PURE__ */ h("button", {
|
|
46
|
+
type: "button",
|
|
46
47
|
onClick: (e) => {
|
|
47
48
|
e.stopPropagation(), v(_.id);
|
|
48
49
|
},
|
|
@@ -52,6 +53,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
52
53
|
children: /* @__PURE__ */ h(d, { size: 14 })
|
|
53
54
|
}),
|
|
54
55
|
w && /* @__PURE__ */ h("button", {
|
|
56
|
+
type: "button",
|
|
55
57
|
onClick: (e) => {
|
|
56
58
|
e.stopPropagation(), y(_.id);
|
|
57
59
|
},
|
|
@@ -60,6 +62,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
60
62
|
children: /* @__PURE__ */ h(u, { size: 14 })
|
|
61
63
|
}),
|
|
62
64
|
S && /* @__PURE__ */ h("button", {
|
|
65
|
+
type: "button",
|
|
63
66
|
onClick: (e) => {
|
|
64
67
|
e.stopPropagation(), S(_.id);
|
|
65
68
|
},
|
|
@@ -68,6 +71,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
68
71
|
children: /* @__PURE__ */ h(a, { size: 14 })
|
|
69
72
|
}),
|
|
70
73
|
C && /* @__PURE__ */ h("button", {
|
|
74
|
+
type: "button",
|
|
71
75
|
onClick: (e) => {
|
|
72
76
|
e.stopPropagation(), C(_.id);
|
|
73
77
|
},
|
|
@@ -76,6 +80,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
76
80
|
children: /* @__PURE__ */ h(o, { size: 14 })
|
|
77
81
|
}),
|
|
78
82
|
/* @__PURE__ */ h("button", {
|
|
83
|
+
type: "button",
|
|
79
84
|
onClick: (e) => {
|
|
80
85
|
e.stopPropagation(), b(_.id);
|
|
81
86
|
},
|
|
@@ -84,6 +89,7 @@ function _({ action: _, onExecute: v, onEdit: y, onDuplicate: b, onDelete: x, on
|
|
|
84
89
|
children: /* @__PURE__ */ h(c, { size: 14 })
|
|
85
90
|
}),
|
|
86
91
|
T && /* @__PURE__ */ h("button", {
|
|
92
|
+
type: "button",
|
|
87
93
|
onClick: (e) => {
|
|
88
94
|
e.stopPropagation(), x(_.id);
|
|
89
95
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionCard.js","names":[],"sources":["../../../src/components/actions/ActionCard.tsx"],"sourcesContent":["import { Play, Pencil, Copy, Trash2, Clock, Hash, CalendarClock, AlarmClock } from 'lucide-react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport { ActionTypeBadge, TriggerTypeBadge, SourceTypeBadge } from './ActionTypeBadge';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface ActionCardAction {\n id: string;\n name: string;\n displayName?: string | null;\n description?: string | null;\n actionType: string;\n sourceType?: string | null;\n triggerType: string;\n category?: string | null;\n tags?: string[] | null;\n executionCount?: number | null;\n lastExecutedAt?: string | null;\n confirmationRequired?: boolean;\n}\n\ninterface ActionCardProps {\n action: ActionCardAction;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDuplicate: (id: string) => void;\n onDelete: (id: string) => void;\n onSchedule?: (id: string) => void;\n onAddToCalendar?: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n isExecuting?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n}\n\nexport function ActionCard({\n action,\n onExecute,\n onEdit,\n onDuplicate,\n onDelete,\n onSchedule,\n onAddToCalendar,\n canUpdate,\n canDelete,\n canExecute,\n isExecuting = false,\n selected = false,\n onToggleSelect,\n}: ActionCardProps) {\n const shouldReduceMotion = useReducedMotion();\n const tr = useTr();\n\n const formatDate = (dateStr: string | null | undefined) => {\n if (!dateStr) return tr('vibecontrols.actions.card.never', 'Never');\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 1) return tr('vibecontrols.actions.card.justNow', 'Just now');\n if (diffMin < 60)\n return tr('vibecontrols.actions.card.minutesAgo', '{{count}}m ago', { count: diffMin });\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24)\n return tr('vibecontrols.actions.card.hoursAgo', '{{count}}h ago', { count: diffHr });\n const diffDays = Math.floor(diffHr / 24);\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n };\n\n return (\n <motion.div\n className={`bg-bg-surface border rounded-lg p-4 hover:border-border-strong transition-colors group ${\n selected\n ? 'border-action-primary-bg ring-1 ring-action-primary-bg/25'\n : 'border-border-default'\n }`}\n whileHover={\n shouldReduceMotion\n ? undefined\n : { y: -2, boxShadow: '0 4px 12px var(--color-border-default)' }\n }\n transition={{ duration: 0.15 }}\n layout\n role=\"group\"\n aria-label={`Action: ${action.displayName || action.name}`}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between gap-3 mb-3\">\n <div className=\"flex items-start gap-3 min-w-0 flex-1\">\n {onToggleSelect && (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select action ${action.displayName || action.name}`}\n />\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold text-text-primary truncate\">\n {action.displayName || action.name}\n </h3>\n {action.description && (\n <p className=\"text-sm text-text-secondary mt-0.5 line-clamp-2\">\n {action.description}\n </p>\n )}\n </div>\n </div>\n {/* Action buttons */}\n <div className=\"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\">\n {canExecute && (\n <button\n onClick={(event) => {\n event.stopPropagation();\n onExecute(action.id);\n }}\n disabled={isExecuting}\n className=\"p-1.5 rounded-md hover:bg-status-success-bg/20 text-status-success-text transition-colors disabled:opacity-50\"\n title={tr('vibecontrols.actions.card.execute', 'Execute')}\n >\n <Play size={14} />\n </button>\n )}\n {canUpdate && (\n <button\n onClick={(event) => {\n event.stopPropagation();\n onEdit(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.edit', 'Edit')}\n >\n <Pencil size={14} />\n </button>\n )}\n {onSchedule && (\n <button\n onClick={(event) => {\n event.stopPropagation();\n onSchedule(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.schedule', 'Schedule this action')}\n >\n <AlarmClock size={14} />\n </button>\n )}\n {onAddToCalendar && (\n <button\n onClick={(event) => {\n event.stopPropagation();\n onAddToCalendar(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.addToCalendar', 'Add to calendar')}\n >\n <CalendarClock size={14} />\n </button>\n )}\n <button\n onClick={(event) => {\n event.stopPropagation();\n onDuplicate(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.duplicate', 'Duplicate')}\n >\n <Copy size={14} />\n </button>\n {canDelete && (\n <button\n onClick={(event) => {\n event.stopPropagation();\n onDelete(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-status-error-bg/20 text-status-error-text transition-colors\"\n title={tr('vibecontrols.actions.card.delete', 'Delete')}\n >\n <Trash2 size={14} />\n </button>\n )}\n </div>\n </div>\n\n {/* Badges */}\n <div className=\"flex flex-wrap items-center gap-1.5 mb-3\">\n <ActionTypeBadge type={action.actionType} />\n <TriggerTypeBadge type={action.triggerType} />\n {action.sourceType && <SourceTypeBadge type={action.sourceType} />}\n </div>\n\n {/* Category and Tags */}\n {(action.category || (action.tags && action.tags.length > 0)) && (\n <div className=\"flex flex-wrap items-center gap-1.5 mb-3\">\n {action.category && (\n <span className=\"text-xs px-1.5 py-0.5 rounded bg-bg-sunken text-text-secondary\">\n {action.category}\n </span>\n )}\n {action.tags?.map((tag) => (\n <span\n key={tag}\n className=\"text-xs px-1.5 py-0.5 rounded bg-bg-sunken text-text-placeholder\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Stats */}\n <div className=\"flex items-center gap-4 text-xs text-text-placeholder\">\n <span className=\"inline-flex items-center gap-1\">\n <Hash size={12} />\n {tr('vibecontrols.actions.card.executionRuns', '{{count}} runs', {\n count: action.executionCount ?? 0,\n })}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Clock size={12} />\n {formatDate(action.lastExecutedAt)}\n </span>\n </div>\n </motion.div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionCard.js","names":[],"sources":["../../../src/components/actions/ActionCard.tsx"],"sourcesContent":["import { Play, Pencil, Copy, Trash2, Clock, Hash, CalendarClock, AlarmClock } from 'lucide-react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport { ActionTypeBadge, TriggerTypeBadge, SourceTypeBadge } from './ActionTypeBadge';\nimport { SelectionCheckbox } from '../shared/SelectionCheckbox';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface ActionCardAction {\n id: string;\n name: string;\n displayName?: string | null;\n description?: string | null;\n actionType: string;\n sourceType?: string | null;\n triggerType: string;\n category?: string | null;\n tags?: string[] | null;\n executionCount?: number | null;\n lastExecutedAt?: string | null;\n confirmationRequired?: boolean;\n}\n\ninterface ActionCardProps {\n action: ActionCardAction;\n onExecute: (id: string) => void;\n onEdit: (id: string) => void;\n onDuplicate: (id: string) => void;\n onDelete: (id: string) => void;\n onSchedule?: (id: string) => void;\n onAddToCalendar?: (id: string) => void;\n canUpdate: boolean;\n canDelete: boolean;\n canExecute: boolean;\n isExecuting?: boolean;\n selected?: boolean;\n onToggleSelect?: (checked: boolean) => void;\n}\n\nexport function ActionCard({\n action,\n onExecute,\n onEdit,\n onDuplicate,\n onDelete,\n onSchedule,\n onAddToCalendar,\n canUpdate,\n canDelete,\n canExecute,\n isExecuting = false,\n selected = false,\n onToggleSelect,\n}: ActionCardProps) {\n const shouldReduceMotion = useReducedMotion();\n const tr = useTr();\n\n const formatDate = (dateStr: string | null | undefined) => {\n if (!dateStr) return tr('vibecontrols.actions.card.never', 'Never');\n const date = new Date(dateStr);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 1) return tr('vibecontrols.actions.card.justNow', 'Just now');\n if (diffMin < 60)\n return tr('vibecontrols.actions.card.minutesAgo', '{{count}}m ago', { count: diffMin });\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24)\n return tr('vibecontrols.actions.card.hoursAgo', '{{count}}h ago', { count: diffHr });\n const diffDays = Math.floor(diffHr / 24);\n if (diffDays < 7) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n };\n\n return (\n <motion.div\n className={`bg-bg-surface border rounded-lg p-4 hover:border-border-strong transition-colors group ${\n selected\n ? 'border-action-primary-bg ring-1 ring-action-primary-bg/25'\n : 'border-border-default'\n }`}\n whileHover={\n shouldReduceMotion\n ? undefined\n : { y: -2, boxShadow: '0 4px 12px var(--color-border-default)' }\n }\n transition={{ duration: 0.15 }}\n layout\n role=\"group\"\n aria-label={`Action: ${action.displayName || action.name}`}\n >\n {/* Header */}\n <div className=\"flex items-start justify-between gap-3 mb-3\">\n <div className=\"flex items-start gap-3 min-w-0 flex-1\">\n {onToggleSelect && (\n <div onClick={(event) => event.stopPropagation()}>\n <SelectionCheckbox\n checked={selected}\n onChange={onToggleSelect}\n ariaLabel={`Select action ${action.displayName || action.name}`}\n />\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"font-semibold text-text-primary truncate\">\n {action.displayName || action.name}\n </h3>\n {action.description && (\n <p className=\"text-sm text-text-secondary mt-0.5 line-clamp-2\">\n {action.description}\n </p>\n )}\n </div>\n </div>\n {/* Action buttons */}\n <div className=\"flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\">\n {canExecute && (\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onExecute(action.id);\n }}\n disabled={isExecuting}\n className=\"p-1.5 rounded-md hover:bg-status-success-bg/20 text-status-success-text transition-colors disabled:opacity-50\"\n title={tr('vibecontrols.actions.card.execute', 'Execute')}\n >\n <Play size={14} />\n </button>\n )}\n {canUpdate && (\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onEdit(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.edit', 'Edit')}\n >\n <Pencil size={14} />\n </button>\n )}\n {onSchedule && (\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onSchedule(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.schedule', 'Schedule this action')}\n >\n <AlarmClock size={14} />\n </button>\n )}\n {onAddToCalendar && (\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onAddToCalendar(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.addToCalendar', 'Add to calendar')}\n >\n <CalendarClock size={14} />\n </button>\n )}\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onDuplicate(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-bg-elevated text-text-secondary transition-colors\"\n title={tr('vibecontrols.actions.card.duplicate', 'Duplicate')}\n >\n <Copy size={14} />\n </button>\n {canDelete && (\n <button type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n onDelete(action.id);\n }}\n className=\"p-1.5 rounded-md hover:bg-status-error-bg/20 text-status-error-text transition-colors\"\n title={tr('vibecontrols.actions.card.delete', 'Delete')}\n >\n <Trash2 size={14} />\n </button>\n )}\n </div>\n </div>\n\n {/* Badges */}\n <div className=\"flex flex-wrap items-center gap-1.5 mb-3\">\n <ActionTypeBadge type={action.actionType} />\n <TriggerTypeBadge type={action.triggerType} />\n {action.sourceType && <SourceTypeBadge type={action.sourceType} />}\n </div>\n\n {/* Category and Tags */}\n {(action.category || (action.tags && action.tags.length > 0)) && (\n <div className=\"flex flex-wrap items-center gap-1.5 mb-3\">\n {action.category && (\n <span className=\"text-xs px-1.5 py-0.5 rounded bg-bg-sunken text-text-secondary\">\n {action.category}\n </span>\n )}\n {action.tags?.map((tag) => (\n <span\n key={tag}\n className=\"text-xs px-1.5 py-0.5 rounded bg-bg-sunken text-text-placeholder\"\n >\n #{tag}\n </span>\n ))}\n </div>\n )}\n\n {/* Stats */}\n <div className=\"flex items-center gap-4 text-xs text-text-placeholder\">\n <span className=\"inline-flex items-center gap-1\">\n <Hash size={12} />\n {tr('vibecontrols.actions.card.executionRuns', '{{count}} runs', {\n count: action.executionCount ?? 0,\n })}\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Clock size={12} />\n {formatDate(action.lastExecutedAt)}\n </span>\n </div>\n </motion.div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -89,9 +89,10 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
89
89
|
className: "text-lg font-semibold text-text-primary",
|
|
90
90
|
children: d
|
|
91
91
|
}), /* @__PURE__ */ c("button", {
|
|
92
|
+
type: "button",
|
|
92
93
|
onClick: h,
|
|
93
94
|
className: "p-1 rounded hover:bg-bg-sunken transition-colors",
|
|
94
|
-
children: /* @__PURE__ */ c(i, { className: "
|
|
95
|
+
children: /* @__PURE__ */ c(i, { className: "size-5 text-text-secondary" })
|
|
95
96
|
})]
|
|
96
97
|
}), /* @__PURE__ */ l("form", {
|
|
97
98
|
onSubmit: E,
|
|
@@ -103,6 +104,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
103
104
|
className: O,
|
|
104
105
|
children: w("vibecontrols.actions.form.nameSlug", "Name (slug)")
|
|
105
106
|
}), /* @__PURE__ */ c("input", {
|
|
107
|
+
"aria-label": "my-action",
|
|
106
108
|
className: D,
|
|
107
109
|
value: v.name,
|
|
108
110
|
onChange: (e) => T("name", e.target.value),
|
|
@@ -112,6 +114,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
112
114
|
className: O,
|
|
113
115
|
children: w("vibecontrols.actions.form.displayName", "Display Name")
|
|
114
116
|
}), /* @__PURE__ */ c("input", {
|
|
117
|
+
"aria-label": "My Action",
|
|
115
118
|
className: D,
|
|
116
119
|
value: v.displayName,
|
|
117
120
|
onChange: (e) => T("displayName", e.target.value),
|
|
@@ -123,6 +126,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
123
126
|
className: O,
|
|
124
127
|
children: w("vibecontrols.actions.form.description", "Description")
|
|
125
128
|
}), /* @__PURE__ */ c("textarea", {
|
|
129
|
+
"aria-label": "What does this action do?",
|
|
126
130
|
className: `${D} resize-none`,
|
|
127
131
|
rows: 2,
|
|
128
132
|
value: v.description,
|
|
@@ -187,6 +191,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
187
191
|
className: O,
|
|
188
192
|
children: w("vibecontrols.actions.form.schedule", "Schedule (cron expression)")
|
|
189
193
|
}), /* @__PURE__ */ c("input", {
|
|
194
|
+
"aria-label": "*/5 * * * *",
|
|
190
195
|
className: D,
|
|
191
196
|
value: v.schedule,
|
|
192
197
|
onChange: (e) => T("schedule", e.target.value),
|
|
@@ -198,6 +203,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
198
203
|
className: O,
|
|
199
204
|
children: w("vibecontrols.actions.form.category", "Category")
|
|
200
205
|
}), /* @__PURE__ */ c("input", {
|
|
206
|
+
"aria-label": "deployment, testing, etc.",
|
|
201
207
|
className: D,
|
|
202
208
|
value: v.category,
|
|
203
209
|
onChange: (e) => T("category", e.target.value),
|
|
@@ -206,6 +212,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
206
212
|
className: O,
|
|
207
213
|
children: w("vibecontrols.actions.form.tags", "Tags (comma separated)")
|
|
208
214
|
}), /* @__PURE__ */ c("input", {
|
|
215
|
+
"aria-label": "ci, deploy, infra",
|
|
209
216
|
className: D,
|
|
210
217
|
value: b,
|
|
211
218
|
onChange: (e) => x(e.target.value),
|
|
@@ -223,6 +230,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
223
230
|
className: O,
|
|
224
231
|
children: w("vibecontrols.actions.form.command", "Command")
|
|
225
232
|
}), /* @__PURE__ */ c("textarea", {
|
|
233
|
+
"aria-label": "echo 'Hello World'",
|
|
226
234
|
className: `${D} font-mono resize-none`,
|
|
227
235
|
rows: 3,
|
|
228
236
|
value: v.command,
|
|
@@ -236,6 +244,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
236
244
|
className: O,
|
|
237
245
|
children: w("vibecontrols.actions.form.workingDirectory", "Working Directory")
|
|
238
246
|
}), /* @__PURE__ */ c("input", {
|
|
247
|
+
"aria-label": "/home/user/project",
|
|
239
248
|
className: D,
|
|
240
249
|
value: v.workingDirectory,
|
|
241
250
|
onChange: (e) => T("workingDirectory", e.target.value),
|
|
@@ -274,6 +283,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
274
283
|
className: O,
|
|
275
284
|
children: w("vibecontrols.actions.form.script", "Script")
|
|
276
285
|
}), /* @__PURE__ */ c("textarea", {
|
|
286
|
+
"aria-label": "#!/bin/bash\necho 'Hello'",
|
|
277
287
|
className: `${D} font-mono resize-none`,
|
|
278
288
|
rows: 6,
|
|
279
289
|
value: v.script,
|
|
@@ -329,6 +339,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
329
339
|
className: O,
|
|
330
340
|
children: w("vibecontrols.actions.form.workingDirectory", "Working Directory")
|
|
331
341
|
}), /* @__PURE__ */ c("input", {
|
|
342
|
+
"aria-label": "/home/user/project",
|
|
332
343
|
className: D,
|
|
333
344
|
value: v.workingDirectory,
|
|
334
345
|
onChange: (e) => T("workingDirectory", e.target.value),
|
|
@@ -349,6 +360,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
349
360
|
className: O,
|
|
350
361
|
children: w("vibecontrols.actions.form.url", "URL")
|
|
351
362
|
}), /* @__PURE__ */ c("input", {
|
|
363
|
+
"aria-label": "https://api.example.com/hook",
|
|
352
364
|
className: D,
|
|
353
365
|
value: v.webhookUrl,
|
|
354
366
|
onChange: (e) => T("webhookUrl", e.target.value),
|
|
@@ -389,6 +401,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
389
401
|
className: O,
|
|
390
402
|
children: w("vibecontrols.actions.form.bodyJson", "Body (JSON)")
|
|
391
403
|
}), /* @__PURE__ */ c("textarea", {
|
|
404
|
+
"aria-label": "control",
|
|
392
405
|
className: `${D} font-mono resize-none`,
|
|
393
406
|
rows: 4,
|
|
394
407
|
value: v.webhookBody,
|
|
@@ -430,6 +443,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
430
443
|
className: O,
|
|
431
444
|
children: w("vibecontrols.actions.form.timeout", "Timeout (ms)")
|
|
432
445
|
}), /* @__PURE__ */ c("input", {
|
|
446
|
+
"aria-label": "control",
|
|
433
447
|
className: D,
|
|
434
448
|
type: "number",
|
|
435
449
|
min: 1e3,
|
|
@@ -441,6 +455,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
441
455
|
className: O,
|
|
442
456
|
children: w("vibecontrols.actions.form.retryCount", "Retry Count")
|
|
443
457
|
}), /* @__PURE__ */ c("input", {
|
|
458
|
+
"aria-label": "control",
|
|
444
459
|
className: D,
|
|
445
460
|
type: "number",
|
|
446
461
|
min: 0,
|
|
@@ -453,6 +468,7 @@ function d({ title: d, initialData: f, agents: p, onSubmit: m, onCancel: h, isLo
|
|
|
453
468
|
children: /* @__PURE__ */ l("label", {
|
|
454
469
|
className: "flex items-center gap-2 text-sm text-text-secondary cursor-pointer",
|
|
455
470
|
children: [/* @__PURE__ */ c("input", {
|
|
471
|
+
"aria-label": "control",
|
|
456
472
|
type: "checkbox",
|
|
457
473
|
checked: v.confirmationRequired,
|
|
458
474
|
onChange: (e) => T("confirmationRequired", e.target.checked),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionForm.js","names":[],"sources":["../../../src/components/actions/ActionForm.tsx"],"sourcesContent":["import { useState, useEffect, useRef, type ReactNode } from 'react';\nimport { X } from 'lucide-react';\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion';\nimport { useTr } from '../../shared/hooks/useTr';\n\nexport interface ActionFormData {\n name: string;\n displayName: string;\n description: string;\n actionType: string;\n triggerType: string;\n schedule: string;\n category: string;\n tags: string[];\n command: string;\n workingDirectory: string;\n targetAgentId: string;\n environmentVariables: Record<string, string>;\n script: string;\n scriptInterpreter: string;\n webhookUrl: string;\n webhookMethod: string;\n webhookHeaders: Record<string, string>;\n webhookBody: string;\n webhookAuthType: string;\n timeoutMs: number;\n retryCount: number;\n confirmationRequired: boolean;\n}\n\nconst DEFAULT_FORM: ActionFormData = {\n name: '',\n displayName: '',\n description: '',\n actionType: 'COMMAND',\n triggerType: 'MANUAL',\n schedule: '',\n category: '',\n tags: [],\n command: '',\n workingDirectory: '',\n targetAgentId: '',\n environmentVariables: {},\n script: '',\n scriptInterpreter: 'bash',\n webhookUrl: '',\n webhookMethod: 'POST',\n webhookHeaders: {},\n webhookBody: '',\n webhookAuthType: '',\n timeoutMs: 30000,\n retryCount: 0,\n confirmationRequired: false,\n};\n\ninterface ActionFormProps {\n title: string;\n initialData?: Partial<ActionFormData>;\n agents: Array<{ id: string; name: string; isActive: boolean }>;\n onSubmit: (data: ActionFormData) => void;\n onCancel: () => void;\n isLoading?: boolean;\n /** Optional extra content rendered below the form fields (e.g. tag picker in edit mode) */\n extraSection?: ReactNode;\n}\n\nexport function ActionForm({\n title,\n initialData,\n agents,\n onSubmit,\n onCancel,\n isLoading = false,\n extraSection,\n}: ActionFormProps) {\n const [form, setForm] = useState<ActionFormData>({ ...DEFAULT_FORM, ...initialData });\n const [tagsInput, setTagsInput] = useState(initialData?.tags?.join(', ') ?? '');\n const dialogRef = useRef<HTMLDialogElement>(null);\n const shouldReduceMotion = useReducedMotion();\n const tr = useTr();\n\n useEffect(() => {\n dialogRef.current?.showModal();\n }, []);\n\n const update = <K extends keyof ActionFormData>(key: K, value: ActionFormData[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const tags = tagsInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n onSubmit({ ...form, tags });\n };\n\n const inputClass =\n 'w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg focus:border-transparent transition-all';\n const labelClass = 'block text-sm font-medium text-text-secondary mb-1';\n\n return (\n <dialog\n ref={dialogRef}\n className=\"fixed inset-0 z-50 m-auto p-0 bg-transparent backdrop:bg-transparent\"\n onClose={onCancel}\n >\n <AnimatePresence>\n <motion.div\n className=\"fixed inset-0 bg-bg-overlay\"\n initial={shouldReduceMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={onCancel}\n />\n <motion.div\n className=\"relative w-full max-w-2xl max-h-[85vh] overflow-y-auto bg-bg-surface rounded-lg shadow-xl\"\n initial={shouldReduceMotion ? undefined : { opacity: 0, scale: 0.95, y: 8 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 8 }}\n transition={{ duration: 0.2, ease: [0.2, 0, 0, 1] }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-6 border-b border-border-default sticky top-0 bg-bg-surface z-10\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n <button onClick={onCancel} className=\"p-1 rounded hover:bg-bg-sunken transition-colors\">\n <X className=\"w-5 h-5 text-text-secondary\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-6 space-y-4\">\n {/* Basic fields */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.nameSlug', 'Name (slug)')}\n </label>\n <input\n className={inputClass}\n value={form.name}\n onChange={(e) => update('name', e.target.value)}\n placeholder=\"my-action\"\n required\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.displayName', 'Display Name')}\n </label>\n <input\n className={inputClass}\n value={form.displayName}\n onChange={(e) => update('displayName', e.target.value)}\n placeholder=\"My Action\"\n required\n />\n </div>\n </div>\n\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.description', 'Description')}\n </label>\n <textarea\n className={`${inputClass} resize-none`}\n rows={2}\n value={form.description}\n onChange={(e) => update('description', e.target.value)}\n placeholder=\"What does this action do?\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.actionType', 'Action Type')}\n </label>\n <select\n className={inputClass}\n value={form.actionType}\n onChange={(e) => update('actionType', e.target.value)}\n >\n <option value=\"COMMAND\">Command</option>\n <option value=\"SCRIPT\">Script</option>\n <option value=\"WEBHOOK\">Webhook</option>\n <option value=\"WORKFLOW\">Workflow</option>\n </select>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.triggerType', 'Trigger Type')}\n </label>\n <select\n className={inputClass}\n value={form.triggerType}\n onChange={(e) => update('triggerType', e.target.value)}\n >\n <option value=\"MANUAL\">Manual</option>\n <option value=\"SCHEDULED\">Scheduled</option>\n <option value=\"EVENT\">Event</option>\n <option value=\"ON_DEMAND\">On Demand</option>\n </select>\n </div>\n </div>\n\n {form.triggerType === 'SCHEDULED' && (\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.schedule', 'Schedule (cron expression)')}\n </label>\n <input\n className={inputClass}\n value={form.schedule}\n onChange={(e) => update('schedule', e.target.value)}\n placeholder=\"*/5 * * * *\"\n />\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.category', 'Category')}\n </label>\n <input\n className={inputClass}\n value={form.category}\n onChange={(e) => update('category', e.target.value)}\n placeholder=\"deployment, testing, etc.\"\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.tags', 'Tags (comma separated)')}\n </label>\n <input\n className={inputClass}\n value={tagsInput}\n onChange={(e) => setTagsInput(e.target.value)}\n placeholder=\"ci, deploy, infra\"\n />\n </div>\n </div>\n\n {/* Type-specific fields */}\n {form.actionType === 'COMMAND' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.commandSettings', 'Command Settings')}\n </h3>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.command', 'Command')}\n </label>\n <textarea\n className={`${inputClass} font-mono resize-none`}\n rows={3}\n value={form.command}\n onChange={(e) => update('command', e.target.value)}\n placeholder=\"echo 'Hello World'\"\n required\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.workingDirectory', 'Working Directory')}\n </label>\n <input\n className={inputClass}\n value={form.workingDirectory}\n onChange={(e) => update('workingDirectory', e.target.value)}\n placeholder=\"/home/user/project\"\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.targetAgent', 'Target Agent')}\n </label>\n <select\n className={inputClass}\n value={form.targetAgentId}\n onChange={(e) => update('targetAgentId', e.target.value)}\n >\n <option value=\"\">\n {tr('vibecontrols.actions.form.anyAvailableAgent', 'Any available agent')}\n </option>\n {agents.map((a) => (\n <option key={a.id} value={a.id} disabled={!a.isActive}>\n {a.name}{' '}\n {!a.isActive ? tr('vibecontrols.actions.form.offline', '(offline)') : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {form.actionType === 'SCRIPT' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.scriptSettings', 'Script Settings')}\n </h3>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.script', 'Script')}\n </label>\n <textarea\n className={`${inputClass} font-mono resize-none`}\n rows={6}\n value={form.script}\n onChange={(e) => update('script', e.target.value)}\n placeholder=\"#!/bin/bash echo 'Hello'\"\n required\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.interpreter', 'Interpreter')}\n </label>\n <select\n className={inputClass}\n value={form.scriptInterpreter}\n onChange={(e) => update('scriptInterpreter', e.target.value)}\n >\n <option value=\"bash\">Bash</option>\n <option value=\"python\">Python</option>\n <option value=\"node\">Node.js</option>\n </select>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.targetAgent', 'Target Agent')}\n </label>\n <select\n className={inputClass}\n value={form.targetAgentId}\n onChange={(e) => update('targetAgentId', e.target.value)}\n >\n <option value=\"\">\n {tr('vibecontrols.actions.form.anyAvailableAgent', 'Any available agent')}\n </option>\n {agents.map((a) => (\n <option key={a.id} value={a.id} disabled={!a.isActive}>\n {a.name}{' '}\n {!a.isActive ? tr('vibecontrols.actions.form.offline', '(offline)') : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.workingDirectory', 'Working Directory')}\n </label>\n <input\n className={inputClass}\n value={form.workingDirectory}\n onChange={(e) => update('workingDirectory', e.target.value)}\n placeholder=\"/home/user/project\"\n />\n </div>\n </div>\n )}\n\n {form.actionType === 'WEBHOOK' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.webhookSettings', 'Webhook Settings')}\n </h3>\n <div className=\"grid grid-cols-[1fr_auto] gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.url', 'URL')}\n </label>\n <input\n className={inputClass}\n value={form.webhookUrl}\n onChange={(e) => update('webhookUrl', e.target.value)}\n placeholder=\"https://api.example.com/hook\"\n required\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.method', 'Method')}\n </label>\n <select\n className={inputClass}\n value={form.webhookMethod}\n onChange={(e) => update('webhookMethod', e.target.value)}\n >\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"PATCH\">PATCH</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.bodyJson', 'Body (JSON)')}\n </label>\n <textarea\n className={`${inputClass} font-mono resize-none`}\n rows={4}\n value={form.webhookBody}\n onChange={(e) => update('webhookBody', e.target.value)}\n placeholder='{\"key\": \"value\"}'\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.authType', 'Auth Type')}\n </label>\n <select\n className={inputClass}\n value={form.webhookAuthType}\n onChange={(e) => update('webhookAuthType', e.target.value)}\n >\n <option value=\"\">None</option>\n <option value=\"BEARER\">Bearer Token</option>\n <option value=\"BASIC\">Basic Auth</option>\n <option value=\"API_KEY\">API Key</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Options */}\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.timeout', 'Timeout (ms)')}\n </label>\n <input\n className={inputClass}\n type=\"number\"\n min={1000}\n max={300000}\n value={form.timeoutMs}\n onChange={(e) => update('timeoutMs', parseInt(e.target.value) || 30000)}\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.retryCount', 'Retry Count')}\n </label>\n <input\n className={inputClass}\n type=\"number\"\n min={0}\n max={10}\n value={form.retryCount}\n onChange={(e) => update('retryCount', parseInt(e.target.value) || 0)}\n />\n </div>\n <div className=\"flex items-end pb-2\">\n <label className=\"flex items-center gap-2 text-sm text-text-secondary cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.confirmationRequired}\n onChange={(e) => update('confirmationRequired', e.target.checked)}\n className=\"rounded border-border-default\"\n />\n {tr('vibecontrols.actions.form.requireConfirmation', 'Require confirmation')}\n </label>\n </div>\n </div>\n\n {extraSection && (\n <div className=\"pt-4 border-t border-border-default\">{extraSection}</div>\n )}\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={isLoading}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-elevated transition-colors disabled:opacity-50\"\n >\n {tr('vibecontrols.actions.form.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"px-4 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {isLoading\n ? tr('vibecontrols.actions.form.saving', 'Saving...')\n : initialData\n ? tr('vibecontrols.actions.form.updateAction', 'Update Action')\n : tr('vibecontrols.actions.form.createAction', 'Create Action')}\n </button>\n </div>\n </form>\n </motion.div>\n </AnimatePresence>\n </dialog>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionForm.js","names":[],"sources":["../../../src/components/actions/ActionForm.tsx"],"sourcesContent":["import { useState, useEffect, useRef, type ReactNode } from 'react';\nimport { X } from 'lucide-react';\nimport { motion, AnimatePresence, useReducedMotion } from 'framer-motion';\nimport { useTr } from '../../shared/hooks/useTr';\n\nexport interface ActionFormData {\n name: string;\n displayName: string;\n description: string;\n actionType: string;\n triggerType: string;\n schedule: string;\n category: string;\n tags: string[];\n command: string;\n workingDirectory: string;\n targetAgentId: string;\n environmentVariables: Record<string, string>;\n script: string;\n scriptInterpreter: string;\n webhookUrl: string;\n webhookMethod: string;\n webhookHeaders: Record<string, string>;\n webhookBody: string;\n webhookAuthType: string;\n timeoutMs: number;\n retryCount: number;\n confirmationRequired: boolean;\n}\n\nconst DEFAULT_FORM: ActionFormData = {\n name: '',\n displayName: '',\n description: '',\n actionType: 'COMMAND',\n triggerType: 'MANUAL',\n schedule: '',\n category: '',\n tags: [],\n command: '',\n workingDirectory: '',\n targetAgentId: '',\n environmentVariables: {},\n script: '',\n scriptInterpreter: 'bash',\n webhookUrl: '',\n webhookMethod: 'POST',\n webhookHeaders: {},\n webhookBody: '',\n webhookAuthType: '',\n timeoutMs: 30000,\n retryCount: 0,\n confirmationRequired: false,\n};\n\ninterface ActionFormProps {\n title: string;\n initialData?: Partial<ActionFormData>;\n agents: Array<{ id: string; name: string; isActive: boolean }>;\n onSubmit: (data: ActionFormData) => void;\n onCancel: () => void;\n isLoading?: boolean;\n /** Optional extra content rendered below the form fields (e.g. tag picker in edit mode) */\n extraSection?: ReactNode;\n}\n\nexport function ActionForm({\n title,\n initialData,\n agents,\n onSubmit,\n onCancel,\n isLoading = false,\n extraSection,\n}: ActionFormProps) {\n const [form, setForm] = useState<ActionFormData>({ ...DEFAULT_FORM, ...initialData });\n const [tagsInput, setTagsInput] = useState(initialData?.tags?.join(', ') ?? '');\n const dialogRef = useRef<HTMLDialogElement>(null);\n const shouldReduceMotion = useReducedMotion();\n const tr = useTr();\n\n useEffect(() => {\n dialogRef.current?.showModal();\n }, []);\n\n const update = <K extends keyof ActionFormData>(key: K, value: ActionFormData[K]) =>\n setForm((prev) => ({ ...prev, [key]: value }));\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n const tags = tagsInput\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean);\n onSubmit({ ...form, tags });\n };\n\n const inputClass =\n 'w-full px-3 py-2 text-sm bg-bg-sunken border border-border-default rounded-md text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-action-primary-bg focus:border-transparent transition-all';\n const labelClass = 'block text-sm font-medium text-text-secondary mb-1';\n\n return (\n <dialog\n ref={dialogRef}\n className=\"fixed inset-0 z-50 m-auto p-0 bg-transparent backdrop:bg-transparent\"\n onClose={onCancel}\n >\n <AnimatePresence>\n <motion.div\n className=\"fixed inset-0 bg-bg-overlay\"\n initial={shouldReduceMotion ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={onCancel}\n />\n <motion.div\n className=\"relative w-full max-w-2xl max-h-[85vh] overflow-y-auto bg-bg-surface rounded-lg shadow-xl\"\n initial={shouldReduceMotion ? undefined : { opacity: 0, scale: 0.95, y: 8 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 8 }}\n transition={{ duration: 0.2, ease: [0.2, 0, 0, 1] }}\n >\n {/* Header */}\n <div className=\"flex items-center justify-between p-6 border-b border-border-default sticky top-0 bg-bg-surface z-10\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{title}</h2>\n <button type=\"button\" onClick={onCancel} className=\"p-1 rounded hover:bg-bg-sunken transition-colors\">\n <X className=\"size-5 text-text-secondary\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-6 space-y-4\">\n {/* Basic fields */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.nameSlug', 'Name (slug)')}\n </label>\n <input aria-label=\"my-action\"\n className={inputClass}\n value={form.name}\n onChange={(e) => update('name', e.target.value)}\n placeholder=\"my-action\"\n required\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.displayName', 'Display Name')}\n </label>\n <input aria-label=\"My Action\"\n className={inputClass}\n value={form.displayName}\n onChange={(e) => update('displayName', e.target.value)}\n placeholder=\"My Action\"\n required\n />\n </div>\n </div>\n\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.description', 'Description')}\n </label>\n <textarea aria-label=\"What does this action do?\"\n className={`${inputClass} resize-none`}\n rows={2}\n value={form.description}\n onChange={(e) => update('description', e.target.value)}\n placeholder=\"What does this action do?\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.actionType', 'Action Type')}\n </label>\n <select\n className={inputClass}\n value={form.actionType}\n onChange={(e) => update('actionType', e.target.value)}\n >\n <option value=\"COMMAND\">Command</option>\n <option value=\"SCRIPT\">Script</option>\n <option value=\"WEBHOOK\">Webhook</option>\n <option value=\"WORKFLOW\">Workflow</option>\n </select>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.triggerType', 'Trigger Type')}\n </label>\n <select\n className={inputClass}\n value={form.triggerType}\n onChange={(e) => update('triggerType', e.target.value)}\n >\n <option value=\"MANUAL\">Manual</option>\n <option value=\"SCHEDULED\">Scheduled</option>\n <option value=\"EVENT\">Event</option>\n <option value=\"ON_DEMAND\">On Demand</option>\n </select>\n </div>\n </div>\n\n {form.triggerType === 'SCHEDULED' && (\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.schedule', 'Schedule (cron expression)')}\n </label>\n <input aria-label=\"*/5 * * * *\"\n className={inputClass}\n value={form.schedule}\n onChange={(e) => update('schedule', e.target.value)}\n placeholder=\"*/5 * * * *\"\n />\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.category', 'Category')}\n </label>\n <input aria-label=\"deployment, testing, etc.\"\n className={inputClass}\n value={form.category}\n onChange={(e) => update('category', e.target.value)}\n placeholder=\"deployment, testing, etc.\"\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.tags', 'Tags (comma separated)')}\n </label>\n <input aria-label=\"ci, deploy, infra\"\n className={inputClass}\n value={tagsInput}\n onChange={(e) => setTagsInput(e.target.value)}\n placeholder=\"ci, deploy, infra\"\n />\n </div>\n </div>\n\n {/* Type-specific fields */}\n {form.actionType === 'COMMAND' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.commandSettings', 'Command Settings')}\n </h3>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.command', 'Command')}\n </label>\n <textarea aria-label=\"echo 'Hello World'\"\n className={`${inputClass} font-mono resize-none`}\n rows={3}\n value={form.command}\n onChange={(e) => update('command', e.target.value)}\n placeholder=\"echo 'Hello World'\"\n required\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.workingDirectory', 'Working Directory')}\n </label>\n <input aria-label=\"/home/user/project\"\n className={inputClass}\n value={form.workingDirectory}\n onChange={(e) => update('workingDirectory', e.target.value)}\n placeholder=\"/home/user/project\"\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.targetAgent', 'Target Agent')}\n </label>\n <select\n className={inputClass}\n value={form.targetAgentId}\n onChange={(e) => update('targetAgentId', e.target.value)}\n >\n <option value=\"\">\n {tr('vibecontrols.actions.form.anyAvailableAgent', 'Any available agent')}\n </option>\n {agents.map((a) => (\n <option key={a.id} value={a.id} disabled={!a.isActive}>\n {a.name}{' '}\n {!a.isActive ? tr('vibecontrols.actions.form.offline', '(offline)') : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {form.actionType === 'SCRIPT' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.scriptSettings', 'Script Settings')}\n </h3>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.script', 'Script')}\n </label>\n <textarea aria-label=\"#!/bin/bash echo 'Hello'\"\n className={`${inputClass} font-mono resize-none`}\n rows={6}\n value={form.script}\n onChange={(e) => update('script', e.target.value)}\n placeholder=\"#!/bin/bash echo 'Hello'\"\n required\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.interpreter', 'Interpreter')}\n </label>\n <select\n className={inputClass}\n value={form.scriptInterpreter}\n onChange={(e) => update('scriptInterpreter', e.target.value)}\n >\n <option value=\"bash\">Bash</option>\n <option value=\"python\">Python</option>\n <option value=\"node\">Node.js</option>\n </select>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.targetAgent', 'Target Agent')}\n </label>\n <select\n className={inputClass}\n value={form.targetAgentId}\n onChange={(e) => update('targetAgentId', e.target.value)}\n >\n <option value=\"\">\n {tr('vibecontrols.actions.form.anyAvailableAgent', 'Any available agent')}\n </option>\n {agents.map((a) => (\n <option key={a.id} value={a.id} disabled={!a.isActive}>\n {a.name}{' '}\n {!a.isActive ? tr('vibecontrols.actions.form.offline', '(offline)') : ''}\n </option>\n ))}\n </select>\n </div>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.workingDirectory', 'Working Directory')}\n </label>\n <input aria-label=\"/home/user/project\"\n className={inputClass}\n value={form.workingDirectory}\n onChange={(e) => update('workingDirectory', e.target.value)}\n placeholder=\"/home/user/project\"\n />\n </div>\n </div>\n )}\n\n {form.actionType === 'WEBHOOK' && (\n <div className=\"space-y-4 p-4 rounded-lg bg-bg-sunken/50 border border-border-default\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.form.webhookSettings', 'Webhook Settings')}\n </h3>\n <div className=\"grid grid-cols-[1fr_auto] gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.url', 'URL')}\n </label>\n <input aria-label=\"https://api.example.com/hook\"\n className={inputClass}\n value={form.webhookUrl}\n onChange={(e) => update('webhookUrl', e.target.value)}\n placeholder=\"https://api.example.com/hook\"\n required\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.method', 'Method')}\n </label>\n <select\n className={inputClass}\n value={form.webhookMethod}\n onChange={(e) => update('webhookMethod', e.target.value)}\n >\n <option value=\"GET\">GET</option>\n <option value=\"POST\">POST</option>\n <option value=\"PUT\">PUT</option>\n <option value=\"PATCH\">PATCH</option>\n <option value=\"DELETE\">DELETE</option>\n </select>\n </div>\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.bodyJson', 'Body (JSON)')}\n </label>\n <textarea aria-label=\"control\"\n className={`${inputClass} font-mono resize-none`}\n rows={4}\n value={form.webhookBody}\n onChange={(e) => update('webhookBody', e.target.value)}\n placeholder='{\"key\": \"value\"}'\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.authType', 'Auth Type')}\n </label>\n <select\n className={inputClass}\n value={form.webhookAuthType}\n onChange={(e) => update('webhookAuthType', e.target.value)}\n >\n <option value=\"\">None</option>\n <option value=\"BEARER\">Bearer Token</option>\n <option value=\"BASIC\">Basic Auth</option>\n <option value=\"API_KEY\">API Key</option>\n </select>\n </div>\n </div>\n )}\n\n {/* Options */}\n <div className=\"grid grid-cols-3 gap-4\">\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.timeout', 'Timeout (ms)')}\n </label>\n <input aria-label=\"control\"\n className={inputClass}\n type=\"number\"\n min={1000}\n max={300000}\n value={form.timeoutMs}\n onChange={(e) => update('timeoutMs', parseInt(e.target.value) || 30000)}\n />\n </div>\n <div>\n <label className={labelClass}>\n {tr('vibecontrols.actions.form.retryCount', 'Retry Count')}\n </label>\n <input aria-label=\"control\"\n className={inputClass}\n type=\"number\"\n min={0}\n max={10}\n value={form.retryCount}\n onChange={(e) => update('retryCount', parseInt(e.target.value) || 0)}\n />\n </div>\n <div className=\"flex items-end pb-2\">\n <label className=\"flex items-center gap-2 text-sm text-text-secondary cursor-pointer\">\n <input aria-label=\"control\"\n type=\"checkbox\"\n checked={form.confirmationRequired}\n onChange={(e) => update('confirmationRequired', e.target.checked)}\n className=\"rounded border-border-default\"\n />\n {tr('vibecontrols.actions.form.requireConfirmation', 'Require confirmation')}\n </label>\n </div>\n </div>\n\n {extraSection && (\n <div className=\"pt-4 border-t border-border-default\">{extraSection}</div>\n )}\n\n {/* Footer */}\n <div className=\"flex items-center justify-end gap-3 pt-4 border-t border-border-default\">\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={isLoading}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-md hover:bg-bg-elevated transition-colors disabled:opacity-50\"\n >\n {tr('vibecontrols.actions.form.cancel', 'Cancel')}\n </button>\n <button\n type=\"submit\"\n disabled={isLoading}\n className=\"px-4 py-2 text-sm font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors disabled:opacity-50\"\n >\n {isLoading\n ? tr('vibecontrols.actions.form.saving', 'Saving...')\n : initialData\n ? tr('vibecontrols.actions.form.updateAction', 'Update Action')\n : tr('vibecontrols.actions.form.createAction', 'Create Action')}\n </button>\n </div>\n </form>\n </motion.div>\n </AnimatePresence>\n </dialog>\n );\n}\n"],"mappings":"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"}
|
|
@@ -74,7 +74,7 @@ function g({ actionId: p, workspaceId: g, actionName: _, onClose: v }) {
|
|
|
74
74
|
className: "text-text-secondary"
|
|
75
75
|
}),
|
|
76
76
|
y("vibecontrols.actions.schedules.title", "Schedules"),
|
|
77
|
-
"
|
|
77
|
+
" - ",
|
|
78
78
|
_,
|
|
79
79
|
A.length > 0 && /* @__PURE__ */ u("span", {
|
|
80
80
|
className: "text-xs font-normal text-text-placeholder",
|
|
@@ -88,10 +88,12 @@ function g({ actionId: p, workspaceId: g, actionName: _, onClose: v }) {
|
|
|
88
88
|
}), /* @__PURE__ */ u("div", {
|
|
89
89
|
className: "flex items-center gap-3",
|
|
90
90
|
children: [/* @__PURE__ */ u("button", {
|
|
91
|
+
type: "button",
|
|
91
92
|
onClick: () => x(`/scheduler?actionId=${encodeURIComponent(p)}`),
|
|
92
93
|
className: "text-xs text-text-secondary hover:text-text-primary transition-colors inline-flex items-center gap-1",
|
|
93
94
|
children: [/* @__PURE__ */ l(o, { size: 12 }), y("vibecontrols.actions.schedules.add", "New schedule")]
|
|
94
95
|
}), /* @__PURE__ */ l("button", {
|
|
96
|
+
type: "button",
|
|
95
97
|
onClick: v,
|
|
96
98
|
className: "text-xs text-text-secondary hover:text-text-primary transition-colors",
|
|
97
99
|
children: y("vibecontrols.actions.schedules.close", "Close")
|
|
@@ -116,6 +118,7 @@ function g({ actionId: p, workspaceId: g, actionName: _, onClose: v }) {
|
|
|
116
118
|
children: A.map((e) => {
|
|
117
119
|
let t = f[e.status] ?? "text-text-secondary", n = d[e.status] ?? e.status.toLowerCase();
|
|
118
120
|
return /* @__PURE__ */ u("button", {
|
|
121
|
+
type: "button",
|
|
119
122
|
onClick: () => x(`/scheduler/${encodeURIComponent(e.id)}`),
|
|
120
123
|
className: "w-full text-left px-4 py-3 hover:bg-bg-sunken/30 transition-colors flex items-center justify-between gap-3",
|
|
121
124
|
children: [/* @__PURE__ */ u("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionSchedulesList.js","names":[],"sources":["../../../src/components/actions/ActionSchedulesList.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AlarmClock, ArrowUpRight, Plus } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useGetScheduledJobsForCalendarQuery } from '@/generated/wspace-operations';\nimport type { GetScheduledJobsForCalendarQuery } from '@/generated/wspace-operations';\nimport type { JobStatus, ScheduleType } from '@/generated/wspace-types';\nimport { useTr } from '@/shared/hooks/useTr';\n\ntype ScheduledJobItem = NonNullable<\n GetScheduledJobsForCalendarQuery['scheduledJobs']['jobs']\n>[number];\n\ninterface ActionSchedulesListProps {\n actionId: string;\n workspaceId: string;\n actionName: string;\n onClose: () => void;\n}\n\nconst STATUS_LABEL: Record<string, string> = {\n ACTIVE: 'active',\n PENDING: 'pending',\n PAUSED: 'paused',\n COMPLETED: 'completed',\n FAILED: 'failed',\n CANCELLED: 'cancelled',\n DISABLED: 'disabled',\n ARCHIVED: 'archived',\n DRAFT: 'draft',\n};\n\nconst STATUS_TONE: Record<string, string> = {\n ACTIVE: 'text-status-success-text',\n PENDING: 'text-status-info-text',\n PAUSED: 'text-text-secondary',\n COMPLETED: 'text-status-success-text',\n FAILED: 'text-status-error-text',\n CANCELLED: 'text-text-placeholder',\n DISABLED: 'text-text-placeholder',\n ARCHIVED: 'text-text-placeholder',\n DRAFT: 'text-text-secondary',\n};\n\nconst SCHEDULE_LABEL: Record<ScheduleType | string, string> = {\n CRON: 'Cron',\n RRULE: 'Recurrence',\n ONE_TIME: 'One-time',\n FIXED_INTERVAL: 'Interval',\n WINDOWED: 'Windowed',\n};\n\nfunction makeFormatTime(locale: string | undefined) {\n return (dateStr: string | null | undefined): string => {\n if (!dateStr) return '—';\n // Pass the app locale through so the displayed format matches\n // whatever the user picked in the shell, not the browser default.\n return new Date(dateStr).toLocaleString(locale || undefined);\n };\n}\n\nfunction makeDescribeSchedule(formatTime: (d: string | null | undefined) => string) {\n return (job: {\n scheduleType: ScheduleType;\n cronExpression?: string | null;\n scheduledAt?: string | null;\n }): string => {\n if (job.scheduleType === 'CRON' && job.cronExpression) return job.cronExpression;\n if (job.scheduleType === 'ONE_TIME' && job.scheduledAt) return formatTime(job.scheduledAt);\n return SCHEDULE_LABEL[job.scheduleType] ?? job.scheduleType;\n };\n}\n\nexport function ActionSchedulesList({\n actionId,\n workspaceId,\n actionName,\n onClose,\n}: ActionSchedulesListProps) {\n const tr = useTr();\n const { locale } = useI18n();\n const navigate = useNavigate();\n const formatTime = useMemo(() => makeFormatTime(locale), [locale]);\n const describeSchedule = useMemo(() => makeDescribeSchedule(formatTime), [formatTime]);\n\n // The scheduler's `JobFilterInput` doesn't support `actionId` today, so we\n // page through up to `pageSize` jobs and filter client-side. The action page\n // is unlikely to need more than a handful of schedules per action; if a\n // workspace ever scales past this, push `actionId` into JobFilterInput.\n const pageSize = 100;\n const { data, loading, error } = useGetScheduledJobsForCalendarQuery({\n variables: { workspaceId, pagination: { first: pageSize } },\n fetchPolicy: 'cache-and-network',\n });\n\n const totalFetched = data?.scheduledJobs?.jobs?.length ?? 0;\n // The query returns at most `pageSize` jobs and we filter client-side,\n // so if the result set hits the page boundary AND the workspace's\n // overall total exceeds it, schedules for this action could be on a\n // later page we never fetched. Surface a warning rather than silently\n // showing an incomplete list. (Long-term fix: add `actionId` to\n // `JobFilterInput` so the server can return the full result set.)\n const totalAvailable = data?.scheduledJobs?.total ?? totalFetched;\n const mayBeTruncated = totalFetched >= pageSize && totalAvailable > totalFetched;\n\n const schedules = useMemo<ScheduledJobItem[]>(() => {\n const jobs: ScheduledJobItem[] = data?.scheduledJobs?.jobs ?? [];\n return jobs\n .filter((j: ScheduledJobItem) => j.actionId === actionId)\n .filter((j: ScheduledJobItem) => (j.status as JobStatus) !== 'ARCHIVED');\n }, [data, actionId]);\n\n return (\n <motion.div\n className=\"bg-bg-surface border border-border-default rounded-lg overflow-hidden\"\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-sunken/50\">\n <h3 className=\"text-sm font-semibold text-text-primary inline-flex items-center gap-2\">\n <AlarmClock size={14} className=\"text-text-secondary\" />\n {tr('vibecontrols.actions.schedules.title', 'Schedules')} — {actionName}\n {schedules.length > 0 && (\n <span className=\"text-xs font-normal text-text-placeholder\">({schedules.length})</span>\n )}\n </h3>\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => navigate(`/scheduler?actionId=${encodeURIComponent(actionId)}`)}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors inline-flex items-center gap-1\"\n >\n <Plus size={12} />\n {tr('vibecontrols.actions.schedules.add', 'New schedule')}\n </button>\n <button\n onClick={onClose}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.actions.schedules.close', 'Close')}\n </button>\n </div>\n </div>\n\n {mayBeTruncated && (\n <div className=\"px-4 py-2 text-xs text-status-warning-text bg-status-warning-surface/40 border-b border-border-default\">\n {tr(\n 'vibecontrols.actions.schedules.truncated',\n `Showing the first ${pageSize} schedules across this workspace; some schedules for this action may not appear here.`\n )}\n </div>\n )}\n\n {loading && schedules.length === 0 ? (\n <div className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n {tr('vibecontrols.actions.schedules.loading', 'Loading schedules…')}\n </div>\n ) : error ? (\n <div className=\"px-4 py-6 text-center text-sm text-status-error-text\">\n {tr('vibecontrols.actions.schedules.error', 'Failed to load schedules')}\n </div>\n ) : schedules.length === 0 ? (\n <div className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n {tr('vibecontrols.actions.schedules.empty', 'No schedules attached to this action')}\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {schedules.map((job: ScheduledJobItem) => {\n const tone = STATUS_TONE[job.status] ?? 'text-text-secondary';\n const statusKey = STATUS_LABEL[job.status] ?? job.status.toLowerCase();\n return (\n <button\n key={job.id}\n onClick={() => navigate(`/scheduler/${encodeURIComponent(job.id)}`)}\n className=\"w-full text-left px-4 py-3 hover:bg-bg-sunken/30 transition-colors flex items-center justify-between gap-3\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {job.name || job.id}\n </span>\n <span className={`text-xs capitalize ${tone}`}>{statusKey}</span>\n </div>\n <div className=\"text-xs text-text-placeholder mt-0.5 truncate\">\n {describeSchedule(job)} · next {formatTime(job.nextExecutionAt)}\n </div>\n </div>\n <ArrowUpRight size={14} className=\"text-text-placeholder flex-shrink-0\" />\n </button>\n );\n })}\n </div>\n )}\n </motion.div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ActionSchedulesList.js","names":[],"sources":["../../../src/components/actions/ActionSchedulesList.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { AlarmClock, ArrowUpRight, Plus } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useGetScheduledJobsForCalendarQuery } from '@/generated/wspace-operations';\nimport type { GetScheduledJobsForCalendarQuery } from '@/generated/wspace-operations';\nimport type { JobStatus, ScheduleType } from '@/generated/wspace-types';\nimport { useTr } from '@/shared/hooks/useTr';\n\ntype ScheduledJobItem = NonNullable<\n GetScheduledJobsForCalendarQuery['scheduledJobs']['jobs']\n>[number];\n\ninterface ActionSchedulesListProps {\n actionId: string;\n workspaceId: string;\n actionName: string;\n onClose: () => void;\n}\n\nconst STATUS_LABEL: Record<string, string> = {\n ACTIVE: 'active',\n PENDING: 'pending',\n PAUSED: 'paused',\n COMPLETED: 'completed',\n FAILED: 'failed',\n CANCELLED: 'cancelled',\n DISABLED: 'disabled',\n ARCHIVED: 'archived',\n DRAFT: 'draft',\n};\n\nconst STATUS_TONE: Record<string, string> = {\n ACTIVE: 'text-status-success-text',\n PENDING: 'text-status-info-text',\n PAUSED: 'text-text-secondary',\n COMPLETED: 'text-status-success-text',\n FAILED: 'text-status-error-text',\n CANCELLED: 'text-text-placeholder',\n DISABLED: 'text-text-placeholder',\n ARCHIVED: 'text-text-placeholder',\n DRAFT: 'text-text-secondary',\n};\n\nconst SCHEDULE_LABEL: Record<ScheduleType | string, string> = {\n CRON: 'Cron',\n RRULE: 'Recurrence',\n ONE_TIME: 'One-time',\n FIXED_INTERVAL: 'Interval',\n WINDOWED: 'Windowed',\n};\n\nfunction makeFormatTime(locale: string | undefined) {\n return (dateStr: string | null | undefined): string => {\n if (!dateStr) return '—';\n // Pass the app locale through so the displayed format matches\n // whatever the user picked in the shell, not the browser default.\n return new Date(dateStr).toLocaleString(locale || undefined);\n };\n}\n\nfunction makeDescribeSchedule(formatTime: (d: string | null | undefined) => string) {\n return (job: {\n scheduleType: ScheduleType;\n cronExpression?: string | null;\n scheduledAt?: string | null;\n }): string => {\n if (job.scheduleType === 'CRON' && job.cronExpression) return job.cronExpression;\n if (job.scheduleType === 'ONE_TIME' && job.scheduledAt) return formatTime(job.scheduledAt);\n return SCHEDULE_LABEL[job.scheduleType] ?? job.scheduleType;\n };\n}\n\nexport function ActionSchedulesList({\n actionId,\n workspaceId,\n actionName,\n onClose,\n}: ActionSchedulesListProps) {\n const tr = useTr();\n const { locale } = useI18n();\n const navigate = useNavigate();\n const formatTime = useMemo(() => makeFormatTime(locale), [locale]);\n const describeSchedule = useMemo(() => makeDescribeSchedule(formatTime), [formatTime]);\n\n // The scheduler's `JobFilterInput` doesn't support `actionId` today, so we\n // page through up to `pageSize` jobs and filter client-side. The action page\n // is unlikely to need more than a handful of schedules per action; if a\n // workspace ever scales past this, push `actionId` into JobFilterInput.\n const pageSize = 100;\n const { data, loading, error } = useGetScheduledJobsForCalendarQuery({\n variables: { workspaceId, pagination: { first: pageSize } },\n fetchPolicy: 'cache-and-network',\n });\n\n const totalFetched = data?.scheduledJobs?.jobs?.length ?? 0;\n // The query returns at most `pageSize` jobs and we filter client-side,\n // so if the result set hits the page boundary AND the workspace's\n // overall total exceeds it, schedules for this action could be on a\n // later page we never fetched. Surface a warning rather than silently\n // showing an incomplete list. (Long-term fix: add `actionId` to\n // `JobFilterInput` so the server can return the full result set.)\n const totalAvailable = data?.scheduledJobs?.total ?? totalFetched;\n const mayBeTruncated = totalFetched >= pageSize && totalAvailable > totalFetched;\n\n const schedules = useMemo<ScheduledJobItem[]>(() => {\n const jobs: ScheduledJobItem[] = data?.scheduledJobs?.jobs ?? [];\n return jobs\n .filter((j: ScheduledJobItem) => j.actionId === actionId)\n .filter((j: ScheduledJobItem) => (j.status as JobStatus) !== 'ARCHIVED');\n }, [data, actionId]);\n\n return (\n <motion.div\n className=\"bg-bg-surface border border-border-default rounded-lg overflow-hidden\"\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-sunken/50\">\n <h3 className=\"text-sm font-semibold text-text-primary inline-flex items-center gap-2\">\n <AlarmClock size={14} className=\"text-text-secondary\" />\n {tr('vibecontrols.actions.schedules.title', 'Schedules')} - {actionName}\n {schedules.length > 0 && (\n <span className=\"text-xs font-normal text-text-placeholder\">({schedules.length})</span>\n )}\n </h3>\n <div className=\"flex items-center gap-3\">\n <button type=\"button\"\n onClick={() => navigate(`/scheduler?actionId=${encodeURIComponent(actionId)}`)}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors inline-flex items-center gap-1\"\n >\n <Plus size={12} />\n {tr('vibecontrols.actions.schedules.add', 'New schedule')}\n </button>\n <button type=\"button\"\n onClick={onClose}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.actions.schedules.close', 'Close')}\n </button>\n </div>\n </div>\n\n {mayBeTruncated && (\n <div className=\"px-4 py-2 text-xs text-status-warning-text bg-status-warning-surface/40 border-b border-border-default\">\n {tr(\n 'vibecontrols.actions.schedules.truncated',\n `Showing the first ${pageSize} schedules across this workspace; some schedules for this action may not appear here.`\n )}\n </div>\n )}\n\n {loading && schedules.length === 0 ? (\n <div className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n {tr('vibecontrols.actions.schedules.loading', 'Loading schedules…')}\n </div>\n ) : error ? (\n <div className=\"px-4 py-6 text-center text-sm text-status-error-text\">\n {tr('vibecontrols.actions.schedules.error', 'Failed to load schedules')}\n </div>\n ) : schedules.length === 0 ? (\n <div className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n {tr('vibecontrols.actions.schedules.empty', 'No schedules attached to this action')}\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {schedules.map((job: ScheduledJobItem) => {\n const tone = STATUS_TONE[job.status] ?? 'text-text-secondary';\n const statusKey = STATUS_LABEL[job.status] ?? job.status.toLowerCase();\n return (\n <button type=\"button\"\n key={job.id}\n onClick={() => navigate(`/scheduler/${encodeURIComponent(job.id)}`)}\n className=\"w-full text-left px-4 py-3 hover:bg-bg-sunken/30 transition-colors flex items-center justify-between gap-3\"\n >\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {job.name || job.id}\n </span>\n <span className={`text-xs capitalize ${tone}`}>{statusKey}</span>\n </div>\n <div className=\"text-xs text-text-placeholder mt-0.5 truncate\">\n {describeSchedule(job)} · next {formatTime(job.nextExecutionAt)}\n </div>\n </div>\n <ArrowUpRight size={14} className=\"text-text-placeholder flex-shrink-0\" />\n </button>\n );\n })}\n </div>\n )}\n </motion.div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -41,11 +41,12 @@ function u({ executions: t, onClose: r, actionName: i }) {
|
|
|
41
41
|
className: "text-sm font-semibold text-text-primary",
|
|
42
42
|
children: [
|
|
43
43
|
u("vibecontrols.actions.executionHistory.recentExecutions", "Recent Executions"),
|
|
44
|
-
"
|
|
44
|
+
" - ",
|
|
45
45
|
" ",
|
|
46
46
|
i
|
|
47
47
|
]
|
|
48
48
|
}), /* @__PURE__ */ o("button", {
|
|
49
|
+
type: "button",
|
|
49
50
|
onClick: r,
|
|
50
51
|
className: "text-xs text-text-secondary hover:text-text-primary transition-colors",
|
|
51
52
|
children: u("vibecontrols.actions.executionHistory.close", "Close")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExecutionHistory.js","names":[],"sources":["../../../src/components/actions/ExecutionHistory.tsx"],"sourcesContent":["import { CheckCircle, XCircle, Clock, Loader } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface Execution {\n id: string;\n status: string;\n triggerType?: string | null;\n triggerSource?: string | null;\n command?: string | null;\n script?: string | null;\n output?: string | null;\n exitCode?: number | null;\n webhookStatusCode?: number | null;\n errorMessage?: string | null;\n durationMs?: number | null;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\ninterface ExecutionHistoryProps {\n executions: Execution[];\n onClose: () => void;\n actionName: string;\n}\n\nconst STATUS_ICON: Record<string, typeof CheckCircle> = {\n SUCCESS: CheckCircle,\n COMPLETED: CheckCircle,\n FAILED: XCircle,\n ERROR: XCircle,\n RUNNING: Loader,\n PENDING: Clock,\n};\n\nconst STATUS_COLOR: Record<string, string> = {\n SUCCESS: 'text-status-success-text',\n COMPLETED: 'text-status-success-text',\n FAILED: 'text-status-error-text',\n ERROR: 'text-status-error-text',\n RUNNING: 'text-status-info-text',\n PENDING: 'text-text-secondary',\n};\n\nexport function ExecutionHistory({ executions, onClose, actionName }: ExecutionHistoryProps) {\n const tr = useTr();\n\n const formatDuration = (ms: number | null | undefined) => {\n if (!ms) return '-';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n };\n\n const formatTime = (dateStr: string | null | undefined) => {\n if (!dateStr) return '-';\n return new Date(dateStr).toLocaleString();\n };\n\n return (\n <motion.div\n className=\"bg-bg-surface border border-border-default rounded-lg overflow-hidden\"\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-sunken/50\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.executionHistory.recentExecutions', 'Recent Executions')}
|
|
1
|
+
{"version":3,"file":"ExecutionHistory.js","names":[],"sources":["../../../src/components/actions/ExecutionHistory.tsx"],"sourcesContent":["import { CheckCircle, XCircle, Clock, Loader } from 'lucide-react';\nimport { motion } from 'framer-motion';\nimport { useTr } from '../../shared/hooks/useTr';\n\ninterface Execution {\n id: string;\n status: string;\n triggerType?: string | null;\n triggerSource?: string | null;\n command?: string | null;\n script?: string | null;\n output?: string | null;\n exitCode?: number | null;\n webhookStatusCode?: number | null;\n errorMessage?: string | null;\n durationMs?: number | null;\n startedAt?: string | null;\n completedAt?: string | null;\n}\n\ninterface ExecutionHistoryProps {\n executions: Execution[];\n onClose: () => void;\n actionName: string;\n}\n\nconst STATUS_ICON: Record<string, typeof CheckCircle> = {\n SUCCESS: CheckCircle,\n COMPLETED: CheckCircle,\n FAILED: XCircle,\n ERROR: XCircle,\n RUNNING: Loader,\n PENDING: Clock,\n};\n\nconst STATUS_COLOR: Record<string, string> = {\n SUCCESS: 'text-status-success-text',\n COMPLETED: 'text-status-success-text',\n FAILED: 'text-status-error-text',\n ERROR: 'text-status-error-text',\n RUNNING: 'text-status-info-text',\n PENDING: 'text-text-secondary',\n};\n\nexport function ExecutionHistory({ executions, onClose, actionName }: ExecutionHistoryProps) {\n const tr = useTr();\n\n const formatDuration = (ms: number | null | undefined) => {\n if (!ms) return '-';\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n };\n\n const formatTime = (dateStr: string | null | undefined) => {\n if (!dateStr) return '-';\n return new Date(dateStr).toLocaleString();\n };\n\n return (\n <motion.div\n className=\"bg-bg-surface border border-border-default rounded-lg overflow-hidden\"\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2 }}\n >\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border-default bg-bg-sunken/50\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {tr('vibecontrols.actions.executionHistory.recentExecutions', 'Recent Executions')} - {' '}\n {actionName}\n </h3>\n <button type=\"button\"\n onClick={onClose}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors\"\n >\n {tr('vibecontrols.actions.executionHistory.close', 'Close')}\n </button>\n </div>\n\n {executions.length === 0 ? (\n <div className=\"px-4 py-6 text-center text-sm text-text-secondary\">\n {tr('vibecontrols.actions.executionHistory.noExecutions', 'No executions yet')}\n </div>\n ) : (\n <div className=\"divide-y divide-border-default\">\n {executions.map((exec) => {\n const Icon = STATUS_ICON[exec.status] || Clock;\n const color = STATUS_COLOR[exec.status] || 'text-text-secondary';\n return (\n <div key={exec.id} className=\"px-4 py-3 space-y-1\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <Icon\n size={14}\n className={`${color} ${exec.status === 'RUNNING' ? 'animate-spin' : ''}`}\n />\n <span className={`text-sm font-medium capitalize ${color}`}>\n {exec.status.toLowerCase()}\n </span>\n {exec.triggerType && (\n <span className=\"text-xs text-text-placeholder\">\n via {exec.triggerType.toLowerCase()}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-3 text-xs text-text-placeholder\">\n <span>{formatDuration(exec.durationMs)}</span>\n <span>{formatTime(exec.startedAt)}</span>\n </div>\n </div>\n {exec.output && (\n <pre className=\"text-xs font-mono text-text-secondary bg-bg-sunken rounded p-2 max-h-20 overflow-y-auto whitespace-pre-wrap\">\n {exec.output}\n </pre>\n )}\n {exec.errorMessage && (\n <pre className=\"text-xs font-mono text-status-error-text bg-status-error-bg/10 rounded p-2 max-h-20 overflow-y-auto whitespace-pre-wrap\">\n {exec.errorMessage}\n </pre>\n )}\n </div>\n );\n })}\n </div>\n )}\n </motion.div>\n );\n}\n"],"mappings":";;;;;AA0BA,IAAM,IAAkD;CACtD,SAAS;CACT,WAAW;CACX,QAAQ;CACR,OAAO;CACP,SAAS;CACT,SAAS;CACV,EAEK,IAAuC;CAC3C,SAAS;CACT,WAAW;CACX,QAAQ;CACR,OAAO;CACP,SAAS;CACT,SAAS;CACV;AAED,SAAgB,EAAiB,EAAE,eAAY,YAAS,iBAAqC;CAC3F,IAAM,IAAK,GAAO,EAEZ,KAAkB,MACjB,IACD,IAAK,MAAa,GAAG,EAAG,MACxB,IAAK,MAAc,IAAI,IAAK,KAAM,QAAQ,EAAE,CAAC,KAC1C,IAAI,IAAK,KAAO,QAAQ,EAAE,CAAC,KAHlB,KAMZ,KAAc,MACb,IACE,IAAI,KAAK,EAAQ,CAAC,gBAAgB,GADpB;AAIvB,QACE,kBAAC,EAAO,KAAR;EACE,WAAU;EACV,SAAS;GAAE,SAAS;GAAG,QAAQ;GAAG;EAClC,SAAS;GAAE,SAAS;GAAG,QAAQ;GAAQ;EACvC,MAAM;GAAE,SAAS;GAAG,QAAQ;GAAG;EAC/B,YAAY,EAAE,UAAU,IAAK;YAL/B,CAOE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cAAd;KACG,EAAG,0DAA0D,oBAAoB;KAAC;KAAI;KACtF;KACE;OACL,kBAAC,UAAD;IAAQ,MAAK;IACX,SAAS;IACT,WAAU;cAET,EAAG,+CAA+C,QAAQ;IACpD,CAAA,CACL;MAEL,EAAW,WAAW,IACrB,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAG,sDAAsD,oBAAoB;GAC1E,CAAA,GAEN,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAW,KAAK,MAAS;IACxB,IAAM,IAAO,EAAY,EAAK,WAAW,GACnC,IAAQ,EAAa,EAAK,WAAW;AAC3C,WACE,kBAAC,OAAD;KAAmB,WAAU;eAA7B;MACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD;UACE,MAAM;UACN,WAAW,GAAG,EAAM,GAAG,EAAK,WAAW,YAAY,iBAAiB;UACpE,CAAA;SACF,kBAAC,QAAD;UAAM,WAAW,kCAAkC;oBAChD,EAAK,OAAO,aAAa;UACrB,CAAA;SACN,EAAK,eACJ,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAAgD,QACzC,EAAK,YAAY,aAAa,CAC9B;;SAEL;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAe,EAAK,WAAW,EAAQ,CAAA,EAC9C,kBAAC,QAAD,EAAA,UAAO,EAAW,EAAK,UAAU,EAAQ,CAAA,CACrC;UACF;;MACL,EAAK,UACJ,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAK;OACF,CAAA;MAEP,EAAK,gBACJ,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAK;OACF,CAAA;MAEJ;OA/BI,EAAK,GA+BT;KAER;GACE,CAAA,CAEG"}
|
|
@@ -82,6 +82,11 @@ function O({ agent: f }) {
|
|
|
82
82
|
exit: { opacity: 0 },
|
|
83
83
|
transition: { duration: .2 },
|
|
84
84
|
children: [/* @__PURE__ */ T("div", {
|
|
85
|
+
role: "button",
|
|
86
|
+
tabIndex: 0,
|
|
87
|
+
onKeyDown: (e) => {
|
|
88
|
+
(e.key === "Enter" || e.key === " ") && (e.preventDefault(), _(!1));
|
|
89
|
+
},
|
|
85
90
|
className: "absolute inset-0 bg-bg-overlay",
|
|
86
91
|
onClick: () => _(!1)
|
|
87
92
|
}), /* @__PURE__ */ E(S.div, {
|
|
@@ -122,12 +127,12 @@ function O({ agent: f }) {
|
|
|
122
127
|
onClick: () => y("/ai-tools/" + p),
|
|
123
128
|
className: "p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary",
|
|
124
129
|
title: O("vibecontrols.agentManager.adminBar.openFullPage", "Open full page"),
|
|
125
|
-
children: /* @__PURE__ */ T(m, { className: "
|
|
130
|
+
children: /* @__PURE__ */ T(m, { className: "size-4" })
|
|
126
131
|
}), /* @__PURE__ */ T("button", {
|
|
127
132
|
type: "button",
|
|
128
133
|
onClick: () => _(!1),
|
|
129
134
|
className: "p-1 rounded hover:bg-bg-elevated transition-colors text-text-tertiary hover:text-text-secondary",
|
|
130
|
-
children: /* @__PURE__ */ T(b, { className: "
|
|
135
|
+
children: /* @__PURE__ */ T(b, { className: "size-4" })
|
|
131
136
|
})]
|
|
132
137
|
})]
|
|
133
138
|
}), /* @__PURE__ */ T("div", {
|
|
@@ -143,7 +148,7 @@ function O({ agent: f }) {
|
|
|
143
148
|
type: "button",
|
|
144
149
|
onClick: () => k(e.key),
|
|
145
150
|
className: `flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded transition-colors whitespace-nowrap ${g && p === e.key ? "bg-action-primary-bg/10 text-action-primary-text" : "text-text-tertiary hover:text-text-secondary hover:bg-bg-elevated"}`,
|
|
146
|
-
children: [/* @__PURE__ */ T(t, { className: "
|
|
151
|
+
children: [/* @__PURE__ */ T(t, { className: "size-3.5" }), /* @__PURE__ */ T("span", { children: e.label })]
|
|
147
152
|
}, e.key);
|
|
148
153
|
})
|
|
149
154
|
})] });
|