@elevasis/ui 2.25.6 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +15 -5
  3. package/dist/app/index.d.ts +61 -14
  4. package/dist/app/index.js +6 -6
  5. package/dist/charts/index.js +6 -5
  6. package/dist/chunk-3MEXPLWT.js +265 -0
  7. package/dist/{chunk-BDKM56TP.js → chunk-4KTLOK7K.js} +1 -1
  8. package/dist/{chunk-KMAXFJPH.js → chunk-CW3UNAF2.js} +5 -409
  9. package/dist/{chunk-HKBEURCV.js → chunk-G26INIF3.js} +1 -1
  10. package/dist/{chunk-7F3IQMLI.js → chunk-G66QFZXD.js} +11 -214
  11. package/dist/{chunk-QIW6OCEI.js → chunk-HLFFKKT3.js} +27 -373
  12. package/dist/chunk-JDNEWB5F.js +10 -0
  13. package/dist/{chunk-L7D6KNHV.js → chunk-JKBGDFX2.js} +890 -749
  14. package/dist/{chunk-YRKQNPK2.js → chunk-JPGX3533.js} +4 -3
  15. package/dist/chunk-KCGGA36K.js +73 -0
  16. package/dist/chunk-KEFWANZY.js +155 -0
  17. package/dist/chunk-LH4GPYDX.js +448 -0
  18. package/dist/{chunk-JXSBOG2R.js → chunk-LWKZ3BCC.js} +5 -4
  19. package/dist/chunk-OGXKOMUT.js +412 -0
  20. package/dist/chunk-OHXU5WWK.js +3731 -0
  21. package/dist/chunk-ONFKASZI.js +2004 -0
  22. package/dist/{chunk-U36X6NZM.js → chunk-RIFTUOPE.js} +2 -14
  23. package/dist/{chunk-T6INEVX6.js → chunk-SGS4CQ2B.js} +1 -1
  24. package/dist/{chunk-C7IBFI5B.js → chunk-UPMX5GJI.js} +5 -5
  25. package/dist/{chunk-ARJPZ66V.js → chunk-UY5I2KOZ.js} +208 -3124
  26. package/dist/chunk-W2ZTLH7Y.js +662 -0
  27. package/dist/{chunk-KNISO652.js → chunk-WUVR4QY6.js} +9 -9
  28. package/dist/{chunk-Q5BEODAT.js → chunk-X2SUMO3P.js} +2 -1
  29. package/dist/{chunk-SNHGSCKH.js → chunk-XBMCDGHA.js} +1 -1
  30. package/dist/{chunk-N55DVMAG.js → chunk-XQQEKWTL.js} +2 -6
  31. package/dist/{chunk-SBQ4MYQV.js → chunk-XZSEPJZQ.js} +5 -6
  32. package/dist/{chunk-CPAJXBTL.js → chunk-YHBPR67D.js} +490 -676
  33. package/dist/{chunk-QARSVM7Q.js → chunk-YO2YORW4.js} +4 -4
  34. package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
  35. package/dist/components/index.css +15 -5
  36. package/dist/components/index.d.ts +202 -383
  37. package/dist/components/index.js +43 -429
  38. package/dist/components/navigation/index.css +25 -15
  39. package/dist/execution/index.d.ts +0 -73
  40. package/dist/features/auth/index.css +25 -15
  41. package/dist/features/crm/index.css +25 -15
  42. package/dist/features/crm/index.d.ts +49 -49
  43. package/dist/features/crm/index.js +14 -15
  44. package/dist/features/dashboard/index.css +25 -15
  45. package/dist/features/dashboard/index.js +18 -16
  46. package/dist/features/delivery/index.css +15 -5
  47. package/dist/features/delivery/index.js +14 -15
  48. package/dist/features/knowledge/index.css +611 -0
  49. package/dist/features/knowledge/index.js +375 -72
  50. package/dist/features/lead-gen/index.css +25 -15
  51. package/dist/features/lead-gen/index.d.ts +60 -21
  52. package/dist/features/lead-gen/index.js +16 -16
  53. package/dist/features/monitoring/index.css +15 -5
  54. package/dist/features/monitoring/index.js +17 -17
  55. package/dist/features/monitoring/requests/index.css +25 -15
  56. package/dist/features/monitoring/requests/index.js +13 -14
  57. package/dist/features/operations/index.css +25 -15
  58. package/dist/features/operations/index.d.ts +16 -98
  59. package/dist/features/operations/index.js +26 -22
  60. package/dist/features/settings/index.css +25 -15
  61. package/dist/features/settings/index.d.ts +1 -0
  62. package/dist/features/settings/index.js +15 -16
  63. package/dist/hooks/delivery/index.css +25 -15
  64. package/dist/hooks/delivery/index.js +2 -2
  65. package/dist/hooks/index.css +15 -5
  66. package/dist/hooks/index.d.ts +172 -380
  67. package/dist/hooks/index.js +13 -14
  68. package/dist/hooks/published.css +15 -5
  69. package/dist/hooks/published.d.ts +172 -380
  70. package/dist/hooks/published.js +13 -14
  71. package/dist/index.css +15 -5
  72. package/dist/index.d.ts +988 -403
  73. package/dist/index.js +15 -15
  74. package/dist/initialization/index.d.ts +1 -0
  75. package/dist/knowledge/index.d.ts +981 -41
  76. package/dist/knowledge/index.js +5449 -294
  77. package/dist/layout/index.d.ts +2 -0
  78. package/dist/layout/index.js +3 -2
  79. package/dist/organization/index.css +25 -15
  80. package/dist/organization/index.d.ts +1 -0
  81. package/dist/provider/index.css +25 -15
  82. package/dist/provider/index.d.ts +818 -26
  83. package/dist/provider/index.js +11 -11
  84. package/dist/provider/published.css +25 -15
  85. package/dist/provider/published.d.ts +817 -25
  86. package/dist/provider/published.js +8 -9
  87. package/dist/test-utils/index.js +2 -2
  88. package/dist/test-utils/setup.js +1 -1
  89. package/dist/theme/index.js +3 -2
  90. package/dist/theme/presets/index.d.ts +97 -0
  91. package/dist/theme/presets/index.js +3 -0
  92. package/dist/types/index.d.ts +71 -126
  93. package/dist/utils/index.js +1 -1
  94. package/dist/vite/index.d.ts +7 -0
  95. package/dist/vite/index.js +10 -0
  96. package/dist/vite-plugin-knowledge/index.d.ts +1 -33
  97. package/dist/vite-plugin-knowledge/index.js +1 -66
  98. package/package.json +16 -3
  99. package/src/knowledge/README.md +8 -8
  100. package/src/theme/presets/README.md +19 -0
  101. package/dist/chunk-5RLYII6P.js +0 -314
  102. package/dist/chunk-6U7AIIHF.js +0 -880
  103. package/dist/chunk-HAEJ4M54.js +0 -94
  104. package/dist/chunk-LPM7O6XM.js +0 -293
  105. /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
@@ -1,32 +1,35 @@
1
- import { SubshellSidebarLoader, SubshellLoader } from './chunk-N55DVMAG.js';
2
1
  import { ChatHeader, ChatSidebar } from './chunk-ROSMICXG.js';
3
- import { buildOrganizationGraph } from './chunk-6U7AIIHF.js';
4
- import { BaseNode, useGraphTheme, BaseEdge, FormFieldRenderer, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-7F3IQMLI.js';
5
- import { ResourceHealthPanel } from './chunk-QARSVM7Q.js';
6
- import { useCyberColors, CyberDonut } from './chunk-KMAXFJPH.js';
2
+ import { getOrganizationGraphLensConfig, useOrganizationGraphFilters, createOrganizationGraphFilters, buildOrganizationGraph, filterOrganizationGraph, getCommandViewVisibilityProjection, resolveOrganizationGraphPathTrace, getCommandViewOperationalOverview, getCommandViewSelectionOperationalSummary, buildCommandViewDrillDownSections, expandAroundGraph, getConnectedHiddenResourceIds, FilterPanel, OrganizationGraphDetailPanel, ExpandAroundPanel, CommandViewSidebarContent, getOrganizationGraphTraceNodeOptions, formatOrganizationGraphTraceNodeOptionLabel } from './chunk-OHXU5WWK.js';
3
+ import { SubshellLoader } from './chunk-JDNEWB5F.js';
4
+ import { resolveSemanticIconComponent } from './chunk-KEFWANZY.js';
5
+ import { SubshellSidebarLoader } from './chunk-XQQEKWTL.js';
6
+ import { BaseNode, useGraphTheme, BaseEdge, ExecutionStats, UnifiedWorkflowGraph, WorkflowExecutionTimeline, AgentExecutionVisualizer, AgentExecutionTimeline, GraphBackground, GraphFitViewButton, GraphFitViewHandler } from './chunk-G66QFZXD.js';
7
+ import { FormFieldRenderer } from './chunk-3MEXPLWT.js';
8
+ import { ResourceHealthPanel } from './chunk-YO2YORW4.js';
9
+ import { useCyberColors, CyberDonut } from './chunk-CW3UNAF2.js';
7
10
  import { AppShellLoader } from './chunk-RYTEQBAO.js';
8
11
  import { PageContainer } from './chunk-BZZCNLT6.js';
9
12
  import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
10
13
  import { CustomModal, ConfirmationModal } from './chunk-KVJ3LFH2.js';
11
- import { getResourceStatusColor, useTimelineData, useAgentIterationData, getStatusIcon } from './chunk-E4WQGJNS.js';
12
- import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, collectResourceFilterFacets, useExecuteAsync, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, COMMAND_VIEW_VISUALIZATION_MODES, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions, getCommandViewGraphPositions } from './chunk-CPAJXBTL.js';
13
- import { showApiErrorNotification, showSuccessNotification } from './chunk-HKBEURCV.js';
14
14
  import { useGraphHighlighting, calculateGraphHeight, Graph_module_css_default, GRAPH_CONSTANTS } from './chunk-22UVE3RA.js';
15
+ import { getResourceStatusColor, useTimelineData, useAgentIterationData, getStatusIcon } from './chunk-E4WQGJNS.js';
16
+ import { useErrorDetail, useExecution, useArchivedLogs, useDeleteExecution, useRetryExecution, useCancelExecution, useCommandQueueTotals, useStatusFilter, useResourceSearch, useResourcesDomainFilters, usePaginationState, useResources, useRecentExecutionsByResource, filterByDomainFilters, collectResourceFilterFacets, useResourceDefinition, isSessionCapable, useDeleteTask, useCommandQueue, useSubmitAction, useCommandViewData, useCommandViewStats, useCommandViewStore, useResourceExecutions, useCheckpointTasks, COMMAND_VIEW_VISUALIZATION_MODES, useExecutionPanelState, useDeleteSession, useCreateSession, useSessions, useSessionExecutions, useSession, useBulkDeleteExecutions, getCommandViewGraphPositions } from './chunk-YHBPR67D.js';
17
+ import { showApiErrorNotification, showSuccessNotification } from './chunk-G26INIF3.js';
15
18
  import { useMergedExecution } from './chunk-3ZMAGTWF.js';
19
+ import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-RIFTUOPE.js';
20
+ import { StyledMarkdown } from './chunk-3KMDHCAR.js';
21
+ import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-V3HUIZJX.js';
16
22
  import { SubshellContentContainer } from './chunk-TKAYX2SP.js';
17
- import { JsonViewer, CardHeader, PageTitleCaption, CollapsibleSection, TabCountBadge, ResourceCard, ContextViewer, EmptyState, APIErrorAlert } from './chunk-U36X6NZM.js';
18
23
  import { NavigationButton } from './chunk-NYBEU5TE.js';
19
- import { useOptionalElevasisFeatures, useElevasisFeatures } from './chunk-V3HUIZJX.js';
20
- import { StyledMarkdown } from './chunk-3KMDHCAR.js';
21
24
  import { useRouterContext } from './chunk-Q7DJKLEN.js';
22
25
  import { useAppearance } from './chunk-E565XMTQ.js';
23
26
  import { topbarHeight } from './chunk-DT3QYZVU.js';
24
- import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, getNodeId, PAGE_SIZE_DEFAULT, debounce } from './chunk-SGXXJE52.js';
27
+ import { getErrorInfo, formatErrorMessage, getResourceIcon, formatRelativeTime, PAGE_SIZE_DEFAULT, debounce } from './chunk-QD4X4H5A.js';
25
28
  import { ResourceStatusColors, toWorkflowLogMessages } from './chunk-KRWALB24.js';
26
29
  import { useInitialization } from './chunk-WKJ47GIW.js';
27
30
  import { useOrganization } from './chunk-DD3CCMCZ.js';
28
- import { Stack, Group, Text, Badge, Title, Textarea, Alert, Button, ActionIcon, Collapse, Card, ThemeIcon, SimpleGrid, Divider, Paper, Space, CopyButton, Center, Tooltip, Code, Menu, useMantineTheme, UnstyledButton, Select, RangeSlider, Box, Progress, Tabs, Pagination, TextInput, Modal, LoadingOverlay, Loader, SegmentedControl, ScrollArea, Checkbox, NumberInput, MultiSelect, Switch } from '@mantine/core';
29
- import { IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconCode, IconAlertCircle, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconPlayerPlay, IconNetwork, IconSitemap, IconCopy, IconPlayerStop, IconReload, IconTrash, IconTerminal2, IconBug, IconChevronDown, IconMessage, IconArrowLeft, IconRobot, IconGitBranch, IconDotsVertical, IconFilter, IconCircleCheck, IconCategory, IconDatabase, IconApps, IconRoute, IconAdjustmentsHorizontal, IconSearch, IconCircleX, IconCircleDashed, IconExternalLink, IconFolders, IconBraces, IconBolt, IconTopologyStar3, IconInfoCircle, IconPlus, IconLayoutSidebarRightExpand, IconNote, IconArchive, IconDownload, IconTimeline, IconActivityHeartbeat, IconClockPause, IconArrowsMaximize, IconShare2, IconHistory } from '@tabler/icons-react';
31
+ import { Stack, Group, Text, Badge, Title, Textarea, Alert, Button, ActionIcon, Collapse, Card, ThemeIcon, SimpleGrid, Divider, Paper, Space, CopyButton, Center, Tooltip, Code, Menu, useMantineTheme, UnstyledButton, Select, RangeSlider, Box, Progress, Tabs, Pagination, TextInput, Loader, SegmentedControl, Modal, LoadingOverlay, ScrollArea } from '@mantine/core';
32
+ import { IconBrain, IconFileText, IconMail, IconSend, IconClock, IconArrowUp, IconMessageCircle, IconRocket, IconEye, IconEdit, IconAlertTriangle, IconRefresh, IconX, IconCheck, IconCode, IconAlertCircle, IconChevronRight, IconTool, IconSettings, IconCpu, IconClockHour4, IconVersions, IconNetwork, IconSitemap, IconCopy, IconPlayerStop, IconReload, IconTrash, IconTerminal2, IconBug, IconChevronDown, IconPlayerPlay, IconMessage, IconArrowLeft, IconRobot, IconGitBranch, IconDotsVertical, IconFilter, IconCircleCheck, IconCategory, IconDatabase, IconApps, IconRoute, IconAdjustmentsHorizontal, IconSearch, IconCircleX, IconCircleDashed, IconExternalLink, IconFolders, IconBraces, IconBolt, IconTopologyStar3, IconInfoCircle, IconPlus, IconLayoutSidebarRightExpand, IconNote, IconArchive, IconDownload, IconTimeline, IconActivityHeartbeat, IconClockPause, IconArrowsMaximize, IconHistory } from '@tabler/icons-react';
30
33
  import { useForm } from '@mantine/form';
31
34
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
32
35
  import { memo, useState, useMemo, useRef, useCallback, useEffect, useDeferredValue, useEffectEvent } from 'react';
@@ -37,8 +40,6 @@ import { useClipboard } from '@mantine/hooks';
37
40
  import { notifications } from '@mantine/notifications';
38
41
  import { useNavigate } from '@tanstack/react-router';
39
42
  import cytoscape from 'cytoscape';
40
- import { create } from 'zustand';
41
- import { formatDistanceToNow } from 'date-fns';
42
43
 
43
44
  var iconMap = {
44
45
  IconCheck,
@@ -55,13 +56,35 @@ var iconMap = {
55
56
  IconSend,
56
57
  IconMail
57
58
  };
59
+ var semanticActionIconMap = {
60
+ "action.approve": IconCheck,
61
+ "action.reject": IconX,
62
+ "action.retry": IconRefresh,
63
+ "action.escalate": IconAlertTriangle,
64
+ "action.edit": IconEdit,
65
+ "action.view": IconEye,
66
+ "action.launch": IconRocket,
67
+ "action.message": IconMessageCircle,
68
+ "action.promote": IconArrowUp,
69
+ "action.submit": IconSend,
70
+ "action.email": IconMail,
71
+ "status.pending": IconClock,
72
+ "status.success": IconCheck,
73
+ "status.error": IconX,
74
+ "status.warning": IconAlertTriangle
75
+ };
58
76
  function getIcon(iconName) {
59
77
  if (!iconName) return null;
60
- const icon = iconMap[iconName];
61
- if (!icon && process.env.NODE_ENV !== "production") {
62
- console.warn(`[iconMap] Unknown icon "${iconName}". Allowed: ${Object.keys(iconMap).join(", ")}`);
78
+ const icon = iconMap[iconName] ?? semanticActionIconMap[iconName];
79
+ if (icon) return icon;
80
+ const semanticIcon = resolveSemanticIconComponent(iconName);
81
+ if (semanticIcon) return semanticIcon;
82
+ if (process.env.NODE_ENV !== "production") {
83
+ console.warn(
84
+ `[iconMap] Unknown icon "${iconName}". Allowed legacy names: ${Object.keys(iconMap).join(", ")}. Semantic action/status tokens are also supported.`
85
+ );
63
86
  }
64
- return icon || null;
87
+ return null;
65
88
  }
66
89
  function resolveDefaultValue(context, path) {
67
90
  if (!context || typeof context !== "object") return void 0;
@@ -587,20 +610,6 @@ function AgentDefinitionDisplay({ agent, defaultExpanded = false }) {
587
610
  }
588
611
  ]
589
612
  }
590
- ),
591
- /* @__PURE__ */ jsx(
592
- ConfigCard,
593
- {
594
- icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
595
- title: "Execution Interface",
596
- color: "teal",
597
- items: [
598
- {
599
- label: "Has Interface",
600
- value: agent.interface ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "green", children: "Yes" }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: "No" })
601
- }
602
- ]
603
- }
604
613
  )
605
614
  ] }),
606
615
  /* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)", marginTop: "var(--mantine-spacing-sm)" }, children: /* @__PURE__ */ jsx(ContractDisplay, { contract: agent.contract, defaultExpanded }) })
@@ -719,36 +728,20 @@ function WorkflowDefinitionDisplay({ workflow, defaultExpanded = false }) {
719
728
  }
720
729
  ),
721
730
  /* @__PURE__ */ jsxs(Collapse, { in: configExpanded, children: [
722
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: 2, spacing: "sm", mt: "xs", pl: "xl", children: [
723
- /* @__PURE__ */ jsx(
724
- ConfigCard,
725
- {
726
- icon: /* @__PURE__ */ jsx(IconVersions, { size: 14 }),
727
- title: "Version",
728
- color: "grape",
729
- items: [
730
- {
731
- label: "Version",
732
- value: /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: workflow.config.version })
733
- }
734
- ]
735
- }
736
- ),
737
- /* @__PURE__ */ jsx(
738
- ConfigCard,
739
- {
740
- icon: /* @__PURE__ */ jsx(IconPlayerPlay, { size: 14 }),
741
- title: "Execution Interface",
742
- color: "teal",
743
- items: [
744
- {
745
- label: "Has Interface",
746
- value: workflow.interface ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "green", children: "Yes" }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: "No" })
747
- }
748
- ]
749
- }
750
- )
751
- ] }),
731
+ /* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)" }, children: /* @__PURE__ */ jsx(
732
+ ConfigCard,
733
+ {
734
+ icon: /* @__PURE__ */ jsx(IconVersions, { size: 14 }),
735
+ title: "Version",
736
+ color: "grape",
737
+ items: [
738
+ {
739
+ label: "Version",
740
+ value: /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", children: workflow.config.version })
741
+ }
742
+ ]
743
+ }
744
+ ) }),
752
745
  /* @__PURE__ */ jsx("div", { style: { paddingLeft: "var(--mantine-spacing-xl)", marginTop: "var(--mantine-spacing-sm)" }, children: /* @__PURE__ */ jsx(ContractDisplay, { contract: workflow.contract, defaultExpanded }) })
