@burdenoff/microfe-vibecontrols 2026.623.1 → 2026.623.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/dist/components/actions/ActionCard.js +2 -2
  2. package/dist/components/actions/ActionCard.js.map +1 -1
  3. package/dist/components/actions/ExecutionHistory.js +1 -1
  4. package/dist/components/actions/ExecutionHistory.js.map +1 -1
  5. package/dist/components/agent-manager/AgentManagerAdminBar.js +1 -1
  6. package/dist/components/agent-manager/AgentManagerAdminBar.js.map +1 -1
  7. package/dist/components/agent-manager/AgentManagerChatPane.js +2 -2
  8. package/dist/components/agent-manager/AgentManagerChatPane.js.map +1 -1
  9. package/dist/components/agent-manager/AgentManagerInputArea.js +4 -4
  10. package/dist/components/agent-manager/AgentManagerInputArea.js.map +1 -1
  11. package/dist/components/agent-manager/AgentManagerLayout.js +1 -1
  12. package/dist/components/agent-manager/AgentManagerLayout.js.map +1 -1
  13. package/dist/components/agent-manager/AgentManagerMessageItem.js +1 -1
  14. package/dist/components/agent-manager/AgentManagerMessageItem.js.map +1 -1
  15. package/dist/components/agent-manager/AgentManagerSidebar.js +5 -5
  16. package/dist/components/agent-manager/AgentManagerSidebar.js.map +1 -1
  17. package/dist/components/agent-manager/AgentManagerTab.js +1 -1
  18. package/dist/components/agent-manager/AgentManagerTab.js.map +1 -1
  19. package/dist/components/agent-manager/AgentManagerTabBar.js +1 -1
  20. package/dist/components/agent-manager/AgentManagerTabBar.js.map +1 -1
  21. package/dist/components/agent-manager/BridleConfigPanel.js +23 -23
  22. package/dist/components/agent-manager/BridleConfigPanel.js.map +1 -1
  23. package/dist/components/agent-manager/PluginInstallModal.js +1 -1
  24. package/dist/components/agent-manager/PluginInstallModal.js.map +1 -1
  25. package/dist/components/agent-manager/ProfilesPanel.js +5 -5
  26. package/dist/components/agent-manager/ProfilesPanel.js.map +1 -1
  27. package/dist/components/agent-manager/controls/AutonomySelector.js +1 -1
  28. package/dist/components/agent-manager/controls/AutonomySelector.js.map +1 -1
  29. package/dist/components/agent-manager/controls/SdkSelector.js +1 -1
  30. package/dist/components/agent-manager/controls/SdkSelector.js.map +1 -1
  31. package/dist/components/agent-manager/controls/VoiceToggle.js +1 -1
  32. package/dist/components/agent-manager/controls/VoiceToggle.js.map +1 -1
  33. package/dist/components/agent-manager/detail/SessionConfigPanel.js +6 -6
  34. package/dist/components/agent-manager/detail/SessionConfigPanel.js.map +1 -1
  35. package/dist/components/agent-manager/detail/SessionLogsPanel.js +5 -5
  36. package/dist/components/agent-manager/detail/SessionLogsPanel.js.map +1 -1
  37. package/dist/components/agent-manager/detail/SessionToolsPanel.js +1 -1
  38. package/dist/components/agent-manager/detail/SessionToolsPanel.js.map +1 -1
  39. package/dist/components/agent-manager/dialogs/NewSessionDialog.js +2 -2
  40. package/dist/components/agent-manager/dialogs/NewSessionDialog.js.map +1 -1
  41. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js +1 -1
  42. package/dist/components/agent-manager/dialogs/RenameSessionDialog.js.map +1 -1
  43. package/dist/components/agents/AgentCard.js +14 -11
  44. package/dist/components/agents/AgentCard.js.map +1 -1
  45. package/dist/components/ai/AIContextsTab.js +1 -1
  46. package/dist/components/ai/AIContextsTab.js.map +1 -1
  47. package/dist/components/ai/AIOverviewTab.js +4 -4
  48. package/dist/components/ai/AIOverviewTab.js.map +1 -1
  49. package/dist/components/ai/AIPlanPanel.js +4 -4
  50. package/dist/components/ai/AIPlanPanel.js.map +1 -1
  51. package/dist/components/ai/AIPlaygroundTab.js +1 -1
  52. package/dist/components/ai/AIPlaygroundTab.js.map +1 -1
  53. package/dist/components/ai/AIPromptsTab.js +2 -2
  54. package/dist/components/ai/AIPromptsTab.js.map +1 -1
  55. package/dist/components/ai/AIProviderCredentialsCard.js +4 -4
  56. package/dist/components/ai/AIProviderCredentialsCard.js.map +1 -1
  57. package/dist/components/ai/AIQueueTab.js +4 -4
  58. package/dist/components/ai/AIQueueTab.js.map +1 -1
  59. package/dist/components/ai/AISessionsTab.js +4 -4
  60. package/dist/components/ai/AISessionsTab.js.map +1 -1
  61. package/dist/components/ai/AITasksTab.js +1 -1
  62. package/dist/components/ai/AITasksTab.js.map +1 -1
  63. package/dist/components/ai/ClaudeCredentialsCard.js +3 -3
  64. package/dist/components/ai/ClaudeCredentialsCard.js.map +1 -1
  65. package/dist/components/ai/PluginHarnessPicker.js +3 -3
  66. package/dist/components/ai/PluginHarnessPicker.js.map +1 -1
  67. package/dist/components/analytics/AnalyticsBreakdownChart.js +8 -8
  68. package/dist/components/analytics/AnalyticsBreakdownChart.js.map +1 -1
  69. package/dist/components/analytics/AnalyticsTimeSeriesChart.js +5 -5
  70. package/dist/components/analytics/AnalyticsTimeSeriesChart.js.map +1 -1
  71. package/dist/components/audit/AuditDeleteDialog.js +2 -2
  72. package/dist/components/audit/AuditDeleteDialog.js.map +1 -1
  73. package/dist/components/audit/AuditExportButton.js +5 -5
  74. package/dist/components/audit/AuditExportButton.js.map +1 -1
  75. package/dist/components/audit/AuditLogDetail.js +9 -9
  76. package/dist/components/audit/AuditLogDetail.js.map +1 -1
  77. package/dist/components/audit/AuditLogFilters.js +1 -1
  78. package/dist/components/audit/AuditLogFilters.js.map +1 -1
  79. package/dist/components/audit/AuditLogStats.js +1 -1
  80. package/dist/components/audit/AuditLogStats.js.map +1 -1
  81. package/dist/components/audit/AuditLogTable.js +28 -28
  82. package/dist/components/audit/AuditLogTable.js.map +1 -1
  83. package/dist/components/catalog/CatalogCard.js +3 -3
  84. package/dist/components/catalog/CatalogCard.js.map +1 -1
  85. package/dist/components/catalog/CatalogForm.js +1 -1
  86. package/dist/components/catalog/CatalogForm.js.map +1 -1
  87. package/dist/components/common/ActionAgentTargetNotice.js +6 -6
  88. package/dist/components/common/ActionAgentTargetNotice.js.map +1 -1
  89. package/dist/components/common/CommandEditor.js +1 -1
  90. package/dist/components/common/CommandEditor.js.map +1 -1
  91. package/dist/components/docs/DocsPageTree.js +1 -1
  92. package/dist/components/docs/DocsPageTree.js.map +1 -1
  93. package/dist/components/docs/DocsPreviewPanel.js +1 -1
  94. package/dist/components/docs/DocsPreviewPanel.js.map +1 -1
  95. package/dist/components/docs/DocsRevisionHistory.js +4 -4
  96. package/dist/components/docs/DocsRevisionHistory.js.map +1 -1
  97. package/dist/components/docs/DocsSettingsPanel.js +7 -7
  98. package/dist/components/docs/DocsSettingsPanel.js.map +1 -1
  99. package/dist/components/docs/DocsTabPanel.js +1 -1
  100. package/dist/components/docs/DocsTabPanel.js.map +1 -1
  101. package/dist/components/graph/ConnectionPermissionsDialog.js +2 -2
  102. package/dist/components/graph/ConnectionPermissionsDialog.js.map +1 -1
  103. package/dist/components/graph/MeshDeployWizard.js +3 -3
  104. package/dist/components/graph/MeshDeployWizard.js.map +1 -1
  105. package/dist/components/graph/MeshRequestPanel.js +2 -2
  106. package/dist/components/graph/MeshRequestPanel.js.map +1 -1
  107. package/dist/components/idp-components/ComponentCard.js +5 -5
  108. package/dist/components/idp-components/ComponentCard.js.map +1 -1
  109. package/dist/components/idp-components/ComponentForm.js +1 -1
  110. package/dist/components/idp-components/ComponentForm.js.map +1 -1
  111. package/dist/components/idp-components/DependencyGraphTab.js +7 -7
  112. package/dist/components/idp-components/DependencyGraphTab.js.map +1 -1
  113. package/dist/components/logs/LogViewer.js +14 -14
  114. package/dist/components/logs/LogViewer.js.map +1 -1
  115. package/dist/components/notes/NoteCard.js +1 -1
  116. package/dist/components/notes/NoteCard.js.map +1 -1
  117. package/dist/components/notes/NoteEditor.js +2 -2
  118. package/dist/components/notes/NoteEditor.js.map +1 -1
  119. package/dist/components/notes/NoteList.js +1 -1
  120. package/dist/components/notes/NoteList.js.map +1 -1
  121. package/dist/components/notes/NotesTabPanel.js +1 -1
  122. package/dist/components/notes/NotesTabPanel.js.map +1 -1
  123. package/dist/components/scorecard/ScorecardEmptyState.js +1 -1
  124. package/dist/components/scorecard/ScorecardEmptyState.js.map +1 -1
  125. package/dist/components/scorecard/ScorecardPanel.js +3 -3
  126. package/dist/components/scorecard/ScorecardPanel.js.map +1 -1
  127. package/dist/components/security/SecurityScanList.js +11 -11
  128. package/dist/components/security/SecurityScanList.js.map +1 -1
  129. package/dist/components/sessions/SessionCard.js +26 -19
  130. package/dist/components/sessions/SessionCard.js.map +1 -1
  131. package/dist/components/sessions/SessionStatusBadge.js +7 -7
  132. package/dist/components/sessions/SessionStatusBadge.js.map +1 -1
  133. package/dist/components/shared/AgentSelector.js +4 -4
  134. package/dist/components/shared/AgentSelector.js.map +1 -1
  135. package/dist/components/shared/AgentSetupBanner.js +3 -3
  136. package/dist/components/shared/AgentSetupBanner.js.map +1 -1
  137. package/dist/components/shared/Card.js +4 -4
  138. package/dist/components/shared/Card.js.map +1 -1
  139. package/dist/components/shared/ErrorState.js +15 -9
  140. package/dist/components/shared/ErrorState.js.map +1 -1
  141. package/dist/components/shared/FilterDropdown.js +2 -2
  142. package/dist/components/shared/FilterDropdown.js.map +1 -1
  143. package/dist/components/shared/PageSkeleton.js +6 -6
  144. package/dist/components/shared/PageSkeleton.js.map +1 -1
  145. package/dist/components/shared/SearchInput.js +1 -1
  146. package/dist/components/shared/SearchInput.js.map +1 -1
  147. package/dist/components/shared/StatCard.js +7 -7
  148. package/dist/components/shared/StatCard.js.map +1 -1
  149. package/dist/components/templates/PublishTemplateForm.js +2 -2
  150. package/dist/components/templates/PublishTemplateForm.js.map +1 -1
  151. package/dist/components/templates/TemplateCard.js +5 -5
  152. package/dist/components/templates/TemplateCard.js.map +1 -1
  153. package/dist/components/templates/TemplateWizard.js +2 -2
  154. package/dist/components/templates/TemplateWizard.js.map +1 -1
  155. package/dist/components/tunnels/DomainVerificationBadge.js +4 -4
  156. package/dist/components/tunnels/DomainVerificationBadge.js.map +1 -1
  157. package/dist/components/tunnels/ProviderBadge.js +1 -1
  158. package/dist/components/tunnels/ProviderBadge.js.map +1 -1
  159. package/dist/components/tunnels/TunnelCard.js +16 -16
  160. package/dist/components/tunnels/TunnelCard.js.map +1 -1
  161. package/dist/components/tunnels/TunnelCreateWizard.js +1 -1
  162. package/dist/components/tunnels/TunnelCreateWizard.js.map +1 -1
  163. package/dist/components/tunnels/TunnelPublicAccessPanel.js +1 -1
  164. package/dist/components/tunnels/TunnelPublicAccessPanel.js.map +1 -1
  165. package/dist/components/tunnels/TunnelStatusBadge.js +4 -4
  166. package/dist/components/tunnels/TunnelStatusBadge.js.map +1 -1
  167. package/dist/components/vibecalendar/LogsDrawer.js +2 -2
  168. package/dist/components/vibecalendar/LogsDrawer.js.map +1 -1
  169. package/dist/components/vibecalendar/ScheduleTaskModal.js +5 -5
  170. package/dist/components/vibecalendar/ScheduleTaskModal.js.map +1 -1
  171. package/dist/components/vibecalendar/VibeCalAgendaView.js +2 -2
  172. package/dist/components/vibecalendar/VibeCalAgendaView.js.map +1 -1
  173. package/dist/components/vibecalendar/VibeCalDayView.js +3 -3
  174. package/dist/components/vibecalendar/VibeCalDayView.js.map +1 -1
  175. package/dist/components/vibecalendar/VibeCalMonthView.js +1 -1
  176. package/dist/components/vibecalendar/VibeCalMonthView.js.map +1 -1
  177. package/dist/components/vibecalendar/VibeCalWeekView.js +4 -4
  178. package/dist/components/vibecalendar/VibeCalWeekView.js.map +1 -1
  179. package/dist/components/vibecalendar/VibeCalendarHeader.js +4 -4
  180. package/dist/components/vibecalendar/VibeCalendarHeader.js.map +1 -1
  181. package/dist/components/vibecalendar/VibeTaskBlock.js +2 -2
  182. package/dist/components/vibecalendar/VibeTaskBlock.js.map +1 -1
  183. package/dist/components/vibecalendar/types.js +6 -6
  184. package/dist/components/vibecalendar/types.js.map +1 -1
  185. package/dist/components/vibedeck/VibeDeckButtonForm.js +9 -9
  186. package/dist/components/vibedeck/VibeDeckButtonForm.js.map +1 -1
  187. package/dist/components/vibedeck/VibeDeckButtonTile.js +6 -6
  188. package/dist/components/vibedeck/VibeDeckButtonTile.js.map +1 -1
  189. package/dist/components/vibedeck/VibeDeckExecutionLog.js +10 -10
  190. package/dist/components/vibedeck/VibeDeckExecutionLog.js.map +1 -1
  191. package/dist/components/vibedeck/VibeDeckForm.js +8 -8
  192. package/dist/components/vibedeck/VibeDeckForm.js.map +1 -1
  193. package/dist/components/vibedeck/VibeDeckGrid.js +2 -2
  194. package/dist/components/vibedeck/VibeDeckGrid.js.map +1 -1
  195. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js +2 -2
  196. package/dist/components/vibedeck/VibeDeckPublicLinkPanel.js.map +1 -1
  197. package/dist/components/vibedeck/VibeDeckSwitcher.js +8 -8
  198. package/dist/components/vibedeck/VibeDeckSwitcher.js.map +1 -1
  199. package/dist/components/vibes/VibeCard.js +22 -18
  200. package/dist/components/vibes/VibeCard.js.map +1 -1
  201. package/dist/components/vibes/VibeList.js +16 -12
  202. package/dist/components/vibes/VibeList.js.map +1 -1
  203. package/dist/pages/ActionsPage.js +4 -3
  204. package/dist/pages/ActionsPage.js.map +1 -1
  205. package/dist/pages/AgentDetailsPage.js +9 -9
  206. package/dist/pages/AgentDetailsPage.js.map +1 -1
  207. package/dist/pages/AgentsLandingPage.js +4 -4
  208. package/dist/pages/AgentsLandingPage.js.map +1 -1
  209. package/dist/pages/AgentsPage.js +14 -14
  210. package/dist/pages/AgentsPage.js.map +1 -1
  211. package/dist/pages/AnalyticsPage.js +8 -8
  212. package/dist/pages/AnalyticsPage.js.map +1 -1
  213. package/dist/pages/CatalogDetailPage.js +11 -11
  214. package/dist/pages/CatalogDetailPage.js.map +1 -1
  215. package/dist/pages/CatalogPage.js +12 -9
  216. package/dist/pages/CatalogPage.js.map +1 -1
  217. package/dist/pages/ComponentDetailPage.js +7 -7
  218. package/dist/pages/ComponentDetailPage.js.map +1 -1
  219. package/dist/pages/ComponentsPage.js +12 -9
  220. package/dist/pages/ComponentsPage.js.map +1 -1
  221. package/dist/pages/EnvTopologyPage.js +2 -2
  222. package/dist/pages/EnvTopologyPage.js.map +1 -1
  223. package/dist/pages/GettingStartedPage.js +12 -12
  224. package/dist/pages/GettingStartedPage.js.map +1 -1
  225. package/dist/pages/HealthPage.js +12 -12
  226. package/dist/pages/HealthPage.js.map +1 -1
  227. package/dist/pages/LogsPage.js +4 -4
  228. package/dist/pages/LogsPage.js.map +1 -1
  229. package/dist/pages/NoteDetailsPage.js +5 -5
  230. package/dist/pages/NoteDetailsPage.js.map +1 -1
  231. package/dist/pages/OverviewPage.js +74 -41
  232. package/dist/pages/OverviewPage.js.map +1 -1
  233. package/dist/pages/PluginsCatalogPage.js +6 -3
  234. package/dist/pages/PluginsCatalogPage.js.map +1 -1
  235. package/dist/pages/ScheduledJobDetailPage.js +7 -7
  236. package/dist/pages/ScheduledJobDetailPage.js.map +1 -1
  237. package/dist/pages/SessionDetailsPage.js +21 -21
  238. package/dist/pages/SessionDetailsPage.js.map +1 -1
  239. package/dist/pages/SessionsPage.js +20 -20
  240. package/dist/pages/SessionsPage.js.map +1 -1
  241. package/dist/pages/SettingsPage.js +64 -52
  242. package/dist/pages/SettingsPage.js.map +1 -1
  243. package/dist/pages/SharedSessionPage.js +21 -21
  244. package/dist/pages/SharedSessionPage.js.map +1 -1
  245. package/dist/pages/SharedVibeDeckPage.js +5 -5
  246. package/dist/pages/SharedVibeDeckPage.js.map +1 -1
  247. package/dist/pages/TargetDetailsPage.js +56 -65
  248. package/dist/pages/TargetDetailsPage.js.map +1 -1
  249. package/dist/pages/TargetsPage.js +4 -4
  250. package/dist/pages/TargetsPage.js.map +1 -1
  251. package/dist/pages/TemplateDetailPage.js +10 -10
  252. package/dist/pages/TemplateDetailPage.js.map +1 -1
  253. package/dist/pages/TemplatesPage.js +6 -5
  254. package/dist/pages/TemplatesPage.js.map +1 -1
  255. package/dist/pages/VibeAuditPage.js +3 -3
  256. package/dist/pages/VibeAuditPage.js.map +1 -1
  257. package/dist/pages/VibeCalendarPage.js +3 -3
  258. package/dist/pages/VibeCalendarPage.js.map +1 -1
  259. package/dist/pages/VibeDeckPage.js +3 -3
  260. package/dist/pages/VibeDeckPage.js.map +1 -1
  261. package/dist/pages/VibeDetailsPage.js +15 -15
  262. package/dist/pages/VibeDetailsPage.js.map +1 -1
  263. package/dist/pages/VibeTaskDetailPage.js +5 -5
  264. package/dist/pages/VibeTaskDetailPage.js.map +1 -1
  265. package/dist/pages/VibesPage.js +18 -18
  266. package/dist/pages/VibesPage.js.map +1 -1
  267. package/dist/pages/WebhooksPage.js +11 -11
  268. package/dist/pages/WebhooksPage.js.map +1 -1
  269. package/dist/pages/ai/AIBookmarksPage.js +1 -1
  270. package/dist/pages/ai/AIBookmarksPage.js.map +1 -1
  271. package/dist/pages/ai/AISessionDetailPage.js +6 -6
  272. package/dist/pages/ai/AISessionDetailPage.js.map +1 -1
  273. package/dist/pages/tunnels/AuditTab.js +1 -1
  274. package/dist/pages/tunnels/AuditTab.js.map +1 -1
  275. package/dist/pages/tunnels/DomainsTab.js +1 -1
  276. package/dist/pages/tunnels/DomainsTab.js.map +1 -1
  277. package/dist/pages/tunnels/ProvidersTab.js +1 -1
  278. package/dist/pages/tunnels/ProvidersTab.js.map +1 -1
  279. package/dist/pages/tunnels/SessionsTab.js +1 -1
  280. package/dist/pages/tunnels/SessionsTab.js.map +1 -1
  281. package/dist/pages/tunnels/TunnelDetailsPage.js +3 -3
  282. package/dist/pages/tunnels/TunnelDetailsPage.js.map +1 -1
  283. package/dist/pages/tunnels/UsageTab.js +1 -1
  284. package/dist/pages/tunnels/UsageTab.js.map +1 -1
  285. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js +16 -16
  286. package/dist/pages/tunnels/tabs/TunnelDomainsTab.js.map +1 -1
  287. package/dist/pages/tunnels/tabs/TunnelOverviewTab.js +1 -1
  288. package/dist/pages/tunnels/tabs/TunnelOverviewTab.js.map +1 -1
  289. package/dist/pages/tunnels/tabs/TunnelSessionsTab.js +52 -49
  290. package/dist/pages/tunnels/tabs/TunnelSessionsTab.js.map +1 -1
  291. package/dist/pages/tunnels/tabs/TunnelSettingsTab.js +9 -9
  292. package/dist/pages/tunnels/tabs/TunnelSettingsTab.js.map +1 -1
  293. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"VibeCalendarPage.js","names":[],"sources":["../../src/pages/VibeCalendarPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { CalendarClock, AlertCircle, X } from 'lucide-react';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { useTenantContext } from '@/hooks/useTenantContext';\nimport {\n VibeCalendarHeader,\n VibeCalMonthView,\n VibeCalWeekView,\n VibeCalDayView,\n VibeCalAgendaView,\n ScheduleTaskModal,\n LogsDrawer,\n} from '../components/vibecalendar';\nimport { useVibeNavigate, useVibeControls } from '@/providers/VibeControlsProvider';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type {\n CalendarViewMode,\n VibeCalendarTask,\n VibeCalendarExecution,\n ScheduleTaskInput,\n} from '../components/vibecalendar';\nimport {\n expandJobsToOccurrences,\n type SchedulerJobLike,\n} from '../components/vibecalendar/expandOccurrences';\nimport {\n useCreateVibeCalendarTaskMutation,\n useExecuteScheduledJobNowMutation,\n useTriggerVibeCalendarTaskNowMutation,\n} from '@/generated/wspace-operations';\n\n/**\n * The /scheduler page writes ScheduledJobs through the WSPACE gateway —\n * `scheduledJobs` is only published by `wspace-scheduler-svc` and is\n * workspace-scoped (the `$workspaceId: ID!` argument is required). The\n * Calendar renders those jobs alongside its own VibeCalendarTasks. We use\n * `graphqlFetch` rather than Apollo to keep the Calendar's local-state\n * timeline decoupled from the global Apollo cache that powers other\n * VibeControls pages.\n */\nconst WORKSPACE_SCHEDULED_JOBS_QUERY = /* GraphQL */ `\n query GetWorkspaceScheduledJobsForCalendar($workspaceId: ID!) {\n scheduledJobs(workspaceId: $workspaceId, pagination: { first: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n }\n }\n`;\n\ninterface WorkspaceScheduledJobsResponse {\n scheduledJobs: {\n jobs: SchedulerJobLike[];\n total: number;\n };\n}\n\n/**\n * Calendar Page\n *\n * Main page for scheduling and managing tasks on VibeControls agents.\n * Supports month and agenda views with task creation, on-demand triggering,\n * and log viewing via the LogsDrawer.\n */\nexport function VibeCalendarPage() {\n const navigate = useVibeNavigate();\n const { workspaceId } = useVibeControls();\n const { t } = useI18n();\n const { viewType } = useParams<{ viewType?: string }>();\n const [searchParams, setSearchParams] = useSearchParams();\n // When navigated here from the Actions page via \"Add to calendar\",\n // the URL carries ?actionId=... — open the modal in Action-linked mode.\n const prefillActionId = searchParams.get('actionId') ?? undefined;\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n // The unified-source migration moved the calendar's only list\n // path onto `scheduledJobs(workspaceId)` (the scheduler subgraph) —\n // there's no parallel `vibeCalendarTasks` query firing here\n // anymore. The page-level access gate is therefore\n // `schedule:read` specifically; admitting calendar-task-only\n // readers would let them past the UI only to hit an empty\n // calendar / scheduler RBAC denial on the actual fetch.\n // calendar-agent-task permissions are still consumed downstream\n // (CREATE for the schedule button, EXECUTE for the per-tile ▶\n // branch) but they don't gate the page mount.\n const canList = hasPermission(VIBE_PERMISSIONS.SCHEDULE_READ);\n // Required by the @include gate on `output`/`errorMessage` in\n // both run-now mutations — without this Apollo rejects the\n // operation before it leaves the browser.\n const canReadExecutionLogs = hasPermission(VIBE_PERMISSIONS.LOG_READ);\n const canCreate = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_CREATE);\n // The agenda exclusively renders ScheduledJob tiles in the\n // current unified-source path, so the prop-level gate on\n // `onTriggerNow` is `schedule:execute` — admitting\n // `calendar-agent-task:execute`-only users would show ▶ on every\n // tile just to bounce off a friendly denial banner. Both\n // permissions stay tracked because handleTriggerNow's per-source\n // pre-check uses them defensively in case a future mixed-source\n // render lands here.\n const canExecuteCalendarTask = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_EXECUTE);\n const canExecuteScheduledJob = hasPermission(VIBE_PERMISSIONS.SCHEDULE_EXECUTE);\n const canExecute = canExecuteScheduledJob;\n\n // URL overrides reach Apollo via per-request headers so tile-▶\n // mutations stay in the same tenant the support deep-link list\n // loaded against.\n const tenantContext = useTenantContext();\n\n const [currentDate, setCurrentDate] = useState(new Date());\n const [viewMode, setViewMode] = useState<CalendarViewMode>(\n (viewType as CalendarViewMode) || 'month'\n );\n const [showCreateModal, setShowCreateModal] = useState(false);\n\n // Auto-open the modal when arriving with an actionId query param.\n useEffect(() => {\n if (prefillActionId) {\n setShowCreateModal(true);\n }\n }, [prefillActionId]);\n const [showLogsDrawer, setShowLogsDrawer] = useState(false);\n const [selectedTask, setSelectedTask] = useState<VibeCalendarTask | null>(null);\n const [selectedExecution, setSelectedExecution] = useState<VibeCalendarExecution | null>(null);\n const [triggerError, setTriggerError] = useState<string | null>(null);\n\n // Memoized so downstream useCallback deps stay referentially\n // stable across renders.\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n // Calculate date range for current view\n const dateRange = useMemo(() => {\n const start = new Date(currentDate);\n const end = new Date(currentDate);\n\n switch (viewMode) {\n case 'month':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'week':\n start.setDate(start.getDate() - start.getDay());\n start.setHours(0, 0, 0, 0);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n break;\n case 'day':\n start.setHours(0, 0, 0, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'agenda':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n }\n\n return { startDate: start.toISOString(), endDate: end.toISOString() };\n }, [currentDate, viewMode]);\n\n // Unified calendar view: fetch every ScheduledJob the workspace owns\n // (where /scheduler writes). The calendar renders jobs regardless of how\n // they were created, so all schedule-to-Action tasks show up here as a\n // single source of truth.\n //\n // `scheduledJobs` is published by `wspace-scheduler-svc` and is workspace-\n // scoped — `workspaceId` is required as a query variable. `graphqlFetch`\n // auto-resolves the workspace/org/tenant context from the shell storage\n // and sets the matching headers; URL params (`?org=`, `?tenant=`)\n // override that resolution for the support-tooling deep-link flow.\n const [jobs, setJobs] = useState<SchedulerJobLike[]>([]);\n const [rangeError, setRangeError] = useState<Error | undefined>(undefined);\n const [jobsLoaded, setJobsLoaded] = useState(false);\n const [jobsLoading, setJobsLoading] = useState(false);\n const refetch = useCallback(async () => {\n // Guard: scheduledJobs requires workspaceId — if it isn't resolved yet,\n // skip rather than firing a request that's guaranteed to fail validation.\n // The effect below re-invokes refetch once workspaceId becomes available.\n // (The state-reset on workspace transitions lives in the effect itself,\n // not here, because the effect early-returns when workspaceId is falsy\n // and refetch never gets called in that path.)\n if (!workspaceId) return;\n setJobsLoading(true);\n try {\n // graphqlFetch reads workspace/org/tenant context from storage and sets\n // the proper x-workspace-id / x-org-id / x-tenant-id headers itself —\n // passing `true` opts in to that auto-resolution. URL params override\n // storage for the org/tenant context (used by the support tooling\n // when impersonating a different tenant via deep-link).\n const urlParams = new URLSearchParams(\n typeof window === 'undefined' ? '' : window.location.search\n );\n const orgFromUrl = urlParams.get('org') ?? undefined;\n const tenantFromUrl = urlParams.get('tenant') ?? undefined;\n\n const res = await graphqlFetch<WorkspaceScheduledJobsResponse>({\n gateway: 'workspace',\n query: WORKSPACE_SCHEDULED_JOBS_QUERY,\n operationName: 'GetWorkspaceScheduledJobsForCalendar',\n variables: { workspaceId },\n // Pass the resolved workspaceId STRING (not `true`) so the\n // `x-workspace-id` header matches the GraphQL variable even when\n // ActiveContextStorage is stale / not hydrated yet. Otherwise the\n // gateway can authorize/federate against the previous workspace's\n // context while the resolver receives the new one.\n workspaceId,\n organizationId: orgFromUrl ?? true,\n tenantId: tenantFromUrl ?? true,\n });\n\n if (res.errors && res.errors.length) {\n // Wrap GraphQL/network errors in a generic, UI-safe Error so we\n // never leak raw resolver / federation messages into the banner.\n throw new Error(res.errors[0]?.message ?? 'Unable to load scheduled tasks');\n }\n setJobs(res.data?.scheduledJobs?.jobs ?? []);\n setRangeError(undefined);\n setJobsLoaded(true);\n } catch (err) {\n console.error('[VibeCalendarPage] Failed to load scheduled jobs:', err);\n setRangeError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setJobsLoading(false);\n }\n }, [workspaceId]);\n\n useEffect(() => {\n if (!workspaceId) {\n // Reset on workspace transitions so the empty-state CTA doesn't\n // flash stale data from the previous workspace while the new one\n // is still resolving. Lives here, not in refetch, because refetch\n // is only called from this effect — when workspaceId is falsy,\n // refetch never runs.\n setJobs([]);\n setRangeError(undefined);\n setJobsLoaded(false);\n return;\n }\n void refetch();\n }, [workspaceId, refetch]);\n\n // `sourceById` built in the same pass so handleTriggerNow does\n // an O(1) Map lookup per click — month/agenda views can mint\n // hundreds of occurrences from a single recurring job.\n const { occurrences, sourceById } = useMemo(() => {\n if (!jobs.length) {\n return {\n occurrences: [],\n sourceById: new Map<string, VibeCalendarTask['source']>(),\n };\n }\n const occs = expandJobsToOccurrences(\n jobs,\n new Date(dateRange.startDate),\n new Date(dateRange.endDate)\n );\n const map = new Map<string, VibeCalendarTask['source']>();\n for (const o of occs) {\n // Always populate with an explicit discriminator. Future\n // shapes (e.g. an externalTrigger source) would otherwise\n // collapse into the default branch silently — `undefined`\n // here means \"id no longer in the visible window\", nothing\n // more.\n map.set(o.task.id, o.task.source ?? 'vibeCalendarTask');\n }\n return { occurrences: occs, sourceById: map };\n }, [jobs, dateRange.startDate, dateRange.endDate]);\n\n // Agents are no longer collected in the modal — the scheduler resolves\n // them from the referenced Action at execution time.\n\n // Mutations\n const [createTaskMutation, { loading: createLoading }] = useCreateVibeCalendarTaskMutation();\n const [triggerNowMutation] = useTriggerVibeCalendarTaskNowMutation();\n // Scheduled-job tiles route to the scheduler subgraph rather than\n // the calendar one (different id space, different RBAC resource).\n const [executeScheduledJobNowMutation] = useExecuteScheduledJobNowMutation();\n\n const handleViewModeChange = useCallback((mode: CalendarViewMode) => {\n setViewMode(mode);\n }, []);\n\n // `undefined` return signals \"no longer in the visible window\" —\n // callers should treat that as the safe default `'vibeCalendarTask'`.\n const sourceForTask = useCallback(\n (taskId: string): VibeCalendarTask['source'] => {\n return sourceById.get(taskId);\n },\n [sourceById]\n );\n\n const handleTriggerNow = useCallback(\n async (taskId: string) => {\n // Clear any prior failure banner before re-attempting — same\n // pattern as ScheduledJobDetailPage.handleExecuteNow.\n setTriggerError(null);\n // Branch on the discriminator set by `jobToVibeCalendarTask`.\n // The view passes `onTriggerNow` to every tile when EITHER\n // permission is held (combined `canExecute` gate above), so we\n // pre-check the per-source permission here and surface a\n // friendly inline banner if missing rather than firing the\n // mutation just to bounce off a server-side RBAC denial.\n const source = sourceForTask(taskId);\n if (source === 'scheduledJob' && !canExecuteScheduledJob) {\n setTriggerError(\n tr(\n 'calendar.scheduleExecuteDenied',\n 'You do not have permission to run scheduled jobs (schedule:execute).'\n )\n );\n return;\n }\n if (source !== 'scheduledJob' && !canExecuteCalendarTask) {\n setTriggerError(\n tr(\n 'calendar.calendarTaskExecuteDenied',\n 'You do not have permission to run calendar tasks (calendar-agent-task:execute).'\n )\n );\n return;\n }\n // VibeControlsProvider sets `errorPolicy: 'all'` so RBAC /\n // GraphQL errors resolve into `result.error` (ApolloError)\n // instead of throwing. Inspect both paths consistently —\n // denials would otherwise be silently dropped. Same pattern\n // ActionsPage already uses for quota-exhaust handling.\n const fallbackMsg = tr(\n 'calendar.triggerFailedFallback',\n 'Failed to trigger task. Try again or contact support.'\n );\n try {\n const result =\n source === 'scheduledJob'\n ? await executeScheduledJobNowMutation({\n variables: { id: taskId, canReadLogs: canReadExecutionLogs },\n context: tenantContext,\n })\n : await triggerNowMutation({\n variables: { id: taskId },\n context: tenantContext,\n });\n if (result.error) {\n console.error('Trigger mutation returned an Apollo error:', result.error);\n setTriggerError(result.error.message || fallbackMsg);\n }\n } catch (err) {\n console.error('Failed to trigger task:', err);\n const msg = err instanceof Error && err.message ? err.message : fallbackMsg;\n setTriggerError(msg);\n }\n },\n [\n triggerNowMutation,\n executeScheduledJobNowMutation,\n sourceForTask,\n canReadExecutionLogs,\n canExecuteCalendarTask,\n canExecuteScheduledJob,\n tenantContext,\n tr,\n ]\n );\n\n const handleViewLogs = useCallback((task: VibeCalendarTask) => {\n setSelectedTask(task);\n setSelectedExecution(null);\n setShowLogsDrawer(true);\n }, []);\n\n const handleViewDetail = useCallback(\n (taskId: string) => {\n // A tile that originated from a ScheduledJob has no row in\n // wspace-calendar-svc, so VibeTaskDetailPage would 404 on it.\n // Route to the matching in-product detail page instead.\n //\n // Carry the existing query string so the support deep-link\n // flow (`?org=…&tenant=…`) keeps its tenant context across\n // the navigation — without it the detail query runs against\n // the default/stored tenant and returns a wrong-context view.\n // Encode the id for defense-in-depth in case the scheduler\n // ever emits ids that contain URL-reserved characters.\n const encoded = encodeURIComponent(taskId);\n const search = searchParams.toString();\n const suffix = search ? `?${search}` : '';\n const path =\n sourceForTask(taskId) === 'scheduledJob'\n ? `/calendar/scheduled-job/${encoded}`\n : `/calendar/task/${encoded}`;\n navigate(`${path}${suffix}`);\n },\n [navigate, sourceForTask, searchParams]\n );\n\n const handleCreateTask = useCallback(\n async (input: ScheduleTaskInput) => {\n try {\n // Calendar entries always delegate execution to a VibeControls\n // Action. The scheduler resolves agent/command/webhook details\n // from the Action definition at run time — we only send\n // actionId + calendar/schedule config from this modal.\n await createTaskMutation({\n variables: {\n input: {\n calendarId: input.calendarId || 'default',\n title: input.title,\n description: input.description,\n actionId: input.actionId,\n scheduleType: input.scheduleType,\n scheduledAt: input.scheduledAt,\n cronExpression: input.cronExpression,\n interval: input.interval,\n intervalUnit: input.intervalUnit,\n timezone: input.timezone,\n },\n },\n });\n await refetch();\n setShowCreateModal(false);\n // Drop the actionId query param after successful creation\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n } catch (err) {\n console.error('Failed to create task:', err);\n }\n },\n [createTaskMutation, refetch, searchParams, setSearchParams]\n );\n\n if (permissionsLoading)\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <LoadingState message={tr('calendar.loadingPermissions', 'Loading permissions...')} />\n </MotionPage>\n );\n\n if (permissions && permissions.permissionStrings?.length > 0 && !canList) {\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <AccessDenied\n title={tr('common.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'calendar.accessDeniedDescription',\n \"You don't have permission to view the Calendar.\"\n )}\n />\n </MotionPage>\n );\n }\n\n // Show the empty-state CTA only after the first successful load returned\n // an empty list — never while loading, and never when an error blocks the\n // distinction between \"no data\" and \"couldn't fetch\".\n const showEmptyState = jobsLoaded && !rangeError && jobs.length === 0;\n\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n {/* Error banner (non-blocking) — friendly message, never raw GraphQL */}\n {rangeError && jobs.length === 0 && (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2\">\n <AlertCircle size={16} className=\"text-status-error-text flex-shrink-0\" />\n <p className=\"flex-1 text-sm text-status-error-text\">\n {tr(\n 'calendar.couldNotLoadEvents',\n \"Could not load events. We'll keep trying — you can retry below.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={jobsLoading}\n className=\"rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg/80 disabled:opacity-50\"\n >\n {tr('calendar.retry', 'Retry')}\n </button>\n </div>\n )}\n\n {triggerError && (\n <div\n role=\"alert\"\n className=\"flex items-start gap-2 rounded-lg border border-status-error-border/30 bg-status-error-bg/10 px-3 py-2 text-sm text-status-error-text\"\n >\n <AlertCircle size={16} className=\"mt-0.5 flex-shrink-0\" />\n <p className=\"flex-1 break-words\">{triggerError}</p>\n <button\n type=\"button\"\n onClick={() => setTriggerError(null)}\n className=\"p-0.5 rounded hover:bg-status-error-bg/20 transition-colors\"\n aria-label={tr('common.dismiss', 'Dismiss')}\n >\n <X size={14} />\n </button>\n </div>\n )}\n\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-2\">\n <CalendarClock size={24} className=\"text-text-primary\" />\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('nav.vibeCalendar', 'Calendar')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('calendar.description', 'Schedule and manage tasks across your agents')}\n </p>\n </div>\n </div>\n\n {/* Empty-state CTA shown when the user has no scheduled tasks yet. */}\n {showEmptyState && (\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 rounded-lg border border-border-default bg-bg-surface px-4 py-3\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('calendar.empty.title', 'No scheduled tasks yet')}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {tr(\n 'calendar.empty.description',\n 'Schedule your first task to start automating actions across your agents.'\n )}\n </p>\n </div>\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => setShowCreateModal(true)}\n className=\"px-3 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('calendar.empty.cta', 'Schedule your first task')}\n </button>\n )}\n </div>\n )}\n\n {/* Calendar Header with nav + view switcher */}\n <div data-tour=\"calendar-header\">\n <VibeCalendarHeader\n currentDate={currentDate}\n viewMode={viewMode}\n onDateChange={setCurrentDate}\n onViewModeChange={handleViewModeChange}\n onCreateTask={canCreate ? () => setShowCreateModal(true) : undefined}\n />\n </div>\n\n {/* Calendar Body */}\n <div data-tour=\"calendar-view-container\" className=\"flex-1 overflow-hidden\">\n {viewMode === 'month' && (\n <VibeCalMonthView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'week' && (\n <VibeCalWeekView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'day' && (\n <VibeCalDayView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'agenda' && (\n <VibeCalAgendaView\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n </div>\n\n {/* Schedule Task Modal */}\n <ScheduleTaskModal\n isOpen={showCreateModal}\n onClose={() => {\n setShowCreateModal(false);\n // Strip the actionId query param on dismiss so reopening the\n // modal without a fresh navigation doesn't silently resume\n // Action-linked mode.\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n }}\n onSubmit={handleCreateTask}\n loading={createLoading}\n prefillActionId={prefillActionId}\n />\n\n {/* Logs Drawer */}\n <LogsDrawer\n isOpen={showLogsDrawer}\n onClose={() => setShowLogsDrawer(false)}\n execution={selectedExecution}\n taskTitle={selectedTask?.title || ''}\n agentId={selectedTask?.agentId || ''}\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"VibeCalendarPage.js","names":[],"sources":["../../src/pages/VibeCalendarPage.tsx"],"sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport { useParams, useSearchParams } from 'react-router-dom';\nimport { CalendarClock, AlertCircle, X } from 'lucide-react';\nimport { MotionPage } from '@burdenoff/fe-libs/shared/motion';\nimport { AccessDenied } from '@burdenoff/fe-libs/shared/components';\nimport { LoadingState } from '@/components/shared/LoadingState';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { VIBE_PERMISSIONS } from '@/constants/permissions';\nimport { useTenantContext } from '@/hooks/useTenantContext';\nimport {\n VibeCalendarHeader,\n VibeCalMonthView,\n VibeCalWeekView,\n VibeCalDayView,\n VibeCalAgendaView,\n ScheduleTaskModal,\n LogsDrawer,\n} from '../components/vibecalendar';\nimport { useVibeNavigate, useVibeControls } from '@/providers/VibeControlsProvider';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\nimport type {\n CalendarViewMode,\n VibeCalendarTask,\n VibeCalendarExecution,\n ScheduleTaskInput,\n} from '../components/vibecalendar';\nimport {\n expandJobsToOccurrences,\n type SchedulerJobLike,\n} from '../components/vibecalendar/expandOccurrences';\nimport {\n useCreateVibeCalendarTaskMutation,\n useExecuteScheduledJobNowMutation,\n useTriggerVibeCalendarTaskNowMutation,\n} from '@/generated/wspace-operations';\n\n/**\n * The /scheduler page writes ScheduledJobs through the WSPACE gateway —\n * `scheduledJobs` is only published by `wspace-scheduler-svc` and is\n * workspace-scoped (the `$workspaceId: ID!` argument is required). The\n * Calendar renders those jobs alongside its own VibeCalendarTasks. We use\n * `graphqlFetch` rather than Apollo to keep the Calendar's local-state\n * timeline decoupled from the global Apollo cache that powers other\n * VibeControls pages.\n */\nconst WORKSPACE_SCHEDULED_JOBS_QUERY = /* GraphQL */ `\n query GetWorkspaceScheduledJobsForCalendar($workspaceId: ID!) {\n scheduledJobs(workspaceId: $workspaceId, pagination: { first: 500 }) {\n jobs {\n id\n name\n description\n status\n scheduleType\n cronExpression\n rrule\n interval\n scheduledAt\n nextExecutionAt\n lastExecutionAt\n actionId\n timezone\n startDate\n endDate\n }\n total\n }\n }\n`;\n\ninterface WorkspaceScheduledJobsResponse {\n scheduledJobs: {\n jobs: SchedulerJobLike[];\n total: number;\n };\n}\n\n/**\n * Calendar Page\n *\n * Main page for scheduling and managing tasks on VibeControls agents.\n * Supports month and agenda views with task creation, on-demand triggering,\n * and log viewing via the LogsDrawer.\n */\nexport function VibeCalendarPage() {\n const navigate = useVibeNavigate();\n const { workspaceId } = useVibeControls();\n const { t } = useI18n();\n const { viewType } = useParams<{ viewType?: string }>();\n const [searchParams, setSearchParams] = useSearchParams();\n // When navigated here from the Actions page via \"Add to calendar\",\n // the URL carries ?actionId=... — open the modal in Action-linked mode.\n const prefillActionId = searchParams.get('actionId') ?? undefined;\n const { hasPermission, isLoading: permissionsLoading, permissions } = usePermissions();\n // The unified-source migration moved the calendar's only list\n // path onto `scheduledJobs(workspaceId)` (the scheduler subgraph) —\n // there's no parallel `vibeCalendarTasks` query firing here\n // anymore. The page-level access gate is therefore\n // `schedule:read` specifically; admitting calendar-task-only\n // readers would let them past the UI only to hit an empty\n // calendar / scheduler RBAC denial on the actual fetch.\n // calendar-agent-task permissions are still consumed downstream\n // (CREATE for the schedule button, EXECUTE for the per-tile ▶\n // branch) but they don't gate the page mount.\n const canList = hasPermission(VIBE_PERMISSIONS.SCHEDULE_READ);\n // Required by the @include gate on `output`/`errorMessage` in\n // both run-now mutations — without this Apollo rejects the\n // operation before it leaves the browser.\n const canReadExecutionLogs = hasPermission(VIBE_PERMISSIONS.LOG_READ);\n const canCreate = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_CREATE);\n // The agenda exclusively renders ScheduledJob tiles in the\n // current unified-source path, so the prop-level gate on\n // `onTriggerNow` is `schedule:execute` — admitting\n // `calendar-agent-task:execute`-only users would show ▶ on every\n // tile just to bounce off a friendly denial banner. Both\n // permissions stay tracked because handleTriggerNow's per-source\n // pre-check uses them defensively in case a future mixed-source\n // render lands here.\n const canExecuteCalendarTask = hasPermission(VIBE_PERMISSIONS.CALENDAR_AGENT_TASK_EXECUTE);\n const canExecuteScheduledJob = hasPermission(VIBE_PERMISSIONS.SCHEDULE_EXECUTE);\n const canExecute = canExecuteScheduledJob;\n\n // URL overrides reach Apollo via per-request headers so tile-▶\n // mutations stay in the same tenant the support deep-link list\n // loaded against.\n const tenantContext = useTenantContext();\n\n const [currentDate, setCurrentDate] = useState(new Date());\n const [viewMode, setViewMode] = useState<CalendarViewMode>(\n (viewType as CalendarViewMode) || 'month'\n );\n const [showCreateModal, setShowCreateModal] = useState(false);\n\n // Auto-open the modal when arriving with an actionId query param.\n useEffect(() => {\n if (prefillActionId) {\n setShowCreateModal(true);\n }\n }, [prefillActionId]);\n const [showLogsDrawer, setShowLogsDrawer] = useState(false);\n const [selectedTask, setSelectedTask] = useState<VibeCalendarTask | null>(null);\n const [selectedExecution, setSelectedExecution] = useState<VibeCalendarExecution | null>(null);\n const [triggerError, setTriggerError] = useState<string | null>(null);\n\n // Memoized so downstream useCallback deps stay referentially\n // stable across renders.\n const tr = useCallback(\n (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n },\n [t]\n );\n\n // Calculate date range for current view\n const dateRange = useMemo(() => {\n const start = new Date(currentDate);\n const end = new Date(currentDate);\n\n switch (viewMode) {\n case 'month':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'week':\n start.setDate(start.getDate() - start.getDay());\n start.setHours(0, 0, 0, 0);\n end.setDate(start.getDate() + 6);\n end.setHours(23, 59, 59, 999);\n break;\n case 'day':\n start.setHours(0, 0, 0, 0);\n end.setHours(23, 59, 59, 999);\n break;\n case 'agenda':\n start.setDate(1);\n start.setHours(0, 0, 0, 0);\n end.setMonth(end.getMonth() + 1, 0);\n end.setHours(23, 59, 59, 999);\n break;\n }\n\n return { startDate: start.toISOString(), endDate: end.toISOString() };\n }, [currentDate, viewMode]);\n\n // Unified calendar view: fetch every ScheduledJob the workspace owns\n // (where /scheduler writes). The calendar renders jobs regardless of how\n // they were created, so all schedule-to-Action tasks show up here as a\n // single source of truth.\n //\n // `scheduledJobs` is published by `wspace-scheduler-svc` and is workspace-\n // scoped — `workspaceId` is required as a query variable. `graphqlFetch`\n // auto-resolves the workspace/org/tenant context from the shell storage\n // and sets the matching headers; URL params (`?org=`, `?tenant=`)\n // override that resolution for the support-tooling deep-link flow.\n const [jobs, setJobs] = useState<SchedulerJobLike[]>([]);\n const [rangeError, setRangeError] = useState<Error | undefined>(undefined);\n const [jobsLoaded, setJobsLoaded] = useState(false);\n const [jobsLoading, setJobsLoading] = useState(false);\n const refetch = useCallback(async () => {\n // Guard: scheduledJobs requires workspaceId — if it isn't resolved yet,\n // skip rather than firing a request that's guaranteed to fail validation.\n // The effect below re-invokes refetch once workspaceId becomes available.\n // (The state-reset on workspace transitions lives in the effect itself,\n // not here, because the effect early-returns when workspaceId is falsy\n // and refetch never gets called in that path.)\n if (!workspaceId) return;\n setJobsLoading(true);\n try {\n // graphqlFetch reads workspace/org/tenant context from storage and sets\n // the proper x-workspace-id / x-org-id / x-tenant-id headers itself —\n // passing `true` opts in to that auto-resolution. URL params override\n // storage for the org/tenant context (used by the support tooling\n // when impersonating a different tenant via deep-link).\n const urlParams = new URLSearchParams(\n typeof window === 'undefined' ? '' : window.location.search\n );\n const orgFromUrl = urlParams.get('org') ?? undefined;\n const tenantFromUrl = urlParams.get('tenant') ?? undefined;\n\n const res = await graphqlFetch<WorkspaceScheduledJobsResponse>({\n gateway: 'workspace',\n query: WORKSPACE_SCHEDULED_JOBS_QUERY,\n operationName: 'GetWorkspaceScheduledJobsForCalendar',\n variables: { workspaceId },\n // Pass the resolved workspaceId STRING (not `true`) so the\n // `x-workspace-id` header matches the GraphQL variable even when\n // ActiveContextStorage is stale / not hydrated yet. Otherwise the\n // gateway can authorize/federate against the previous workspace's\n // context while the resolver receives the new one.\n workspaceId,\n organizationId: orgFromUrl ?? true,\n tenantId: tenantFromUrl ?? true,\n });\n\n if (res.errors && res.errors.length) {\n // Wrap GraphQL/network errors in a generic, UI-safe Error so we\n // never leak raw resolver / federation messages into the banner.\n throw new Error(res.errors[0]?.message ?? 'Unable to load scheduled tasks');\n }\n setJobs(res.data?.scheduledJobs?.jobs ?? []);\n setRangeError(undefined);\n setJobsLoaded(true);\n } catch (err) {\n console.error('[VibeCalendarPage] Failed to load scheduled jobs:', err);\n setRangeError(err instanceof Error ? err : new Error(String(err)));\n } finally {\n setJobsLoading(false);\n }\n }, [workspaceId]);\n\n useEffect(() => {\n if (!workspaceId) {\n // Reset on workspace transitions so the empty-state CTA doesn't\n // flash stale data from the previous workspace while the new one\n // is still resolving. Lives here, not in refetch, because refetch\n // is only called from this effect — when workspaceId is falsy,\n // refetch never runs.\n setJobs([]);\n setRangeError(undefined);\n setJobsLoaded(false);\n return;\n }\n void refetch();\n }, [workspaceId, refetch]);\n\n // `sourceById` built in the same pass so handleTriggerNow does\n // an O(1) Map lookup per click — month/agenda views can mint\n // hundreds of occurrences from a single recurring job.\n const { occurrences, sourceById } = useMemo(() => {\n if (!jobs.length) {\n return {\n occurrences: [],\n sourceById: new Map<string, VibeCalendarTask['source']>(),\n };\n }\n const occs = expandJobsToOccurrences(\n jobs,\n new Date(dateRange.startDate),\n new Date(dateRange.endDate)\n );\n const map = new Map<string, VibeCalendarTask['source']>();\n for (const o of occs) {\n // Always populate with an explicit discriminator. Future\n // shapes (e.g. an externalTrigger source) would otherwise\n // collapse into the default branch silently — `undefined`\n // here means \"id no longer in the visible window\", nothing\n // more.\n map.set(o.task.id, o.task.source ?? 'vibeCalendarTask');\n }\n return { occurrences: occs, sourceById: map };\n }, [jobs, dateRange.startDate, dateRange.endDate]);\n\n // Agents are no longer collected in the modal — the scheduler resolves\n // them from the referenced Action at execution time.\n\n // Mutations\n const [createTaskMutation, { loading: createLoading }] = useCreateVibeCalendarTaskMutation();\n const [triggerNowMutation] = useTriggerVibeCalendarTaskNowMutation();\n // Scheduled-job tiles route to the scheduler subgraph rather than\n // the calendar one (different id space, different RBAC resource).\n const [executeScheduledJobNowMutation] = useExecuteScheduledJobNowMutation();\n\n const handleViewModeChange = useCallback((mode: CalendarViewMode) => {\n setViewMode(mode);\n }, []);\n\n // `undefined` return signals \"no longer in the visible window\" —\n // callers should treat that as the safe default `'vibeCalendarTask'`.\n const sourceForTask = useCallback(\n (taskId: string): VibeCalendarTask['source'] => {\n return sourceById.get(taskId);\n },\n [sourceById]\n );\n\n const handleTriggerNow = useCallback(\n async (taskId: string) => {\n // Clear any prior failure banner before re-attempting — same\n // pattern as ScheduledJobDetailPage.handleExecuteNow.\n setTriggerError(null);\n // Branch on the discriminator set by `jobToVibeCalendarTask`.\n // The view passes `onTriggerNow` to every tile when EITHER\n // permission is held (combined `canExecute` gate above), so we\n // pre-check the per-source permission here and surface a\n // friendly inline banner if missing rather than firing the\n // mutation just to bounce off a server-side RBAC denial.\n const source = sourceForTask(taskId);\n if (source === 'scheduledJob' && !canExecuteScheduledJob) {\n setTriggerError(\n tr(\n 'calendar.scheduleExecuteDenied',\n 'You do not have permission to run scheduled jobs (schedule:execute).'\n )\n );\n return;\n }\n if (source !== 'scheduledJob' && !canExecuteCalendarTask) {\n setTriggerError(\n tr(\n 'calendar.calendarTaskExecuteDenied',\n 'You do not have permission to run calendar tasks (calendar-agent-task:execute).'\n )\n );\n return;\n }\n // VibeControlsProvider sets `errorPolicy: 'all'` so RBAC /\n // GraphQL errors resolve into `result.error` (ApolloError)\n // instead of throwing. Inspect both paths consistently —\n // denials would otherwise be silently dropped. Same pattern\n // ActionsPage already uses for quota-exhaust handling.\n const fallbackMsg = tr(\n 'calendar.triggerFailedFallback',\n 'Failed to trigger task. Try again or contact support.'\n );\n try {\n const result =\n source === 'scheduledJob'\n ? await executeScheduledJobNowMutation({\n variables: { id: taskId, canReadLogs: canReadExecutionLogs },\n context: tenantContext,\n })\n : await triggerNowMutation({\n variables: { id: taskId },\n context: tenantContext,\n });\n if (result.error) {\n console.error('Trigger mutation returned an Apollo error:', result.error);\n setTriggerError(result.error.message || fallbackMsg);\n }\n } catch (err) {\n console.error('Failed to trigger task:', err);\n const msg = err instanceof Error && err.message ? err.message : fallbackMsg;\n setTriggerError(msg);\n }\n },\n [\n triggerNowMutation,\n executeScheduledJobNowMutation,\n sourceForTask,\n canReadExecutionLogs,\n canExecuteCalendarTask,\n canExecuteScheduledJob,\n tenantContext,\n tr,\n ]\n );\n\n const handleViewLogs = useCallback((task: VibeCalendarTask) => {\n setSelectedTask(task);\n setSelectedExecution(null);\n setShowLogsDrawer(true);\n }, []);\n\n const handleViewDetail = useCallback(\n (taskId: string) => {\n // A tile that originated from a ScheduledJob has no row in\n // wspace-calendar-svc, so VibeTaskDetailPage would 404 on it.\n // Route to the matching in-product detail page instead.\n //\n // Carry the existing query string so the support deep-link\n // flow (`?org=…&tenant=…`) keeps its tenant context across\n // the navigation — without it the detail query runs against\n // the default/stored tenant and returns a wrong-context view.\n // Encode the id for defense-in-depth in case the scheduler\n // ever emits ids that contain URL-reserved characters.\n const encoded = encodeURIComponent(taskId);\n const search = searchParams.toString();\n const suffix = search ? `?${search}` : '';\n const path =\n sourceForTask(taskId) === 'scheduledJob'\n ? `/calendar/scheduled-job/${encoded}`\n : `/calendar/task/${encoded}`;\n navigate(`${path}${suffix}`);\n },\n [navigate, sourceForTask, searchParams]\n );\n\n const handleCreateTask = useCallback(\n async (input: ScheduleTaskInput) => {\n try {\n // Calendar entries always delegate execution to a VibeControls\n // Action. The scheduler resolves agent/command/webhook details\n // from the Action definition at run time — we only send\n // actionId + calendar/schedule config from this modal.\n await createTaskMutation({\n variables: {\n input: {\n calendarId: input.calendarId || 'default',\n title: input.title,\n description: input.description,\n actionId: input.actionId,\n scheduleType: input.scheduleType,\n scheduledAt: input.scheduledAt,\n cronExpression: input.cronExpression,\n interval: input.interval,\n intervalUnit: input.intervalUnit,\n timezone: input.timezone,\n },\n },\n });\n await refetch();\n setShowCreateModal(false);\n // Drop the actionId query param after successful creation\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n } catch (err) {\n console.error('Failed to create task:', err);\n }\n },\n [createTaskMutation, refetch, searchParams, setSearchParams]\n );\n\n if (permissionsLoading)\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <LoadingState message={tr('calendar.loadingPermissions', 'Loading permissions...')} />\n </MotionPage>\n );\n\n if (permissions && permissions.permissionStrings?.length > 0 && !canList) {\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n <AccessDenied\n title={tr('common.accessDeniedTitle', 'Access Denied')}\n description={tr(\n 'calendar.accessDeniedDescription',\n \"You don't have permission to view the Calendar.\"\n )}\n />\n </MotionPage>\n );\n }\n\n // Show the empty-state CTA only after the first successful load returned\n // an empty list — never while loading, and never when an error blocks the\n // distinction between \"no data\" and \"couldn't fetch\".\n const showEmptyState = jobsLoaded && !rangeError && jobs.length === 0;\n\n return (\n <MotionPage className=\"flex flex-col h-full p-4 gap-4\">\n {/* Error banner (non-blocking) — friendly message, never raw GraphQL */}\n {rangeError && jobs.length === 0 && (\n <div className=\"flex items-center gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-4 py-2\">\n <AlertCircle size={16} className=\"text-status-error-text flex-shrink-0\" />\n <p className=\"flex-1 text-sm text-status-error-text\">\n {tr(\n 'calendar.couldNotLoadEvents',\n \"Could not load events. We'll keep trying — you can retry below.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={jobsLoading}\n className=\"rounded px-3 py-1 text-xs text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n {tr('calendar.retry', 'Retry')}\n </button>\n </div>\n )}\n\n {triggerError && (\n <div\n role=\"alert\"\n className=\"flex items-start gap-2 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\"\n >\n <AlertCircle size={16} className=\"mt-0.5 flex-shrink-0\" />\n <p className=\"flex-1 break-words\">{triggerError}</p>\n <button\n type=\"button\"\n onClick={() => setTriggerError(null)}\n className=\"p-0.5 rounded hover:bg-bg-sunken transition-colors\"\n aria-label={tr('common.dismiss', 'Dismiss')}\n >\n <X size={14} />\n </button>\n </div>\n )}\n\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-2\">\n <CalendarClock size={24} className=\"text-text-primary\" />\n <div>\n <h1 className=\"text-xl font-bold text-text-primary\">\n {tr('nav.vibeCalendar', 'Calendar')}\n </h1>\n <p className=\"text-sm text-text-secondary\">\n {tr('calendar.description', 'Schedule and manage tasks across your agents')}\n </p>\n </div>\n </div>\n\n {/* Empty-state CTA shown when the user has no scheduled tasks yet. */}\n {showEmptyState && (\n <div className=\"flex flex-col sm:flex-row sm:items-center gap-3 rounded-lg border border-border-default bg-bg-surface px-4 py-3\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {tr('calendar.empty.title', 'No scheduled tasks yet')}\n </p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {tr(\n 'calendar.empty.description',\n 'Schedule your first task to start automating actions across your agents.'\n )}\n </p>\n </div>\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => setShowCreateModal(true)}\n className=\"px-3 py-1.5 text-xs font-medium rounded-md bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg-hover transition-colors\"\n >\n {tr('calendar.empty.cta', 'Schedule your first task')}\n </button>\n )}\n </div>\n )}\n\n {/* Calendar Header with nav + view switcher */}\n <div data-tour=\"calendar-header\">\n <VibeCalendarHeader\n currentDate={currentDate}\n viewMode={viewMode}\n onDateChange={setCurrentDate}\n onViewModeChange={handleViewModeChange}\n onCreateTask={canCreate ? () => setShowCreateModal(true) : undefined}\n />\n </div>\n\n {/* Calendar Body */}\n <div data-tour=\"calendar-view-container\" className=\"flex-1 overflow-hidden\">\n {viewMode === 'month' && (\n <VibeCalMonthView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'week' && (\n <VibeCalWeekView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'day' && (\n <VibeCalDayView\n currentDate={currentDate}\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n {viewMode === 'agenda' && (\n <VibeCalAgendaView\n occurrences={occurrences}\n onTriggerNow={canExecute ? handleTriggerNow : undefined}\n onViewLogs={handleViewLogs}\n onViewDetail={handleViewDetail}\n />\n )}\n </div>\n\n {/* Schedule Task Modal */}\n <ScheduleTaskModal\n isOpen={showCreateModal}\n onClose={() => {\n setShowCreateModal(false);\n // Strip the actionId query param on dismiss so reopening the\n // modal without a fresh navigation doesn't silently resume\n // Action-linked mode.\n if (searchParams.has('actionId')) {\n const next = new URLSearchParams(searchParams);\n next.delete('actionId');\n setSearchParams(next, { replace: true });\n }\n }}\n onSubmit={handleCreateTask}\n loading={createLoading}\n prefillActionId={prefillActionId}\n />\n\n {/* Logs Drawer */}\n <LogsDrawer\n isOpen={showLogsDrawer}\n onClose={() => setShowLogsDrawer(false)}\n execution={selectedExecution}\n taskTitle={selectedTask?.title || ''}\n agentId={selectedTask?.agentId || ''}\n />\n </MotionPage>\n );\n}\n"],"mappings":"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"}
@@ -541,7 +541,7 @@ function tt() {
541
541
  children: [
542
542
  /* @__PURE__ */ f("div", {
543
543
  "data-tour": "vibedeck-mode-switcher",
544
- className: "flex items-center rounded-lg border border-border-default bg-bg-secondary p-0.5",
544
+ className: "flex items-center rounded-lg border border-border-default bg-bg-surface p-0.5",
545
545
  children: [/* @__PURE__ */ f("button", {
546
546
  type: "button",
547
547
  onClick: () => ut("preview"),
@@ -589,7 +589,7 @@ function tt() {
589
589
  onClick: () => {
590
590
  R(), B && Wt();
591
591
  },
592
- className: "p-2 rounded-lg hover:bg-bg-tertiary text-text-tertiary hover:text-text-primary transition-colors",
592
+ className: "p-2 rounded-lg hover:bg-bg-sunken text-text-tertiary hover:text-text-primary transition-colors",
593
593
  title: "Refresh",
594
594
  children: /* @__PURE__ */ d(Je, { size: 16 })
595
595
  })
@@ -886,7 +886,7 @@ function tt() {
886
886
  onKeyDown: (t) => {
887
887
  (t.key === "Enter" || t.key === " ") && (t.preventDefault(), Rt(e.id));
888
888
  },
889
- className: `p-4 rounded-xl shadow-lg border cursor-pointer ${e.variant === "success" ? "bg-status-success-bg/10 border-status-success-border/30 text-status-success-text" : "bg-status-error-bg/10 border-status-error-border/30 text-status-error-text"}`,
889
+ className: `p-4 rounded-xl shadow-lg border cursor-pointer ${e.variant === "success" ? "bg-status-success-bg-subtle border-status-success-border text-status-success-text" : "bg-status-error-bg-subtle border-status-error-border text-status-error-text"}`,
890
890
  onClick: () => Rt(e.id),
891
891
  children: [/* @__PURE__ */ d("div", {
892
892
  className: "font-medium text-sm",