@elevasis/ui 2.25.6 → 2.26.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/api/index.js +2 -2
  2. package/dist/app/index.css +15 -5
  3. package/dist/app/index.d.ts +61 -14
  4. package/dist/app/index.js +6 -6
  5. package/dist/charts/index.js +6 -5
  6. package/dist/chunk-3MEXPLWT.js +265 -0
  7. package/dist/{chunk-BDKM56TP.js → chunk-4KTLOK7K.js} +1 -1
  8. package/dist/{chunk-KMAXFJPH.js → chunk-CW3UNAF2.js} +5 -409
  9. package/dist/{chunk-HKBEURCV.js → chunk-G26INIF3.js} +1 -1
  10. package/dist/{chunk-7F3IQMLI.js → chunk-G66QFZXD.js} +11 -214
  11. package/dist/{chunk-QIW6OCEI.js → chunk-HLFFKKT3.js} +27 -373
  12. package/dist/chunk-JDNEWB5F.js +10 -0
  13. package/dist/{chunk-L7D6KNHV.js → chunk-JKBGDFX2.js} +890 -749
  14. package/dist/{chunk-YRKQNPK2.js → chunk-JPGX3533.js} +4 -3
  15. package/dist/chunk-KEFWANZY.js +155 -0
  16. package/dist/chunk-LH4GPYDX.js +448 -0
  17. package/dist/{chunk-JXSBOG2R.js → chunk-LWKZ3BCC.js} +5 -4
  18. package/dist/chunk-MYEOTM7D.js +92 -0
  19. package/dist/chunk-OGXKOMUT.js +412 -0
  20. package/dist/chunk-OHXU5WWK.js +3731 -0
  21. package/dist/chunk-ONFKASZI.js +2004 -0
  22. package/dist/{chunk-U36X6NZM.js → chunk-RIFTUOPE.js} +2 -14
  23. package/dist/{chunk-T6INEVX6.js → chunk-SGS4CQ2B.js} +1 -1
  24. package/dist/{chunk-C7IBFI5B.js → chunk-UPMX5GJI.js} +5 -5
  25. package/dist/{chunk-ARJPZ66V.js → chunk-UY5I2KOZ.js} +208 -3124
  26. package/dist/chunk-W2ZTLH7Y.js +662 -0
  27. package/dist/{chunk-KNISO652.js → chunk-WUVR4QY6.js} +9 -9
  28. package/dist/{chunk-Q5BEODAT.js → chunk-X2SUMO3P.js} +2 -1
  29. package/dist/{chunk-SNHGSCKH.js → chunk-XBMCDGHA.js} +1 -1
  30. package/dist/{chunk-N55DVMAG.js → chunk-XQQEKWTL.js} +2 -6
  31. package/dist/{chunk-SBQ4MYQV.js → chunk-XZSEPJZQ.js} +5 -6
  32. package/dist/{chunk-CPAJXBTL.js → chunk-YHBPR67D.js} +490 -676
  33. package/dist/{chunk-QARSVM7Q.js → chunk-YO2YORW4.js} +4 -4
  34. package/dist/{chunk-TAIX4NO3.js → chunk-ZFLM2YVW.js} +2 -2
  35. package/dist/components/index.css +15 -5
  36. package/dist/components/index.d.ts +202 -383
  37. package/dist/components/index.js +43 -429
  38. package/dist/components/navigation/index.css +25 -15
  39. package/dist/execution/index.d.ts +0 -73
  40. package/dist/features/auth/index.css +25 -15
  41. package/dist/features/crm/index.css +25 -15
  42. package/dist/features/crm/index.d.ts +49 -49
  43. package/dist/features/crm/index.js +14 -15
  44. package/dist/features/dashboard/index.css +25 -15
  45. package/dist/features/dashboard/index.js +18 -16
  46. package/dist/features/delivery/index.css +15 -5
  47. package/dist/features/delivery/index.js +14 -15
  48. package/dist/features/knowledge/index.css +611 -0
  49. package/dist/features/knowledge/index.js +375 -72
  50. package/dist/features/lead-gen/index.css +25 -15
  51. package/dist/features/lead-gen/index.d.ts +60 -21
  52. package/dist/features/lead-gen/index.js +16 -16
  53. package/dist/features/monitoring/index.css +15 -5
  54. package/dist/features/monitoring/index.js +17 -17
  55. package/dist/features/monitoring/requests/index.css +25 -15
  56. package/dist/features/monitoring/requests/index.js +13 -14
  57. package/dist/features/operations/index.css +25 -15
  58. package/dist/features/operations/index.d.ts +16 -98
  59. package/dist/features/operations/index.js +26 -22
  60. package/dist/features/settings/index.css +25 -15
  61. package/dist/features/settings/index.d.ts +1 -0
  62. package/dist/features/settings/index.js +15 -16
  63. package/dist/hooks/delivery/index.css +25 -15
  64. package/dist/hooks/delivery/index.js +2 -2
  65. package/dist/hooks/index.css +15 -5
  66. package/dist/hooks/index.d.ts +172 -380
  67. package/dist/hooks/index.js +13 -14
  68. package/dist/hooks/published.css +15 -5
  69. package/dist/hooks/published.d.ts +172 -380
  70. package/dist/hooks/published.js +13 -14
  71. package/dist/index.css +15 -5
  72. package/dist/index.d.ts +988 -403
  73. package/dist/index.js +15 -15
  74. package/dist/initialization/index.d.ts +1 -0
  75. package/dist/knowledge/index.d.ts +981 -41
  76. package/dist/knowledge/index.js +5449 -294
  77. package/dist/layout/index.d.ts +2 -0
  78. package/dist/layout/index.js +3 -2
  79. package/dist/organization/index.css +25 -15
  80. package/dist/organization/index.d.ts +1 -0
  81. package/dist/provider/index.css +25 -15
  82. package/dist/provider/index.d.ts +818 -26
  83. package/dist/provider/index.js +11 -11
  84. package/dist/provider/published.css +25 -15
  85. package/dist/provider/published.d.ts +817 -25
  86. package/dist/provider/published.js +8 -9
  87. package/dist/test-utils/index.js +2 -2
  88. package/dist/test-utils/setup.js +1 -1
  89. package/dist/theme/index.js +3 -2
  90. package/dist/theme/presets/index.d.ts +97 -0
  91. package/dist/theme/presets/index.js +3 -0
  92. package/dist/types/index.d.ts +71 -126
  93. package/dist/utils/index.js +1 -1
  94. package/dist/vite/index.d.ts +7 -0
  95. package/dist/vite/index.js +10 -0
  96. package/dist/vite-plugin-knowledge/index.d.ts +1 -33
  97. package/dist/vite-plugin-knowledge/index.js +1 -66
  98. package/package.json +16 -3
  99. package/src/knowledge/README.md +8 -8
  100. package/src/theme/presets/README.md +19 -0
  101. package/dist/chunk-5RLYII6P.js +0 -314
  102. package/dist/chunk-6U7AIIHF.js +0 -880
  103. package/dist/chunk-HAEJ4M54.js +0 -94
  104. package/dist/chunk-LPM7O6XM.js +0 -293
  105. /package/dist/{chunk-SGXXJE52.js → chunk-QD4X4H5A.js} +0 -0