753
746
  ] })
754
747
  ] }) });
@@ -2723,174 +2716,12 @@ function ResourceNotFoundState2({ type, resourceId, onNavigateBack }) {
2723
2716
  /* @__PURE__ */ jsx(Button, { variant: "light", leftSection: /* @__PURE__ */ jsx(IconArrowLeft, { size: 16 }), onClick: handleBack, children: "Back to Operations" })
2724
2717
  ] }) }) });
2725
2718
  }
2726
- function ExecuteWorkflowModal({
2727
- opened,
2728
- onClose,
2729
- resource,
2730
- isPending = false,
2731
- error,
2732
- result,
2733
- onViewExecution,
2734
- onReset,
2735
- children
2736
- }) {
2737
- const canClose = !isPending;
2738
- const title = resource.name ?? resource.resourceId;
2739
- return /* @__PURE__ */ jsx(
2740
- Modal,
2741
- {
2742
- opened,
2743
- onClose: canClose ? onClose : () => void 0,
2744
- centered: true,
2745
- size: "lg",
2746
- closeOnClickOutside: canClose,
2747
- closeOnEscape: canClose,
2748
- withCloseButton: canClose,
2749
- title: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
2750
- /* @__PURE__ */ jsxs(Text, { fw: 600, children: [
2751
- "Run ",
2752
- resource.resourceType
2753
- ] }),
2754
- /* @__PURE__ */ jsx(Badge, { color: "blue", variant: "light", size: "sm", children: resource.resourceType })
2755
- ] }),
2756
- children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
2757
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
2758
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Target:" }),
2759
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: title }),
2760
- /* @__PURE__ */ jsx(Code, { children: resource.resourceId })
2761
- ] }),
2762
- /* @__PURE__ */ jsx(Divider, {}),
2763
- result ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
2764
- /* @__PURE__ */ jsx(Alert, { variant: "light", color: "teal", title: "Execution started", icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }), children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
2765
- /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
2766
- "The ",
2767
- resource.resourceType,
2768
- " is now running."
2769
- ] }),
2770
- /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
2771
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Execution ID:" }),
2772
- /* @__PURE__ */ jsx(Code, { children: result.executionId })
2773
- ] })
2774
- ] }) }),
2775
- /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
2776
- onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Run again" }),
2777
- onViewExecution && /* @__PURE__ */ jsx(
2778
- Button,
2779
- {
2780
- leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 16 }),
2781
- onClick: () => onViewExecution(result.executionId),
2782
- children: "View execution"
2783
- }
2784
- ),
2785
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
2786
- ] })
2787
- ] }) : error ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
2788
- /* @__PURE__ */ jsx(Alert, { variant: "light", color: "red", title: "Execution failed to start", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: /* @__PURE__ */ jsx(Text, { size: "sm", children: error.message || "An unknown error occurred." }) }),
2789
- /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
2790
- onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Try again" }),
2791
- /* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
2792
- ] })
2793
- ] }) : /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
2794
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: isPending, zIndex: 1e3, overlayProps: { blur: 2 } }),
2795
- children ?? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No input form provided." })
2796
- ] })
2797
- ] })
2798
- }
2799
- );
2800
- }
2801
- function getInitialValues(fields) {
2802
- const values = {};
2803
- for (const field of fields) {
2804
- values[field.name] = field.defaultValue ?? (field.type === "checkbox" ? false : "");
2805
- }
2806
- return values;
2807
- }
2808
- function applyFieldMappings(values, mappings) {
2809
- if (!mappings) return values;
2810
- const mapped = {};
2811
- for (const [key, value] of Object.entries(values)) {
2812
- const targetKey = mappings[key] ?? key;
2813
- mapped[targetKey] = value;
2814
- }
2815
- return mapped;
2816
- }
2817
- function ResourceExecuteForm({
2818
- formSchema,
2819
- onSubmit,
2820
- isPending = false,
2821
- disabled = false,
2822
- submitLabel = "Run"
2823
- }) {
2824
- const hasFields = formSchema?.fields?.length > 0;
2825
- const form = useForm({
2826
- initialValues: hasFields ? getInitialValues(formSchema.fields) : {},
2827
- validate: hasFields ? Object.fromEntries(
2828
- formSchema.fields.filter((f) => f.required).map((f) => [
2829
- f.name,
2830
- (value) => !value && value !== false ? `${f.label} is required` : null
2831
- ])
2832
- ) : {}
2833
- });
2834
- const handleSubmit = (values) => {
2835
- const input = applyFieldMappings(values, formSchema?.fieldMappings);
2836
- void onSubmit(input);
2837
- };
2838
- if (!hasFields) {
2839
- return /* @__PURE__ */ jsxs(Stack, { children: [
2840
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "This workflow takes no input." }),
2841
- /* @__PURE__ */ jsx(Button, { onClick: () => void onSubmit({}), loading: isPending, disabled, fullWidth: true, children: isPending ? formSchema?.submitButton?.loadingLabel ?? "Running..." : submitLabel })
2842
- ] });
2843
- }
2844
- return /* @__PURE__ */ jsx("form", { onSubmit: form.onSubmit(handleSubmit), children: /* @__PURE__ */ jsxs(Stack, { children: [
2845
- formSchema.fields.map((field) => /* @__PURE__ */ jsx(FormFieldRenderer, { field, form }, field.name)),
2846
- /* @__PURE__ */ jsx(Button, { type: "submit", loading: isPending, disabled, fullWidth: true, children: isPending ? formSchema.submitButton?.loadingLabel ?? "Running..." : submitLabel })
2847
- ] }) });
2848
- }
2849
- function ResourceExecuteDialog({ opened, onClose, resource, onViewExecution }) {
2850
- const mutation = useExecuteAsync();
2851
- const handleSubmit = async (input) => {
2852
- await mutation.mutateAsync({
2853
- resourceId: resource.resourceId,
2854
- resourceType: resource.resourceType,
2855
- input
2856
- });
2857
- };
2858
- const handleReset = () => {
2859
- mutation.reset();
2860
- };
2861
- const modalResource = {
2862
- resourceId: resource.resourceId,
2863
- resourceType: resource.resourceType,
2864
- name: resource.name
2865
- };
2866
- return /* @__PURE__ */ jsx(
2867
- ExecuteWorkflowModal,
2868
- {
2869
- opened,
2870
- onClose,
2871
- resource: modalResource,
2872
- isPending: mutation.isPending,
2873
- error: mutation.error,
2874
- result: mutation.data ?? null,
2875
- onViewExecution,
2876
- onReset: handleReset,
2877
- children: /* @__PURE__ */ jsx(
2878
- ResourceExecuteForm,
2879
- {
2880
- formSchema: resource.formSchema ?? { fields: [] },
2881
- onSubmit: handleSubmit,
2882
- isPending: mutation.isPending,
2883
- disabled: mutation.isPending
2884
- }
2885
- )
2886
- }
2887
- );
2888
- }
2889
2719
  function ResourceDetailPage({
2890
2720
  type,
2891
2721
  resourceId,
2892
2722
  timeRange,
2893
2723
  renderExecutionPanel,
2724
+ renderExecuteDialog,
2894
2725
  onNavigateToResources,
2895
2726
  onNavigateToSessions,
2896
2727
  onNavigateBack
@@ -2926,19 +2757,13 @@ function ResourceDetailPage({
2926
2757
  const validResource = resource;
2927
2758
  const sessionCapable = isSessionCapable(type, resourceDefinition);
2928
2759
  return /* @__PURE__ */ jsxs(Fragment, { children: [
2929
- /* @__PURE__ */ jsx(
2930
- ResourceExecuteDialog,
2931
- {
2932
- opened: runOpened,
2933
- onClose: () => setRunOpened(false),
2934
- resource: {
2935
- resourceId,
2936
- resourceType: type,
2937
- name: validResource.name,
2938
- formSchema: resourceDefinition?.interface?.form
2939
- }
2940
- }
2941
- ),
2760
+ renderExecuteDialog({
2761
+ opened: runOpened,
2762
+ onClose: () => setRunOpened(false),
2763
+ resourceId,
2764
+ resourceType: type,
2765
+ name: validResource.name
2766
+ }),
2942
2767
  /* @__PURE__ */ jsxs(Stack, { children: [
2943
2768
  /* @__PURE__ */ jsx(
2944
2769
  ResourceHeader,
@@ -3547,2534 +3372,74 @@ function CommandQueueDetailPage({
3547
3372
  ] }) })
3548
3373
  ] });
3549
3374
  }
3550
-
3551
- // src/features/operations/organization-graph/organizationGraphDetail.ts
3552
- var NODE_KIND_LABELS = {
3553
- organization: "Organization root",
3554
- feature: "Feature",
3555
- surface: "Surface",
3556
- entity: "Entity",
3557
- capability: "Capability",
3558
- resource: "Resource",
3559
- knowledge: "Knowledge"
3560
- };
3561
- var NODE_KIND_MEANINGS = {
3562
- organization: "The root of the shared organization model and the parent for every derived node.",
3563
- feature: "A feature that enables or disables downstream surfaces and model surfaces.",
3564
- surface: "A user-facing or operational surface that exposes feature behavior in the model.",
3565
- entity: "A shared business concept that can be referenced by surfaces, resources, or capabilities.",
3566
- capability: "A reusable capability that can be attached to a feature or surface.",
3567
- resource: "A concrete command-view or mapped resource that bridges execution topology into the model.",
3568
- knowledge: "An operational knowledge node that documents a process, strategy, or runbook in the org model."
3569
- };
3570
- var EDGE_KIND_LABELS = {
3571
- contains: "Containment",
3572
- references: "Reference",
3573
- exposes: "Exposure",
3574
- maps_to: "Mapping",
3575
- "operates-on": "Operates on",
3576
- uses: "Uses",
3577
- governs: "Governs"
3578
- };
3579
- var EDGE_KIND_MEANINGS = {
3580
- contains: "A hierarchy or ownership link inside the shared graph.",
3581
- references: "A semantic association or dependency between two graph nodes.",
3582
- exposes: "A feature enables a surface to be visible or reachable.",
3583
- maps_to: "A concrete resource is aligned to a domain, entity, capability, or surface.",
3584
- "operates-on": "A concrete resource operates on an Organization Model node.",
3585
- uses: "A concrete resource depends on another graph node or integration.",
3586
- governs: "A knowledge node governs or provides authoritative guidance for another node."
3587
- };
3588
- var RELATIONSHIP_MEANINGS = {
3589
- triggers: "Executable handoff: the source resource starts the target resource.",
3590
- uses: "Operational dependency: the source resource relies on the target integration.",
3591
- approval: "Human gate: the source resource pauses for approval at the target checkpoint."
3375
+ var cellStyle = {
3376
+ padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
3377
+ display: "flex",
3378
+ alignItems: "center",
3379
+ gap: "var(--mantine-spacing-sm)",
3380
+ minWidth: 0
3592
3381
  };
3593
- function titleCase(value) {
3594
- return value.replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
3595
- }
3596
- function getGraphIndex(graph) {
3597
- const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
3598
- const edgesById = new Map(graph.edges.map((edge) => [edge.id, edge]));
3599
- return { nodesById, edgesById };
3600
- }
3601
- function getNodeKindLabel(kind) {
3602
- return NODE_KIND_LABELS[kind];
3603
- }
3604
- function getNodeMeaning(node) {
3605
- const baseMeaning = NODE_KIND_MEANINGS[node.kind];
3606
- if (node.kind === "feature") {
3607
- return node.enabled === false ? `${baseMeaning} This feature is currently disabled in the organization model.` : `${baseMeaning} This feature is currently enabled in the organization model.`;
3608
- }
3609
- if (node.kind === "resource" && node.resourceType) {
3610
- return `${baseMeaning} Resource type: ${titleCase(node.resourceType)}.`;
3611
- }
3612
- if (node.description) {
3613
- return `${baseMeaning} ${node.description}`;
3614
- }
3615
- return baseMeaning;
3616
- }
3617
- function getEdgeKindLabel(kind) {
3618
- return EDGE_KIND_LABELS[kind];
3619
- }
3620
- function getEdgeMeaning(edge, sourceNode, targetNode) {
3621
- const sourceLabel = sourceNode?.label ?? edge.sourceId;
3622
- const targetLabel = targetNode?.label ?? edge.targetId;
3623
- if (edge.relationshipType) {
3624
- const relationshipMeaning = RELATIONSHIP_MEANINGS[edge.relationshipType];
3625
- return `${relationshipMeaning} The graph renders the link from ${sourceLabel} to ${targetLabel} as a ${getEdgeKindLabel(edge.kind).toLowerCase()} edge.`;
3626
- }
3627
- return `${EDGE_KIND_MEANINGS[edge.kind]} This link connects ${sourceLabel} to ${targetLabel}.`;
3628
- }
3629
- function countByKind(nodes) {
3630
- const counts = /* @__PURE__ */ new Map();
3631
- for (const node of nodes) {
3632
- counts.set(node.kind, (counts.get(node.kind) ?? 0) + 1);
3633
- }
3634
- return [...counts.entries()].map(([kind, count]) => ({
3635
- kind,
3636
- label: getNodeKindLabel(kind),
3637
- count
3638
- })).sort((left, right) => left.label.localeCompare(right.label));
3639
- }
3640
- function uniqueNodesById(nodes) {
3641
- const byId = /* @__PURE__ */ new Map();
3642
- for (const node of nodes) {
3643
- byId.set(node.id, node);
3644
- }
3645
- return [...byId.values()];
3646
- }
3647
- function uniqueEdgesById(edges) {
3648
- const byId = /* @__PURE__ */ new Map();
3649
- for (const edge of edges) {
3650
- byId.set(edge.id, edge);
3651
- }
3652
- return [...byId.values()];
3653
- }
3654
- function buildNodeState(graph, node, nodesById) {
3655
- const incidentEdges = graph.edges.filter((edge) => edge.sourceId === node.id || edge.targetId === node.id);
3656
- const incomingEdges = incidentEdges.filter((edge) => edge.targetId === node.id);
3657
- const outgoingEdges = incidentEdges.filter((edge) => edge.sourceId === node.id);
3658
- const adjacentNodes = uniqueNodesById(
3659
- incidentEdges.map((edge) => edge.sourceId === node.id ? nodesById.get(edge.targetId) : nodesById.get(edge.sourceId)).filter((value) => Boolean(value))
3660
- );
3661
- const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
3662
- const contexts = incidentEdges.filter(
3663
- (edge) => edge.sourceId === node.id ? edge.targetId === adjacentNode.id : edge.sourceId === adjacentNode.id
3664
- ).map(
3665
- (edge) => `${edge.sourceId === node.id ? "outgoing" : "incoming"} via ${edge.label ?? getEdgeKindLabel(edge.kind).toLowerCase()}`
3666
- );
3667
- return {
3668
- id: adjacentNode.id,
3669
- label: adjacentNode.label,
3670
- kind: adjacentNode.kind,
3671
- kindLabel: getNodeKindLabel(adjacentNode.kind),
3672
- context: contexts.slice(0, 2).join(", ")
3673
- };
3674
- });
3675
- const relatedEdges = incidentEdges.slice().sort((left, right) => left.id.localeCompare(right.id)).map((edge) => {
3676
- const connectedId = edge.sourceId === node.id ? edge.targetId : edge.sourceId;
3677
- const connectedNode = nodesById.get(connectedId);
3678
- return {
3679
- id: edge.id,
3680
- label: edge.label ?? edge.relationshipType ?? getEdgeKindLabel(edge.kind),
3681
- kind: edge.kind,
3682
- kindLabel: getEdgeKindLabel(edge.kind),
3683
- context: `${edge.sourceId === node.id ? "outgoing" : "incoming"}${connectedNode ? ` to ${connectedNode.label}` : ""}`
3684
- };
3685
- });
3686
- const metadata = [
3687
- { label: "Graph ID", value: node.id },
3688
- { label: "Source ID", value: node.sourceId ?? node.id },
3689
- { label: "Kind", value: getNodeKindLabel(node.kind) }
3690
- ];
3691
- if (node.enabled !== void 0) {
3692
- metadata.push({ label: "Enabled", value: node.enabled ? "Yes" : "No" });
3693
- }
3694
- if (node.featureId) {
3695
- metadata.push({ label: "Feature ID", value: node.featureId });
3696
- }
3697
- if (node.resourceType) {
3698
- metadata.push({ label: "Resource Type", value: titleCase(node.resourceType) });
3699
- }
3700
- const meaningfulEdges = incidentEdges.filter((edge) => edge.kind !== "contains" || edge.relationshipType);
3701
- return {
3702
- state: "node",
3703
- title: node.label,
3704
- semanticCategory: getNodeKindLabel(node.kind),
3705
- operationalMeaning: getNodeMeaning(node),
3706
- description: node.description,
3707
- metrics: [
3708
- {
3709
- label: "Connected edges",
3710
- value: String(incidentEdges.length),
3711
- hint: "All direct relationships attached to this node"
3712
- },
3713
- { label: "Incoming", value: String(incomingEdges.length), hint: "Edges that point into this node" },
3714
- { label: "Outgoing", value: String(outgoingEdges.length), hint: "Edges that start at this node" },
3715
- {
3716
- label: "Meaningful links",
3717
- value: String(meaningfulEdges.length),
3718
- hint: "Edges with semantic or operational meaning"
3719
- }
3720
- ],
3721
- metadata,
3722
- adjacentKindCounts: countByKind(adjacentNodes),
3723
- node,
3724
- relatedNodes,
3725
- relatedEdges
3726
- };
3727
- }
3728
- function buildEdgeState(graph, edge, nodesById) {
3729
- const sourceNode = nodesById.get(edge.sourceId);
3730
- const targetNode = nodesById.get(edge.targetId);
3731
- const sourceIncidentEdges = graph.edges.filter(
3732
- (candidate) => candidate.sourceId === edge.sourceId || candidate.targetId === edge.sourceId
3733
- );
3734
- const targetIncidentEdges = graph.edges.filter(
3735
- (candidate) => candidate.sourceId === edge.targetId || candidate.targetId === edge.targetId
3736
- );
3737
- const adjacentNodes = uniqueNodesById(
3738
- [...sourceIncidentEdges, ...targetIncidentEdges].map((candidate) => {
3739
- if (candidate.sourceId === edge.sourceId) return nodesById.get(candidate.targetId);
3740
- if (candidate.targetId === edge.sourceId) return nodesById.get(candidate.sourceId);
3741
- if (candidate.sourceId === edge.targetId) return nodesById.get(candidate.targetId);
3742
- if (candidate.targetId === edge.targetId) return nodesById.get(candidate.sourceId);
3743
- return null;
3744
- }).filter((value) => Boolean(value)).filter((candidate) => candidate.id !== edge.sourceId && candidate.id !== edge.targetId)
3745
- );
3746
- const sourceNeighborIds = new Set(
3747
- sourceIncidentEdges.map((candidate) => {
3748
- if (candidate.sourceId === edge.sourceId) return candidate.targetId;
3749
- if (candidate.targetId === edge.sourceId) return candidate.sourceId;
3750
- return null;
3751
- }).filter((value) => Boolean(value))
3752
- );
3753
- const targetNeighborIds = new Set(
3754
- targetIncidentEdges.map((candidate) => {
3755
- if (candidate.sourceId === edge.targetId) return candidate.targetId;
3756
- if (candidate.targetId === edge.targetId) return candidate.sourceId;
3757
- return null;
3758
- }).filter((value) => Boolean(value))
3759
- );
3760
- const sharedNeighborCount = [...sourceNeighborIds].filter((neighborId) => targetNeighborIds.has(neighborId)).length;
3761
- const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
3762
- const sourceContext = sourceIncidentEdges.some(
3763
- (candidate) => candidate.sourceId === edge.sourceId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.sourceId && candidate.sourceId === adjacentNode.id
3764
- );
3765
- const targetContext = targetIncidentEdges.some(
3766
- (candidate) => candidate.sourceId === edge.targetId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.targetId && candidate.sourceId === adjacentNode.id
3767
- );
3768
- const contextParts = [];
3769
- if (sourceContext) contextParts.push("source neighborhood");
3770
- if (targetContext) contextParts.push("target neighborhood");
3771
- return {
3772
- id: adjacentNode.id,
3773
- label: adjacentNode.label,
3774
- kind: adjacentNode.kind,
3775
- kindLabel: getNodeKindLabel(adjacentNode.kind),
3776
- context: contextParts.join(" + ")
3777
- };
3778
- });
3779
- const surroundingEdges = uniqueEdgesById([...sourceIncidentEdges, ...targetIncidentEdges]).filter((candidate) => candidate.id !== edge.id).sort((left, right) => left.id.localeCompare(right.id)).map((candidate) => {
3780
- const leftNode = nodesById.get(candidate.sourceId);
3781
- const rightNode = nodesById.get(candidate.targetId);
3782
- return {
3783
- id: candidate.id,
3784
- label: candidate.label ?? candidate.relationshipType ?? getEdgeKindLabel(candidate.kind),
3785
- kind: candidate.kind,
3786
- kindLabel: getEdgeKindLabel(candidate.kind),
3787
- context: `${leftNode?.label ?? candidate.sourceId} -> ${rightNode?.label ?? candidate.targetId}`
3788
- };
3789
- });
3790
- const metadata = [
3791
- { label: "Graph ID", value: edge.id },
3792
- { label: "Source ID", value: edge.sourceId },
3793
- { label: "Target ID", value: edge.targetId },
3794
- { label: "Edge kind", value: getEdgeKindLabel(edge.kind) }
3795
- ];
3796
- if (edge.label) {
3797
- metadata.push({ label: "Label", value: edge.label });
3798
- }
3799
- if (edge.relationshipType) {
3800
- metadata.push({ label: "Relationship", value: titleCase(edge.relationshipType) });
3801
- }
3802
- return {
3803
- state: "edge",
3804
- title: edge.label ?? `${sourceNode?.label ?? edge.sourceId} \u2192 ${targetNode?.label ?? edge.targetId}`,
3805
- semanticCategory: edge.relationshipType ? titleCase(edge.relationshipType) : getEdgeKindLabel(edge.kind),
3806
- operationalMeaning: getEdgeMeaning(edge, sourceNode, targetNode),
3807
- description: edge.label,
3808
- metrics: [
3809
- {
3810
- label: "Source degree",
3811
- value: String(sourceIncidentEdges.length),
3812
- hint: "Relationships attached to the source node"
3813
- },
3814
- {
3815
- label: "Target degree",
3816
- value: String(targetIncidentEdges.length),
3817
- hint: "Relationships attached to the target node"
3818
- },
3819
- {
3820
- label: "Nearby nodes",
3821
- value: String(adjacentNodes.length),
3822
- hint: "Unique nodes in the source and target neighborhoods"
3823
- },
3824
- {
3825
- label: "Shared peers",
3826
- value: String(sharedNeighborCount),
3827
- hint: "Neighbors that appear in both node neighborhoods"
3828
- }
3829
- ],
3830
- metadata,
3831
- adjacentKindCounts: countByKind(adjacentNodes),
3832
- edge,
3833
- sourceNode,
3834
- targetNode,
3835
- relatedNodes,
3836
- relatedEdges: surroundingEdges
3837
- };
3838
- }
3839
- function getOrganizationGraphDetailState(graph, selectedElement) {
3840
- if (!selectedElement) {
3841
- return {
3842
- state: "empty",
3843
- title: "No element selected",
3844
- semanticCategory: "Selection",
3845
- operationalMeaning: "Select a node or edge to inspect its semantic and operational context.",
3846
- metrics: [],
3847
- metadata: [],
3848
- adjacentKindCounts: []
3849
- };
3850
- }
3851
- if (!graph) {
3852
- return {
3853
- state: "missing",
3854
- title: "Graph unavailable",
3855
- semanticCategory: selectedElement.type === "node" ? "Selected node" : "Selected edge",
3856
- operationalMeaning: "The graph data is not available yet, so this selection cannot be resolved.",
3857
- metrics: [],
3858
- metadata: [{ label: "Selected ID", value: selectedElement.id }],
3859
- adjacentKindCounts: [],
3860
- missingId: selectedElement.id
3861
- };
3862
- }
3863
- const { nodesById, edgesById } = getGraphIndex(graph);
3864
- if (selectedElement.type === "node") {
3865
- const node = nodesById.get(selectedElement.id);
3866
- if (!node) {
3867
- return {
3868
- state: "missing",
3869
- title: "Selected node unavailable",
3870
- semanticCategory: "Node",
3871
- operationalMeaning: "The selected node is no longer present in the current graph build.",
3872
- metrics: [],
3873
- metadata: [{ label: "Selected ID", value: selectedElement.id }],
3874
- adjacentKindCounts: [],
3875
- missingId: selectedElement.id
3876
- };
3877
- }
3878
- return buildNodeState(graph, node, nodesById);
3879
- }
3880
- const edge = edgesById.get(selectedElement.id);
3881
- if (!edge) {
3882
- return {
3883
- state: "missing",
3884
- title: "Selected edge unavailable",
3885
- semanticCategory: "Edge",
3886
- operationalMeaning: "The selected edge is no longer present in the current graph build.",
3887
- metrics: [],
3888
- metadata: [{ label: "Selected ID", value: selectedElement.id }],
3889
- adjacentKindCounts: [],
3890
- missingId: selectedElement.id
3891
- };
3892
- }
3893
- return buildEdgeState(graph, edge, nodesById);
3894
- }
3895
- function getNodeKindColor(kind) {
3896
- switch (kind) {
3897
- case "organization":
3898
- return "gray";
3899
- case "feature":
3900
- return "blue";
3901
- case "domain":
3902
- return "violet";
3903
- case "surface":
3904
- return "cyan";
3905
- case "entity":
3906
- return "pink";
3907
- case "capability":
3908
- return "green";
3909
- case "resource":
3910
- return "orange";
3911
- default:
3912
- return "gray";
3913
- }
3914
- }
3915
- function getEdgeKindColor(kind) {
3916
- switch (kind) {
3917
- case "contains":
3918
- return "gray";
3919
- case "references":
3920
- return "cyan";
3921
- case "exposes":
3922
- return "blue";
3923
- case "maps_to":
3924
- return "violet";
3925
- default:
3926
- return "gray";
3927
- }
3928
- }
3929
- function getNodeKindLabel2(kind) {
3930
- switch (kind) {
3931
- case "organization":
3932
- return "Organization root";
3933
- case "feature":
3934
- return "Feature gate";
3935
- case "domain":
3936
- return "Domain boundary";
3937
- case "surface":
3938
- return "Surface";
3939
- case "entity":
3940
- return "Entity";
3941
- case "capability":
3942
- return "Capability";
3943
- case "resource":
3944
- return "Resource";
3945
- default:
3946
- return kind;
3947
- }
3948
- }
3949
- function titleCase2(value) {
3950
- return value.charAt(0).toUpperCase() + value.slice(1);
3951
- }
3952
- function MetricCard({ metric }) {
3953
- return /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
3954
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: metric.label }),
3955
- /* @__PURE__ */ jsx(Text, { size: "lg", fw: 800, children: metric.value }),
3956
- metric.hint ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: metric.hint }) : null
3957
- ] }) });
3958
- }
3959
- function RelatedItemCard({ item, itemType }) {
3960
- const badgeColor = itemType === "node" ? getNodeKindColor(item.kind) : getEdgeKindColor(item.kind);
3961
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
3962
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
3963
- /* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
3964
- /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: badgeColor, children: item.kindLabel })
3965
- ] }),
3966
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.context }),
3967
- /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.id })
3968
- ] }) });
3969
- }
3970
- function getStatusColor3(value) {
3971
- switch (value) {
3972
- case "failed":
3973
- return "red";
3974
- case "warning":
3975
- return "yellow";
3976
- case "running":
3977
- case "processing":
3978
- return "blue";
3979
- case "completed":
3980
- return "green";
3981
- case "pending":
3982
- return "orange";
3983
- case "expired":
3984
- return "gray";
3985
- default:
3986
- return "gray";
3987
- }
3988
- }
3989
- function FollowUpSectionCard({ section }) {
3990
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3991
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
3992
- /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
3993
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: section.title }),
3994
- section.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: section.description }) : null
3995
- ] }),
3996
- section.primaryAction ? /* @__PURE__ */ jsx(
3997
- Button,
3998
- {
3999
- size: "xs",
4000
- variant: "light",
4001
- component: "a",
4002
- href: section.primaryAction.href,
4003
- target: "_blank",
4004
- rel: "noreferrer",
4005
- children: section.primaryAction.label
4006
- }
4007
- ) : null
4008
- ] }),
4009
- section.items.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: section.items.map((item) => /* @__PURE__ */ jsx(
4010
- Paper,
4011
- {
4012
- withBorder: true,
4013
- radius: "md",
4014
- p: "sm",
4015
- component: "a",
4016
- href: item.href,
4017
- target: "_blank",
4018
- rel: "noreferrer",
4019
- style: { display: "block", textDecoration: "none", color: "inherit" },
4020
- children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
4021
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
4022
- /* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
4023
- item.badgeLabel ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: item.badgeColor ?? getStatusColor3(item.badgeLabel), children: item.badgeLabel }) : null
4024
- ] }),
4025
- item.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.description }) : null,
4026
- item.meta ? /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.meta }) : null
4027
- ] })
4028
- },
4029
- item.id
4030
- )) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: section.emptyMessage })
4031
- ] }) });
4032
- }
4033
- function OrganizationGraphDetailPanel({
4034
- graph,
4035
- selectedElement,
4036
- supplementalSummary,
4037
- followUpSections,
4038
- expandAroundPanel,
4039
- onClearSelection,
4040
- className
4041
- }) {
4042
- const state = getOrganizationGraphDetailState(graph, selectedElement);
4043
- if (state.state === "empty") {
4044
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsx(EmptyState, { icon: IconShare2, title: state.title, description: state.operationalMeaning, py: "md" }) });
4045
- }
4046
- if (state.state === "missing") {
4047
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
4048
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
4049
- /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
4050
- /* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", children: state.title }),
4051
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
4052
- ] }),
4053
- onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
4054
- ] }),
4055
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: "gray", children: state.semanticCategory }),
4056
- /* @__PURE__ */ jsxs(Paper, { withBorder: true, radius: "md", p: "sm", children: [
4057
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Selected ID" }),
4058
- /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", children: state.missingId })
4059
- ] })
4060
- ] }) });
4061
- }
4062
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
4063
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
4064
- /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
4065
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4066
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: "violet", children: state.semanticCategory }),
4067
- state.state === "node" ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: state.node.enabled === false ? "gray" : "green", children: state.node.enabled === false ? "Disabled" : "Enabled" }) : null,
4068
- state.state === "edge" && state.edge.relationshipType ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "orange", children: titleCase2(state.edge.relationshipType) }) : null
4069
- ] }),
4070
- /* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", children: state.title }),
4071
- /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
4072
- ] }),
4073
- onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
4074
- ] }),
4075
- /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: state.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, metric.label)) }),
4076
- expandAroundPanel,
4077
- supplementalSummary && (supplementalSummary.metrics.length > 0 || supplementalSummary.metadata.length > 0) ? /* @__PURE__ */ jsxs(Fragment, { children: [
4078
- /* @__PURE__ */ jsx(
4079
- Divider,
4080
- {
4081
- label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
4082
- /* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
4083
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: supplementalSummary.title })
4084
- ] }),
4085
- labelPosition: "center"
4086
- }
4087
- ),
4088
- supplementalSummary.description ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: supplementalSummary.description }) : null,
4089
- supplementalSummary.metrics.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: supplementalSummary.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, `supplemental-${metric.label}`)) }) : null,
4090
- supplementalSummary.metadata.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: supplementalSummary.metadata.map((item) => /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
4091
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
4092
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
4093
- ] }) }, `supplemental-${item.label}`)) }) : null
4094
- ] }) : null,
4095
- followUpSections && followUpSections.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
4096
- /* @__PURE__ */ jsx(
4097
- Divider,
4098
- {
4099
- label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
4100
- /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
4101
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Follow-up actions" })
4102
- ] }),
4103
- labelPosition: "center"
4104
- }
4105
- ),
4106
- /* @__PURE__ */ jsx(Stack, { gap: "sm", children: followUpSections.map((section) => /* @__PURE__ */ jsx(FollowUpSectionCard, { section }, section.title)) })
4107
- ] }) : null,
4108
- /* @__PURE__ */ jsx(
4109
- Divider,
4110
- {
4111
- label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
4112
- /* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
4113
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Linked metadata" })
4114
- ] }),
4115
- labelPosition: "center"
4116
- }
4117
- ),
4118
- /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.metadata.map((item) => /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
4119
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
4120
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
4121
- ] }) }, item.label)) }),
4122
- state.adjacentKindCounts.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
4123
- /* @__PURE__ */ jsx(
4124
- Divider,
4125
- {
4126
- label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
4127
- /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
4128
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Nearby kinds" })
4129
- ] }),
4130
- labelPosition: "center"
4131
- }
4132
- ),
4133
- /* @__PURE__ */ jsx(Group, { gap: "xs", children: state.adjacentKindCounts.map((item) => /* @__PURE__ */ jsxs(Badge, { variant: "light", color: getNodeKindColor(item.kind), children: [
4134
- item.count,
4135
- " ",
4136
- item.label
4137
- ] }, item.kind)) })
4138
- ] }) : null,
4139
- state.state === "edge" ? /* @__PURE__ */ jsxs(Fragment, { children: [
4140
- /* @__PURE__ */ jsx(
4141
- Divider,
4142
- {
4143
- label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
4144
- /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
4145
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Endpoints" })
4146
- ] }),
4147
- labelPosition: "center"
4148
- }
4149
- ),
4150
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
4151
- /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
4152
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Source" }),
4153
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4154
- /* @__PURE__ */ jsx(Text, { fw: 700, children: state.sourceNode?.label ?? state.edge.sourceId }),
4155
- /* @__PURE__ */ jsx(
4156
- Badge,
4157
- {
4158
- size: "xs",
4159
- variant: "light",
4160
- color: state.sourceNode ? getNodeKindColor(state.sourceNode.kind) : "gray",
4161
- children: state.sourceNode ? getNodeKindLabel2(state.sourceNode.kind) : "unresolved"
4162
- }
4163
- )
4164
- ] })
4165
- ] }) }),
4166
- /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
4167
- /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Target" }),
4168
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
4169
- /* @__PURE__ */ jsx(Text, { fw: 700, children: state.targetNode?.label ?? state.edge.targetId }),
4170
- /* @__PURE__ */ jsx(
4171
- Badge,
4172
- {
4173
- size: "xs",
4174
- variant: "light",
4175
- color: state.targetNode ? getNodeKindColor(state.targetNode.kind) : "gray",
4176
- children: state.targetNode ? getNodeKindLabel2(state.targetNode.kind) : "unresolved"
4177
- }
4178
- )
4179
- ] })
4180
- ] }) })
4181
- ] })
4182
- ] }) : null,
4183
- /* @__PURE__ */ jsx(
4184
- Divider,
4185
- {
4186
- label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding nodes" : "Direct nodes" }),
4187
- labelPosition: "center"
4188
- }
4189
- ),
4190
- state.relatedNodes.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.relatedNodes.map((item) => /* @__PURE__ */ jsx(RelatedItemCard, { item, itemType: "node" }, item.id)) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No nearby nodes were found in the current graph selection." }),
4191
- /* @__PURE__ */ jsx(
4192
- Divider,
4193
- {
4194
- label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding edges" : "Direct edges" }),
4195
- labelPosition: "center"
4196
- }
4197
- ),
4198
- state.relatedEdges.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: state.relatedEdges.map((item) => /* @__PURE__ */ jsx(RelatedItemCard, { item, itemType: "edge" }, item.id)) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No adjacent edges were found for the current selection." })
4199
- ] }) });
4200
- }
4201
-
4202
- // src/features/operations/organization-graph/types.ts
4203
- var ORGANIZATION_GRAPH_NODE_KIND_ORDER = [
4204
- "organization",
4205
- "feature",
4206
- "surface",
4207
- "entity",
4208
- "capability",
4209
- "resource",
4210
- "knowledge"
4211
- ];
4212
- var ORGANIZATION_GRAPH_NODE_KIND_LABELS = {
4213
- organization: "Organization",
4214
- feature: "Feature",
4215
- surface: "Surface",
4216
- entity: "Entity",
4217
- capability: "Capability",
4218
- resource: "Resource",
4219
- knowledge: "Knowledge"
4220
- };
4221
- var DEFAULT_ORGANIZATION_GRAPH_FILTERS = {
4222
- search: "",
4223
- nodeKinds: [],
4224
- topologyPresence: "all",
4225
- environmentStatus: "all",
4226
- resourceTypes: [],
4227
- showIntegrations: true,
4228
- domainFilters: {}
4229
- };
4230
-
4231
- // src/features/operations/organization-graph/helpers.ts
4232
- var TOPLOGY_EDGE_TYPES = /* @__PURE__ */ new Set(["maps_to", "triggers", "uses", "approval"]);
4233
- function getCommandViewNodes(data) {
4234
- return [
4235
- ...data.agents,
4236
- ...data.workflows,
4237
- ...data.triggers,
4238
- ...data.integrations,
4239
- ...data.externalResources,
4240
- ...data.humanCheckpoints
4241
- ];
4242
- }
4243
- function getCommandViewNodeForGraphNode(node, commandViewData) {
4244
- if (!commandViewData || node.kind !== "resource" || !node.sourceId) {
4245
- return null;
4246
- }
4247
- return getCommandViewNodes(commandViewData).find((item) => item.resourceId === node.sourceId) ?? null;
4248
- }
4249
- function normalizeText(value) {
4250
- return value.trim().toLowerCase();
4251
- }
4252
- function includesQuery(value, query) {
4253
- if (!value) return false;
4254
- return normalizeText(value).includes(query);
4255
- }
4256
- function titleCase3(value) {
4257
- return value.replace(/_/g, " ").split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
4258
- }
4259
- function isTopologyEdge(edge) {
4260
- return TOPLOGY_EDGE_TYPES.has(edge.kind) || Boolean(edge.relationshipType);
4261
- }
4262
- function isSemanticEdge(edge) {
4263
- return !isTopologyEdge(edge);
4264
- }
4265
- function getIncidentEdges(graph, nodeId) {
4266
- return graph.edges.filter((edge) => edge.sourceId === nodeId || edge.targetId === nodeId);
4267
- }
4268
- function createOrganizationGraphFilters(partial) {
4269
- return {
4270
- search: partial?.search ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.search,
4271
- nodeKinds: partial?.nodeKinds ? [...partial.nodeKinds] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.nodeKinds],
4272
- topologyPresence: partial?.topologyPresence ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.topologyPresence,
4273
- environmentStatus: partial?.environmentStatus ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.environmentStatus,
4274
- resourceTypes: partial?.resourceTypes ? [...partial.resourceTypes] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.resourceTypes],
4275
- showIntegrations: partial?.showIntegrations ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.showIntegrations,
4276
- domainFilters: partial?.domainFilters ? { ...partial.domainFilters } : { ...DEFAULT_ORGANIZATION_GRAPH_FILTERS.domainFilters }
4277
- };
4278
- }
4279
- function normalizeOrganizationGraphSearch(search) {
4280
- return search.trim().toLowerCase();
4281
- }
4282
- function getOrganizationGraphNodePresence(node, incidentEdges) {
4283
- if (node.kind === "resource") {
4284
- const relevantEdges = incidentEdges.filter((edge) => edge.kind !== "contains");
4285
- const hasTopologyEdges2 = relevantEdges.some(isTopologyEdge);
4286
- const hasSemanticEdges2 = relevantEdges.some(isSemanticEdge);
4287
- if (hasTopologyEdges2 && hasSemanticEdges2) {
4288
- return "bridge";
4289
- }
4290
- if (hasTopologyEdges2) {
4291
- return "topology-only";
4292
- }
4293
- return "semantic-only";
4294
- }
4295
- const hasTopologyEdges = incidentEdges.some(isTopologyEdge);
4296
- const hasSemanticEdges = incidentEdges.some(isSemanticEdge);
4297
- if (hasTopologyEdges && hasSemanticEdges) {
4298
- return "bridge";
4299
- }
4300
- if (hasTopologyEdges) {
4301
- return "topology-only";
4302
- }
4303
- return "semantic-only";
4304
- }
4305
- function getOrganizationGraphNodePresenceMap(graph) {
4306
- const presenceByNodeId = /* @__PURE__ */ new Map();
4307
- for (const node of graph.nodes) {
4308
- presenceByNodeId.set(node.id, getOrganizationGraphNodePresence(node, getIncidentEdges(graph, node.id)));
4309
- }
4310
- return presenceByNodeId;
4311
- }
4312
- function getOrganizationGraphNodeKindOptions(kinds = ORGANIZATION_GRAPH_NODE_KIND_ORDER) {
4313
- return kinds.map((kind) => ({
4314
- kind,
4315
- label: ORGANIZATION_GRAPH_NODE_KIND_LABELS[kind]
4316
- }));
4317
- }
4318
- function getOrganizationGraphResourceTypeOptions(resourceTypes = [
4319
- "workflow",
4320
- "agent",
4321
- "trigger",
4322
- "integration",
4323
- "external",
4324
- "human_checkpoint"
4325
- ]) {
4326
- return resourceTypes.map((resourceType) => ({
4327
- resourceType,
4328
- label: titleCase3(resourceType)
4329
- }));
4330
- }
4331
- function getNodeStatus(node, commandViewData) {
4332
- const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
4333
- if (commandViewNode) {
4334
- return commandViewNode.status;
4335
- }
4336
- return "status" in node && typeof node.status === "string" ? node.status : void 0;
4337
- }
4338
- function getExplicitNodeFacets(node, commandViewData) {
4339
- const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
4340
- if (commandViewNode) {
4341
- return [
4342
- ...commandViewNode.category ? [`category:${commandViewNode.category}`] : [],
4343
- ...commandViewNode.links?.map((link) => link.nodeId) ?? []
4344
- ];
4345
- }
4346
- return [];
4347
- }
4348
- function getNodeFacets(graph, node, commandViewData) {
4349
- const explicitFacets = getExplicitNodeFacets(node, commandViewData);
4350
- if (explicitFacets.length > 0) {
4351
- return explicitFacets;
4352
- }
4353
- if (node.kind === "feature") {
4354
- return node.sourceId ? [node.sourceId] : [];
4355
- }
4356
- if (node.kind !== "resource") {
4357
- return [];
4358
- }
4359
- const facetIds = /* @__PURE__ */ new Set();
4360
- for (const edge of graph.edges) {
4361
- if (edge.sourceId !== node.id) {
4362
- continue;
4363
- }
4364
- const targetNode = graph.nodes.find((candidate) => candidate.id === edge.targetId);
4365
- if (targetNode?.kind === "feature" && targetNode.sourceId) {
4366
- facetIds.add(targetNode.id);
4367
- }
4368
- }
4369
- return [...facetIds];
4370
- }
4371
- function matchesOrganizationGraphNodeSearch(node, search) {
4372
- const query = normalizeOrganizationGraphSearch(search);
4373
- if (!query) return true;
4374
- const nodeStatus = getNodeStatus(node);
4375
- const nodeFacets = getExplicitNodeFacets(node);
4376
- return includesQuery(node.id, query) || includesQuery(node.label, query) || includesQuery(node.description, query) || includesQuery(node.sourceId, query) || includesQuery(node.featureId, query) || includesQuery(node.resourceType, query) || includesQuery(nodeStatus, query) || nodeFacets.some((facet) => includesQuery(facet, query)) || includesQuery(node.kind, query);
4377
- }
4378
- function matchesOrganizationGraphEdgeSearch(edge, graph, search) {
4379
- const query = normalizeOrganizationGraphSearch(search);
4380
- if (!query) return true;
4381
- const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
4382
- const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
4383
- return includesQuery(edge.id, query) || includesQuery(edge.label, query) || includesQuery(edge.kind, query) || includesQuery(edge.relationshipType, query) || includesQuery(sourceNode?.label, query) || includesQuery(sourceNode?.sourceId, query) || includesQuery(targetNode?.label, query) || includesQuery(targetNode?.sourceId, query);
4384
- }
4385
- function matchesTopologyPresence(nodePresence, topologyPresence) {
4386
- if (topologyPresence === "all") return true;
4387
- return nodePresence === topologyPresence;
4388
- }
4389
- function hasActiveDomainFilters(domainFilters) {
4390
- return Object.values(domainFilters).some((filterState) => filterState !== "neutral");
4391
- }
4392
- function matchesDomainFilters(graph, node, domainFilters, commandViewData) {
4393
- if (!hasActiveDomainFilters(domainFilters)) {
4394
- return true;
4395
- }
4396
- const includedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "include").map(([domainId]) => domainId);
4397
- const excludedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "exclude").map(([domainId]) => domainId);
4398
- const nodeFacets = getNodeFacets(graph, node, commandViewData);
4399
- if (excludedDomains.length > 0 && nodeFacets.some((domainId) => excludedDomains.includes(domainId))) {
4400
- return false;
4401
- }
4402
- if (includedDomains.length > 0 && !nodeFacets.some((domainId) => includedDomains.includes(domainId))) {
4403
- return false;
4404
- }
4405
- return true;
4406
- }
4407
- function matchesEnvironmentStatus(node, environmentStatus, commandViewData) {
4408
- if (environmentStatus === "all") {
4409
- return true;
4410
- }
4411
- const nodeStatus = getNodeStatus(node, commandViewData);
4412
- if (!nodeStatus) {
4413
- return true;
4414
- }
4415
- return nodeStatus === environmentStatus;
4416
- }
4417
- function matchesResourceTypeFilters(node, resourceTypes) {
4418
- if (node.kind !== "resource" || resourceTypes.length === 0) {
4419
- return true;
4420
- }
4421
- return Boolean(node.resourceType && resourceTypes.includes(node.resourceType));
4422
- }
4423
- function matchesIntegrationVisibility(node, showIntegrations) {
4424
- if (showIntegrations) {
4425
- return true;
4426
- }
4427
- return !(node.kind === "resource" && node.resourceType === "integration");
4428
- }
4429
- function filterOrganizationGraph(graph, filters, options) {
4430
- const normalizedFilters = createOrganizationGraphFilters(filters);
4431
- const normalizedSearch = normalizeOrganizationGraphSearch(normalizedFilters.search);
4432
- const nodePresenceMap = getOrganizationGraphNodePresenceMap(graph);
4433
- const selectedKinds = new Set(normalizedFilters.nodeKinds);
4434
- const commandViewData = options?.commandViewData;
4435
- const visibleNodeIds = /* @__PURE__ */ new Set();
4436
- for (const node of graph.nodes) {
4437
- if (selectedKinds.size > 0 && !selectedKinds.has(node.kind)) {
4438
- continue;
4439
- }
4440
- if (!matchesIntegrationVisibility(node, normalizedFilters.showIntegrations)) {
4441
- continue;
4442
- }
4443
- if (!matchesResourceTypeFilters(node, normalizedFilters.resourceTypes)) {
4444
- continue;
4445
- }
4446
- if (!matchesEnvironmentStatus(node, normalizedFilters.environmentStatus, commandViewData)) {
4447
- continue;
4448
- }
4449
- if (!matchesDomainFilters(graph, node, normalizedFilters.domainFilters, commandViewData)) {
4450
- continue;
4451
- }
4452
- const presence = nodePresenceMap.get(node.id) ?? "semantic-only";
4453
- if (!matchesTopologyPresence(presence, normalizedFilters.topologyPresence)) {
4454
- continue;
4455
- }
4456
- if (normalizedSearch && !matchesOrganizationGraphNodeSearch(node, normalizedSearch)) {
4457
- const incidentEdges = getIncidentEdges(graph, node.id);
4458
- const edgeMatch = incidentEdges.some((edge) => matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch));
4459
- if (!edgeMatch) {
4460
- continue;
4461
- }
4462
- }
4463
- visibleNodeIds.add(node.id);
4464
- }
4465
- const visibleEdges = graph.edges.filter((edge) => {
4466
- const sourceVisible = visibleNodeIds.has(edge.sourceId);
4467
- const targetVisible = visibleNodeIds.has(edge.targetId);
4468
- if (!sourceVisible || !targetVisible) {
4469
- return false;
4470
- }
4471
- if (normalizedSearch && !matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch)) {
4472
- const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
4473
- const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
4474
- const nodeSearchMatch = Boolean(sourceNode && matchesOrganizationGraphNodeSearch(sourceNode, normalizedSearch)) || Boolean(targetNode && matchesOrganizationGraphNodeSearch(targetNode, normalizedSearch));
4475
- if (!nodeSearchMatch) {
4476
- return false;
4477
- }
4478
- }
4479
- return true;
4480
- });
4481
- return {
4482
- ...graph,
4483
- nodes: graph.nodes.filter((node) => visibleNodeIds.has(node.id)),
4484
- edges: visibleEdges
4485
- };
4486
- }
4487
- function getCommandViewResourceCategory(node, commandViewData) {
4488
- return getCommandViewNodeForGraphNode(node, commandViewData)?.category ?? null;
4489
- }
4490
- function getConnectedHiddenResourceIds(graph, nodeId, hiddenIds) {
4491
- if (!nodeId) {
4492
- return /* @__PURE__ */ new Set();
4493
- }
4494
- const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
4495
- const connectedIds = /* @__PURE__ */ new Set();
4496
- for (const edge of graph.edges) {
4497
- const neighborId = edge.sourceId === nodeId ? edge.targetId : edge.targetId === nodeId ? edge.sourceId : null;
4498
- if (!neighborId || !hiddenIds.has(neighborId)) {
4499
- continue;
4500
- }
4501
- if (nodesById.get(neighborId)?.kind === "resource") {
4502
- connectedIds.add(neighborId);
4503
- }
4504
- }
4505
- return connectedIds;
4506
- }
4507
- function getCommandViewVisibilityProjection({
4508
- graph,
4509
- commandViewData,
4510
- resourcesHidden,
4511
- diagnosticsHidden,
4512
- diagnosticCategories,
4513
- revealedIds = /* @__PURE__ */ new Set(),
4514
- mode
4515
- }) {
4516
- const hiddenIds = /* @__PURE__ */ new Set();
4517
- const hiddenEdgeIds = /* @__PURE__ */ new Set();
4518
- const diagnosticCategorySet = new Set(diagnosticCategories);
4519
- let totalResourceCount = 0;
4520
- let hiddenDiagnosticResourceCount = 0;
4521
- if (mode === "trace" || mode === "impact") {
4522
- const resourceCount = graph.nodes.filter((node) => node.kind === "resource").length;
4523
- return {
4524
- hiddenIds,
4525
- hiddenEdgeIds,
4526
- totalResourceCount: resourceCount,
4527
- visibleResourceCount: resourceCount,
4528
- hiddenResourceCount: 0,
4529
- hiddenDiagnosticResourceCount: 0
4530
- };
4531
- }
4532
- for (const node of graph.nodes) {
4533
- if (node.kind !== "resource") {
4534
- continue;
4535
- }
4536
- totalResourceCount += 1;
4537
- const category = getCommandViewResourceCategory(node, commandViewData);
4538
- const isDiagnostic = Boolean(category && diagnosticCategorySet.has(category));
4539
- if (isDiagnostic && diagnosticsHidden) {
4540
- hiddenDiagnosticResourceCount += 1;
4541
- }
4542
- if (revealedIds.has(node.id)) {
4543
- continue;
4544
- }
4545
- if (resourcesHidden || diagnosticsHidden && isDiagnostic) {
4546
- hiddenIds.add(node.id);
4547
- }
4548
- }
4549
- for (const edge of graph.edges) {
4550
- if (hiddenIds.has(edge.sourceId) || hiddenIds.has(edge.targetId)) {
4551
- hiddenEdgeIds.add(edge.id);
4552
- }
4553
- }
4554
- const hiddenResourceCount = hiddenIds.size;
4555
- return {
4556
- hiddenIds,
4557
- hiddenEdgeIds,
4558
- totalResourceCount,
4559
- visibleResourceCount: totalResourceCount - hiddenResourceCount,
4560
- hiddenResourceCount,
4561
- hiddenDiagnosticResourceCount
4562
- };
4563
- }
4564
- function isOrganizationGraphFilterPristine(filters) {
4565
- return normalizeOrganizationGraphSearch(filters.search) === "" && filters.nodeKinds.length === 0 && filters.topologyPresence === DEFAULT_ORGANIZATION_GRAPH_FILTERS.topologyPresence && filters.environmentStatus === DEFAULT_ORGANIZATION_GRAPH_FILTERS.environmentStatus && filters.resourceTypes.length === 0 && filters.showIntegrations === DEFAULT_ORGANIZATION_GRAPH_FILTERS.showIntegrations && !hasActiveDomainFilters(filters.domainFilters);
4566
- }
4567
- var TOPOLOGY_PRESENCE_OPTIONS = [
4568
- { label: "All", value: "all" },
4569
- { label: "Semantic only", value: "semantic-only" },
4570
- { label: "Topology only", value: "topology-only" }
4571
- ];
4572
- var ENVIRONMENT_STATUS_OPTIONS = [
4573
- { label: "All", value: "all" },
4574
- { label: "Prod", value: "prod" },
4575
- { label: "Dev", value: "dev" }
4576
- ];
4577
- function OrganizationGraphFilterToolbar({
4578
- value,
4579
- onChange,
4580
- availableKinds,
4581
- disabled = false,
4582
- searchPlaceholder = "Search nodes, relationships, or IDs",
4583
- kindLabel = "Node kinds",
4584
- resourceTypeLabel = "Resource types",
4585
- topologyLabel = "Relationship presence",
4586
- environmentLabel = "Environment",
4587
- showIntegrationsLabel = "Show integrations",
4588
- resetLabel = "Reset filters",
4589
- resetValue = createOrganizationGraphFilters()
4590
- }) {
4591
- const kindOptions = getOrganizationGraphNodeKindOptions(availableKinds);
4592
- const resourceTypeOptions = getOrganizationGraphResourceTypeOptions();
4593
- const canReset = !isOrganizationGraphFilterPristine(value);
4594
- return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
4595
- /* @__PURE__ */ jsx(
4596
- TextInput,
4597
- {
4598
- label: "Search",
4599
- placeholder: searchPlaceholder,
4600
- value: value.search,
4601
- onChange: (event) => onChange({
4602
- ...value,
4603
- search: event.currentTarget.value
4604
- }),
4605
- leftSection: /* @__PURE__ */ jsx(IconSearch, { size: 14 }),
4606
- disabled
4607
- }
4608
- ),
4609
- /* @__PURE__ */ jsx(
4610
- MultiSelect,
4611
- {
4612
- label: kindLabel,
4613
- placeholder: "All kinds",
4614
- data: kindOptions.map((option) => ({ value: option.kind, label: option.label })),
4615
- value: value.nodeKinds,
4616
- onChange: (nodeKinds) => onChange({
4617
- ...value,
4618
- nodeKinds
4619
- }),
4620
- searchable: true,
4621
- clearable: true,
4622
- disabled
4623
- }
4624
- ),
4625
- /* @__PURE__ */ jsx(
4626
- MultiSelect,
4627
- {
4628
- label: resourceTypeLabel,
4629
- placeholder: "All resource types",
4630
- data: resourceTypeOptions.map((option) => ({ value: option.resourceType, label: option.label })),
4631
- value: value.resourceTypes,
4632
- onChange: (resourceTypes) => onChange({
4633
- ...value,
4634
- resourceTypes
4635
- }),
4636
- searchable: true,
4637
- clearable: true,
4638
- disabled
4639
- }
4640
- ),
4641
- /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
4642
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: topologyLabel }),
4643
- /* @__PURE__ */ jsx(
4644
- SegmentedControl,
4645
- {
4646
- value: value.topologyPresence,
4647
- onChange: (topologyPresence) => onChange({
4648
- ...value,
4649
- topologyPresence
4650
- }),
4651
- data: TOPOLOGY_PRESENCE_OPTIONS,
4652
- size: "sm",
4653
- fullWidth: true,
4654
- disabled
4655
- }
4656
- )
4657
- ] }),
4658
- /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
4659
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: environmentLabel }),
4660
- /* @__PURE__ */ jsx(
4661
- SegmentedControl,
4662
- {
4663
- value: value.environmentStatus,
4664
- onChange: (environmentStatus) => onChange({
4665
- ...value,
4666
- environmentStatus
4667
- }),
4668
- data: ENVIRONMENT_STATUS_OPTIONS,
4669
- size: "sm",
4670
- fullWidth: true,
4671
- disabled
4672
- }
4673
- )
4674
- ] }),
4675
- /* @__PURE__ */ jsx(
4676
- Switch,
4677
- {
4678
- label: showIntegrationsLabel,
4679
- description: "Hide integration resources and their relationship edges.",
4680
- checked: value.showIntegrations,
4681
- onChange: (event) => onChange({
4682
- ...value,
4683
- showIntegrations: event.currentTarget.checked
4684
- }),
4685
- size: "sm",
4686
- disabled
4687
- }
4688
- ),
4689
- /* @__PURE__ */ jsx(Group, { justify: "flex-end", children: /* @__PURE__ */ jsx(
4690
- Button,
4691
- {
4692
- variant: "subtle",
4693
- leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
4694
- onClick: () => onChange(resetValue),
4695
- disabled: disabled || !canReset,
4696
- children: resetLabel
4697
- }
4698
- ) })
4699
- ] });
4700
- }
4701
- var useOrganizationGraphFiltersStore = create((set) => ({
4702
- filtersByScope: {},
4703
- initializeScope: (scope, initialFilters) => set((state) => {
4704
- if (state.filtersByScope[scope]) {
4705
- return state;
4706
- }
4707
- return {
4708
- filtersByScope: {
4709
- ...state.filtersByScope,
4710
- [scope]: createOrganizationGraphFilters(initialFilters)
4711
- }
4712
- };
4713
- }),
4714
- updateScope: (scope, next) => set((state) => ({
4715
- filtersByScope: {
4716
- ...state.filtersByScope,
4717
- [scope]: createOrganizationGraphFilters({
4718
- ...state.filtersByScope[scope],
4719
- ...next
4720
- })
4721
- }
4722
- })),
4723
- resetScope: (scope, initialFilters) => set((state) => ({
4724
- filtersByScope: {
4725
- ...state.filtersByScope,
4726
- [scope]: createOrganizationGraphFilters(initialFilters)
4727
- }
4728
- }))
4729
- }));
4730
- function getOrganizationGraphFilterScope(initialFilters) {
4731
- return JSON.stringify(createOrganizationGraphFilters(initialFilters));
4732
- }
4733
- function useOrganizationGraphFilters(initialFilters) {
4734
- const scopeRef = useRef(getOrganizationGraphFilterScope(initialFilters));
4735
- const fallbackFiltersRef = useRef(createOrganizationGraphFilters(initialFilters));
4736
- const filters = useOrganizationGraphFiltersStore(
4737
- (state) => state.filtersByScope[scopeRef.current] ?? fallbackFiltersRef.current
4738
- );
4739
- const initializeScope = useOrganizationGraphFiltersStore((state) => state.initializeScope);
4740
- const updateScope = useOrganizationGraphFiltersStore((state) => state.updateScope);
4741
- const resetScope = useOrganizationGraphFiltersStore((state) => state.resetScope);
4742
- useEffect(() => {
4743
- initializeScope(scopeRef.current, initialFilters);
4744
- }, [initialFilters, initializeScope]);
4745
- const updateFilters = (next) => {
4746
- updateScope(scopeRef.current, next);
4747
- };
4748
- const setSearch = (search) => {
4749
- updateFilters({ search });
4750
- };
4751
- const setNodeKinds = (nodeKinds) => {
4752
- updateFilters({ nodeKinds });
4753
- };
4754
- const setTopologyPresence = (topologyPresence) => {
4755
- updateFilters({ topologyPresence });
4756
- };
4757
- const resetFilters = () => {
4758
- resetScope(scopeRef.current, initialFilters);
4759
- };
4760
- return {
4761
- filters,
4762
- setSearch,
4763
- setNodeKinds,
4764
- setTopologyPresence,
4765
- resetFilters,
4766
- updateFilters
4767
- };
4768
- }
4769
-
4770
- // src/features/operations/organization-graph/lenses.ts
4771
- var COMMAND_VIEW_NODE_KINDS = [
4772
- "organization",
4773
- "feature",
4774
- "surface",
4775
- "entity",
4776
- "capability",
4777
- "resource"
4778
- ];
4779
- function getOrganizationGraphLensConfig(lens) {
4780
- if (lens === "command-view") {
4781
- return {
4782
- title: "Command View",
4783
- caption: "Operations lens backed by the shared organization graph. This preset focuses the graph on bridged runtime resources and their operational relationships.",
4784
- initialMode: "map",
4785
- initialFilters: {
4786
- nodeKinds: COMMAND_VIEW_NODE_KINDS,
4787
- topologyPresence: "all"
4788
- },
4789
- filterSummary: "Command View lens keeps the organization structure visible while resource visibility is controlled progressively."
4790
- };
4791
- }
4792
- return {
4793
- title: "Organization Graph",
4794
- caption: "Cytoscape-based shared graph surface built from the organization model and bridged Command View topology.",
4795
- initialMode: "map",
4796
- filterSummary: "Filter by node kind, semantic-vs-topology presence, and free-text search across nodes and relationships."
4797
- };
4798
- }
4799
-
4800
- // src/features/operations/organization-graph/commandViewOperationalSummary.ts
4801
- function toPercentage(numerator, denominator) {
4802
- if (denominator <= 0) return null;
4803
- return numerator / denominator * 100;
4804
- }
4805
- function formatPercent(value) {
4806
- return value == null ? "N/A" : `${Math.round(value)}%`;
4807
- }
4808
- function formatTimestamp(value) {
4809
- if (!value) return "N/A";
4810
- return new Intl.DateTimeFormat("en-US", {
4811
- month: "short",
4812
- day: "numeric",
4813
- hour: "numeric",
4814
- minute: "2-digit"
4815
- }).format(new Date(value));
4816
- }
4817
- function getCommandViewNodes2(data) {
4818
- return [
4819
- ...data.agents,
4820
- ...data.workflows,
4821
- ...data.triggers,
4822
- ...data.integrations,
4823
- ...data.externalResources,
4824
- ...data.humanCheckpoints
4825
- ];
4826
- }
4827
- function getNodeByResourceId(data, resourceId) {
4828
- return getCommandViewNodes2(data).find((node) => node.resourceId === resourceId) ?? null;
4829
- }
4830
- function getCommandViewOperationalOverview(data, stats) {
4831
- if (!stats) {
4832
- return null;
4833
- }
4834
- const resourceEntries = Object.entries(stats.resources);
4835
- const humanEntries = Object.entries(stats.humanCheckpoints);
4836
- const totalRuns = resourceEntries.reduce((sum, [, item]) => sum + item.totalRuns, 0);
4837
- const successCount = resourceEntries.reduce((sum, [, item]) => sum + item.successCount, 0);
4838
- const failureCount = resourceEntries.reduce((sum, [, item]) => sum + item.failureCount, 0);
4839
- const warningCount = resourceEntries.reduce((sum, [, item]) => sum + item.warningCount, 0);
4840
- const pendingApprovals = humanEntries.reduce((sum, [, item]) => sum + item.pendingCount, 0);
4841
- const activeHumanCheckpoints = humanEntries.filter(([, item]) => item.pendingCount > 0).length;
4842
- const topFailingResources = resourceEntries.map(([resourceId, item]) => ({
4843
- id: resourceId,
4844
- label: data ? getNodeByResourceId(data, resourceId)?.name ?? resourceId : resourceId,
4845
- failureCount: item.failureCount,
4846
- warningCount: item.warningCount
4847
- })).filter((item) => item.failureCount > 0 || item.warningCount > 0).sort((left, right) => {
4848
- if (right.failureCount !== left.failureCount) {
4849
- return right.failureCount - left.failureCount;
4850
- }
4851
- if (right.warningCount !== left.warningCount) {
4852
- return right.warningCount - left.warningCount;
4853
- }
4854
- return left.label.localeCompare(right.label);
4855
- }).slice(0, 3);
4856
- return {
4857
- totalRuns,
4858
- successCount,
4859
- failureCount,
4860
- warningCount,
4861
- successRate: toPercentage(successCount, totalRuns),
4862
- trackedResources: resourceEntries.length,
4863
- pendingApprovals,
4864
- activeHumanCheckpoints,
4865
- topFailingResources,
4866
- timeRange: stats.timeRange,
4867
- generatedAt: stats.generatedAt
4868
- };
4869
- }
4870
- function buildResourceSelectionSummary(node, stats) {
4871
- const successRate = toPercentage(stats.successCount, stats.totalRuns);
4872
- const metadata = [
4873
- { label: "Operational Type", value: node.type },
4874
- { label: "Environment", value: node.status.toUpperCase() },
4875
- { label: "Version", value: node.version },
4876
- { label: "Origin", value: node.origin ? node.origin : "local" }
4877
- ];
4878
- if (node.category) {
4879
- metadata.push({ label: "Category", value: node.category });
4880
- }
4881
- if (node.links?.length) {
4882
- metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
4883
- }
4884
- if (node.type === "agent") {
4885
- metadata.push({ label: "Model", value: `${node.modelProvider}/${node.modelId}` });
4886
- metadata.push({ label: "Tools", value: String(node.toolCount) });
4887
- metadata.push({ label: "Memory", value: node.hasMemory ? "Enabled" : "Disabled" });
4888
- }
4889
- if (node.type === "workflow") {
4890
- metadata.push({ label: "Entry Point", value: node.entryPoint });
4891
- metadata.push({ label: "Steps", value: String(node.stepCount) });
4892
- }
4893
- if (node.type === "integration") {
4894
- metadata.push({ label: "Provider", value: node.provider });
4895
- metadata.push({ label: "Credential", value: node.credentialName });
4896
- }
4897
- if (node.type === "trigger") {
4898
- metadata.push({ label: "Trigger Type", value: node.triggerType });
4899
- }
4900
- if (node.type === "external") {
4901
- metadata.push({ label: "Platform", value: node.platform });
4902
- }
4903
- return {
4904
- title: "Operational Summary",
4905
- description: "Execution telemetry for this resource inside the Command View lens.",
4906
- metrics: [
4907
- { label: "Runs", value: String(stats.totalRuns), hint: "Total tracked executions in the selected time range" },
4908
- { label: "Success rate", value: formatPercent(successRate), hint: "Completed and warning runs as a percentage of all runs" },
4909
- { label: "Failures", value: String(stats.failureCount), hint: "Runs that ended in a failed state" },
4910
- { label: "Warnings", value: String(stats.warningCount), hint: "Completed runs that surfaced warnings" }
4911
- ],
4912
- metadata: [...metadata, { label: "Last Run", value: formatTimestamp(stats.lastRunAt) }]
4913
- };
4914
- }
4915
- function buildHumanSelectionSummary(node, stats) {
4916
- const metadata = [
4917
- { label: "Operational Type", value: "human checkpoint" },
4918
- { label: "Environment", value: node.status.toUpperCase() },
4919
- { label: "Version", value: node.version },
4920
- { label: "Origin", value: node.origin ? node.origin : "local" }
4921
- ];
4922
- if (node.category) {
4923
- metadata.push({ label: "Category", value: node.category });
4924
- }
4925
- if (node.links?.length) {
4926
- metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
4927
- }
4928
- return {
4929
- title: "Approval Queue Summary",
4930
- description: "Human checkpoint activity for the current Command View lens.",
4931
- metrics: [
4932
- { label: "Pending", value: String(stats.pendingCount), hint: "Tasks currently waiting on a decision" },
4933
- { label: "Completed", value: String(stats.completedCount), hint: "Tasks completed in the selected time range" },
4934
- { label: "Expired", value: String(stats.expiredCount), hint: "Tasks that expired before resolution" }
4935
- ],
4936
- metadata: [...metadata, { label: "Last Decision", value: formatTimestamp(stats.lastDecisionAt) }]
4937
- };
4938
- }
4939
- function getCommandViewSelectionOperationalSummary(data, stats, selectedElement) {
4940
- if (!data || !stats || !selectedElement || selectedElement.type !== "node") {
4941
- return null;
4942
- }
4943
- if (!selectedElement.id.startsWith("resource:")) {
4944
- return null;
4945
- }
4946
- const resourceId = selectedElement.id.slice("resource:".length);
4947
- const node = getNodeByResourceId(data, resourceId);
4948
- if (!node) {
4949
- return null;
4950
- }
4951
- if (node.type === "human") {
4952
- const checkpointStats = stats.humanCheckpoints[resourceId];
4953
- return checkpointStats ? buildHumanSelectionSummary(node, checkpointStats) : null;
4954
- }
4955
- const resourceStats = stats.resources[resourceId];
4956
- return resourceStats ? buildResourceSelectionSummary(node, resourceStats) : null;
4957
- }
4958
- function formatRelativeTime3(date) {
4959
- if (!date) return "N/A";
4960
- const dateObj = typeof date === "string" ? new Date(date) : date;
4961
- return formatDistanceToNow(dateObj, { addSuffix: true });
4962
- }
4963
-
4964
- // src/hooks/operations/command-view/utils/mergeStatsWithTopology.ts
4965
- function mergeStatsWithTopology(topology, stats) {
4966
- return {
4967
- ...topology,
4968
- agents: topology.agents.map((agent) => ({
4969
- ...agent,
4970
- stats: stats.resources[agent.resourceId] || null
4971
- })),
4972
- workflows: topology.workflows.map((workflow) => ({
4973
- ...workflow,
4974
- stats: stats.resources[workflow.resourceId] || null
4975
- })),
4976
- humanCheckpoints: topology.humanCheckpoints.map((checkpoint) => ({
4977
- ...checkpoint,
4978
- stats: stats.humanCheckpoints[checkpoint.resourceId] || null
4979
- }))
4980
- };
4981
- }
4982
-
4983
- // src/features/operations/organization-graph/commandViewDrillDown.ts
4984
- function titleCase4(value) {
4985
- return value.replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
4986
- }
4987
- function getResourceHref(resourceType, resourceId) {
4988
- if (resourceType === "agent") {
4989
- return `/operations/resources/agent/${resourceId}`;
4990
- }
4991
- if (resourceType === "workflow") {
4992
- return `/operations/resources/workflow/${resourceId}`;
4993
- }
4994
- if (resourceType === "human_checkpoint") {
4995
- return `/operations/command-queue?checkpoint=${resourceId}`;
4996
- }
4997
- return null;
4998
- }
4999
- function getExecutionBadgeColor(status) {
5000
- switch (status) {
5001
- case "failed":
5002
- return "red";
5003
- case "warning":
5004
- return "yellow";
5005
- case "running":
5006
- return "blue";
5007
- case "completed":
5008
- return "green";
5009
- case "pending":
5010
- default:
5011
- return "gray";
5012
- }
5013
- }
5014
- function getTaskBadgeColor(status) {
5015
- switch (status) {
5016
- case "pending":
5017
- return "orange";
5018
- case "processing":
5019
- return "blue";
5020
- case "completed":
5021
- return "green";
5022
- case "failed":
5023
- return "red";
5024
- case "expired":
5025
- default:
5026
- return "gray";
5027
- }
5028
- }
5029
- function getExecutionDescription(execution) {
5030
- if (execution.errorMessage) {
5031
- return execution.errorMessage;
5032
- }
5033
- if (execution.status === "running") {
5034
- return "Currently running";
5035
- }
5036
- if (execution.status === "warning") {
5037
- return "Completed with warnings";
5038
- }
5039
- if (execution.status === "completed") {
5040
- return "Completed successfully";
5041
- }
5042
- return titleCase4(execution.status);
5043
- }
5044
- function getTaskDescription(task) {
5045
- if (task.description) {
5046
- return task.description;
5047
- }
5048
- if (task.humanCheckpoint) {
5049
- return `Checkpoint: ${task.humanCheckpoint}`;
5050
- }
5051
- return "Pending approval task";
5052
- }
5053
- function buildCommandViewDrillDownSections({
5054
- node,
5055
- timeRange,
5056
- executions,
5057
- checkpointTasks
5058
- }) {
5059
- if (!node || node.kind !== "resource" || !node.sourceId || !node.resourceType) {
5060
- return [];
5061
- }
5062
- const sections = [];
5063
- const resourceHref = getResourceHref(node.resourceType, node.sourceId);
5064
- if ((node.resourceType === "agent" || node.resourceType === "workflow") && executions) {
5065
- sections.push({
5066
- title: "Recent executions",
5067
- description: `Latest runs for this ${titleCase4(node.resourceType)} in the ${timeRange} window.`,
5068
- emptyMessage: `No executions were recorded for this ${titleCase4(node.resourceType).toLowerCase()} in the current window.`,
5069
- primaryAction: resourceHref ? {
5070
- label: "Open resource",
5071
- href: resourceHref
5072
- } : void 0,
5073
- items: executions.map((execution) => ({
5074
- id: execution.executionId,
5075
- label: execution.executionId,
5076
- href: `${resourceHref ?? "#"}?exec=${execution.executionId}`,
5077
- description: getExecutionDescription(execution),
5078
- badgeLabel: execution.status,
5079
- badgeColor: getExecutionBadgeColor(execution.status),
5080
- meta: `Started ${formatRelativeTime3(execution.startedAt)}`
5081
- }))
5082
- });
5083
- }
5084
- if (node.resourceType === "human_checkpoint" && checkpointTasks) {
5085
- sections.push({
5086
- title: "Pending tasks",
5087
- description: "Human approval tasks waiting on this checkpoint.",
5088
- emptyMessage: "No pending tasks are currently assigned to this checkpoint.",
5089
- primaryAction: resourceHref ? {
5090
- label: "Open queue",
5091
- href: resourceHref
5092
- } : void 0,
5093
- items: checkpointTasks.map((task) => ({
5094
- id: task.id,
5095
- label: task.description ?? task.id,
5096
- href: `/operations/command-queue?task=${task.id}`,
5097
- description: getTaskDescription(task),
5098
- badgeLabel: task.status,
5099
- badgeColor: getTaskBadgeColor(task.status),
5100
- meta: `Created ${formatRelativeTime3(task.createdAt)}`
5101
- }))
5102
- });
5103
- }
5104
- return sections;
5105
- }
5106
-
5107
- // src/features/operations/organization-graph/path-tracing/trace.ts
5108
- var NODE_KIND_ORDER = {
5109
- organization: 0,
5110
- feature: 1,
5111
- surface: 2,
5112
- capability: 3,
5113
- entity: 4,
5114
- resource: 5,
5115
- knowledge: 6
5116
- };
5117
- var NODE_KIND_LABEL = {
5118
- organization: "Organization",
5119
- feature: "Feature",
5120
- surface: "Surface",
5121
- capability: "Capability",
5122
- entity: "Entity",
5123
- resource: "Resource",
5124
- knowledge: "Knowledge"
5125
- };
5126
- function getNodeLabel(node) {
5127
- return node.label || node.sourceId || node.id;
5128
- }
5129
- function compareTraceNodes(a, b) {
5130
- const kindDelta = NODE_KIND_ORDER[a.kind] - NODE_KIND_ORDER[b.kind];
5131
- if (kindDelta !== 0) {
5132
- return kindDelta;
5133
- }
5134
- const labelDelta = getNodeLabel(a).localeCompare(getNodeLabel(b));
5135
- if (labelDelta !== 0) {
5136
- return labelDelta;
5137
- }
5138
- return a.id.localeCompare(b.id);
5139
- }
5140
- function buildMissingNodeMessage(selection, missingNodeIds) {
5141
- if (missingNodeIds.length === 0) {
5142
- return "The selected trace is not available.";
5143
- }
5144
- if (missingNodeIds.length === 1) {
5145
- const missingId = missingNodeIds[0];
5146
- return `Graph node "${missingId}" is not available.`;
5147
- }
5148
- return `Graph nodes "${selection.sourceId}" and "${selection.targetId}" are not available.`;
5149
- }
5150
- function buildPathNotFoundMessage(source, target) {
5151
- return `No directed path found from "${source.label}" to "${target.label}".`;
5152
- }
5153
- function buildOrganizationGraphTraceIndex(graph) {
5154
- const nodesById = /* @__PURE__ */ new Map();
5155
- const edgesById = /* @__PURE__ */ new Map();
5156
- const outgoingEdgesByNodeId = /* @__PURE__ */ new Map();
5157
- const incomingEdgesByNodeId = /* @__PURE__ */ new Map();
5158
- for (const node of graph.nodes) {
5159
- nodesById.set(node.id, node);
5160
- outgoingEdgesByNodeId.set(node.id, []);
5161
- incomingEdgesByNodeId.set(node.id, []);
5162
- }
5163
- for (const edge of graph.edges) {
5164
- edgesById.set(edge.id, edge);
5165
- const outgoingEdges = outgoingEdgesByNodeId.get(edge.sourceId);
5166
- if (outgoingEdges) {
5167
- outgoingEdges.push(edge);
5168
- }
5169
- const incomingEdges = incomingEdgesByNodeId.get(edge.targetId);
5170
- if (incomingEdges) {
5171
- incomingEdges.push(edge);
5172
- }
5173
- }
5174
- return {
5175
- nodesById,
5176
- edgesById,
5177
- outgoingEdgesByNodeId,
5178
- incomingEdgesByNodeId
5179
- };
5180
- }
5181
- function getOrganizationGraphTraceNodeKindLabel(kind) {
5182
- return NODE_KIND_LABEL[kind];
5183
- }
5184
- function formatOrganizationGraphTraceNodeOptionLabel(option) {
5185
- return `${option.label} \xB7 ${getOrganizationGraphTraceNodeKindLabel(option.kind)}`;
5186
- }
5187
- function getOrganizationGraphTraceNodeOptions(graph) {
5188
- return [...graph.nodes].sort(compareTraceNodes).map((node) => ({
5189
- id: node.id,
5190
- label: getNodeLabel(node),
5191
- kind: node.kind,
5192
- sourceId: node.sourceId,
5193
- description: node.description,
5194
- enabled: node.enabled
5195
- }));
5196
- }
5197
- function resolveOrganizationGraphPathTrace(graph, selection) {
5198
- const index = buildOrganizationGraphTraceIndex(graph);
5199
- const source = selection.sourceId ? index.nodesById.get(selection.sourceId) ?? null : null;
5200
- const target = selection.targetId ? index.nodesById.get(selection.targetId) ?? null : null;
5201
- const missingNodeIds = [
5202
- selection.sourceId && !source ? selection.sourceId : null,
5203
- selection.targetId && !target ? selection.targetId : null
5204
- ].filter((value) => Boolean(value));
5205
- if (!selection.sourceId && !selection.targetId) {
5206
- return {
5207
- status: "idle",
5208
- selection,
5209
- source,
5210
- target,
5211
- missingNodeIds: [],
5212
- pathNodes: [],
5213
- pathEdges: [],
5214
- highlightNodeIds: [],
5215
- highlightEdgeIds: [],
5216
- distance: 0,
5217
- message: "Select a source and target to trace a path."
5218
- };
5219
- }
5220
- if (!selection.sourceId || !selection.targetId) {
5221
- return {
5222
- status: "incomplete",
5223
- selection,
5224
- source,
5225
- target,
5226
- missingNodeIds,
5227
- pathNodes: [],
5228
- pathEdges: [],
5229
- highlightNodeIds: [],
5230
- highlightEdgeIds: [],
5231
- distance: 0,
5232
- message: "Select both a source and a target to resolve a path."
5233
- };
5234
- }
5235
- if (missingNodeIds.length > 0 || !source || !target) {
5236
- return {
5237
- status: "missing-node",
5238
- selection,
5239
- source,
5240
- target,
5241
- missingNodeIds,
5242
- pathNodes: [],
5243
- pathEdges: [],
5244
- highlightNodeIds: [],
5245
- highlightEdgeIds: [],
5246
- distance: 0,
5247
- message: buildMissingNodeMessage(selection, missingNodeIds)
5248
- };
5249
- }
5250
- if (source.id === target.id) {
5251
- return {
5252
- status: "found",
5253
- selection,
5254
- source,
5255
- target,
5256
- missingNodeIds: [],
5257
- pathNodes: [source],
5258
- pathEdges: [],
5259
- highlightNodeIds: [source.id],
5260
- highlightEdgeIds: [],
5261
- distance: 0,
5262
- message: `Source and target already point to "${source.label}".`
5263
- };
5264
- }
5265
- const visitedNodeIds = /* @__PURE__ */ new Set([source.id]);
5266
- const predecessorByNodeId = /* @__PURE__ */ new Map();
5267
- const queue = [source.id];
5268
- while (queue.length > 0) {
5269
- const currentNodeId = queue.shift();
5270
- if (!currentNodeId) {
5271
- continue;
5272
- }
5273
- const outgoingEdges = index.outgoingEdgesByNodeId.get(currentNodeId) ?? [];
5274
- for (const edge of outgoingEdges) {
5275
- if (visitedNodeIds.has(edge.targetId)) {
5276
- continue;
5277
- }
5278
- visitedNodeIds.add(edge.targetId);
5279
- predecessorByNodeId.set(edge.targetId, {
5280
- nodeId: currentNodeId,
5281
- edgeId: edge.id
5282
- });
5283
- if (edge.targetId === target.id) {
5284
- queue.length = 0;
5285
- break;
5286
- }
5287
- queue.push(edge.targetId);
5288
- }
5289
- }
5290
- if (!predecessorByNodeId.has(target.id)) {
5291
- return {
5292
- status: "not-found",
5293
- selection,
5294
- source,
5295
- target,
5296
- missingNodeIds: [],
5297
- pathNodes: [],
5298
- pathEdges: [],
5299
- highlightNodeIds: [],
5300
- highlightEdgeIds: [],
5301
- distance: 0,
5302
- message: buildPathNotFoundMessage(source, target)
5303
- };
5304
- }
5305
- const pathNodes = [target];
5306
- const pathEdges = [];
5307
- let cursorNodeId = target.id;
5308
- while (cursorNodeId !== source.id) {
5309
- const predecessor = predecessorByNodeId.get(cursorNodeId);
5310
- if (!predecessor) {
5311
- break;
5312
- }
5313
- const edge = index.edgesById.get(predecessor.edgeId);
5314
- const previousNode = index.nodesById.get(predecessor.nodeId);
5315
- if (edge) {
5316
- pathEdges.push(edge);
5317
- }
5318
- if (previousNode) {
5319
- pathNodes.push(previousNode);
5320
- }
5321
- cursorNodeId = predecessor.nodeId;
5322
- }
5323
- pathNodes.reverse();
5324
- pathEdges.reverse();
5325
- return {
5326
- status: "found",
5327
- selection,
5328
- source,
5329
- target,
5330
- missingNodeIds: [],
5331
- pathNodes,
5332
- pathEdges,
5333
- highlightNodeIds: pathNodes.map((node) => node.id),
5334
- highlightEdgeIds: pathEdges.map((edge) => edge.id),
5335
- distance: pathEdges.length,
5336
- message: `Path found from "${source.label}" to "${target.label}" across ${pathEdges.length} edge${pathEdges.length === 1 ? "" : "s"}.`
5337
- };
5338
- }
5339
-
5340
- // src/features/operations/organization-graph/expand-around/expandAroundGraph.ts
5341
- var DEFAULT_MAX_DEPTH = 1;
5342
- var DEFAULT_MAX_RESULTS = 25;
5343
- var ORG_MODEL_ROOT_KINDS = /* @__PURE__ */ new Set([
5344
- "feature",
5345
- "surface",
5346
- "entity",
5347
- "capability"
5348
- ]);
5349
- var PRESET_EDGE_KINDS = {
5350
- coverage: ["contains", "exposes", "operates-on", "maps_to", "references"],
5351
- "operational-dependencies": ["references"],
5352
- "org-context": ["contains", "exposes", "operates-on", "maps_to"],
5353
- "impact-path": ["references"]
5354
- };
5355
- var PRESET_RELATIONSHIP_TYPES = {
5356
- "operational-dependencies": ["triggers", "uses", "approval"],
5357
- "impact-path": ["triggers", "uses", "approval"]
5358
- };
5359
- var PRESET_DIRECTIONS = {
5360
- coverage: "both",
5361
- "operational-dependencies": "both",
5362
- "org-context": "both",
5363
- "impact-path": "both"
5364
- };
5365
- function toSet(values) {
5366
- if (!values || values.length === 0) {
5367
- return null;
5368
- }
5369
- return new Set(values);
5370
- }
5371
- function clampMaxDepth(maxDepth) {
5372
- if (maxDepth === 2 || maxDepth === 3) {
5373
- return maxDepth;
5374
- }
5375
- return 1;
5376
- }
5377
- function resolvePreset(rootNode, preset) {
5378
- if (preset) {
5379
- return preset;
5380
- }
5381
- if (!rootNode) {
5382
- return null;
5383
- }
5384
- if (ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
5385
- return "coverage";
5386
- }
5387
- if (rootNode.kind === "resource") {
5388
- return "operational-dependencies";
5389
- }
5390
- return null;
5391
- }
5392
- function resolveRequest(rootNode, request) {
5393
- const preset = resolvePreset(rootNode, request.preset);
5394
- const maxResults = request.maxResults === void 0 || !Number.isFinite(request.maxResults) ? DEFAULT_MAX_RESULTS : Math.max(0, request.maxResults);
5395
- return {
5396
- rootNodeId: request.rootNodeId,
5397
- direction: request.direction ?? (preset ? PRESET_DIRECTIONS[preset] : "both"),
5398
- maxDepth: clampMaxDepth(request.maxDepth ?? DEFAULT_MAX_DEPTH),
5399
- maxResults,
5400
- edgeKinds: toSet(request.edgeKinds ?? (preset ? PRESET_EDGE_KINDS[preset] : void 0)),
5401
- relationshipTypes: toSet(
5402
- request.relationshipTypes ?? (preset ? PRESET_RELATIONSHIP_TYPES[preset] : void 0)
5403
- ),
5404
- preset,
5405
- nodeKinds: toSet(request.nodeKinds),
5406
- resourceTypes: toSet(request.resourceTypes),
5407
- includeHiddenResources: request.includeHiddenResources ?? false
5408
- };
5409
- }
5410
- function getOppositeNodeId(edge, currentNodeId) {
5411
- if (edge.sourceId === currentNodeId) {
5412
- return edge.targetId;
5413
- }
5414
- if (edge.targetId === currentNodeId) {
5415
- return edge.sourceId;
5416
- }
5417
- return null;
5418
- }
5419
- function getCandidateEdges(index, nodeId, direction) {
5420
- if (direction === "outgoing") {
5421
- return index.outgoingEdgesByNodeId.get(nodeId) ?? [];
5422
- }
5423
- if (direction === "incoming") {
5424
- return index.incomingEdgesByNodeId.get(nodeId) ?? [];
5425
- }
5426
- const seenEdgeIds = /* @__PURE__ */ new Set();
5427
- const edges = [];
5428
- for (const edge of [
5429
- ...index.outgoingEdgesByNodeId.get(nodeId) ?? [],
5430
- ...index.incomingEdgesByNodeId.get(nodeId) ?? []
5431
- ]) {
5432
- if (seenEdgeIds.has(edge.id)) {
5433
- continue;
5434
- }
5435
- seenEdgeIds.add(edge.id);
5436
- edges.push(edge);
5437
- }
5438
- return edges;
5439
- }
5440
- function matchesPresetTraversalDirection(edge, currentNodeId, request) {
5441
- if (request.preset === "coverage" && (edge.kind === "contains" || edge.kind === "exposes")) {
5442
- return edge.sourceId === currentNodeId;
5443
- }
5444
- return true;
5445
- }
5446
- function matchesEdgeFilters(edge, currentNodeId, request) {
5447
- if (request.edgeKinds && !request.edgeKinds.has(edge.kind)) {
5448
- return false;
5449
- }
5450
- if (request.relationshipTypes && (!edge.relationshipType || !request.relationshipTypes.has(edge.relationshipType))) {
5451
- return false;
5452
- }
5453
- return matchesPresetTraversalDirection(edge, currentNodeId, request);
5454
- }
5455
- function matchesNodeFilters(node, request) {
5456
- if (request.nodeKinds && !request.nodeKinds.has(node.kind)) {
5457
- return false;
5458
- }
5459
- if (request.resourceTypes) {
5460
- if (node.kind !== "resource") {
5461
- return false;
5462
- }
5463
- if (!node.resourceType || !request.resourceTypes.has(node.resourceType)) {
5464
- return false;
5465
- }
5466
- }
5467
- return true;
5468
- }
5469
- function pluralize(count, singular, plural = `${singular}s`) {
5470
- return `${count} ${count === 1 ? singular : plural}`;
5471
- }
5472
- function getNodeDisplayName(node) {
5473
- return node.label || node.sourceId || node.id;
5474
- }
5475
- function buildSummaryMessages(input) {
5476
- const { rootNode, preset, expandedNodes, counts, truncated } = input;
5477
- if (!rootNode) {
5478
- return ["Select an available node to expand around."];
5479
- }
5480
- if (!preset && rootNode.kind === "organization") {
5481
- return ["Choose a feature, surface, capability, entity, or resource before expanding."];
5482
- }
5483
- if (expandedNodes.length === 0) {
5484
- return [`No matching graph context found around "${getNodeDisplayName(rootNode)}".`];
5485
- }
5486
- const resourceCount = expandedNodes.filter((node) => node.kind === "resource").length;
5487
- const semanticContextCount = expandedNodes.length - resourceCount;
5488
- const rootLabel = getNodeDisplayName(rootNode);
5489
- const messages = [];
5490
- if (preset === "coverage" && ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
5491
- if (resourceCount > 0 && semanticContextCount > 0) {
5492
- messages.push(
5493
- `${pluralize(resourceCount, "resource")} and ${pluralize(
5494
- semanticContextCount,
5495
- "semantic context node"
5496
- )} support "${rootLabel}".`
5497
- );
5498
- } else if (resourceCount > 0) {
5499
- messages.push(`${pluralize(resourceCount, "resource")} support "${rootLabel}".`);
5500
- } else {
5501
- messages.push(
5502
- `${pluralize(semanticContextCount, "semantic context node")} found around "${rootLabel}"; no mapped resources matched this coverage preset.`
5503
- );
5504
- }
5505
- } else if (preset === "operational-dependencies") {
5506
- messages.push(`${pluralize(resourceCount, "operational dependency resource")} found around "${rootLabel}".`);
5507
- } else if (preset === "org-context") {
5508
- messages.push(`${pluralize(expandedNodes.length, "semantic context node")} found around "${rootLabel}".`);
5509
- } else if (preset === "impact-path") {
5510
- messages.push(`${pluralize(resourceCount, "resource")} can call or be affected by "${rootLabel}".`);
5511
- } else {
5512
- messages.push(`${pluralize(expandedNodes.length, "node")} found around "${rootLabel}".`);
5513
- }
5514
- if (counts.hiddenResourceNodes > 0) {
5515
- messages.push(`${pluralize(counts.hiddenResourceNodes, "hidden resource")} matched current visibility settings.`);
5516
- }
5517
- if (counts.alreadyVisibleNodes > 0) {
5518
- messages.push(`${pluralize(counts.alreadyVisibleNodes, "node")} already visible in the graph.`);
5519
- }
5520
- if (truncated) {
5521
- messages.push(`Results were limited to ${pluralize(expandedNodes.length, "node")}.`);
5522
- }
5523
- return messages;
5524
- }
5525
- function expandAroundGraph(graph, request, options = {}) {
5526
- const index = buildOrganizationGraphTraceIndex(graph);
5527
- const rootNode = index.nodesById.get(request.rootNodeId) ?? null;
5528
- const resolved = resolveRequest(rootNode, request);
5529
- const alreadyVisibleNodeIds = new Set(options.alreadyVisibleNodeIds ?? []);
5530
- const hiddenResourceNodeIds = new Set(options.hiddenResourceNodeIds ?? []);
5531
- const expandedNodeIds = /* @__PURE__ */ new Set();
5532
- const expandedEdgeIds = /* @__PURE__ */ new Set();
5533
- const frontierNodeIds = /* @__PURE__ */ new Set();
5534
- const visitedDepthByNodeId = /* @__PURE__ */ new Map([[resolved.rootNodeId, 0]]);
5535
- const hasExplicitTraversalFilter = Boolean(
5536
- request.preset || request.edgeKinds?.length || request.relationshipTypes?.length || request.nodeKinds?.length || request.resourceTypes?.length
5537
- );
5538
- const queue = rootNode && (resolved.preset || hasExplicitTraversalFilter) ? [{ nodeId: rootNode.id, depth: 0 }] : [];
5539
- let truncated = false;
5540
- for (let queueIndex = 0; queueIndex < queue.length; queueIndex += 1) {
5541
- const current = queue[queueIndex];
5542
- if (current.depth >= resolved.maxDepth) {
5543
- if (current.nodeId !== resolved.rootNodeId) {
5544
- frontierNodeIds.add(current.nodeId);
5545
- }
5546
- continue;
5547
- }
5548
- for (const edge of getCandidateEdges(index, current.nodeId, resolved.direction)) {
5549
- if (!matchesEdgeFilters(edge, current.nodeId, resolved)) {
5550
- continue;
5551
- }
5552
- const nextNodeId = getOppositeNodeId(edge, current.nodeId);
5553
- if (!nextNodeId) {
5554
- continue;
5555
- }
5556
- const nextNode = index.nodesById.get(nextNodeId);
5557
- if (!nextNode || !matchesNodeFilters(nextNode, resolved)) {
5558
- continue;
5559
- }
5560
- if (!resolved.includeHiddenResources && hiddenResourceNodeIds.has(nextNode.id)) {
5561
- continue;
5562
- }
5563
- const nextDepth = current.depth + 1;
5564
- const previousDepth = visitedDepthByNodeId.get(nextNode.id);
5565
- if (previousDepth !== void 0) {
5566
- if (nextNode.id === resolved.rootNodeId || expandedNodeIds.has(nextNode.id)) {
5567
- expandedEdgeIds.add(edge.id);
5568
- }
5569
- continue;
5570
- }
5571
- if (expandedNodeIds.size >= resolved.maxResults) {
5572
- truncated = true;
5573
- frontierNodeIds.add(nextNode.id);
5574
- continue;
5575
- }
5576
- visitedDepthByNodeId.set(nextNode.id, nextDepth);
5577
- expandedNodeIds.add(nextNode.id);
5578
- expandedEdgeIds.add(edge.id);
5579
- if (nextDepth >= resolved.maxDepth) {
5580
- frontierNodeIds.add(nextNode.id);
5581
- continue;
5582
- }
5583
- queue.push({ nodeId: nextNode.id, depth: nextDepth });
5584
- }
5585
- }
5586
- const expandedNodes = [...expandedNodeIds].map((nodeId) => index.nodesById.get(nodeId)).filter((node) => Boolean(node));
5587
- const hiddenResourceNodes = expandedNodes.filter((node) => hiddenResourceNodeIds.has(node.id)).length;
5588
- const alreadyVisibleNodes = expandedNodes.filter((node) => alreadyVisibleNodeIds.has(node.id)).length;
5589
- const newNodes = expandedNodes.filter(
5590
- (node) => !hiddenResourceNodeIds.has(node.id) && !alreadyVisibleNodeIds.has(node.id)
5591
- ).length;
5592
- const counts = {
5593
- newNodes,
5594
- newEdges: expandedEdgeIds.size,
5595
- alreadyVisibleNodes,
5596
- hiddenResourceNodes
5597
- };
5598
- const summaryMessages = buildSummaryMessages({
5599
- rootNode,
5600
- preset: resolved.preset,
5601
- expandedNodes,
5602
- counts,
5603
- truncated
5604
- });
5605
- return {
5606
- rootNodeId: request.rootNodeId,
5607
- rootNode,
5608
- preset: resolved.preset,
5609
- direction: resolved.direction,
5610
- maxDepth: resolved.maxDepth,
5611
- maxResults: resolved.maxResults,
5612
- expandedNodeIds: [...expandedNodeIds],
5613
- expandedEdgeIds: [...expandedEdgeIds],
5614
- frontierNodeIds: [...frontierNodeIds].filter((nodeId) => nodeId !== resolved.rootNodeId),
5615
- truncated,
5616
- counts,
5617
- summaryMessages,
5618
- message: summaryMessages[0] ?? ""
5619
- };
5620
- }
5621
- var PRESET_OPTIONS = [
5622
- { value: "coverage", label: "Coverage" },
5623
- { value: "operational-dependencies", label: "Operational dependencies" },
5624
- { value: "org-context", label: "Org context" },
5625
- { value: "impact-path", label: "Impact path" }
5626
- ];
5627
- var DIRECTION_OPTIONS = [
5628
- { value: "both", label: "Both" },
5629
- { value: "outgoing", label: "Outgoing" },
5630
- { value: "incoming", label: "Incoming" }
5631
- ];
5632
- var EDGE_KIND_OPTIONS = [
5633
- { value: "contains", label: "Containment" },
5634
- { value: "references", label: "References" },
5635
- { value: "exposes", label: "Exposes" },
5636
- { value: "maps_to", label: "Maps to" },
5637
- { value: "operates-on", label: "Operates on" },
5638
- { value: "uses", label: "Uses" }
5639
- ];
5640
- var RELATIONSHIP_OPTIONS = [
5641
- { value: "triggers", label: "Triggers" },
5642
- { value: "uses", label: "Uses" },
5643
- { value: "approval", label: "Approval" }
5644
- ];
5645
- var RESOURCE_TYPE_OPTIONS = [
5646
- { value: "workflow", label: "Workflow" },
5647
- { value: "agent", label: "Agent" },
5648
- { value: "trigger", label: "Trigger" },
5649
- { value: "integration", label: "Integration" },
5650
- { value: "external", label: "External" },
5651
- { value: "human_checkpoint", label: "Human checkpoint" }
5652
- ];
5653
- function updateValue(value, key, nextValue, onChange) {
5654
- onChange({
5655
- ...value,
5656
- [key]: nextValue
5657
- });
5658
- }
5659
- function toOptionalArray(values) {
5660
- return values.length > 0 ? values : void 0;
5661
- }
5662
- function toMaxDepth(value) {
5663
- const numeric = typeof value === "number" ? value : Number.parseInt(value, 10);
5664
- if (numeric === 3) return 3;
5665
- if (numeric === 2) return 2;
5666
- return 1;
5667
- }
5668
- function ExpandAroundPanel({
5669
- selectedNode,
5670
- value,
5671
- result,
5672
- appliedNodeCount,
5673
- appliedEdgeCount,
5674
- onChange,
5675
- onPreview,
5676
- onApply,
5677
- onClear
5678
- }) {
5679
- const disabled = !selectedNode;
5680
- const canApply = Boolean(result && result.expandedNodeIds.length > 0);
5681
- const rootIsTooBroad = selectedNode?.kind === "organization" && !value.preset;
5682
- return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
5683
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "wrap", children: [
5684
- /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
5685
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 800, children: "Expand Around" }),
5686
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode ? `Preview typed graph context around ${selectedNode.label}.` : "Select a graph node to preview nearby operational context." })
5687
- ] }),
5688
- appliedNodeCount > 0 || appliedEdgeCount > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
5689
- appliedNodeCount,
5690
- " nodes / ",
5691
- appliedEdgeCount,
5692
- " edges applied"
5693
- ] }) : null
5694
- ] }),
5695
- /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
5696
- /* @__PURE__ */ jsx(
5697
- Select,
5698
- {
5699
- label: "Preset",
5700
- placeholder: "Auto",
5701
- data: PRESET_OPTIONS,
5702
- value: value.preset ?? null,
5703
- onChange: (preset) => updateValue(value, "preset", preset ?? void 0, onChange),
5704
- disabled,
5705
- clearable: true
5706
- }
5707
- ),
5708
- /* @__PURE__ */ jsx(
5709
- Select,
5710
- {
5711
- label: "Direction",
5712
- data: DIRECTION_OPTIONS,
5713
- value: value.direction ?? "both",
5714
- onChange: (direction) => updateValue(value, "direction", direction ?? "both", onChange),
5715
- disabled
5716
- }
5717
- ),
5718
- /* @__PURE__ */ jsx(
5719
- NumberInput,
5720
- {
5721
- label: "Depth",
5722
- min: 1,
5723
- max: 3,
5724
- value: value.maxDepth ?? 1,
5725
- onChange: (maxDepth) => updateValue(value, "maxDepth", toMaxDepth(maxDepth), onChange),
5726
- disabled
5727
- }
5728
- ),
5729
- /* @__PURE__ */ jsx(
5730
- NumberInput,
5731
- {
5732
- label: "Max results",
5733
- min: 1,
5734
- max: 100,
5735
- value: value.maxResults ?? 25,
5736
- onChange: (maxResults) => updateValue(
5737
- value,
5738
- "maxResults",
5739
- Math.max(1, typeof maxResults === "number" ? maxResults : Number.parseInt(maxResults, 10) || 25),
5740
- onChange
5741
- ),
5742
- disabled
5743
- }
5744
- )
5745
- ] }),
5746
- /* @__PURE__ */ jsx(
5747
- MultiSelect,
5748
- {
5749
- label: "Relationship filters",
5750
- placeholder: "Preset defaults",
5751
- data: RELATIONSHIP_OPTIONS,
5752
- value: value.relationshipTypes ?? [],
5753
- onChange: (relationshipTypes) => updateValue(value, "relationshipTypes", toOptionalArray(relationshipTypes), onChange),
5754
- disabled,
5755
- clearable: true
5756
- }
5757
- ),
5758
- /* @__PURE__ */ jsx(
5759
- MultiSelect,
5760
- {
5761
- label: "Edge kind filters",
5762
- placeholder: "Preset defaults",
5763
- data: EDGE_KIND_OPTIONS,
5764
- value: value.edgeKinds ?? [],
5765
- onChange: (edgeKinds) => updateValue(value, "edgeKinds", toOptionalArray(edgeKinds), onChange),
5766
- disabled,
5767
- clearable: true
5768
- }
5769
- ),
5770
- /* @__PURE__ */ jsx(
5771
- MultiSelect,
5772
- {
5773
- label: "Resource type filters",
5774
- placeholder: "All resource types",
5775
- data: RESOURCE_TYPE_OPTIONS,
5776
- value: value.resourceTypes ?? [],
5777
- onChange: (resourceTypes) => updateValue(value, "resourceTypes", toOptionalArray(resourceTypes), onChange),
5778
- disabled,
5779
- clearable: true
5780
- }
5781
- ),
5782
- /* @__PURE__ */ jsx(
5783
- Switch,
5784
- {
5785
- label: "Include hidden resources",
5786
- checked: value.includeHiddenResources ?? true,
5787
- onChange: (event) => updateValue(value, "includeHiddenResources", event.currentTarget.checked, onChange),
5788
- disabled
5789
- }
5790
- ),
5791
- rootIsTooBroad ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "orange", children: "The organization root is broad. Choose a narrower node or a semantic preset before previewing." }) : null,
5792
- result ? /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
5793
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
5794
- /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
5795
- result.counts.newNodes,
5796
- " new"
5797
- ] }),
5798
- /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
5799
- result.counts.alreadyVisibleNodes,
5800
- " visible"
5801
- ] }),
5802
- /* @__PURE__ */ jsxs(Badge, { variant: "light", color: result.counts.hiddenResourceNodes > 0 ? "orange" : "gray", children: [
5803
- result.counts.hiddenResourceNodes,
5804
- " hidden"
5805
- ] }),
5806
- result.truncated ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", children: "Truncated" }) : null
5807
- ] }),
5808
- result.summaryMessages.map((message) => /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: message }, message))
5809
- ] }) }) : null,
5810
- /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "wrap", children: [
5811
- /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5812
- /* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: onPreview, disabled: disabled || rootIsTooBroad, children: "Preview" }),
5813
- /* @__PURE__ */ jsx(Button, { size: "xs", onClick: onApply, disabled: !canApply, children: "Apply" })
5814
- ] }),
5815
- /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClear, disabled: !result && appliedNodeCount === 0, children: "Clear expansion" })
5816
- ] })
5817
- ] }) });
5818
- }
5819
- var cellStyle = {
5820
- padding: "var(--mantine-spacing-sm) var(--mantine-spacing-md)",
5821
- display: "flex",
5822
- alignItems: "center",
5823
- gap: "var(--mantine-spacing-sm)",
5824
- minWidth: 0
5825
- };
5826
- function CommandViewHealthStrip({
5827
- overview,
5828
- hotspots,
5829
- visibleResources,
5830
- hiddenResources = 0,
5831
- resourcesHidden,
5832
- selectedLabel,
5833
- onFocusHotspot,
5834
- onResourcesHiddenChange,
5835
- onResetFocus
5836
- }) {
5837
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
5838
- /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
5839
- /* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
5840
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
5841
- /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
5842
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
5843
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
5844
- /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
5845
- ] }),
5846
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
5847
- ] }),
5848
- /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
5849
- /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
5850
- hotspots.length > 0 ? /* @__PURE__ */ jsx(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0, overflow: "hidden" }, children: hotspots.map((hotspot) => /* @__PURE__ */ jsx(Group, { gap: 4, wrap: "nowrap", children: /* @__PURE__ */ jsx(
5851
- Badge,
5852
- {
5853
- variant: "light",
5854
- color: "red",
5855
- size: "xs",
5856
- style: { cursor: "pointer", flexShrink: 0 },
5857
- onClick: () => onFocusHotspot(hotspot.resourceId),
5858
- children: hotspot.label
5859
- }
5860
- ) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
5861
- ] }),
5862
- /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
5863
- /* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
5864
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
5865
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
5866
- "pending / ",
5867
- overview?.activeHumanCheckpoints ?? 0,
5868
- " queues"
5869
- ] })
5870
- ] }),
5871
- /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
5872
- /* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
5873
- /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
5874
- /* @__PURE__ */ jsx(
5875
- Button,
5876
- {
5877
- size: "compact-xs",
5878
- variant: resourcesHidden ? "light" : "subtle",
5879
- onClick: () => onResourcesHiddenChange(!resourcesHidden),
5880
- style: { flexShrink: 0 },
5881
- children: resourcesHidden ? "Show resources" : "Hide resources"
5882
- }
5883
- ),
5884
- /* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
5885
- ] })
5886
- ] });
5887
- }
5888
- var FILTER_STATE_ICONS2 = {
5889
- neutral: IconCircleDashed,
5890
- include: IconCircleCheck,
5891
- exclude: IconCircleX
5892
- };
5893
- var FILTER_STATE_COLORS2 = {
5894
- neutral: "var(--color-text-dimmed)",
5895
- include: "var(--mantine-color-green-6)",
5896
- exclude: "var(--mantine-color-red-6)"
5897
- };
5898
- var FILTER_STATE_LABELS2 = {
5899
- neutral: "Not filtered",
5900
- include: "Include only",
5901
- exclude: "Exclude"
5902
- };
5903
- function getCommandViewResources(commandViewData) {
5904
- if (!commandViewData) {
5905
- return [];
5906
- }
5907
- return [
5908
- ...commandViewData.agents,
5909
- ...commandViewData.workflows,
5910
- ...commandViewData.triggers,
5911
- ...commandViewData.integrations,
5912
- ...commandViewData.externalResources,
5913
- ...commandViewData.humanCheckpoints
5914
- ];
5915
- }
5916
- function nextDomainFilterState(current) {
5917
- if (current === "neutral") return "include";
5918
- if (current === "include") return "exclude";
5919
- return "neutral";
5920
- }
5921
- function FilterPanel({
5922
- filters,
5923
- onChangeFilters,
5924
- resetValue,
5925
- disabled = false,
5926
- commandViewData,
5927
- lens,
5928
- resourcesHidden,
5929
- diagnosticsHidden,
5930
- onResourcesHiddenChange,
5931
- onDiagnosticsHiddenChange,
5932
- onRevealResources,
5933
- onResetFilters,
5934
- visibilityCounts,
5935
- graph,
5936
- baseGraph,
5937
- layout = "grid"
5938
- }) {
5939
- const resourceFacets = collectResourceFilterFacets(getCommandViewResources(commandViewData));
5940
- const Section = ({ children }) => layout === "stack" ? /* @__PURE__ */ jsx(
5941
- Stack,
5942
- {
5943
- gap: "sm",
5944
- pb: "sm",
5945
- style: {
5946
- borderBottom: "1px solid var(--color-border)"
5947
- },
5948
- children
5949
- }
5950
- ) : /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", style: { background: "var(--color-surface)" }, children });
5951
- const updateDomainFilter = (domainId) => {
5952
- const current = filters.domainFilters[domainId] ?? "neutral";
5953
- onChangeFilters({
5954
- ...filters,
5955
- domainFilters: {
5956
- ...filters.domainFilters,
5957
- [domainId]: nextDomainFilterState(current)
5958
- }
5959
- });
5960
- };
5961
- const handleResourceVisibilityAction = () => {
5962
- if (resourcesHidden) {
5963
- onRevealResources();
5964
- return;
5965
- }
5966
- onResourcesHiddenChange(true);
5967
- };
5968
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
5969
- /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
5970
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Filters" }),
5971
- /* @__PURE__ */ jsx(
5972
- OrganizationGraphFilterToolbar,
5973
- {
5974
- value: filters,
5975
- onChange: onChangeFilters,
5976
- disabled,
5977
- resetValue
5978
- }
5979
- )
5980
- ] }) }),
5981
- /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
5982
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
5983
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Visibility" }),
5984
- /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
5985
- visibilityCounts.visibleResourceCount,
5986
- "/",
5987
- visibilityCounts.totalResourceCount,
5988
- " resources"
5989
- ] })
5990
- ] }),
5991
- lens === "command-view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
5992
- /* @__PURE__ */ jsx(
5993
- Checkbox,
5994
- {
5995
- label: "Hide resource nodes",
5996
- description: "Keep the organization structure readable and reveal resource nodes as needed.",
5997
- checked: resourcesHidden,
5998
- onChange: (event) => onResourcesHiddenChange(event.currentTarget.checked),
5999
- disabled
6000
- }
6001
- ),
6002
- /* @__PURE__ */ jsx(
6003
- Checkbox,
6004
- {
6005
- label: "Hide diagnostic and testing resources",
6006
- description: "Diagnostics stay available through filters, trace, impact, and contextual reveal.",
6007
- checked: diagnosticsHidden,
6008
- onChange: (event) => onDiagnosticsHiddenChange(event.currentTarget.checked),
6009
- disabled
6010
- }
6011
- ),
6012
- /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
6013
- /* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenResourceCount > 0 ? "yellow" : "green", children: [
6014
- visibilityCounts.hiddenResourceCount,
6015
- " hidden"
6016
- ] }),
6017
- /* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenDiagnosticResourceCount > 0 ? "yellow" : "gray", children: [
6018
- visibilityCounts.hiddenDiagnosticResourceCount,
6019
- " diagnostic/testing"
6020
- ] })
6021
- ] }),
6022
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
6023
- /* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: handleResourceVisibilityAction, disabled, children: resourcesHidden ? "Reveal resources" : "Hide resources" }),
6024
- /* @__PURE__ */ jsx(
6025
- Button,
6026
- {
6027
- size: "xs",
6028
- variant: "subtle",
6029
- leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
6030
- onClick: onResetFilters,
6031
- disabled,
6032
- children: "Reset filters"
6033
- }
6034
- )
6035
- ] })
6036
- ] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Visibility controls are available in the Command View lens." })
6037
- ] }) }),
6038
- /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
6039
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Resource Facets" }),
6040
- resourceFacets.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: resourceFacets.map((facet) => {
6041
- const filterState = filters.domainFilters[facet.id] ?? "neutral";
6042
- const StateIcon = FILTER_STATE_ICONS2[filterState];
6043
- return /* @__PURE__ */ jsx(
6044
- UnstyledButton,
6045
- {
6046
- title: FILTER_STATE_LABELS2[filterState],
6047
- onClick: () => updateDomainFilter(facet.id),
6048
- disabled,
6049
- style: {
6050
- border: "1px solid var(--color-border)",
6051
- borderRadius: "var(--mantine-radius-sm)",
6052
- padding: "6px 8px"
6053
- },
6054
- children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
6055
- /* @__PURE__ */ jsx(StateIcon, { size: 16, style: { color: FILTER_STATE_COLORS2[filterState], flexShrink: 0 } }),
6056
- /* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, c: filterState === "neutral" ? "dimmed" : void 0, children: facet.label })
6057
- ] })
6058
- },
6059
- facet.id
6060
- );
6061
- }) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No resource facets are available for the current topology." }),
6062
- /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
6063
- "Showing ",
6064
- graph?.nodes.length ?? 0,
6065
- " nodes and ",
6066
- graph?.edges.length ?? 0,
6067
- " edges from",
6068
- " ",
6069
- baseGraph?.nodes.length ?? 0,
6070
- " total nodes."
6071
- ] })
6072
- ] }) })
6073
- ] });
6074
- if (layout === "stack") {
6075
- return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: content });
6076
- }
6077
- return /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, lg: 3 }, spacing: "md", children: content });
3382
+ function CommandViewHealthStrip({
3383
+ overview,
3384
+ hotspots,
3385
+ visibleResources,
3386
+ hiddenResources = 0,
3387
+ resourcesHidden,
3388
+ selectedLabel,
3389
+ onFocusHotspot,
3390
+ onResourcesHiddenChange,
3391
+ onResetFocus
3392
+ }) {
3393
+ return /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between" }, children: [
3394
+ /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
3395
+ /* @__PURE__ */ jsx(IconActivityHeartbeat, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
3396
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.successRate == null ? "N/A" : `${Math.round(overview.successRate)}%` }),
3397
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
3398
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", children: overview?.successCount ?? 0 }),
3399
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: "red", size: "xs", children: overview?.failureCount ?? 0 }),
3400
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", size: "xs", children: overview?.warningCount ?? 0 })
3401
+ ] }),
3402
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", truncate: true, style: { flexShrink: 1, minWidth: 0 }, children: overview ? `${overview.totalRuns} runs / ${overview.trackedResources} resources` : "" })
3403
+ ] }),
3404
+ /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
3405
+ /* @__PURE__ */ jsx(IconAlertTriangle, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
3406
+ hotspots.length > 0 ? /* @__PURE__ */ jsx(Group, { gap: "xs", wrap: "nowrap", style: { minWidth: 0, overflow: "hidden" }, children: hotspots.map((hotspot) => /* @__PURE__ */ jsx(Group, { gap: 4, wrap: "nowrap", children: /* @__PURE__ */ jsx(
3407
+ Badge,
3408
+ {
3409
+ variant: "light",
3410
+ color: "red",
3411
+ size: "xs",
3412
+ style: { cursor: "pointer", flexShrink: 0 },
3413
+ onClick: () => onFocusHotspot(hotspot.resourceId),
3414
+ children: hotspot.label
3415
+ }
3416
+ ) }, hotspot.nodeId)) }) : /* @__PURE__ */ jsx(Badge, { variant: "light", color: "green", size: "xs", leftSection: /* @__PURE__ */ jsx(IconCircleCheck, { size: 10 }), children: "No hotspots" })
3417
+ ] }),
3418
+ /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
3419
+ /* @__PURE__ */ jsx(IconClockPause, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
3420
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, style: { flexShrink: 0 }, children: overview?.pendingApprovals ?? 0 }),
3421
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", truncate: true, children: [
3422
+ "pending / ",
3423
+ overview?.activeHumanCheckpoints ?? 0,
3424
+ " queues"
3425
+ ] })
3426
+ ] }),
3427
+ /* @__PURE__ */ jsxs("div", { style: cellStyle, children: [
3428
+ /* @__PURE__ */ jsx(IconTopologyStar3, { size: 16, style: { flexShrink: 0, color: "var(--color-text-dimmed)" } }),
3429
+ /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, truncate: true, style: { minWidth: 0 }, children: selectedLabel ?? `${visibleResources} visible / ${hiddenResources} hidden` }),
3430
+ /* @__PURE__ */ jsx(
3431
+ Button,
3432
+ {
3433
+ size: "compact-xs",
3434
+ variant: resourcesHidden ? "light" : "subtle",
3435
+ onClick: () => onResourcesHiddenChange(!resourcesHidden),
3436
+ style: { flexShrink: 0 },
3437
+ children: resourcesHidden ? "Show resources" : "Hide resources"
3438
+ }
3439
+ ),
3440
+ /* @__PURE__ */ jsx(Button, { size: "compact-xs", variant: "subtle", onClick: onResetFocus, style: { flexShrink: 0 }, children: "Reset" })
3441
+ ] })
3442
+ ] });
6078
3443
  }
