@elevasis/ui 2.25.5 → 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 (101) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +18 -29
  3. package/dist/app/index.d.ts +118 -64
  4. package/dist/app/index.js +6 -5
  5. package/dist/charts/index.js +6 -5
  6. package/dist/chunk-3MEXPLWT.js +265 -0
  7. package/dist/{chunk-IS53MXE4.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-NHHCUECV.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-VMAWXEVG.js → chunk-JKBGDFX2.js} +1136 -828
  14. package/dist/{chunk-MU4VPAMR.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-QNCVK3ZF.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-KINQW4JT.js → chunk-UPMX5GJI.js} +5 -5
  25. package/dist/{chunk-N2AP4I5N.js → chunk-UY5I2KOZ.js} +223 -3857
  26. package/dist/{chunk-JMI7L7Y7.js → chunk-W2ZTLH7Y.js} +142 -4
  27. package/dist/{chunk-3KY2GNPE.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-F7JDHS2I.js → chunk-XZSEPJZQ.js} +5 -5
  32. package/dist/{chunk-5BJXMZN4.js → chunk-YHBPR67D.js} +438 -620
  33. package/dist/{chunk-FVKLHLF4.js → chunk-YO2YORW4.js} +4 -4
  34. package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
  35. package/dist/components/index.css +18 -29
  36. package/dist/components/index.d.ts +211 -383
  37. package/dist/components/index.js +43 -427
  38. package/dist/components/navigation/index.css +28 -39
  39. package/dist/execution/index.d.ts +0 -73
  40. package/dist/features/auth/index.css +28 -39
  41. package/dist/features/crm/index.css +28 -39
  42. package/dist/features/crm/index.d.ts +49 -49
  43. package/dist/features/crm/index.js +14 -14
  44. package/dist/features/dashboard/index.css +28 -39
  45. package/dist/features/dashboard/index.js +18 -15
  46. package/dist/features/delivery/index.css +18 -29
  47. package/dist/features/delivery/index.js +14 -14
  48. package/dist/features/knowledge/index.css +611 -0
  49. package/dist/features/knowledge/index.js +700 -1
  50. package/dist/features/lead-gen/index.css +28 -39
  51. package/dist/features/lead-gen/index.d.ts +212 -166
  52. package/dist/features/lead-gen/index.js +16 -15
  53. package/dist/features/monitoring/index.css +18 -29
  54. package/dist/features/monitoring/index.js +17 -16
  55. package/dist/features/monitoring/requests/index.css +28 -39
  56. package/dist/features/monitoring/requests/index.js +13 -13
  57. package/dist/features/operations/index.css +28 -39
  58. package/dist/features/operations/index.d.ts +16 -98
  59. package/dist/features/operations/index.js +26 -20
  60. package/dist/features/settings/index.css +28 -39
  61. package/dist/features/settings/index.d.ts +1 -0
  62. package/dist/features/settings/index.js +15 -15
  63. package/dist/hooks/delivery/index.css +28 -39
  64. package/dist/hooks/delivery/index.js +2 -2
  65. package/dist/hooks/index.css +18 -29
  66. package/dist/hooks/index.d.ts +180 -377
  67. package/dist/hooks/index.js +13 -13
  68. package/dist/hooks/published.css +18 -29
  69. package/dist/hooks/published.d.ts +180 -377
  70. package/dist/hooks/published.js +13 -13
  71. package/dist/index.css +18 -29
  72. package/dist/index.d.ts +1549 -946
  73. package/dist/index.js +15 -14
  74. package/dist/initialization/index.d.ts +1 -0
  75. package/dist/knowledge/index.d.ts +991 -41
  76. package/dist/knowledge/index.js +5469 -413
  77. package/dist/layout/index.d.ts +2 -0
  78. package/dist/layout/index.js +3 -2
  79. package/dist/organization/index.css +28 -39
  80. package/dist/organization/index.d.ts +1 -0
  81. package/dist/provider/index.css +28 -39
  82. package/dist/provider/index.d.ts +1147 -348
  83. package/dist/provider/index.js +11 -10
  84. package/dist/provider/published.css +28 -39
  85. package/dist/provider/published.d.ts +1146 -347
  86. package/dist/provider/published.js +8 -8
  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 +46 -33
  99. package/src/knowledge/README.md +8 -8
  100. package/src/theme/presets/README.md +19 -0
  101. /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