@@ -1,66 +1,58 @@
1
- import { KnowledgeTree } from '../../chunk-HAEJ4M54.js';
2
- import { buildOrganizationGraph, OrganizationModelSchema, DEFAULT_ORGANIZATION_MODEL_OPERATIONS, DEFAULT_ORGANIZATION_MODEL_STATUSES, DEFAULT_ORGANIZATION_MODEL_GOALS, DEFAULT_ORGANIZATION_MODEL_ROLES, DEFAULT_ORGANIZATION_MODEL_OFFERINGS, DEFAULT_ORGANIZATION_MODEL_CUSTOMERS, DEFAULT_ORGANIZATION_MODEL_IDENTITY, DEFAULT_ORGANIZATION_MODEL_PROJECTS, DEFAULT_ORGANIZATION_MODEL_BRANDING } from '../../chunk-6U7AIIHF.js';
1
+ import { KnowledgeSearchBar, KnowledgeTree, getKnowledgeIconToken, byKind } from '../../chunk-ONFKASZI.js';
2
+ import { CommandViewSidebarContent, OrganizationModelSchema, buildOrganizationGraph, DEFAULT_ORGANIZATION_MODEL_OPERATIONS, DEFAULT_ORGANIZATION_MODEL_STATUSES, DEFAULT_ORGANIZATION_MODEL_GOALS, DEFAULT_ORGANIZATION_MODEL_ROLES, DEFAULT_ORGANIZATION_MODEL_OFFERINGS, DEFAULT_ORGANIZATION_MODEL_CUSTOMERS, DEFAULT_ORGANIZATION_MODEL_IDENTITY, DEFAULT_ORGANIZATION_MODEL_PROJECTS, DEFAULT_ORGANIZATION_MODEL_BRANDING } from '../../chunk-OHXU5WWK.js';
3
+ import '../../chunk-ZTWA5H77.js';
4
+ import { SemanticIcon } from '../../chunk-KEFWANZY.js';
5
+ import '../../chunk-XQQEKWTL.js';
3
6
  import { KNOWLEDGE_FEATURE_ID } from '../../chunk-ECNNI3NT.js';
4
- import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from '../../chunk-BDKM56TP.js';
7
+ import { DEFAULT_ORGANIZATION_MODEL_PROSPECTING } from '../../chunk-4KTLOK7K.js';
8
+ import '../../chunk-CW3UNAF2.js';
5
9
  import { SubshellSidebarSection } from '../../chunk-IIMU5YAJ.js';
