@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.
Files changed (434) hide show
  1. package/dist/components/actions/ActionCard.js +6 -0
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/actions/ActionForm.js +17 -1
  4. package/dist/components/actions/ActionForm.js.map +1 -1
  5. package/dist/components/actions/ActionSchedulesList.js +4 -1
  6. package/dist/components/actions/ActionSchedulesList.js.map +1 -1
  7. package/dist/components/actions/ExecutionHistory.js +2 -1
  8. package/dist/components/actions/ExecutionHistory.js.map +1 -1
  9. package/dist/components/agent-manager/AgentManagerAdminBar.js +8 -3
  10. package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
  11. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js +9 -9
  12. package/dist/components/agent-manager/AgentManagerBookmarksDrawer.js.map +1 -1
  13. package/dist/components/agent-manager/AgentManagerBulkActions.js +6 -3
  14. package/dist/components/agent-manager/AgentManagerBulkActions.js.map +1 -1
  15. package/dist/components/agent-manager/AgentManagerCenter.js +8 -2
  16. package/dist/components/agent-manager/AgentManagerCenter.js.map +1 -1
  17. package/dist/components/agent-manager/AgentManagerChatPane.js +6 -6
  18. package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
  19. package/dist/components/agent-manager/AgentManagerDetailPanel.js +1 -1
  20. package/dist/components/agent-manager/AgentManagerDetailPanel.js.map +1 -1
  21. package/dist/components/agent-manager/AgentManagerInputArea.js +7 -5
  22. package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
  23. package/dist/components/agent-manager/AgentManagerLayout.js +8 -4
  24. package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
  25. package/dist/components/agent-manager/AgentManagerMessageItem.js +6 -4
  26. package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
  27. package/dist/components/agent-manager/AgentManagerMessageList.js +3 -3
  28. package/dist/components/agent-manager/AgentManagerMessageList.js.map +1 -1
  29. package/dist/components/agent-manager/AgentManagerSessionItem.js +29 -21
  30. package/dist/components/agent-manager/AgentManagerSessionItem.js.map +1 -1
  31. package/dist/components/agent-manager/AgentManagerSessionList.js +4 -2
  32. package/dist/components/agent-manager/AgentManagerSessionList.js.map +1 -1
  33. package/dist/components/agent-manager/AgentManagerSidebar.js +15 -5
  34. package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
  35. package/dist/components/agent-manager/AgentManagerStreamingIndicator.js +5 -4
  36. package/dist/components/agent-manager/AgentManagerStreamingIndicator.js.map +1 -1
  37. package/dist/components/agent-manager/AgentManagerTab.js +11 -7
  38. package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
  39. package/dist/components/agent-manager/AgentManagerTabBar.js +14 -9
  40. package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
  41. package/dist/components/agent-manager/BridleConfigPanel.js +34 -10
  42. package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
  43. package/dist/components/agent-manager/PluginInstallModal.js +3 -3
  44. package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
  45. package/dist/components/agent-manager/ProfilesPanel.js +15 -10
  46. package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
  47. package/dist/components/agent-manager/controls/AutonomySelector.js +4 -4
  48. package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
  49. package/dist/components/agent-manager/controls/ContextLevelToggle.js +3 -3
  50. package/dist/components/agent-manager/controls/ContextLevelToggle.js.map +1 -1
  51. package/dist/components/agent-manager/controls/FileAttachButton.js +2 -1
  52. package/dist/components/agent-manager/controls/FileAttachButton.js.map +1 -1
  53. package/dist/components/agent-manager/controls/McpServerSelector.js +7 -7
  54. package/dist/components/agent-manager/controls/McpServerSelector.js.map +1 -1
  55. package/dist/components/agent-manager/controls/ModelSelector.js +3 -3
  56. package/dist/components/agent-manager/controls/ModelSelector.js.map +1 -1
  57. package/dist/components/agent-manager/controls/SdkSelector.js +5 -5
  58. package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
  59. package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
  60. package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
  61. package/dist/components/agent-manager/detail/SessionConfigPanel.js +7 -2
  62. package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
  63. package/dist/components/agent-manager/detail/SessionLogsPanel.js +1 -1
  64. package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
  65. package/dist/components/agent-manager/detail/SessionToolsPanel.js +3 -3
  66. package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
  67. package/dist/components/agent-manager/dialogs/ExportSessionDialog.js +4 -2
  68. package/dist/components/agent-manager/dialogs/ExportSessionDialog.js.map +1 -1
  69. package/dist/components/agent-manager/dialogs/NewSessionDialog.js +4 -3
  70. package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
  71. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +3 -3
  72. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
  73. package/dist/components/agent-manager/dialogs/SessionSearchDialog.js +4 -3
  74. package/dist/components/agent-manager/dialogs/SessionSearchDialog.js.map +1 -1
  75. package/dist/components/agents/AgentCard.js +16 -14
  76. package/dist/components/agents/AgentCard.js.map +1 -1
  77. package/dist/components/agents/AgentForm.js +29 -24
  78. package/dist/components/agents/AgentForm.js.map +1 -1
  79. package/dist/components/agents/AgentList.js +38 -20
  80. package/dist/components/agents/AgentList.js.map +1 -1
  81. package/dist/components/agents/AgentStatusBadge.js +1 -1
  82. package/dist/components/agents/AgentStatusBadge.js.map +1 -1
  83. package/dist/components/agents/OpenInBrowserEditorButton.js +3 -2
  84. package/dist/components/agents/OpenInBrowserEditorButton.js.map +1 -1
  85. package/dist/components/agents/OpenInEditorMenu.js +7 -7
  86. package/dist/components/agents/OpenInEditorMenu.js.map +1 -1
  87. package/dist/components/agents/PluginUIPanel.js +28 -14
  88. package/dist/components/agents/PluginUIPanel.js.map +1 -1
  89. package/dist/components/agents/backup/AgentBackupTab.js +30 -20
  90. package/dist/components/agents/backup/AgentBackupTab.js.map +1 -1
  91. package/dist/components/ai/AIContextsTab.js +26 -7
  92. package/dist/components/ai/AIContextsTab.js.map +1 -1
  93. package/dist/components/ai/AIModeToggle.js +2 -1
  94. package/dist/components/ai/AIModeToggle.js.map +1 -1
  95. package/dist/components/ai/AIOverviewTab.js +5 -4
  96. package/dist/components/ai/AIOverviewTab.js.map +1 -1
  97. package/dist/components/ai/AIPlanPanel.js +21 -15
  98. package/dist/components/ai/AIPlanPanel.js.map +1 -1
  99. package/dist/components/ai/AIPlaygroundTab.js +6 -3
  100. package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
  101. package/dist/components/ai/AIPromptsTab.js +10 -4
  102. package/dist/components/ai/AIPromptsTab.js.map +1 -1
  103. package/dist/components/ai/AIProviderCredentialsCard.js +9 -8
  104. package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
  105. package/dist/components/ai/AISessionsTab.js +16 -6
  106. package/dist/components/ai/AISessionsTab.js.map +1 -1
  107. package/dist/components/ai/AIStatsTab.js +7 -6
  108. package/dist/components/ai/AIStatsTab.js.map +1 -1
  109. package/dist/components/ai/AITasksTab.js +30 -9
  110. package/dist/components/ai/AITasksTab.js.map +1 -1
  111. package/dist/components/ai/AITemplatesTab.js +51 -9
  112. package/dist/components/ai/AITemplatesTab.js.map +1 -1
  113. package/dist/components/ai/ClaudeCredentialsCard.js +6 -5
  114. package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
  115. package/dist/components/ai/PluginHarnessPicker.js +6 -6
  116. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  117. package/dist/components/aliases/AliasManager.js +32 -13
  118. package/dist/components/aliases/AliasManager.js.map +1 -1
  119. package/dist/components/analytics/AnalyticsBreakdownTable.js +9 -9
  120. package/dist/components/analytics/AnalyticsBreakdownTable.js.map +1 -1
  121. package/dist/components/analytics/AnalyticsFilterBar.js +4 -3
  122. package/dist/components/analytics/AnalyticsFilterBar.js.map +1 -1
  123. package/dist/components/analytics/AnalyticsKpiGrid.js +12 -12
  124. package/dist/components/analytics/AnalyticsKpiGrid.js.map +1 -1
  125. package/dist/components/assistant/AIAssistantPanel.js +6 -3
  126. package/dist/components/assistant/AIAssistantPanel.js.map +1 -1
  127. package/dist/components/assistant/AssistantChatInput.js +2 -1
  128. package/dist/components/assistant/AssistantChatInput.js.map +1 -1
  129. package/dist/components/assistant/AssistantConversationList.js +18 -7
  130. package/dist/components/assistant/AssistantConversationList.js.map +1 -1
  131. package/dist/components/assistant/AssistantExportMenu.js +6 -3
  132. package/dist/components/assistant/AssistantExportMenu.js.map +1 -1
  133. package/dist/components/assistant/AssistantMarkdownRenderer.js +2 -1
  134. package/dist/components/assistant/AssistantMarkdownRenderer.js.map +1 -1
  135. package/dist/components/assistant/AssistantMessageItem.js +2 -2
  136. package/dist/components/assistant/AssistantMessageItem.js.map +1 -1
  137. package/dist/components/assistant/AssistantMessageList.js +1 -1
  138. package/dist/components/assistant/AssistantMessageList.js.map +1 -1
  139. package/dist/components/assistant/AssistantModeSelector.js +5 -3
  140. package/dist/components/assistant/AssistantModeSelector.js.map +1 -1
  141. package/dist/components/assistant/AssistantWelcome.js +4 -3
  142. package/dist/components/assistant/AssistantWelcome.js.map +1 -1
  143. package/dist/components/audit/AuditDeleteDialog.js +4 -2
  144. package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
  145. package/dist/components/audit/AuditLogDetail.js +4 -1
  146. package/dist/components/audit/AuditLogDetail.js.map +1 -1
  147. package/dist/components/audit/AuditLogFilters.js +1 -0
  148. package/dist/components/audit/AuditLogFilters.js.map +1 -1
  149. package/dist/components/catalog/CatalogCard.js +10 -9
  150. package/dist/components/catalog/CatalogCard.js.map +1 -1
  151. package/dist/components/catalog/CatalogForm.js +8 -1
  152. package/dist/components/catalog/CatalogForm.js.map +1 -1
  153. package/dist/components/docs/DocsCompileStatus.js +6 -5
  154. package/dist/components/docs/DocsCompileStatus.js.map +1 -1
  155. package/dist/components/docs/DocsEditPanel.js +10 -5
  156. package/dist/components/docs/DocsEditPanel.js.map +1 -1
  157. package/dist/components/docs/DocsEmptyState.js +4 -2
  158. package/dist/components/docs/DocsEmptyState.js.map +1 -1
  159. package/dist/components/docs/DocsFullScreenViewer.js +15 -8
  160. package/dist/components/docs/DocsFullScreenViewer.js.map +1 -1
  161. package/dist/components/docs/DocsPageEditor.js +7 -4
  162. package/dist/components/docs/DocsPageEditor.js.map +1 -1
  163. package/dist/components/docs/DocsPageTree.js +13 -4
  164. package/dist/components/docs/DocsPageTree.js.map +1 -1
  165. package/dist/components/docs/DocsPreviewPanel.js +18 -8
  166. package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
  167. package/dist/components/docs/DocsRevisionHistory.js +8 -7
  168. package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
  169. package/dist/components/docs/DocsSettingsPanel.js +43 -10
  170. package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
  171. package/dist/components/docs/DocsTabPanel.js +3 -2
  172. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  173. package/dist/components/gitops/CIDurationChart.js +1 -1
  174. package/dist/components/gitops/CIDurationChart.js.map +1 -1
  175. package/dist/components/gitops/CIFailedRuns.js +3 -3
  176. package/dist/components/gitops/CIFailedRuns.js.map +1 -1
  177. package/dist/components/gitops/CIPipelineRunsTable.js +2 -2
  178. package/dist/components/gitops/CIPipelineRunsTable.js.map +1 -1
  179. package/dist/components/gitops/CISuccessRateChart.js +1 -1
  180. package/dist/components/gitops/CISuccessRateChart.js.map +1 -1
  181. package/dist/components/gitops/CITab.js +1 -1
  182. package/dist/components/gitops/CITab.js.map +1 -1
  183. package/dist/components/gitops/CIWorkflowList.js +1 -1
  184. package/dist/components/gitops/CIWorkflowList.js.map +1 -1
  185. package/dist/components/gitops/GitOpsSetup.js +5 -3
  186. package/dist/components/gitops/GitOpsSetup.js.map +1 -1
  187. package/dist/components/gitops/GitOpsStatusBadge.js +1 -1
  188. package/dist/components/gitops/GitOpsStatusBadge.js.map +1 -1
  189. package/dist/components/gitops/RepoActivityCard.js +3 -3
  190. package/dist/components/gitops/RepoActivityCard.js.map +1 -1
  191. package/dist/components/gitops/RepoIssuesCard.js +1 -1
  192. package/dist/components/gitops/RepoIssuesCard.js.map +1 -1
  193. package/dist/components/gitops/RepoLanguagesCard.js +3 -3
  194. package/dist/components/gitops/RepoLanguagesCard.js.map +1 -1
  195. package/dist/components/gitops/RepoOverviewCard.js +8 -8
  196. package/dist/components/gitops/RepoOverviewCard.js.map +1 -1
  197. package/dist/components/gitops/RepoPullRequestsCard.js +1 -1
  198. package/dist/components/gitops/RepoPullRequestsCard.js.map +1 -1
  199. package/dist/components/gitops/RepoSecurityCard.js +1 -1
  200. package/dist/components/gitops/RepoSecurityCard.js.map +1 -1
  201. package/dist/components/gitops/RepoStatsTab.js +1 -1
  202. package/dist/components/gitops/RepoStatsTab.js.map +1 -1
  203. package/dist/components/gitops/VibeGitOpsTab.js +11 -6
  204. package/dist/components/gitops/VibeGitOpsTab.js.map +1 -1
  205. package/dist/components/graph/AgentNode.js +1 -1
  206. package/dist/components/graph/AgentNode.js.map +1 -1
  207. package/dist/components/graph/ConnectionPermissionsDialog.js +10 -0
  208. package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
  209. package/dist/components/graph/TargetNode.js +1 -1
  210. package/dist/components/graph/TargetNode.js.map +1 -1
  211. package/dist/components/idp-components/ComponentCard.js +7 -6
  212. package/dist/components/idp-components/ComponentCard.js.map +1 -1
  213. package/dist/components/idp-components/ComponentForm.js +17 -3
  214. package/dist/components/idp-components/ComponentForm.js.map +1 -1
  215. package/dist/components/idp-components/DependencyGraphTab.js +1 -1
  216. package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
  217. package/dist/components/logs/LogViewer.js +2 -1
  218. package/dist/components/logs/LogViewer.js.map +1 -1
  219. package/dist/components/notes/NoteCard.js +15 -14
  220. package/dist/components/notes/NoteCard.js.map +1 -1
  221. package/dist/components/notes/NoteEditor.js +19 -14
  222. package/dist/components/notes/NoteEditor.js.map +1 -1
  223. package/dist/components/notes/NoteList.js +23 -15
  224. package/dist/components/notes/NoteList.js.map +1 -1
  225. package/dist/components/notes/NotesTabPanel.js +19 -10
  226. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  227. package/dist/components/plugins/AddTabDialog.js +6 -6
  228. package/dist/components/plugins/AddTabDialog.js.map +1 -1
  229. package/dist/components/scorecard/ScorecardPanel.js +19 -9
  230. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  231. package/dist/components/security/SecurityEmptyState.js +1 -1
  232. package/dist/components/security/SecurityEmptyState.js.map +1 -1
  233. package/dist/components/security/SecurityFindingsTable.js +1 -1
  234. package/dist/components/security/SecurityFindingsTable.js.map +1 -1
  235. package/dist/components/security/SecurityHeaderStrip.js +1 -1
  236. package/dist/components/security/SecurityHeaderStrip.js.map +1 -1
  237. package/dist/components/security/SecurityProviderDrawer.js +1 -1
  238. package/dist/components/security/SecurityProviderDrawer.js.map +1 -1
  239. package/dist/components/sessions/CollaboratorsList.js +15 -12
  240. package/dist/components/sessions/CollaboratorsList.js.map +1 -1
  241. package/dist/components/sessions/ControlStatusBar.js +11 -9
  242. package/dist/components/sessions/ControlStatusBar.js.map +1 -1
  243. package/dist/components/sessions/SessionCard.js +13 -11
  244. package/dist/components/sessions/SessionCard.js.map +1 -1
  245. package/dist/components/sessions/SessionList.js +23 -13
  246. package/dist/components/sessions/SessionList.js.map +1 -1
  247. package/dist/components/sessions/SessionShareDialog.js +31 -19
  248. package/dist/components/sessions/SessionShareDialog.js.map +1 -1
  249. package/dist/components/sessions/SharedTerminalPanel.js +4 -2
  250. package/dist/components/sessions/SharedTerminalPanel.js.map +1 -1
  251. package/dist/components/sessions/TerminalPanel.js +287 -235
  252. package/dist/components/sessions/TerminalPanel.js.map +1 -1
  253. package/dist/components/settings/AdvancedSection.js +12 -4
  254. package/dist/components/settings/AdvancedSection.js.map +1 -1
  255. package/dist/components/settings/IdePreferencesSection.js +1 -1
  256. package/dist/components/settings/IdePreferencesSection.js.map +1 -1
  257. package/dist/components/settings/SettingsForm.js +3 -1
  258. package/dist/components/settings/SettingsForm.js.map +1 -1
  259. package/dist/components/shared/AgentSelector.js +6 -6
  260. package/dist/components/shared/AgentSelector.js.map +1 -1
  261. package/dist/components/shared/AgentSetupBanner.js +14 -10
  262. package/dist/components/shared/AgentSetupBanner.js.map +1 -1
  263. package/dist/components/shared/Card.js.map +1 -1
  264. package/dist/components/shared/ConfirmDialog.js +4 -3
  265. package/dist/components/shared/ConfirmDialog.js.map +1 -1
  266. package/dist/components/shared/EmptyState.js +4 -4
  267. package/dist/components/shared/EmptyState.js.map +1 -1
  268. package/dist/components/shared/EntityTagPicker.js +9 -10
  269. package/dist/components/shared/EntityTagPicker.js.map +1 -1
  270. package/dist/components/shared/ErrorState.js +7 -6
  271. package/dist/components/shared/ErrorState.js.map +1 -1
  272. package/dist/components/shared/FilterDropdown.js +6 -3
  273. package/dist/components/shared/FilterDropdown.js.map +1 -1
  274. package/dist/components/shared/GetHelpButton.js +1 -1
  275. package/dist/components/shared/GetHelpButton.js.map +1 -1
  276. package/dist/components/shared/InstallTabs.js +2 -2
  277. package/dist/components/shared/InstallTabs.js.map +1 -1
  278. package/dist/components/shared/LoadingState.js +3 -3
  279. package/dist/components/shared/LoadingState.js.map +1 -1
  280. package/dist/components/shared/NotificationToast.js +3 -3
  281. package/dist/components/shared/NotificationToast.js.map +1 -1
  282. package/dist/components/shared/PageSkeleton.js +1 -1
  283. package/dist/components/shared/PageSkeleton.js.map +1 -1
  284. package/dist/components/shared/PluginGate.js +12 -8
  285. package/dist/components/shared/PluginGate.js.map +1 -1
  286. package/dist/components/shared/RequireAgentReachable.js +4 -4
  287. package/dist/components/shared/RequireAgentReachable.js.map +1 -1
  288. package/dist/components/shared/SearchInput.js +3 -2
  289. package/dist/components/shared/SearchInput.js.map +1 -1
  290. package/dist/components/shared/SearchableSelect.js +10 -5
  291. package/dist/components/shared/SearchableSelect.js.map +1 -1
  292. package/dist/components/shared/SelectionCheckbox.js +2 -2
  293. package/dist/components/shared/SelectionCheckbox.js.map +1 -1
  294. package/dist/components/shared/SessionNotificationBanner.js +8 -6
  295. package/dist/components/shared/SessionNotificationBanner.js.map +1 -1
  296. package/dist/components/shared/StatCard.js +2 -2
  297. package/dist/components/shared/StatCard.js.map +1 -1
  298. package/dist/components/shared/StatusBadge.js +1 -1
  299. package/dist/components/shared/StatusBadge.js.map +1 -1
  300. package/dist/components/targets/TargetCard.js +24 -11
  301. package/dist/components/targets/TargetCard.js.map +1 -1
  302. package/dist/components/templates/PublishTemplateForm.js +27 -7
  303. package/dist/components/templates/PublishTemplateForm.js.map +1 -1
  304. package/dist/components/templates/TemplateCard.js +6 -6
  305. package/dist/components/templates/TemplateCard.js.map +1 -1
  306. package/dist/components/templates/TemplateVariableEditor.js +21 -3
  307. package/dist/components/templates/TemplateVariableEditor.js.map +1 -1
  308. package/dist/components/templates/TemplateWizard.js +38 -15
  309. package/dist/components/templates/TemplateWizard.js.map +1 -1
  310. package/dist/components/tunnels/TunnelCard.js +5 -5
  311. package/dist/components/tunnels/TunnelCard.js.map +1 -1
  312. package/dist/components/tunnels/TunnelCreateWizard.js +8 -0
  313. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  314. package/dist/components/vibe/VibeAgentEmptyState.js +9 -5
  315. package/dist/components/vibe/VibeAgentEmptyState.js.map +1 -1
  316. package/dist/components/vibe/VibeAgentSwitcher.js +20 -16
  317. package/dist/components/vibe/VibeAgentSwitcher.js.map +1 -1
  318. package/dist/components/vibe/VibeLlmContextAdminPanel.js +5 -4
  319. package/dist/components/vibe/VibeLlmContextAdminPanel.js.map +1 -1
  320. package/dist/components/vibe/VibeLlmContextTabPanel.js +35 -18
  321. package/dist/components/vibe/VibeLlmContextTabPanel.js.map +1 -1
  322. package/dist/components/vibecalendar/LogsDrawer.js +6 -0
  323. package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
  324. package/dist/components/vibecalendar/ScheduleTaskModal.js +19 -0
  325. package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
  326. package/dist/components/vibecalendar/VibeCalAgendaView.js +7 -0
  327. package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
  328. package/dist/components/vibecalendar/VibeCalDayView.js +7 -0
  329. package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
  330. package/dist/components/vibecalendar/VibeCalMonthView.js +2 -2
  331. package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
  332. package/dist/components/vibecalendar/VibeCalWeekView.js +8 -1
  333. package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
  334. package/dist/components/vibecalendar/VibeCalendarHeader.js +5 -0
  335. package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
  336. package/dist/components/vibecalendar/VibeTaskBlock.js +8 -0
  337. package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
  338. package/dist/components/vibedeck/VibeDeckButtonForm.js +20 -0
  339. package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
  340. package/dist/components/vibedeck/VibeDeckButtonTile.js +12 -4
  341. package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
  342. package/dist/components/vibedeck/VibeDeckExecutionLog.js +6 -0
  343. package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
  344. package/dist/components/vibedeck/VibeDeckForm.js +5 -0
  345. package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
  346. package/dist/components/vibedeck/VibeDeckGrid.js +1 -0
  347. package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
  348. package/dist/components/vibedeck/VibeDeckShareDialog.js +18 -1
  349. package/dist/components/vibedeck/VibeDeckShareDialog.js.map +1 -1
  350. package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -0
  351. package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
  352. package/dist/components/vibes/VibeCard.js +10 -9
  353. package/dist/components/vibes/VibeCard.js.map +1 -1
  354. package/dist/components/vibes/VibeList.js +30 -16
  355. package/dist/components/vibes/VibeList.js.map +1 -1
  356. package/dist/pages/ActionsPage.js +12 -0
  357. package/dist/pages/ActionsPage.js.map +1 -1
  358. package/dist/pages/AgentDetailsPage.js +125 -68
  359. package/dist/pages/AgentDetailsPage.js.map +1 -1
  360. package/dist/pages/AgentGraphPage.js +5 -5
  361. package/dist/pages/AgentGraphPage.js.map +1 -1
  362. package/dist/pages/AgentsPage.js +339 -301
  363. package/dist/pages/AgentsPage.js.map +1 -1
  364. package/dist/pages/AnalyticsPage.js +1 -1
  365. package/dist/pages/AnalyticsPage.js.map +1 -1
  366. package/dist/pages/CatalogDetailPage.js +34 -20
  367. package/dist/pages/CatalogDetailPage.js.map +1 -1
  368. package/dist/pages/CatalogPage.js +9 -5
  369. package/dist/pages/CatalogPage.js.map +1 -1
  370. package/dist/pages/ComponentDetailPage.js +40 -23
  371. package/dist/pages/ComponentDetailPage.js.map +1 -1
  372. package/dist/pages/ComponentsPage.js +9 -5
  373. package/dist/pages/ComponentsPage.js.map +1 -1
  374. package/dist/pages/GettingStartedPage.js +6 -5
  375. package/dist/pages/GettingStartedPage.js.map +1 -1
  376. package/dist/pages/HealthPage.js +16 -15
  377. package/dist/pages/HealthPage.js.map +1 -1
  378. package/dist/pages/LogsPage.js +2 -2
  379. package/dist/pages/LogsPage.js.map +1 -1
  380. package/dist/pages/NoteDetailsPage.js +12 -7
  381. package/dist/pages/NoteDetailsPage.js.map +1 -1
  382. package/dist/pages/OverviewPage.js +26 -15
  383. package/dist/pages/OverviewPage.js.map +1 -1
  384. package/dist/pages/SessionDetailsPage.js +73 -50
  385. package/dist/pages/SessionDetailsPage.js.map +1 -1
  386. package/dist/pages/SessionsPage.js +49 -22
  387. package/dist/pages/SessionsPage.js.map +1 -1
  388. package/dist/pages/SettingsPage.js +4 -4
  389. package/dist/pages/SettingsPage.js.map +1 -1
  390. package/dist/pages/SharedSessionPage.js +36 -29
  391. package/dist/pages/SharedSessionPage.js.map +1 -1
  392. package/dist/pages/SharedVibeDeckPage.js +8 -6
  393. package/dist/pages/SharedVibeDeckPage.js.map +1 -1
  394. package/dist/pages/TargetDetailsPage.js +7 -6
  395. package/dist/pages/TargetDetailsPage.js.map +1 -1
  396. package/dist/pages/TargetsPage.js +84 -11
  397. package/dist/pages/TargetsPage.js.map +1 -1
  398. package/dist/pages/TemplateDetailPage.js +33 -23
  399. package/dist/pages/TemplateDetailPage.js.map +1 -1
  400. package/dist/pages/TemplatesPage.js +5 -3
  401. package/dist/pages/TemplatesPage.js.map +1 -1
  402. package/dist/pages/VibeCalendarPage.js +1 -0
  403. package/dist/pages/VibeCalendarPage.js.map +1 -1
  404. package/dist/pages/VibeDeckPage.js +256 -239
  405. package/dist/pages/VibeDeckPage.js.map +1 -1
  406. package/dist/pages/VibeDetailsPage.js +657 -619
  407. package/dist/pages/VibeDetailsPage.js.map +1 -1
  408. package/dist/pages/VibeTaskDetailPage.js +3 -0
  409. package/dist/pages/VibeTaskDetailPage.js.map +1 -1
  410. package/dist/pages/VibesPage.js +21 -8
  411. package/dist/pages/VibesPage.js.map +1 -1
  412. package/dist/pages/ai/AIBookmarksPage.js +8 -8
  413. package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
  414. package/dist/pages/ai/AIPage.js +4 -2
  415. package/dist/pages/ai/AIPage.js.map +1 -1
  416. package/dist/pages/ai/AISessionDetailPage.js +19 -10
  417. package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
  418. package/dist/pages/ai/AgentManagerPage.js +2 -1
  419. package/dist/pages/ai/AgentManagerPage.js.map +1 -1
  420. package/dist/pages/tunnels/ProvidersTab.js +1 -1
  421. package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
  422. package/dist/pages/tunnels/TunnelDetailsPage.js +2 -1
  423. package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
  424. package/dist/pages/tunnels/tabs/TunnelCliTab.js +1 -1
  425. package/dist/pages/tunnels/tabs/TunnelCliTab.js.map +1 -1
  426. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +1 -0
  427. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
  428. package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js +1 -1
  429. package/dist/pages/tunnels/tabs/TunnelEndpointsTab.js.map +1 -1
  430. package/dist/providers/AgentEventsProvider.js +5 -5
  431. package/dist/providers/AgentEventsProvider.js.map +1 -1
  432. package/dist/providers/VibeControlsProvider.js +3 -3
  433. package/dist/providers/VibeControlsProvider.js.map +1 -1
  434. 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":";;;;;;;AAqCA,SAAgB,EAAW,EACzB,WACA,cACA,WACA,gBACA,aACA,eACA,oBACA,cACA,cACA,eACA,iBAAc,IACd,cAAW,IACX,qBACkB;CAClB,IAAM,IAAqB,GAAkB,EACvC,IAAK,GAAO;AAmBlB,QACE,kBAAC,EAAO,KAAR;EACE,WAAW,0FACT,IACI,8DACA;EAEN,YACE,IACI,KAAA,IACA;GAAE,GAAG;GAAI,WAAW;GAA0C;EAEpE,YAAY,EAAE,UAAU,KAAM;EAC9B,QAAA;EACA,MAAK;EACL,cAAY,WAAW,EAAO,eAAe,EAAO;YAdtD;GAiBE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,KACC,kBAAC,OAAD;MAAK,UAAU,MAAU,EAAM,iBAAiB;gBAC9C,kBAAC,GAAD;OACE,SAAS;OACT,UAAU;OACV,WAAW,iBAAiB,EAAO,eAAe,EAAO;OACzD,CAAA;MACE,CAAA,EAER,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAO,eAAe,EAAO;OAC3B,CAAA,EACJ,EAAO,eACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAO;OACN,CAAA,CAEF;QACF;QAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,KACC,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAU,EAAO,GAAG;;OAEtB,UAAU;OACV,WAAU;OACV,OAAO,EAAG,qCAAqC,UAAU;iBAEzD,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA;MAEV,KACC,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAO,EAAO,GAAG;;OAEnB,WAAU;OACV,OAAO,EAAG,kCAAkC,OAAO;iBAEnD,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;OACb,CAAA;MAEV,KACC,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAW,EAAO,GAAG;;OAEvB,WAAU;OACV,OAAO,EAAG,sCAAsC,uBAAuB;iBAEvE,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;OACjB,CAAA;MAEV,KACC,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAgB,EAAO,GAAG;;OAE5B,WAAU;OACV,OAAO,EAAG,2CAA2C,kBAAkB;iBAEvE,kBAAC,GAAD,EAAe,MAAM,IAAM,CAAA;OACpB,CAAA;MAEX,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAY,EAAO,GAAG;;OAExB,WAAU;OACV,OAAO,EAAG,uCAAuC,YAAY;iBAE7D,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA;MACR,KACC,kBAAC,UAAD;OAAQ,MAAK;OACX,UAAU,MAAU;AAElB,QADA,EAAM,iBAAiB,EACvB,EAAS,EAAO,GAAG;;OAErB,WAAU;OACV,OAAO,EAAG,oCAAoC,SAAS;iBAEvD,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;OACb,CAAA;MAEP;OACF;;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAiB,MAAM,EAAO,YAAc,CAAA;KAC5C,kBAAC,GAAD,EAAkB,MAAM,EAAO,aAAe,CAAA;KAC7C,EAAO,cAAc,kBAAC,GAAD,EAAiB,MAAM,EAAO,YAAc,CAAA;KAC9D;;IAGJ,EAAO,YAAa,EAAO,QAAQ,EAAO,KAAK,SAAS,MACxD,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,EAAO,YACN,kBAAC,QAAD;KAAM,WAAU;eACb,EAAO;KACH,CAAA,EAER,EAAO,MAAM,KAAK,MACjB,kBAAC,QAAD;KAEE,WAAU;eAFZ,CAGC,KACG,EACG;OAJA,EAIA,CACP,CACE;;GAIR,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,2CAA2C,kBAAkB,EAC/D,OAAO,EAAO,kBAAkB,GACjC,CAAC,CACG;QACP,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,IAxKP,MAAuC;AACzD,UAAI,CAAC,EAAS,QAAO,EAAG,mCAAmC,QAAQ;MACnE,IAAM,IAAO,IAAI,KAAK,EAAQ,EAExB,qBADM,IAAI,MAAM,EACH,SAAS,GAAG,EAAK,SAAS,EACvC,IAAU,KAAK,MAAM,IAAS,IAAM;AAC1C,UAAI,IAAU,EAAG,QAAO,EAAG,qCAAqC,WAAW;AAC3E,UAAI,IAAU,GACZ,QAAO,EAAG,wCAAwC,kBAAkB,EAAE,OAAO,GAAS,CAAC;MACzF,IAAM,IAAS,KAAK,MAAM,IAAU,GAAG;AACvC,UAAI,IAAS,GACX,QAAO,EAAG,sCAAsC,kBAAkB,EAAE,OAAO,GAAQ,CAAC;MACtF,IAAM,IAAW,KAAK,MAAM,IAAS,GAAG;AAExC,aADI,IAAW,IAAU,GAAG,EAAS,SAC9B,EAAK,oBAAoB;QA2Jd,EAAO,eAAe,CAC7B;OACH;;GACK"}
@@ -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: "w-5 h-5 text-text-secondary" })
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&#10;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&#10;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&#10;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')} —{' '}\n {actionName}\n </h3>\n <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;KAAG;KACrF;KACE;OACL,kBAAC,UAAD;IACE,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"}
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: "w-4 h-4" })
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: "w-4 h-4" })
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: "w-3.5 h-3.5" }), /* @__PURE__ */ T("span", { children: e.label })]
151
+ children: [/* @__PURE__ */ T(t, { className: "size-3.5" }), /* @__PURE__ */ T("span", { children: e.label })]
147
152
  }, e.key);
148
153
  })
149
154
  })] });