@elevasis/ui 1.8.0 → 1.8.1

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.
@@ -1,42 +1,48 @@
1
- import { useCyberColors, EmptyState, CyberLegendItem, CyberAreaChart, APIErrorAlert, CardHeader, StatsCardSkeleton, TrendIndicator, DetailCardSkeleton, ContextViewer, JsonViewer, StyledMarkdown } from '../chunk-EHXOR5LA.js';
2
- export { APIErrorAlert, CardHeader, CollapsibleSection, ContextViewer, CustomSelector, DetailCardSkeleton, EmptyState, JsonViewer, ListSkeleton, PageNotFound, PageTitleCaption, ResourceCard, StatCard, StatCardSkeleton, StatsCardSkeleton, StyledMarkdown, TabCountBadge, TimeRangeSelector, TrendIndicator, catalogItemToResourceDefinition } from '../chunk-EHXOR5LA.js';
1
+ import { useCyberColors, EmptyState, CyberLegendItem, CyberAreaChart, APIErrorAlert, CardHeader, StatsCardSkeleton, TrendIndicator, DetailCardSkeleton, ContextViewer, JsonViewer, StyledMarkdown, PageTitleCaption, StatCard, CyberDonut, CollapsibleSection } from '../chunk-3I2P4XG6.js';
2
+ export { APIErrorAlert, CardHeader, CollapsibleSection, ContextViewer, CustomSelector, DetailCardSkeleton, EmptyState, JsonViewer, ListSkeleton, PageNotFound, PageTitleCaption, ResourceCard, StatCard, StatCardSkeleton, StatsCardSkeleton, StyledMarkdown, TabCountBadge, TimeRangeSelector, TrendIndicator, catalogItemToResourceDefinition } from '../chunk-3I2P4XG6.js';
3
+ import { SubshellLoader, SubshellContainer, SubshellSidebar, SubshellRightSideContainer, SubshellContentContainer, PageContainer, AppShellLoader, SubshellSidebarSection, CollapsibleSidebarGroup, SidebarListItem } from '../chunk-WSVFUERF.js';
4
+ import { ElevasisLoader } from '../chunk-YGYF6G7W.js';
3
5
  export { ElevasisLoader, NavigationButton } from '../chunk-YGYF6G7W.js';
6
+ import { showApiErrorNotification, showSuccessNotification, showErrorNotification } from '../chunk-QWYJHM3S.js';
4
7
  export { showApiErrorNotification, showErrorNotification, showInfoNotification, showSuccessNotification, showWarningNotification } from '../chunk-QWYJHM3S.js';
5
- import { useResourcesHealth, useResolveError, useResolveAllErrors, usePaginationState, useErrorDetails, useMarkAsRead, useMarkAllAsRead, useNotificationCount, useNotifications, useSubmitAction, useDeleteTask } from '../chunk-BWZMI4KP.js';
8
+ import { useCommandViewLayout, useResourcesHealth, useResolveError, useResolveAllErrors, usePaginationState, useErrorDetails, useMarkAsRead, useMarkAllAsRead, useNotificationCount, useNotifications, useSubmitAction, useDeleteTask, useErrorDetail, useExecution, useDeleteExecution, useRetryExecution, useCancelExecution, useResources, useResourceDefinition, isSessionCapable, useDeploymentDocs, useCreateSchedule, useListSchedules, usePauseSchedule, useResumeSchedule, useCancelSchedule, useDeleteSchedule, useCommandQueueTotals } from '../chunk-BWZMI4KP.js';
6
9
  import { getTimeRangeDates, formatBucketTime } from '../chunk-ARZM3OTI.js';
7
10
  import '../chunk-JGJSZ3UE.js';
8
11
  import '../chunk-LHQTTUL2.js';
9
- import { Graph_module_css_default, useDirectedChainHighlighting, useNodeSelection, useFitViewTrigger, useGraphHighlighting, calculateGraphHeight, GRAPH_CONSTANTS } from '../chunk-F6RBK7NJ.js';
12
+ import { Graph_module_css_default, useDirectedChainHighlighting, useNodeSelection, GRAPH_CONSTANTS, useFitViewTrigger, useGraphHighlighting, calculateGraphHeight } from '../chunk-F6RBK7NJ.js';
10
13
  export { Graph_module_css_default as graphStyles } from '../chunk-F6RBK7NJ.js';
11
- import { STATUS_COLORS, getStatusIcon, formatDuration, getStatusColors, AGENT_CONSTANTS, shouldAnimateEdge, TIMELINE_CONSTANTS, calculateBarPosition, CONTAINER_CONSTANTS, useExecutionPath, useUnifiedWorkflowLayout, WORKFLOW_CONSTANTS, useReactFlowAgent } from '../chunk-3Q5V2T6L.js';
12
- export { CONTAINER_CONSTANTS, SHARED_VIZ_CONSTANTS } from '../chunk-3Q5V2T6L.js';
13
- import '../chunk-YZ6GTZXL.js';
14
+ import { STATUS_COLORS, getStatusIcon, formatDuration, getStatusColors, AGENT_CONSTANTS, shouldAnimateEdge, TIMELINE_CONSTANTS, calculateBarPosition, CONTAINER_CONSTANTS, useExecutionPath, useUnifiedWorkflowLayout, WORKFLOW_CONSTANTS, useReactFlowAgent, getResourceStatusColor } from '../chunk-XA34RETF.js';
15
+ export { CONTAINER_CONSTANTS, SHARED_VIZ_CONSTANTS } from '../chunk-XA34RETF.js';
16
+ import { ResourceStatusColors, toWorkflowLogMessages } from '../chunk-ELJIFLCB.js';
14
17
  import '../chunk-3I2LOKQU.js';
18
+ import '../chunk-3PURTICE.js';
15
19
  import '../chunk-RNP5R5I3.js';
16
20
  import '../chunk-ESOQEOOX.js';
17
21
  import '../chunk-KB5NKPTN.js';
18
22
  import '../chunk-JRJW2H57.js';
19
23
  import '../chunk-2YBPRE6H.js';
20
24
  import '../chunk-JUPCUF77.js';
21
- import { formatChartAxisDate, PAGE_SIZE_DEFAULT, getErrorInfo, formatErrorMessage } from '../chunk-Z4TPHMRD.js';
25
+ import { getResourceIcon, getResourceColor, formatChartAxisDate, PAGE_SIZE_DEFAULT, getErrorInfo, formatErrorMessage } from '../chunk-Z4TPHMRD.js';
22
26
  import '../chunk-6TMW6VQ2.js';
23
27
  import '../chunk-FWZJH3TL.js';
24
- import '../chunk-WUQWCUCB.js';
25
- import '../chunk-GZVH423C.js';
26
- import '../chunk-DD3CCMCZ.js';
28
+ import { useInitialization } from '../chunk-WUQWCUCB.js';
29
+ import { useElevasisServices } from '../chunk-GZVH423C.js';
30
+ import { useOrganization } from '../chunk-DD3CCMCZ.js';
27
31
  import '../chunk-7PLEQFHO.js';
28
32
  import { useRouterContext } from '../chunk-Q7DJKLEN.js';
29
- import { Paper, Stack, Text, Group, Badge, Box, useComputedColorScheme, Modal, Center, Space, Button, Title, TextInput, Table, Textarea, Radio, Checkbox, Select, NumberInput, Tooltip, Card, Loader, ActionIcon, SegmentedControl, NumberFormatter, Alert, Switch, Pagination, UnstyledButton, Divider, ScrollArea, Popover, Indicator, ThemeIcon, Menu, Accordion, Collapse, SimpleGrid } from '@mantine/core';
33
+ import { Paper, Stack, Text, Group, Badge, Box, ThemeIcon, useComputedColorScheme, Card, ActionIcon, Modal, Center, Space, Button, Title, TextInput, Table, Textarea, Radio, Checkbox, Select, NumberInput, Tooltip, Loader, SegmentedControl, NumberFormatter, Alert, Switch, Pagination, UnstyledButton, Divider, ScrollArea, Popover, Indicator, Menu, Accordion, Collapse, SimpleGrid, CopyButton, Code, useMantineTheme, Timeline, RangeSlider, Progress } from '@mantine/core';
30
34
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
31
- import { memo, useMemo, cloneElement, useState, useEffect, useCallback, Fragment as Fragment$1 } from 'react';
32
- import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconChevronUp, IconChevronDown, IconSelector, IconTrash, IconChartBar, IconCircleCheck, IconThumbDown, IconThumbUp, IconCircleX, IconSearch, IconFilterOff, IconArrowUpRight, IconAlertCircle, IconExternalLink, IconDownload, IconInfoCircle, IconBug, IconChecks, IconCircle, IconCircleFilled, IconBell, IconFocus2, IconRobot, IconGitBranch, IconDotsVertical, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconNetwork, IconSitemap, IconArrowDown, IconFileOff, IconKey, IconUser } from '@tabler/icons-react';
35
+ import { memo, forwardRef, useMemo, useImperativeHandle, cloneElement, useState, useEffect, useCallback, Fragment as Fragment$1, useRef } from 'react';
36
+ import { IconPlayerPlay, IconPlayerStop, IconArrowsSplit, IconSquare, IconBrain, IconFileText, IconDatabase, IconMessage, IconAlertCircle, IconCircleX, IconCircleCheck, IconBolt, IconHandClick, IconClock, IconWebhook, IconExternalLink, IconFocus2, IconMail, IconSend, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconChevronUp, IconChevronDown, IconSelector, IconTrash, IconChartBar, IconThumbDown, IconThumbUp, IconSearch, IconFilterOff, IconArrowUpRight, IconDownload, IconInfoCircle, IconBug, IconChecks, IconCircle, IconCircleFilled, IconBell, IconRobot, IconGitBranch, IconDotsVertical, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconNetwork, IconSitemap, IconCopy, IconReload, IconArrowLeft, IconBook2, IconFileOff, IconList, IconCalendarRepeat, IconCalendarEvent, IconCalendarTime, IconPlus, IconCalendar, IconKey, IconPlayerPause, IconCalendarDue, IconCalendarStats, IconCalendarOff, IconListCheck, IconFilter, IconCategory, IconArrowDown, IconUser, IconFolderOpen, IconFolder } from '@tabler/icons-react';
33
37
  import { AreaChart } from '@mantine/charts';
34
38
  import { formatDistanceToNow } from 'date-fns';
35
- import { useDisclosure } from '@mantine/hooks';
36
- import { Position, Handle, getSmoothStepPath, BaseEdge as BaseEdge$1, EdgeLabelRenderer, Panel, useReactFlow, Controls, ReactFlowProvider, ReactFlow } from '@xyflow/react';
39
+ import { useDisclosure, useClipboard } from '@mantine/hooks';
40
+ import { Position, Handle, getSmoothStepPath, BaseEdge as BaseEdge$1, EdgeLabelRenderer, useReactFlow, ReactFlow, ReactFlowProvider, Panel, Controls } from '@xyflow/react';
37
41
  import '@xyflow/react/dist/style.css';
38
42
  import { useForm } from '@mantine/form';
39
43
  import dagre from '@dagrejs/dagre';
44
+ import { notifications } from '@mantine/notifications';
45
+ import { useNavigate } from '@tanstack/react-router';
40
46
 
41
47
  var CustomModal = ({ children, opened, onClose, loading, style, size }) => {
42
48
  const canClose = loading === true ? false : true;
@@ -1560,18 +1566,18 @@ function NotificationItem({ notification, onClose, onNavigate }) {
1560
1566
  }
1561
1567
  );
1562
1568
  }
1563
- function NotificationList({ notifications, isLoading, onClose, onNavigate }) {
1569
+ function NotificationList({ notifications: notifications2, isLoading, onClose, onNavigate }) {
1564
1570
  if (isLoading) {
1565
1571
  return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) });
1566
1572
  }
1567
- if (notifications.length === 0) {
1573
+ if (notifications2.length === 0) {
1568
1574
  return /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No notifications" }) });
1569
1575
  }
1570
- return /* @__PURE__ */ jsx(Stack, { gap: 0, children: notifications.map((notification) => /* @__PURE__ */ jsx(NotificationItem, { notification, onClose, onNavigate }, notification.id)) });
1576
+ return /* @__PURE__ */ jsx(Stack, { gap: 0, children: notifications2.map((notification) => /* @__PURE__ */ jsx(NotificationItem, { notification, onClose, onNavigate }, notification.id)) });
1571
1577
  }
1572
- function NotificationPanel({ notifications, isLoading, onClose, onNavigate }) {
1578
+ function NotificationPanel({ notifications: notifications2, isLoading, onClose, onNavigate }) {
1573
1579
  const markAllAsRead = useMarkAllAsRead();
1574
- const hasUnread = notifications.some((n) => !n.read);
1580
+ const hasUnread = notifications2.some((n) => !n.read);
1575
1581
  const handleMarkAllAsRead = async () => {
1576
1582
  await markAllAsRead.mutateAsync();
1577
1583
  };
@@ -1584,7 +1590,7 @@ function NotificationPanel({ notifications, isLoading, onClose, onNavigate }) {
1584
1590
  /* @__PURE__ */ jsx(ScrollArea, { h: 400, type: "auto", children: /* @__PURE__ */ jsx(
1585
1591
  NotificationList,
1586
1592
  {
1587
- notifications,
1593
+ notifications: notifications2,
1588
1594
  isLoading,
1589
1595
  onClose,
1590
1596
  onNavigate
@@ -1596,14 +1602,14 @@ function NotificationBell({ unreadCount, onNavigate }) {
1596
1602
  const [opened, { toggle, close }] = useDisclosure(false);
1597
1603
  const { data: apiCount = 0 } = useNotificationCount();
1598
1604
  const { data, isLoading } = useNotifications({ limit: 20 });
1599
- const notifications = data?.notifications ?? [];
1605
+ const notifications2 = data?.notifications ?? [];
1600
1606
  const count = unreadCount ?? apiCount;
1601
1607
  return /* @__PURE__ */ jsxs(Popover, { opened, onChange: toggle, position: "bottom-end", width: 400, children: [
1602
1608
  /* @__PURE__ */ jsx(Tooltip, { label: "Notifications", disabled: opened, children: /* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(Indicator, { label: count > 99 ? "99+" : count, disabled: count === 0, size: 16, offset: 4, children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "lg", onClick: toggle, children: /* @__PURE__ */ jsx(IconBell, { size: 20, color: "var(--color-text-subtle)" }) }) }) }) }),
1603
1609
  /* @__PURE__ */ jsx(Popover.Dropdown, { p: 0, children: /* @__PURE__ */ jsx(
1604
1610
  NotificationPanel,
1605
1611
  {
1606
- notifications,
1612
+ notifications: notifications2,
1607
1613
  isLoading,
1608
1614
  onClose: close,
1609
1615
  onNavigate
@@ -2944,12 +2950,12 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
2944
2950
  }
2945
2951
  setConfirmAction(null);
2946
2952
  };
2947
- const getPriorityColor = (priority) => {
2953
+ const getPriorityColor2 = (priority) => {
2948
2954
  if (priority >= 8) return "red";
2949
2955
  if (priority >= 5) return "yellow";
2950
2956
  return "gray";
2951
2957
  };
2952
- const getStatusColor = (status) => {
2958
+ const getStatusColor4 = (status) => {
2953
2959
  switch (status) {
2954
2960
  case "pending":
2955
2961
  return "blue";
@@ -2974,7 +2980,7 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
2974
2980
  });
2975
2981
  }
2976
2982
  };
2977
- const formatDate = (date) => {
2983
+ const formatDate2 = (date) => {
2978
2984
  const now = /* @__PURE__ */ new Date();
2979
2985
  const diffMs = now.getTime() - date.getTime();
2980
2986
  const diffMins = Math.floor(diffMs / 6e4);
@@ -3002,7 +3008,7 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
3002
3008
  /* @__PURE__ */ jsxs("div", { style: { flex: 1 }, children: [
3003
3009
  /* @__PURE__ */ jsxs(Group, { gap: "xs", mb: 4, children: [
3004
3010
  /* @__PURE__ */ jsx(Text, { fw: 600, size: "sm", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: task.description || "Task approval required" }),
3005
- /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: getPriorityColor(task.priority), radius: "sm", children: [
3011
+ /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", color: getPriorityColor2(task.priority), radius: "sm", children: [
3006
3012
  "P",
3007
3013
  task.priority
3008
3014
  ] })
@@ -3016,7 +3022,7 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
3016
3022
  /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "\u2022" }),
3017
3023
  /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
3018
3024
  /* @__PURE__ */ jsx(IconClock, { size: 12 }),
3019
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDate(task.createdAt) })
3025
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatDate2(task.createdAt) })
3020
3026
  ] })
3021
3027
  ] })
3022
3028
  ] })
@@ -3027,7 +3033,7 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
3027
3033
  {
3028
3034
  size: "sm",
3029
3035
  variant: "light",
3030
- color: getStatusColor(task.status),
3036
+ color: getStatusColor4(task.status),
3031
3037
  radius: "sm",
3032
3038
  leftSection: task.status === "processing" ? /* @__PURE__ */ jsx(Loader, { size: 6 }) : void 0,
3033
3039
  children: task.status.charAt(0).toUpperCase() + task.status.slice(1)
@@ -3084,7 +3090,7 @@ function TaskCard({ task, onViewExecution, richTextRenderer }) {
3084
3090
  task.actionPayload !== void 0 && task.actionPayload !== null && /* @__PURE__ */ jsx(JsonViewer, { data: task.actionPayload, maxHeight: 200 }),
3085
3091
  task.completedAt && /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
3086
3092
  "Completed ",
3087
- formatDate(task.completedAt),
3093
+ formatDate2(task.completedAt),
3088
3094
  task.completedBy ? ` by ${task.completedBy}` : ""
3089
3095
  ] }),