6
- import { DEFAULT_ORGANIZATION_MODEL_SALES } from '../../chunk-5RLYII6P.js';
10
+ import '../../chunk-7M2VOCYN.js';
11
+ import '../../chunk-YHBPR67D.js';
12
+ import '../../chunk-VKMNWHTL.js';
13
+ import '../../chunk-G26INIF3.js';
14
+ import '../../chunk-BRXELOHC.js';
15
+ import '../../chunk-3ZMAGTWF.js';
16
+ import '../../chunk-VMJVQAFZ.js';
17
+ import '../../chunk-JPGX3533.js';
18
+ import '../../chunk-LH4GPYDX.js';
19
+ import '../../chunk-HLFFKKT3.js';
20
+ import '../../chunk-WLOQ4IBG.js';
21
+ import '../../chunk-ZFLM2YVW.js';
22
+ import '../../chunk-RIFTUOPE.js';
23
+ import '../../chunk-3KMDHCAR.js';
24
+ import { DEFAULT_ORGANIZATION_MODEL_SALES } from '../../chunk-W2ZTLH7Y.js';
25
+ import '../../chunk-SZHARWKU.js';
26
+ import { useElevasisFeatures } from '../../chunk-V3HUIZJX.js';
27
+ import '../../chunk-TKAYX2SP.js';
28
+ import '../../chunk-NYBEU5TE.js';
29
+ import '../../chunk-SGS4CQ2B.js';
7
30
  import '../../chunk-2IFYDILW.js';
8
31
  import { useRouterContext } from '../../chunk-Q7DJKLEN.js';
32
+ import '../../chunk-GESXCQWY.js';
33
+ import '../../chunk-HOIT677G.js';
34
+ import '../../chunk-E565XMTQ.js';
35
+ import '../../chunk-KU7ZDWQ7.js';
9
36
  import '../../chunk-DT3QYZVU.js';
37
+ import '../../chunk-RNP5R5I3.js';
38
+ import '../../chunk-QD4X4H5A.js';
39
+ import '../../chunk-KRWALB24.js';
40
+ import '../../chunk-WFTNY755.js';
41
+ import '../../chunk-WKJ47GIW.js';
42
+ import '../../chunk-DD3CCMCZ.js';
43
+ import '../../chunk-XTVZFT7U.js';
44
+ import '../../chunk-5WWZXCS5.js';
45
+ import '../../chunk-BRJ3QZ4E.js';
10
46
  import '../../chunk-I2KLQ2HA.js';
11
- import { IconBrain } from '@tabler/icons-react';
12
- import { Stack } from '@mantine/core';
13
- import { useMemo } from 'react';
47
+ import { IconBrain, IconCheck, IconCopy } from '@tabler/icons-react';
48
+ import { Stack, Box, SegmentedControl, Text, UnstyledButton, Group, Badge } from '@mantine/core';
49
+ import { useClipboard } from '@mantine/hooks';
50
+ import { useMemo, useState } from 'react';
14
51
  import { jsx, jsxs } from 'react/jsx-runtime';
15
52
 
16
53
  // ../core/src/organization-model/defaults.ts
17
54
  var DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE = {
18
- nodes: [
19
- // --- playbook: outreach sequence SOP ---
20
- {
21
- id: "knowledge.outreach-playbook",
22
- kind: "playbook",
23
- title: "Outreach Sequence Playbook",
24
- summary: "Step-by-step runbook for launching a cold outreach campaign: prospect sourcing, copy review, sending schedule, and reply handling.",
25
- body: "## Overview\n\nThis playbook covers the end-to-end process for launching a cold outreach campaign using the Elevasis lead-gen pipeline.\n\n## Steps\n\n1. Source prospects via the Lead Gen feature.\n2. Review and approve copy in the CRM campaign editor.\n3. Schedule sends using the Task Scheduler.\n4. Monitor replies in the CRM inbox and route to the appropriate deal stage.",
26
- links: [{ nodeId: "feature:sales.lead-gen" }, { nodeId: "feature:sales.crm" }],
27
- ownerIds: [],
28
- updatedAt: "2026-05-01"
29
- },
30
- // --- strategy: lead-gen targeting strategy ---
31
- {
32
- id: "knowledge.lead-gen-strategy",
33
- kind: "strategy",
34
- title: "Lead Gen Targeting Strategy",
35
- summary: "Defines ICP signal prioritization, firmographic filters, and scoring thresholds used by the lead-gen pipeline.",
36
- body: "## Strategy\n\nThe lead-gen pipeline targets SMBs with 10-200 employees in recession-resistant verticals (manufacturing, logistics, professional services). Firmographic filters: revenue \\>$1M, HQ in US/CA/AU, tech stack includes at least one SaaS CRM.\n\n## Scoring Thresholds\n\n- High priority: ICP score \\>= 80\n- Medium priority: ICP score 60-79\n- Low priority: \\< 60 (excluded from active outreach)",
37
- links: [{ nodeId: "feature:sales.lead-gen" }],
38
- ownerIds: [],
39
- updatedAt: "2026-05-01"
40
- },
41
- // --- reference: organization model schema reference ---
42
- {
43
- id: "knowledge.org-model-reference",
44
- kind: "reference",
45
- title: "Organization Model Schema Reference",
46
- summary: "Technical reference for the OrganizationModel Zod schema: all domains, field contracts, and versioning rules.",
47
- body: "## Schema\n\nThe `OrganizationModel` schema is defined in `packages/core/src/organization-model/schema.ts`. It is versioned at `version: 1` and composed from domain sub-schemas.\n\n## Domains\n\n- `features` \u2014 flat array of FeatureSchema nodes (nav tree)\n- `knowledge` \u2014 flat array of KnowledgeNodeSchema nodes\n- `sales`, `prospecting`, `projects` \u2014 sales and GTM domains\n- `operations`, `statuses` \u2014 runtime entity domains\n- `customers`, `offerings`, `roles`, `goals` \u2014 business context domains",
48
- links: [{ nodeId: "feature:knowledge.command-view" }],
49
- ownerIds: [],
50
- updatedAt: "2026-05-01"
51
- },
52
- // --- playbook: multi-feature governs (SEO + lead-gen) ---
53
- {
54
- id: "knowledge.seo-lead-gen-playbook",
55
- kind: "playbook",
56
- title: "SEO-to-Lead-Gen Handoff Playbook",
57
- summary: "Runbook for promoting SEO-qualified prospects into the active lead-gen pipeline: signal capture, scoring override, and campaign assignment.",
58
- body: "## Overview\n\nThis playbook governs the handoff from SEO-sourced traffic to the lead-gen pipeline.\n\n## Steps\n\n1. SEO feature captures visitor signal (form fill or intent data).\n2. Score the lead using the standard ICP scoring thresholds.\n3. If score >= 60, inject into the lead-gen prospect list.\n4. Assign to the appropriate outreach campaign in the CRM.",
59
- links: [{ nodeId: "feature:seo" }, { nodeId: "feature:sales.lead-gen" }, { nodeId: "feature:sales.crm" }],
60
- ownerIds: [],
61
- updatedAt: "2026-05-01"
62
- }
63
- ]
55
+ nodes: []
64
56
  };