@@ -0,0 +1,3731 @@
1
+ import { SemanticIcon } from './chunk-KEFWANZY.js';
2
+ import { SubshellSidebarLoader } from './chunk-XQQEKWTL.js';
3
+ import { OrganizationModelProspectingSchema } from './chunk-4KTLOK7K.js';
4
+ import { useCyberColors, CyberDonut } from './chunk-CW3UNAF2.js';
5
+ import { SubshellSidebarSection } from './chunk-IIMU5YAJ.js';
6
+ import { collectResourceFilterFacets, useCommandViewStore, useCommandViewData, useCommandViewStats, usePaginationState, useResourceExecutions, useCheckpointTasks } from './chunk-YHBPR67D.js';
7
+ import { EmptyState, APIErrorAlert } from './chunk-RIFTUOPE.js';
8
+ import { LabelSchema, ColorTokenSchema, IconNameSchema, PathSchema, DescriptionSchema, DisplayMetadataSchema, ModelIdSchema, ReferenceIdsSchema, OrganizationModelSalesSchema } from './chunk-W2ZTLH7Y.js';
9
+ import { useElevasisFeatures } from './chunk-V3HUIZJX.js';
10
+ import { getNodeId } from './chunk-QD4X4H5A.js';
11
+ import { useRef, useEffect, useMemo } from 'react';
12
+ import { Paper, Stack, Group, Text, Button, Badge, SimpleGrid, Divider, Select, NumberInput, MultiSelect, Switch, Card, Checkbox, UnstyledButton, useMantineTheme, Box, Title, Space, Center, Loader, Pagination, TextInput, SegmentedControl } from '@mantine/core';
13
+ import { IconShare2, IconTopologyStar3, IconRefresh, IconCircleX, IconCircleCheck, IconCircleDashed, IconSitemap, IconExternalLink, IconSearch } from '@tabler/icons-react';
14
+ import { z } from 'zod';
15
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
16
+ import { create } from 'zustand';
17
+ import { formatDistanceToNow } from 'date-fns';
18
+
19
+ var NodeIdPathSchema = z.string().trim().min(1).max(100).regex(/^([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node IDs must be lowercase dotted paths");
20
+ var NodeIdStringSchema = z.string().trim().min(1).max(200).regex(/^[a-z]+:([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node references must use kind:dotted-path");
21
+ var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]);
22
+ var FeatureSchema = z.object({
23
+ id: NodeIdPathSchema,
24
+ label: LabelSchema,
25
+ description: DescriptionSchema.optional(),
26
+ enabled: z.boolean().default(true),
27
+ path: PathSchema.optional(),
28
+ icon: IconNameSchema.optional(),
29
+ color: ColorTokenSchema.optional(),
30
+ uiPosition: UiPositionSchema.optional(),
31
+ requiresAdmin: z.boolean().optional(),
32
+ devOnly: z.boolean().optional()
33
+ });
34
+ var OrganizationModelBrandingSchema = z.object({
35
+ organizationName: LabelSchema,
36
+ productName: LabelSchema,
37
+ shortName: z.string().trim().min(1).max(40),
38
+ description: DescriptionSchema.optional(),
39
+ logos: z.object({
40
+ light: z.string().trim().min(1).max(2048).optional(),
41
+ dark: z.string().trim().min(1).max(2048).optional()
42
+ }).default({})
43
+ });
44
+ var DEFAULT_ORGANIZATION_MODEL_BRANDING = {
45
+ organizationName: "Default Organization",
46
+ productName: "Elevasis",
47
+ shortName: "Elevasis",
48
+ logos: {}
49
+ };
50
+ var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
51
+ id: ModelIdSchema,
52
+ order: z.number().int().min(0)
53
+ });
54
+ var OrganizationModelProjectsSchema = z.object({
55
+ projectEntityId: ModelIdSchema,
56
+ milestoneEntityId: ModelIdSchema,
57
+ taskEntityId: ModelIdSchema,
58
+ projectStatuses: z.array(ProjectsDomainStateSchema).min(1),
59
+ milestoneStatuses: z.array(ProjectsDomainStateSchema).min(1),
60
+ taskStatuses: z.array(ProjectsDomainStateSchema).min(1)
61
+ });
62
+ var DEFAULT_ORGANIZATION_MODEL_PROJECTS = {
63
+ projectEntityId: "delivery.project",
64
+ milestoneEntityId: "delivery.milestone",
65
+ taskEntityId: "delivery.task",
66
+ projectStatuses: [
67
+ { id: "active", label: "Active", order: 1 },
68
+ { id: "on_track", label: "On Track", order: 2 },
69
+ { id: "at_risk", label: "At Risk", order: 3 },
70
+ { id: "blocked", label: "Blocked", order: 4 },
71
+ { id: "paused", label: "Paused", order: 5 },
72
+ { id: "completed", label: "Completed", order: 6 }
73
+ ],
74
+ milestoneStatuses: [
75
+ { id: "upcoming", label: "Upcoming", order: 1 },
76
+ { id: "in_progress", label: "In Progress", order: 2 },
77
+ { id: "blocked", label: "Blocked", order: 3 },
78
+ { id: "overdue", label: "Overdue", order: 4 },
79
+ { id: "completed", label: "Completed", order: 5 }
80
+ ],
81
+ taskStatuses: [
82
+ { id: "planned", label: "Planned", order: 1 },
83
+ { id: "in_progress", label: "In Progress", order: 2 },
84
+ { id: "blocked", label: "Blocked", order: 3 },
85
+ { id: "submitted", label: "Submitted", order: 4 },
86
+ { id: "approved", label: "Approved", order: 5 },
87
+ { id: "revision_requested", label: "Revision Requested", order: 6 },
88
+ { id: "rejected", label: "Rejected", order: 7 },
89
+ { id: "cancelled", label: "Cancelled", order: 8 },
90
+ { id: "completed", label: "Completed", order: 9 }
91
+ ]
92
+ };
93
+ var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]);
94
+ var SurfaceDefinitionSchema = z.object({
95
+ id: ModelIdSchema,
96
+ label: LabelSchema,
97
+ path: PathSchema,
98
+ surfaceType: SurfaceTypeSchema,
99
+ description: DescriptionSchema.optional(),
100
+ enabled: z.boolean().default(true),
101
+ devOnly: z.boolean().optional(),
102
+ icon: IconNameSchema.optional(),
103
+ featureId: ModelIdSchema.optional(),
104
+ featureIds: ReferenceIdsSchema,
105
+ entityIds: ReferenceIdsSchema,
106
+ resourceIds: ReferenceIdsSchema,
107
+ capabilityIds: ReferenceIdsSchema,
108
+ parentId: ModelIdSchema.optional()
109
+ });
110
+ var NavigationGroupSchema = z.object({
111
+ id: ModelIdSchema,
112
+ label: LabelSchema,
113
+ placement: z.string().trim().min(1).max(50),
114
+ surfaceIds: z.array(ModelIdSchema).default([])
115
+ });
116
+ var OrganizationModelNavigationSchema = z.object({
117
+ defaultSurfaceId: ModelIdSchema.optional(),
118
+ surfaces: z.array(SurfaceDefinitionSchema).default([]),
119
+ groups: z.array(NavigationGroupSchema).default([])
120
+ });
121
+ var BusinessHoursDaySchema = z.object({
122
+ open: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format"),
123
+ close: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format")
124
+ });
125
+ var BusinessHoursSchema = z.object({
126
+ monday: BusinessHoursDaySchema.optional(),
127
+ tuesday: BusinessHoursDaySchema.optional(),
128
+ wednesday: BusinessHoursDaySchema.optional(),
129
+ thursday: BusinessHoursDaySchema.optional(),
130
+ friday: BusinessHoursDaySchema.optional(),
131
+ saturday: BusinessHoursDaySchema.optional(),
132
+ sunday: BusinessHoursDaySchema.optional()
133
+ }).default({});
134
+ var IdentityDomainSchema = z.object({
135
+ /** Why the organization exists — one or two plain-language sentences. */
136
+ mission: z.string().trim().max(1e3).default(""),
137
+ /** Long-term direction the organization is moving toward. */
138
+ vision: z.string().trim().max(1e3).default(""),
139
+ /** Legal registered name of the entity. */
140
+ legalName: z.string().trim().max(200).default(""),
141
+ /**
142
+ * Type of legal entity (e.g. "LLC", "Corporation", "Sole Proprietor",
143
+ * "Non-profit"). Free-form string so it covers any jurisdiction.
144
+ */
145
+ entityType: z.string().trim().max(100).default(""),
146
+ /**
147
+ * Primary jurisdiction of registration or operation
148
+ * (e.g. "United States – Delaware", "Canada – Ontario").
149
+ */
150
+ jurisdiction: z.string().trim().max(200).default(""),
151
+ /**
152
+ * Industry category — broad classification (e.g. "Marketing Agency",
153
+ * "Software / SaaS", "Professional Services").
154
+ */
155
+ industryCategory: z.string().trim().max(200).default(""),
156
+ /**
157
+ * Geographic focus — where the organization primarily operates or serves
158
+ * (e.g. "North America", "Global", "Southeast Asia").
159
+ */
160
+ geographicFocus: z.string().trim().max(200).default(""),
161
+ /**
162
+ * IANA timezone identifier for the organization's primary operating timezone
163
+ * (e.g. "America/Los_Angeles", "Europe/London", "UTC").
164
+ */
165
+ timeZone: z.string().trim().max(100).default("UTC"),
166
+ /** Typical operating hours per day of week. Empty object means not configured. */
167
+ businessHours: BusinessHoursSchema,
168
+ /**
169
+ * Long-form markdown capturing client context, problem narrative, and domain
170
+ * background. Populated by /setup; surfaced to agents as organizational context.
171
+ * Optional — many projects have no external client.
172
+ */
173
+ clientBrief: z.string().trim().default("")
174
+ });
175
+ var DEFAULT_ORGANIZATION_MODEL_IDENTITY = {
176
+ mission: "",
177
+ vision: "",
178
+ legalName: "",
179
+ entityType: "",
180
+ jurisdiction: "",
181
+ industryCategory: "",
182
+ geographicFocus: "",
183
+ timeZone: "UTC",
184
+ businessHours: {},
185
+ clientBrief: ""
186
+ };
187
+ var FirmographicsSchema = z.object({
188
+ /** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
189
+ industry: z.string().trim().max(200).optional(),
190
+ /**
191
+ * Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
192
+ * Free-form string to accommodate any band notation.
193
+ */
194
+ companySize: z.string().trim().max(100).optional(),
195
+ /**
196
+ * Primary geographic region the segment operates in or is targeted from
197
+ * (e.g. "North America", "Europe", "Global").
198
+ */
199
+ region: z.string().trim().max(200).optional()
200
+ });
201
+ var CustomerSegmentSchema = z.object({
202
+ /** Stable unique identifier for the segment (e.g. "segment-smb-agencies"). */
203
+ id: z.string().trim().min(1).max(100),
204
+ /** Human-readable name shown to agents and in UI (e.g. "SMB Marketing Agencies"). */
205
+ name: z.string().trim().max(200).default(""),
206
+ /** One or two sentences describing who this segment is. */
207
+ description: z.string().trim().max(2e3).default(""),
208
+ /**
209
+ * The primary job(s) this segment is trying to get done — the goal they hire
210
+ * a product/service to accomplish. Plain-language narrative or bullet list.
211
+ */
212
+ jobsToBeDone: z.string().trim().max(2e3).default(""),
213
+ /**
214
+ * Pains — frustrations, obstacles, and risks the segment experiences
215
+ * when trying to accomplish their jobs-to-be-done.
216
+ */
217
+ pains: z.array(z.string().trim().max(500)).default([]),
218
+ /**
219
+ * Gains — outcomes and benefits the segment desires; positive motivators
220
+ * beyond merely resolving pains.
221
+ */
222
+ gains: z.array(z.string().trim().max(500)).default([]),
223
+ /** Firmographic profile for targeting and filtering. */
224
+ firmographics: FirmographicsSchema.default({}),
225
+ /**
226
+ * Value proposition — one or two sentences stating why this organization's
227
+ * offering is uniquely suited for this segment's needs.
228
+ */
229
+ valueProp: z.string().trim().max(2e3).default("")
230
+ });
231
+ var CustomersDomainSchema = z.object({
232
+ segments: z.array(CustomerSegmentSchema).default([])
233
+ });
234
+ var DEFAULT_ORGANIZATION_MODEL_CUSTOMERS = {
235
+ segments: []
236
+ };
237
+ var PricingModelSchema = z.enum(["one-time", "subscription", "usage-based", "custom"]);
238
+ var ProductSchema = z.object({
239
+ /** Stable unique identifier for the product (e.g. "product-starter-plan"). */
240
+ id: z.string().trim().min(1).max(100),
241
+ /** Human-readable name shown to agents and in UI (e.g. "Starter Plan"). */
242
+ name: z.string().trim().max(200).default(""),
243
+ /** One or two sentences describing what this product/service delivers. */
244
+ description: z.string().trim().max(2e3).default(""),
245
+ /**
246
+ * How this product is priced:
247
+ * - "one-time" — single purchase (setup fee, project fee)
248
+ * - "subscription" — recurring (monthly/annual SaaS, retainer)
249
+ * - "usage-based" — metered by consumption (API calls, seats)
250
+ * - "custom" — negotiated or bespoke pricing
251
+ */
252
+ pricingModel: PricingModelSchema.default("custom"),
253
+ /** Base price amount (≥ 0). Currency unit defined by `currency`. */
254
+ price: z.number().min(0).default(0),
255
+ /**
256
+ * ISO 4217 currency code (e.g. "USD", "EUR", "GBP").
257
+ * Free-form string to accommodate any currency; defaults to "USD".
258
+ */
259
+ currency: z.string().trim().max(10).default("USD"),
260
+ /**
261
+ * IDs of customer segments this product targets.
262
+ * Each id must reference a declared `customers.segments[].id`.
263
+ * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
264
+ */
265
+ targetSegmentIds: z.array(z.string().trim().min(1)).default([]),
266
+ /**
267
+ * Optional: ID of the platform feature responsible for delivering this product.
268
+ * When present, must reference a declared `features[].id`.
269
+ * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
270
+ */
271
+ deliveryFeatureId: z.string().trim().min(1).optional()
272
+ });
273
+ var OfferingsDomainSchema = z.object({
274
+ products: z.array(ProductSchema).default([])
275
+ });
276
+ var DEFAULT_ORGANIZATION_MODEL_OFFERINGS = {
277
+ products: []
278
+ };
279
+ var RoleSchema = z.object({
280
+ /** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
281
+ id: z.string().trim().min(1).max(100),
282
+ /** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
283
+ title: z.string().trim().min(1).max(200),
284
+ /**
285
+ * List of responsibilities this role owns — plain-language descriptions of
286
+ * what the person in this role is accountable for delivering.
287
+ * Defaults to empty array so minimal role definitions stay concise.
288
+ */
289
+ responsibilities: z.array(z.string().trim().max(500)).default([]),
290
+ /**
291
+ * Optional: ID of another role this role reports to.
292
+ * When present, must reference another `roles[].id` in the same organization.
293
+ * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
294
+ * Absence indicates a top-level role (no reporting line).
295
+ */
296
+ reportsToId: z.string().trim().min(1).max(100).optional(),
297
+ /**
298
+ * Optional: name or email of the person currently holding this role.
299
+ * Free-form string — supports "Alice Johnson", "alice@example.com", or
300
+ * any human-readable identifier. Not validated against any user registry.
301
+ */
302
+ heldBy: z.string().trim().max(200).optional()
303
+ });
304
+ var RolesDomainSchema = z.object({
305
+ roles: z.array(RoleSchema).default([])
306
+ });
307
+ var DEFAULT_ORGANIZATION_MODEL_ROLES = {
308
+ roles: []
309
+ };
310
+ var KeyResultSchema = z.object({
311
+ /** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
312
+ id: z.string().trim().min(1).max(100),
313
+ /** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
314
+ description: z.string().trim().min(1).max(500),
315
+ /**
316
+ * What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
317
+ * "trial-to-paid conversion rate"). Free-form string.
318
+ */
319
+ targetMetric: z.string().trim().min(1).max(200),
320
+ /** Current measured value. Defaults to 0 when not yet tracked. */
321
+ currentValue: z.number().default(0),
322
+ /**
323
+ * Target value to reach for this measurable outcome to be considered achieved.
324
+ * Optional — omit if the outcome is directional (e.g. "reduce churn") without
325
+ * a hard numeric target.
326
+ */
327
+ targetValue: z.number().optional()
328
+ });
329
+ var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
330
+ var ObjectiveSchema = z.object({
331
+ /** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
332
+ id: z.string().trim().min(1).max(100),
333
+ /** Plain-language description of what the organization wants to achieve. */
334
+ description: z.string().trim().min(1).max(1e3),
335
+ /**
336
+ * Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
337
+ * Must be strictly before `periodEnd`.
338
+ */
339
+ periodStart: z.string().regex(ISO_DATE_REGEX, "periodStart must be an ISO date string (YYYY-MM-DD)"),
340
+ /**
341
+ * End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
342
+ * Must be strictly after `periodStart`.
343
+ * Enforced via `OrganizationModelSchema.superRefine()`.
344
+ */
345
+ periodEnd: z.string().regex(ISO_DATE_REGEX, "periodEnd must be an ISO date string (YYYY-MM-DD)"),
346
+ /**
347
+ * List of measurable outcomes that define success for this goal.
348
+ * Defaults to empty array so goals can be declared before outcomes are defined.
349
+ */
350
+ keyResults: z.array(KeyResultSchema).default([])
351
+ });
352
+ var GoalsDomainSchema = z.object({
353
+ objectives: z.array(ObjectiveSchema).default([])
354
+ });
355
+ var DEFAULT_ORGANIZATION_MODEL_GOALS = {
356
+ objectives: []
357
+ };
358
+ var OperationSemanticClassSchema = z.enum(["queue", "executions", "sessions", "notifications", "schedules"]);
359
+ var OperationEntrySchema = z.object({
360
+ id: z.string().trim().min(1).max(100),
361
+ label: z.string().trim().min(1).max(120),
362
+ semanticClass: OperationSemanticClassSchema,
363
+ /** Optional reference to the feature that owns this runtime entity. */
364
+ featureId: z.string().trim().min(1).max(100).optional(),
365
+ /**
366
+ * Optional pointer to the status semanticClass values that apply to this
367
+ * entity — ties operations back to the statuses domain for vibe rendering.
368
+ */
369
+ supportedStatusSemanticClass: z.array(z.string().trim().min(1).max(80)).optional()
370
+ });
371
+ var OperationsDomainSchema = z.object({
372
+ entries: z.array(OperationEntrySchema).default([])
373
+ });
374
+ var DEFAULT_ORGANIZATION_MODEL_OPERATIONS = {
375
+ entries: [
376
+ // --- queue (HITL command queue) ---
377
+ {
378
+ id: "operations.queue",
379
+ label: "HITL Queue",
380
+ semanticClass: "queue",
381
+ featureId: "operations",
382
+ supportedStatusSemanticClass: ["queue"]
383
+ },
384
+ // --- executions (workflow / agent executions) ---
385
+ {
386
+ id: "operations.executions",
387
+ label: "Executions",
388
+ semanticClass: "executions",
389
+ featureId: "operations",
390
+ supportedStatusSemanticClass: ["execution"]
391
+ },
392
+ // --- sessions (agent conversation sessions) ---
393
+ {
394
+ id: "operations.sessions",
395
+ label: "Sessions",
396
+ semanticClass: "sessions",
397
+ featureId: "operations"
398
+ },
399
+ // --- notifications (platform in-app notifications) ---
400
+ {
401
+ id: "operations.notifications",
402
+ label: "Notifications",
403
+ semanticClass: "notifications",
404
+ featureId: "monitoring"
405
+ },
406
+ // --- schedules (task scheduler) ---
407
+ {
408
+ id: "operations.schedules",
409
+ label: "Schedules",
410
+ semanticClass: "schedules",
411
+ featureId: "operations",
412
+ supportedStatusSemanticClass: ["schedule", "schedule.run"]
413
+ }
414
+ ]
415
+ };
416
+ var StatusSemanticClassSchema = z.enum([
417
+ "delivery.task",
418
+ "delivery.project",
419
+ "delivery.milestone",
420
+ "queue",
421
+ "execution",
422
+ "schedule",
423
+ "schedule.run",
424
+ "request"
425
+ ]);
426
+ var StatusEntrySchema = z.object({
427
+ id: z.string().trim().min(1).max(100),
428
+ label: z.string().trim().min(1).max(120),
429
+ semanticClass: StatusSemanticClassSchema,
430
+ category: z.string().trim().min(1).max(80).optional()
431
+ });
432
+ var StatusesDomainSchema = z.object({
433
+ entries: z.array(StatusEntrySchema).default([])
434
+ });
435
+ var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
436
+ entries: [
437
+ // --- delivery.task (TaskStatus — 9 values) ---
438
+ { id: "delivery.task.planned", label: "Planned", semanticClass: "delivery.task", category: "delivery" },
439
+ { id: "delivery.task.in_progress", label: "In Progress", semanticClass: "delivery.task", category: "delivery" },
440
+ { id: "delivery.task.blocked", label: "Blocked", semanticClass: "delivery.task", category: "delivery" },
441
+ { id: "delivery.task.submitted", label: "Submitted", semanticClass: "delivery.task", category: "delivery" },
442
+ { id: "delivery.task.approved", label: "Approved", semanticClass: "delivery.task", category: "delivery" },
443
+ {
444
+ id: "delivery.task.revision_requested",
445
+ label: "Revision Requested",
446
+ semanticClass: "delivery.task",
447
+ category: "delivery"
448
+ },
449
+ { id: "delivery.task.rejected", label: "Rejected", semanticClass: "delivery.task", category: "delivery" },
450
+ { id: "delivery.task.cancelled", label: "Cancelled", semanticClass: "delivery.task", category: "delivery" },
451
+ { id: "delivery.task.completed", label: "Completed", semanticClass: "delivery.task", category: "delivery" },
452
+ // --- delivery.project (ProjectStatus — 6 values) ---
453
+ { id: "delivery.project.active", label: "Active", semanticClass: "delivery.project", category: "delivery" },
454
+ { id: "delivery.project.on_track", label: "On Track", semanticClass: "delivery.project", category: "delivery" },
455
+ { id: "delivery.project.at_risk", label: "At Risk", semanticClass: "delivery.project", category: "delivery" },
456
+ { id: "delivery.project.blocked", label: "Blocked", semanticClass: "delivery.project", category: "delivery" },
457
+ { id: "delivery.project.paused", label: "Paused", semanticClass: "delivery.project", category: "delivery" },
458
+ { id: "delivery.project.completed", label: "Completed", semanticClass: "delivery.project", category: "delivery" },
459
+ // --- delivery.milestone (MilestoneStatus — 5 values) ---
460
+ {
461
+ id: "delivery.milestone.upcoming",
462
+ label: "Upcoming",
463
+ semanticClass: "delivery.milestone",
464
+ category: "delivery"
465
+ },
466
+ {
467
+ id: "delivery.milestone.in_progress",
468
+ label: "In Progress",
469
+ semanticClass: "delivery.milestone",
470
+ category: "delivery"
471
+ },
472
+ {
473
+ id: "delivery.milestone.blocked",
474
+ label: "Blocked",
475
+ semanticClass: "delivery.milestone",
476
+ category: "delivery"
477
+ },
478
+ { id: "delivery.milestone.overdue", label: "Overdue", semanticClass: "delivery.milestone", category: "delivery" },
479
+ {
480
+ id: "delivery.milestone.completed",
481
+ label: "Completed",
482
+ semanticClass: "delivery.milestone",
483
+ category: "delivery"
484
+ },
485
+ // --- queue (QueueTaskStatus — 5 values, maps hitl/command-queue tasks) ---
486
+ { id: "queue.pending", label: "Pending", semanticClass: "queue", category: "queue" },
487
+ { id: "queue.processing", label: "Processing", semanticClass: "queue", category: "queue" },
488
+ { id: "queue.completed", label: "Completed", semanticClass: "queue", category: "queue" },
489
+ { id: "queue.failed", label: "Failed", semanticClass: "queue", category: "queue" },
490
+ { id: "queue.expired", label: "Expired", semanticClass: "queue", category: "queue" },
491
+ // --- execution (ExecutionStatus — 5 values) ---
492
+ { id: "execution.pending", label: "Pending", semanticClass: "execution", category: "execution" },
493
+ { id: "execution.running", label: "Running", semanticClass: "execution", category: "execution" },
494
+ { id: "execution.completed", label: "Completed", semanticClass: "execution", category: "execution" },
495
+ { id: "execution.failed", label: "Failed", semanticClass: "execution", category: "execution" },
496
+ { id: "execution.warning", label: "Warning", semanticClass: "execution", category: "execution" },
497
+ // --- schedule (schedule status — 4 values) ---
498
+ { id: "schedule.active", label: "Active", semanticClass: "schedule", category: "schedule" },
499
+ { id: "schedule.paused", label: "Paused", semanticClass: "schedule", category: "schedule" },
500
+ { id: "schedule.completed", label: "Completed", semanticClass: "schedule", category: "schedule" },
501
+ { id: "schedule.cancelled", label: "Cancelled", semanticClass: "schedule", category: "schedule" },
502
+ // --- schedule.run (schedule run status — 4 values) ---
503
+ { id: "schedule.run.running", label: "Running", semanticClass: "schedule.run", category: "schedule" },
504
+ { id: "schedule.run.completed", label: "Completed", semanticClass: "schedule.run", category: "schedule" },
505
+ { id: "schedule.run.failed", label: "Failed", semanticClass: "schedule.run", category: "schedule" },
506
+ { id: "schedule.run.cancelled", label: "Cancelled", semanticClass: "schedule.run", category: "schedule" },
507
+ // --- request (RequestStatus — 4 values, maps reported_requests) ---
508
+ { id: "request.open", label: "Open", semanticClass: "request", category: "request" },
509
+ { id: "request.investigating", label: "Investigating", semanticClass: "request", category: "request" },
510
+ { id: "request.resolved", label: "Resolved", semanticClass: "request", category: "request" },
511
+ { id: "request.wont_fix", label: "Won't Fix", semanticClass: "request", category: "request" }
512
+ ]
513
+ };
514
+ var KnowledgeLinkSchema = z.object({
515
+ nodeId: NodeIdStringSchema
516
+ });
517
+ var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]);
518
+ var OrgKnowledgeNodeSchema = z.object({
519
+ id: ModelIdSchema,
520
+ kind: OrgKnowledgeKindSchema,
521
+ title: z.string().trim().min(1).max(200),
522
+ summary: z.string().trim().min(1).max(1e3),
523
+ icon: IconNameSchema.optional(),
524
+ /** Raw MDX string. Phase 2 will introduce a structured block format. */
525
+ body: z.string().trim().min(1),
526
+ /**
527
+ * Graph links to other OM nodes this knowledge node governs.
528
+ * Each link emits a `governs` edge: knowledge-node -> target node.
529
+ */
530
+ links: z.array(KnowledgeLinkSchema).default([]),
531
+ /** Identifiers of the roles or members who own this knowledge node. */
532
+ ownerIds: z.array(ModelIdSchema).default([]),
533
+ /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
534
+ updatedAt: z.string().trim().min(1).max(50)
535
+ });
536
+ var KnowledgeDomainSchema = z.object({
537
+ nodes: z.array(OrgKnowledgeNodeSchema).default([])
538
+ });
539
+
540
+ // ../core/src/organization-model/schema.ts
541
+ var OrganizationModelSchemaBase = z.object({
542
+ version: z.literal(1).default(1),
543
+ features: z.array(FeatureSchema).default([]),
544
+ branding: OrganizationModelBrandingSchema,
545
+ navigation: OrganizationModelNavigationSchema.default({ surfaces: [], groups: [] }),
546
+ sales: OrganizationModelSalesSchema,
547
+ prospecting: OrganizationModelProspectingSchema,
548
+ projects: OrganizationModelProjectsSchema,
549
+ identity: IdentityDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_IDENTITY),
550
+ customers: CustomersDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CUSTOMERS),
551
+ offerings: OfferingsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_OFFERINGS),
552
+ roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
553
+ goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
554
+ statuses: StatusesDomainSchema.default({ entries: [] }),
555
+ operations: OperationsDomainSchema.default({ entries: [] }),
556
+ knowledge: KnowledgeDomainSchema.default({ nodes: [] })
557
+ });
558
+ function addIssue(ctx, path, message) {
559
+ ctx.addIssue({
560
+ code: z.ZodIssueCode.custom,
561
+ path,
562
+ message
563
+ });
564
+ }
565
+ function collectIds(items, ctx, collectionPath, label) {
566
+ const itemsById = /* @__PURE__ */ new Map();
567
+ items.forEach((item, index) => {
568
+ if (itemsById.has(item.id)) {
569
+ addIssue(ctx, [...collectionPath, index, "id"], `${label} id "${item.id}" must be unique`);
570
+ return;
571
+ }
572
+ itemsById.set(item.id, item);
573
+ });
574
+ return itemsById;
575
+ }
576
+ var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
577
+ ["crm", "sales.crm"],
578
+ ["lead-gen", "sales.lead-gen"],
579
+ ["submitted-requests", "monitoring.submitted-requests"]
580
+ ]);
581
+ function hasFeature(featuresById, featureId) {
582
+ return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
583
+ }
584
+ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
585
+ const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
586
+ model.features.forEach((feature, featureIndex) => {
587
+ const segments = feature.id.split(".");
588
+ if (segments.length > 1) {
589
+ const parentId = segments.slice(0, -1).join(".");
590
+ if (!featuresById.has(parentId)) {
591
+ addIssue(
592
+ ctx,
593
+ ["features", featureIndex, "id"],
594
+ `Feature "${feature.id}" references unknown parent "${parentId}"`
595
+ );
596
+ }
597
+ }
598
+ const hasChildren = model.features.some(
599
+ (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
600
+ );
601
+ if (hasChildren && feature.enabled) {
602
+ const hasEnabledDescendant = model.features.some(
603
+ (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
604
+ );
605
+ if (!hasEnabledDescendant) {
606
+ addIssue(
607
+ ctx,
608
+ ["features", featureIndex, "enabled"],
609
+ `Feature "${feature.id}" is enabled but has no enabled descendants`
610
+ );
611
+ }
612
+ }
613
+ });
614
+ const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
615
+ model.offerings.products.forEach((product, productIndex) => {
616
+ product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
617
+ if (!segmentsById.has(segmentId)) {
618
+ addIssue(
619
+ ctx,
620
+ ["offerings", "products", productIndex, "targetSegmentIds", segmentIndex],
621
+ `Product "${product.id}" references unknown customer segment "${segmentId}"`
622
+ );
623
+ }
624
+ });
625
+ if (product.deliveryFeatureId !== void 0 && !hasFeature(featuresById, product.deliveryFeatureId)) {
626
+ addIssue(
627
+ ctx,
628
+ ["offerings", "products", productIndex, "deliveryFeatureId"],
629
+ `Product "${product.id}" references unknown delivery feature "${product.deliveryFeatureId}"`
630
+ );
631
+ }
632
+ });
633
+ model.goals.objectives.forEach((objective, index) => {
634
+ if (objective.periodEnd <= objective.periodStart) {
635
+ addIssue(
636
+ ctx,
637
+ ["goals", "objectives", index, "periodEnd"],
638
+ `Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
639
+ );
640
+ }
641
+ });
642
+ const rolesById = new Map(model.roles.roles.map((role) => [role.id, role]));
643
+ model.roles.roles.forEach((role, roleIndex) => {
644
+ if (role.reportsToId !== void 0 && !rolesById.has(role.reportsToId)) {
645
+ addIssue(
646
+ ctx,
647
+ ["roles", "roles", roleIndex, "reportsToId"],
648
+ `Role "${role.id}" references unknown reportsToId "${role.reportsToId}"`
649
+ );
650
+ }
651
+ });
652
+ });
653
+
654
+ // ../core/src/organization-model/graph/schema.ts
655
+ var OrganizationGraphNodeKindSchema = z.enum([
656
+ "organization",
657
+ "feature",
658
+ "surface",
659
+ "entity",
660
+ "capability",
661
+ "resource",
662
+ "knowledge"
663
+ ]);
664
+ var OrganizationGraphEdgeKindSchema = z.enum([
665
+ "contains",
666
+ "references",
667
+ "exposes",
668
+ "maps_to",
669
+ "operates-on",
670
+ "uses",
671
+ "governs"
672
+ ]);
673
+ var OrganizationGraphNodeSchema = z.object({
674
+ id: z.string().trim().min(1).max(200),
675
+ kind: OrganizationGraphNodeKindSchema,
676
+ label: LabelSchema,
677
+ sourceId: z.string().trim().min(1).max(255).optional(),
678
+ description: DescriptionSchema.optional(),
679
+ icon: IconNameSchema.optional(),
680
+ enabled: z.boolean().optional(),
681
+ featureId: z.string().trim().min(1).max(100).optional(),
682
+ resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]).optional()
683
+ });
684
+ var OrganizationGraphEdgeSchema = z.object({
685
+ id: z.string().trim().min(1).max(250),
686
+ kind: OrganizationGraphEdgeKindSchema,
687
+ sourceId: z.string().trim().min(1).max(200),
688
+ targetId: z.string().trim().min(1).max(200),
689
+ label: z.string().trim().min(1).max(120).optional(),
690
+ relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
691
+ });
692
+ var OrganizationGraphSchema = z.object({
693
+ version: z.literal(1),
694
+ organizationModelVersion: OrganizationModelSchema.shape.version,
695
+ nodes: z.array(OrganizationGraphNodeSchema),
696
+ edges: z.array(OrganizationGraphEdgeSchema)
697
+ });
698
+ var BuildOrganizationGraphInputSchema = z.object({
699
+ organizationModel: OrganizationModelSchema,
700
+ commandViewData: z.unknown().optional()
701
+ });
702
+
703
+ // ../core/src/organization-model/graph/build.ts
704
+ function nodeId(kind, sourceId) {
705
+ return kind === "organization" ? "organization-model" : `${kind}:${sourceId ?? ""}`;
706
+ }
707
+ function edgeId(kind, sourceId, targetId, variant) {
708
+ return variant ? `edge:${kind}:${variant}:${sourceId}:${targetId}` : `edge:${kind}:${sourceId}:${targetId}`;
709
+ }
710
+ function pushUniqueNode(nodes, seen, node) {
711
+ if (seen.has(node.id)) return;
712
+ seen.add(node.id);
713
+ nodes.push(node);
714
+ }
715
+ function pushUniqueEdge(edges, seen, edge) {
716
+ if (seen.has(edge.id)) return;
717
+ seen.add(edge.id);
718
+ edges.push(edge);
719
+ }
720
+ function upsertResourceNode(nodes, seen, resourceNodesById, node) {
721
+ const existing = resourceNodesById.get(node.id);
722
+ if (existing) {
723
+ if (!existing.label || existing.label === existing.sourceId) {
724
+ existing.label = node.label;
725
+ }
726
+ if (!existing.description && node.description) {
727
+ existing.description = node.description;
728
+ }
729
+ if (!existing.sourceId && node.sourceId) {
730
+ existing.sourceId = node.sourceId;
731
+ }
732
+ if (!existing.resourceType && node.resourceType) {
733
+ existing.resourceType = node.resourceType;
734
+ }
735
+ return existing;
736
+ }
737
+ resourceNodesById.set(node.id, node);
738
+ pushUniqueNode(nodes, seen, node);
739
+ return node;
740
+ }
741
+ function ensureResourceNode(nodes, seen, resourceNodesById, resourceId) {
742
+ const existing = resourceNodesById.get(nodeId("resource", resourceId));
743
+ if (existing) return existing;
744
+ return upsertResourceNode(nodes, seen, resourceNodesById, {
745
+ id: nodeId("resource", resourceId),
746
+ kind: "resource",
747
+ label: resourceId,
748
+ sourceId: resourceId
749
+ });
750
+ }
751
+ function normalizeCommandViewResourceType(resourceType) {
752
+ return resourceType === "human" ? "human_checkpoint" : resourceType;
753
+ }
754
+ function collectCommandViewResources(commandViewData) {
755
+ return [
756
+ ...commandViewData.workflows,
757
+ ...commandViewData.agents,
758
+ ...commandViewData.triggers,
759
+ ...commandViewData.integrations,
760
+ ...commandViewData.externalResources,
761
+ ...commandViewData.humanCheckpoints
762
+ ];
763
+ }
764
+ function pushResourceLinks(edges, edgeIds, resourceNodeId, links) {
765
+ for (const link of links ?? []) {
766
+ pushUniqueEdge(edges, edgeIds, {
767
+ id: edgeId(link.kind, resourceNodeId, link.nodeId),
768
+ kind: link.kind,
769
+ sourceId: resourceNodeId,
770
+ targetId: link.nodeId
771
+ });
772
+ }
773
+ }
774
+ function buildOrganizationGraph(input) {
775
+ const parsed = BuildOrganizationGraphInputSchema.parse(input);
776
+ const organizationModel = parsed.organizationModel;
777
+ const commandViewData = parsed.commandViewData;
778
+ const nodes = [];
779
+ const edges = [];
780
+ const nodeIds = /* @__PURE__ */ new Set();
781
+ const edgeIds = /* @__PURE__ */ new Set();
782
+ const resourceNodesById = /* @__PURE__ */ new Map();
783
+ const organizationNode = {
784
+ id: nodeId("organization"),
785
+ kind: "organization",
786
+ label: "Organization Model"
787
+ };
788
+ pushUniqueNode(nodes, nodeIds, organizationNode);
789
+ for (const feature of [...organizationModel.features].sort((a, b) => a.id.localeCompare(b.id))) {
790
+ const id = nodeId("feature", feature.id);
791
+ pushUniqueNode(nodes, nodeIds, {
792
+ id,
793
+ kind: "feature",
794
+ label: feature.label,
795
+ sourceId: feature.id,
796
+ description: feature.description,
797
+ icon: feature.icon,
798
+ enabled: feature.enabled,
799
+ featureId: feature.id
800
+ });
801
+ pushUniqueEdge(edges, edgeIds, {
802
+ id: edgeId("contains", organizationNode.id, id),
803
+ kind: "contains",
804
+ sourceId: organizationNode.id,
805
+ targetId: id
806
+ });
807
+ const parentId = feature.id.includes(".") ? feature.id.slice(0, feature.id.lastIndexOf(".")) : void 0;
808
+ if (parentId) {
809
+ pushUniqueEdge(edges, edgeIds, {
810
+ id: edgeId("contains", nodeId("feature", parentId), id),
811
+ kind: "contains",
812
+ sourceId: nodeId("feature", parentId),
813
+ targetId: id
814
+ });
815
+ }
816
+ }
817
+ for (const node of [...organizationModel.knowledge?.nodes ?? []].sort((a, b) => a.id.localeCompare(b.id))) {
818
+ const id = nodeId("knowledge", node.id);
819
+ pushUniqueNode(nodes, nodeIds, {
820
+ id,
821
+ kind: "knowledge",
822
+ label: node.title,
823
+ sourceId: node.id,
824
+ description: node.summary,
825
+ icon: node.icon
826
+ });
827
+ pushUniqueEdge(edges, edgeIds, {
828
+ id: edgeId("contains", organizationNode.id, id),
829
+ kind: "contains",
830
+ sourceId: organizationNode.id,
831
+ targetId: id
832
+ });
833
+ for (const link of node.links) {
834
+ pushUniqueEdge(edges, edgeIds, {
835
+ id: edgeId("governs", id, link.nodeId),
836
+ kind: "governs",
837
+ sourceId: id,
838
+ targetId: link.nodeId
839
+ });
840
+ }
841
+ }
842
+ if (commandViewData) {
843
+ const commandViewResources = collectCommandViewResources(commandViewData).sort(
844
+ (a, b) => a.resourceId.localeCompare(b.resourceId)
845
+ );
846
+ for (const resource of commandViewResources) {
847
+ const id = nodeId("resource", resource.resourceId);
848
+ const resourceNode = upsertResourceNode(nodes, nodeIds, resourceNodesById, {
849
+ id,
850
+ kind: "resource",
851
+ label: resource.name,
852
+ sourceId: resource.resourceId,
853
+ description: resource.description,
854
+ resourceType: normalizeCommandViewResourceType(resource.type)
855
+ });
856
+ pushUniqueEdge(edges, edgeIds, {
857
+ id: edgeId("contains", organizationNode.id, resourceNode.id),
858
+ kind: "contains",
859
+ sourceId: organizationNode.id,
860
+ targetId: resourceNode.id
861
+ });
862
+ pushResourceLinks(edges, edgeIds, resourceNode.id, resource.links);
863
+ }
864
+ for (const relationship of [...commandViewData.edges].sort((a, b) => a.id.localeCompare(b.id))) {
865
+ const sourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.source);
866
+ const targetNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, relationship.target);
867
+ pushUniqueEdge(edges, edgeIds, {
868
+ id: edgeId("contains", organizationNode.id, sourceNode.id),
869
+ kind: "contains",
870
+ sourceId: organizationNode.id,
871
+ targetId: sourceNode.id
872
+ });
873
+ pushUniqueEdge(edges, edgeIds, {
874
+ id: edgeId("contains", organizationNode.id, targetNode.id),
875
+ kind: "contains",
876
+ sourceId: organizationNode.id,
877
+ targetId: targetNode.id
878
+ });
879
+ pushUniqueEdge(edges, edgeIds, {
880
+ id: edgeId("references", sourceNode.id, targetNode.id, relationship.relationship),
881
+ kind: "references",
882
+ sourceId: sourceNode.id,
883
+ targetId: targetNode.id,
884
+ label: relationship.relationship,
885
+ relationshipType: relationship.relationship
886
+ });
887
+ }
888
+ }
889
+ const graph = {
890
+ version: 1,
891
+ organizationModelVersion: organizationModel.version,
892
+ nodes,
893
+ edges
894
+ };
895
+ return OrganizationGraphSchema.parse(graph);
896
+ }
897
+
898
+ // src/features/operations/organization-graph/organizationGraphDetail.ts
899
+ var NODE_KIND_LABELS = {
900
+ organization: "Organization root",
901
+ feature: "Feature",
902
+ surface: "Surface",
903
+ entity: "Entity",
904
+ capability: "Capability",
905
+ resource: "Resource",
906
+ knowledge: "Knowledge"
907
+ };
908
+ var NODE_KIND_MEANINGS = {
909
+ organization: "The root of the shared organization model and the parent for every derived node.",
910
+ feature: "A feature that enables or disables downstream surfaces and model surfaces.",
911
+ surface: "A user-facing or operational surface that exposes feature behavior in the model.",
912
+ entity: "A shared business concept that can be referenced by surfaces, resources, or capabilities.",
913
+ capability: "A reusable capability that can be attached to a feature or surface.",
914
+ resource: "A concrete command-view or mapped resource that bridges execution topology into the model.",
915
+ knowledge: "An operational knowledge node that documents a process, strategy, or runbook in the org model."
916
+ };
917
+ var EDGE_KIND_LABELS = {
918
+ contains: "Containment",
919
+ references: "Reference",
920
+ exposes: "Exposure",
921
+ maps_to: "Mapping",
922
+ "operates-on": "Operates on",
923
+ uses: "Uses",
924
+ governs: "Governs"
925
+ };
926
+ var EDGE_KIND_MEANINGS = {
927
+ contains: "A hierarchy or ownership link inside the shared graph.",
928
+ references: "A semantic association or dependency between two graph nodes.",
929
+ exposes: "A feature enables a surface to be visible or reachable.",
930
+ maps_to: "A concrete resource is aligned to a domain, entity, capability, or surface.",
931
+ "operates-on": "A concrete resource operates on an Organization Model node.",
932
+ uses: "A concrete resource depends on another graph node or integration.",
933
+ governs: "A knowledge node governs or provides authoritative guidance for another node."
934
+ };
935
+ var RELATIONSHIP_MEANINGS = {
936
+ triggers: "Executable handoff: the source resource starts the target resource.",
937
+ uses: "Operational dependency: the source resource relies on the target integration.",
938
+ approval: "Human gate: the source resource pauses for approval at the target checkpoint."
939
+ };
940
+ function titleCase(value) {
941
+ return value.replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
942
+ }
943
+ function getGraphIndex(graph) {
944
+ const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
945
+ const edgesById = new Map(graph.edges.map((edge) => [edge.id, edge]));
946
+ return { nodesById, edgesById };
947
+ }
948
+ function getNodeKindLabel(kind) {
949
+ return NODE_KIND_LABELS[kind];
950
+ }
951
+ function getNodeMeaning(node) {
952
+ const baseMeaning = NODE_KIND_MEANINGS[node.kind];
953
+ if (node.kind === "feature") {
954
+ return node.enabled === false ? `${baseMeaning} This feature is currently disabled in the organization model.` : `${baseMeaning} This feature is currently enabled in the organization model.`;
955
+ }
956
+ if (node.kind === "resource" && node.resourceType) {
957
+ return `${baseMeaning} Resource type: ${titleCase(node.resourceType)}.`;
958
+ }
959
+ if (node.description) {
960
+ return `${baseMeaning} ${node.description}`;
961
+ }
962
+ return baseMeaning;
963
+ }
964
+ function getEdgeKindLabel(kind) {
965
+ return EDGE_KIND_LABELS[kind];
966
+ }
967
+ function getEdgeMeaning(edge, sourceNode, targetNode) {
968
+ const sourceLabel = sourceNode?.label ?? edge.sourceId;
969
+ const targetLabel = targetNode?.label ?? edge.targetId;
970
+ if (edge.relationshipType) {
971
+ const relationshipMeaning = RELATIONSHIP_MEANINGS[edge.relationshipType];
972
+ return `${relationshipMeaning} The graph renders the link from ${sourceLabel} to ${targetLabel} as a ${getEdgeKindLabel(edge.kind).toLowerCase()} edge.`;
973
+ }
974
+ return `${EDGE_KIND_MEANINGS[edge.kind]} This link connects ${sourceLabel} to ${targetLabel}.`;
975
+ }
976
+ function countByKind(nodes) {
977
+ const counts = /* @__PURE__ */ new Map();
978
+ for (const node of nodes) {
979
+ counts.set(node.kind, (counts.get(node.kind) ?? 0) + 1);
980
+ }
981
+ return [...counts.entries()].map(([kind, count]) => ({
982
+ kind,
983
+ label: getNodeKindLabel(kind),
984
+ count
985
+ })).sort((left, right) => left.label.localeCompare(right.label));
986
+ }
987
+ function uniqueNodesById(nodes) {
988
+ const byId = /* @__PURE__ */ new Map();
989
+ for (const node of nodes) {
990
+ byId.set(node.id, node);
991
+ }
992
+ return [...byId.values()];
993
+ }
994
+ function uniqueEdgesById(edges) {
995
+ const byId = /* @__PURE__ */ new Map();
996
+ for (const edge of edges) {
997
+ byId.set(edge.id, edge);
998
+ }
999
+ return [...byId.values()];
1000
+ }
1001
+ function buildNodeState(graph, node, nodesById) {
1002
+ const incidentEdges = graph.edges.filter((edge) => edge.sourceId === node.id || edge.targetId === node.id);
1003
+ const incomingEdges = incidentEdges.filter((edge) => edge.targetId === node.id);
1004
+ const outgoingEdges = incidentEdges.filter((edge) => edge.sourceId === node.id);
1005
+ const adjacentNodes = uniqueNodesById(
1006
+ incidentEdges.map((edge) => edge.sourceId === node.id ? nodesById.get(edge.targetId) : nodesById.get(edge.sourceId)).filter((value) => Boolean(value))
1007
+ );
1008
+ const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
1009
+ const contexts = incidentEdges.filter(
1010
+ (edge) => edge.sourceId === node.id ? edge.targetId === adjacentNode.id : edge.sourceId === adjacentNode.id
1011
+ ).map(
1012
+ (edge) => `${edge.sourceId === node.id ? "outgoing" : "incoming"} via ${edge.label ?? getEdgeKindLabel(edge.kind).toLowerCase()}`
1013
+ );
1014
+ return {
1015
+ id: adjacentNode.id,
1016
+ label: adjacentNode.label,
1017
+ kind: adjacentNode.kind,
1018
+ kindLabel: getNodeKindLabel(adjacentNode.kind),
1019
+ context: contexts.slice(0, 2).join(", ")
1020
+ };
1021
+ });
1022
+ const relatedEdges = incidentEdges.slice().sort((left, right) => left.id.localeCompare(right.id)).map((edge) => {
1023
+ const connectedId = edge.sourceId === node.id ? edge.targetId : edge.sourceId;
1024
+ const connectedNode = nodesById.get(connectedId);
1025
+ return {
1026
+ id: edge.id,
1027
+ label: edge.label ?? edge.relationshipType ?? getEdgeKindLabel(edge.kind),
1028
+ kind: edge.kind,
1029
+ kindLabel: getEdgeKindLabel(edge.kind),
1030
+ context: `${edge.sourceId === node.id ? "outgoing" : "incoming"}${connectedNode ? ` to ${connectedNode.label}` : ""}`
1031
+ };
1032
+ });
1033
+ const metadata = [
1034
+ { label: "Graph ID", value: node.id },
1035
+ { label: "Source ID", value: node.sourceId ?? node.id },
1036
+ { label: "Kind", value: getNodeKindLabel(node.kind) }
1037
+ ];
1038
+ if (node.enabled !== void 0) {
1039
+ metadata.push({ label: "Enabled", value: node.enabled ? "Yes" : "No" });
1040
+ }
1041
+ if (node.featureId) {
1042
+ metadata.push({ label: "Feature ID", value: node.featureId });
1043
+ }
1044
+ if (node.resourceType) {
1045
+ metadata.push({ label: "Resource Type", value: titleCase(node.resourceType) });
1046
+ }
1047
+ const meaningfulEdges = incidentEdges.filter((edge) => edge.kind !== "contains" || edge.relationshipType);
1048
+ return {
1049
+ state: "node",
1050
+ title: node.label,
1051
+ semanticCategory: getNodeKindLabel(node.kind),
1052
+ operationalMeaning: getNodeMeaning(node),
1053
+ description: node.description,
1054
+ metrics: [
1055
+ {
1056
+ label: "Connected edges",
1057
+ value: String(incidentEdges.length),
1058
+ hint: "All direct relationships attached to this node"
1059
+ },
1060
+ { label: "Incoming", value: String(incomingEdges.length), hint: "Edges that point into this node" },
1061
+ { label: "Outgoing", value: String(outgoingEdges.length), hint: "Edges that start at this node" },
1062
+ {
1063
+ label: "Meaningful links",
1064
+ value: String(meaningfulEdges.length),
1065
+ hint: "Edges with semantic or operational meaning"
1066
+ }
1067
+ ],
1068
+ metadata,
1069
+ adjacentKindCounts: countByKind(adjacentNodes),
1070
+ node,
1071
+ relatedNodes,
1072
+ relatedEdges
1073
+ };
1074
+ }
1075
+ function buildEdgeState(graph, edge, nodesById) {
1076
+ const sourceNode = nodesById.get(edge.sourceId);
1077
+ const targetNode = nodesById.get(edge.targetId);
1078
+ const sourceIncidentEdges = graph.edges.filter(
1079
+ (candidate) => candidate.sourceId === edge.sourceId || candidate.targetId === edge.sourceId
1080
+ );
1081
+ const targetIncidentEdges = graph.edges.filter(
1082
+ (candidate) => candidate.sourceId === edge.targetId || candidate.targetId === edge.targetId
1083
+ );
1084
+ const adjacentNodes = uniqueNodesById(
1085
+ [...sourceIncidentEdges, ...targetIncidentEdges].map((candidate) => {
1086
+ if (candidate.sourceId === edge.sourceId) return nodesById.get(candidate.targetId);
1087
+ if (candidate.targetId === edge.sourceId) return nodesById.get(candidate.sourceId);
1088
+ if (candidate.sourceId === edge.targetId) return nodesById.get(candidate.targetId);
1089
+ if (candidate.targetId === edge.targetId) return nodesById.get(candidate.sourceId);
1090
+ return null;
1091
+ }).filter((value) => Boolean(value)).filter((candidate) => candidate.id !== edge.sourceId && candidate.id !== edge.targetId)
1092
+ );
1093
+ const sourceNeighborIds = new Set(
1094
+ sourceIncidentEdges.map((candidate) => {
1095
+ if (candidate.sourceId === edge.sourceId) return candidate.targetId;
1096
+ if (candidate.targetId === edge.sourceId) return candidate.sourceId;
1097
+ return null;
1098
+ }).filter((value) => Boolean(value))
1099
+ );
1100
+ const targetNeighborIds = new Set(
1101
+ targetIncidentEdges.map((candidate) => {
1102
+ if (candidate.sourceId === edge.targetId) return candidate.targetId;
1103
+ if (candidate.targetId === edge.targetId) return candidate.sourceId;
1104
+ return null;
1105
+ }).filter((value) => Boolean(value))
1106
+ );
1107
+ const sharedNeighborCount = [...sourceNeighborIds].filter((neighborId) => targetNeighborIds.has(neighborId)).length;
1108
+ const relatedNodes = adjacentNodes.slice().sort((left, right) => left.label.localeCompare(right.label)).map((adjacentNode) => {
1109
+ const sourceContext = sourceIncidentEdges.some(
1110
+ (candidate) => candidate.sourceId === edge.sourceId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.sourceId && candidate.sourceId === adjacentNode.id
1111
+ );
1112
+ const targetContext = targetIncidentEdges.some(
1113
+ (candidate) => candidate.sourceId === edge.targetId && candidate.targetId === adjacentNode.id || candidate.targetId === edge.targetId && candidate.sourceId === adjacentNode.id
1114
+ );
1115
+ const contextParts = [];
1116
+ if (sourceContext) contextParts.push("source neighborhood");
1117
+ if (targetContext) contextParts.push("target neighborhood");
1118
+ return {
1119
+ id: adjacentNode.id,
1120
+ label: adjacentNode.label,
1121
+ kind: adjacentNode.kind,
1122
+ kindLabel: getNodeKindLabel(adjacentNode.kind),
1123
+ context: contextParts.join(" + ")
1124
+ };
1125
+ });
1126
+ const surroundingEdges = uniqueEdgesById([...sourceIncidentEdges, ...targetIncidentEdges]).filter((candidate) => candidate.id !== edge.id).sort((left, right) => left.id.localeCompare(right.id)).map((candidate) => {
1127
+ const leftNode = nodesById.get(candidate.sourceId);
1128
+ const rightNode = nodesById.get(candidate.targetId);
1129
+ return {
1130
+ id: candidate.id,
1131
+ label: candidate.label ?? candidate.relationshipType ?? getEdgeKindLabel(candidate.kind),
1132
+ kind: candidate.kind,
1133
+ kindLabel: getEdgeKindLabel(candidate.kind),
1134
+ context: `${leftNode?.label ?? candidate.sourceId} -> ${rightNode?.label ?? candidate.targetId}`
1135
+ };
1136
+ });
1137
+ const metadata = [
1138
+ { label: "Graph ID", value: edge.id },
1139
+ { label: "Source ID", value: edge.sourceId },
1140
+ { label: "Target ID", value: edge.targetId },
1141
+ { label: "Edge kind", value: getEdgeKindLabel(edge.kind) }
1142
+ ];
1143
+ if (edge.label) {
1144
+ metadata.push({ label: "Label", value: edge.label });
1145
+ }
1146
+ if (edge.relationshipType) {
1147
+ metadata.push({ label: "Relationship", value: titleCase(edge.relationshipType) });
1148
+ }
1149
+ return {
1150
+ state: "edge",
1151
+ title: edge.label ?? `${sourceNode?.label ?? edge.sourceId} \u2192 ${targetNode?.label ?? edge.targetId}`,
1152
+ semanticCategory: edge.relationshipType ? titleCase(edge.relationshipType) : getEdgeKindLabel(edge.kind),
1153
+ operationalMeaning: getEdgeMeaning(edge, sourceNode, targetNode),
1154
+ description: edge.label,
1155
+ metrics: [
1156
+ {
1157
+ label: "Source degree",
1158
+ value: String(sourceIncidentEdges.length),
1159
+ hint: "Relationships attached to the source node"
1160
+ },
1161
+ {
1162
+ label: "Target degree",
1163
+ value: String(targetIncidentEdges.length),
1164
+ hint: "Relationships attached to the target node"
1165
+ },
1166
+ {
1167
+ label: "Nearby nodes",
1168
+ value: String(adjacentNodes.length),
1169
+ hint: "Unique nodes in the source and target neighborhoods"
1170
+ },
1171
+ {
1172
+ label: "Shared peers",
1173
+ value: String(sharedNeighborCount),
1174
+ hint: "Neighbors that appear in both node neighborhoods"
1175
+ }
1176
+ ],
1177
+ metadata,
1178
+ adjacentKindCounts: countByKind(adjacentNodes),
1179
+ edge,
1180
+ sourceNode,
1181
+ targetNode,
1182
+ relatedNodes,
1183
+ relatedEdges: surroundingEdges
1184
+ };
1185
+ }
1186
+ function getOrganizationGraphDetailState(graph, selectedElement) {
1187
+ if (!selectedElement) {
1188
+ return {
1189
+ state: "empty",
1190
+ title: "No element selected",
1191
+ semanticCategory: "Selection",
1192
+ operationalMeaning: "Select a node or edge to inspect its semantic and operational context.",
1193
+ metrics: [],
1194
+ metadata: [],
1195
+ adjacentKindCounts: []
1196
+ };
1197
+ }
1198
+ if (!graph) {
1199
+ return {
1200
+ state: "missing",
1201
+ title: "Graph unavailable",
1202
+ semanticCategory: selectedElement.type === "node" ? "Selected node" : "Selected edge",
1203
+ operationalMeaning: "The graph data is not available yet, so this selection cannot be resolved.",
1204
+ metrics: [],
1205
+ metadata: [{ label: "Selected ID", value: selectedElement.id }],
1206
+ adjacentKindCounts: [],
1207
+ missingId: selectedElement.id
1208
+ };
1209
+ }
1210
+ const { nodesById, edgesById } = getGraphIndex(graph);
1211
+ if (selectedElement.type === "node") {
1212
+ const node = nodesById.get(selectedElement.id);
1213
+ if (!node) {
1214
+ return {
1215
+ state: "missing",
1216
+ title: "Selected node unavailable",
1217
+ semanticCategory: "Node",
1218
+ operationalMeaning: "The selected node is no longer present in the current graph build.",
1219
+ metrics: [],
1220
+ metadata: [{ label: "Selected ID", value: selectedElement.id }],
1221
+ adjacentKindCounts: [],
1222
+ missingId: selectedElement.id
1223
+ };
1224
+ }
1225
+ return buildNodeState(graph, node, nodesById);
1226
+ }
1227
+ const edge = edgesById.get(selectedElement.id);
1228
+ if (!edge) {
1229
+ return {
1230
+ state: "missing",
1231
+ title: "Selected edge unavailable",
1232
+ semanticCategory: "Edge",
1233
+ operationalMeaning: "The selected edge is no longer present in the current graph build.",
1234
+ metrics: [],
1235
+ metadata: [{ label: "Selected ID", value: selectedElement.id }],
1236
+ adjacentKindCounts: [],
1237
+ missingId: selectedElement.id
1238
+ };
1239
+ }
1240
+ return buildEdgeState(graph, edge, nodesById);
1241
+ }
1242
+ function getNodeKindColor(kind) {
1243
+ switch (kind) {
1244
+ case "organization":
1245
+ return "gray";
1246
+ case "feature":
1247
+ return "blue";
1248
+ case "domain":
1249
+ return "violet";
1250
+ case "surface":
1251
+ return "cyan";
1252
+ case "entity":
1253
+ return "pink";
1254
+ case "capability":
1255
+ return "green";
1256
+ case "resource":
1257
+ return "orange";
1258
+ default:
1259
+ return "gray";
1260
+ }
1261
+ }
1262
+ function getEdgeKindColor(kind) {
1263
+ switch (kind) {
1264
+ case "contains":
1265
+ return "gray";
1266
+ case "references":
1267
+ return "cyan";
1268
+ case "exposes":
1269
+ return "blue";
1270
+ case "maps_to":
1271
+ return "violet";
1272
+ default:
1273
+ return "gray";
1274
+ }
1275
+ }
1276
+ function getNodeKindLabel2(kind) {
1277
+ switch (kind) {
1278
+ case "organization":
1279
+ return "Organization root";
1280
+ case "feature":
1281
+ return "Feature gate";
1282
+ case "domain":
1283
+ return "Domain boundary";
1284
+ case "surface":
1285
+ return "Surface";
1286
+ case "entity":
1287
+ return "Entity";
1288
+ case "capability":
1289
+ return "Capability";
1290
+ case "resource":
1291
+ return "Resource";
1292
+ default:
1293
+ return kind;
1294
+ }
1295
+ }
1296
+ function getNodeIconFallbackKind(kind) {
1297
+ if (kind === "knowledge") return "knowledge";
1298
+ if (kind === "feature") return "feature";
1299
+ if (kind === "resource") return "resource";
1300
+ return "unknown";
1301
+ }
1302
+ function titleCase2(value) {
1303
+ return value.charAt(0).toUpperCase() + value.slice(1);
1304
+ }
1305
+ function MetricCard({ metric }) {
1306
+ return /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
1307
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: metric.label }),
1308
+ /* @__PURE__ */ jsx(Text, { size: "lg", fw: 800, children: metric.value }),
1309
+ metric.hint ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: metric.hint }) : null
1310
+ ] }) });
1311
+ }
1312
+ function RelatedItemCard({ item, itemType }) {
1313
+ const badgeColor = itemType === "node" ? getNodeKindColor(item.kind) : getEdgeKindColor(item.kind);
1314
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1315
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
1316
+ /* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
1317
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: badgeColor, children: item.kindLabel })
1318
+ ] }),
1319
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.context }),
1320
+ /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.id })
1321
+ ] }) });
1322
+ }
1323
+ function getStatusColor(value) {
1324
+ switch (value) {
1325
+ case "failed":
1326
+ return "red";
1327
+ case "warning":
1328
+ return "yellow";
1329
+ case "running":
1330
+ case "processing":
1331
+ return "blue";
1332
+ case "completed":
1333
+ return "green";
1334
+ case "pending":
1335
+ return "orange";
1336
+ case "expired":
1337
+ return "gray";
1338
+ default:
1339
+ return "gray";
1340
+ }
1341
+ }
1342
+ function FollowUpSectionCard({ section }) {
1343
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1344
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
1345
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
1346
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: section.title }),
1347
+ section.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: section.description }) : null
1348
+ ] }),
1349
+ section.primaryAction ? /* @__PURE__ */ jsx(
1350
+ Button,
1351
+ {
1352
+ size: "xs",
1353
+ variant: "light",
1354
+ component: "a",
1355
+ href: section.primaryAction.href,
1356
+ target: "_blank",
1357
+ rel: "noreferrer",
1358
+ children: section.primaryAction.label
1359
+ }
1360
+ ) : null
1361
+ ] }),
1362
+ section.items.length > 0 ? /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: section.items.map((item) => /* @__PURE__ */ jsx(
1363
+ Paper,
1364
+ {
1365
+ withBorder: true,
1366
+ radius: "md",
1367
+ p: "sm",
1368
+ component: "a",
1369
+ href: item.href,
1370
+ target: "_blank",
1371
+ rel: "noreferrer",
1372
+ style: { display: "block", textDecoration: "none", color: "inherit" },
1373
+ children: /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1374
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", align: "flex-start", children: [
1375
+ /* @__PURE__ */ jsx(Text, { fw: 700, size: "sm", style: { lineHeight: 1.2 }, children: item.label }),
1376
+ item.badgeLabel ? /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: item.badgeColor ?? getStatusColor(item.badgeLabel), children: item.badgeLabel }) : null
1377
+ ] }),
1378
+ item.description ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: item.description }) : null,
1379
+ item.meta ? /* @__PURE__ */ jsx(Text, { size: "xs", ff: "monospace", c: "dimmed", children: item.meta }) : null
1380
+ ] })
1381
+ },
1382
+ item.id
1383
+ )) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: section.emptyMessage })
1384
+ ] }) });
1385
+ }
1386
+ function OrganizationGraphDetailPanel({
1387
+ graph,
1388
+ selectedElement,
1389
+ supplementalSummary,
1390
+ followUpSections,
1391
+ expandAroundPanel,
1392
+ onClearSelection,
1393
+ className
1394
+ }) {
1395
+ const state = getOrganizationGraphDetailState(graph, selectedElement);
1396
+ if (state.state === "empty") {
1397
+ 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" }) });
1398
+ }
1399
+ if (state.state === "missing") {
1400
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
1401
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
1402
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1403
+ /* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", children: state.title }),
1404
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
1405
+ ] }),
1406
+ onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
1407
+ ] }),
1408
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: "gray", children: state.semanticCategory }),
1409
+ /* @__PURE__ */ jsxs(Paper, { withBorder: true, radius: "md", p: "sm", children: [
1410
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Selected ID" }),
1411
+ /* @__PURE__ */ jsx(Text, { size: "sm", ff: "monospace", children: state.missingId })
1412
+ ] })
1413
+ ] }) });
1414
+ }
1415
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "lg", p: "md", className, children: /* @__PURE__ */ jsxs(Stack, { gap: "md", children: [
1416
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", children: [
1417
+ /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
1418
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1419
+ /* @__PURE__ */ jsx(Badge, { variant: "light", color: "violet", children: state.semanticCategory }),
1420
+ state.state === "node" ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: state.node.enabled === false ? "gray" : "green", children: state.node.enabled === false ? "Disabled" : "Enabled" }) : null,
1421
+ state.state === "edge" && state.edge.relationshipType ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "orange", children: titleCase2(state.edge.relationshipType) }) : null
1422
+ ] }),
1423
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", align: "center", children: [
1424
+ state.state === "node" ? /* @__PURE__ */ jsx(
1425
+ SemanticIcon,
1426
+ {
1427
+ token: state.node.icon,
1428
+ fallbackKind: getNodeIconFallbackKind(state.node.kind),
1429
+ size: 18,
1430
+ style: { color: "var(--color-text-subtle)" }
1431
+ }
1432
+ ) : null,
1433
+ /* @__PURE__ */ jsx(Text, { fw: 800, size: "lg", style: { minWidth: 0 }, children: state.title })
1434
+ ] }),
1435
+ /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: state.operationalMeaning })
1436
+ ] }),
1437
+ onClearSelection ? /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClearSelection, children: "Clear" }) : null
1438
+ ] }),
1439
+ /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 2, md: 4 }, spacing: "sm", children: state.metrics.map((metric) => /* @__PURE__ */ jsx(MetricCard, { metric }, metric.label)) }),
1440
+ expandAroundPanel,
1441
+ supplementalSummary && (supplementalSummary.metrics.length > 0 || supplementalSummary.metadata.length > 0) ? /* @__PURE__ */ jsxs(Fragment, { children: [
1442
+ /* @__PURE__ */ jsx(
1443
+ Divider,
1444
+ {
1445
+ label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
1446
+ /* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
1447
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: supplementalSummary.title })
1448
+ ] }),
1449
+ labelPosition: "center"
1450
+ }
1451
+ ),
1452
+ supplementalSummary.description ? /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: supplementalSummary.description }) : null,
1453
+ 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,
1454
+ 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: [
1455
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
1456
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
1457
+ ] }) }, `supplemental-${item.label}`)) }) : null
1458
+ ] }) : null,
1459
+ followUpSections && followUpSections.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1460
+ /* @__PURE__ */ jsx(
1461
+ Divider,
1462
+ {
1463
+ label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
1464
+ /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
1465
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Follow-up actions" })
1466
+ ] }),
1467
+ labelPosition: "center"
1468
+ }
1469
+ ),
1470
+ /* @__PURE__ */ jsx(Stack, { gap: "sm", children: followUpSections.map((section) => /* @__PURE__ */ jsx(FollowUpSectionCard, { section }, section.title)) })
1471
+ ] }) : null,
1472
+ /* @__PURE__ */ jsx(
1473
+ Divider,
1474
+ {
1475
+ label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
1476
+ /* @__PURE__ */ jsx(IconTopologyStar3, { size: 14 }),
1477
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Linked metadata" })
1478
+ ] }),
1479
+ labelPosition: "center"
1480
+ }
1481
+ ),
1482
+ /* @__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: [
1483
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: item.label }),
1484
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 600, children: item.value })
1485
+ ] }) }, item.label)) }),
1486
+ state.adjacentKindCounts.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1487
+ /* @__PURE__ */ jsx(
1488
+ Divider,
1489
+ {
1490
+ label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
1491
+ /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
1492
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Nearby kinds" })
1493
+ ] }),
1494
+ labelPosition: "center"
1495
+ }
1496
+ ),
1497
+ /* @__PURE__ */ jsx(Group, { gap: "xs", children: state.adjacentKindCounts.map((item) => /* @__PURE__ */ jsxs(Badge, { variant: "light", color: getNodeKindColor(item.kind), children: [
1498
+ item.count,
1499
+ " ",
1500
+ item.label
1501
+ ] }, item.kind)) })
1502
+ ] }) : null,
1503
+ state.state === "edge" ? /* @__PURE__ */ jsxs(Fragment, { children: [
1504
+ /* @__PURE__ */ jsx(
1505
+ Divider,
1506
+ {
1507
+ label: /* @__PURE__ */ jsxs(Group, { gap: 6, children: [
1508
+ /* @__PURE__ */ jsx(IconShare2, { size: 14 }),
1509
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: "Endpoints" })
1510
+ ] }),
1511
+ labelPosition: "center"
1512
+ }
1513
+ ),
1514
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
1515
+ /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
1516
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Source" }),
1517
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1518
+ /* @__PURE__ */ jsx(Text, { fw: 700, children: state.sourceNode?.label ?? state.edge.sourceId }),
1519
+ /* @__PURE__ */ jsx(
1520
+ Badge,
1521
+ {
1522
+ size: "xs",
1523
+ variant: "light",
1524
+ color: state.sourceNode ? getNodeKindColor(state.sourceNode.kind) : "gray",
1525
+ children: state.sourceNode ? getNodeKindLabel2(state.sourceNode.kind) : "unresolved"
1526
+ }
1527
+ )
1528
+ ] })
1529
+ ] }) }),
1530
+ /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
1531
+ /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, c: "dimmed", children: "Target" }),
1532
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
1533
+ /* @__PURE__ */ jsx(Text, { fw: 700, children: state.targetNode?.label ?? state.edge.targetId }),
1534
+ /* @__PURE__ */ jsx(
1535
+ Badge,
1536
+ {
1537
+ size: "xs",
1538
+ variant: "light",
1539
+ color: state.targetNode ? getNodeKindColor(state.targetNode.kind) : "gray",
1540
+ children: state.targetNode ? getNodeKindLabel2(state.targetNode.kind) : "unresolved"
1541
+ }
1542
+ )
1543
+ ] })
1544
+ ] }) })
1545
+ ] })
1546
+ ] }) : null,
1547
+ /* @__PURE__ */ jsx(
1548
+ Divider,
1549
+ {
1550
+ label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding nodes" : "Direct nodes" }),
1551
+ labelPosition: "center"
1552
+ }
1553
+ ),
1554
+ 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." }),
1555
+ /* @__PURE__ */ jsx(
1556
+ Divider,
1557
+ {
1558
+ label: /* @__PURE__ */ jsx(Text, { size: "xs", tt: "uppercase", fw: 700, children: state.state === "edge" ? "Surrounding edges" : "Direct edges" }),
1559
+ labelPosition: "center"
1560
+ }
1561
+ ),
1562
+ 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." })
1563
+ ] }) });
1564
+ }
1565
+
1566
+ // src/features/operations/organization-graph/types.ts
1567
+ var ORGANIZATION_GRAPH_NODE_KIND_ORDER = [
1568
+ "organization",
1569
+ "feature",
1570
+ "surface",
1571
+ "entity",
1572
+ "capability",
1573
+ "resource",
1574
+ "knowledge"
1575
+ ];
1576
+ var ORGANIZATION_GRAPH_NODE_KIND_LABELS = {
1577
+ organization: "Organization",
1578
+ feature: "Feature",
1579
+ surface: "Surface",
1580
+ entity: "Entity",
1581
+ capability: "Capability",
1582
+ resource: "Resource",
1583
+ knowledge: "Knowledge"
1584
+ };
1585
+ var DEFAULT_ORGANIZATION_GRAPH_FILTERS = {
1586
+ search: "",
1587
+ nodeKinds: [],
1588
+ topologyPresence: "all",
1589
+ environmentStatus: "all",
1590
+ resourceTypes: [],
1591
+ showIntegrations: true,
1592
+ domainFilters: {}
1593
+ };
1594
+
1595
+ // src/features/operations/organization-graph/helpers.ts
1596
+ var TOPLOGY_EDGE_TYPES = /* @__PURE__ */ new Set(["maps_to", "triggers", "uses", "approval"]);
1597
+ function getCommandViewNodes(data) {
1598
+ return [
1599
+ ...data.agents,
1600
+ ...data.workflows,
1601
+ ...data.triggers,
1602
+ ...data.integrations,
1603
+ ...data.externalResources,
1604
+ ...data.humanCheckpoints
1605
+ ];
1606
+ }
1607
+ function getCommandViewNodeForGraphNode(node, commandViewData) {
1608
+ if (!commandViewData || node.kind !== "resource" || !node.sourceId) {
1609
+ return null;
1610
+ }
1611
+ return getCommandViewNodes(commandViewData).find((item) => item.resourceId === node.sourceId) ?? null;
1612
+ }
1613
+ function normalizeText(value) {
1614
+ return value.trim().toLowerCase();
1615
+ }
1616
+ function includesQuery(value, query) {
1617
+ if (!value) return false;
1618
+ return normalizeText(value).includes(query);
1619
+ }
1620
+ function titleCase3(value) {
1621
+ return value.replace(/_/g, " ").split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
1622
+ }
1623
+ function isTopologyEdge(edge) {
1624
+ return TOPLOGY_EDGE_TYPES.has(edge.kind) || Boolean(edge.relationshipType);
1625
+ }
1626
+ function isSemanticEdge(edge) {
1627
+ return !isTopologyEdge(edge);
1628
+ }
1629
+ function getIncidentEdges(graph, nodeId2) {
1630
+ return graph.edges.filter((edge) => edge.sourceId === nodeId2 || edge.targetId === nodeId2);
1631
+ }
1632
+ function createOrganizationGraphFilters(partial) {
1633
+ return {
1634
+ search: partial?.search ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.search,
1635
+ nodeKinds: partial?.nodeKinds ? [...partial.nodeKinds] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.nodeKinds],
1636
+ topologyPresence: partial?.topologyPresence ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.topologyPresence,
1637
+ environmentStatus: partial?.environmentStatus ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.environmentStatus,
1638
+ resourceTypes: partial?.resourceTypes ? [...partial.resourceTypes] : [...DEFAULT_ORGANIZATION_GRAPH_FILTERS.resourceTypes],
1639
+ showIntegrations: partial?.showIntegrations ?? DEFAULT_ORGANIZATION_GRAPH_FILTERS.showIntegrations,
1640
+ domainFilters: partial?.domainFilters ? { ...partial.domainFilters } : { ...DEFAULT_ORGANIZATION_GRAPH_FILTERS.domainFilters }
1641
+ };
1642
+ }
1643
+ function normalizeOrganizationGraphSearch(search) {
1644
+ return search.trim().toLowerCase();
1645
+ }
1646
+ function getOrganizationGraphNodePresence(node, incidentEdges) {
1647
+ if (node.kind === "resource") {
1648
+ const relevantEdges = incidentEdges.filter((edge) => edge.kind !== "contains");
1649
+ const hasTopologyEdges2 = relevantEdges.some(isTopologyEdge);
1650
+ const hasSemanticEdges2 = relevantEdges.some(isSemanticEdge);
1651
+ if (hasTopologyEdges2 && hasSemanticEdges2) {
1652
+ return "bridge";
1653
+ }
1654
+ if (hasTopologyEdges2) {
1655
+ return "topology-only";
1656
+ }
1657
+ return "semantic-only";
1658
+ }
1659
+ const hasTopologyEdges = incidentEdges.some(isTopologyEdge);
1660
+ const hasSemanticEdges = incidentEdges.some(isSemanticEdge);
1661
+ if (hasTopologyEdges && hasSemanticEdges) {
1662
+ return "bridge";
1663
+ }
1664
+ if (hasTopologyEdges) {
1665
+ return "topology-only";
1666
+ }
1667
+ return "semantic-only";
1668
+ }
1669
+ function getOrganizationGraphNodePresenceMap(graph) {
1670
+ const presenceByNodeId = /* @__PURE__ */ new Map();
1671
+ for (const node of graph.nodes) {
1672
+ presenceByNodeId.set(node.id, getOrganizationGraphNodePresence(node, getIncidentEdges(graph, node.id)));
1673
+ }
1674
+ return presenceByNodeId;
1675
+ }
1676
+ function getOrganizationGraphNodeKindOptions(kinds = ORGANIZATION_GRAPH_NODE_KIND_ORDER) {
1677
+ return kinds.map((kind) => ({
1678
+ kind,
1679
+ label: ORGANIZATION_GRAPH_NODE_KIND_LABELS[kind]
1680
+ }));
1681
+ }
1682
+ function getOrganizationGraphResourceTypeOptions(resourceTypes = [
1683
+ "workflow",
1684
+ "agent",
1685
+ "trigger",
1686
+ "integration",
1687
+ "external",
1688
+ "human_checkpoint"
1689
+ ]) {
1690
+ return resourceTypes.map((resourceType) => ({
1691
+ resourceType,
1692
+ label: titleCase3(resourceType)
1693
+ }));
1694
+ }
1695
+ function getNodeStatus(node, commandViewData) {
1696
+ const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
1697
+ if (commandViewNode) {
1698
+ return commandViewNode.status;
1699
+ }
1700
+ return "status" in node && typeof node.status === "string" ? node.status : void 0;
1701
+ }
1702
+ function getExplicitNodeFacets(node, commandViewData) {
1703
+ const commandViewNode = getCommandViewNodeForGraphNode(node, commandViewData);
1704
+ if (commandViewNode) {
1705
+ return [
1706
+ ...commandViewNode.category ? [`category:${commandViewNode.category}`] : [],
1707
+ ...commandViewNode.links?.map((link) => link.nodeId) ?? []
1708
+ ];
1709
+ }
1710
+ return [];
1711
+ }
1712
+ function getNodeFacets(graph, node, commandViewData) {
1713
+ const explicitFacets = getExplicitNodeFacets(node, commandViewData);
1714
+ if (explicitFacets.length > 0) {
1715
+ return explicitFacets;
1716
+ }
1717
+ if (node.kind === "feature") {
1718
+ return node.sourceId ? [node.sourceId] : [];
1719
+ }
1720
+ if (node.kind !== "resource") {
1721
+ return [];
1722
+ }
1723
+ const facetIds = /* @__PURE__ */ new Set();
1724
+ for (const edge of graph.edges) {
1725
+ if (edge.sourceId !== node.id) {
1726
+ continue;
1727
+ }
1728
+ const targetNode = graph.nodes.find((candidate) => candidate.id === edge.targetId);
1729
+ if (targetNode?.kind === "feature" && targetNode.sourceId) {
1730
+ facetIds.add(targetNode.id);
1731
+ }
1732
+ }
1733
+ return [...facetIds];
1734
+ }
1735
+ function matchesOrganizationGraphNodeSearch(node, search) {
1736
+ const query = normalizeOrganizationGraphSearch(search);
1737
+ if (!query) return true;
1738
+ const nodeStatus = getNodeStatus(node);
1739
+ const nodeFacets = getExplicitNodeFacets(node);
1740
+ 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);
1741
+ }
1742
+ function matchesOrganizationGraphEdgeSearch(edge, graph, search) {
1743
+ const query = normalizeOrganizationGraphSearch(search);
1744
+ if (!query) return true;
1745
+ const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
1746
+ const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
1747
+ 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);
1748
+ }
1749
+ function matchesTopologyPresence(nodePresence, topologyPresence) {
1750
+ if (topologyPresence === "all") return true;
1751
+ return nodePresence === topologyPresence;
1752
+ }
1753
+ function hasActiveDomainFilters(domainFilters) {
1754
+ return Object.values(domainFilters).some((filterState) => filterState !== "neutral");
1755
+ }
1756
+ function matchesDomainFilters(graph, node, domainFilters, commandViewData) {
1757
+ if (!hasActiveDomainFilters(domainFilters)) {
1758
+ return true;
1759
+ }
1760
+ const includedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "include").map(([domainId]) => domainId);
1761
+ const excludedDomains = Object.entries(domainFilters).filter(([, filterState]) => filterState === "exclude").map(([domainId]) => domainId);
1762
+ const nodeFacets = getNodeFacets(graph, node, commandViewData);
1763
+ if (excludedDomains.length > 0 && nodeFacets.some((domainId) => excludedDomains.includes(domainId))) {
1764
+ return false;
1765
+ }
1766
+ if (includedDomains.length > 0 && !nodeFacets.some((domainId) => includedDomains.includes(domainId))) {
1767
+ return false;
1768
+ }
1769
+ return true;
1770
+ }
1771
+ function matchesEnvironmentStatus(node, environmentStatus, commandViewData) {
1772
+ if (environmentStatus === "all") {
1773
+ return true;
1774
+ }
1775
+ const nodeStatus = getNodeStatus(node, commandViewData);
1776
+ if (!nodeStatus) {
1777
+ return true;
1778
+ }
1779
+ return nodeStatus === environmentStatus;
1780
+ }
1781
+ function matchesResourceTypeFilters(node, resourceTypes) {
1782
+ if (node.kind !== "resource" || resourceTypes.length === 0) {
1783
+ return true;
1784
+ }
1785
+ return Boolean(node.resourceType && resourceTypes.includes(node.resourceType));
1786
+ }
1787
+ function matchesIntegrationVisibility(node, showIntegrations) {
1788
+ if (showIntegrations) {
1789
+ return true;
1790
+ }
1791
+ return !(node.kind === "resource" && node.resourceType === "integration");
1792
+ }
1793
+ function filterOrganizationGraph(graph, filters, options) {
1794
+ const normalizedFilters = createOrganizationGraphFilters(filters);
1795
+ const normalizedSearch = normalizeOrganizationGraphSearch(normalizedFilters.search);
1796
+ const nodePresenceMap = getOrganizationGraphNodePresenceMap(graph);
1797
+ const selectedKinds = new Set(normalizedFilters.nodeKinds);
1798
+ const commandViewData = options?.commandViewData;
1799
+ const visibleNodeIds = /* @__PURE__ */ new Set();
1800
+ for (const node of graph.nodes) {
1801
+ if (selectedKinds.size > 0 && !selectedKinds.has(node.kind)) {
1802
+ continue;
1803
+ }
1804
+ if (!matchesIntegrationVisibility(node, normalizedFilters.showIntegrations)) {
1805
+ continue;
1806
+ }
1807
+ if (!matchesResourceTypeFilters(node, normalizedFilters.resourceTypes)) {
1808
+ continue;
1809
+ }
1810
+ if (!matchesEnvironmentStatus(node, normalizedFilters.environmentStatus, commandViewData)) {
1811
+ continue;
1812
+ }
1813
+ if (!matchesDomainFilters(graph, node, normalizedFilters.domainFilters, commandViewData)) {
1814
+ continue;
1815
+ }
1816
+ const presence = nodePresenceMap.get(node.id) ?? "semantic-only";
1817
+ if (!matchesTopologyPresence(presence, normalizedFilters.topologyPresence)) {
1818
+ continue;
1819
+ }
1820
+ if (normalizedSearch && !matchesOrganizationGraphNodeSearch(node, normalizedSearch)) {
1821
+ const incidentEdges = getIncidentEdges(graph, node.id);
1822
+ const edgeMatch = incidentEdges.some((edge) => matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch));
1823
+ if (!edgeMatch) {
1824
+ continue;
1825
+ }
1826
+ }
1827
+ visibleNodeIds.add(node.id);
1828
+ }
1829
+ const visibleEdges = graph.edges.filter((edge) => {
1830
+ const sourceVisible = visibleNodeIds.has(edge.sourceId);
1831
+ const targetVisible = visibleNodeIds.has(edge.targetId);
1832
+ if (!sourceVisible || !targetVisible) {
1833
+ return false;
1834
+ }
1835
+ if (normalizedSearch && !matchesOrganizationGraphEdgeSearch(edge, graph, normalizedSearch)) {
1836
+ const sourceNode = graph.nodes.find((node) => node.id === edge.sourceId);
1837
+ const targetNode = graph.nodes.find((node) => node.id === edge.targetId);
1838
+ const nodeSearchMatch = Boolean(sourceNode && matchesOrganizationGraphNodeSearch(sourceNode, normalizedSearch)) || Boolean(targetNode && matchesOrganizationGraphNodeSearch(targetNode, normalizedSearch));
1839
+ if (!nodeSearchMatch) {
1840
+ return false;
1841
+ }
1842
+ }
1843
+ return true;
1844
+ });
1845
+ return {
1846
+ ...graph,
1847
+ nodes: graph.nodes.filter((node) => visibleNodeIds.has(node.id)),
1848
+ edges: visibleEdges
1849
+ };
1850
+ }
1851
+ function getCommandViewResourceCategory(node, commandViewData) {
1852
+ return getCommandViewNodeForGraphNode(node, commandViewData)?.category ?? null;
1853
+ }
1854
+ function getConnectedHiddenResourceIds(graph, nodeId2, hiddenIds) {
1855
+ if (!nodeId2) {
1856
+ return /* @__PURE__ */ new Set();
1857
+ }
1858
+ const nodesById = new Map(graph.nodes.map((node) => [node.id, node]));
1859
+ const connectedIds = /* @__PURE__ */ new Set();
1860
+ for (const edge of graph.edges) {
1861
+ const neighborId = edge.sourceId === nodeId2 ? edge.targetId : edge.targetId === nodeId2 ? edge.sourceId : null;
1862
+ if (!neighborId || !hiddenIds.has(neighborId)) {
1863
+ continue;
1864
+ }
1865
+ if (nodesById.get(neighborId)?.kind === "resource") {
1866
+ connectedIds.add(neighborId);
1867
+ }
1868
+ }
1869
+ return connectedIds;
1870
+ }
1871
+ function getCommandViewVisibilityProjection({
1872
+ graph,
1873
+ commandViewData,
1874
+ resourcesHidden,
1875
+ diagnosticsHidden,
1876
+ diagnosticCategories,
1877
+ revealedIds = /* @__PURE__ */ new Set(),
1878
+ mode
1879
+ }) {
1880
+ const hiddenIds = /* @__PURE__ */ new Set();
1881
+ const hiddenEdgeIds = /* @__PURE__ */ new Set();
1882
+ const diagnosticCategorySet = new Set(diagnosticCategories);
1883
+ let totalResourceCount = 0;
1884
+ let hiddenDiagnosticResourceCount = 0;
1885
+ if (mode === "trace" || mode === "impact") {
1886
+ const resourceCount = graph.nodes.filter((node) => node.kind === "resource").length;
1887
+ return {
1888
+ hiddenIds,
1889
+ hiddenEdgeIds,
1890
+ totalResourceCount: resourceCount,
1891
+ visibleResourceCount: resourceCount,
1892
+ hiddenResourceCount: 0,
1893
+ hiddenDiagnosticResourceCount: 0
1894
+ };
1895
+ }
1896
+ for (const node of graph.nodes) {
1897
+ if (node.kind !== "resource") {
1898
+ continue;
1899
+ }
1900
+ totalResourceCount += 1;
1901
+ const category = getCommandViewResourceCategory(node, commandViewData);
1902
+ const isDiagnostic = Boolean(category && diagnosticCategorySet.has(category));
1903
+ if (isDiagnostic && diagnosticsHidden) {
1904
+ hiddenDiagnosticResourceCount += 1;
1905
+ }
1906
+ if (revealedIds.has(node.id)) {
1907
+ continue;
1908
+ }
1909
+ if (resourcesHidden || diagnosticsHidden && isDiagnostic) {
1910
+ hiddenIds.add(node.id);
1911
+ }
1912
+ }
1913
+ for (const edge of graph.edges) {
1914
+ if (hiddenIds.has(edge.sourceId) || hiddenIds.has(edge.targetId)) {
1915
+ hiddenEdgeIds.add(edge.id);
1916
+ }
1917
+ }
1918
+ const hiddenResourceCount = hiddenIds.size;
1919
+ return {
1920
+ hiddenIds,
1921
+ hiddenEdgeIds,
1922
+ totalResourceCount,
1923
+ visibleResourceCount: totalResourceCount - hiddenResourceCount,
1924
+ hiddenResourceCount,
1925
+ hiddenDiagnosticResourceCount
1926
+ };
1927
+ }
1928
+ function isOrganizationGraphFilterPristine(filters) {
1929
+ 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);
1930
+ }
1931
+ var TOPOLOGY_PRESENCE_OPTIONS = [
1932
+ { label: "All", value: "all" },
1933
+ { label: "Semantic only", value: "semantic-only" },
1934
+ { label: "Topology only", value: "topology-only" }
1935
+ ];
1936
+ var ENVIRONMENT_STATUS_OPTIONS = [
1937
+ { label: "All", value: "all" },
1938
+ { label: "Prod", value: "prod" },
1939
+ { label: "Dev", value: "dev" }
1940
+ ];
1941
+ function OrganizationGraphFilterToolbar({
1942
+ value,
1943
+ onChange,
1944
+ availableKinds,
1945
+ disabled = false,
1946
+ searchPlaceholder = "Search nodes, relationships, or IDs",
1947
+ kindLabel = "Node kinds",
1948
+ resourceTypeLabel = "Resource types",
1949
+ topologyLabel = "Relationship presence",
1950
+ environmentLabel = "Environment",
1951
+ showIntegrationsLabel = "Show integrations",
1952
+ resetLabel = "Reset filters",
1953
+ resetValue = createOrganizationGraphFilters()
1954
+ }) {
1955
+ const kindOptions = getOrganizationGraphNodeKindOptions(availableKinds);
1956
+ const resourceTypeOptions = getOrganizationGraphResourceTypeOptions();
1957
+ const canReset = !isOrganizationGraphFilterPristine(value);
1958
+ return /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
1959
+ /* @__PURE__ */ jsx(
1960
+ TextInput,
1961
+ {
1962
+ label: "Search",
1963
+ placeholder: searchPlaceholder,
1964
+ value: value.search,
1965
+ onChange: (event) => onChange({
1966
+ ...value,
1967
+ search: event.currentTarget.value
1968
+ }),
1969
+ leftSection: /* @__PURE__ */ jsx(IconSearch, { size: 14 }),
1970
+ disabled
1971
+ }
1972
+ ),
1973
+ /* @__PURE__ */ jsx(
1974
+ MultiSelect,
1975
+ {
1976
+ label: kindLabel,
1977
+ placeholder: "All kinds",
1978
+ data: kindOptions.map((option) => ({ value: option.kind, label: option.label })),
1979
+ value: value.nodeKinds,
1980
+ onChange: (nodeKinds) => onChange({
1981
+ ...value,
1982
+ nodeKinds
1983
+ }),
1984
+ searchable: true,
1985
+ clearable: true,
1986
+ disabled
1987
+ }
1988
+ ),
1989
+ /* @__PURE__ */ jsx(
1990
+ MultiSelect,
1991
+ {
1992
+ label: resourceTypeLabel,
1993
+ placeholder: "All resource types",
1994
+ data: resourceTypeOptions.map((option) => ({ value: option.resourceType, label: option.label })),
1995
+ value: value.resourceTypes,
1996
+ onChange: (resourceTypes) => onChange({
1997
+ ...value,
1998
+ resourceTypes
1999
+ }),
2000
+ searchable: true,
2001
+ clearable: true,
2002
+ disabled
2003
+ }
2004
+ ),
2005
+ /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
2006
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: topologyLabel }),
2007
+ /* @__PURE__ */ jsx(
2008
+ SegmentedControl,
2009
+ {
2010
+ value: value.topologyPresence,
2011
+ onChange: (topologyPresence) => onChange({
2012
+ ...value,
2013
+ topologyPresence
2014
+ }),
2015
+ data: TOPOLOGY_PRESENCE_OPTIONS,
2016
+ size: "sm",
2017
+ fullWidth: true,
2018
+ disabled
2019
+ }
2020
+ )
2021
+ ] }),
2022
+ /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
2023
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 500, children: environmentLabel }),
2024
+ /* @__PURE__ */ jsx(
2025
+ SegmentedControl,
2026
+ {
2027
+ value: value.environmentStatus,
2028
+ onChange: (environmentStatus) => onChange({
2029
+ ...value,
2030
+ environmentStatus
2031
+ }),
2032
+ data: ENVIRONMENT_STATUS_OPTIONS,
2033
+ size: "sm",
2034
+ fullWidth: true,
2035
+ disabled
2036
+ }
2037
+ )
2038
+ ] }),
2039
+ /* @__PURE__ */ jsx(
2040
+ Switch,
2041
+ {
2042
+ label: showIntegrationsLabel,
2043
+ description: "Hide integration resources and their relationship edges.",
2044
+ checked: value.showIntegrations,
2045
+ onChange: (event) => onChange({
2046
+ ...value,
2047
+ showIntegrations: event.currentTarget.checked
2048
+ }),
2049
+ size: "sm",
2050
+ disabled
2051
+ }
2052
+ ),
2053
+ /* @__PURE__ */ jsx(Group, { justify: "flex-end", children: /* @__PURE__ */ jsx(
2054
+ Button,
2055
+ {
2056
+ variant: "subtle",
2057
+ leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
2058
+ onClick: () => onChange(resetValue),
2059
+ disabled: disabled || !canReset,
2060
+ children: resetLabel
2061
+ }
2062
+ ) })
2063
+ ] });
2064
+ }
2065
+ var useOrganizationGraphFiltersStore = create((set) => ({
2066
+ filtersByScope: {},
2067
+ initializeScope: (scope, initialFilters) => set((state) => {
2068
+ if (state.filtersByScope[scope]) {
2069
+ return state;
2070
+ }
2071
+ return {
2072
+ filtersByScope: {
2073
+ ...state.filtersByScope,
2074
+ [scope]: createOrganizationGraphFilters(initialFilters)
2075
+ }
2076
+ };
2077
+ }),
2078
+ updateScope: (scope, next) => set((state) => ({
2079
+ filtersByScope: {
2080
+ ...state.filtersByScope,
2081
+ [scope]: createOrganizationGraphFilters({
2082
+ ...state.filtersByScope[scope],
2083
+ ...next
2084
+ })
2085
+ }
2086
+ })),
2087
+ resetScope: (scope, initialFilters) => set((state) => ({
2088
+ filtersByScope: {
2089
+ ...state.filtersByScope,
2090
+ [scope]: createOrganizationGraphFilters(initialFilters)
2091
+ }
2092
+ }))
2093
+ }));
2094
+ function getOrganizationGraphFilterScope(initialFilters) {
2095
+ return JSON.stringify(createOrganizationGraphFilters(initialFilters));
2096
+ }
2097
+ function useOrganizationGraphFilters(initialFilters) {
2098
+ const scopeRef = useRef(getOrganizationGraphFilterScope(initialFilters));
2099
+ const fallbackFiltersRef = useRef(createOrganizationGraphFilters(initialFilters));
2100
+ const filters = useOrganizationGraphFiltersStore(
2101
+ (state) => state.filtersByScope[scopeRef.current] ?? fallbackFiltersRef.current
2102
+ );
2103
+ const initializeScope = useOrganizationGraphFiltersStore((state) => state.initializeScope);
2104
+ const updateScope = useOrganizationGraphFiltersStore((state) => state.updateScope);
2105
+ const resetScope = useOrganizationGraphFiltersStore((state) => state.resetScope);
2106
+ useEffect(() => {
2107
+ initializeScope(scopeRef.current, initialFilters);
2108
+ }, [initialFilters, initializeScope]);
2109
+ const updateFilters = (next) => {
2110
+ updateScope(scopeRef.current, next);
2111
+ };
2112
+ const setSearch = (search) => {
2113
+ updateFilters({ search });
2114
+ };
2115
+ const setNodeKinds = (nodeKinds) => {
2116
+ updateFilters({ nodeKinds });
2117
+ };
2118
+ const setTopologyPresence = (topologyPresence) => {
2119
+ updateFilters({ topologyPresence });
2120
+ };
2121
+ const resetFilters = () => {
2122
+ resetScope(scopeRef.current, initialFilters);
2123
+ };
2124
+ return {
2125
+ filters,
2126
+ setSearch,
2127
+ setNodeKinds,
2128
+ setTopologyPresence,
2129
+ resetFilters,
2130
+ updateFilters
2131
+ };
2132
+ }
2133
+
2134
+ // src/features/operations/organization-graph/lenses.ts
2135
+ var COMMAND_VIEW_NODE_KINDS = [
2136
+ "organization",
2137
+ "feature",
2138
+ "surface",
2139
+ "entity",
2140
+ "capability",
2141
+ "resource"
2142
+ ];
2143
+ function getOrganizationGraphLensConfig(lens) {
2144
+ if (lens === "command-view") {
2145
+ return {
2146
+ title: "Command View",
2147
+ caption: "Operations lens backed by the shared organization graph. This preset focuses the graph on bridged runtime resources and their operational relationships.",
2148
+ initialMode: "map",
2149
+ initialFilters: {
2150
+ nodeKinds: COMMAND_VIEW_NODE_KINDS,
2151
+ topologyPresence: "all"
2152
+ },
2153
+ filterSummary: "Command View lens keeps the organization structure visible while resource visibility is controlled progressively."
2154
+ };
2155
+ }
2156
+ return {
2157
+ title: "Organization Graph",
2158
+ caption: "Cytoscape-based shared graph surface built from the organization model and bridged Command View topology.",
2159
+ initialMode: "map",
2160
+ filterSummary: "Filter by node kind, semantic-vs-topology presence, and free-text search across nodes and relationships."
2161
+ };
2162
+ }
2163
+
2164
+ // src/features/operations/organization-graph/commandViewOperationalSummary.ts
2165
+ function toPercentage(numerator, denominator) {
2166
+ if (denominator <= 0) return null;
2167
+ return numerator / denominator * 100;
2168
+ }
2169
+ function formatPercent(value) {
2170
+ return value == null ? "N/A" : `${Math.round(value)}%`;
2171
+ }
2172
+ function formatTimestamp(value) {
2173
+ if (!value) return "N/A";
2174
+ return new Intl.DateTimeFormat("en-US", {
2175
+ month: "short",
2176
+ day: "numeric",
2177
+ hour: "numeric",
2178
+ minute: "2-digit"
2179
+ }).format(new Date(value));
2180
+ }
2181
+ function getCommandViewNodes2(data) {
2182
+ return [
2183
+ ...data.agents,
2184
+ ...data.workflows,
2185
+ ...data.triggers,
2186
+ ...data.integrations,
2187
+ ...data.externalResources,
2188
+ ...data.humanCheckpoints
2189
+ ];
2190
+ }
2191
+ function getNodeByResourceId(data, resourceId) {
2192
+ return getCommandViewNodes2(data).find((node) => node.resourceId === resourceId) ?? null;
2193
+ }
2194
+ function getCommandViewOperationalOverview(data, stats) {
2195
+ if (!stats) {
2196
+ return null;
2197
+ }
2198
+ const resourceEntries = Object.entries(stats.resources);
2199
+ const humanEntries = Object.entries(stats.humanCheckpoints);
2200
+ const totalRuns = resourceEntries.reduce((sum, [, item]) => sum + item.totalRuns, 0);
2201
+ const successCount = resourceEntries.reduce((sum, [, item]) => sum + item.successCount, 0);
2202
+ const failureCount = resourceEntries.reduce((sum, [, item]) => sum + item.failureCount, 0);
2203
+ const warningCount = resourceEntries.reduce((sum, [, item]) => sum + item.warningCount, 0);
2204
+ const pendingApprovals = humanEntries.reduce((sum, [, item]) => sum + item.pendingCount, 0);
2205
+ const activeHumanCheckpoints = humanEntries.filter(([, item]) => item.pendingCount > 0).length;
2206
+ const topFailingResources = resourceEntries.map(([resourceId, item]) => ({
2207
+ id: resourceId,
2208
+ label: data ? getNodeByResourceId(data, resourceId)?.name ?? resourceId : resourceId,
2209
+ failureCount: item.failureCount,
2210
+ warningCount: item.warningCount
2211
+ })).filter((item) => item.failureCount > 0 || item.warningCount > 0).sort((left, right) => {
2212
+ if (right.failureCount !== left.failureCount) {
2213
+ return right.failureCount - left.failureCount;
2214
+ }
2215
+ if (right.warningCount !== left.warningCount) {
2216
+ return right.warningCount - left.warningCount;
2217
+ }
2218
+ return left.label.localeCompare(right.label);
2219
+ }).slice(0, 3);
2220
+ return {
2221
+ totalRuns,
2222
+ successCount,
2223
+ failureCount,
2224
+ warningCount,
2225
+ successRate: toPercentage(successCount, totalRuns),
2226
+ trackedResources: resourceEntries.length,
2227
+ pendingApprovals,
2228
+ activeHumanCheckpoints,
2229
+ topFailingResources,
2230
+ timeRange: stats.timeRange,
2231
+ generatedAt: stats.generatedAt
2232
+ };
2233
+ }
2234
+ function buildResourceSelectionSummary(node, stats) {
2235
+ const successRate = toPercentage(stats.successCount, stats.totalRuns);
2236
+ const metadata = [
2237
+ { label: "Operational Type", value: node.type },
2238
+ { label: "Environment", value: node.status.toUpperCase() },
2239
+ { label: "Version", value: node.version },
2240
+ { label: "Origin", value: node.origin ? node.origin : "local" }
2241
+ ];
2242
+ if (node.category) {
2243
+ metadata.push({ label: "Category", value: node.category });
2244
+ }
2245
+ if (node.links?.length) {
2246
+ metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
2247
+ }
2248
+ if (node.type === "agent") {
2249
+ metadata.push({ label: "Model", value: `${node.modelProvider}/${node.modelId}` });
2250
+ metadata.push({ label: "Tools", value: String(node.toolCount) });
2251
+ metadata.push({ label: "Memory", value: node.hasMemory ? "Enabled" : "Disabled" });
2252
+ }
2253
+ if (node.type === "workflow") {
2254
+ metadata.push({ label: "Entry Point", value: node.entryPoint });
2255
+ metadata.push({ label: "Steps", value: String(node.stepCount) });
2256
+ }
2257
+ if (node.type === "integration") {
2258
+ metadata.push({ label: "Provider", value: node.provider });
2259
+ metadata.push({ label: "Credential", value: node.credentialName });
2260
+ }
2261
+ if (node.type === "trigger") {
2262
+ metadata.push({ label: "Trigger Type", value: node.triggerType });
2263
+ }
2264
+ if (node.type === "external") {
2265
+ metadata.push({ label: "Platform", value: node.platform });
2266
+ }
2267
+ return {
2268
+ title: "Operational Summary",
2269
+ description: "Execution telemetry for this resource inside the Command View lens.",
2270
+ metrics: [
2271
+ { label: "Runs", value: String(stats.totalRuns), hint: "Total tracked executions in the selected time range" },
2272
+ { label: "Success rate", value: formatPercent(successRate), hint: "Completed and warning runs as a percentage of all runs" },
2273
+ { label: "Failures", value: String(stats.failureCount), hint: "Runs that ended in a failed state" },
2274
+ { label: "Warnings", value: String(stats.warningCount), hint: "Completed runs that surfaced warnings" }
2275
+ ],
2276
+ metadata: [...metadata, { label: "Last Run", value: formatTimestamp(stats.lastRunAt) }]
2277
+ };
2278
+ }
2279
+ function buildHumanSelectionSummary(node, stats) {
2280
+ const metadata = [
2281
+ { label: "Operational Type", value: "human checkpoint" },
2282
+ { label: "Environment", value: node.status.toUpperCase() },
2283
+ { label: "Version", value: node.version },
2284
+ { label: "Origin", value: node.origin ? node.origin : "local" }
2285
+ ];
2286
+ if (node.category) {
2287
+ metadata.push({ label: "Category", value: node.category });
2288
+ }
2289
+ if (node.links?.length) {
2290
+ metadata.push({ label: "Links", value: node.links.map((link) => `${link.kind} ${link.nodeId}`).join(", ") });
2291
+ }
2292
+ return {
2293
+ title: "Approval Queue Summary",
2294
+ description: "Human checkpoint activity for the current Command View lens.",
2295
+ metrics: [
2296
+ { label: "Pending", value: String(stats.pendingCount), hint: "Tasks currently waiting on a decision" },
2297
+ { label: "Completed", value: String(stats.completedCount), hint: "Tasks completed in the selected time range" },
2298
+ { label: "Expired", value: String(stats.expiredCount), hint: "Tasks that expired before resolution" }
2299
+ ],
2300
+ metadata: [...metadata, { label: "Last Decision", value: formatTimestamp(stats.lastDecisionAt) }]
2301
+ };
2302
+ }
2303
+ function getCommandViewSelectionOperationalSummary(data, stats, selectedElement) {
2304
+ if (!data || !stats || !selectedElement || selectedElement.type !== "node") {
2305
+ return null;
2306
+ }
2307
+ if (!selectedElement.id.startsWith("resource:")) {
2308
+ return null;
2309
+ }
2310
+ const resourceId = selectedElement.id.slice("resource:".length);
2311
+ const node = getNodeByResourceId(data, resourceId);
2312
+ if (!node) {
2313
+ return null;
2314
+ }
2315
+ if (node.type === "human") {
2316
+ const checkpointStats = stats.humanCheckpoints[resourceId];
2317
+ return checkpointStats ? buildHumanSelectionSummary(node, checkpointStats) : null;
2318
+ }
2319
+ const resourceStats = stats.resources[resourceId];
2320
+ return resourceStats ? buildResourceSelectionSummary(node, resourceStats) : null;
2321
+ }
2322
+ function formatRelativeTime(date) {
2323
+ if (!date) return "N/A";
2324
+ const dateObj = typeof date === "string" ? new Date(date) : date;
2325
+ return formatDistanceToNow(dateObj, { addSuffix: true });
2326
+ }
2327
+
2328
+ // src/hooks/operations/command-view/utils/mergeStatsWithTopology.ts
2329
+ function mergeStatsWithTopology(topology, stats) {
2330
+ return {
2331
+ ...topology,
2332
+ agents: topology.agents.map((agent) => ({
2333
+ ...agent,
2334
+ stats: stats.resources[agent.resourceId] || null
2335
+ })),
2336
+ workflows: topology.workflows.map((workflow) => ({
2337
+ ...workflow,
2338
+ stats: stats.resources[workflow.resourceId] || null
2339
+ })),
2340
+ humanCheckpoints: topology.humanCheckpoints.map((checkpoint) => ({
2341
+ ...checkpoint,
2342
+ stats: stats.humanCheckpoints[checkpoint.resourceId] || null
2343
+ }))
2344
+ };
2345
+ }
2346
+
2347
+ // src/features/operations/organization-graph/commandViewDrillDown.ts
2348
+ function titleCase4(value) {
2349
+ return value.replace(/[-_.]+/g, " ").replace(/\s+/g, " ").trim().split(" ").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
2350
+ }
2351
+ function getResourceHref(resourceType, resourceId) {
2352
+ if (resourceType === "agent") {
2353
+ return `/operations/resources/agent/${resourceId}`;
2354
+ }
2355
+ if (resourceType === "workflow") {
2356
+ return `/operations/resources/workflow/${resourceId}`;
2357
+ }
2358
+ if (resourceType === "human_checkpoint") {
2359
+ return `/operations/command-queue?checkpoint=${resourceId}`;
2360
+ }
2361
+ return null;
2362
+ }
2363
+ function getExecutionBadgeColor(status) {
2364
+ switch (status) {
2365
+ case "failed":
2366
+ return "red";
2367
+ case "warning":
2368
+ return "yellow";
2369
+ case "running":
2370
+ return "blue";
2371
+ case "completed":
2372
+ return "green";
2373
+ case "pending":
2374
+ default:
2375
+ return "gray";
2376
+ }
2377
+ }
2378
+ function getTaskBadgeColor(status) {
2379
+ switch (status) {
2380
+ case "pending":
2381
+ return "orange";
2382
+ case "processing":
2383
+ return "blue";
2384
+ case "completed":
2385
+ return "green";
2386
+ case "failed":
2387
+ return "red";
2388
+ case "expired":
2389
+ default:
2390
+ return "gray";
2391
+ }
2392
+ }
2393
+ function getExecutionDescription(execution) {
2394
+ if (execution.errorMessage) {
2395
+ return execution.errorMessage;
2396
+ }
2397
+ if (execution.status === "running") {
2398
+ return "Currently running";
2399
+ }
2400
+ if (execution.status === "warning") {
2401
+ return "Completed with warnings";
2402
+ }
2403
+ if (execution.status === "completed") {
2404
+ return "Completed successfully";
2405
+ }
2406
+ return titleCase4(execution.status);
2407
+ }
2408
+ function getTaskDescription(task) {
2409
+ if (task.description) {
2410
+ return task.description;
2411
+ }
2412
+ if (task.humanCheckpoint) {
2413
+ return `Checkpoint: ${task.humanCheckpoint}`;
2414
+ }
2415
+ return "Pending approval task";
2416
+ }
2417
+ function buildCommandViewDrillDownSections({
2418
+ node,
2419
+ timeRange,
2420
+ executions,
2421
+ checkpointTasks
2422
+ }) {
2423
+ if (!node || node.kind !== "resource" || !node.sourceId || !node.resourceType) {
2424
+ return [];
2425
+ }
2426
+ const sections = [];
2427
+ const resourceHref = getResourceHref(node.resourceType, node.sourceId);
2428
+ if ((node.resourceType === "agent" || node.resourceType === "workflow") && executions) {
2429
+ sections.push({
2430
+ title: "Recent executions",
2431
+ description: `Latest runs for this ${titleCase4(node.resourceType)} in the ${timeRange} window.`,
2432
+ emptyMessage: `No executions were recorded for this ${titleCase4(node.resourceType).toLowerCase()} in the current window.`,
2433
+ primaryAction: resourceHref ? {
2434
+ label: "Open resource",
2435
+ href: resourceHref
2436
+ } : void 0,
2437
+ items: executions.map((execution) => ({
2438
+ id: execution.executionId,
2439
+ label: execution.executionId,
2440
+ href: `${resourceHref ?? "#"}?exec=${execution.executionId}`,
2441
+ description: getExecutionDescription(execution),
2442
+ badgeLabel: execution.status,
2443
+ badgeColor: getExecutionBadgeColor(execution.status),
2444
+ meta: `Started ${formatRelativeTime(execution.startedAt)}`
2445
+ }))
2446
+ });
2447
+ }
2448
+ if (node.resourceType === "human_checkpoint" && checkpointTasks) {
2449
+ sections.push({
2450
+ title: "Pending tasks",
2451
+ description: "Human approval tasks waiting on this checkpoint.",
2452
+ emptyMessage: "No pending tasks are currently assigned to this checkpoint.",
2453
+ primaryAction: resourceHref ? {
2454
+ label: "Open queue",
2455
+ href: resourceHref
2456
+ } : void 0,
2457
+ items: checkpointTasks.map((task) => ({
2458
+ id: task.id,
2459
+ label: task.description ?? task.id,
2460
+ href: `/operations/command-queue?task=${task.id}`,
2461
+ description: getTaskDescription(task),
2462
+ badgeLabel: task.status,
2463
+ badgeColor: getTaskBadgeColor(task.status),
2464
+ meta: `Created ${formatRelativeTime(task.createdAt)}`
2465
+ }))
2466
+ });
2467
+ }
2468
+ return sections;
2469
+ }
2470
+
2471
+ // src/features/operations/organization-graph/path-tracing/trace.ts
2472
+ var NODE_KIND_ORDER = {
2473
+ organization: 0,
2474
+ feature: 1,
2475
+ surface: 2,
2476
+ capability: 3,
2477
+ entity: 4,
2478
+ resource: 5,
2479
+ knowledge: 6
2480
+ };
2481
+ var NODE_KIND_LABEL = {
2482
+ organization: "Organization",
2483
+ feature: "Feature",
2484
+ surface: "Surface",
2485
+ capability: "Capability",
2486
+ entity: "Entity",
2487
+ resource: "Resource",
2488
+ knowledge: "Knowledge"
2489
+ };
2490
+ function getNodeLabel(node) {
2491
+ return node.label || node.sourceId || node.id;
2492
+ }
2493
+ function compareTraceNodes(a, b) {
2494
+ const kindDelta = NODE_KIND_ORDER[a.kind] - NODE_KIND_ORDER[b.kind];
2495
+ if (kindDelta !== 0) {
2496
+ return kindDelta;
2497
+ }
2498
+ const labelDelta = getNodeLabel(a).localeCompare(getNodeLabel(b));
2499
+ if (labelDelta !== 0) {
2500
+ return labelDelta;
2501
+ }
2502
+ return a.id.localeCompare(b.id);
2503
+ }
2504
+ function buildMissingNodeMessage(selection, missingNodeIds) {
2505
+ if (missingNodeIds.length === 0) {
2506
+ return "The selected trace is not available.";
2507
+ }
2508
+ if (missingNodeIds.length === 1) {
2509
+ const missingId = missingNodeIds[0];
2510
+ return `Graph node "${missingId}" is not available.`;
2511
+ }
2512
+ return `Graph nodes "${selection.sourceId}" and "${selection.targetId}" are not available.`;
2513
+ }
2514
+ function buildPathNotFoundMessage(source, target) {
2515
+ return `No directed path found from "${source.label}" to "${target.label}".`;
2516
+ }
2517
+ function buildOrganizationGraphTraceIndex(graph) {
2518
+ const nodesById = /* @__PURE__ */ new Map();
2519
+ const edgesById = /* @__PURE__ */ new Map();
2520
+ const outgoingEdgesByNodeId = /* @__PURE__ */ new Map();
2521
+ const incomingEdgesByNodeId = /* @__PURE__ */ new Map();
2522
+ for (const node of graph.nodes) {
2523
+ nodesById.set(node.id, node);
2524
+ outgoingEdgesByNodeId.set(node.id, []);
2525
+ incomingEdgesByNodeId.set(node.id, []);
2526
+ }
2527
+ for (const edge of graph.edges) {
2528
+ edgesById.set(edge.id, edge);
2529
+ const outgoingEdges = outgoingEdgesByNodeId.get(edge.sourceId);
2530
+ if (outgoingEdges) {
2531
+ outgoingEdges.push(edge);
2532
+ }
2533
+ const incomingEdges = incomingEdgesByNodeId.get(edge.targetId);
2534
+ if (incomingEdges) {
2535
+ incomingEdges.push(edge);
2536
+ }
2537
+ }
2538
+ return {
2539
+ nodesById,
2540
+ edgesById,
2541
+ outgoingEdgesByNodeId,
2542
+ incomingEdgesByNodeId
2543
+ };
2544
+ }
2545
+ function getOrganizationGraphTraceNodeKindLabel(kind) {
2546
+ return NODE_KIND_LABEL[kind];
2547
+ }
2548
+ function formatOrganizationGraphTraceNodeOptionLabel(option) {
2549
+ return `${option.label} \xB7 ${getOrganizationGraphTraceNodeKindLabel(option.kind)}`;
2550
+ }
2551
+ function getOrganizationGraphTraceNodeOptions(graph) {
2552
+ return [...graph.nodes].sort(compareTraceNodes).map((node) => ({
2553
+ id: node.id,
2554
+ label: getNodeLabel(node),
2555
+ kind: node.kind,
2556
+ sourceId: node.sourceId,
2557
+ description: node.description,
2558
+ enabled: node.enabled
2559
+ }));
2560
+ }
2561
+ function resolveOrganizationGraphPathTrace(graph, selection) {
2562
+ const index = buildOrganizationGraphTraceIndex(graph);
2563
+ const source = selection.sourceId ? index.nodesById.get(selection.sourceId) ?? null : null;
2564
+ const target = selection.targetId ? index.nodesById.get(selection.targetId) ?? null : null;
2565
+ const missingNodeIds = [
2566
+ selection.sourceId && !source ? selection.sourceId : null,
2567
+ selection.targetId && !target ? selection.targetId : null
2568
+ ].filter((value) => Boolean(value));
2569
+ if (!selection.sourceId && !selection.targetId) {
2570
+ return {
2571
+ status: "idle",
2572
+ selection,
2573
+ source,
2574
+ target,
2575
+ missingNodeIds: [],
2576
+ pathNodes: [],
2577
+ pathEdges: [],
2578
+ highlightNodeIds: [],
2579
+ highlightEdgeIds: [],
2580
+ distance: 0,
2581
+ message: "Select a source and target to trace a path."
2582
+ };
2583
+ }
2584
+ if (!selection.sourceId || !selection.targetId) {
2585
+ return {
2586
+ status: "incomplete",
2587
+ selection,
2588
+ source,
2589
+ target,
2590
+ missingNodeIds,
2591
+ pathNodes: [],
2592
+ pathEdges: [],
2593
+ highlightNodeIds: [],
2594
+ highlightEdgeIds: [],
2595
+ distance: 0,
2596
+ message: "Select both a source and a target to resolve a path."
2597
+ };
2598
+ }
2599
+ if (missingNodeIds.length > 0 || !source || !target) {
2600
+ return {
2601
+ status: "missing-node",
2602
+ selection,
2603
+ source,
2604
+ target,
2605
+ missingNodeIds,
2606
+ pathNodes: [],
2607
+ pathEdges: [],
2608
+ highlightNodeIds: [],
2609
+ highlightEdgeIds: [],
2610
+ distance: 0,
2611
+ message: buildMissingNodeMessage(selection, missingNodeIds)
2612
+ };
2613
+ }
2614
+ if (source.id === target.id) {
2615
+ return {
2616
+ status: "found",
2617
+ selection,
2618
+ source,
2619
+ target,
2620
+ missingNodeIds: [],
2621
+ pathNodes: [source],
2622
+ pathEdges: [],
2623
+ highlightNodeIds: [source.id],
2624
+ highlightEdgeIds: [],
2625
+ distance: 0,
2626
+ message: `Source and target already point to "${source.label}".`
2627
+ };
2628
+ }
2629
+ const visitedNodeIds = /* @__PURE__ */ new Set([source.id]);
2630
+ const predecessorByNodeId = /* @__PURE__ */ new Map();
2631
+ const queue = [source.id];
2632
+ while (queue.length > 0) {
2633
+ const currentNodeId = queue.shift();
2634
+ if (!currentNodeId) {
2635
+ continue;
2636
+ }
2637
+ const outgoingEdges = index.outgoingEdgesByNodeId.get(currentNodeId) ?? [];
2638
+ for (const edge of outgoingEdges) {
2639
+ if (visitedNodeIds.has(edge.targetId)) {
2640
+ continue;
2641
+ }
2642
+ visitedNodeIds.add(edge.targetId);
2643
+ predecessorByNodeId.set(edge.targetId, {
2644
+ nodeId: currentNodeId,
2645
+ edgeId: edge.id
2646
+ });
2647
+ if (edge.targetId === target.id) {
2648
+ queue.length = 0;
2649
+ break;
2650
+ }
2651
+ queue.push(edge.targetId);
2652
+ }
2653
+ }
2654
+ if (!predecessorByNodeId.has(target.id)) {
2655
+ return {
2656
+ status: "not-found",
2657
+ selection,
2658
+ source,
2659
+ target,
2660
+ missingNodeIds: [],
2661
+ pathNodes: [],
2662
+ pathEdges: [],
2663
+ highlightNodeIds: [],
2664
+ highlightEdgeIds: [],
2665
+ distance: 0,
2666
+ message: buildPathNotFoundMessage(source, target)
2667
+ };
2668
+ }
2669
+ const pathNodes = [target];
2670
+ const pathEdges = [];
2671
+ let cursorNodeId = target.id;
2672
+ while (cursorNodeId !== source.id) {
2673
+ const predecessor = predecessorByNodeId.get(cursorNodeId);
2674
+ if (!predecessor) {
2675
+ break;
2676
+ }
2677
+ const edge = index.edgesById.get(predecessor.edgeId);
2678
+ const previousNode = index.nodesById.get(predecessor.nodeId);
2679
+ if (edge) {
2680
+ pathEdges.push(edge);
2681
+ }
2682
+ if (previousNode) {
2683
+ pathNodes.push(previousNode);
2684
+ }
2685
+ cursorNodeId = predecessor.nodeId;
2686
+ }
2687
+ pathNodes.reverse();
2688
+ pathEdges.reverse();
2689
+ return {
2690
+ status: "found",
2691
+ selection,
2692
+ source,
2693
+ target,
2694
+ missingNodeIds: [],
2695
+ pathNodes,
2696
+ pathEdges,
2697
+ highlightNodeIds: pathNodes.map((node) => node.id),
2698
+ highlightEdgeIds: pathEdges.map((edge) => edge.id),
2699
+ distance: pathEdges.length,
2700
+ message: `Path found from "${source.label}" to "${target.label}" across ${pathEdges.length} edge${pathEdges.length === 1 ? "" : "s"}.`
2701
+ };
2702
+ }
2703
+
2704
+ // src/features/operations/organization-graph/expand-around/expandAroundGraph.ts
2705
+ var DEFAULT_MAX_DEPTH = 1;
2706
+ var DEFAULT_MAX_RESULTS = 25;
2707
+ var ORG_MODEL_ROOT_KINDS = /* @__PURE__ */ new Set([
2708
+ "feature",
2709
+ "surface",
2710
+ "entity",
2711
+ "capability"
2712
+ ]);
2713
+ var PRESET_EDGE_KINDS = {
2714
+ coverage: ["contains", "exposes", "operates-on", "maps_to", "references"],
2715
+ "operational-dependencies": ["references"],
2716
+ "org-context": ["contains", "exposes", "operates-on", "maps_to"],
2717
+ "impact-path": ["references"]
2718
+ };
2719
+ var PRESET_RELATIONSHIP_TYPES = {
2720
+ "operational-dependencies": ["triggers", "uses", "approval"],
2721
+ "impact-path": ["triggers", "uses", "approval"]
2722
+ };
2723
+ var PRESET_DIRECTIONS = {
2724
+ coverage: "both",
2725
+ "operational-dependencies": "both",
2726
+ "org-context": "both",
2727
+ "impact-path": "both"
2728
+ };
2729
+ function toSet(values) {
2730
+ if (!values || values.length === 0) {
2731
+ return null;
2732
+ }
2733
+ return new Set(values);
2734
+ }
2735
+ function clampMaxDepth(maxDepth) {
2736
+ if (maxDepth === 2 || maxDepth === 3) {
2737
+ return maxDepth;
2738
+ }
2739
+ return 1;
2740
+ }
2741
+ function resolvePreset(rootNode, preset) {
2742
+ if (preset) {
2743
+ return preset;
2744
+ }
2745
+ if (!rootNode) {
2746
+ return null;
2747
+ }
2748
+ if (ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
2749
+ return "coverage";
2750
+ }
2751
+ if (rootNode.kind === "resource") {
2752
+ return "operational-dependencies";
2753
+ }
2754
+ return null;
2755
+ }
2756
+ function resolveRequest(rootNode, request) {
2757
+ const preset = resolvePreset(rootNode, request.preset);
2758
+ const maxResults = request.maxResults === void 0 || !Number.isFinite(request.maxResults) ? DEFAULT_MAX_RESULTS : Math.max(0, request.maxResults);
2759
+ return {
2760
+ rootNodeId: request.rootNodeId,
2761
+ direction: request.direction ?? (preset ? PRESET_DIRECTIONS[preset] : "both"),
2762
+ maxDepth: clampMaxDepth(request.maxDepth ?? DEFAULT_MAX_DEPTH),
2763
+ maxResults,
2764
+ edgeKinds: toSet(request.edgeKinds ?? (preset ? PRESET_EDGE_KINDS[preset] : void 0)),
2765
+ relationshipTypes: toSet(
2766
+ request.relationshipTypes ?? (preset ? PRESET_RELATIONSHIP_TYPES[preset] : void 0)
2767
+ ),
2768
+ preset,
2769
+ nodeKinds: toSet(request.nodeKinds),
2770
+ resourceTypes: toSet(request.resourceTypes),
2771
+ includeHiddenResources: request.includeHiddenResources ?? false
2772
+ };
2773
+ }
2774
+ function getOppositeNodeId(edge, currentNodeId) {
2775
+ if (edge.sourceId === currentNodeId) {
2776
+ return edge.targetId;
2777
+ }
2778
+ if (edge.targetId === currentNodeId) {
2779
+ return edge.sourceId;
2780
+ }
2781
+ return null;
2782
+ }
2783
+ function getCandidateEdges(index, nodeId2, direction) {
2784
+ if (direction === "outgoing") {
2785
+ return index.outgoingEdgesByNodeId.get(nodeId2) ?? [];
2786
+ }
2787
+ if (direction === "incoming") {
2788
+ return index.incomingEdgesByNodeId.get(nodeId2) ?? [];
2789
+ }
2790
+ const seenEdgeIds = /* @__PURE__ */ new Set();
2791
+ const edges = [];
2792
+ for (const edge of [
2793
+ ...index.outgoingEdgesByNodeId.get(nodeId2) ?? [],
2794
+ ...index.incomingEdgesByNodeId.get(nodeId2) ?? []
2795
+ ]) {
2796
+ if (seenEdgeIds.has(edge.id)) {
2797
+ continue;
2798
+ }
2799
+ seenEdgeIds.add(edge.id);
2800
+ edges.push(edge);
2801
+ }
2802
+ return edges;
2803
+ }
2804
+ function matchesPresetTraversalDirection(edge, currentNodeId, request) {
2805
+ if (request.preset === "coverage" && (edge.kind === "contains" || edge.kind === "exposes")) {
2806
+ return edge.sourceId === currentNodeId;
2807
+ }
2808
+ return true;
2809
+ }
2810
+ function matchesEdgeFilters(edge, currentNodeId, request) {
2811
+ if (request.edgeKinds && !request.edgeKinds.has(edge.kind)) {
2812
+ return false;
2813
+ }
2814
+ if (request.relationshipTypes && (!edge.relationshipType || !request.relationshipTypes.has(edge.relationshipType))) {
2815
+ return false;
2816
+ }
2817
+ return matchesPresetTraversalDirection(edge, currentNodeId, request);
2818
+ }
2819
+ function matchesNodeFilters(node, request) {
2820
+ if (request.nodeKinds && !request.nodeKinds.has(node.kind)) {
2821
+ return false;
2822
+ }
2823
+ if (request.resourceTypes) {
2824
+ if (node.kind !== "resource") {
2825
+ return false;
2826
+ }
2827
+ if (!node.resourceType || !request.resourceTypes.has(node.resourceType)) {
2828
+ return false;
2829
+ }
2830
+ }
2831
+ return true;
2832
+ }
2833
+ function pluralize(count, singular, plural = `${singular}s`) {
2834
+ return `${count} ${count === 1 ? singular : plural}`;
2835
+ }
2836
+ function getNodeDisplayName(node) {
2837
+ return node.label || node.sourceId || node.id;
2838
+ }
2839
+ function buildSummaryMessages(input) {
2840
+ const { rootNode, preset, expandedNodes, counts, truncated } = input;
2841
+ if (!rootNode) {
2842
+ return ["Select an available node to expand around."];
2843
+ }
2844
+ if (!preset && rootNode.kind === "organization") {
2845
+ return ["Choose a feature, surface, capability, entity, or resource before expanding."];
2846
+ }
2847
+ if (expandedNodes.length === 0) {
2848
+ return [`No matching graph context found around "${getNodeDisplayName(rootNode)}".`];
2849
+ }
2850
+ const resourceCount = expandedNodes.filter((node) => node.kind === "resource").length;
2851
+ const semanticContextCount = expandedNodes.length - resourceCount;
2852
+ const rootLabel = getNodeDisplayName(rootNode);
2853
+ const messages = [];
2854
+ if (preset === "coverage" && ORG_MODEL_ROOT_KINDS.has(rootNode.kind)) {
2855
+ if (resourceCount > 0 && semanticContextCount > 0) {
2856
+ messages.push(
2857
+ `${pluralize(resourceCount, "resource")} and ${pluralize(
2858
+ semanticContextCount,
2859
+ "semantic context node"
2860
+ )} support "${rootLabel}".`
2861
+ );
2862
+ } else if (resourceCount > 0) {
2863
+ messages.push(`${pluralize(resourceCount, "resource")} support "${rootLabel}".`);
2864
+ } else {
2865
+ messages.push(
2866
+ `${pluralize(semanticContextCount, "semantic context node")} found around "${rootLabel}"; no mapped resources matched this coverage preset.`
2867
+ );
2868
+ }
2869
+ } else if (preset === "operational-dependencies") {
2870
+ messages.push(`${pluralize(resourceCount, "operational dependency resource")} found around "${rootLabel}".`);
2871
+ } else if (preset === "org-context") {
2872
+ messages.push(`${pluralize(expandedNodes.length, "semantic context node")} found around "${rootLabel}".`);
2873
+ } else if (preset === "impact-path") {
2874
+ messages.push(`${pluralize(resourceCount, "resource")} can call or be affected by "${rootLabel}".`);
2875
+ } else {
2876
+ messages.push(`${pluralize(expandedNodes.length, "node")} found around "${rootLabel}".`);
2877
+ }
2878
+ if (counts.hiddenResourceNodes > 0) {
2879
+ messages.push(`${pluralize(counts.hiddenResourceNodes, "hidden resource")} matched current visibility settings.`);
2880
+ }
2881
+ if (counts.alreadyVisibleNodes > 0) {
2882
+ messages.push(`${pluralize(counts.alreadyVisibleNodes, "node")} already visible in the graph.`);
2883
+ }
2884
+ if (truncated) {
2885
+ messages.push(`Results were limited to ${pluralize(expandedNodes.length, "node")}.`);
2886
+ }
2887
+ return messages;
2888
+ }
2889
+ function expandAroundGraph(graph, request, options = {}) {
2890
+ const index = buildOrganizationGraphTraceIndex(graph);
2891
+ const rootNode = index.nodesById.get(request.rootNodeId) ?? null;
2892
+ const resolved = resolveRequest(rootNode, request);
2893
+ const alreadyVisibleNodeIds = new Set(options.alreadyVisibleNodeIds ?? []);
2894
+ const hiddenResourceNodeIds = new Set(options.hiddenResourceNodeIds ?? []);
2895
+ const expandedNodeIds = /* @__PURE__ */ new Set();
2896
+ const expandedEdgeIds = /* @__PURE__ */ new Set();
2897
+ const frontierNodeIds = /* @__PURE__ */ new Set();
2898
+ const visitedDepthByNodeId = /* @__PURE__ */ new Map([[resolved.rootNodeId, 0]]);
2899
+ const hasExplicitTraversalFilter = Boolean(
2900
+ request.preset || request.edgeKinds?.length || request.relationshipTypes?.length || request.nodeKinds?.length || request.resourceTypes?.length
2901
+ );
2902
+ const queue = rootNode && (resolved.preset || hasExplicitTraversalFilter) ? [{ nodeId: rootNode.id, depth: 0 }] : [];
2903
+ let truncated = false;
2904
+ for (let queueIndex = 0; queueIndex < queue.length; queueIndex += 1) {
2905
+ const current = queue[queueIndex];
2906
+ if (current.depth >= resolved.maxDepth) {
2907
+ if (current.nodeId !== resolved.rootNodeId) {
2908
+ frontierNodeIds.add(current.nodeId);
2909
+ }
2910
+ continue;
2911
+ }
2912
+ for (const edge of getCandidateEdges(index, current.nodeId, resolved.direction)) {
2913
+ if (!matchesEdgeFilters(edge, current.nodeId, resolved)) {
2914
+ continue;
2915
+ }
2916
+ const nextNodeId = getOppositeNodeId(edge, current.nodeId);
2917
+ if (!nextNodeId) {
2918
+ continue;
2919
+ }
2920
+ const nextNode = index.nodesById.get(nextNodeId);
2921
+ if (!nextNode || !matchesNodeFilters(nextNode, resolved)) {
2922
+ continue;
2923
+ }
2924
+ if (!resolved.includeHiddenResources && hiddenResourceNodeIds.has(nextNode.id)) {
2925
+ continue;
2926
+ }
2927
+ const nextDepth = current.depth + 1;
2928
+ const previousDepth = visitedDepthByNodeId.get(nextNode.id);
2929
+ if (previousDepth !== void 0) {
2930
+ if (nextNode.id === resolved.rootNodeId || expandedNodeIds.has(nextNode.id)) {
2931
+ expandedEdgeIds.add(edge.id);
2932
+ }
2933
+ continue;
2934
+ }
2935
+ if (expandedNodeIds.size >= resolved.maxResults) {
2936
+ truncated = true;
2937
+ frontierNodeIds.add(nextNode.id);
2938
+ continue;
2939
+ }
2940
+ visitedDepthByNodeId.set(nextNode.id, nextDepth);
2941
+ expandedNodeIds.add(nextNode.id);
2942
+ expandedEdgeIds.add(edge.id);
2943
+ if (nextDepth >= resolved.maxDepth) {
2944
+ frontierNodeIds.add(nextNode.id);
2945
+ continue;
2946
+ }
2947
+ queue.push({ nodeId: nextNode.id, depth: nextDepth });
2948
+ }
2949
+ }
2950
+ const expandedNodes = [...expandedNodeIds].map((nodeId2) => index.nodesById.get(nodeId2)).filter((node) => Boolean(node));
2951
+ const hiddenResourceNodes = expandedNodes.filter((node) => hiddenResourceNodeIds.has(node.id)).length;
2952
+ const alreadyVisibleNodes = expandedNodes.filter((node) => alreadyVisibleNodeIds.has(node.id)).length;
2953
+ const newNodes = expandedNodes.filter(
2954
+ (node) => !hiddenResourceNodeIds.has(node.id) && !alreadyVisibleNodeIds.has(node.id)
2955
+ ).length;
2956
+ const counts = {
2957
+ newNodes,
2958
+ newEdges: expandedEdgeIds.size,
2959
+ alreadyVisibleNodes,
2960
+ hiddenResourceNodes
2961
+ };
2962
+ const summaryMessages = buildSummaryMessages({
2963
+ rootNode,
2964
+ preset: resolved.preset,
2965
+ expandedNodes,
2966
+ counts,
2967
+ truncated
2968
+ });
2969
+ return {
2970
+ rootNodeId: request.rootNodeId,
2971
+ rootNode,
2972
+ preset: resolved.preset,
2973
+ direction: resolved.direction,
2974
+ maxDepth: resolved.maxDepth,
2975
+ maxResults: resolved.maxResults,
2976
+ expandedNodeIds: [...expandedNodeIds],
2977
+ expandedEdgeIds: [...expandedEdgeIds],
2978
+ frontierNodeIds: [...frontierNodeIds].filter((nodeId2) => nodeId2 !== resolved.rootNodeId),
2979
+ truncated,
2980
+ counts,
2981
+ summaryMessages,
2982
+ message: summaryMessages[0] ?? ""
2983
+ };
2984
+ }
2985
+ var PRESET_OPTIONS = [
2986
+ { value: "coverage", label: "Coverage" },
2987
+ { value: "operational-dependencies", label: "Operational dependencies" },
2988
+ { value: "org-context", label: "Org context" },
2989
+ { value: "impact-path", label: "Impact path" }
2990
+ ];
2991
+ var DIRECTION_OPTIONS = [
2992
+ { value: "both", label: "Both" },
2993
+ { value: "outgoing", label: "Outgoing" },
2994
+ { value: "incoming", label: "Incoming" }
2995
+ ];
2996
+ var EDGE_KIND_OPTIONS = [
2997
+ { value: "contains", label: "Containment" },
2998
+ { value: "references", label: "References" },
2999
+ { value: "exposes", label: "Exposes" },
3000
+ { value: "maps_to", label: "Maps to" },
3001
+ { value: "operates-on", label: "Operates on" },
3002
+ { value: "uses", label: "Uses" }
3003
+ ];
3004
+ var RELATIONSHIP_OPTIONS = [
3005
+ { value: "triggers", label: "Triggers" },
3006
+ { value: "uses", label: "Uses" },
3007
+ { value: "approval", label: "Approval" }
3008
+ ];
3009
+ var RESOURCE_TYPE_OPTIONS = [
3010
+ { value: "workflow", label: "Workflow" },
3011
+ { value: "agent", label: "Agent" },
3012
+ { value: "trigger", label: "Trigger" },
3013
+ { value: "integration", label: "Integration" },
3014
+ { value: "external", label: "External" },
3015
+ { value: "human_checkpoint", label: "Human checkpoint" }
3016
+ ];
3017
+ function updateValue(value, key, nextValue, onChange) {
3018
+ onChange({
3019
+ ...value,
3020
+ [key]: nextValue
3021
+ });
3022
+ }
3023
+ function toOptionalArray(values) {
3024
+ return values.length > 0 ? values : void 0;
3025
+ }
3026
+ function toMaxDepth(value) {
3027
+ const numeric = typeof value === "number" ? value : Number.parseInt(value, 10);
3028
+ if (numeric === 3) return 3;
3029
+ if (numeric === 2) return 2;
3030
+ return 1;
3031
+ }
3032
+ function ExpandAroundPanel({
3033
+ selectedNode,
3034
+ value,
3035
+ result,
3036
+ appliedNodeCount,
3037
+ appliedEdgeCount,
3038
+ onChange,
3039
+ onPreview,
3040
+ onApply,
3041
+ onClear
3042
+ }) {
3043
+ const disabled = !selectedNode;
3044
+ const canApply = Boolean(result && result.expandedNodeIds.length > 0);
3045
+ const rootIsTooBroad = selectedNode?.kind === "organization" && !value.preset;
3046
+ return /* @__PURE__ */ jsx(Paper, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3047
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "wrap", children: [
3048
+ /* @__PURE__ */ jsxs(Stack, { gap: 2, children: [
3049
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 800, children: "Expand Around" }),
3050
+ /* @__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." })
3051
+ ] }),
3052
+ appliedNodeCount > 0 || appliedEdgeCount > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "light", color: "blue", children: [
3053
+ appliedNodeCount,
3054
+ " nodes / ",
3055
+ appliedEdgeCount,
3056
+ " edges applied"
3057
+ ] }) : null
3058
+ ] }),
3059
+ /* @__PURE__ */ jsxs(SimpleGrid, { cols: { base: 1, sm: 2 }, spacing: "sm", children: [
3060
+ /* @__PURE__ */ jsx(
3061
+ Select,
3062
+ {
3063
+ label: "Preset",
3064
+ placeholder: "Auto",
3065
+ data: PRESET_OPTIONS,
3066
+ value: value.preset ?? null,
3067
+ onChange: (preset) => updateValue(value, "preset", preset ?? void 0, onChange),
3068
+ disabled,
3069
+ clearable: true
3070
+ }
3071
+ ),
3072
+ /* @__PURE__ */ jsx(
3073
+ Select,
3074
+ {
3075
+ label: "Direction",
3076
+ data: DIRECTION_OPTIONS,
3077
+ value: value.direction ?? "both",
3078
+ onChange: (direction) => updateValue(value, "direction", direction ?? "both", onChange),
3079
+ disabled
3080
+ }
3081
+ ),
3082
+ /* @__PURE__ */ jsx(
3083
+ NumberInput,
3084
+ {
3085
+ label: "Depth",
3086
+ min: 1,
3087
+ max: 3,
3088
+ value: value.maxDepth ?? 1,
3089
+ onChange: (maxDepth) => updateValue(value, "maxDepth", toMaxDepth(maxDepth), onChange),
3090
+ disabled
3091
+ }
3092
+ ),
3093
+ /* @__PURE__ */ jsx(
3094
+ NumberInput,
3095
+ {
3096
+ label: "Max results",
3097
+ min: 1,
3098
+ max: 100,
3099
+ value: value.maxResults ?? 25,
3100
+ onChange: (maxResults) => updateValue(
3101
+ value,
3102
+ "maxResults",
3103
+ Math.max(1, typeof maxResults === "number" ? maxResults : Number.parseInt(maxResults, 10) || 25),
3104
+ onChange
3105
+ ),
3106
+ disabled
3107
+ }
3108
+ )
3109
+ ] }),
3110
+ /* @__PURE__ */ jsx(
3111
+ MultiSelect,
3112
+ {
3113
+ label: "Relationship filters",
3114
+ placeholder: "Preset defaults",
3115
+ data: RELATIONSHIP_OPTIONS,
3116
+ value: value.relationshipTypes ?? [],
3117
+ onChange: (relationshipTypes) => updateValue(value, "relationshipTypes", toOptionalArray(relationshipTypes), onChange),
3118
+ disabled,
3119
+ clearable: true
3120
+ }
3121
+ ),
3122
+ /* @__PURE__ */ jsx(
3123
+ MultiSelect,
3124
+ {
3125
+ label: "Edge kind filters",
3126
+ placeholder: "Preset defaults",
3127
+ data: EDGE_KIND_OPTIONS,
3128
+ value: value.edgeKinds ?? [],
3129
+ onChange: (edgeKinds) => updateValue(value, "edgeKinds", toOptionalArray(edgeKinds), onChange),
3130
+ disabled,
3131
+ clearable: true
3132
+ }
3133
+ ),
3134
+ /* @__PURE__ */ jsx(
3135
+ MultiSelect,
3136
+ {
3137
+ label: "Resource type filters",
3138
+ placeholder: "All resource types",
3139
+ data: RESOURCE_TYPE_OPTIONS,
3140
+ value: value.resourceTypes ?? [],
3141
+ onChange: (resourceTypes) => updateValue(value, "resourceTypes", toOptionalArray(resourceTypes), onChange),
3142
+ disabled,
3143
+ clearable: true
3144
+ }
3145
+ ),
3146
+ /* @__PURE__ */ jsx(
3147
+ Switch,
3148
+ {
3149
+ label: "Include hidden resources",
3150
+ checked: value.includeHiddenResources ?? true,
3151
+ onChange: (event) => updateValue(value, "includeHiddenResources", event.currentTarget.checked, onChange),
3152
+ disabled
3153
+ }
3154
+ ),
3155
+ 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,
3156
+ result ? /* @__PURE__ */ jsx(Card, { withBorder: true, radius: "md", p: "sm", children: /* @__PURE__ */ jsxs(Stack, { gap: 6, children: [
3157
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
3158
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
3159
+ result.counts.newNodes,
3160
+ " new"
3161
+ ] }),
3162
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
3163
+ result.counts.alreadyVisibleNodes,
3164
+ " visible"
3165
+ ] }),
3166
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", color: result.counts.hiddenResourceNodes > 0 ? "orange" : "gray", children: [
3167
+ result.counts.hiddenResourceNodes,
3168
+ " hidden"
3169
+ ] }),
3170
+ result.truncated ? /* @__PURE__ */ jsx(Badge, { variant: "light", color: "yellow", children: "Truncated" }) : null
3171
+ ] }),
3172
+ result.summaryMessages.map((message) => /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: message }, message))
3173
+ ] }) }) : null,
3174
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", justify: "space-between", wrap: "wrap", children: [
3175
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", children: [
3176
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: onPreview, disabled: disabled || rootIsTooBroad, children: "Preview" }),
3177
+ /* @__PURE__ */ jsx(Button, { size: "xs", onClick: onApply, disabled: !canApply, children: "Apply" })
3178
+ ] }),
3179
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "subtle", onClick: onClear, disabled: !result && appliedNodeCount === 0, children: "Clear expansion" })
3180
+ ] })
3181
+ ] }) });
3182
+ }
3183
+ var FILTER_STATE_ICONS = {
3184
+ neutral: IconCircleDashed,
3185
+ include: IconCircleCheck,
3186
+ exclude: IconCircleX
3187
+ };
3188
+ var FILTER_STATE_COLORS = {
3189
+ neutral: "var(--color-text-dimmed)",
3190
+ include: "var(--mantine-color-green-6)",
3191
+ exclude: "var(--mantine-color-red-6)"
3192
+ };
3193
+ var FILTER_STATE_LABELS = {
3194
+ neutral: "Not filtered",
3195
+ include: "Include only",
3196
+ exclude: "Exclude"
3197
+ };
3198
+ function getCommandViewResources(commandViewData) {
3199
+ if (!commandViewData) {
3200
+ return [];
3201
+ }
3202
+ return [
3203
+ ...commandViewData.agents,
3204
+ ...commandViewData.workflows,
3205
+ ...commandViewData.triggers,
3206
+ ...commandViewData.integrations,
3207
+ ...commandViewData.externalResources,
3208
+ ...commandViewData.humanCheckpoints
3209
+ ];
3210
+ }
3211
+ function nextDomainFilterState(current) {
3212
+ if (current === "neutral") return "include";
3213
+ if (current === "include") return "exclude";
3214
+ return "neutral";
3215
+ }
3216
+ function FilterPanel({
3217
+ filters,
3218
+ onChangeFilters,
3219
+ resetValue,
3220
+ disabled = false,
3221
+ commandViewData,
3222
+ lens,
3223
+ resourcesHidden,
3224
+ diagnosticsHidden,
3225
+ onResourcesHiddenChange,
3226
+ onDiagnosticsHiddenChange,
3227
+ onRevealResources,
3228
+ onResetFilters,
3229
+ visibilityCounts,
3230
+ graph,
3231
+ baseGraph,
3232
+ layout = "grid"
3233
+ }) {
3234
+ const resourceFacets = collectResourceFilterFacets(getCommandViewResources(commandViewData));
3235
+ const Section = ({ children }) => layout === "stack" ? /* @__PURE__ */ jsx(
3236
+ Stack,
3237
+ {
3238
+ gap: "sm",
3239
+ pb: "sm",
3240
+ style: {
3241
+ borderBottom: "1px solid var(--color-border)"
3242
+ },
3243
+ children
3244
+ }
3245
+ ) : /* @__PURE__ */ jsx(Paper, { withBorder: true, p: "md", radius: "md", style: { background: "var(--color-surface)" }, children });
3246
+ const updateDomainFilter = (domainId) => {
3247
+ const current = filters.domainFilters[domainId] ?? "neutral";
3248
+ onChangeFilters({
3249
+ ...filters,
3250
+ domainFilters: {
3251
+ ...filters.domainFilters,
3252
+ [domainId]: nextDomainFilterState(current)
3253
+ }
3254
+ });
3255
+ };
3256
+ const handleResourceVisibilityAction = () => {
3257
+ if (resourcesHidden) {
3258
+ onRevealResources();
3259
+ return;
3260
+ }
3261
+ onResourcesHiddenChange(true);
3262
+ };
3263
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
3264
+ /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3265
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Filters" }),
3266
+ /* @__PURE__ */ jsx(
3267
+ OrganizationGraphFilterToolbar,
3268
+ {
3269
+ value: filters,
3270
+ onChange: onChangeFilters,
3271
+ disabled,
3272
+ resetValue
3273
+ }
3274
+ )
3275
+ ] }) }),
3276
+ /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3277
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", children: [
3278
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Visibility" }),
3279
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
3280
+ visibilityCounts.visibleResourceCount,
3281
+ "/",
3282
+ visibilityCounts.totalResourceCount,
3283
+ " resources"
3284
+ ] })
3285
+ ] }),
3286
+ lens === "command-view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
3287
+ /* @__PURE__ */ jsx(
3288
+ Checkbox,
3289
+ {
3290
+ label: "Hide resource nodes",
3291
+ description: "Keep the organization structure readable and reveal resource nodes as needed.",
3292
+ checked: resourcesHidden,
3293
+ onChange: (event) => onResourcesHiddenChange(event.currentTarget.checked),
3294
+ disabled
3295
+ }
3296
+ ),
3297
+ /* @__PURE__ */ jsx(
3298
+ Checkbox,
3299
+ {
3300
+ label: "Hide diagnostic and testing resources",
3301
+ description: "Diagnostics stay available through filters, trace, impact, and contextual reveal.",
3302
+ checked: diagnosticsHidden,
3303
+ onChange: (event) => onDiagnosticsHiddenChange(event.currentTarget.checked),
3304
+ disabled
3305
+ }
3306
+ ),
3307
+ /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "wrap", children: [
3308
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenResourceCount > 0 ? "yellow" : "green", children: [
3309
+ visibilityCounts.hiddenResourceCount,
3310
+ " hidden"
3311
+ ] }),
3312
+ /* @__PURE__ */ jsxs(Badge, { variant: "light", color: visibilityCounts.hiddenDiagnosticResourceCount > 0 ? "yellow" : "gray", children: [
3313
+ visibilityCounts.hiddenDiagnosticResourceCount,
3314
+ " diagnostic/testing"
3315
+ ] })
3316
+ ] }),
3317
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", children: [
3318
+ /* @__PURE__ */ jsx(Button, { size: "xs", variant: "light", onClick: handleResourceVisibilityAction, disabled, children: resourcesHidden ? "Reveal resources" : "Hide resources" }),
3319
+ /* @__PURE__ */ jsx(
3320
+ Button,
3321
+ {
3322
+ size: "xs",
3323
+ variant: "subtle",
3324
+ leftSection: /* @__PURE__ */ jsx(IconRefresh, { size: 14 }),
3325
+ onClick: onResetFilters,
3326
+ disabled,
3327
+ children: "Reset filters"
3328
+ }
3329
+ )
3330
+ ] })
3331
+ ] }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "Visibility controls are available in the Command View lens." })
3332
+ ] }) }),
3333
+ /* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", children: [
3334
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Resource Facets" }),
3335
+ resourceFacets.length > 0 ? /* @__PURE__ */ jsx(Stack, { gap: 4, children: resourceFacets.map((facet) => {
3336
+ const filterState = filters.domainFilters[facet.id] ?? "neutral";
3337
+ const StateIcon = FILTER_STATE_ICONS[filterState];
3338
+ return /* @__PURE__ */ jsx(
3339
+ UnstyledButton,
3340
+ {
3341
+ title: FILTER_STATE_LABELS[filterState],
3342
+ onClick: () => updateDomainFilter(facet.id),
3343
+ disabled,
3344
+ style: {
3345
+ border: "1px solid var(--color-border)",
3346
+ borderRadius: "var(--mantine-radius-sm)",
3347
+ padding: "6px 8px"
3348
+ },
3349
+ children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
3350
+ /* @__PURE__ */ jsx(StateIcon, { size: 16, style: { color: FILTER_STATE_COLORS[filterState], flexShrink: 0 } }),
3351
+ /* @__PURE__ */ jsx(Text, { size: "sm", truncate: true, c: filterState === "neutral" ? "dimmed" : void 0, children: facet.label })
3352
+ ] })
3353
+ },
3354
+ facet.id
3355
+ );
3356
+ }) }) : /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No resource facets are available for the current topology." }),
3357
+ /* @__PURE__ */ jsxs(Text, { size: "xs", c: "dimmed", children: [
3358
+ "Showing ",
3359
+ graph?.nodes.length ?? 0,
3360
+ " nodes and ",
3361
+ graph?.edges.length ?? 0,
3362
+ " edges from",
3363
+ " ",
3364
+ baseGraph?.nodes.length ?? 0,
3365
+ " total nodes."
3366
+ ] })
3367
+ ] }) })
3368
+ ] });
3369
+ if (layout === "stack") {
3370
+ return /* @__PURE__ */ jsx(Stack, { gap: "sm", children: content });
3371
+ }
3372
+ return /* @__PURE__ */ jsx(SimpleGrid, { cols: { base: 1, lg: 3 }, spacing: "md", children: content });
3373
+ }
3374
+ var EXECUTION_SECTIONS = [
3375
+ { status: "failed", title: "Failed Executions", badgeColor: "red" },
3376
+ { status: "warning", title: "Warning Executions", badgeColor: "yellow" },
3377
+ { status: "completed", title: "Successful Executions", badgeColor: null }
3378
+ ];
3379
+ var HOVER_CARD_STYLE = {
3380
+ cursor: "pointer",
3381
+ transition: "box-shadow var(--duration-fast) var(--easing)",
3382
+ textDecoration: "none",
3383
+ color: "inherit"
3384
+ };
3385
+ function handleHoverEnter(e) {
3386
+ e.currentTarget.style.boxShadow = "var(--standard-box-shadow)";
3387
+ }
3388
+ function handleHoverLeave(e) {
3389
+ e.currentTarget.style.boxShadow = "";
3390
+ }
3391
+ function ExecutionStatusSection({ executions, status, title, badgeColor, resourceUrl }) {
3392
+ const filtered = executions.filter((e) => e.status === status);
3393
+ if (filtered.length === 0) return null;
3394
+ return /* @__PURE__ */ jsxs("div", { children: [
3395
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
3396
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: title }),
3397
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: filtered.length })
3398
+ ] }),
3399
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: filtered.map((execution) => /* @__PURE__ */ jsxs(
3400
+ Card,
3401
+ {
3402
+ padding: "xs",
3403
+ withBorder: true,
3404
+ component: "a",
3405
+ href: `${resourceUrl}?exec=${execution.executionId}`,
3406
+ target: "_blank",
3407
+ rel: "noopener noreferrer",
3408
+ style: HOVER_CARD_STYLE,
3409
+ onMouseEnter: handleHoverEnter,
3410
+ onMouseLeave: handleHoverLeave,
3411
+ children: [
3412
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: status === "failed" && execution.errorMessage ? 4 : 0, children: [
3413
+ badgeColor ? /* @__PURE__ */ jsx(Badge, { size: "xs", color: badgeColor, variant: "light", children: status }) : /* @__PURE__ */ jsx(Text, { size: "xs", c: "green", children: "\u2713 Completed" }),
3414
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime(execution.startedAt) })
3415
+ ] }),
3416
+ status === "failed" && execution.errorMessage && /* @__PURE__ */ jsx(Text, { size: "xs", c: "red", lineClamp: 2, children: execution.errorMessage })
3417
+ ]
3418
+ },
3419
+ execution.executionId
3420
+ )) }),
3421
+ /* @__PURE__ */ jsx(Space, { h: "sm" })
3422
+ ] });
3423
+ }
3424
+ function CommandViewSidebarContent({ timeRange }) {
3425
+ const theme = useMantineTheme();
3426
+ const colors = useCyberColors();
3427
+ const { organizationModel } = useElevasisFeatures();
3428
+ const lensConfig = useMemo(() => getOrganizationGraphLensConfig("command-view"), []);
3429
+ const { filters, resetFilters, updateFilters } = useOrganizationGraphFilters(lensConfig.initialFilters);
3430
+ const toolbarResetValue = useMemo(
3431
+ () => createOrganizationGraphFilters(lensConfig.initialFilters),
3432
+ [lensConfig.initialFilters]
3433
+ );
3434
+ const selectedNodeId = useCommandViewStore((s) => s.selectedNodeId);
3435
+ const resourcesHidden = useCommandViewStore((s) => s.resourcesHidden);
3436
+ const setResourcesHidden = useCommandViewStore((s) => s.setResourcesHidden);
3437
+ const diagnosticsHidden = useCommandViewStore((s) => s.diagnosticsHidden);
3438
+ const setDiagnosticsHidden = useCommandViewStore((s) => s.setDiagnosticsHidden);
3439
+ const diagnosticCategories = useCommandViewStore((s) => s.diagnosticCategories);
3440
+ const revealedIds = useCommandViewStore((s) => s.revealedIds);
3441
+ const clearRevealedIds = useCommandViewStore((s) => s.clearRevealedIds);
3442
+ const { data, isLoading } = useCommandViewData();
3443
+ const { data: statsData } = useCommandViewStats(timeRange);
3444
+ const cleanData = data ?? null;
3445
+ const dataWithStats = useMemo(() => {
3446
+ if (!cleanData) return null;
3447
+ if (!statsData) return cleanData;
3448
+ return mergeStatsWithTopology(cleanData, statsData);
3449
+ }, [cleanData, statsData]);
3450
+ const baseGraph = useMemo(() => {
3451
+ if (!organizationModel) {
3452
+ return null;
3453
+ }
3454
+ return buildOrganizationGraph({
3455
+ organizationModel,
3456
+ commandViewData: cleanData ?? void 0
3457
+ });
3458
+ }, [cleanData, organizationModel]);
3459
+ const graph = useMemo(() => {
3460
+ if (!baseGraph) {
3461
+ return null;
3462
+ }
3463
+ return filterOrganizationGraph(baseGraph, filters, {
3464
+ commandViewData: cleanData
3465
+ });
3466
+ }, [baseGraph, cleanData, filters]);
3467
+ const visibilityProjection = useMemo(() => {
3468
+ if (!graph) {
3469
+ return {
3470
+ hiddenIds: /* @__PURE__ */ new Set(),
3471
+ hiddenEdgeIds: /* @__PURE__ */ new Set(),
3472
+ totalResourceCount: 0,
3473
+ visibleResourceCount: 0,
3474
+ hiddenResourceCount: 0,
3475
+ hiddenDiagnosticResourceCount: 0
3476
+ };
3477
+ }
3478
+ return getCommandViewVisibilityProjection({
3479
+ graph,
3480
+ commandViewData: cleanData,
3481
+ resourcesHidden,
3482
+ diagnosticsHidden,
3483
+ diagnosticCategories,
3484
+ revealedIds,
3485
+ mode: "map"
3486
+ });
3487
+ }, [cleanData, diagnosticCategories, diagnosticsHidden, graph, resourcesHidden, revealedIds]);
3488
+ const visibleGraph = useMemo(() => {
3489
+ if (!graph || visibilityProjection.hiddenIds.size === 0) {
3490
+ return graph;
3491
+ }
3492
+ return {
3493
+ ...graph,
3494
+ nodes: graph.nodes.filter((node) => !visibilityProjection.hiddenIds.has(node.id)),
3495
+ edges: graph.edges.filter((edge) => !visibilityProjection.hiddenEdgeIds.has(edge.id))
3496
+ };
3497
+ }, [graph, visibilityProjection]);
3498
+ const handleResetFilters = () => {
3499
+ resetFilters();
3500
+ clearRevealedIds();
3501
+ };
3502
+ const handleResourcesHiddenChange = (value) => {
3503
+ setResourcesHidden(value);
3504
+ if (value) {
3505
+ clearRevealedIds();
3506
+ }
3507
+ };
3508
+ const handleDiagnosticsHiddenChange = (value) => {
3509
+ setDiagnosticsHidden(value);
3510
+ if (value) {
3511
+ clearRevealedIds();
3512
+ }
3513
+ };
3514
+ const revealAllResources = () => {
3515
+ setResourcesHidden(false);
3516
+ setDiagnosticsHidden(false);
3517
+ clearRevealedIds();
3518
+ };
3519
+ const { donutSuccessCount, donutFailedCount } = useMemo(() => {
3520
+ if (!cleanData || !statsData) return { donutSuccessCount: 0, donutFailedCount: 0 };
3521
+ const allResources = [
3522
+ ...cleanData.agents,
3523
+ ...cleanData.workflows,
3524
+ ...cleanData.triggers,
3525
+ ...cleanData.integrations,
3526
+ ...cleanData.externalResources ?? [],
3527
+ ...cleanData.humanCheckpoints ?? []
3528
+ ];
3529
+ const filteredIds = new Set(allResources.map((resource) => resource.resourceId));
3530
+ let success = 0;
3531
+ let failed = 0;
3532
+ for (const [id, stats] of Object.entries(statsData.resources)) {
3533
+ if (filteredIds.has(id)) {
3534
+ success += stats.successCount;
3535
+ failed += stats.failureCount;
3536
+ }
3537
+ }
3538
+ return { donutSuccessCount: success, donutFailedCount: failed };
3539
+ }, [cleanData, statsData]);
3540
+ const selectedNode = useMemo(() => {
3541
+ if (!selectedNodeId || !dataWithStats) return null;
3542
+ const allNodes = [
3543
+ ...dataWithStats.agents || [],
3544
+ ...dataWithStats.workflows || [],
3545
+ ...dataWithStats.triggers || [],
3546
+ ...dataWithStats.integrations || [],
3547
+ ...dataWithStats.externalResources || [],
3548
+ ...dataWithStats.humanCheckpoints || []
3549
+ ];
3550
+ return allNodes.find((node) => {
3551
+ const nodeId2 = getNodeId(node);
3552
+ return nodeId2 === selectedNodeId || node.name === selectedNodeId;
3553
+ }) || null;
3554
+ }, [selectedNodeId, dataWithStats]);
3555
+ const isNavigable = selectedNode?.type === "agent" || selectedNode?.type === "workflow";
3556
+ const isHumanCheckpoint = selectedNode?.type === "human";
3557
+ const selectedResourceId = useMemo(() => {
3558
+ if (!selectedNode) return null;
3559
+ return getNodeId(selectedNode);
3560
+ }, [selectedNode]);
3561
+ const {
3562
+ page: executionPage,
3563
+ setPage: setExecutionPage,
3564
+ totalPages: totalExecutionPages
3565
+ } = usePaginationState(10, [selectedResourceId, timeRange]);
3566
+ const getNavigationUrl = () => {
3567
+ if (!selectedNode || !selectedResourceId) return null;
3568
+ if (selectedNode.type === "agent") return `/operations/resources/agent/${selectedResourceId}`;
3569
+ if (selectedNode.type === "workflow") return `/operations/resources/workflow/${selectedResourceId}`;
3570
+ if (selectedNode.type === "human") return `/operations/command-queue?checkpoint=${selectedResourceId}`;
3571
+ return null;
3572
+ };
3573
+ const resourceUrl = selectedNode?.type === "agent" ? `/operations/resources/agent/${selectedResourceId}` : `/operations/resources/workflow/${selectedResourceId}`;
3574
+ const {
3575
+ data: executionsData,
3576
+ isLoading: executionsLoading,
3577
+ error: executionsError
3578
+ } = useResourceExecutions({
3579
+ resourceId: selectedResourceId,
3580
+ timeRange,
3581
+ page: executionPage,
3582
+ limit: 10,
3583
+ enabled: isNavigable
3584
+ });
3585
+ const {
3586
+ data: checkpointTasksData,
3587
+ isLoading: checkpointTasksLoading,
3588
+ error: checkpointTasksError
3589
+ } = useCheckpointTasks({
3590
+ checkpointId: selectedResourceId,
3591
+ enabled: isHumanCheckpoint
3592
+ });
3593
+ const totalExecutions = donutSuccessCount + donutFailedCount;
3594
+ const successRate = totalExecutions > 0 ? donutSuccessCount / totalExecutions * 100 : 0;
3595
+ const healthSegments = [
3596
+ { name: "Completed", value: donutSuccessCount, color: colors.green },
3597
+ { name: "Failed", value: donutFailedCount, color: colors.red }
3598
+ ];
3599
+ const centerValueColor = totalExecutions === 0 ? "var(--mantine-color-dimmed)" : successRate >= 95 ? colors.green : successRate >= 80 ? colors.yellow : colors.red;
3600
+ if (isLoading && !data) {
3601
+ return /* @__PURE__ */ jsx(SubshellSidebarLoader, {});
3602
+ }
3603
+ return /* @__PURE__ */ jsx(
3604
+ Box,
3605
+ {
3606
+ style: {
3607
+ flex: 1,
3608
+ height: "100%",
3609
+ minHeight: 0,
3610
+ display: "flex",
3611
+ flexDirection: "column",
3612
+ overflow: "hidden"
3613
+ },
3614
+ children: /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", overflowX: "hidden" }, children: [
3615
+ /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconSitemap, label: "Command View" }),
3616
+ /* @__PURE__ */ jsx(Box, { style: { padding: theme.spacing.sm, paddingBottom: 0 }, children: /* @__PURE__ */ jsx(Box, { pb: "xs", mb: 4, children: /* @__PURE__ */ jsx(
3617
+ CyberDonut,
3618
+ {
3619
+ title: `Execution Health (${timeRange})`,
3620
+ segments: healthSegments,
3621
+ centerValue: totalExecutions === 0 ? "\u2014" : `${Math.round(successRate)}%`,
3622
+ centerLabel: `${totalExecutions} runs`,
3623
+ centerValueColor,
3624
+ glowId: "cvHealthGlow",
3625
+ colors
3626
+ }
3627
+ ) }) }),
3628
+ /* @__PURE__ */ jsx(Box, { p: "sm", children: /* @__PURE__ */ jsx(
3629
+ FilterPanel,
3630
+ {
3631
+ filters,
3632
+ onChangeFilters: updateFilters,
3633
+ resetValue: toolbarResetValue,
3634
+ disabled: !baseGraph,
3635
+ commandViewData: cleanData,
3636
+ lens: "command-view",
3637
+ resourcesHidden,
3638
+ diagnosticsHidden,
3639
+ onResourcesHiddenChange: handleResourcesHiddenChange,
3640
+ onDiagnosticsHiddenChange: handleDiagnosticsHiddenChange,
3641
+ onRevealResources: revealAllResources,
3642
+ onResetFilters: handleResetFilters,
3643
+ visibilityCounts: visibilityProjection,
3644
+ graph: visibleGraph,
3645
+ baseGraph,
3646
+ layout: "stack"
3647
+ }
3648
+ ) }),
3649
+ selectedNode && /* @__PURE__ */ jsxs(Fragment, { children: [
3650
+ /* @__PURE__ */ jsx(Divider, {}),
3651
+ /* @__PURE__ */ jsxs(Stack, { gap: "xs", p: "sm", mt: 8, children: [
3652
+ /* @__PURE__ */ jsx(Title, { order: 4, children: selectedNode.name }),
3653
+ selectedNode.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: selectedNode.description }),
3654
+ (isNavigable || isHumanCheckpoint) && /* @__PURE__ */ jsxs(
3655
+ Button,
3656
+ {
3657
+ component: "a",
3658
+ href: getNavigationUrl() || "#",
3659
+ target: "_blank",
3660
+ rel: "noopener noreferrer",
3661
+ variant: "light",
3662
+ size: "xs",
3663
+ leftSection: /* @__PURE__ */ jsx(IconExternalLink, { size: 14 }),
3664
+ mt: 4,
3665
+ children: [
3666
+ "Go to",
3667
+ " ",
3668
+ selectedNode.type === "agent" ? "Agent" : selectedNode.type === "workflow" ? "Workflow" : "Queue"
3669
+ ]
3670
+ }
3671
+ ),
3672
+ /* @__PURE__ */ jsx(Space, { h: "sm" })
3673
+ ] })
3674
+ ] }),
3675
+ 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: [
3676
+ EXECUTION_SECTIONS.map((section) => /* @__PURE__ */ jsx(
3677
+ ExecutionStatusSection,
3678
+ {
3679
+ executions: executionsData.executions,
3680
+ status: section.status,
3681
+ title: section.title,
3682
+ badgeColor: section.badgeColor,
3683
+ resourceUrl
3684
+ },
3685
+ section.status
3686
+ )),
3687
+ totalExecutionPages(executionsData.totalExecutions) > 1 && /* @__PURE__ */ jsx(Group, { justify: "center", children: /* @__PURE__ */ jsx(
3688
+ Pagination,
3689
+ {
3690
+ size: "sm",
3691
+ total: totalExecutionPages(executionsData.totalExecutions),
3692
+ value: executionPage,
3693
+ onChange: setExecutionPage,
3694
+ boundaries: 1
3695
+ }
3696
+ ) })
3697
+ ] }) : executionsData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No executions in the selected time range" }) : null }),
3698
+ 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: [
3699
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: 8, children: [
3700
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", children: "Pending Tasks" }),
3701
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: checkpointTasksData.tasks.length })
3702
+ ] }),
3703
+ /* @__PURE__ */ jsx(Stack, { gap: "xs", children: checkpointTasksData.tasks.map((task) => /* @__PURE__ */ jsxs(
3704
+ Card,
3705
+ {
3706
+ padding: "xs",
3707
+ withBorder: true,
3708
+ component: "a",
3709
+ href: `/operations/command-queue?task=${task.id}`,
3710
+ target: "_blank",
3711
+ rel: "noopener noreferrer",
3712
+ style: HOVER_CARD_STYLE,
3713
+ onMouseEnter: handleHoverEnter,
3714
+ onMouseLeave: handleHoverLeave,
3715
+ children: [
3716
+ /* @__PURE__ */ jsxs(Group, { justify: "space-between", mb: task.description ? 4 : 0, children: [
3717
+ /* @__PURE__ */ jsx(Badge, { size: "xs", color: "orange", variant: "light", children: "pending" }),
3718
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: formatRelativeTime(task.createdAt) })
3719
+ ] }),
3720
+ task.description && /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", lineClamp: 2, children: task.description })
3721
+ ]
3722
+ },
3723
+ task.id
3724
+ )) })
3725
+ ] }) : checkpointTasksData ? /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", children: "No pending tasks" }) : null })
3726
+ ] })
3727
+ }
3728
+ );
3729
+ }
3730
+
3731
+ export { CommandViewSidebarContent, DEFAULT_ORGANIZATION_MODEL_BRANDING, DEFAULT_ORGANIZATION_MODEL_CUSTOMERS, DEFAULT_ORGANIZATION_MODEL_GOALS, DEFAULT_ORGANIZATION_MODEL_IDENTITY, DEFAULT_ORGANIZATION_MODEL_OFFERINGS, DEFAULT_ORGANIZATION_MODEL_OPERATIONS, DEFAULT_ORGANIZATION_MODEL_PROJECTS, DEFAULT_ORGANIZATION_MODEL_ROLES, DEFAULT_ORGANIZATION_MODEL_STATUSES, ExpandAroundPanel, FilterPanel, OrganizationGraphDetailPanel, OrganizationModelSchema, buildCommandViewDrillDownSections, buildOrganizationGraph, createOrganizationGraphFilters, expandAroundGraph, filterOrganizationGraph, formatOrganizationGraphTraceNodeOptionLabel, getCommandViewOperationalOverview, getCommandViewSelectionOperationalSummary, getCommandViewVisibilityProjection, getConnectedHiddenResourceIds, getOrganizationGraphLensConfig, getOrganizationGraphTraceNodeOptions, resolveOrganizationGraphPathTrace, useOrganizationGraphFilters };