6079
3444
 
6080
3445
  // src/features/operations/organization-graph/commandViewGraphHealth.ts
@@ -7863,362 +5228,6 @@ function OrganizationGraphPage({ lens = "default", timeRange = "30d" }) {
7863
5228
  function CommandViewPage({ timeRange }) {
7864
5229
  return /* @__PURE__ */ jsx(OrganizationGraphPage, { lens: "command-view", timeRange });
7865
5230
  }
7866
- var EXECUTION_SECTIONS = [
7867
- { status: "failed", title: "Failed Executions", badgeColor: "red" },
7868
- { status: "warning", title: "Warning Executions", badgeColor: "yellow" },
7869
- { status: "completed", title: "Successful Executions", badgeColor: null }
7870
- ];
7871
- var HOVER_CARD_STYLE = {
7872
- cursor: "pointer",
7873
- transition: "box-shadow var(--duration-fast) var(--easing)",
7874
- textDecoration: "none",
7875
- color: "inherit"
7876
- };
7877
- function handleHoverEnter(e) {
7878
- e.currentTarget.style.boxShadow = "var(--standard-box-shadow)";
7879
- }
7880
- function handleHoverLeave(e) {
7881
- e.currentTarget.style.boxShadow = "";
7882
- }
7883
- function ExecutionStatusSection({ executions, status, title, badgeColor, resourceUrl }) {
7884
- const filtered = executions.filter((e) => e.status === status);
7885
- if (filtered.length === 0) return null;
7886
- return /* @__PURE__ */ jsxs("div", { children: [
7887
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
7888
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: title }),
7889
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: filtered.length })
7890
- ] }),
7891
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: filtered.map((execution) => /* @__PURE__ */ jsxs(
7892
- Card,
7893
- {
7894
- padding: "xs",
7895
- withBorder: true,
7896
- component: "a",
7897
- href: `${resourceUrl}?exec=${execution.executionId}`,
7898
- target: "_blank",
7899
- rel: "noopener noreferrer",
7900
- style: HOVER_CARD_STYLE,
7901
- onMouseEnter: handleHoverEnter,
7902
- onMouseLeave: handleHoverLeave,
7903
- children: [
7904
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: status === "failed" && execution.errorMessage ? 4 : 0, children: [
7905
- badgeColor ? /* @__PURE__ */ jsx(Badge, { size: "xs", color: badgeColor, variant: "light", children: status }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "green", children: "\u2713 Completed" }),
7906
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(execution.startedAt) })
7907
- ] }),
7908
- status === "failed" && execution.errorMessage && /* @__PURE__ */ jsx(Text, { size: "xs", c: "red", lineClamp: 2, children: execution.errorMessage })
7909
- ]
7910
- },
7911
- execution.executionId
7912
- )) }),
7913
- /* @__PURE__ */ jsx(Space, { h: "sm" })
7914
- ] });
7915
- }
7916
- function CommandViewSidebarContent({ timeRange }) {
7917
- const theme = useMantineTheme();
7918
- const colors = useCyberColors();
7919
- const { organizationModel } = useElevasisFeatures();
7920
- const lensConfig = useMemo(() => getOrganizationGraphLensConfig("command-view"), []);
7921
- const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
7922
- const toolbarResetValue = useMemo(
7923
- () => createOrganizationGraphFilters(lensConfig.initialFilters),
7924
- [lensConfig.initialFilters]
7925
- );
7926
- const selectedNodeId = useCommandViewStore((s) => s.selectedNodeId);
7927
- const resourcesHidden = useCommandViewStore((s) => s.resourcesHidden);
7928
- const setResourcesHidden = useCommandViewStore((s) => s.setResourcesHidden);
7929
- const diagnosticsHidden = useCommandViewStore((s) => s.diagnosticsHidden);
7930
- const setDiagnosticsHidden = useCommandViewStore((s) => s.setDiagnosticsHidden);
7931
- const diagnosticCategories = useCommandViewStore((s) => s.diagnosticCategories);
7932
- const revealedIds = useCommandViewStore((s) => s.revealedIds);
7933
- const clearRevealedIds = useCommandViewStore((s) => s.clearRevealedIds);
7934
- const { data, isLoading } = useCommandViewData();
7935
- const { data: statsData } = useCommandViewStats(timeRange);
7936
- const cleanData = data ?? null;
7937
- const dataWithStats = useMemo(() => {
7938
- if (!cleanData) return null;
7939
- if (!statsData) return cleanData;
7940
- return mergeStatsWithTopology(cleanData, statsData);
7941
- }, [cleanData, statsData]);
7942
- const baseGraph = useMemo(() => {
7943
- if (!organizationModel) {
7944
- return null;
7945
- }
7946
- return buildOrganizationGraph({
7947
- organizationModel,
7948
- commandViewData: cleanData ?? void 0
7949
- });
7950
- }, [cleanData, organizationModel]);
7951
- const graph = useMemo(() => {
7952
- if (!baseGraph) {
7953
- return null;
7954
- }
7955
- return filterOrganizationGraph(baseGraph, filters, {
7956
- commandViewData: cleanData
7957
- });
7958
- }, [baseGraph, cleanData, filters]);
7959
- const visibilityProjection = useMemo(() => {
7960
- if (!graph) {
7961
- return {
7962
- hiddenIds: /* @__PURE__ */ new Set(),
7963
- hiddenEdgeIds: /* @__PURE__ */ new Set(),
7964
- totalResourceCount: 0,
7965
- visibleResourceCount: 0,
7966
- hiddenResourceCount: 0,
7967
- hiddenDiagnosticResourceCount: 0
7968
- };
7969
- }
7970
- return getCommandViewVisibilityProjection({
7971
- graph,
7972
- commandViewData: cleanData,
7973
- resourcesHidden,
7974
- diagnosticsHidden,
7975
- diagnosticCategories,
7976
- revealedIds,
7977
- mode: "map"
7978
- });
7979
- }, [cleanData, diagnosticCategories, diagnosticsHidden, graph, resourcesHidden, revealedIds]);
7980
- const visibleGraph = useMemo(() => {
7981
- if (!graph || visibilityProjection.hiddenIds.size === 0) {
7982
- return graph;
7983
- }
7984
- return {
7985
- ...graph,
7986
- nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
7987
- edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
7988
- };
7989
- }, [graph, visibilityProjection]);
7990
- const handleResetFilters = () => {
7991
- resetFilters();
7992
- clearRevealedIds();
7993
- };
7994
- const handleResourcesHiddenChange = (value) => {
7995
- setResourcesHidden(value);
7996
- if (value) {
7997
- clearRevealedIds();
7998
- }
7999
- };
8000
- const handleDiagnosticsHiddenChange = (value) => {
8001
- setDiagnosticsHidden(value);
8002
- if (value) {
8003
- clearRevealedIds();
8004
- }
8005
- };
8006
- const revealAllResources = () => {
8007
- setResourcesHidden(false);
8008
- setDiagnosticsHidden(false);
8009
- clearRevealedIds();
8010
- };
8011
- const { donutSuccessCount, donutFailedCount } = useMemo(() => {
8012
- if (!cleanData || !statsData) return { donutSuccessCount: 0, donutFailedCount: 0 };
8013
- const allResources = [
8014
- ...cleanData.agents,
8015
- ...cleanData.workflows,
8016
- ...cleanData.triggers,
8017
- ...cleanData.integrations,
8018
- ...cleanData.externalResources ?? [],
8019
- ...cleanData.humanCheckpoints ?? []
8020
- ];
8021
- const filteredIds = new Set(allResources.map((resource) => resource.resourceId));
8022
- let success = 0;
8023
- let failed = 0;
8024
- for (const [id, stats] of Object.entries(statsData.resources)) {
8025
- if (filteredIds.has(id)) {
8026
- success += stats.successCount;
8027
- failed += stats.failureCount;
8028
- }
8029
- }
8030
- return { donutSuccessCount: success, donutFailedCount: failed };
8031
- }, [cleanData, statsData]);
8032
- const selectedNode = useMemo(() => {
8033
- if (!selectedNodeId || !dataWithStats) return null;
8034
- const allNodes = [
8035
- ...dataWithStats.agents || [],
8036
- ...dataWithStats.workflows || [],
8037
- ...dataWithStats.triggers || [],
8038
- ...dataWithStats.integrations || [],
8039
- ...dataWithStats.externalResources || [],
8040
- ...dataWithStats.humanCheckpoints || []
8041
- ];
8042
- return allNodes.find((node) => {
8043
- const nodeId = getNodeId(node);
8044
- return nodeId === selectedNodeId || node.name === selectedNodeId;
8045
- }) || null;
8046
- }, [selectedNodeId, dataWithStats]);
8047
- const isNavigable = selectedNode?.type === "agent" || selectedNode?.type === "workflow";
8048
- const isHumanCheckpoint = selectedNode?.type === "human";
8049
- const selectedResourceId = useMemo(() => {
8050
- if (!selectedNode) return null;
8051
- return getNodeId(selectedNode);
8052
- }, [selectedNode]);
8053
- const {
8054
- page: executionPage,
8055
- setPage: setExecutionPage,
8056
- totalPages: totalExecutionPages
8057
- } = usePaginationState(10, [selectedResourceId, timeRange]);
8058
- const getNavigationUrl = () => {
8059
- if (!selectedNode || !selectedResourceId) return null;
8060
- if (selectedNode.type === "agent") return `/operations/resources/agent/${selectedResourceId}`;
8061
- if (selectedNode.type === "workflow") return `/operations/resources/workflow/${selectedResourceId}`;
8062
- if (selectedNode.type === "human") return `/operations/command-queue?checkpoint=${selectedResourceId}`;
8063
- return null;
8064
- };
8065
- const resourceUrl = selectedNode?.type === "agent" ? `/operations/resources/agent/${selectedResourceId}` : `/operations/resources/workflow/${selectedResourceId}`;
8066
- const {
8067
- data: executionsData,
8068
- isLoading: executionsLoading,
8069
- error: executionsError
8070
- } = useResourceExecutions({
8071
- resourceId: selectedResourceId,
8072
- timeRange,
8073
- page: executionPage,
8074
- limit: 10,
8075
- enabled: isNavigable
8076
- });
8077
- const {
8078
- data: checkpointTasksData,
8079
- isLoading: checkpointTasksLoading,
8080
- error: checkpointTasksError
8081
- } = useCheckpointTasks({
8082
- checkpointId: selectedResourceId,
8083
- enabled: isHumanCheckpoint
8084
- });
8085
- const totalExecutions = donutSuccessCount + donutFailedCount;
8086
- const successRate = totalExecutions > 0 ? donutSuccessCount / totalExecutions * 100 : 0;
8087
- const healthSegments = [
8088
- { name: "Completed", value: donutSuccessCount, color: colors.green },
8089
- { name: "Failed", value: donutFailedCount, color: colors.red }
8090
- ];
8091
- const centerValueColor = totalExecutions === 0 ? "var(--mantine-color-dimmed)" : successRate >= 95 ? colors.green : successRate >= 80 ? colors.yellow : colors.red;
8092
- if (isLoading && !data) {
8093
- return /* @__PURE__ */ jsx(SubshellSidebarLoader, {});
8094
- }
8095
- return /* @__PURE__ */ jsx(
8096
- Box,
8097
- {
8098
- style: {
8099
- flex: 1,
8100
- height: "100%",
8101
- minHeight: 0,
8102
- display: "flex",
8103
- flexDirection: "column",
8104
- overflow: "hidden"
8105
- },
8106
- children: /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", overflowX: "hidden" }, children: [
8107
- /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconSitemap, label: "Command View" }),
8108
- /* @__PURE__ */ jsx(Box, { style: { padding: theme.spacing.sm, paddingBottom: 0 }, children: /* @__PURE__ */ jsx(Box, { pb: "xs", mb: 4, children: /* @__PURE__ */ jsx(
8109
- CyberDonut,
8110
- {
8111
- title: `Execution Health (${timeRange})`,
8112
- segments: healthSegments,
8113
- centerValue: totalExecutions === 0 ? "\u2014" : `${Math.round(successRate)}%`,
8114
- centerLabel: `${totalExecutions} runs`,
8115
- centerValueColor,
8116
- glowId: "cvHealthGlow",
8117
- colors
8118
- }
8119
- ) }) }),
8120
- /* @__PURE__ */ jsx(Box, { p: "sm", children: /* @__PURE__ */ jsx(
8121
- FilterPanel,
8122
- {
8123
- filters,
8124
- onChangeFilters: updateFilters,
8125
- resetValue: toolbarResetValue,
8126
- disabled: !baseGraph,
8127
- commandViewData: cleanData,
8128
- lens: "command-view",
8129
- resourcesHidden,
8130
- diagnosticsHidden,
8131
- onResourcesHiddenChange: handleResourcesHiddenChange,
8132
- onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
8133
- onRevealResources: revealAllResources,
8134
- onResetFilters: handleResetFilters,
8135
- visibilityCounts: visibilityProjection,
8136
- graph: visibleGraph,
8137
- baseGraph,
8138
- layout: "stack"
8139
- }
8140
- ) }),
8141
- selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
8142
- /* @__PURE__ */ jsx(Divider, {}),
8143
- /* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
8144
- /* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
8145
- selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
8146
- (isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
8147
- Button,
8148
- {
8149
- component: "a",
8150
- href: getNavigationUrl() || "#",
8151
- target: "_blank",
8152
- rel: "noopener noreferrer",
8153
- variant: "light",
8154
- size: "xs",
8155
- leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
8156
- mt: 4,
8157
- children: [
8158
- "Go to",
8159
- " ",
8160
- selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
8161
- ]
8162
- }
8163
- ),
8164
- /* @__PURE__ */ jsx(Space, { h: "sm" })
8165
- ] })
8166
- ] }),
8167
- selectedNode && isNavigable && /* @__PURE__ */ jsx(Stack, { p: "sm", children: executionsLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : executionsError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: executionsError, title: "Failed to load executions" }) : executionsData && executionsData.executions.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
8168
- EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
8169
- ExecutionStatusSection,
8170
- {
8171
- executions: executionsData.executions,
8172
- status: section.status,
8173
- title: section.title,
8174
- badgeColor: section.badgeColor,
8175
- resourceUrl
8176
- },
8177
- section.status
8178
- )),
8179
- totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
8180
- Pagination,
8181
- {
8182
- size: "sm",
8183
- total: totalExecutionPages(executionsData.totalExecutions),
8184
- value: executionPage,
8185
- onChange: setExecutionPage,
8186
- boundaries: 1
8187
- }
8188
- ) })
8189
- ] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
8190
- selectedNode && isHumanCheckpoint && /* @__PURE__ */ jsx(Stack, { p: "sm", children: checkpointTasksLoading ? /* @__PURE__ */ jsx(Center, { py: "md", children: /* @__PURE__ */ jsx(Loader, { size: "sm" }) }) : checkpointTasksError ? /* @__PURE__ */ jsx(APIErrorAlert, { error: checkpointTasksError, title: "Failed to load pending tasks" }) : checkpointTasksData && checkpointTasksData.tasks.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
8191
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
8192
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
8193
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
8194
- ] }),
8195
- /* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
8196
- Card,
8197
- {
8198
- padding: "xs",
8199
- withBorder: true,
8200
- component: "a",
8201
- href: `/operations/command-queue?task=${task.id}`,
8202
- target: "_blank",
8203
- rel: "noopener noreferrer",
8204
- style: HOVER_CARD_STYLE,
8205
- onMouseEnter: handleHoverEnter,
8206
- onMouseLeave: handleHoverLeave,
8207
- children: [
8208
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: task.description ? 4 : 0, children: [
8209
- /* @__PURE__ */ jsx(Badge, { size: "xs", color: "orange", variant: "light", children: "pending" }),
8210
- /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime3(task.createdAt) })
8211
- ] }),
8212
- task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
8213
- ]
8214
- },
8215
- task.id
8216
- )) })
8217
- ] }) : checkpointTasksData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending tasks" }) : null })
8218
- ] })
8219
- }
8220
- );
8221
- }
8222
5231
  function WorkflowExecutionPanel({
8223
5232
  resourceId,
8224
5233
  resourceDefinition,
@@ -8403,6 +5412,81 @@ function ExecutionPanel({
8403
5412
  return isWorkflowDefinition2(resourceDefinition) ? /* @__PURE__ */ jsx(WorkflowExecutionPanel, { ...diProps, resourceDefinition }) : /* @__PURE__ */ jsx(ResourceDefinitionError, { resourceId, resourceType, resourceName });
8404
5413
  }
8405
5414
  }
5415
+ function ExecuteWorkflowModal({
5416
+ opened,
5417
+ onClose,
5418
+ resource,
5419
+ isPending = false,
5420
+ error,
5421
+ result,
5422
+ onViewExecution,
5423
+ onReset,
5424
+ children
5425
+ }) {
5426
+ const canClose = !isPending;
5427
+ const title = resource.name ?? resource.resourceId;
5428
+ return /* @__PURE__ */ jsx(
5429
+ Modal,
5430
+ {
5431
+ opened,
5432
+ onClose: canClose ? onClose : () => void 0,
5433
+ centered: true,
5434
+ size: "lg",
5435
+ closeOnClickOutside: canClose,
5436
+ closeOnEscape: canClose,
5437
+ withCloseButton: canClose,
5438
+ title: /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
5439
+ /* @__PURE__ */ jsxs(Text, { fw: 600, children: [
5440
+ "Run ",
5441
+ resource.resourceType
5442
+ ] }),
5443
+ /* @__PURE__ */ jsx(Badge, { color: "blue", variant: "light", size: "sm", children: resource.resourceType })
5444
+ ] }),
5445
+ children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
5446
+ /* @__PURE__ */ jsxs(Group, { gap: 4, wrap: "nowrap", children: [
5447
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Target:" }),
5448
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: title }),
5449
+ /* @__PURE__ */ jsx(Code, { children: resource.resourceId })
5450
+ ] }),
5451
+ /* @__PURE__ */ jsx(Divider, {}),
5452
+ result ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
5453
+ /* @__PURE__ */ jsx(Alert, { variant: "light", color: "teal", title: "Execution started", icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }), children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
5454
+ /* @__PURE__ */ jsxs(Text, { size: "sm", children: [
5455
+ "The ",
5456
+ resource.resourceType,
5457
+ " is now running."
5458
+ ] }),
5459
+ /* @__PURE__ */ jsxs(Group, { gap: 4, children: [
5460
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "Execution ID:" }),
5461
+ /* @__PURE__ */ jsx(Code, { children: result.executionId })
5462
+ ] })
5463
+ ] }) }),
5464
+ /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
5465
+ onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Run again" }),
5466
+ onViewExecution && /* @__PURE__ */ jsx(
5467
+ Button,
5468
+ {
5469
+ leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 16 }),
5470
+ onClick: () => onViewExecution(result.executionId),
5471
+ children: "View execution"
5472
+ }
5473
+ ),
5474
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
5475
+ ] })
5476
+ ] }) : error ? /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
5477
+ /* @__PURE__ */ jsx(Alert, { variant: "light", color: "red", title: "Execution failed to start", icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: 16 }), children: /* @__PURE__ */ jsx(Text, { size: "sm", children: error.message || "An unknown error occurred." }) }),
5478
+ /* @__PURE__ */ jsxs(Group, { justify: "flex-end", gap: "xs", children: [
5479
+ onReset && /* @__PURE__ */ jsx(Button, { variant: "default", onClick: onReset, children: "Try again" }),
5480
+ /* @__PURE__ */ jsx(Button, { variant: "light", onClick: onClose, children: "Close" })
5481
+ ] })
5482
+ ] }) : /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
5483
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: isPending, zIndex: 1e3, overlayProps: { blur: 2 } }),
5484
+ children ?? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No input form provided." })
5485
+ ] })
5486
+ ] })
5487
+ }
5488
+ );
5489
+ }
8406
5490
  function SessionListItem({ session, onClick, isSelected = false, onDeleted }) {
8407
5491
  const deleteSession = useDeleteSession();
8408
5492
  const [isDeleting, setIsDeleting] = useState(false);
@@ -9536,4 +6620,4 @@ var operationsManifest = {
9536
6620
  sidebarWidth: ({ currentPath }) => currentPath.startsWith("/knowledge/command-view") ? commandViewSidebarWidth : defaultOperationsSidebarWidth
9537
6621
  };
9538
6622
 
9539
- export { ActionModal, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionPanel, AgentSessionGroup, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, CheckpointGroup, CollapsibleJsonSection, CommandQueueDetailPage, CommandQueuePage, CommandQueueShell, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewPage, CommandViewSidebarContent, ConfigCard, ContentSections, ContextUsageBadge, ContractDisplay, ExecuteWorkflowModal, ExecutionErrorSection, ExecutionPanel, LogEntry, LogGroup, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, OperationsSidebar, OperationsSidebarMiddle, OperationsSidebarTop, OrganizationGraphPage, ResourceDefinitionSection, ResourceDetailPage, ResourceErrorState, ResourceExecuteDialog, ResourceExecuteForm, ResourceFilter, ResourceHeader, ResourceNotFoundState, ResourcesPage, ResourcesSidebar, SessionChatArea, SessionChatInterface, SessionChatPage, SessionDetailsSidebar, SessionExecutionLogs, SessionHeader, SessionListItem, SessionMemory, SessionsPage, SessionsSidebar, ToolsListDisplay, WorkflowDefinitionDisplay, WorkflowExecutionLogs, WorkflowExecutionPanel, getExecutionStatusConfig, getIcon, getLogLevelConfig, iconMap, operationsManifest, useNewKnowledgeMapLayout };
6623
+ export { ActionModal, AgentDefinitionDisplay, AgentExecutionLogs, AgentExecutionPanel, AgentSessionGroup, BaseExecutionLogs, BaseExecutionLogsHeader, BaseExecutionLogsStates, CheckpointGroup, CollapsibleJsonSection, CommandQueueDetailPage, CommandQueuePage, CommandQueueShell, CommandQueueSidebar, CommandQueueSidebarMiddle, CommandQueueSidebarTop, CommandQueueTaskRow, CommandViewPage, ConfigCard, ContentSections, ContextUsageBadge, ContractDisplay, ExecuteWorkflowModal, ExecutionErrorSection, ExecutionPanel, LogEntry, LogGroup, NewKnowledgeMapEdge, NewKnowledgeMapGraph, NewKnowledgeMapNode, OperationsSidebar, OperationsSidebarMiddle, OperationsSidebarTop, OrganizationGraphPage, ResourceDefinitionSection, ResourceDetailPage, ResourceErrorState, ResourceFilter, ResourceHeader, ResourceNotFoundState, ResourcesPage, ResourcesSidebar, SessionChatArea, SessionChatInterface, SessionChatPage, SessionDetailsSidebar, SessionExecutionLogs, SessionHeader, SessionListItem, SessionMemory, SessionsPage, SessionsSidebar, ToolsListDisplay, WorkflowDefinitionDisplay, WorkflowExecutionLogs, WorkflowExecutionPanel, getExecutionStatusConfig, getIcon, getLogLevelConfig, iconMap, operationsManifest, useNewKnowledgeMapLayout };