65
57
  var DEFAULT_ORGANIZATION_MODEL = {
66
58
  version: 1,
@@ -70,16 +62,39 @@ var DEFAULT_ORGANIZATION_MODEL = {
70
62
  label: "Dashboard",
71
63
  enabled: true,
72
64
  path: "/",
73
- icon: "dashboard",
65
+ icon: "feature.dashboard",
74
66
  uiPosition: "sidebar-primary"
75
67
  },
68
+ {
69
+ id: "identity",
70
+ label: "Identity",
71
+ description: "Company identity, positioning, and market context",
72
+ enabled: true,
73
+ color: "indigo"
74
+ },
75
+ {
76
+ id: "platform",
77
+ label: "Platform",
78
+ description: "Elevasis platform architecture, capabilities, and implementation patterns",
79
+ enabled: true,
80
+ color: "cyan",
81
+ icon: "feature.platform"
82
+ },
83
+ {
84
+ id: "finance",
85
+ label: "Finance",
86
+ description: "Finance operations, accounting, billing, reconciliation, and tax prep",
87
+ enabled: true,
88
+ color: "green",
89
+ icon: "feature.finance"
90
+ },
76
91
  {
77
92
  id: "sales",
78
93
  label: "Sales",
79
94
  description: "Revenue workflows and customer acquisition",
80
95
  enabled: true,
81
96
  color: "blue",
82
- icon: "crm",
97
+ icon: "feature.sales",
83
98
  uiPosition: "sidebar-primary"
84
99
  },
85
100
  {
@@ -88,7 +103,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
88
103
  description: "Relationship pipeline and deal management",
89
104
  enabled: true,
90
105
  color: "blue",
91
- icon: "crm",
106
+ icon: "feature.crm",
92
107
  path: "/crm"
93
108
  },
94
109
  {
@@ -97,7 +112,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
97
112
  description: "Prospecting, qualification, and outreach preparation",
98
113
  enabled: true,
99
114
  color: "cyan",
100
- icon: "lead-gen",
115
+ icon: "feature.lead-gen",
101
116
  path: "/lead-gen"
102
117
  },
103
118
  {
@@ -106,7 +121,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
106
121
  description: "Projects, milestones, and client work execution",
107
122
  enabled: true,
108
123
  color: "orange",
109
- icon: "projects",
124
+ icon: "feature.projects",
110
125
  path: "/projects",
111
126
  uiPosition: "sidebar-primary"
112
127
  },
@@ -116,7 +131,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
116
131
  description: "Operational resources, topology, and orchestration visibility",
117
132
  enabled: true,
118
133
  color: "violet",
119
- icon: "operations",
134
+ icon: "feature.operations",
120
135
  uiPosition: "sidebar-primary"
121
136
  },
122
137
  {
@@ -202,7 +217,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
202
217
  id: "settings",
203
218
  label: "Settings",
204
219
  enabled: true,
205
- icon: "settings",
220
+ icon: "feature.settings",
206
221
  uiPosition: "sidebar-bottom"
207
222
  },
208
223
  {
@@ -258,7 +273,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
258
273
  label: "Admin",
259
274
  enabled: true,
260
275
  path: "/admin",
261
- icon: "settings",
276
+ icon: "feature.admin",
262
277
  uiPosition: "sidebar-bottom",
263
278
  requiresAdmin: true
264
279
  },
@@ -297,7 +312,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
297
312
  label: "Archive",
298
313
  enabled: true,
299
314
  path: "/archive",
300
- icon: "archive",
315
+ icon: "feature.archive",
301
316
  uiPosition: "sidebar-bottom",
302
317
  devOnly: true
303
318
  },
@@ -325,7 +340,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
325
340
  description: "Operational knowledge, playbooks, and strategy docs",
326
341
  enabled: true,
327
342
  color: "teal",