3090
3096
  task.targetExecutionId && /* @__PURE__ */ jsx(
@@ -3791,4 +3797,3528 @@ function ResourceDefinitionSection({
3791
3797
  return /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "sm", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", fs: "italic", children: "Unknown resource type" }) });
3792
3798
  }
3793
3799
 
3794
- export { ActionModal, ActivityCard, ActivityFilters as ActivityFiltersBar, ActivityTable, AgentDefinitionDisplay, AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseNode, BusinessImpactCard, CollapsibleJsonSection, ConfigCard, ConfirmationInputModal, ConfirmationModal, ContentSections, ContractDisplay, CostBreakdownCard, CostByModelTable, CostMetricsCard, CustomModal, EmptyVisualizer, ErrorAnalysisCard, ErrorBreakdownTable, ExecutionBreakdownTable, ExecutionHealthCard, ExecutionLogsFilters as ExecutionLogsFilterBar, ExecutionLogsTable, ExecutionStats, ExecutionStatusBadge, FilterBar, FormFieldRenderer, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, NotificationBell, NotificationItem, NotificationList, NotificationPanel, ResourceDefinitionSection, ResourceHealthChart, ResourceHealthPanel, SortableHeader, TableSelectionToolbar, TaskCard, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, ToolsListDisplay, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, VisualizerContainer, WorkflowDefinitionDisplay, WorkflowExecutionTimeline, getGraphBackgroundStyles, getHealthColor, getIcon, iconMap, useGraphBackgroundStyles, useGraphTheme, useNewKnowledgeMapLayout };
3800
+ // src/components/operations/executions/logConstants.ts
3801
+ var LOG_LEVEL_CONFIG = {
3802
+ debug: {
3803
+ label: "DEBUG",
3804
+ color: "gray",
3805
+ textColor: "var(--color-text-subtle)",
3806
+ icon: "\u{1F50D}"
3807
+ },
3808
+ info: {
3809
+ label: "INFO",
3810
+ color: "blue",
3811
+ textColor: "var(--color-text-dimmed)",
3812
+ icon: "\u2139\uFE0F"
3813
+ },
3814
+ warn: {
3815
+ label: "WARN",
3816
+ color: "yellow",
3817
+ textColor: "var(--color-warning)",
3818
+ icon: "\u26A0\uFE0F"
3819
+ },
3820
+ error: {
3821
+ label: "ERROR",
3822
+ color: "red",
3823
+ textColor: "var(--color-error)",
3824
+ icon: "\u274C"
3825
+ }
3826
+ };
3827
+ var EXECUTION_STATUS_CONFIG = {
3828
+ pending: {
3829
+ label: "Pending",
3830
+ color: "gray",
3831
+ textColor: "var(--color-text-dimmed)"
3832
+ },
3833
+ running: {
3834
+ label: "Running",
3835
+ color: "blue",
3836
+ textColor: "var(--color-primary)"
3837
+ },
3838
+ completed: {
3839
+ label: "Completed",
3840
+ color: "green",
3841
+ textColor: "var(--color-success)"
3842
+ },
3843
+ failed: {
3844
+ label: "Failed",
3845
+ color: "red",
3846
+ textColor: "var(--color-error)"
3847
+ },
3848
+ warning: {
3849
+ label: "Warning",
3850
+ color: "yellow",
3851
+ textColor: "var(--color-warning)"
3852
+ }
3853
+ };
3854
+ function getLogLevelConfig(level) {
3855
+ const normalizedLevel = level.toLowerCase();
3856
+ return LOG_LEVEL_CONFIG[normalizedLevel] || LOG_LEVEL_CONFIG.info;
3857
+ }
3858
+ function getExecutionStatusConfig(status) {
3859
+ const normalizedStatus = status.toLowerCase();
3860
+ return EXECUTION_STATUS_CONFIG[normalizedStatus] || EXECUTION_STATUS_CONFIG.pending;
3861
+ }
3862
+ function BaseExecutionLogsHeader({
3863
+ execution,
3864
+ resourceId,
3865
+ onDeleteClick,
3866
+ onRetryClick,
3867
+ onCancelClick,
3868
+ renderMetrics
3869
+ }) {
3870
+ const { currentMembership } = useOrganization();
3871
+ const organizationName = currentMembership?.organization?.name;
3872
+ const resourceTag = organizationName ? `${organizationName}/${resourceId}` : resourceId;
3873
+ return /* @__PURE__ */ jsxs(Stack, { children: [
3874
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", gap: "xs", children: [
3875
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
3876
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "Execution Logs" }),
3877
+ /* @__PURE__ */ jsx(Badge, { color: getExecutionStatusConfig(execution.status).color, size: "sm", children: getExecutionStatusConfig(execution.status).label.toUpperCase() }),
3878
+ /* @__PURE__ */ jsx(Badge, { color: getResourceStatusColor(execution.resourceStatus), size: "sm", variant: "outline", children: execution.resourceStatus.toUpperCase() })
3879
+ ] }),
3880
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
3881
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "var(--color-text-subtle)", ff: "monospace", children: execution.id }),
3882
+ /* @__PURE__ */ jsx(CopyButton, { value: `${resourceTag} ${execution.id}`, children: ({ copied, copy }) => /* @__PURE__ */ jsx(ActionIcon, { onClick: copy, variant: "subtle", color: copied ? "green" : "var(--color-text-subtle)", children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 16 }) : /* @__PURE__ */ jsx(IconCopy, { size: 16 }) }) }),
3883
+ onCancelClick && /* @__PURE__ */ jsx(ActionIcon, { onClick: onCancelClick, variant: "subtle", color: "orange", children: /* @__PURE__ */ jsx(IconPlayerStop, { size: 16 }) }),
3884
+ onRetryClick && /* @__PURE__ */ jsx(ActionIcon, { onClick: onRetryClick, variant: "subtle", children: /* @__PURE__ */ jsx(IconReload, { size: 16 }) }),
3885
+ /* @__PURE__ */ jsx(ActionIcon, { onClick: onDeleteClick, variant: "subtle", color: "var(--color-error)", children: /* @__PURE__ */ jsx(IconTrash, { size: 16 }) })
3886
+ ] })
3887
+ ] }),
3888
+ renderMetrics ? renderMetrics(execution) : /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
3889
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3890
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "Started:" }),
3891
+ " ",
3892
+ new Date(execution.startTime).toLocaleString()
3893
+ ] }),
3894
+ execution.endTime && /* @__PURE__ */ jsxs(Fragment, { children: [
3895
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3896
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "Ended:" }),
3897
+ " ",
3898
+ new Date(execution.endTime).toLocaleString()
3899
+ ] }),
3900
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3901
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "Duration:" }),
3902
+ " ",
3903
+ ((execution.endTime - execution.startTime) / 1e3).toFixed(2),
3904
+ "s"
3905
+ ] })
3906
+ ] }),
3907
+ execution.apiVersion && /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3908
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "API:" }),
3909
+ " ",
3910
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "gray", children: [
3911
+ "v",
3912
+ execution.apiVersion
3913
+ ] })
3914
+ ] }),
3915
+ execution.resourceVersion && /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3916
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "Resource:" }),
3917
+ " ",
3918
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "gray", children: [
3919
+ "v",
3920
+ execution.resourceVersion
3921
+ ] })
3922
+ ] }),
3923
+ execution.sdkVersion && /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
3924
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 500, children: "SDK:" }),
3925
+ " ",
3926
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "gray", children: [
3927
+ "v",
3928
+ execution.sdkVersion
3929
+ ] })
3930
+ ] })
3931
+ ] })
3932
+ ] });
3933
+ }
3934
+ function BaseExecutionLogsStates({ executionId, isLoading, execution }) {
3935
+ if (!executionId) {
3936
+ return /* @__PURE__ */ jsx(Center, { h: "100%", children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Select an execution to view details" }) });
3937
+ }
3938
+ if (isLoading) {
3939
+ return /* @__PURE__ */ jsx(Center, { h: "100%", children: /* @__PURE__ */ jsx(Loader, { size: "lg", loaders: { elevasis: ElevasisLoader }, type: "elevasis" }) });
3940
+ }
3941
+ if (!execution) {
3942
+ return /* @__PURE__ */ jsx(Center, { h: "100%", children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Execution not found" }) });
3943
+ }
3944
+ return null;
3945
+ }
3946
+ function ExecutionErrorSection({ executionId, fallbackError }) {
3947
+ const { data: errors, isLoading, isError } = useErrorDetail(executionId);
3948
+ const [showStack, setShowStack] = useState(false);
3949
+ const [showErrorContext, setShowErrorContext] = useState(false);
3950
+ const primaryError = errors?.[0];
3951
+ if (isLoading || isError || !primaryError) {
3952
+ return /* @__PURE__ */ jsxs(
3953
+ Paper,
3954
+ {
3955
+ withBorder: true,
3956
+ p: "sm",
3957
+ bg: "color-mix(in srgb, var(--color-error) 10%, transparent)",
3958
+ style: { borderColor: "var(--color-error)" },
3959
+ children: [
3960
+ /* @__PURE__ */ jsx(Text, { fw: 500, c: "var(--color-error)", mb: "xs", children: "Error" }),
3961
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "var(--color-error)", ff: "monospace", style: { whiteSpace: "pre-wrap" }, children: fallbackError })
3962
+ ]
3963
+ }
3964
+ );
3965
+ }
3966
+ const severityColor = primaryError.severity === "critical" ? "red" : primaryError.severity === "warning" ? "orange" : "blue";
3967
+ return /* @__PURE__ */ jsx(
3968
+ Paper,
3969
+ {
3970
+ withBorder: true,
3971
+ p: "sm",
3972
+ bg: "color-mix(in srgb, var(--color-error) 10%, transparent)",
3973
+ style: { borderColor: "var(--color-error)" },
3974
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3975
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
3976
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
3977
+ /* @__PURE__ */ jsx(
3978
+ Text,
3979
+ {
3980
+ fw: 600,
3981
+ size: "sm",
3982
+ c: "var(--color-error)",
3983
+ style: { fontFamily: "var(--mantine-font-family-headings)" },
3984
+ children: primaryError.errorType
3985
+ }
3986
+ ),
3987
+ /* @__PURE__ */ jsx(Badge, { variant: "light", size: "sm", children: primaryError.category })
3988
+ ] }),
3989
+ /* @__PURE__ */ jsx(Badge, { color: severityColor, variant: "light", size: "sm", children: primaryError.severity })
3990
+ ] }),
3991
+ /* @__PURE__ */ jsx(Alert, { color: "red", icon: /* @__PURE__ */ jsx(IconBug, { size: 16 }), children: primaryError.message }),
3992
+ errors && errors.length > 1 && /* @__PURE__ */ jsxs(Alert, { color: "yellow", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: [
3993
+ "This execution has ",
3994
+ errors.length,
3995
+ " errors (including retries). Showing most recent."
3996
+ ] }),
3997
+ primaryError.stackTrace && /* @__PURE__ */ jsxs("div", { children: [
3998
+ /* @__PURE__ */ jsxs(
3999
+ Group,
4000
+ {
4001
+ justify: "space-between",
4002
+ mb: "xs",
4003
+ onClick: () => setShowStack(!showStack),
4004
+ style: { cursor: "pointer" },
4005
+ children: [
4006
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Stack Trace" }),
4007
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4008
+ /* @__PURE__ */ jsx(CopyButton, { value: primaryError.stackTrace, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy stack trace", children: /* @__PURE__ */ jsx(
4009
+ ActionIcon,
4010
+ {
4011
+ variant: "subtle",
4012
+ size: "sm",
4013
+ onClick: (e) => {
4014
+ e.stopPropagation();
4015
+ copy();
4016
+ },
4017
+ children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 14 }) : /* @__PURE__ */ jsx(IconCopy, { size: 14 })
4018
+ }
4019
+ ) }) }),
4020
+ /* @__PURE__ */ jsx(
4021
+ IconChevronDown,
4022
+ {
4023
+ size: 14,
4024
+ style: {
4025
+ transform: showStack ? "rotate(180deg)" : "rotate(0)",
4026
+ transition: "transform var(--duration-fast)"
4027
+ }
4028
+ }
4029
+ )
4030
+ ] })
4031
+ ]
4032
+ }
4033
+ ),
4034
+ /* @__PURE__ */ jsx(Collapse, { in: showStack, children: /* @__PURE__ */ jsx(Code, { block: true, style: { maxHeight: 300, overflow: "auto", fontSize: "12px", lineHeight: "1.5" }, children: primaryError.stackTrace }) })
4035
+ ] }),
4036
+ primaryError.errorContext && Object.keys(primaryError.errorContext).length > 0 && /* @__PURE__ */ jsxs("div", { children: [
4037
+ /* @__PURE__ */ jsxs(
4038
+ Group,
4039
+ {
4040
+ justify: "space-between",
4041
+ mb: "xs",
4042
+ onClick: () => setShowErrorContext(!showErrorContext),
4043
+ style: { cursor: "pointer" },
4044
+ children: [
4045
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Error Context" }),
4046
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4047
+ /* @__PURE__ */ jsx(CopyButton, { value: JSON.stringify(primaryError.errorContext, null, 2), children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy error context", children: /* @__PURE__ */ jsx(
4048
+ ActionIcon,
4049
+ {
4050
+ variant: "subtle",
4051
+ size: "sm",
4052
+ onClick: (e) => {
4053
+ e.stopPropagation();
4054
+ copy();
4055
+ },
4056
+ children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: 14 }) : /* @__PURE__ */ jsx(IconCopy, { size: 14 })
4057
+ }
4058
+ ) }) }),
4059
+ /* @__PURE__ */ jsx(
4060
+ IconChevronDown,
4061
+ {
4062
+ size: 14,
4063
+ style: {
4064
+ transform: showErrorContext ? "rotate(180deg)" : "rotate(0)",
4065
+ transition: "transform var(--duration-fast)"
4066
+ }
4067
+ }
4068
+ )
4069
+ ] })
4070
+ ]
4071
+ }
4072
+ ),
4073
+ /* @__PURE__ */ jsx(Collapse, { in: showErrorContext, children: /* @__PURE__ */ jsx(JsonViewer, { data: primaryError.errorContext, maxHeight: 200, fontSize: "12px" }) })
4074
+ ] })
4075
+ ] })
4076
+ }
4077
+ );
4078
+ }
4079
+ function BaseExecutionLogs({
4080
+ resourceId,
4081
+ resourceType,
4082
+ executionId,
4083
+ execution: externalExecution,
4084
+ onExecutionDeleted,
4085
+ renderLogsSection,
4086
+ renderMetrics,
4087
+ hideInput = false,
4088
+ hideResult = false,
4089
+ hideError = false
4090
+ }) {
4091
+ const { data: fetchedExecution, isLoading } = useExecution(resourceId, executionId || "");
4092
+ const typedExecution = externalExecution ?? fetchedExecution;
4093
+ const [deleteModalOpened, setDeleteModalOpened] = useState(false);
4094
+ const [retryModalOpened, setRetryModalOpened] = useState(false);
4095
+ const [cancelModalOpened, setCancelModalOpened] = useState(false);
4096
+ const [retryError, setRetryError] = useState(null);
4097
+ const deleteExecutionMutation = useDeleteExecution();
4098
+ const retryExecutionMutation = useRetryExecution();
4099
+ const cancelExecutionMutation = useCancelExecution();
4100
+ const handleDelete = async () => {
4101
+ if (!executionId) return;
4102
+ try {
4103
+ await deleteExecutionMutation.mutateAsync({
4104
+ resourceId,
4105
+ executionId
4106
+ });
4107
+ setDeleteModalOpened(false);
4108
+ onExecutionDeleted?.();
4109
+ } catch (error) {
4110
+ console.error("Failed to delete execution:", error);
4111
+ showApiErrorNotification(error);
4112
+ }
4113
+ };
4114
+ const handleCancel = async () => {
4115
+ if (!executionId) return;
4116
+ try {
4117
+ await cancelExecutionMutation.mutateAsync({
4118
+ resourceId,
4119
+ executionId
4120
+ });
4121
+ setCancelModalOpened(false);
4122
+ } catch (error) {
4123
+ console.error("Failed to cancel execution:", error);
4124
+ showApiErrorNotification(error);
4125
+ }
4126
+ };
4127
+ const handleRetry = async () => {
4128
+ if (!typedExecution || !resourceType) return;
4129
+ setRetryError(null);
4130
+ try {
4131
+ await retryExecutionMutation.mutateAsync({
4132
+ resourceId,
4133
+ resourceType,
4134
+ input: typedExecution.input
4135
+ });
4136
+ setRetryModalOpened(false);
4137
+ showSuccessNotification("Resource re-executed with the same inputs.");
4138
+ } catch (error) {
4139
+ const message = error instanceof Error ? error.message : "Failed to re-execute resource";
4140
+ setRetryError(message);
4141
+ }
4142
+ };
4143
+ if (!executionId || isLoading || !typedExecution) {
4144
+ return /* @__PURE__ */ jsx(BaseExecutionLogsStates, { executionId, isLoading, execution: typedExecution });
4145
+ }
4146
+ return /* @__PURE__ */ jsxs(Stack, { h: "100%", children: [
4147
+ /* @__PURE__ */ jsx(
4148
+ BaseExecutionLogsHeader,
4149
+ {
4150
+ execution: typedExecution,
4151
+ resourceId,
4152
+ onDeleteClick: () => setDeleteModalOpened(true),
4153
+ onCancelClick: typedExecution.status === "running" ? () => setCancelModalOpened(true) : void 0,
4154
+ onRetryClick: resourceType ? () => {
4155
+ setRetryError(null);
4156
+ setRetryModalOpened(true);
4157
+ } : void 0,
4158
+ renderMetrics
4159
+ }
4160
+ ),
4161
+ !hideInput && typedExecution.input != null && /* @__PURE__ */ jsx(Paper, { withBorder: true, bg: "none", children: /* @__PURE__ */ jsx(CollapsibleJsonSection, { title: /* @__PURE__ */ jsx(Text, { fw: 500, children: "Input" }), data: typedExecution.input }) }),
4162
+ renderLogsSection?.(typedExecution),
4163
+ !hideResult && typedExecution.result != null && /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsx(
4164
+ CollapsibleJsonSection,
4165
+ {
4166
+ title: /* @__PURE__ */ jsx(Text, { fw: 500, c: "var(--color-success)", children: "Result" }),
4167
+ data: typedExecution.result
4168
+ }
4169
+ ) }),
4170
+ !hideError && typedExecution.error && /* @__PURE__ */ jsx(ExecutionErrorSection, { executionId: typedExecution.id, fallbackError: typedExecution.error }),
4171
+ /* @__PURE__ */ jsx(
4172
+ ConfirmationModal,
4173
+ {
4174
+ opened: deleteModalOpened,
4175
+ onClose: () => setDeleteModalOpened(false),
4176
+ icon: /* @__PURE__ */ jsx(IconTrash, { color: "red" }),
4177
+ title: "Delete Execution Log",
4178
+ text: "Are you sure you want to delete this execution log? This action cannot be undone.",
4179
+ buttonText: "Delete",
4180
+ buttonColor: "red",
4181
+ confirmationHandler: handleDelete,
4182
+ loading: deleteExecutionMutation.isPending
4183
+ }
4184
+ ),
4185
+ /* @__PURE__ */ jsx(
4186
+ ConfirmationModal,
4187
+ {
4188
+ opened: cancelModalOpened,
4189
+ onClose: () => setCancelModalOpened(false),
4190
+ icon: /* @__PURE__ */ jsx(IconPlayerStop, {}),
4191
+ title: "Stop Execution",
4192
+ text: "Are you sure you want to stop this running execution? This action cannot be undone.",
4193
+ buttonText: "Stop",
4194
+ buttonColor: "orange",
4195
+ confirmationHandler: handleCancel,
4196
+ loading: cancelExecutionMutation.isPending
4197
+ }
4198
+ ),
4199
+ /* @__PURE__ */ jsx(
4200
+ CustomModal,
4201
+ {
4202
+ opened: retryModalOpened,
4203
+ onClose: () => setRetryModalOpened(false),
4204
+ size: "sm",
4205
+ loading: retryExecutionMutation.isPending,
4206
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
4207
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
4208
+ /* @__PURE__ */ jsx(IconReload, { size: 24, color: "var(--color-primary)" }),
4209
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "Re-execute Resource" })
4210
+ ] }),
4211
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
4212
+ "This will re-execute",
4213
+ " ",
4214
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 600, children: resourceId }),
4215
+ " ",
4216
+ "with the exact same inputs from this execution."
4217
+ ] }),
4218
+ typedExecution?.input != null && /* @__PURE__ */ jsx(Paper, { withBorder: true, bg: "none", style: { maxHeight: 150, overflow: "auto" }, children: /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", style: { whiteSpace: "pre-wrap" }, children: JSON.stringify(typedExecution.input, null, 2) }) }),
4219
+ retryError && /* @__PURE__ */ jsx(
4220
+ Paper,
4221
+ {
4222
+ withBorder: true,
4223
+ p: "xs",
4224
+ bg: "color-mix(in srgb, var(--color-error) 10%, transparent)",
4225
+ style: { borderColor: "var(--color-error)" },
4226
+ children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "var(--color-error)", children: retryError })
4227
+ }
4228
+ ),
4229
+ /* @__PURE__ */ jsxs(Group, { justify: "flex-end", mt: "md", children: [
4230
+ /* @__PURE__ */ jsx(
4231
+ Button,
4232
+ {
4233
+ variant: "light",
4234
+ onClick: () => setRetryModalOpened(false),
4235
+ disabled: retryExecutionMutation.isPending,
4236
+ children: "Cancel"
4237
+ }
4238
+ ),
4239
+ /* @__PURE__ */ jsx(Button, { onClick: handleRetry, loading: retryExecutionMutation.isPending, children: "Re-execute" })
4240
+ ] })
4241
+ ] })
4242
+ }
4243
+ )
4244
+ ] });
4245
+ }
4246
+ function LogEntry({ log, index }) {
4247
+ const hasContext = log.context && Object.keys(log.context).length > 0;
4248
+ const logConfig = getLogLevelConfig(log.level);
4249
+ const logTitle = /* @__PURE__ */ jsxs(Group, { gap: "xs", style: { flex: 1 }, wrap: "nowrap", children: [
4250
+ /* @__PURE__ */ jsx(
4251
+ Badge,
4252
+ {
4253
+ size: "sm",
4254
+ variant: "light",
4255
+ color: logConfig.color,
4256
+ style: { minWidth: "60px", fontFamily: "var(--mantine-font-family-monospace)" },
4257
+ children: logConfig.label
4258
+ }
4259
+ ),
4260
+ /* @__PURE__ */ jsx(Text, { span: true, c: "dimmed", size: "xs", style: { fontFamily: "var(--mantine-font-family-monospace)" }, children: new Date(log.timestamp).toLocaleTimeString("en-US", {
4261
+ hour12: false,
4262
+ hour: "2-digit",
4263
+ minute: "2-digit",
4264
+ second: "2-digit",
4265
+ fractionalSecondDigits: 3
4266
+ }) }),
4267
+ /* @__PURE__ */ jsx(Text, { size: "sm", span: true, style: { fontFamily: "var(--mantine-font-family-monospace)" }, children: log.message })
4268
+ ] });
4269
+ if (!hasContext) {
4270
+ return /* @__PURE__ */ jsx(
4271
+ "div",
4272
+ {
4273
+ style: {
4274
+ padding: "0.375rem 0.5rem",
4275
+ borderRadius: "var(--mantine-radius-default)"
4276
+ },
4277
+ children: logTitle
4278
+ },
4279
+ index
4280
+ );
4281
+ }
4282
+ return /* @__PURE__ */ jsx(CollapsibleJsonSection, { title: logTitle, data: log.context }, index);
4283
+ }
4284
+ function LogGroup({ title, logs, statusBadge }) {
4285
+ return /* @__PURE__ */ jsxs(
4286
+ "div",
4287
+ {
4288
+ style: {
4289
+ borderRadius: "8px",
4290
+ padding: "12px",
4291
+ border: "1px solid var(--color-border)"
4292
+ },
4293
+ children: [
4294
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", mb: "xs", children: [
4295
+ /* @__PURE__ */ jsx(Text, { fw: 600, size: "sm", c: "var(--color-text)", style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: title }),
4296
+ statusBadge && /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: statusBadge.color, children: statusBadge.label }),
4297
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", color: "gray", children: [
4298
+ logs.length,
4299
+ " ",
4300
+ logs.length === 1 ? "log" : "logs"
4301
+ ] })
4302
+ ] }),
4303
+ /* @__PURE__ */ jsx(Stack, { gap: 4, children: logs.map((log, logIndex) => /* @__PURE__ */ jsx(LogEntry, { log, index: logIndex }, logIndex)) })
4304
+ ]
4305
+ }
4306
+ );
4307
+ }
4308
+ var ResourceFilter = ({ value, onChange, fullWidth }) => {
4309
+ const buttonStyles = fullWidth ? { padding: "2px 8px", height: "28px", fontSize: "12px", flex: 1 } : { padding: "2px 8px", height: "24px", fontSize: "12px" };
4310
+ return /* @__PURE__ */ jsxs(Button.Group, { style: fullWidth ? { width: "100%" } : void 0, children: [
4311
+ /* @__PURE__ */ jsx(
4312
+ Button,
4313
+ {
4314
+ variant: value === "all" ? "filled" : "default",
4315
+ size: "xs",
4316
+ onClick: () => onChange("all"),
4317
+ bg: value === "all" ? void 0 : "var(--color-background)",
4318
+ styles: { root: buttonStyles },
4319
+ children: "All"
4320
+ }
4321
+ ),
4322
+ /* @__PURE__ */ jsx(
4323
+ Button,
4324
+ {
4325
+ variant: value === "dev" ? "filled" : "default",
4326
+ size: "xs",
4327
+ onClick: () => onChange("dev"),
4328
+ bg: value === "dev" ? void 0 : "var(--color-background)",
4329
+ styles: { root: buttonStyles },
4330
+ children: "Dev"
4331
+ }
4332
+ ),
4333
+ /* @__PURE__ */ jsx(
4334
+ Button,
4335
+ {
4336
+ variant: value === "prod" ? "filled" : "default",
4337
+ size: "xs",
4338
+ onClick: () => onChange("prod"),
4339
+ bg: value === "prod" ? void 0 : "var(--color-background)",
4340
+ styles: { root: buttonStyles },
4341
+ children: "Prod"
4342
+ }
4343
+ )
4344
+ ] });
4345
+ };
4346
+ function ResourceHeader({ resource, type, connected, runningCount, sessionCapable }) {
4347
+ const { currentMembership } = useOrganization();
4348
+ const organizationName = currentMembership?.organization?.name;
4349
+ const navigate = useNavigate();
4350
+ const Icon = getResourceIcon(type);
4351
+ const clipboard = useClipboard({ timeout: 2e3 });
4352
+ const handleCopyId = () => {
4353
+ clipboard.copy(`"${organizationName}/${resource.resourceId}"`);
4354
+ notifications.show({
4355
+ message: "Resource ID copied to clipboard",
4356
+ color: "teal"
4357
+ });
4358
+ };
4359
+ const handleGoToSessions = () => {
4360
+ navigate({
4361
+ to: "/operations/sessions",
4362
+ search: { agent: resource.resourceId }
4363
+ });
4364
+ };
4365
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4366
+ /* @__PURE__ */ jsx(
4367
+ PageTitleCaption,
4368
+ {
4369
+ title: resource.name,
4370
+ caption: resource.description || `${type.charAt(0).toUpperCase()}${type.slice(1)} details`
4371
+ }
4372
+ ),
4373
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
4374
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4375
+ /* @__PURE__ */ jsx(Icon, { size: 20, color: "var(--color-primary)" }),
4376
+ /* @__PURE__ */ jsxs(Badge, { color: "blue", variant: "light", children: [
4377
+ type.charAt(0).toUpperCase(),
4378
+ type.slice(1)
4379
+ ] }),
4380
+ /* @__PURE__ */ jsx(Badge, { color: ResourceStatusColors[resource.status], variant: "outline", size: "sm", children: resource.status.toUpperCase() }),
4381
+ resource.version && /* @__PURE__ */ jsxs(Badge, { variant: "outline", size: "sm", children: [
4382
+ "v",
4383
+ resource.version
4384
+ ] }),
4385
+ /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
4386
+ /* @__PURE__ */ jsxs(Text, { size: "sm", ff: "monospace", c: "dimmed", children: [
4387
+ organizationName,
4388
+ "/",
4389
+ resource.resourceId
4390
+ ] }),
4391
+ /* @__PURE__ */ jsx(Tooltip, { label: clipboard.copied ? "Copied!" : "Copy ID", children: /* @__PURE__ */ jsx(ActionIcon, { size: "sm", variant: "subtle", onClick: handleCopyId, color: clipboard.copied ? "teal" : "gray", children: /* @__PURE__ */ jsx(IconCopy, { size: 14, color: clipboard.copied ? "teal" : "gray" }) }) })
4392
+ ] })
4393
+ ] }),
4394
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4395
+ connected && /* @__PURE__ */ jsx(Badge, { color: "green", variant: "dot", children: "CONNECTED" }),
4396
+ runningCount && runningCount > 0 && /* @__PURE__ */ jsxs(Badge, { color: "blue", variant: "filled", children: [
4397
+ runningCount,
4398
+ " running"
4399
+ ] }),
4400
+ type === "agent" && sessionCapable && /* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", leftSection: /* @__PURE__ */ jsx(IconMessage, { size: 16 }), onClick: handleGoToSessions, children: "Go to Sessions" }),
4401
+ /* @__PURE__ */ jsx(
4402
+ Button,
4403
+ {
4404
+ size: "sm",
4405
+ variant: "light",
4406
+ leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
4407
+ onClick: () => navigate({ to: "/operations/resources" }),
4408
+ children: "Resources"
4409
+ }
4410
+ )
4411
+ ] })
4412
+ ] })
4413
+ ] });
4414
+ }
4415
+ function ResourceErrorState({ error }) {
4416
+ return /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", children: [
4417
+ /* @__PURE__ */ jsx(Text, { c: "red", children: "Failed to load resource" }),
4418
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: error.message })
4419
+ ] }) }) });
4420
+ }
4421
+ function ResourceNotFoundState({ type, resourceId }) {
4422
+ const navigate = useNavigate();
4423
+ const { currentMembership } = useOrganization();
4424
+ const orgName = currentMembership?.organization?.name || "current organization";
4425
+ return /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Stack, { align: "center", children: [
4426
+ /* @__PURE__ */ jsx(Text, { size: "lg", c: "dimmed", fw: 500, children: "Resource not found" }),
4427
+ /* @__PURE__ */ jsxs(Text, { size: "sm", c: "dimmed", ta: "center", children: [
4428
+ "The ",
4429
+ type,
4430
+ ' "',
4431
+ resourceId,
4432
+ '" could not be found in ',
4433
+ orgName,
4434
+ "."
4435
+ ] }),
4436
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", ta: "center", children: "This resource may exist in a different organization. Try switching organizations or returning to the overview." }),
4437
+ /* @__PURE__ */ jsx(
4438
+ Button,
4439
+ {
4440
+ variant: "light",
4441
+ leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }),
4442
+ onClick: () => navigate({ to: "/operations", search: { type: void 0 } }),
4443
+ children: "Back to Operations"
4444
+ }
4445
+ )
4446
+ ] }) }) });
4447
+ }
4448
+ function ResourceDetailPage({
4449
+ type,
4450
+ resourceId,
4451
+ renderExecutionPanel,
4452
+ renderHealthPanel,
4453
+ renderDefinitionSection
4454
+ }) {
4455
+ const { organizationReady } = useInitialization();
4456
+ const { data, isLoading, error } = useResources();
4457
+ const [connected, setConnected] = useState(false);
4458
+ const [runningCount, setRunningCount] = useState(0);
4459
+ const resource = data ? (() => {
4460
+ const resources = [...data.workflows, ...data.agents];
4461
+ const found = resources.find((r) => r.resourceId === resourceId && r.type === type);
4462
+ return found || null;
4463
+ })() : null;
4464
+ const {
4465
+ data: resourceDefinition,
4466
+ isLoading: definitionLoading,
4467
+ error: definitionError
4468
+ } = useResourceDefinition(resourceId, true);
4469
+ const handleConnectionStatus = (isConnected, count) => {
4470
+ setConnected(isConnected);
4471
+ setRunningCount(count);
4472
+ };
4473
+ if (!organizationReady || isLoading || definitionLoading) {
4474
+ return /* @__PURE__ */ jsx(SubshellLoader, {});
4475
+ }
4476
+ if (error) {
4477
+ return /* @__PURE__ */ jsx(ResourceErrorState, { error });
4478
+ }
4479
+ if (!resource) {
4480
+ return /* @__PURE__ */ jsx(ResourceNotFoundState, { type, resourceId });
4481
+ }
4482
+ const validResource = resource;
4483
+ const sessionCapable = isSessionCapable(type, resourceDefinition);
4484
+ return /* @__PURE__ */ jsxs(Stack, { style: { overflow: "hidden", boxShadow: "var(--standard-box-shadow)" }, children: [
4485
+ /* @__PURE__ */ jsx(
4486
+ ResourceHeader,
4487
+ {
4488
+ resource: validResource,
4489
+ type,
4490
+ connected,
4491
+ runningCount,
4492
+ sessionCapable
4493
+ }
4494
+ ),
4495
+ renderHealthPanel?.({ resourceId, resourceType: type }),
4496
+ resourceDefinition && renderDefinitionSection?.(resourceDefinition),
4497
+ /* @__PURE__ */ jsx(
4498
+ Paper,
4499
+ {
4500
+ withBorder: true,
4501
+ p: "0",
4502
+ style: {
4503
+ flex: 1,
4504
+ overflow: "hidden",
4505
+ display: "flex",
4506
+ flexDirection: "column"
4507
+ },
4508
+ children: definitionError ? /* @__PURE__ */ jsx(ResourceErrorState, { error: definitionError }) : !resourceDefinition ? /* @__PURE__ */ jsx(ResourceErrorState, { error: new Error("Resource definition not found") }) : renderExecutionPanel?.({
4509
+ resourceId,
4510
+ resourceType: type,
4511
+ resourceName: validResource.name,
4512
+ resourceDefinition,
4513
+ onConnectionStatus: handleConnectionStatus
4514
+ })
4515
+ }
4516
+ )
4517
+ ] });
4518
+ }
4519
+ function AgentExecutionLogs({
4520
+ resourceId,
4521
+ executionId,
4522
+ execution: externalExecution,
4523
+ selectedIterationId,
4524
+ iterationData,
4525
+ onExecutionDeleted
4526
+ }) {
4527
+ const isIterationSelected = selectedIterationId !== null;
4528
+ const logGroups = useMemo(() => {
4529
+ if (!iterationData) {
4530
+ return [];
4531
+ }
4532
+ if (selectedIterationId !== null) {
4533
+ if (selectedIterationId === "initialization") {
4534
+ return [
4535
+ {
4536
+ title: "Initialization",
4537
+ groupKey: "initialization",
4538
+ logs: [],
4539
+ // Will be filled in renderLogsSection
4540
+ status: iterationData.initialization.status
4541
+ }
4542
+ ];
4543
+ }
4544
+ if (selectedIterationId === "completion") {
4545
+ return [
4546
+ {
4547
+ title: "Completion",
4548
+ groupKey: "completion",
4549
+ logs: [],
4550
+ // Will be filled in renderLogsSection
4551
+ status: iterationData.completion.status
4552
+ }
4553
+ ];
4554
+ }
4555
+ const selectedIteration = iterationData.iterations.find((iter) => iter.iterationNumber === selectedIterationId);
4556
+ if (!selectedIteration) {
4557
+ return [];
4558
+ }
4559
+ return [
4560
+ {
4561
+ title: `Iteration ${selectedIteration.iterationNumber}`,
4562
+ groupKey: selectedIteration.iterationNumber,
4563
+ logs: [],
4564
+ // Will be filled in renderLogsSection
4565
+ status: selectedIteration.status
4566
+ }
4567
+ ];
4568
+ }
4569
+ const groups = [];
4570
+ groups.push({
4571
+ title: "Initialization",
4572
+ groupKey: "initialization",
4573
+ logs: [],
4574
+ status: iterationData.initialization.status
4575
+ });
4576
+ for (const iteration of iterationData.iterations) {
4577
+ groups.push({
4578
+ title: `Iteration ${iteration.iterationNumber}`,
4579
+ groupKey: iteration.iterationNumber,
4580
+ logs: [],
4581
+ status: iteration.status
4582
+ });
4583
+ }
4584
+ groups.push({
4585
+ title: "Completion",
4586
+ groupKey: "completion",
4587
+ logs: [],
4588
+ status: iterationData.completion.status
4589
+ });
4590
+ return groups;
4591
+ }, [selectedIterationId, iterationData]);
4592
+ const getSelectedNodeTitle = () => {
4593
+ if (selectedIterationId === null) return null;
4594
+ if (selectedIterationId === "initialization") return "Initialization";
4595
+ if (selectedIterationId === "completion") return "Completion";
4596
+ return `Iteration ${selectedIterationId}`;
4597
+ };
4598
+ const selectedNodeTitle = getSelectedNodeTitle();
4599
+ const getIterationStatusBadge = (_groupKey, status) => {
4600
+ if (status) {
4601
+ const statusConfig3 = getExecutionStatusConfig(status);
4602
+ return {
4603
+ label: statusConfig3.label,
4604
+ color: statusConfig3.color
4605
+ };
4606
+ }
4607
+ return null;
4608
+ };
4609
+ const renderLogsSection = (execution) => {
4610
+ if (!execution.executionLogs || execution.executionLogs.length === 0) {
4611
+ return /* @__PURE__ */ jsx(Text, { c: "dimmed", ta: "center", mt: "md", children: "No logs available" });
4612
+ }
4613
+ const logsByGroup = /* @__PURE__ */ new Map();
4614
+ for (const log of execution.executionLogs) {
4615
+ const context = log.context;
4616
+ let groupKey;
4617
+ if (context?.type === "agent" && "lifecycle" in context) {
4618
+ const lifecycle = context.lifecycle;
4619
+ if (lifecycle === "initialization") {
4620
+ groupKey = "initialization";
4621
+ } else if (lifecycle === "iteration" && "iteration" in context) {
4622
+ groupKey = context.iteration;
4623
+ } else if (lifecycle === "completion") {
4624
+ groupKey = "completion";
4625
+ } else {
4626
+ groupKey = "completion";
4627
+ }
4628
+ } else {
4629
+ groupKey = "completion";
4630
+ }
4631
+ if (!logsByGroup.has(groupKey)) {
4632
+ logsByGroup.set(groupKey, []);
4633
+ }
4634
+ logsByGroup.get(groupKey).push(log);
4635
+ }
4636
+ const populatedGroups = logGroups.map((group) => ({
4637
+ ...group,
4638
+ logs: logsByGroup.get(group.groupKey) || []
4639
+ })).filter((group) => group.logs.length > 0);
4640
+ const totalLogsCount = populatedGroups.reduce((total, group) => total + group.logs.length, 0);
4641
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", style: { flex: 1, minHeight: 0 }, children: [
4642
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
4643
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: selectedNodeTitle ? `Logs for ${selectedNodeTitle} (${totalLogsCount})` : `Logs (${totalLogsCount})` }),
4644
+ iterationData && /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4645
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
4646
+ "Iterations: ",
4647
+ iterationData.iterations.filter((i) => i.status === "completed").length,
4648
+ "/",
4649
+ iterationData.totalIterations
4650
+ ] }),
4651
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
4652
+ "Events: ",
4653
+ iterationData.iterations.reduce((sum, iter) => sum + iter.iterationEvents.length, 0)
4654
+ ] })
4655
+ ] })
4656
+ ] }),
4657
+ /* @__PURE__ */ jsx(ScrollArea, { style: { flex: 1 }, scrollbarSize: 8, children: /* @__PURE__ */ jsxs(Stack, { children: [
4658
+ populatedGroups.map((group) => {
4659
+ const statusBadge = getIterationStatusBadge(group.groupKey, group.status);
4660
+ return /* @__PURE__ */ jsx(
4661
+ LogGroup,
4662
+ {
4663
+ title: group.title,
4664
+ logs: group.logs,
4665
+ statusBadge: statusBadge || void 0
4666
+ },
4667
+ group.groupKey
4668
+ );
4669
+ }),
4670
+ populatedGroups.length === 0 && /* @__PURE__ */ jsx(Text, { c: "dimmed", ta: "center", mt: "md", children: selectedNodeTitle ? `No logs for ${selectedNodeTitle}` : "No logs available" })
4671
+ ] }) })
4672
+ ] });
4673
+ };
4674
+ return /* @__PURE__ */ jsx(
4675
+ BaseExecutionLogs,
4676
+ {
4677
+ resourceId,
4678
+ resourceType: "agent",
4679
+ executionId,
4680
+ execution: externalExecution,
4681
+ onExecutionDeleted,
4682
+ renderLogsSection,
4683
+ hideInput: isIterationSelected,
4684
+ hideResult: isIterationSelected,
4685
+ hideError: isIterationSelected
4686
+ }
4687
+ );
4688
+ }
4689
+ function WorkflowExecutionLogs({
4690
+ resourceId,
4691
+ executionId,
4692
+ execution: externalExecution,
4693
+ selectedStepId,
4694
+ timelineData,
4695
+ onExecutionDeleted
4696
+ }) {
4697
+ const { data: fetchedExecution } = useExecution(resourceId, executionId || "");
4698
+ const typedExecution = externalExecution ?? fetchedExecution;
4699
+ const isStepSelected = !!selectedStepId;
4700
+ const logGroups = useMemo(() => {
4701
+ if (selectedStepId && timelineData) {
4702
+ const selectedStep2 = timelineData.steps.find((s) => s.stepId === selectedStepId);
4703
+ return selectedStep2 ? [{ stepName: selectedStep2.stepName, stepId: selectedStep2.stepId, logs: selectedStep2.logs }] : [];
4704
+ }
4705
+ if (!timelineData || !typedExecution) {
4706
+ return [];
4707
+ }
4708
+ const groups = [];
4709
+ for (const step of timelineData.steps) {
4710
+ if (step.logs.length > 0) {
4711
+ groups.push({
4712
+ stepName: step.stepName,
4713
+ stepId: step.stepId,
4714
+ logs: step.logs
4715
+ });
4716
+ }
4717
+ }
4718
+ const stepLogTimestamps = new Set(timelineData.steps.flatMap((s) => s.logs.map((l) => l.timestamp)));
4719
+ const generalExecutionLogs = typedExecution.executionLogs.filter((log) => !stepLogTimestamps.has(log.timestamp));
4720
+ const generalWorkflowLogs = toWorkflowLogMessages(generalExecutionLogs);
4721
+ if (generalWorkflowLogs.length > 0) {
4722
+ groups.unshift({
4723
+ stepName: "General",
4724
+ stepId: "general",
4725
+ logs: generalWorkflowLogs
4726
+ });
4727
+ }
4728
+ return groups;
4729
+ }, [selectedStepId, timelineData, typedExecution]);
4730
+ const selectedStep = selectedStepId && timelineData ? timelineData.steps.find((s) => s.stepId === selectedStepId) : null;
4731
+ const totalLogsCount = logGroups.reduce((total, group) => total + group.logs.length, 0);
4732
+ const scrollViewportRef = useRef(null);
4733
+ const isNearBottomRef = useRef(true);
4734
+ const handleScroll = useCallback(() => {
4735
+ const viewport = scrollViewportRef.current;
4736
+ if (!viewport) return;
4737
+ isNearBottomRef.current = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight < 50;
4738
+ }, []);
4739
+ useEffect(() => {
4740
+ if (!isNearBottomRef.current) return;
4741
+ const viewport = scrollViewportRef.current;
4742
+ if (!viewport) return;
4743
+ viewport.scrollTop = viewport.scrollHeight;
4744
+ }, [totalLogsCount]);
4745
+ const getStepStatusBadge = (stepId) => {
4746
+ if (stepId === "general") {
4747
+ return { label: "General", color: "blue" };
4748
+ }
4749
+ if (!timelineData) {
4750
+ return null;
4751
+ }
4752
+ const step = timelineData.steps.find((s) => s.stepId === stepId);
4753
+ if (!step) {
4754
+ return null;
4755
+ }
4756
+ const statusConfig3 = getExecutionStatusConfig(step.status);
4757
+ return {
4758
+ label: statusConfig3.label,
4759
+ color: statusConfig3.color
4760
+ };
4761
+ };
4762
+ const renderLogsSection = () => {
4763
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", style: { flex: 1, minHeight: 0 }, children: [
4764
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
4765
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: selectedStep ? `Logs for ${selectedStep.stepName} (${totalLogsCount})` : `Logs (${totalLogsCount})` }),
4766
+ timelineData && /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4767
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
4768
+ "Steps: ",
4769
+ timelineData.steps.filter((s) => s.status === "completed").length,
4770
+ "/",
4771
+ timelineData.steps.length
4772
+ ] }),
4773
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
4774
+ "Duration:",
4775
+ " ",
4776
+ timelineData.totalDuration < 1e3 ? `${timelineData.totalDuration}ms` : `${(timelineData.totalDuration / 1e3).toFixed(2)}s`
4777
+ ] })
4778
+ ] })
4779
+ ] }),
4780
+ /* @__PURE__ */ jsx(
4781
+ ScrollArea,
4782
+ {
4783
+ style: { flex: 1 },
4784
+ scrollbarSize: 8,
4785
+ viewportRef: scrollViewportRef,
4786
+ onScrollPositionChange: handleScroll,
4787
+ children: /* @__PURE__ */ jsxs(Stack, { children: [
4788
+ logGroups.map((group) => {
4789
+ const statusBadge = getStepStatusBadge(group.stepId);
4790
+ return /* @__PURE__ */ jsx(
4791
+ LogGroup,
4792
+ {
4793
+ title: group.stepName,
4794
+ logs: group.logs,
4795
+ statusBadge: statusBadge || void 0
4796
+ },
4797
+ group.stepId
4798
+ );
4799
+ }),
4800
+ logGroups.length === 0 && /* @__PURE__ */ jsx(Text, { c: "dimmed", ta: "center", mt: "md", children: selectedStep ? `No logs for ${selectedStep.stepName}` : "No logs available" })
4801
+ ] })
4802
+ }
4803
+ )
4804
+ ] });
4805
+ };
4806
+ return /* @__PURE__ */ jsx(
4807
+ BaseExecutionLogs,
4808
+ {
4809
+ resourceId,
4810
+ resourceType: "workflow",
4811
+ executionId,
4812
+ onExecutionDeleted,
4813
+ renderLogsSection,
4814
+ hideInput: isStepSelected,
4815
+ hideResult: isStepSelected,
4816
+ hideError: isStepSelected
4817
+ }
4818
+ );
4819
+ }
4820
+ function buildTree(files) {
4821
+ const root = { label: "root", path: null, order: 0, isIndex: false, children: [] };
4822
+ for (const file of files) {
4823
+ const segments = file.path.split("/");
4824
+ let current = root;
4825
+ for (let i = 0; i < segments.length; i++) {
4826
+ const segment = segments[i];
4827
+ const isLastSegment = i === segments.length - 1;
4828
+ const isIndexFile = isLastSegment && (segment === "index.mdx" || segment === "index.md");
4829
+ if (isLastSegment) {
4830
+ if (isIndexFile) {
4831
+ current.path = file.path;
4832
+ current.label = file.frontmatter.title || current.label;
4833
+ current.order = file.frontmatter.order ?? current.order;
4834
+ current.isIndex = true;
4835
+ } else {
4836
+ current.children.push({
4837
+ label: file.frontmatter.title || segment.replace(/\.mdx?$/, ""),
4838
+ path: file.path,
4839
+ order: file.frontmatter.order ?? Infinity,
4840
+ isIndex: false,
4841
+ children: []
4842
+ });
4843
+ }
4844
+ } else {
4845
+ let child = current.children.find((c) => c.label === segment && c.path === null);
4846
+ if (!child) {
4847
+ child = {
4848
+ label: segment,
4849
+ path: null,
4850
+ order: Infinity,
4851
+ isIndex: false,
4852
+ children: []
4853
+ };
4854
+ current.children.push(child);
4855
+ }
4856
+ current = child;
4857
+ }
4858
+ }
4859
+ }
4860
+ return sortNodes(root.children);
4861
+ }
4862
+ function sortNodes(nodes) {
4863
+ return nodes.map((node) => ({
4864
+ ...node,
4865
+ children: sortNodes(node.children)
4866
+ })).sort((a, b) => {
4867
+ if (a.isIndex && !b.isIndex) return -1;
4868
+ if (!a.isIndex && b.isIndex) return 1;
4869
+ if (a.order !== b.order) return a.order - b.order;
4870
+ return a.label.localeCompare(b.label);
4871
+ });
4872
+ }
4873
+ function hasDescendant(node, targetPath) {
4874
+ if (!targetPath) return false;
4875
+ if (node.path === targetPath) return true;
4876
+ return node.children.some((child) => hasDescendant(child, targetPath));
4877
+ }
4878
+ function TreeNodeItem({
4879
+ node,
4880
+ selectedPath,
4881
+ onSelect,
4882
+ expandedPaths,
4883
+ onToggle
4884
+ }) {
4885
+ const isDirectory = node.children.length > 0;
4886
+ const key = node.path ?? node.label;
4887
+ if (isDirectory && node.path) {
4888
+ const isExpanded = expandedPaths[key] ?? true;
4889
+ const isActive = hasDescendant(node, selectedPath);
4890
+ return /* @__PURE__ */ jsx(
4891
+ CollapsibleSidebarGroup,
4892
+ {
4893
+ icon: isExpanded ? IconFolderOpen : IconFolder,
4894
+ label: node.label,
4895
+ isExpanded,
4896
+ onToggle: () => onToggle(key),
4897
+ isActive,
4898
+ onLabelClick: () => onSelect(node.path),
4899
+ children: node.children.map((child) => /* @__PURE__ */ jsx(
4900
+ TreeNodeItem,
4901
+ {
4902
+ node: child,
4903
+ selectedPath,
4904
+ onSelect,
4905
+ expandedPaths,
4906
+ onToggle
4907
+ },
4908
+ child.path ?? child.label
4909
+ ))
4910
+ }
4911
+ );
4912
+ }
4913
+ if (isDirectory) {
4914
+ const isExpanded = expandedPaths[key] ?? true;
4915
+ const isActive = hasDescendant(node, selectedPath);
4916
+ return /* @__PURE__ */ jsx(
4917
+ CollapsibleSidebarGroup,
4918
+ {
4919
+ icon: isExpanded ? IconFolderOpen : IconFolder,
4920
+ label: node.label,
4921
+ isExpanded,
4922
+ onToggle: () => onToggle(key),
4923
+ isActive,
4924
+ children: node.children.map((child) => /* @__PURE__ */ jsx(
4925
+ TreeNodeItem,
4926
+ {
4927
+ node: child,
4928
+ selectedPath,
4929
+ onSelect,
4930
+ expandedPaths,
4931
+ onToggle
4932
+ },
4933
+ child.path ?? child.label
4934
+ ))
4935
+ }
4936
+ );
4937
+ }
4938
+ return /* @__PURE__ */ jsx(
4939
+ SidebarListItem,
4940
+ {
4941
+ icon: IconFileText,
4942
+ label: node.label,
4943
+ isActive: node.path === selectedPath,
4944
+ onClick: () => {
4945
+ if (node.path) onSelect(node.path);
4946
+ }
4947
+ }
4948
+ );
4949
+ }
4950
+ function DocTreeNav({ files, selectedPath, onSelect }) {
4951
+ const theme = useMantineTheme();
4952
+ const tree = useMemo(() => buildTree(files), [files]);
4953
+ const [expandedPaths, setExpandedPaths] = useState(() => {
4954
+ const expanded = {};
4955
+ function collectKeys(nodes) {
4956
+ for (const node of nodes) {
4957
+ if (node.children.length > 0) {
4958
+ expanded[node.path ?? node.label] = true;
4959
+ collectKeys(node.children);
4960
+ }
4961
+ }
4962
+ }
4963
+ collectKeys(tree);
4964
+ return expanded;
4965
+ });
4966
+ const handleToggle = (key) => {
4967
+ setExpandedPaths((prev) => ({ ...prev, [key]: !prev[key] }));
4968
+ };
4969
+ return /* @__PURE__ */ jsx(
4970
+ Box,
4971
+ {
4972
+ style: {
4973
+ flex: 1,
4974
+ minHeight: 0,
4975
+ padding: theme.spacing.sm,
4976
+ display: "flex",
4977
+ flexDirection: "column",
4978
+ overflow: "hidden"
4979
+ },
4980
+ children: /* @__PURE__ */ jsx(ScrollArea, { style: { flex: 1, minHeight: 0 }, scrollbarSize: 8, children: /* @__PURE__ */ jsx(Stack, { gap: 0, children: tree.map((node) => /* @__PURE__ */ jsx(
4981
+ TreeNodeItem,
4982
+ {
4983
+ node,
4984
+ selectedPath,
4985
+ onSelect,
4986
+ expandedPaths,
4987
+ onToggle: handleToggle
4988
+ },
4989
+ node.path ?? node.label
4990
+ )) }) })
4991
+ }
4992
+ );
4993
+ }
4994
+ function KnowledgeBasePage({ mdxRenderer: MdxRenderer }) {
4995
+ const { organizationReady } = useInitialization();
4996
+ const [selectedDeploymentId, setSelectedDeploymentId] = useState(void 0);
4997
+ const [selectedPath, setSelectedPath] = useState(null);
4998
+ const { files, isLoading, error, activeDeployment, activeDeployments } = useDeploymentDocs(selectedDeploymentId);
4999
+ const effectivePath = useMemo(() => {
5000
+ if (selectedPath && files.some((f) => f.path === selectedPath)) {
5001
+ return selectedPath;
5002
+ }
5003
+ if (files.length === 0) return null;
5004
+ const indexFile = files.find((f) => f.path === "index.mdx" || f.path === "docs/index.mdx");
5005
+ if (indexFile) return indexFile.path;
5006
+ return files[0].path;
5007
+ }, [selectedPath, files]);
5008
+ const selectedFile = useMemo(() => {
5009
+ if (!effectivePath) return null;
5010
+ return files.find((f) => f.path === effectivePath) ?? null;
5011
+ }, [effectivePath, files]);
5012
+ const handleSelect = useCallback((path) => {
5013
+ setSelectedPath(path);
5014
+ }, []);
5015
+ const contentRef = useRef(null);
5016
+ const [headings, setHeadings] = useState([]);
5017
+ const [activeHeadingId, setActiveHeadingId] = useState(null);
5018
+ useEffect(() => {
5019
+ if (!contentRef.current) {
5020
+ setHeadings([]);
5021
+ return;
5022
+ }
5023
+ const timer = setTimeout(() => {
5024
+ if (!contentRef.current) return;
5025
+ const elements = contentRef.current.querySelectorAll("h3[id], h4[id]");
5026
+ const items = Array.from(elements).map((el) => ({
5027
+ id: el.id,
5028
+ text: el.textContent || "",
5029
+ level: parseInt(el.tagName[1])
5030
+ }));
5031
+ setHeadings(items);
5032
+ setActiveHeadingId(items[0]?.id ?? null);
5033
+ }, 100);
5034
+ return () => clearTimeout(timer);
5035
+ }, [selectedFile?.compiledSource]);
5036
+ useEffect(() => {
5037
+ if (headings.length === 0) return;
5038
+ const scrollContainer = contentRef.current?.closest('[style*="overflow"]');
5039
+ if (!scrollContainer) return;
5040
+ const handleScroll = () => {
5041
+ if (!contentRef.current) return;
5042
+ const elements = contentRef.current.querySelectorAll("h3[id], h4[id]");
5043
+ let current = headings[0]?.id ?? null;
5044
+ for (const el of elements) {
5045
+ const rect = el.getBoundingClientRect();
5046
+ if (rect.top <= 120) {
5047
+ current = el.id;
5048
+ } else {
5049
+ break;
5050
+ }
5051
+ }
5052
+ setActiveHeadingId(current);
5053
+ };
5054
+ scrollContainer.addEventListener("scroll", handleScroll, { passive: true });
5055
+ return () => scrollContainer.removeEventListener("scroll", handleScroll);
5056
+ }, [headings]);
5057
+ if (!organizationReady || isLoading) return /* @__PURE__ */ jsx(SubshellLoader, {});
5058
+ const showError = !!error;
5059
+ const showNoDeployments = !error && !activeDeployment;
5060
+ const showNoDocs = !error && !!activeDeployment && files.length === 0;
5061
+ const showContent = !error && files.length > 0;
5062
+ return /* @__PURE__ */ jsxs(SubshellContainer, { children: [
5063
+ /* @__PURE__ */ jsxs(SubshellSidebar, { width: 250, children: [
5064
+ /* @__PURE__ */ jsx(
5065
+ Box,
5066
+ {
5067
+ p: "sm",
5068
+ style: { borderBottom: "1px solid var(--color-border)", borderRadius: "var(--mantine-radius-default)" },
5069
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5070
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5071
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5072
+ /* @__PURE__ */ jsx(IconBook2, { size: 16, color: "var(--color-text-subtle)" }),
5073
+ /* @__PURE__ */ jsx(
5074
+ Text,
5075
+ {
5076
+ size: "sm",
5077
+ fw: 600,
5078
+ c: "var(--color-text-subtle)",
5079
+ style: { fontFamily: "var(--mantine-font-family-headings)" },
5080
+ children: "Documentation"
5081
+ }
5082
+ )
5083
+ ] }),
5084
+ activeDeployment && /* @__PURE__ */ jsxs(Badge, { size: "xs", variant: "light", children: [
5085
+ "v",
5086
+ activeDeployment.sdkVersion
5087
+ ] })
5088
+ ] }),
5089
+ activeDeployments.length > 1 && /* @__PURE__ */ jsx(
5090
+ Select,
5091
+ {
5092
+ size: "xs",
5093
+ placeholder: "Select deployment",
5094
+ data: activeDeployments.map((d) => ({
5095
+ value: d.id,
5096
+ label: `${d.sdkVersion} -- ${new Date(d.createdAt).toLocaleDateString()}`
5097
+ })),
5098
+ value: activeDeployment?.id ?? null,
5099
+ onChange: (value) => setSelectedDeploymentId(value ?? void 0)
5100
+ }
5101
+ )
5102
+ ] })
5103
+ }
5104
+ ),
5105
+ showContent && /* @__PURE__ */ jsx(DocTreeNav, { files, selectedPath: effectivePath, onSelect: handleSelect })
5106
+ ] }),
5107
+ /* @__PURE__ */ jsx(SubshellRightSideContainer, { children: /* @__PURE__ */ jsx(SubshellContentContainer, { children: /* @__PURE__ */ jsx(PageContainer, { children: /* @__PURE__ */ jsxs(Stack, { children: [
5108
+ /* @__PURE__ */ jsx(PageTitleCaption, { title: "Knowledge Base" }),
5109
+ showError && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), title: "Failed to load documentation", color: "red", children: error instanceof Error ? error.message : "An unexpected error occurred" }),
5110
+ showNoDeployments && /* @__PURE__ */ jsx(Center, { style: { flex: 1 }, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "sm", children: [
5111
+ /* @__PURE__ */ jsx(IconFileOff, { size: 48, color: "var(--color-text-subtle)" }),
5112
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "lg", children: "No active deployments" }),
5113
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: "Deploy your project using the Elevasis SDK to see documentation here." })
5114
+ ] }) }),
5115
+ showNoDocs && /* @__PURE__ */ jsx(Center, { style: { flex: 1 }, children: /* @__PURE__ */ jsxs(Stack, { align: "center", gap: "sm", children: [
5116
+ /* @__PURE__ */ jsx(IconFileOff, { size: 48, color: "var(--color-text-subtle)" }),
5117
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "lg", children: "No documentation found" }),
5118
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", size: "sm", children: "Add MDX files to your project's docs directory and redeploy." })
5119
+ ] }) }),
5120
+ showContent && selectedFile && /* @__PURE__ */ jsxs(Box, { style: { display: "flex", gap: "1rem", alignItems: "flex-start" }, children: [
5121
+ /* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(Card, { withBorder: true, children: /* @__PURE__ */ jsx("div", { ref: contentRef, children: MdxRenderer ? /* @__PURE__ */ jsx(MdxRenderer, { compiledSource: selectedFile.compiledSource }) : /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "No MDX renderer provided" }) }) }) }),
5122
+ headings.length > 1 && /* @__PURE__ */ jsxs(
5123
+ Box,
5124
+ {
5125
+ style: {
5126
+ width: 200,
5127
+ flexShrink: 0,
5128
+ position: "sticky",
5129
+ top: 70,
5130
+ border: "1px solid var(--color-border)",
5131
+ padding: "0.75rem",
5132
+ background: "var(--glass-background)",
5133
+ backdropFilter: "var(--glass-blur)",
5134
+ borderRadius: "var(--mantine-radius-default)"
5135
+ },
5136
+ children: [
5137
+ /* @__PURE__ */ jsxs(Group, { gap: 6, mb: "xs", children: [
5138
+ /* @__PURE__ */ jsx(IconList, { size: 16, style: { opacity: 0.5 } }),
5139
+ /* @__PURE__ */ jsx(Title, { order: 6, c: "dimmed", tt: "uppercase", children: "On this page" })
5140
+ ] }),
5141
+ /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: 400, scrollbarSize: 4, children: /* @__PURE__ */ jsx(Stack, { gap: 2, children: headings.map((heading) => /* @__PURE__ */ jsx(
5142
+ Text,
5143
+ {
5144
+ component: "a",
5145
+ href: `#${heading.id}`,
5146
+ size: "sm",
5147
+ onClick: (e) => {
5148
+ e.preventDefault();
5149
+ document.getElementById(heading.id)?.scrollIntoView({ behavior: "smooth", block: "start" });
5150
+ },
5151
+ style: {
5152
+ display: "block",
5153
+ padding: "3px 8px",
5154
+ paddingLeft: heading.level === 4 ? "16px" : "8px",
5155
+ borderLeft: activeHeadingId === heading.id ? "2px solid var(--color-primary)" : "2px solid transparent",
5156
+ color: activeHeadingId === heading.id ? "var(--color-primary)" : "var(--color-text-subtle)",
5157
+ textDecoration: "none",
5158
+ borderRadius: 0,
5159
+ transition: "all var(--duration-fast) var(--easing)",
5160
+ cursor: "pointer",
5161
+ lineHeight: 1.4
5162
+ },
5163
+ onMouseEnter: (e) => {
5164
+ if (activeHeadingId !== heading.id) {
5165
+ e.currentTarget.style.color = "var(--color-text)";
5166
+ }
5167
+ },
5168
+ onMouseLeave: (e) => {
5169
+ if (activeHeadingId !== heading.id) {
5170
+ e.currentTarget.style.color = "var(--color-text-subtle)";
5171
+ }
5172
+ },
5173
+ children: heading.text
5174
+ },
5175
+ heading.id
5176
+ )) }) })
5177
+ ]
5178
+ }
5179
+ )
5180
+ ] }),
5181
+ showContent && !selectedFile && /* @__PURE__ */ jsx(Center, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Select a page from the navigation" }) })
5182
+ ] }) }) }) })
5183
+ ] });
5184
+ }
5185
+ function ScheduleTypeSelector({ value, onChange, disabled }) {
5186
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5187
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Schedule Type" }),
5188
+ /* @__PURE__ */ jsx(
5189
+ SegmentedControl,
5190
+ {
5191
+ value,
5192
+ onChange: (v) => onChange(v),
5193
+ disabled,
5194
+ data: [
5195
+ {
5196
+ value: "recurring",
5197
+ label: /* @__PURE__ */ jsxs(Stack, { gap: 4, align: "center", children: [
5198
+ /* @__PURE__ */ jsx(IconCalendarRepeat, { size: 20 }),
5199
+ /* @__PURE__ */ jsx(Text, { size: "xs", children: "Recurring" })
5200
+ ] })
5201
+ },
5202
+ {
5203
+ value: "relative",
5204
+ label: /* @__PURE__ */ jsxs(Stack, { gap: 4, align: "center", children: [
5205
+ /* @__PURE__ */ jsx(IconCalendarEvent, { size: 20 }),
5206
+ /* @__PURE__ */ jsx(Text, { size: "xs", children: "Relative" })
5207
+ ] })
5208
+ },
5209
+ {
5210
+ value: "absolute",
5211
+ label: /* @__PURE__ */ jsxs(Stack, { gap: 4, align: "center", children: [
5212
+ /* @__PURE__ */ jsx(IconCalendarTime, { size: 20 }),
5213
+ /* @__PURE__ */ jsx(Text, { size: "xs", children: "Absolute" })
5214
+ ] })
5215
+ }
5216
+ ],
5217
+ fullWidth: true
5218
+ }
5219
+ ),
5220
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
5221
+ value === "recurring" && "Run on a schedule (daily, weekly, or cron expression)",
5222
+ value === "relative" && "Run at offsets from an anchor date (e.g., 3 days before event)",
5223
+ value === "absolute" && "Run at specific dates and times"
5224
+ ] })
5225
+ ] });
5226
+ }
5227
+ function toDateTimeLocal(isoString) {
5228
+ if (!isoString) return "";
5229
+ const date = new Date(isoString);
5230
+ return date.toISOString().slice(0, 16);
5231
+ }
5232
+ function fromDateTimeLocal(dateTimeLocal) {
5233
+ if (!dateTimeLocal) return null;
5234
+ return new Date(dateTimeLocal).toISOString();
5235
+ }
5236
+ function RecurringScheduleForm({ value, onChange, disabled }) {
5237
+ const [useCron, setUseCron] = useState(!!value.cron);
5238
+ const handleChange = (updates) => {
5239
+ onChange({ ...value, ...updates });
5240
+ };
5241
+ return /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5242
+ /* @__PURE__ */ jsx(
5243
+ Switch,
5244
+ {
5245
+ label: "Use cron expression",
5246
+ description: "Advanced scheduling with cron syntax",
5247
+ checked: useCron,
5248
+ onChange: (e) => {
5249
+ setUseCron(e.currentTarget.checked);
5250
+ if (e.currentTarget.checked) {
5251
+ handleChange({ cron: "0 9 * * *", interval: void 0, time: void 0 });
5252
+ } else {
5253
+ handleChange({ cron: void 0, interval: "daily", time: "09:00" });
5254
+ }
5255
+ },
5256
+ disabled
5257
+ }
5258
+ ),
5259
+ useCron ? /* @__PURE__ */ jsx(
5260
+ TextInput,
5261
+ {
5262
+ label: "Cron Expression",
5263
+ placeholder: "0 9 * * 1 (Every Monday at 9am)",
5264
+ value: value.cron || "",
5265
+ onChange: (e) => handleChange({ cron: e.currentTarget.value }),
5266
+ description: "Format: minute hour day month weekday",
5267
+ disabled
5268
+ }
5269
+ ) : /* @__PURE__ */ jsxs(Group, { grow: true, children: [
5270
+ /* @__PURE__ */ jsx(
5271
+ Select,
5272
+ {
5273
+ label: "Interval",
5274
+ data: [
5275
+ { value: "daily", label: "Daily" },
5276
+ { value: "weekly", label: "Weekly" },
5277
+ { value: "monthly", label: "Monthly" }
5278
+ ],
5279
+ value: value.interval || "daily",
5280
+ onChange: (v) => handleChange({ interval: v }),
5281
+ disabled
5282
+ }
5283
+ ),
5284
+ /* @__PURE__ */ jsx(
5285
+ TextInput,
5286
+ {
5287
+ label: "Time",
5288
+ type: "time",
5289
+ value: value.time || "09:00",
5290
+ onChange: (e) => handleChange({ time: e.currentTarget.value }),
5291
+ disabled
5292
+ }
5293
+ )
5294
+ ] }),
5295
+ /* @__PURE__ */ jsx(
5296
+ Select,
5297
+ {
5298
+ label: "Timezone",
5299
+ placeholder: "Select timezone",
5300
+ data: [
5301
+ { value: "UTC", label: "UTC" },
5302
+ { value: "America/New_York", label: "Eastern Time" },
5303
+ { value: "America/Chicago", label: "Central Time" },
5304
+ { value: "America/Denver", label: "Mountain Time" },
5305
+ { value: "America/Los_Angeles", label: "Pacific Time" },
5306
+ { value: "Europe/London", label: "London" },
5307
+ { value: "Europe/Paris", label: "Paris" },
5308
+ { value: "Asia/Tokyo", label: "Tokyo" }
5309
+ ],
5310
+ value: value.timezone || "UTC",
5311
+ onChange: (v) => handleChange({ timezone: v || "UTC" }),
5312
+ searchable: true,
5313
+ disabled
5314
+ }
5315
+ ),
5316
+ /* @__PURE__ */ jsx(
5317
+ TextInput,
5318
+ {
5319
+ label: "End Date (Optional)",
5320
+ type: "datetime-local",
5321
+ value: toDateTimeLocal(value.endAt),
5322
+ onChange: (e) => handleChange({ endAt: fromDateTimeLocal(e.currentTarget.value) }),
5323
+ disabled
5324
+ }
5325
+ )
5326
+ ] });
5327
+ }
5328
+ function toDateTimeLocal2(isoString) {
5329
+ if (!isoString) return "";
5330
+ const date = new Date(isoString);
5331
+ return date.toISOString().slice(0, 16);
5332
+ }
5333
+ function fromDateTimeLocal2(dateTimeLocal) {
5334
+ if (!dateTimeLocal) return void 0;
5335
+ return new Date(dateTimeLocal).toISOString();
5336
+ }
5337
+ function RelativeScheduleForm({ value, onChange, disabled }) {
5338
+ const items = value.items || [];
5339
+ const handleAnchorChange = (dateTimeLocal) => {
5340
+ onChange({ ...value, anchorAt: fromDateTimeLocal2(dateTimeLocal) });
5341
+ };
5342
+ const handleItemChange = (index, updates) => {
5343
+ const newItems = [...items];
5344
+ newItems[index] = { ...newItems[index], ...updates };
5345
+ onChange({ ...value, items: newItems });
5346
+ };
5347
+ const handleAddItem = () => {
5348
+ const newItems = [...items, { offset: "+1d", payload: {}, label: "" }];
5349
+ onChange({ ...value, items: newItems });
5350
+ };
5351
+ const handleRemoveItem = (index) => {
5352
+ const newItems = items.filter((_, i) => i !== index);
5353
+ onChange({ ...value, items: newItems });
5354
+ };
5355
+ return /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5356
+ /* @__PURE__ */ jsx(
5357
+ TextInput,
5358
+ {
5359
+ label: "Anchor Date",
5360
+ description: "Reference date for calculating run times",
5361
+ type: "datetime-local",
5362
+ value: toDateTimeLocal2(value.anchorAt),
5363
+ onChange: (e) => handleAnchorChange(e.currentTarget.value),
5364
+ required: true,
5365
+ disabled
5366
+ }
5367
+ ),
5368
+ /* @__PURE__ */ jsx(
5369
+ TextInput,
5370
+ {
5371
+ label: "Anchor Label (Optional)",
5372
+ placeholder: "e.g., meeting_date, deadline, event_start",
5373
+ value: value.anchorLabel || "",
5374
+ onChange: (e) => onChange({ ...value, anchorLabel: e.currentTarget.value || void 0 }),
5375
+ disabled
5376
+ }
5377
+ ),
5378
+ /* @__PURE__ */ jsxs(Stack, { children: [
5379
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5380
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Schedule Items" }),
5381
+ /* @__PURE__ */ jsx(
5382
+ Button,
5383
+ {
5384
+ size: "xs",
5385
+ variant: "light",
5386
+ leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 14 }),
5387
+ onClick: handleAddItem,
5388
+ disabled,
5389
+ children: "Add Item"
5390
+ }
5391
+ )
5392
+ ] }),
5393
+ items.length === 0 && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: 'No items yet. Click "Add Item" to create a schedule step.' }),
5394
+ items.map((item, index) => /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5395
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5396
+ /* @__PURE__ */ jsxs(Text, { size: "sm", fw: 500, children: [
5397
+ "Step ",
5398
+ index + 1
5399
+ ] }),
5400
+ /* @__PURE__ */ jsx(
5401
+ ActionIcon,
5402
+ {
5403
+ size: "sm",
5404
+ color: "red",
5405
+ variant: "subtle",
5406
+ onClick: () => handleRemoveItem(index),
5407
+ disabled,
5408
+ children: /* @__PURE__ */ jsx(IconTrash, { size: 14 })
5409
+ }
5410
+ )
5411
+ ] }),
5412
+ /* @__PURE__ */ jsxs(Group, { grow: true, children: [
5413
+ /* @__PURE__ */ jsx(
5414
+ TextInput,
5415
+ {
5416
+ label: "Offset",
5417
+ placeholder: "+3d, -2h, +30m",
5418
+ value: item.offset,
5419
+ onChange: (e) => handleItemChange(index, { offset: e.currentTarget.value }),
5420
+ description: "+ after anchor, - before anchor",
5421
+ disabled
5422
+ }
5423
+ ),
5424
+ /* @__PURE__ */ jsx(
5425
+ TextInput,
5426
+ {
5427
+ label: "Label (Optional)",
5428
+ placeholder: "e.g., Thank you, Follow up",
5429
+ value: item.label || "",
5430
+ onChange: (e) => handleItemChange(index, { label: e.currentTarget.value || void 0 }),
5431
+ disabled
5432
+ }
5433
+ )
5434
+ ] }),
5435
+ /* @__PURE__ */ jsx(
5436
+ Textarea,
5437
+ {
5438
+ label: "Payload (JSON)",
5439
+ placeholder: '{"key": "value"}',
5440
+ value: JSON.stringify(item.payload, null, 2),
5441
+ onChange: (e) => {
5442
+ try {
5443
+ const payload = JSON.parse(e.currentTarget.value);
5444
+ handleItemChange(index, { payload });
5445
+ } catch {
5446
+ }
5447
+ },
5448
+ minRows: 2,
5449
+ disabled
5450
+ }
5451
+ )
5452
+ ] }) }, index))
5453
+ ] })
5454
+ ] });
5455
+ }
5456
+ function toDateTimeLocal3(isoString) {
5457
+ if (!isoString) return "";
5458
+ const date = new Date(isoString);
5459
+ return date.toISOString().slice(0, 16);
5460
+ }
5461
+ function fromDateTimeLocal3(dateTimeLocal) {
5462
+ if (!dateTimeLocal) return "";
5463
+ return new Date(dateTimeLocal).toISOString();
5464
+ }
5465
+ function AbsoluteScheduleForm({ value, onChange, disabled }) {
5466
+ const items = value.items || [];
5467
+ const handleItemChange = (index, updates) => {
5468
+ const newItems = [...items];
5469
+ newItems[index] = { ...newItems[index], ...updates };
5470
+ onChange({ ...value, items: newItems });
5471
+ };
5472
+ const handleAddItem = () => {
5473
+ const newItems = [...items, { runAt: (/* @__PURE__ */ new Date()).toISOString(), payload: {}, label: "" }];
5474
+ onChange({ ...value, items: newItems });
5475
+ };
5476
+ const handleRemoveItem = (index) => {
5477
+ const newItems = items.filter((_, i) => i !== index);
5478
+ onChange({ ...value, items: newItems });
5479
+ };
5480
+ return /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5481
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5482
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: "Scheduled Executions" }),
5483
+ /* @__PURE__ */ jsx(
5484
+ Button,
5485
+ {
5486
+ size: "xs",
5487
+ variant: "light",
5488
+ leftSection: /* @__PURE__ */ jsx(IconPlus, { size: 14 }),
5489
+ onClick: handleAddItem,
5490
+ disabled,
5491
+ children: "Add Execution"
5492
+ }
5493
+ )
5494
+ ] }),
5495
+ items.length === 0 && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: 'No executions yet. Click "Add Execution" to schedule a run.' }),
5496
+ items.map((item, index) => /* @__PURE__ */ jsx(Paper, { withBorder: true, children: /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5497
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5498
+ /* @__PURE__ */ jsxs(Text, { size: "sm", fw: 500, children: [
5499
+ "Execution ",
5500
+ index + 1
5501
+ ] }),
5502
+ /* @__PURE__ */ jsx(
5503
+ ActionIcon,
5504
+ {
5505
+ size: "sm",
5506
+ color: "red",
5507
+ variant: "subtle",
5508
+ onClick: () => handleRemoveItem(index),
5509
+ disabled,
5510
+ children: /* @__PURE__ */ jsx(IconTrash, { size: 14 })
5511
+ }
5512
+ )
5513
+ ] }),
5514
+ /* @__PURE__ */ jsxs(Group, { grow: true, children: [
5515
+ /* @__PURE__ */ jsx(
5516
+ TextInput,
5517
+ {
5518
+ label: "Run At",
5519
+ type: "datetime-local",
5520
+ value: toDateTimeLocal3(item.runAt),
5521
+ onChange: (e) => handleItemChange(index, { runAt: fromDateTimeLocal3(e.currentTarget.value) }),
5522
+ required: true,
5523
+ disabled
5524
+ }
5525
+ ),
5526
+ /* @__PURE__ */ jsx(
5527
+ TextInput,
5528
+ {
5529
+ label: "Label (Optional)",
5530
+ placeholder: "e.g., Launch, Phase 2",
5531
+ value: item.label || "",
5532
+ onChange: (e) => handleItemChange(index, { label: e.currentTarget.value || void 0 }),
5533
+ disabled
5534
+ }
5535
+ )
5536
+ ] }),
5537
+ /* @__PURE__ */ jsx(
5538
+ Textarea,
5539
+ {
5540
+ label: "Payload (JSON)",
5541
+ placeholder: '{"key": "value"}',
5542
+ value: JSON.stringify(item.payload, null, 2),
5543
+ onChange: (e) => {
5544
+ try {
5545
+ const payload = JSON.parse(e.currentTarget.value);
5546
+ handleItemChange(index, { payload });
5547
+ } catch {
5548
+ }
5549
+ },
5550
+ minRows: 2,
5551
+ disabled
5552
+ }
5553
+ )
5554
+ ] }) }, index))
5555
+ ] });
5556
+ }
5557
+ var defaultRecurringConfig = {
5558
+ type: "recurring",
5559
+ interval: "daily",
5560
+ time: "09:00",
5561
+ timezone: "UTC",
5562
+ payload: {}
5563
+ };
5564
+ var defaultRelativeConfig = {
5565
+ type: "relative",
5566
+ items: []
5567
+ };
5568
+ var defaultAbsoluteConfig = {
5569
+ type: "absolute",
5570
+ items: []
5571
+ };
5572
+ function CreateScheduleModal({ opened, onClose }) {
5573
+ const [name, setName] = useState("");
5574
+ const [description, setDescription] = useState("");
5575
+ const [resourceId, setResourceId] = useState("");
5576
+ const [scheduleType, setScheduleType] = useState("recurring");
5577
+ const [recurringConfig, setRecurringConfig] = useState(defaultRecurringConfig);
5578
+ const [relativeConfig, setRelativeConfig] = useState(defaultRelativeConfig);
5579
+ const [absoluteConfig, setAbsoluteConfig] = useState(defaultAbsoluteConfig);
5580
+ const { data: resourcesData } = useResources();
5581
+ const createSchedule = useCreateSchedule();
5582
+ const allResources = useMemo(() => {
5583
+ if (!resourcesData) return [];
5584
+ const workflows = (resourcesData.workflows || []).map((w) => ({
5585
+ id: w.resourceId,
5586
+ type: "workflow"
5587
+ }));
5588
+ const agents = (resourcesData.agents || []).map((a) => ({
5589
+ id: a.resourceId,
5590
+ type: "agent"
5591
+ }));
5592
+ return [...workflows, ...agents];
5593
+ }, [resourcesData]);
5594
+ const resourceOptions2 = useMemo(() => {
5595
+ if (!resourcesData) return [];
5596
+ const workflowOptions = (resourcesData.workflows || []).filter((w) => w?.resourceId).map((w) => ({
5597
+ value: w.resourceId,
5598
+ label: `Workflow: ${w.resourceId}`
5599
+ }));
5600
+ const agentOptions = (resourcesData.agents || []).filter((a) => a?.resourceId).map((a) => ({
5601
+ value: a.resourceId,
5602
+ label: `Agent: ${a.resourceId}`
5603
+ }));
5604
+ return [...workflowOptions, ...agentOptions];
5605
+ }, [resourcesData]);
5606
+ const handleScheduleTypeChange = (newType) => {
5607
+ setScheduleType(newType);
5608
+ };
5609
+ const buildScheduleConfig = () => {
5610
+ switch (scheduleType) {
5611
+ case "recurring": {
5612
+ if (!recurringConfig.timezone) {
5613
+ showErrorNotification("Timezone is required");
5614
+ return null;
5615
+ }
5616
+ const config = {
5617
+ type: "recurring",
5618
+ timezone: recurringConfig.timezone,
5619
+ payload: recurringConfig.payload || {},
5620
+ endAt: recurringConfig.endAt
5621
+ };
5622
+ if (recurringConfig.cron) {
5623
+ config.cron = recurringConfig.cron;
5624
+ } else {
5625
+ config.interval = recurringConfig.interval || "daily";
5626
+ config.time = recurringConfig.time || "09:00";
5627
+ }
5628
+ return config;
5629
+ }
5630
+ case "relative": {
5631
+ if (!relativeConfig.anchorAt) {
5632
+ showErrorNotification("Anchor date is required for relative schedules");
5633
+ return null;
5634
+ }
5635
+ if (!relativeConfig.items || relativeConfig.items.length === 0) {
5636
+ showErrorNotification("At least one schedule item is required");
5637
+ return null;
5638
+ }
5639
+ return {
5640
+ type: "relative",
5641
+ anchorAt: relativeConfig.anchorAt,
5642
+ anchorLabel: relativeConfig.anchorLabel,
5643
+ items: relativeConfig.items
5644
+ };
5645
+ }
5646
+ case "absolute": {
5647
+ if (!absoluteConfig.items || absoluteConfig.items.length === 0) {
5648
+ showErrorNotification("At least one scheduled execution is required");
5649
+ return null;
5650
+ }
5651
+ return {
5652
+ type: "absolute",
5653
+ items: absoluteConfig.items
5654
+ };
5655
+ }
5656
+ default:
5657
+ return null;
5658
+ }
5659
+ };
5660
+ const handleSubmit = async (e) => {
5661
+ e.preventDefault();
5662
+ try {
5663
+ const resource = allResources.find((r) => r.id === resourceId);
5664
+ if (!resource) {
5665
+ showErrorNotification("Please select a valid resource");
5666
+ return;
5667
+ }
5668
+ if (!name.trim()) {
5669
+ showErrorNotification("Schedule name is required");
5670
+ return;
5671
+ }
5672
+ const scheduleConfig = buildScheduleConfig();
5673
+ if (!scheduleConfig) {
5674
+ return;
5675
+ }
5676
+ const input = {
5677
+ name: name.trim(),
5678
+ description: description.trim() || void 0,
5679
+ target: {
5680
+ resourceType: resource.type,
5681
+ resourceId: resource.id
5682
+ },
5683
+ scheduleConfig,
5684
+ maxRetries: 3,
5685
+ originResourceType: "api",
5686
+ originResourceId: "task-scheduler-ui"
5687
+ };
5688
+ await createSchedule.mutateAsync(input);
5689
+ showSuccessNotification("Schedule created successfully");
5690
+ handleClose();
5691
+ } catch (error) {
5692
+ showApiErrorNotification(error);
5693
+ }
5694
+ };
5695
+ const handleClose = () => {
5696
+ if (!createSchedule.isPending) {
5697
+ setName("");
5698
+ setDescription("");
5699
+ setResourceId("");
5700
+ setScheduleType("recurring");
5701
+ setRecurringConfig(defaultRecurringConfig);
5702
+ setRelativeConfig(defaultRelativeConfig);
5703
+ setAbsoluteConfig(defaultAbsoluteConfig);
5704
+ onClose();
5705
+ }
5706
+ };
5707
+ return /* @__PURE__ */ jsx(CustomModal, { opened, onClose: handleClose, size: "lg", loading: createSchedule.isPending, children: /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5708
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "Create Schedule" }),
5709
+ /* @__PURE__ */ jsx(
5710
+ TextInput,
5711
+ {
5712
+ label: "Schedule Name",
5713
+ placeholder: "e.g., Daily Sales Report, Weekly Sync",
5714
+ value: name,
5715
+ onChange: (e) => setName(e.currentTarget.value),
5716
+ required: true,
5717
+ disabled: createSchedule.isPending
5718
+ }
5719
+ ),
5720
+ /* @__PURE__ */ jsx(
5721
+ Textarea,
5722
+ {
5723
+ label: "Description (Optional)",
5724
+ placeholder: "Describe what this schedule does...",
5725
+ value: description,
5726
+ onChange: (e) => setDescription(e.currentTarget.value),
5727
+ disabled: createSchedule.isPending
5728
+ }
5729
+ ),
5730
+ /* @__PURE__ */ jsx(
5731
+ Select,
5732
+ {
5733
+ label: "Resource to Execute",
5734
+ placeholder: resourcesData ? "Select an agent or workflow" : "Loading resources...",
5735
+ data: resourceOptions2,
5736
+ value: resourceId,
5737
+ onChange: (value) => setResourceId(value || ""),
5738
+ searchable: true,
5739
+ required: true,
5740
+ disabled: !resourcesData || createSchedule.isPending
5741
+ }
5742
+ ),
5743
+ /* @__PURE__ */ jsx(Divider, {}),
5744
+ /* @__PURE__ */ jsx(
5745
+ ScheduleTypeSelector,
5746
+ {
5747
+ value: scheduleType,
5748
+ onChange: handleScheduleTypeChange,
5749
+ disabled: createSchedule.isPending
5750
+ }
5751
+ ),
5752
+ /* @__PURE__ */ jsx(Divider, {}),
5753
+ scheduleType === "recurring" && /* @__PURE__ */ jsx(
5754
+ RecurringScheduleForm,
5755
+ {
5756
+ value: recurringConfig,
5757
+ onChange: setRecurringConfig,
5758
+ disabled: createSchedule.isPending
5759
+ }
5760
+ ),
5761
+ scheduleType === "relative" && /* @__PURE__ */ jsx(
5762
+ RelativeScheduleForm,
5763
+ {
5764
+ value: relativeConfig,
5765
+ onChange: setRelativeConfig,
5766
+ disabled: createSchedule.isPending
5767
+ }
5768
+ ),
5769
+ scheduleType === "absolute" && /* @__PURE__ */ jsx(
5770
+ AbsoluteScheduleForm,
5771
+ {
5772
+ value: absoluteConfig,
5773
+ onChange: setAbsoluteConfig,
5774
+ disabled: createSchedule.isPending
5775
+ }
5776
+ ),
5777
+ /* @__PURE__ */ jsxs(Group, { justify: "flex-end", mt: "md", children: [
5778
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, type: "button", disabled: createSchedule.isPending, children: "Cancel" }),
5779
+ /* @__PURE__ */ jsx(Button, { type: "submit", loading: createSchedule.isPending, children: "Create Schedule" })
5780
+ ] })
5781
+ ] }) }) });
5782
+ }
5783
+ function DeleteScheduleModal({ opened, onClose, onConfirm, schedule, isDeleting }) {
5784
+ const handleClose = () => {
5785
+ if (!isDeleting) {
5786
+ onClose();
5787
+ }
5788
+ };
5789
+ return /* @__PURE__ */ jsx(CustomModal, { opened, onClose: handleClose, size: "sm", loading: isDeleting, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5790
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
5791
+ /* @__PURE__ */ jsx(IconAlertTriangle, { size: 24, color: "var(--color-error)" }),
5792
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "Delete Schedule" })
5793
+ ] }),
5794
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
5795
+ "Are you sure you want to delete",
5796
+ " ",
5797
+ /* @__PURE__ */ jsx(Text, { span: true, fw: 600, children: schedule?.name }),
5798
+ "?"
5799
+ ] }),
5800
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "This action cannot be undone. Any pending executions will be cancelled." }),
5801
+ /* @__PURE__ */ jsxs(Group, { justify: "flex-end", mt: "md", children: [
5802
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: handleClose, disabled: isDeleting, children: "Cancel" }),
5803
+ /* @__PURE__ */ jsx(Button, { color: "red", onClick: onConfirm, loading: isDeleting, children: "Delete" })
5804
+ ] })
5805
+ ] }) });
5806
+ }
5807
+ function getStatusColor(status) {
5808
+ switch (status) {
5809
+ case "active":
5810
+ return "green";
5811
+ case "paused":
5812
+ return "yellow";
5813
+ case "completed":
5814
+ return "blue";
5815
+ case "cancelled":
5816
+ return "gray";
5817
+ }
5818
+ }
5819
+ function formatDate(date) {
5820
+ if (!date) return "N/A";
5821
+ const d = typeof date === "string" ? new Date(date) : date;
5822
+ return d.toLocaleString("en-US", {
5823
+ month: "short",
5824
+ day: "numeric",
5825
+ year: "numeric",
5826
+ hour: "numeric",
5827
+ minute: "2-digit",
5828
+ timeZoneName: "short"
5829
+ });
5830
+ }
5831
+ function ScheduleConfigDetails({ schedule }) {
5832
+ const config = schedule.scheduleConfig;
5833
+ switch (config.type) {
5834
+ case "recurring":
5835
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5836
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5837
+ /* @__PURE__ */ jsx(IconCalendarRepeat, { size: 16, color: "var(--color-text-subtle)" }),
5838
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: "Recurring Schedule" })
5839
+ ] }),
5840
+ /* @__PURE__ */ jsx(Table, { withRowBorders: false, verticalSpacing: 4, children: /* @__PURE__ */ jsxs(Table.Tbody, { children: [
5841
+ config.cron && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5842
+ /* @__PURE__ */ jsx(Table.Td, { w: 120, children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Cron" }) }),
5843
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Code, { children: config.cron }) })
5844
+ ] }),
5845
+ config.interval && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5846
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Interval" }) }),
5847
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Text, { children: [
5848
+ config.interval,
5849
+ " at ",
5850
+ config.time
5851
+ ] }) })
5852
+ ] }),
5853
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5854
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Timezone" }) }),
5855
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { children: config.timezone }) })
5856
+ ] }),
5857
+ config.endAt && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5858
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Ends" }) }),
5859
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { children: formatDate(config.endAt) }) })
5860
+ ] }),
5861
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5862
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Overdue" }) }),
5863
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: config.overduePolicy === "execute" ? "orange" : "gray", children: config.overduePolicy ?? "skip" }) })
5864
+ ] }),
5865
+ Object.keys(config.payload).length > 0 && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5866
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Payload" }) }),
5867
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Code, { block: true, children: JSON.stringify(config.payload, null, 2) }) })
5868
+ ] })
5869
+ ] }) })
5870
+ ] });
5871
+ case "relative":
5872
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5873
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5874
+ /* @__PURE__ */ jsx(IconCalendarEvent, { size: 16, color: "var(--color-text-subtle)" }),
5875
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: "Relative Schedule" })
5876
+ ] }),
5877
+ /* @__PURE__ */ jsx(Table, { withRowBorders: false, verticalSpacing: 4, children: /* @__PURE__ */ jsxs(Table.Tbody, { children: [
5878
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5879
+ /* @__PURE__ */ jsx(Table.Td, { w: 120, children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Anchor" }) }),
5880
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Text, { children: [
5881
+ formatDate(config.anchorAt),
5882
+ config.anchorLabel && ` (${config.anchorLabel})`
5883
+ ] }) })
5884
+ ] }),
5885
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5886
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Steps" }) }),
5887
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Stack, { gap: 4, children: config.items.map((item, i) => /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5888
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: i === schedule.currentStep ? "blue" : "gray", children: item.offset }),
5889
+ item.label && /* @__PURE__ */ jsx(Text, { c: "dimmed", children: item.label })
5890
+ ] }, i)) }) })
5891
+ ] })
5892
+ ] }) })
5893
+ ] });
5894
+ case "absolute":
5895
+ return /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5896
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5897
+ /* @__PURE__ */ jsx(IconCalendarTime, { size: 16, color: "var(--color-text-subtle)" }),
5898
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: "Absolute Schedule" })
5899
+ ] }),
5900
+ /* @__PURE__ */ jsx(Stack, { gap: 4, children: config.items.map((item, i) => /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5901
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: i === schedule.currentStep ? "blue" : "gray", children: i + 1 }),
5902
+ /* @__PURE__ */ jsx(Text, { children: formatDate(item.runAt) }),
5903
+ item.label && /* @__PURE__ */ jsxs(Text, { c: "dimmed", children: [
5904
+ "\u2014 ",
5905
+ item.label
5906
+ ] })
5907
+ ] }, i)) })
5908
+ ] });
5909
+ }
5910
+ }
5911
+ function ScheduleDetailModal({ opened, onClose, schedule, resourceStatus }) {
5912
+ const ResourceIcon = schedule?.target.resourceType === "agent" ? IconRobot : IconGitBranch;
5913
+ const resourceNotFound = resourceStatus === void 0;
5914
+ return /* @__PURE__ */ jsx(CustomModal, { opened, onClose, size: "lg", children: schedule && /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5915
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
5916
+ /* @__PURE__ */ jsxs(Group, { gap: "sm", children: [
5917
+ /* @__PURE__ */ jsx(ResourceIcon, { size: 24, color: "var(--color-primary)" }),
5918
+ /* @__PURE__ */ jsxs("div", { children: [
5919
+ /* @__PURE__ */ jsx(Title, { order: 4, style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: schedule.name }),
5920
+ schedule.description && /* @__PURE__ */ jsx(Text, { c: "dimmed", mt: 2, children: schedule.description })
5921
+ ] })
5922
+ ] }),
5923
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: getStatusColor(schedule.status), children: schedule.status })
5924
+ ] }),
5925
+ resourceNotFound && /* @__PURE__ */ jsxs(Alert, { icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 18 }), color: "red", variant: "light", title: "Resource not found", children: [
5926
+ "The target resource ",
5927
+ /* @__PURE__ */ jsx(Code, { children: schedule.target.resourceId }),
5928
+ " does not exist in the current deployment. This schedule will fail when it tries to execute. Consider deleting or updating it."
5929
+ ] }),
5930
+ /* @__PURE__ */ jsx(Divider, {}),
5931
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
5932
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5933
+ /* @__PURE__ */ jsx(ResourceIcon, { size: 14, color: "var(--color-text-subtle)" }),
5934
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Target" })
5935
+ ] }),
5936
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5937
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", radius: "sm", children: schedule.target.resourceType }),
5938
+ /* @__PURE__ */ jsx(Code, { children: schedule.target.resourceId })
5939
+ ] })
5940
+ ] }),
5941
+ /* @__PURE__ */ jsx(Divider, {}),
5942
+ /* @__PURE__ */ jsx(ScheduleConfigDetails, { schedule }),
5943
+ /* @__PURE__ */ jsx(Divider, {}),
5944
+ /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
5945
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5946
+ /* @__PURE__ */ jsx(IconSettings, { size: 16, color: "var(--color-text-subtle)" }),
5947
+ /* @__PURE__ */ jsx(Text, { fw: 500, children: "Execution Details" })
5948
+ ] }),
5949
+ /* @__PURE__ */ jsx(Table, { withRowBorders: false, verticalSpacing: 4, children: /* @__PURE__ */ jsxs(Table.Tbody, { children: [
5950
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5951
+ /* @__PURE__ */ jsx(Table.Td, { w: 140, children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
5952
+ /* @__PURE__ */ jsx(IconClock, { size: 12, color: "var(--color-text-subtle)" }),
5953
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Next Run" })
5954
+ ] }) }),
5955
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { children: formatDate(schedule.nextRunAt) }) })
5956
+ ] }),
5957
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5958
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
5959
+ /* @__PURE__ */ jsx(IconCalendar, { size: 12, color: "var(--color-text-subtle)" }),
5960
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Last Run" })
5961
+ ] }) }),
5962
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { children: formatDate(schedule.lastRunAt) }) })
5963
+ ] }),
5964
+ /* @__PURE__ */ jsxs(Table.Tr, { children: [
5965
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
5966
+ /* @__PURE__ */ jsx(IconRefresh, { size: 12, color: "var(--color-text-subtle)" }),
5967
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Max Retries" })
5968
+ ] }) }),
5969
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { children: schedule.maxRetries }) })
5970
+ ] }),
5971
+ schedule.idempotencyKey && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5972
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
5973
+ /* @__PURE__ */ jsx(IconKey, { size: 12, color: "var(--color-text-subtle)" }),
5974
+ /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Idempotency" })
5975
+ ] }) }),
5976
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Code, { children: schedule.idempotencyKey }) })
5977
+ ] }),
5978
+ schedule.lastExecutionId && /* @__PURE__ */ jsxs(Table.Tr, { children: [
5979
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Text, { c: "dimmed", children: "Last Execution" }) }),
5980
+ /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Code, { children: schedule.lastExecutionId }) })
5981
+ ] })
5982
+ ] }) })
5983
+ ] }),
5984
+ /* @__PURE__ */ jsx(Divider, {}),
5985
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
5986
+ /* @__PURE__ */ jsxs(Group, { gap: "lg", children: [
5987
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
5988
+ "Created ",
5989
+ formatDate(schedule.createdAt)
5990
+ ] }),
5991
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
5992
+ "Updated ",
5993
+ formatDate(schedule.updatedAt)
5994
+ ] })
5995
+ ] }),
5996
+ /* @__PURE__ */ jsx(
5997
+ Button,
5998
+ {
5999
+ variant: "light",
6000
+ size: "xs",
6001
+ rightSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
6002
+ component: "a",
6003
+ href: schedule.target.resourceType === "agent" ? `/operations/resources/agent/${schedule.target.resourceId}` : `/operations/resources/workflow/${schedule.target.resourceId}`,
6004
+ target: "_blank",
6005
+ disabled: resourceNotFound,
6006
+ children: "Go to Resource"
6007
+ }
6008
+ )
6009
+ ] })
6010
+ ] }) });
6011
+ }
6012
+ function getScheduleTypeIcon(config) {
6013
+ switch (config.type) {
6014
+ case "recurring":
6015
+ return IconCalendarRepeat;
6016
+ case "relative":
6017
+ return IconCalendarEvent;
6018
+ case "absolute":
6019
+ return IconCalendarTime;
6020
+ }
6021
+ }
6022
+ function getScheduleTypeLabel(config) {
6023
+ switch (config.type) {
6024
+ case "recurring":
6025
+ if (config.cron) return `Cron: ${config.cron}`;
6026
+ if (config.interval)
6027
+ return `${config.interval.charAt(0).toUpperCase() + config.interval.slice(1)} at ${config.time}`;
6028
+ return "Recurring";
6029
+ case "relative":
6030
+ return `${config.items.length} steps from anchor`;
6031
+ case "absolute":
6032
+ return `${config.items.length} scheduled runs`;
6033
+ }
6034
+ }
6035
+ function getStatusColor2(status) {
6036
+ switch (status) {
6037
+ case "active":
6038
+ return "green";
6039
+ case "paused":
6040
+ return "yellow";
6041
+ case "completed":
6042
+ return "blue";
6043
+ case "cancelled":
6044
+ return "gray";
6045
+ }
6046
+ }
6047
+ function formatNextRun(date) {
6048
+ if (!date) return "";
6049
+ const now = /* @__PURE__ */ new Date();
6050
+ const diffMs = date.getTime() - now.getTime();
6051
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
6052
+ const diffHours = Math.floor(diffMs % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60));
6053
+ if (diffMs < 0) return "Overdue";
6054
+ if (diffDays === 0) {
6055
+ if (diffHours === 0) return "Less than an hour";
6056
+ return `In ${diffHours}h`;
6057
+ }
6058
+ if (diffDays === 1) return "Tomorrow";
6059
+ if (diffDays <= 7) return `In ${diffDays}d`;
6060
+ return date.toLocaleDateString("en-US", {
6061
+ month: "short",
6062
+ day: "numeric"
6063
+ });
6064
+ }
6065
+ function ScheduleCard({
6066
+ schedule,
6067
+ resourceStatus,
6068
+ onPause,
6069
+ onResume,
6070
+ onCancel,
6071
+ onDelete,
6072
+ onClick,
6073
+ isLoading
6074
+ }) {
6075
+ const [hovered, setHovered] = useState(false);
6076
+ const TypeIcon = getScheduleTypeIcon(schedule.scheduleConfig);
6077
+ const ResourceIcon = schedule.target.resourceType === "agent" ? IconRobot : IconGitBranch;
6078
+ const nextRunAt = schedule.nextRunAt ? typeof schedule.nextRunAt === "string" ? new Date(schedule.nextRunAt) : schedule.nextRunAt : void 0;
6079
+ const nextRunLabel = nextRunAt && schedule.status === "active" ? formatNextRun(nextRunAt) : "";
6080
+ return /* @__PURE__ */ jsx(
6081
+ Card,
6082
+ {
6083
+ style: {
6084
+ cursor: "pointer",
6085
+ border: "1px solid var(--color-border)",
6086
+ transition: "background 150ms ease",
6087
+ background: hovered ? "var(--active-background)" : "var(--glass-background)"
6088
+ },
6089
+ onClick: (e) => {
6090
+ if (e.target.closest("[data-menu-dropdown]") || e.target.closest("button")) {
6091
+ return;
6092
+ }
6093
+ onClick?.(schedule);
6094
+ },
6095
+ onMouseEnter: () => setHovered(true),
6096
+ onMouseLeave: () => setHovered(false),
6097
+ children: /* @__PURE__ */ jsxs(
6098
+ "div",
6099
+ {
6100
+ style: {
6101
+ display: "grid",
6102
+ gridTemplateColumns: "18px minmax(120px, 1.5fr) minmax(100px, 1fr) minmax(80px, 1fr) 270px",
6103
+ alignItems: "center",
6104
+ gap: "var(--mantine-spacing-sm)"
6105
+ },
6106
+ children: [
6107
+ /* @__PURE__ */ jsx(ResourceIcon, { size: 18, color: "var(--color-primary)" }),
6108
+ /* @__PURE__ */ jsx(Text, { fw: 600, size: "md", truncate: true, style: { fontFamily: "var(--elevasis-font-family-subtitle)" }, children: schedule.name }),
6109
+ /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", children: [
6110
+ /* @__PURE__ */ jsx(TypeIcon, { size: 14, color: "var(--color-text-subtle)", style: { flexShrink: 0 } }),
6111
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", truncate: true, children: getScheduleTypeLabel(schedule.scheduleConfig) })
6112
+ ] }),
6113
+ /* @__PURE__ */ jsxs(Group, { gap: 6, wrap: "nowrap", style: { minWidth: 0 }, children: [
6114
+ /* @__PURE__ */ jsx(Tooltip, { label: resourceStatus ? `Deployed: ${resourceStatus}` : "Resource not found", children: /* @__PURE__ */ jsx(
6115
+ "div",
6116
+ {
6117
+ style: {
6118
+ width: 8,
6119
+ height: 8,
6120
+ borderRadius: "50%",
6121
+ flexShrink: 0,
6122
+ backgroundColor: resourceStatus ? resourceStatus === "prod" ? "var(--color-success)" : "var(--color-primary)" : "var(--mantine-color-red-6)"
6123
+ }
6124
+ }
6125
+ ) }),
6126
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", truncate: true, ff: "monospace", style: { minWidth: 0 }, children: schedule.target.resourceId })
6127
+ ] }),
6128
+ /* @__PURE__ */ jsxs(Group, { gap: 8, wrap: "nowrap", justify: "flex-end", children: [
6129
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", children: schedule.target.resourceType }),
6130
+ nextRunLabel && /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
6131
+ /* @__PURE__ */ jsx(IconClock, { size: 12, color: "var(--color-text-subtle)" }),
6132
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", style: { whiteSpace: "nowrap" }, children: nextRunLabel })
6133
+ ] }),
6134
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor2(schedule.status), children: schedule.status }),
6135
+ /* @__PURE__ */ jsxs(Menu, { position: "bottom-end", withinPortal: true, children: [
6136
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", disabled: isLoading, children: /* @__PURE__ */ jsx(IconDotsVertical, { size: 16 }) }) }),
6137
+ /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
6138
+ schedule.status === "active" && /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconPlayerPause, { size: 14 }), onClick: () => onPause(schedule.id), children: "Pause" }),
6139
+ schedule.status === "paused" && /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }), onClick: () => onResume(schedule.id), children: "Resume" }),
6140
+ (schedule.status === "active" || schedule.status === "paused") && /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconPlayerStop, { size: 14 }), onClick: () => onCancel(schedule.id), children: "Cancel" }),
6141
+ /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconTrash, { size: 14 }), color: "red", onClick: () => onDelete(schedule.id), children: "Delete" })
6142
+ ] })
6143
+ ] })
6144
+ ] })
6145
+ ]
6146
+ }
6147
+ )
6148
+ }
6149
+ );
6150
+ }
6151
+ var TaskScheduler = () => {
6152
+ const { isReady } = useElevasisServices();
6153
+ const [isModalOpen, setIsModalOpen] = useState(false);
6154
+ const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
6155
+ const [scheduleToDelete, setScheduleToDelete] = useState(null);
6156
+ const [selectedSchedule, setSelectedSchedule] = useState(null);
6157
+ const [viewMode, setViewMode] = useState("buckets");
6158
+ const [statusFilter, setStatusFilter] = useState("all");
6159
+ const [typeFilter, setTypeFilter] = useState("all");
6160
+ const queryFilters = useMemo(() => {
6161
+ const filters = {};
6162
+ if (statusFilter !== "all") {
6163
+ filters.status = statusFilter;
6164
+ }
6165
+ return filters;
6166
+ }, [statusFilter]);
6167
+ const { data, isLoading, error } = useListSchedules(queryFilters);
6168
+ const pauseSchedule = usePauseSchedule();
6169
+ const resumeSchedule = useResumeSchedule();
6170
+ const cancelSchedule = useCancelSchedule();
6171
+ const deleteSchedule = useDeleteSchedule();
6172
+ const filteredSchedules = useMemo(() => {
6173
+ if (!data?.schedules) return [];
6174
+ if (typeFilter === "all") return data.schedules;
6175
+ return data.schedules.filter((s) => s.scheduleConfig.type === typeFilter);
6176
+ }, [data?.schedules, typeFilter]);
6177
+ const isActionLoading = pauseSchedule.isPending || resumeSchedule.isPending || cancelSchedule.isPending || deleteSchedule.isPending;
6178
+ const schedulesByType = useMemo(() => {
6179
+ if (!data?.schedules) return { recurring: 0, relative: 0, absolute: 0 };
6180
+ return data.schedules.reduce(
6181
+ (acc, s) => {
6182
+ acc[s.scheduleConfig.type]++;
6183
+ return acc;
6184
+ },
6185
+ { recurring: 0, relative: 0, absolute: 0 }
6186
+ );
6187
+ }, [data?.schedules]);
6188
+ const schedulesByStatus = useMemo(() => {
6189
+ if (!data?.schedules) return { active: 0, paused: 0, completed: 0, cancelled: 0 };
6190
+ return data.schedules.reduce(
6191
+ (acc, s) => {
6192
+ if (s.status === "active") acc.active++;
6193
+ else if (s.status === "paused") acc.paused++;
6194
+ else if (s.status === "completed") acc.completed++;
6195
+ else if (s.status === "cancelled") acc.cancelled++;
6196
+ return acc;
6197
+ },
6198
+ { active: 0, paused: 0, completed: 0, cancelled: 0 }
6199
+ );
6200
+ }, [data?.schedules]);
6201
+ const { data: resourcesData } = useResources();
6202
+ const resourceStatusMap = useMemo(() => {
6203
+ const map = /* @__PURE__ */ new Map();
6204
+ if (!resourcesData) return map;
6205
+ for (const w of resourcesData.workflows) map.set(w.resourceId, w.status);
6206
+ for (const a of resourcesData.agents) map.set(a.resourceId, a.status);
6207
+ return map;
6208
+ }, [resourcesData]);
6209
+ const handleCardClick = useCallback((schedule) => {
6210
+ setSelectedSchedule(schedule);
6211
+ }, []);
6212
+ if (isLoading || !isReady) {
6213
+ return /* @__PURE__ */ jsx(AppShellLoader, {});
6214
+ }
6215
+ const handlePause = async (scheduleId) => {
6216
+ await pauseSchedule.mutateAsync(scheduleId);
6217
+ };
6218
+ const handleResume = async (scheduleId) => {
6219
+ await resumeSchedule.mutateAsync(scheduleId);
6220
+ };
6221
+ const handleCancel = async (scheduleId) => {
6222
+ await cancelSchedule.mutateAsync(scheduleId);
6223
+ };
6224
+ const handleDelete = (scheduleId) => {
6225
+ const schedule = data?.schedules.find((s) => s.id === scheduleId);
6226
+ if (schedule) {
6227
+ setScheduleToDelete(schedule);
6228
+ setIsDeleteModalOpen(true);
6229
+ }
6230
+ };
6231
+ const handleConfirmDelete = async () => {
6232
+ if (scheduleToDelete) {
6233
+ await deleteSchedule.mutateAsync(scheduleToDelete.id);
6234
+ setIsDeleteModalOpen(false);
6235
+ setScheduleToDelete(null);
6236
+ }
6237
+ };
6238
+ const handleCloseDeleteModal = () => {
6239
+ setIsDeleteModalOpen(false);
6240
+ setScheduleToDelete(null);
6241
+ };
6242
+ const formatNextRun2 = (schedule) => {
6243
+ if (!schedule.nextRunAt) return "Not scheduled";
6244
+ const date = typeof schedule.nextRunAt === "string" ? new Date(schedule.nextRunAt) : schedule.nextRunAt;
6245
+ const now = /* @__PURE__ */ new Date();
6246
+ const diffMs = date.getTime() - now.getTime();
6247
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
6248
+ if (diffMs < 0) return "Overdue";
6249
+ if (diffDays === 0) {
6250
+ return `Today at ${date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}`;
6251
+ } else if (diffDays === 1) {
6252
+ return `Tomorrow at ${date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}`;
6253
+ } else if (diffDays > 0 && diffDays <= 7) {
6254
+ return `In ${diffDays} days at ${date.toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit" })}`;
6255
+ } else {
6256
+ return date.toLocaleString("en-US", {
6257
+ month: "short",
6258
+ day: "numeric",
6259
+ hour: "numeric",
6260
+ minute: "2-digit"
6261
+ });
6262
+ }
6263
+ };
6264
+ const groupByTimeBucket = (schedules) => {
6265
+ const now = /* @__PURE__ */ new Date();
6266
+ const buckets = {
6267
+ today: [],
6268
+ tomorrow: [],
6269
+ thisWeek: [],
6270
+ later: [],
6271
+ noNextRun: []
6272
+ };
6273
+ schedules.forEach((schedule) => {
6274
+ if (!schedule.nextRunAt) {
6275
+ buckets.noNextRun.push(schedule);
6276
+ return;
6277
+ }
6278
+ const nextRun = typeof schedule.nextRunAt === "string" ? new Date(schedule.nextRunAt) : schedule.nextRunAt;
6279
+ const diffMs = nextRun.getTime() - now.getTime();
6280
+ const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
6281
+ if (diffDays < 0) {
6282
+ buckets.today.push(schedule);
6283
+ } else if (diffDays === 0) {
6284
+ buckets.today.push(schedule);
6285
+ } else if (diffDays === 1) {
6286
+ buckets.tomorrow.push(schedule);
6287
+ } else if (diffDays <= 7) {
6288
+ buckets.thisWeek.push(schedule);
6289
+ } else {
6290
+ buckets.later.push(schedule);
6291
+ }
6292
+ });
6293
+ return buckets;
6294
+ };
6295
+ if (error) {
6296
+ return /* @__PURE__ */ jsx(APIErrorAlert, { error, title: "Failed to load schedules" });
6297
+ }
6298
+ const timeBuckets = groupByTimeBucket(filteredSchedules);
6299
+ const renderScheduleCards = (schedules) => schedules.map((schedule) => /* @__PURE__ */ jsx(
6300
+ ScheduleCard,
6301
+ {
6302
+ schedule,
6303
+ resourceStatus: resourceStatusMap.get(schedule.target.resourceId),
6304
+ onPause: handlePause,
6305
+ onResume: handleResume,
6306
+ onCancel: handleCancel,
6307
+ onDelete: handleDelete,
6308
+ onClick: handleCardClick,
6309
+ isLoading: isActionLoading
6310
+ },
6311
+ schedule.id
6312
+ ));
6313
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6314
+ /* @__PURE__ */ jsx(
6315
+ PageTitleCaption,
6316
+ {
6317
+ title: "Task Scheduler",
6318
+ caption: "Schedule agents and workflows to run automatically",
6319
+ rightSection: /* @__PURE__ */ jsx(
6320
+ SegmentedControl,
6321
+ {
6322
+ value: viewMode,
6323
+ onChange: (value) => setViewMode(value),
6324
+ data: [
6325
+ { label: "Buckets", value: "buckets" },
6326
+ { label: "Timeline", value: "timeline" }
6327
+ ]
6328
+ }
6329
+ )
6330
+ }
6331
+ ),
6332
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 2, sm: 5 }, children: [
6333
+ /* @__PURE__ */ jsx(StatCard, { variant: "hero", label: "Active", value: schedulesByStatus.active, icon: IconCalendarEvent }),
6334
+ /* @__PURE__ */ jsx(StatCard, { variant: "hero", label: "Paused", value: schedulesByStatus.paused, icon: IconCalendarDue }),
6335
+ /* @__PURE__ */ jsx(StatCard, { variant: "hero", label: "Completed", value: schedulesByStatus.completed, icon: IconCalendarStats }),
6336
+ /* @__PURE__ */ jsx(StatCard, { variant: "hero", label: "Cancelled", value: schedulesByStatus.cancelled, icon: IconCalendarOff }),
6337
+ /* @__PURE__ */ jsx(StatCard, { variant: "hero", label: "Total", value: data?.schedules.length || 0, icon: IconListCheck })
6338
+ ] }),
6339
+ /* @__PURE__ */ jsxs(
6340
+ FilterBar,
6341
+ {
6342
+ actions: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
6343
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", leftSection: /* @__PURE__ */ jsx(IconCalendarRepeat, { size: 12 }), children: [
6344
+ schedulesByType.recurring,
6345
+ " Recurring"
6346
+ ] }),
6347
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", leftSection: /* @__PURE__ */ jsx(IconCalendarEvent, { size: 12 }), children: [
6348
+ schedulesByType.relative,
6349
+ " Relative"
6350
+ ] }),
6351
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", leftSection: /* @__PURE__ */ jsx(IconCalendarTime, { size: 12 }), children: [
6352
+ schedulesByType.absolute,
6353
+ " Absolute"
6354
+ ] })
6355
+ ] }),
6356
+ children: [
6357
+ /* @__PURE__ */ jsx(
6358
+ Select,
6359
+ {
6360
+ size: "sm",
6361
+ placeholder: "Status",
6362
+ data: [
6363
+ { value: "all", label: "All Statuses" },
6364
+ { value: "active", label: "Active" },
6365
+ { value: "paused", label: "Paused" },
6366
+ { value: "completed", label: "Completed" },
6367
+ { value: "cancelled", label: "Cancelled" }
6368
+ ],
6369
+ value: statusFilter,
6370
+ onChange: (v) => setStatusFilter(v || "all"),
6371
+ clearable: false,
6372
+ style: { minWidth: 150 }
6373
+ }
6374
+ ),
6375
+ /* @__PURE__ */ jsx(
6376
+ Select,
6377
+ {
6378
+ size: "sm",
6379
+ placeholder: "Type",
6380
+ data: [
6381
+ { value: "all", label: "All Types" },
6382
+ { value: "recurring", label: "Recurring" },
6383
+ { value: "relative", label: "Relative" },
6384
+ { value: "absolute", label: "Absolute" }
6385
+ ],
6386
+ value: typeFilter,
6387
+ onChange: (v) => setTypeFilter(v || "all"),
6388
+ clearable: false,
6389
+ style: { minWidth: 150 }
6390
+ }
6391
+ )
6392
+ ]
6393
+ }
6394
+ ),
6395
+ viewMode === "timeline" && filteredSchedules.length > 0 && /* @__PURE__ */ jsx(Paper, { children: /* @__PURE__ */ jsxs(Stack, { children: [
6396
+ /* @__PURE__ */ jsx(CardHeader, { title: "All Schedules" }),
6397
+ /* @__PURE__ */ jsx(Timeline, { bulletSize: 24, lineWidth: 2, children: [...filteredSchedules].sort((a, b) => {
6398
+ const aDate = a.nextRunAt ? typeof a.nextRunAt === "string" ? new Date(a.nextRunAt) : a.nextRunAt : new Date(9999, 0);
6399
+ const bDate = b.nextRunAt ? typeof b.nextRunAt === "string" ? new Date(b.nextRunAt) : b.nextRunAt : new Date(9999, 0);
6400
+ return aDate.getTime() - bDate.getTime();
6401
+ }).map((schedule) => {
6402
+ const nextRun = schedule.nextRunAt ? typeof schedule.nextRunAt === "string" ? new Date(schedule.nextRunAt) : schedule.nextRunAt : null;
6403
+ const isOverdue = nextRun && nextRun.getTime() < Date.now();
6404
+ return /* @__PURE__ */ jsxs(
6405
+ Timeline.Item,
6406
+ {
6407
+ style: { cursor: "pointer" },
6408
+ onClick: () => handleCardClick(schedule),
6409
+ bullet: /* @__PURE__ */ jsx(ThemeIcon, { size: 24, radius: "xl", children: /* @__PURE__ */ jsx(IconClock, { size: 12 }) }),
6410
+ title: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", children: [
6411
+ /* @__PURE__ */ jsx(Text, { fw: 600, style: { fontFamily: "var(--mantine-font-family-headings)" }, children: schedule.name }),
6412
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
6413
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: isOverdue ? "orange" : void 0, children: formatNextRun2(schedule) }),
6414
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: schedule.status === "active" ? "green" : "yellow", children: schedule.status })
6415
+ ] })
6416
+ ] }),
6417
+ children: [
6418
+ schedule.description && /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", mt: 4, children: schedule.description }),
6419
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", mt: "xs", children: [
6420
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", children: schedule.target.resourceType }),
6421
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "outline", children: schedule.scheduleConfig.type })
6422
+ ] })
6423
+ ]
6424
+ },
6425
+ schedule.id
6426
+ );
6427
+ }) })
6428
+ ] }) }),
6429
+ viewMode === "buckets" && /* @__PURE__ */ jsxs(Fragment, { children: [
6430
+ timeBuckets.today.length > 0 && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
6431
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6432
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "Today" }),
6433
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", children: timeBuckets.today.length })
6434
+ ] }),
6435
+ renderScheduleCards(timeBuckets.today)
6436
+ ] }),
6437
+ timeBuckets.tomorrow.length > 0 && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
6438
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6439
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "Tomorrow" }),
6440
+ /* @__PURE__ */ jsx(Badge, { color: "orange", size: "sm", variant: "light", children: timeBuckets.tomorrow.length })
6441
+ ] }),
6442
+ renderScheduleCards(timeBuckets.tomorrow)
6443
+ ] }),
6444
+ timeBuckets.thisWeek.length > 0 && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
6445
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6446
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "This Week" }),
6447
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", children: timeBuckets.thisWeek.length })
6448
+ ] }),
6449
+ renderScheduleCards(timeBuckets.thisWeek)
6450
+ ] }),
6451
+ timeBuckets.later.length > 0 && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
6452
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6453
+ /* @__PURE__ */ jsx(Title, { order: 4, children: "Later" }),
6454
+ /* @__PURE__ */ jsx(Badge, { color: "gray", size: "sm", variant: "light", children: timeBuckets.later.length })
6455
+ ] }),
6456
+ renderScheduleCards(timeBuckets.later)
6457
+ ] }),
6458
+ timeBuckets.noNextRun.length > 0 && /* @__PURE__ */ jsxs(Stack, { gap: "xs", children: [
6459
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6460
+ /* @__PURE__ */ jsx(Text, { fw: 600, size: "md", c: "dimmed", children: "No Scheduled Run" }),
6461
+ /* @__PURE__ */ jsx(Badge, { color: "gray", size: "sm", variant: "light", children: timeBuckets.noNextRun.length })
6462
+ ] }),
6463
+ renderScheduleCards(timeBuckets.noNextRun)
6464
+ ] })
6465
+ ] }),
6466
+ filteredSchedules.length === 0 && /* @__PURE__ */ jsx(
6467
+ EmptyState,
6468
+ {
6469
+ icon: IconClock,
6470
+ title: "No schedules found",
6471
+ description: statusFilter !== "all" || typeFilter !== "all" ? "No schedules match your filters. Try adjusting the filters or create a new schedule." : "No schedules yet. Use the CLI to create automated task execution."
6472
+ }
6473
+ ),
6474
+ /* @__PURE__ */ jsx(CreateScheduleModal, { opened: isModalOpen, onClose: () => setIsModalOpen(false) }),
6475
+ /* @__PURE__ */ jsx(
6476
+ DeleteScheduleModal,
6477
+ {
6478
+ opened: isDeleteModalOpen,
6479
+ onClose: handleCloseDeleteModal,
6480
+ onConfirm: handleConfirmDelete,
6481
+ schedule: scheduleToDelete,
6482
+ isDeleting: deleteSchedule.isPending
6483
+ }
6484
+ ),
6485
+ /* @__PURE__ */ jsx(
6486
+ ScheduleDetailModal,
6487
+ {
6488
+ opened: !!selectedSchedule,
6489
+ onClose: () => setSelectedSchedule(null),
6490
+ schedule: selectedSchedule,
6491
+ resourceStatus: selectedSchedule ? resourceStatusMap.get(selectedSchedule.target.resourceId) : void 0
6492
+ }
6493
+ )
6494
+ ] });
6495
+ };
6496
+ function getPriorityColor(priority) {
6497
+ if (priority >= 8) return "red";
6498
+ if (priority >= 5) return "yellow";
6499
+ return "gray";
6500
+ }
6501
+ function getPriorityLabel(priority) {
6502
+ if (priority >= 8) return "Critical";
6503
+ if (priority >= 5) return "High";
6504
+ if (priority >= 3) return "Medium";
6505
+ return "Low";
6506
+ }
6507
+ function getStatusColor3(status) {
6508
+ switch (status) {
6509
+ case "pending":
6510
+ return "blue";
6511
+ case "processing":
6512
+ return "blue";
6513
+ case "completed":
6514
+ return "green";
6515
+ case "failed":
6516
+ return "red";
6517
+ case "expired":
6518
+ return "orange";
6519
+ default:
6520
+ return "gray";
6521
+ }
6522
+ }
6523
+ function getPriorityDotColor(priority) {
6524
+ if (priority >= 8) return "var(--mantine-color-red-6)";
6525
+ if (priority >= 5) return "var(--mantine-color-yellow-6)";
6526
+ if (priority >= 3) return "var(--mantine-color-blue-6)";
6527
+ return "var(--color-text-subtle)";
6528
+ }
6529
+ function formatRelativeTime(date) {
6530
+ const now = /* @__PURE__ */ new Date();
6531
+ const diffMs = now.getTime() - date.getTime();
6532
+ const diffMins = Math.floor(diffMs / 6e4);
6533
+ const diffHours = Math.floor(diffMins / 60);
6534
+ const diffDays = Math.floor(diffHours / 24);
6535
+ if (diffMins < 60) return `${diffMins}m ago`;
6536
+ if (diffHours < 24) return `${diffHours}h ago`;
6537
+ return `${diffDays}d ago`;
6538
+ }
6539
+ function CommandQueueTaskRow({ task, onClick, onDelete }) {
6540
+ const [hovered, setHovered] = useState(false);
6541
+ const OriginIcon = task.originResourceType === "agent" ? IconRobot : IconGitBranch;
6542
+ return /* @__PURE__ */ jsx(
6543
+ Card,
6544
+ {
6545
+ padding: 0,
6546
+ style: {
6547
+ cursor: "pointer",
6548
+ border: "1px solid var(--color-border)",
6549
+ transition: "background var(--duration-fast) var(--easing)",
6550
+ background: hovered ? "var(--active-background)" : "var(--glass-background)"
6551
+ },
6552
+ onClick: (e) => {
6553
+ if (e.target.closest("[data-menu-dropdown]") || e.target.closest("button")) {
6554
+ return;
6555
+ }
6556
+ onClick();
6557
+ },
6558
+ onMouseEnter: () => setHovered(true),
6559
+ onMouseLeave: () => setHovered(false),
6560
+ children: /* @__PURE__ */ jsxs(
6561
+ "div",
6562
+ {
6563
+ style: {
6564
+ display: "grid",
6565
+ gridTemplateColumns: "10px 80px 1fr 1fr 90px 90px 32px",
6566
+ alignItems: "center",
6567
+ gap: "var(--mantine-spacing-sm)"
6568
+ },
6569
+ children: [
6570
+ /* @__PURE__ */ jsx(Tooltip, { label: `P${task.priority} \u2014 ${getPriorityLabel(task.priority)}`, children: /* @__PURE__ */ jsx(
6571
+ "div",
6572
+ {
6573
+ style: {
6574
+ width: 10,
6575
+ height: 10,
6576
+ borderRadius: "50%",
6577
+ flexShrink: 0,
6578
+ backgroundColor: getPriorityDotColor(task.priority)
6579
+ }
6580
+ }
6581
+ ) }),
6582
+ /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, c: getPriorityColor(task.priority), children: getPriorityLabel(task.priority).toUpperCase() }),
6583
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, truncate: true, title: task.description || "Task approval required", children: task.description || "Task approval required" }),
6584
+ /* @__PURE__ */ jsxs(Group, { gap: 5, wrap: "nowrap", style: { minWidth: 0 }, children: [
6585
+ /* @__PURE__ */ jsx(OriginIcon, { size: 13, color: "var(--color-text-subtle)", style: { flexShrink: 0 } }),
6586
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, ff: "monospace", style: { minWidth: 0 }, children: task.originResourceId })
6587
+ ] }),
6588
+ /* @__PURE__ */ jsx(Badge, { size: "sm", variant: "light", color: getStatusColor3(task.status), radius: "sm", children: task.status.charAt(0).toUpperCase() + task.status.slice(1) }),
6589
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
6590
+ /* @__PURE__ */ jsx(IconClock, { size: 11, color: "var(--color-text-subtle)", style: { flexShrink: 0 } }),
6591
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", style: { whiteSpace: "nowrap" }, children: formatRelativeTime(task.createdAt) })
6592
+ ] }),
6593
+ /* @__PURE__ */ jsxs(Menu, { position: "bottom-end", withinPortal: true, children: [
6594
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { variant: "subtle", size: "sm", color: "gray", children: /* @__PURE__ */ jsx(IconDotsVertical, { size: 16 }) }) }),
6595
+ /* @__PURE__ */ jsx(Menu.Dropdown, { children: /* @__PURE__ */ jsx(Menu.Item, { leftSection: /* @__PURE__ */ jsx(IconTrash, { size: 14 }), color: "red", onClick: () => onDelete(task.id), children: "Delete" }) })
6596
+ ] })
6597
+ ]
6598
+ }
6599
+ )
6600
+ }
6601
+ );
6602
+ }
6603
+ function CheckpointGroup({ name, count, isActive, onClick }) {
6604
+ const theme = useMantineTheme();
6605
+ const activeColor = theme.colors[theme.primaryColor][6];
6606
+ const defaultTextColor = "var(--color-text)";
6607
+ const textColor = isActive ? activeColor : defaultTextColor;
6608
+ const fontWeight = isActive ? 600 : 500;
6609
+ const activeBg = `color-mix(in srgb, ${activeColor} 10%, transparent)`;
6610
+ return /* @__PURE__ */ jsx(
6611
+ UnstyledButton,
6612
+ {
6613
+ onClick,
6614
+ style: {
6615
+ display: "flex",
6616
+ alignItems: "center",
6617
+ width: "100%",
6618
+ padding: theme.spacing.xs,
6619
+ borderRadius: theme.radius.sm,
6620
+ backgroundColor: isActive ? activeBg : "transparent",
6621
+ transition: `all var(--duration-fast) var(--easing)`,
6622
+ cursor: "pointer"
6623
+ },
6624
+ onMouseEnter: (e) => {
6625
+ if (!isActive) {
6626
+ e.currentTarget.style.backgroundColor = "var(--color-surface-hover)";
6627
+ }
6628
+ },
6629
+ onMouseLeave: (e) => {
6630
+ if (!isActive) {
6631
+ e.currentTarget.style.backgroundColor = "transparent";
6632
+ }
6633
+ },
6634
+ children: /* @__PURE__ */ jsxs(Group, { justify: "space-between", wrap: "nowrap", style: { width: "100%" }, children: [
6635
+ /* @__PURE__ */ jsx(
6636
+ Text,
6637
+ {
6638
+ size: "sm",
6639
+ fw: fontWeight,
6640
+ style: {
6641
+ color: textColor,
6642
+ fontFamily: "var(--elevasis-font-family-subtitle)",
6643
+ transition: `color var(--duration-fast) var(--easing)`
6644
+ },
6645
+ children: name
6646
+ }
6647
+ ),
6648
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: count })
6649
+ ] })
6650
+ }
6651
+ );
6652
+ }
6653
+ var CommandQueueSidebarTop = ({
6654
+ status,
6655
+ onStatusChange,
6656
+ priorityRange,
6657
+ onPriorityRangeChange
6658
+ }) => {
6659
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6660
+ /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconFilter, label: "Filters" }),
6661
+ /* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", children: [
6662
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Status" }),
6663
+ /* @__PURE__ */ jsx(
6664
+ Select,
6665
+ {
6666
+ size: "sm",
6667
+ value: status,
6668
+ onChange: (value) => value && onStatusChange(value),
6669
+ data: [
6670
+ { value: "all", label: "All" },
6671
+ { value: "pending", label: "Pending" },
6672
+ { value: "completed", label: "Completed" },
6673
+ { value: "expired", label: "Expired" }
6674
+ ],
6675
+ leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 14 })
6676
+ }
6677
+ ),
6678
+ /* @__PURE__ */ jsx(Group, { justify: "space-between", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Priority" }) }),
6679
+ /* @__PURE__ */ jsx(
6680
+ RangeSlider,
6681
+ {
6682
+ size: "sm",
6683
+ min: 1,
6684
+ max: 10,
6685
+ step: 1,
6686
+ minRange: 0,
6687
+ defaultValue: priorityRange,
6688
+ onChangeEnd: onPriorityRangeChange,
6689
+ marks: [
6690
+ { value: 1, label: "1" },
6691
+ { value: 5, label: "5" },
6692
+ { value: 10, label: "10" }
6693
+ ],
6694
+ styles: { markLabel: { fontSize: 10 } }
6695
+ },
6696
+ `${priorityRange[0]}-${priorityRange[1]}`
6697
+ ),
6698
+ /* @__PURE__ */ jsx(Space, { h: 8 })
6699
+ ] })
6700
+ ] });
6701
+ };
6702
+ function CommandQueueSidebarMiddle({
6703
+ selectedCheckpoint,
6704
+ onSelectCheckpoint,
6705
+ priorityRange,
6706
+ status,
6707
+ timeRange
6708
+ }) {
6709
+ const { data, isLoading } = useCommandQueueTotals({
6710
+ timeRange,
6711
+ priorityMin: priorityRange[0],
6712
+ priorityMax: priorityRange[1],
6713
+ status: status === "all" ? void 0 : status
6714
+ });
6715
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
6716
+ /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconCategory, label: "Checkpoint Groups", withTopBorder: true }),
6717
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", p: "sm", style: { flex: 1, overflowY: "auto" }, children: isLoading ? /* @__PURE__ */ jsx(Center, { p: "xl", children: /* @__PURE__ */ jsx(Loader, {}) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
6718
+ /* @__PURE__ */ jsx(
6719
+ CheckpointGroup,
6720
+ {
6721
+ id: void 0,
6722
+ name: "All Tasks",
6723
+ count: data?.total ?? 0,
6724
+ isActive: selectedCheckpoint === void 0,
6725
+ onClick: () => onSelectCheckpoint(void 0)
6726
+ }
6727
+ ),
6728
+ data?.checkpoints.map((checkpoint) => /* @__PURE__ */ jsx(
6729
+ CheckpointGroup,
6730
+ {
6731
+ id: checkpoint.id,
6732
+ name: checkpoint.name,
6733
+ count: checkpoint.count,
6734
+ isActive: selectedCheckpoint === checkpoint.id,
6735
+ onClick: () => onSelectCheckpoint(checkpoint.id)
6736
+ },
6737
+ checkpoint.id
6738
+ ))
6739
+ ] }) })
6740
+ ] });
6741
+ }
6742
+ var CommandQueueSidebar = ({
6743
+ selectedCheckpoint,
6744
+ onSelectCheckpoint,
6745
+ status,
6746
+ onStatusChange,
6747
+ priorityRange,
6748
+ onPriorityRangeChange,
6749
+ timeRange
6750
+ }) => {
6751
+ const colors = useCyberColors();
6752
+ const statusFilter = status === "all" ? void 0 : status;
6753
+ const { data: checkpointData, isLoading: isDonutLoading } = useCommandQueueTotals({
6754
+ timeRange,
6755
+ priorityMin: priorityRange[0],
6756
+ priorityMax: priorityRange[1],
6757
+ status: statusFilter
6758
+ });
6759
+ const {
6760
+ pending: pendingCount,
6761
+ completed: completedCount,
6762
+ expired: expiredCount
6763
+ } = checkpointData?.statusCounts ?? { pending: 0, completed: 0, expired: 0 };
6764
+ const {
6765
+ critical: criticalCount,
6766
+ high: highCount,
6767
+ medium: mediumCount,
6768
+ low: lowCount
6769
+ } = checkpointData?.priorityCounts ?? { critical: 0, high: 0, medium: 0, low: 0 };
6770
+ const totalTasks = checkpointData?.total ?? 0;
6771
+ const statusSegments = [
6772
+ { name: "Pending", value: pendingCount, color: colors.cyan },
6773
+ { name: "Completed", value: completedCount, color: colors.green },
6774
+ { name: "Expired", value: expiredCount, color: colors.red }
6775
+ ];
6776
+ const prioritySegments = [
6777
+ { name: "Critical", value: criticalCount, color: colors.red },
6778
+ { name: "High", value: highCount, color: colors.yellow },
6779
+ { name: "Medium", value: mediumCount, color: colors.blue },
6780
+ { name: "Low", value: lowCount, color: colors.cyanDim }
6781
+ ];
6782
+ return /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { height: "100%", display: "flex", flexDirection: "column" }, children: [
6783
+ /* @__PURE__ */ jsx(Box, { p: "sm", style: { borderBottom: "1px solid var(--color-border)" }, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
6784
+ status === "all" && /* @__PURE__ */ jsx(
6785
+ CyberDonut,
6786
+ {
6787
+ title: "Status",
6788
+ segments: statusSegments,
6789
+ centerValue: totalTasks,
6790
+ centerLabel: "total",
6791
+ glowId: "sbStatusGlow",
6792
+ colors,
6793
+ isLoading: isDonutLoading
6794
+ }
6795
+ ),
6796
+ /* @__PURE__ */ jsx(
6797
+ CyberDonut,
6798
+ {
6799
+ title: "Priority",
6800
+ segments: prioritySegments,
6801
+ centerValue: criticalCount + highCount + mediumCount + lowCount,
6802
+ centerLabel: status === "all" ? "total" : status,
6803
+ glowId: "sbPrioGlow",
6804
+ colors,
6805
+ isLoading: isDonutLoading
6806
+ }
6807
+ )
6808
+ ] }) }),
6809
+ /* @__PURE__ */ jsx(
6810
+ CommandQueueSidebarTop,
6811
+ {
6812
+ status,
6813
+ onStatusChange,
6814
+ priorityRange,
6815
+ onPriorityRangeChange
6816
+ }
6817
+ ),
6818
+ /* @__PURE__ */ jsx(
6819
+ CommandQueueSidebarMiddle,
6820
+ {
6821
+ selectedCheckpoint,
6822
+ onSelectCheckpoint,
6823
+ priorityRange,
6824
+ status,
6825
+ timeRange
6826
+ }
6827
+ )
6828
+ ] });
6829
+ };
6830
+ function ContextUsageBadge({ currentTokens, maxTokens }) {
6831
+ const percentage = currentTokens / maxTokens * 100;
6832
+ const color = percentage > 90 ? "red" : percentage > 70 ? "yellow" : "green";
6833
+ return /* @__PURE__ */ jsx(
6834
+ Tooltip,
6835
+ {
6836
+ label: `${currentTokens.toLocaleString()} of ${maxTokens.toLocaleString()} tokens used (${percentage.toFixed(1)}%)`,
6837
+ position: "bottom",
6838
+ children: /* @__PURE__ */ jsxs(Group, { gap: 6, style: { cursor: "help" }, children: [
6839
+ /* @__PURE__ */ jsx(IconBrain, { size: 16, color: `var(--mantine-color-${color}-6)` }),
6840
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: color, fw: 500, children: [
6841
+ currentTokens.toLocaleString(),
6842
+ " / ",
6843
+ maxTokens.toLocaleString()
6844
+ ] }),
6845
+ /* @__PURE__ */ jsx(Progress, { value: percentage, color, size: "sm", w: 80, radius: "xl" })
6846
+ ] })
6847
+ }
6848
+ );
6849
+ }
6850
+ function parseMemoryContent(memory) {
6851
+ const parsedSessionMemory = {};
6852
+ for (const [key, entry] of Object.entries(memory.sessionMemory || {})) {
6853
+ try {
6854
+ if (typeof entry.content === "string") {
6855
+ parsedSessionMemory[key] = {
6856
+ ...entry,
6857
+ content: JSON.parse(entry.content)
6858
+ };
6859
+ } else {
6860
+ parsedSessionMemory[key] = entry;
6861
+ }
6862
+ } catch {
6863
+ parsedSessionMemory[key] = entry;
6864
+ }
6865
+ }
6866
+ const parsedHistory = (memory.history || []).map((entry) => {
6867
+ try {
6868
+ if (typeof entry.content === "string") {
6869
+ return {
6870
+ ...entry,
6871
+ content: JSON.parse(entry.content)
6872
+ };
6873
+ }
6874
+ return entry;
6875
+ } catch {
6876
+ return entry;
6877
+ }
6878
+ });
6879
+ return {
6880
+ sessionMemory: parsedSessionMemory,
6881
+ history: parsedHistory
6882
+ };
6883
+ }
6884
+ function SessionMemory({ memory }) {
6885
+ if (!memory) {
6886
+ return /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
6887
+ /* @__PURE__ */ jsx(IconDatabase, { size: 18 }),
6888
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No memory data available" })
6889
+ ] });
6890
+ }
6891
+ const sessionMemoryKeys = Object.keys(memory.sessionMemory || {});
6892
+ const historyCount = memory.history?.length || 0;
6893
+ const parsedMemory = parseMemoryContent(memory);
6894
+ return /* @__PURE__ */ jsxs(Stack, { children: [
6895
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6896
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
6897
+ /* @__PURE__ */ jsx(IconDatabase, { size: 20 }),
6898
+ /* @__PURE__ */ jsx(Text, { fw: 600, size: "sm", style: { fontFamily: "var(--mantine-font-family-headings)" }, children: "Session Memory" })
6899
+ ] }),
6900
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
6901
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", children: [
6902
+ sessionMemoryKeys.length,
6903
+ " keys"
6904
+ ] }),
6905
+ /* @__PURE__ */ jsxs(Badge, { size: "sm", variant: "light", children: [
6906
+ historyCount,
6907
+ " history items"
6908
+ ] })
6909
+ ] })
6910
+ ] }),
6911
+ /* @__PURE__ */ jsxs(Stack, { children: [
6912
+ /* @__PURE__ */ jsx(
6913
+ CollapsibleSection,
6914
+ {
6915
+ title: "Session Memory",
6916
+ count: sessionMemoryKeys.length,
6917
+ countLabel: "keys",
6918
+ emptyMessage: "No session memory stored",
6919
+ defaultExpanded: false,
6920
+ children: /* @__PURE__ */ jsx(JsonViewer, { data: parsedMemory.sessionMemory, maxHeight: 300 })
6921
+ }
6922
+ ),
6923
+ /* @__PURE__ */ jsx(
6924
+ CollapsibleSection,
6925
+ {
6926
+ title: "Conversation History",
6927
+ count: historyCount,
6928
+ countLabel: "items",
6929
+ emptyMessage: "No history available",
6930
+ defaultExpanded: false,
6931
+ children: /* @__PURE__ */ jsx(JsonViewer, { data: parsedMemory.history, maxHeight: 300 })
6932
+ }
6933
+ )
6934
+ ] })
6935
+ ] });
6936
+ }
6937
+ var triggerTypeIcons = {
6938
+ webhook: IconWebhook,
6939
+ schedule: IconClock,
6940
+ manual: IconHandClick,
6941
+ event: IconBolt
6942
+ };
6943
+ var connectionStatusIcons = {
6944
+ connected: IconCircleCheck,
6945
+ disconnected: IconCircleX,
6946
+ error: IconAlertCircle
6947
+ };
6948
+ var statBubbleBase = {
6949
+ minWidth: 20,
6950
+ height: 20,
6951
+ borderRadius: 10,
6952
+ display: "flex",
6953
+ alignItems: "center",
6954
+ justifyContent: "center",
6955
+ fontSize: 11,
6956
+ fontWeight: 600,
6957
+ padding: "0 6px",
6958
+ color: "white",
6959
+ boxShadow: "0 2px 4px rgba(0,0,0,0.2)"
6960
+ };
6961
+ var CommandViewNode = memo(function CommandViewNode2({ data, selected }) {
6962
+ const Icon = getResourceIcon(data.type);
6963
+ const color = getResourceColor(data.type);
6964
+ const successCount = (data.type === "agent" || data.type === "workflow") && data.stats ? data.stats.successCount : 0;
6965
+ const failureCount = (data.type === "agent" || data.type === "workflow") && data.stats ? data.stats.failureCount : 0;
6966
+ const warningCount = (data.type === "agent" || data.type === "workflow") && data.stats ? data.stats.warningCount : 0;
6967
+ const pendingCount = data.type === "human" && data.stats ? data.stats.pendingCount : 0;
6968
+ const showBubbles = successCount > 0 || failureCount > 0 || warningCount > 0 || pendingCount > 0;
6969
+ return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
6970
+ showBubbles && /* @__PURE__ */ jsxs(
6971
+ "div",
6972
+ {
6973
+ style: {
6974
+ position: "absolute",
6975
+ top: -8,
6976
+ right: -8,
6977
+ display: "flex",
6978
+ gap: 4,
6979
+ zIndex: 10
6980
+ },
6981
+ children: [
6982
+ successCount > 0 && /* @__PURE__ */ jsx(
6983
+ "div",
6984
+ {
6985
+ style: {
6986
+ ...statBubbleBase,
6987
+ background: "linear-gradient(135deg, var(--mantine-color-green-5), var(--mantine-color-green-7))"
6988
+ },
6989
+ children: successCount
6990
+ }
6991
+ ),
6992
+ warningCount > 0 && /* @__PURE__ */ jsx(
6993
+ "div",
6994
+ {
6995
+ style: {
6996
+ ...statBubbleBase,
6997
+ background: "linear-gradient(135deg, var(--mantine-color-yellow-5), var(--mantine-color-yellow-7))"
6998
+ },
6999
+ children: warningCount
7000
+ }
7001
+ ),
7002
+ failureCount > 0 && /* @__PURE__ */ jsx(
7003
+ "div",
7004
+ {
7005
+ style: {
7006
+ ...statBubbleBase,
7007
+ background: "linear-gradient(135deg, var(--mantine-color-red-5), var(--mantine-color-red-7))"
7008
+ },
7009
+ children: failureCount
7010
+ }
7011
+ ),
7012
+ pendingCount > 0 && /* @__PURE__ */ jsx(
7013
+ "div",
7014
+ {
7015
+ style: {
7016
+ ...statBubbleBase,
7017
+ background: "linear-gradient(135deg, var(--mantine-color-orange-5), var(--mantine-color-orange-7))"
7018
+ },
7019
+ children: pendingCount
7020
+ }
7021
+ )
7022
+ ]
7023
+ }
7024
+ ),
7025
+ /* @__PURE__ */ jsx(BaseNode, { color, selected, highlighted: Boolean(data.highlighted), children: /* @__PURE__ */ jsxs(Stack, { gap: 8, children: [
7026
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
7027
+ /* @__PURE__ */ jsx(
7028
+ ThemeIcon,
7029
+ {
7030
+ size: "md",
7031
+ variant: "gradient",
7032
+ gradient: { from: `${color}.4`, to: `${color}.6`, deg: 135 },
7033
+ className: Graph_module_css_default.nodeIcon,
7034
+ children: /* @__PURE__ */ jsx(Icon, { size: 16 })
7035
+ }
7036
+ ),
7037
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, truncate: true, style: { flex: 1, fontFamily: "var(--elevasis-font-family-subtitle)" }, children: data.name })
7038
+ ] }),
7039
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: data.description }),
7040
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "wrap", children: [
7041
+ /* @__PURE__ */ jsx(
7042
+ Badge,
7043
+ {
7044
+ size: "xs",
7045
+ variant: "gradient",
7046
+ gradient: data.status === "prod" ? { from: "green.5", to: "green.7", deg: 135 } : { from: "blue.5", to: "blue.7", deg: 135 },
7047
+ className: data.status === "prod" ? Graph_module_css_default.badgeProd : "",
7048
+ style: {
7049
+ textTransform: "uppercase",
7050
+ letterSpacing: "0.5px"
7051
+ },
7052
+ children: data.status
7053
+ }
7054
+ ),
7055
+ data.type === "agent" && /* @__PURE__ */ jsxs(Fragment, { children: [
7056
+ /* @__PURE__ */ jsxs(
7057
+ Badge,
7058
+ {
7059
+ size: "xs",
7060
+ variant: "outline",
7061
+ color: "gray",
7062
+ className: Graph_module_css_default.badge,
7063
+ style: { backdropFilter: "blur(4px)" },
7064
+ children: [
7065
+ data.toolCount,
7066
+ " tools"
7067
+ ]
7068
+ }
7069
+ ),
7070
+ data.hasKnowledgeMap && /* @__PURE__ */ jsx(
7071
+ Badge,
7072
+ {
7073
+ size: "xs",
7074
+ variant: "gradient",
7075
+ gradient: { from: "grape.5", to: "grape.7", deg: 135 },
7076
+ leftSection: /* @__PURE__ */ jsx(IconBrain, { size: 10 }),
7077
+ className: Graph_module_css_default.badge,
7078
+ children: "KM"
7079
+ }
7080
+ ),
7081
+ data.hasMemory && /* @__PURE__ */ jsx(
7082
+ Badge,
7083
+ {
7084
+ size: "xs",
7085
+ variant: "gradient",
7086
+ gradient: { from: "cyan.5", to: "cyan.7", deg: 135 },
7087
+ leftSection: /* @__PURE__ */ jsx(IconDatabase, { size: 10 }),
7088
+ className: Graph_module_css_default.badge,
7089
+ children: "Mem"
7090
+ }
7091
+ ),
7092
+ data.sessionCapable && /* @__PURE__ */ jsx(
7093
+ Badge,
7094
+ {
7095
+ size: "xs",
7096
+ variant: "gradient",
7097
+ gradient: { from: "blue.5", to: "blue.7", deg: 135 },
7098
+ leftSection: /* @__PURE__ */ jsx(IconMessage, { size: 10 }),
7099
+ className: Graph_module_css_default.badge,
7100
+ children: "Session"
7101
+ }
7102
+ )
7103
+ ] }),
7104
+ data.type === "workflow" && /* @__PURE__ */ jsxs(
7105
+ Badge,
7106
+ {
7107
+ size: "xs",
7108
+ variant: "outline",
7109
+ color: "gray",
7110
+ className: Graph_module_css_default.badge,
7111
+ style: { backdropFilter: "blur(4px)" },
7112
+ children: [
7113
+ data.stepCount,
7114
+ " steps"
7115
+ ]
7116
+ }
7117
+ ),
7118
+ data.type === "integration" && /* @__PURE__ */ jsx(
7119
+ Badge,
7120
+ {
7121
+ size: "xs",
7122
+ variant: "gradient",
7123
+ gradient: data.connectionStatus === "connected" ? { from: "green.5", to: "green.7", deg: 135 } : data.connectionStatus === "error" ? { from: "red.5", to: "red.7", deg: 135 } : { from: "gray.5", to: "gray.7", deg: 135 },
7124
+ leftSection: (() => {
7125
+ const StatusIcon = connectionStatusIcons[data.connectionStatus];
7126
+ return /* @__PURE__ */ jsx(StatusIcon, { size: 10 });
7127
+ })(),
7128
+ className: Graph_module_css_default.badge,
7129
+ children: data.connectionStatus
7130
+ }
7131
+ ),
7132
+ data.type === "trigger" && /* @__PURE__ */ jsx(
7133
+ Badge,
7134
+ {
7135
+ size: "xs",
7136
+ variant: "outline",
7137
+ color: "gray",
7138
+ leftSection: (() => {
7139
+ const TriggerIcon = triggerTypeIcons[data.triggerType] || IconBolt;
7140
+ return /* @__PURE__ */ jsx(TriggerIcon, { size: 10 });
7141
+ })(),
7142
+ className: Graph_module_css_default.badge,
7143
+ style: { backdropFilter: "blur(4px)" },
7144
+ children: data.triggerType
7145
+ }
7146
+ ),
7147
+ data.type === "external" && /* @__PURE__ */ jsx(
7148
+ Badge,
7149
+ {
7150
+ size: "xs",
7151
+ variant: "outline",
7152
+ color: "gray",
7153
+ leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 10 }),
7154
+ className: Graph_module_css_default.badge,
7155
+ style: { backdropFilter: "blur(4px)" },
7156
+ children: data.platform
7157
+ }
7158
+ ),
7159
+ data.type === "human" && /* @__PURE__ */ jsx(
7160
+ Badge,
7161
+ {
7162
+ size: "xs",
7163
+ variant: "gradient",
7164
+ gradient: { from: "yellow.5", to: "orange.6", deg: 135 },
7165
+ leftSection: /* @__PURE__ */ jsx(IconHandClick, { size: 10 }),
7166
+ className: Graph_module_css_default.badge,
7167
+ children: "Approval Required"
7168
+ }
7169
+ )
7170
+ ] })
7171
+ ] }) })
7172
+ ] });
7173
+ });
7174
+ var relationshipColorMap = {
7175
+ triggers: { color: "edgeTriggers", glow: "edgeTriggersGlow" },
7176
+ uses: { color: "edgeUses", glow: "edgeUsesGlow" },
7177
+ approval: { color: "edgeApproval", glow: "edgeApprovalGlow" }
7178
+ };
7179
+ function getEdgeColors(relationship, colors) {
7180
+ const mapping = relationshipColorMap[relationship] ?? relationshipColorMap.approval;
7181
+ return {
7182
+ edgeColor: colors[mapping.color],
7183
+ glowColor: colors[mapping.glow]
7184
+ };
7185
+ }
7186
+ var CommandViewEdge = memo(function CommandViewEdge2({
7187
+ id,
7188
+ sourceX,
7189
+ sourceY,
7190
+ targetX,
7191
+ targetY,
7192
+ sourcePosition,
7193
+ targetPosition,
7194
+ data,
7195
+ selected
7196
+ }) {
7197
+ const colors = useGraphTheme();
7198
+ const relationship = data?.relationship || "uses";
7199
+ const { edgeColor, glowColor } = getEdgeColors(relationship, colors);
7200
+ return /* @__PURE__ */ jsx(
7201
+ BaseEdge,
7202
+ {
7203
+ id,
7204
+ sourceX,
7205
+ sourceY,
7206
+ targetX,
7207
+ targetY,
7208
+ sourcePosition,
7209
+ targetPosition,
7210
+ color: edgeColor,
7211
+ glowColor,
7212
+ label: data?.label || relationship,
7213
+ animated: data?.animated ?? false,
7214
+ selected,
7215
+ dimmed: data?.dimmed,
7216
+ edgeIndex: data?.edgeIndex,
7217
+ totalEdges: data?.totalEdges
7218
+ }
7219
+ );
7220
+ });
7221
+ var nodeTypes4 = {
7222
+ commandView: CommandViewNode
7223
+ };
7224
+ var edgeTypes4 = {
7225
+ commandView: CommandViewEdge
7226
+ };
7227
+ var CommandViewGraphInner = forwardRef(function CommandViewGraphInner2({ graph, height, selectedNodeId, onNodeSelect }, ref) {
7228
+ const { fitView } = useReactFlow();
7229
+ const { nodes: layoutNodes, edges: layoutEdges } = useCommandViewLayout(graph);
7230
+ const { nodes, edges, handleNodeMouseEnter, handleNodeMouseLeave } = useDirectedChainHighlighting(
7231
+ layoutNodes,
7232
+ layoutEdges,
7233
+ { selectedNodeId }
7234
+ );
7235
+ const { handleNodeClick, handlePaneClick } = useNodeSelection(selectedNodeId ?? null, onNodeSelect ?? (() => {
7236
+ }));
7237
+ const nodesWithSelection = useMemo(
7238
+ () => nodes.map((node) => ({
7239
+ ...node,
7240
+ selected: node.id === selectedNodeId
7241
+ })),
7242
+ [nodes, selectedNodeId]
7243
+ );
7244
+ useImperativeHandle(ref, () => ({
7245
+ fitView: () => fitView({ padding: 0.15, duration: 300 })
7246
+ }));
7247
+ return /* @__PURE__ */ jsx(
7248
+ Box,
7249
+ {
7250
+ className: Graph_module_css_default.graphContainer,
7251
+ style: {
7252
+ width: "100%",
7253
+ height,
7254
+ border: "1px solid var(--color-border)",
7255
+ borderRadius: "var(--mantine-radius-default)",
7256
+ overflow: "hidden"
7257
+ },
7258
+ children: /* @__PURE__ */ jsxs(
7259
+ ReactFlow,
7260
+ {
7261
+ nodes: nodesWithSelection,
7262
+ edges,
7263
+ nodeTypes: nodeTypes4,
7264
+ edgeTypes: edgeTypes4,
7265
+ onNodeMouseEnter: handleNodeMouseEnter,
7266
+ onNodeMouseLeave: handleNodeMouseLeave,
7267
+ onNodeClick: onNodeSelect ? handleNodeClick : void 0,
7268
+ onPaneClick: onNodeSelect ? handlePaneClick : void 0,
7269
+ fitView: true,
7270
+ fitViewOptions: { padding: 0.15 },
7271
+ proOptions: { hideAttribution: true },
7272
+ minZoom: GRAPH_CONSTANTS.MIN_ZOOM,
7273
+ maxZoom: GRAPH_CONSTANTS.MAX_ZOOM,
7274
+ nodesDraggable: false,
7275
+ nodesConnectable: false,
7276
+ elementsSelectable: !!onNodeSelect,
7277
+ selectNodesOnDrag: false,
7278
+ panOnDrag: true,
7279
+ zoomOnScroll: true,
7280
+ zoomOnPinch: true,
7281
+ panOnScroll: false,
7282
+ children: [
7283
+ /* @__PURE__ */ jsx(GraphBackground, {}),
7284
+ /* @__PURE__ */ jsx(
7285
+ GraphLegend,
7286
+ {
7287
+ title: "",
7288
+ position: "bottom-right",
7289
+ items: [
7290
+ { color: "orange", label: "Triggers" },
7291
+ { color: "violet", label: "Agents" },
7292
+ { color: "blue", label: "Workflows" },
7293
+ { color: "teal", label: "Integrations" },
7294
+ { color: "yellow", label: "Human" },
7295
+ { color: "gray", label: "External" }
7296
+ ]
7297
+ }
7298
+ ),
7299
+ /* @__PURE__ */ jsx(
7300
+ GraphLegend,
7301
+ {
7302
+ title: "",
7303
+ position: "bottom-left",
7304
+ items: [
7305
+ { color: "blue", label: "Triggers", type: "line" },
7306
+ { color: "teal", label: "Uses", type: "line" },
7307
+ { color: "yellow", label: "Requires Approval", type: "line" }
7308
+ ]
7309
+ }
7310
+ ),
7311
+ /* @__PURE__ */ jsx(GraphFitViewButton, { padding: 0.15, variant: "mantine", duration: 300 })
7312
+ ]
7313
+ }
7314
+ )
7315
+ }
7316
+ );
7317
+ });
7318
+ var CommandViewGraph = forwardRef(
7319
+ function CommandViewGraph2(props, ref) {
7320
+ return /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(CommandViewGraphInner, { ref, ...props }) });
7321
+ }
7322
+ );
7323
+
7324
+ export { AbsoluteScheduleForm, ActionModal, ActivityCard, ActivityFilters as ActivityFiltersBar, ActivityTable, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionTimeline, AgentExecutionVisualizer, AgentIterationEdge, AgentIterationNode, BaseEdge, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, BaseNode, BusinessImpactCard, CheckpointGroup, CollapsibleJsonSection, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewEdge, CommandViewGraph, CommandViewNode, ConfigCard, ConfirmationInputModal, ConfirmationModal, ContentSections, ContextUsageBadge, ContractDisplay, CostBreakdownCard, CostByModelTable, CostMetricsCard, CreateScheduleModal, CustomModal, DeleteScheduleModal, DocTreeNav, EmptyVisualizer, ErrorAnalysisCard, ErrorBreakdownTable, ExecutionBreakdownTable, ExecutionErrorSection, ExecutionHealthCard, ExecutionLogsFilters as ExecutionLogsFilterBar, ExecutionLogsTable, ExecutionStats, ExecutionStatusBadge, FilterBar, FormFieldRenderer, GraphBackground, GraphContainer, GraphFitViewButton, GraphFitViewHandler, GraphLegend, KnowledgeBasePage, LogEntry, LogGroup, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, NotificationBell, NotificationItem, NotificationList, NotificationPanel, RecurringScheduleForm, RelativeScheduleForm, ResourceDefinitionSection, ResourceDetailPage, ResourceErrorState, ResourceFilter, ResourceHeader, ResourceHealthChart, ResourceHealthPanel, ResourceNotFoundState, ScheduleCard, ScheduleDetailModal, ScheduleTypeSelector, SessionMemory, SortableHeader, TableSelectionToolbar, TaskCard, TaskScheduler, TimelineAxis, TimelineBar, TimelineContainer, TimelineRow, ToolsListDisplay, UnifiedWorkflowEdge, UnifiedWorkflowGraph, UnifiedWorkflowNode, VisualizerContainer, WorkflowDefinitionDisplay, WorkflowExecutionLogs, WorkflowExecutionTimeline, getExecutionStatusConfig, getGraphBackgroundStyles, getHealthColor, getIcon, getLogLevelConfig, iconMap, useGraphBackgroundStyles, useGraphTheme, useNewKnowledgeMapLayout };