328
- icon: "knowledge",
343
+ icon: "feature.knowledge",
329
344
  uiPosition: "sidebar-primary"
330
345
  },
331
346
  {
@@ -365,31 +380,319 @@ function resolveOrganizationModel(override, organizationId) {
365
380
  }
366
381
  return model;
367
382
  }
368
- var ORG_MODEL = resolveOrganizationModel();
369
- var KNOWLEDGE_GRAPH = buildOrganizationGraph({ organizationModel: ORG_MODEL });
383
+ var SEGMENT_DATA = [
384
+ { label: "By Feature", value: "by-feature" },
385
+ { label: "By Kind", value: "by-kind" },
386
+ { label: "Config", value: "config" }
387
+ ];
370
388
  var KnowledgeSidebarMiddle = () => {
371
389
  const { navigate, currentPath } = useRouterContext();
372
- const knowledgeNodes = useMemo(() => ORG_MODEL.knowledge.nodes, []);
390
+ const { timeRange = "30d", organizationModel } = useElevasisFeatures();
391
+ if (currentPath.startsWith("/knowledge/command-view")) {
392
+ return /* @__PURE__ */ jsx(CommandViewSidebarContent, { timeRange });
393
+ }
394
+ const orgModel = organizationModel ?? resolveOrganizationModel();
395
+ return /* @__PURE__ */ jsx(KnowledgeBaseSidebarBody, { navigate, currentPath, organizationModel: orgModel });
396
+ };
397
+ function KnowledgeBaseSidebarBody({ navigate, currentPath, organizationModel }) {
398
+ const knowledgeNodes = useMemo(() => organizationModel.knowledge.nodes, [organizationModel]);
399
+ const graph = useMemo(() => buildOrganizationGraph({ organizationModel }), [organizationModel]);
400
+ const [searchResults, setSearchResults] = useState(null);
401
+ const [axis, setAxis] = useState("by-feature");
373
402
  const selectedNodeId = useMemo(() => {
374
403
  const match = currentPath.match(/^\/knowledge\/([^/]+)/);
375
404
  if (!match) return void 0;
376
405
  const segment = match[1];
377
- if (["by-feature", "by-kind", "by-owner", "graph", "command-view"].includes(segment)) return void 0;
406
+ if (["by-feature", "by-kind", "config", "graph", "command-view"].includes(segment)) return void 0;
378
407
  return segment;
379
408
  }, [currentPath]);
409
+ const handleSelect = (node) => {
410
+ navigate(`/knowledge/${node.id}`);
411
+ };
412
+ const handleSelectGraphNode = (node) => {
413
+ navigate(`/knowledge/${node.id}`);
414
+ };
380
415
  return /* @__PURE__ */ jsxs(Stack, { gap: 0, style: { flex: 1, overflow: "hidden", display: "flex", flexDirection: "column" }, children: [
381
416
  /* @__PURE__ */ jsx(SubshellSidebarSection, { icon: IconBrain, label: "Knowledge", withTopBorder: false }),
382
- /* @__PURE__ */ jsx(Stack, { gap: 0, style: { flex: 1, overflowY: "auto" }, children: /* @__PURE__ */ jsx(
383
- KnowledgeTree,
417
+ /* @__PURE__ */ jsx(Box, { px: "sm", pt: "sm", pb: 0, children: /* @__PURE__ */ jsx(
418
+ SegmentedControl,
384
419
  {
385
- graph: KNOWLEDGE_GRAPH,
420
+ "data-testid": "knowledge-axis-control",
421
+ fullWidth: true,
422
+ size: "xs",
423
+ value: axis,
424
+ onChange: (v) => setAxis(v),
425
+ data: SEGMENT_DATA
426
+ }
427
+ ) }),
428
+ /* @__PURE__ */ jsx(Box, { p: "sm", pb: 0, children: /* @__PURE__ */ jsx(KnowledgeSearchBar, { knowledgeNodes, onResults: setSearchResults }) }),
429
+ /* @__PURE__ */ jsx(Stack, { gap: 0, style: { flex: 1, overflowY: "auto" }, children: searchResults ? /* @__PURE__ */ jsx(SearchResultsList, { searchResults, selectedNodeId, onSelect: handleSelect }) : /* @__PURE__ */ jsx(
430
+ AxisBody,
431
+ {
432
+ axis,
433
+ graph,
386
434
  knowledgeNodes,
387
- onSelectNode: (node) => navigate(`/knowledge/${node.id}`),
388
- selectedNodeId
435
+ selectedNodeId,
436
+ onSelect: handleSelect,
437
+ onSelectGraphNode: handleSelectGraphNode
389
438
  }
390
439
  ) })
391
440
  ] });
441
+ }
442
+ function SearchResultsList({ searchResults, selectedNodeId, onSelect }) {
443
+ if (searchResults.length === 0) {
444
+ return /* @__PURE__ */ jsx(Box, { p: "md", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No results." }) });
445
+ }
446
+ return /* @__PURE__ */ jsx(Stack, { gap: 2, p: "sm", children: searchResults.map((node) => {
447
+ const isActive = node.id === selectedNodeId;
448
+ return /* @__PURE__ */ jsx(NodeButton, { node, isActive, onSelect }, node.id);
449
+ }) });
450
+ }
451
+ function AxisBody({ axis, graph, knowledgeNodes, selectedNodeId, onSelect, onSelectGraphNode }) {
452
+ switch (axis) {
453
+ case "by-feature":
454
+ return /* @__PURE__ */ jsx(
455
+ KnowledgeTree,
456
+ {
457
+ graph,
458
+ knowledgeNodes,
459
+ onSelectNode: onSelect,
460
+ selectedNodeId
461
+ }
462
+ );
463
+ case "by-kind":
464
+ return /* @__PURE__ */ jsx(ByKindBody, { graph, knowledgeNodes, selectedNodeId, onSelect });
465
+ case "config":
466
+ return /* @__PURE__ */ jsx(ConfigBody, { graph, selectedNodeId, onSelect: onSelectGraphNode });
467
+ }
468
+ }
469
+ var KIND_ORDER = ["playbook", "strategy", "reference"];
470
+ var KIND_LABELS = {
471
+ playbook: "Playbook",
472
+ strategy: "Strategy",
473
+ reference: "Reference"
474
+ };
475
+ function ByKindBody({ graph, knowledgeNodes, selectedNodeId, onSelect }) {
476
+ const groups = useMemo(() => {
477
+ return KIND_ORDER.map((kind) => ({
478
+ kind,
479
+ nodes: byKind(graph, kind, knowledgeNodes)
480
+ })).filter((g) => g.nodes.length > 0);
481
+ }, [graph, knowledgeNodes]);
482
+ if (groups.length === 0) {
483
+ return /* @__PURE__ */ jsx(Box, { p: "md", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No knowledge nodes." }) });
484
+ }
485
+ return /* @__PURE__ */ jsx(Stack, { gap: "md", style: { padding: "var(--mantine-spacing-sm)" }, children: groups.map(({ kind, nodes }) => /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
486
+ /* @__PURE__ */ jsx(
487
+ GroupHeader,
488
+ {
489
+ label: KIND_LABELS[kind],
490
+ count: nodes.length,
491
+ command: getKnowledgeReadKindFolderCommand(kind)
492
+ }
493
+ ),
494
+ /* @__PURE__ */ jsx(Stack, { gap: 2, children: nodes.map((node) => /* @__PURE__ */ jsx(NodeButton, { node, isActive: node.id === selectedNodeId, onSelect }, node.id)) })
495
+ ] }, kind)) });
496
+ }
497
+ var CONFIG_KIND_ORDER = ["feature", "resource", "organization", "entity", "surface", "capability"];
498
+ var CONFIG_KIND_LABELS = {
499
+ feature: "Features",
500
+ resource: "Resources",
501
+ organization: "Organizations",
502
+ entity: "Entities",
503
+ surface: "Surfaces",
504
+ capability: "Capabilities"
392
505
  };
506
+ function isSelectedConfigNode(selectedNodeId, node) {
507
+ if (!selectedNodeId) return false;
508
+ return selectedNodeId === node.id || selectedNodeId === node.sourceId || selectedNodeId === node.id.split(":")[1];
509
+ }
510
+ function ConfigBody({ graph, selectedNodeId, onSelect }) {
511
+ const groups = useMemo(() => {
512
+ const grouped = /* @__PURE__ */ new Map();
513
+ for (const node of graph.nodes) {
514
+ if (node.kind === "knowledge") continue;
515
+ const nodes = grouped.get(node.kind) ?? [];
516
+ nodes.push(node);
517
+ grouped.set(node.kind, nodes);
518
+ }
519
+ const knownGroups = CONFIG_KIND_ORDER.map((kind) => ({
520
+ kind,
521
+ label: CONFIG_KIND_LABELS[kind],
522
+ nodes: grouped.get(kind)?.sort((a, b) => a.label.localeCompare(b.label)) ?? []
523
+ })).filter((group) => group.nodes.length > 0);
524
+ const unknownGroups = Array.from(grouped.entries()).filter(([kind]) => !CONFIG_KIND_ORDER.includes(kind)).map(([kind, nodes]) => ({
525
+ kind,
526
+ label: CONFIG_KIND_LABELS[kind] ?? kind,
527
+ nodes: nodes.sort((a, b) => a.label.localeCompare(b.label))
528
+ })).sort((a, b) => a.label.localeCompare(b.label));
529
+ return [...knownGroups, ...unknownGroups];
530
+ }, [graph]);
531
+ if (groups.length === 0) {
532
+ return /* @__PURE__ */ jsx(Box, { p: "md", children: /* @__PURE__ */ jsx(Text, { size: "sm", c: "dimmed", children: "No configuration nodes." }) });
533
+ }
534
+ return /* @__PURE__ */ jsx(Stack, { gap: "md", style: { padding: "var(--mantine-spacing-sm)" }, children: groups.map(({ kind, label, nodes }) => /* @__PURE__ */ jsxs(Stack, { gap: 4, children: [
535
+ /* @__PURE__ */ jsx(GroupHeader, { label, count: nodes.length }),
536
+ /* @__PURE__ */ jsx(Stack, { gap: 2, children: nodes.map((node) => /* @__PURE__ */ jsx(
537
+ ConfigNodeButton,
538
+ {
539
+ node,
540
+ isActive: isSelectedConfigNode(selectedNodeId, node),
541
+ onSelect
542
+ },
543
+ node.id
544
+ )) })
545
+ ] }, kind)) });
546
+ }
547
+ function GroupHeader({ label, count, command }) {
548
+ const [hovered, setHovered] = useState(false);
549
+ return /* @__PURE__ */ jsxs(Group, { gap: "xs", onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [
550
+ /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, tt: "uppercase", c: "dimmed", style: { letterSpacing: "0.05em" }, children: label }),
551
+ /* @__PURE__ */ jsx(TrailingCopySlot, { count, command, label: "Copy group knowledge commands", showCopy: hovered })
552
+ ] });
553
+ }
554
+ function NodeButton({ node, isActive, onSelect }) {
555
+ const [hovered, setHovered] = useState(false);
556
+ return /* @__PURE__ */ jsx(
557
+ UnstyledButton,
558
+ {
559
+ onClick: () => onSelect(node),
560
+ onMouseEnter: () => setHovered(true),
561
+ onMouseLeave: () => setHovered(false),
562
+ style: {
563
+ padding: "6px 10px",
564
+ borderRadius: "var(--mantine-radius-sm)",
565
+ backgroundColor: isActive ? "color-mix(in srgb, var(--color-primary) 10%, transparent)" : hovered ? "var(--color-surface-hover)" : "transparent",
566
+ width: "100%",
567
+ textAlign: "left",
568
+ transition: "background-color var(--duration-fast) var(--easing), color var(--duration-fast) var(--easing)"
569
+ },
570
+ children: /* @__PURE__ */ jsx(
571
+ Text,
572
+ {
573
+ size: "sm",
574
+ c: isActive ? "var(--color-primary)" : hovered ? "var(--color-text)" : void 0,
575
+ fw: isActive ? 600 : 400,
576
+ children: /* @__PURE__ */ jsxs(Group, { component: "span", gap: "xs", wrap: "nowrap", children: [
577
+ /* @__PURE__ */ jsx(
578
+ SemanticIcon,
579
+ {
580
+ token: getKnowledgeIconToken(node),
581
+ fallbackKind: node.kind,
582
+ size: 15,
583
+ style: {
584
+ color: isActive ? "var(--color-primary)" : hovered ? "var(--color-text)" : "var(--color-text-subtle)"
585
+ }
586
+ }
587
+ ),
588
+ /* @__PURE__ */ jsx("span", { style: { minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: node.title }),
589
+ /* @__PURE__ */ jsx(
590
+ CopyCommandControl,
591
+ {
592
+ command: getKnowledgeReadCommand(node.id),
593
+ label: "Copy knowledge command",
594
+ visible: hovered
595
+ }
596
+ )
597
+ ] })
598
+ }
599
+ )
600
+ }
601
+ );
602
+ }
603
+ function ConfigNodeButton({ node, isActive, onSelect }) {
604
+ return /* @__PURE__ */ jsx(
605
+ UnstyledButton,
606
+ {
607
+ onClick: () => onSelect(node),
608
+ style: {
609
+ padding: "6px 10px",
610
+ borderRadius: "var(--mantine-radius-sm)",
611
+ backgroundColor: isActive ? "color-mix(in srgb, var(--color-primary) 10%, transparent)" : "transparent",
612
+ width: "100%",
613
+ textAlign: "left"
614
+ },
615
+ children: /* @__PURE__ */ jsxs(Group, { gap: "xs", wrap: "nowrap", children: [
616
+ /* @__PURE__ */ jsx(
617
+ SemanticIcon,
618
+ {
619
+ token: node.icon,
620
+ fallbackKind: node.kind === "feature" ? "feature" : node.kind === "knowledge" ? "knowledge" : "unknown",
621
+ size: 15,
622
+ style: { color: isActive ? "var(--color-primary)" : "var(--color-text-subtle)" }
623
+ }
624
+ ),
625
+ /* @__PURE__ */ jsx(
626
+ Text,
627
+ {
628
+ size: "sm",
629
+ c: isActive ? "var(--color-primary)" : void 0,
630
+ fw: isActive ? 600 : 400,
631
+ style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
632
+ children: node.label
633
+ }
634
+ )
635
+ ] })
636
+ }
637
+ );
638
+ }
639
+ function getKnowledgeReadCommand(nodeId) {
640
+ return `/knowledge read ${nodeId}`;
641
+ }
642
+ function getKnowledgeReadKindFolderCommand(kind) {
643
+ return `/knowledge read-folder kind:${kind}`;
644
+ }
645
+ function CopyCommandControl({ command, label, visible }) {
646
+ const clipboard = useClipboard({ timeout: 1500 });
647
+ return /* @__PURE__ */ jsx(
648
+ "span",
649
+ {
650
+ role: "button",
651
+ tabIndex: 0,
652
+ "aria-label": label,
653
+ onClick: (event) => {
654
+ event.preventDefault();
655
+ event.stopPropagation();
656
+ clipboard.copy(command);
657
+ },
658
+ onKeyDown: (event) => {
659
+ if (event.key !== "Enter" && event.key !== " ") return;
660
+ event.preventDefault();
661
+ event.stopPropagation();
662
+ clipboard.copy(command);
663
+ },
664
+ style: {
665
+ display: "inline-flex",
666
+ alignItems: "center",
667
+ justifyContent: "center",
668
+ width: 22,
669
+ height: 22,
670
+ flexShrink: 0,
671
+ opacity: visible ? 1 : 0,
672
+ pointerEvents: visible ? "auto" : "none",
673
+ color: clipboard.copied ? "var(--color-primary)" : "var(--color-text-subtle)",
674
+ transition: "opacity 120ms ease, color 120ms ease"
675
+ },
676
+ children: clipboard.copied ? /* @__PURE__ */ jsx(IconCheck, { size: 14 }) : /* @__PURE__ */ jsx(IconCopy, { size: 14 })
677
+ }
678
+ );
679
+ }
680
+ function TrailingCopySlot({ count, command, label, showCopy }) {
681
+ return /* @__PURE__ */ jsx(
682
+ "span",
683
+ {
684
+ style: {
685
+ display: "inline-flex",
686
+ alignItems: "center",
687
+ justifyContent: "center",
688
+ width: 32,
689
+ height: 22,
690
+ flexShrink: 0
691
+ },
692
+ children: showCopy && command ? /* @__PURE__ */ jsx(CopyCommandControl, { command, label, visible: true }) : /* @__PURE__ */ jsx(Badge, { size: "xs", variant: "light", color: "gray", children: count })
693
+ }
694
+ );
695
+ }
393
696
  var KnowledgeSidebar = () => /* @__PURE__ */ jsx(Stack, { gap: 0, style: { height: "100%", display: "flex", flexDirection: "column" }, children: /* @__PURE__ */ jsx(KnowledgeSidebarMiddle, {}) });
394
697
 
395
698
  // src/features/knowledge/manifest.ts
@@ -138,14 +138,14 @@
138
138
  }
139
139
  .lead-gen-build-action-button:disabled,
140
140
  .lead-gen-build-action-button[data-disabled] {
141
- background-color: color-mix(in srgb, var(--mantine-color-gray-8) 48%, var(--color-surface) 52%) !important;
142
- border-color: color-mix(in srgb, var(--mantine-color-gray-8) 58%, var(--color-surface) 42%) !important;
141
+ background-color: var(--surface-primary-muted) !important;
142
+ border-color: var(--border-primary-subtle) !important;
143
143
  color: color-mix(in srgb, var(--color-text-subtle) 88%, var(--color-text-dimmed) 12%) !important;
144
144
  opacity: 0.78;
145
145
  }
146
146
  .lead-gen-build-action-button:disabled:hover,
147
147
  .lead-gen-build-action-button[data-disabled]:hover {
148
- background-color: color-mix(in srgb, var(--mantine-color-gray-8) 48%, var(--color-surface) 52%) !important;
148
+ background-color: var(--surface-primary-muted) !important;
149
149
  }
150
150
  .mantine-Accordion-control:hover {
151
151
  background-color: var(--color-surface-hover);
@@ -153,8 +153,18 @@
153
153
  .mantine-Menu-item:hover:not([data-disabled]) {
154
154
  background-color: var(--color-surface-hover);
155
155
  }
156
- .mantine-Select-option:hover {
157
- background-color: var(--color-surface-hover) !important;
156
+ .mantine-Select-option:hover,
157
+ .mantine-MultiSelect-option:hover,
158
+ .mantine-TagsInput-option:hover,
159
+ .mantine-Combobox-option:hover {
160
+ background-color: var(--surface-primary-muted) !important;
161
+ }
162
+ .mantine-Select-option[data-combobox-selected],
163
+ .mantine-MultiSelect-option[data-combobox-selected],
164
+ .mantine-TagsInput-option[data-combobox-selected],
165
+ .mantine-Combobox-option[data-combobox-selected] {
166
+ background-color: var(--surface-primary-subtle) !important;
167
+ color: var(--color-text);
158
168
  }
159
169
  [data-mantine-color-scheme=dark] .mantine-Tabs-root {
160
170
  --tab-border-color: var(--color-border);
@@ -216,6 +226,16 @@
216
226
  display: none;
217
227
  }
218
228
 
229
+ /* src/graph/Graph.globals.css */
230
+ .elevasis-graph-root .react-flow__node.selected,
231
+ .elevasis-graph-root .react-flow__node:focus,
232
+ .elevasis-graph-root .react-flow__node:focus-visible {
233
+ outline: none !important;
234
+ }
235
+ .elevasis-graph-root .react-flow__node.selected > * {
236
+ box-shadow: none;
237
+ }
238
+
219
239
  /* src/graph/Graph.module.css */
220
240
  @keyframes edgeFlow {
221
241
  0% {
@@ -589,13 +609,3 @@
589
609
  transform: none;
590
610
  }
591
611
  }
592
-
593
- /* src/graph/Graph.globals.css */
594
- .elevasis-graph-root .react-flow__node.selected,
595
- .elevasis-graph-root .react-flow__node:focus,
596
- .elevasis-graph-root .react-flow__node:focus-visible {
597
- outline: none !important;
598
- }
599
- .elevasis-graph-root .react-flow__node.selected > * {
600
- box-shadow: none;
601
- }