@eventcatalog/core 4.12.3 → 5.0.0-beta.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 (267) hide show
  1. package/LICENSE +226 -95
  2. package/NOTICE +30 -0
  3. package/README.md +3 -2
  4. package/dist/analytics/analytics.cjs +2 -1
  5. package/dist/analytics/analytics.js +2 -2
  6. package/dist/analytics/log-build.cjs +44 -16
  7. package/dist/analytics/log-build.d.cts +6 -5
  8. package/dist/analytics/log-build.d.ts +6 -5
  9. package/dist/analytics/log-build.js +4 -3
  10. package/dist/{chunk-U4YJSTGV.js → chunk-AYNZXUB5.js} +2 -10
  11. package/dist/{chunk-5BPN6QEC.js → chunk-K2ACDO7Y.js} +1 -1
  12. package/dist/{chunk-ZYTCBNB3.js → chunk-KYJZJLBD.js} +2 -1
  13. package/dist/{chunk-TV3YAWKQ.js → chunk-Q6SD5SNQ.js} +1 -1
  14. package/dist/{chunk-HPC6KUDQ.js → chunk-S2QGT7ZF.js} +1 -1
  15. package/dist/chunk-TQLRG35T.js +203 -0
  16. package/dist/{chunk-M577VUOX.js → chunk-UDS3SYLZ.js} +13 -16
  17. package/dist/constants.cjs +1 -1
  18. package/dist/constants.js +1 -1
  19. package/dist/eventcatalog.cjs +408 -291
  20. package/dist/eventcatalog.config.d.cts +2 -3
  21. package/dist/eventcatalog.config.d.ts +2 -3
  22. package/dist/eventcatalog.js +35 -98
  23. package/dist/federation/content-cache.d.cts +0 -5
  24. package/dist/federation/content-cache.d.ts +0 -5
  25. package/dist/federation/diagnostics.d.cts +0 -5
  26. package/dist/federation/diagnostics.d.ts +0 -5
  27. package/dist/federation/federate.cjs +0 -9
  28. package/dist/federation/federate.d.cts +0 -5
  29. package/dist/federation/federate.d.ts +0 -5
  30. package/dist/federation/federate.js +4 -5
  31. package/dist/federation/filesystem-source-provider.d.cts +0 -5
  32. package/dist/federation/filesystem-source-provider.d.ts +0 -5
  33. package/dist/federation/github-source-provider.d.cts +0 -5
  34. package/dist/federation/github-source-provider.d.ts +0 -5
  35. package/dist/federation/output-transaction.d.cts +0 -4
  36. package/dist/federation/output-transaction.d.ts +0 -4
  37. package/dist/federation/public-assets.d.cts +0 -5
  38. package/dist/federation/public-assets.d.ts +0 -5
  39. package/dist/federation/source-provider.d.cts +0 -5
  40. package/dist/federation/source-provider.d.ts +0 -5
  41. package/dist/federation/types.d.cts +0 -5
  42. package/dist/federation/types.d.ts +0 -5
  43. package/dist/generate.cjs +1 -1
  44. package/dist/generate.js +3 -3
  45. package/dist/license-C1y-56bb.d.cts +23 -0
  46. package/dist/license-C1y-56bb.d.ts +23 -0
  47. package/dist/runtime-dependencies/@eventcatalog__visualiser__layout.mjs +3 -0
  48. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps.mjs +3 -0
  49. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__react.mjs +3 -0
  50. package/dist/runtime-dependencies/@modelcontextprotocol__ext-apps__server.mjs +3 -0
  51. package/dist/runtime-dependencies/@modelcontextprotocol__sdk__types.js.mjs +3 -0
  52. package/dist/runtime-dependencies/manifest.json +12 -1
  53. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__graphql.mjs +3 -0
  54. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__json.mjs +3 -0
  55. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__markup.mjs +3 -0
  56. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__protobuf.mjs +3 -0
  57. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__languages__prism__yaml.mjs +3 -0
  58. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-dark.mjs +3 -0
  59. package/dist/runtime-dependencies/react-syntax-highlighter__dist__esm__styles__prism__one-light.mjs +3 -0
  60. package/dist/utils/cli-logger.cjs +1 -1
  61. package/dist/utils/cli-logger.js +2 -2
  62. package/dist/utils/license-status.cjs +240 -0
  63. package/dist/utils/license-status.d.cts +28 -0
  64. package/dist/utils/license-status.d.ts +28 -0
  65. package/dist/utils/license-status.js +12 -0
  66. package/eventcatalog/astro.config.mjs +1 -1
  67. package/eventcatalog/integrations/eventcatalog-runtime.mjs +1 -1
  68. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +29 -19
  69. package/eventcatalog/src/components/ChatPanel/OfflineReply.tsx +74 -0
  70. package/eventcatalog/src/components/FieldsExplorer/FieldFilters.tsx +24 -28
  71. package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +16 -11
  72. package/eventcatalog/src/components/FieldsExplorer/FieldsExplorer.tsx +4 -218
  73. package/eventcatalog/src/components/FieldsExplorer/FieldsTable.tsx +27 -36
  74. package/eventcatalog/src/components/Header.astro +43 -58
  75. package/eventcatalog/src/components/Lists/PillListFlat.styles.css +17 -17
  76. package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +1 -1
  77. package/eventcatalog/src/components/MDX/Flow/Flow.astro +4 -0
  78. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -0
  79. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +49 -18
  80. package/eventcatalog/src/components/MDX/RemoteFile.astro +2 -24
  81. package/eventcatalog/src/components/SchemaExplorer/ApiAccessSection.tsx +59 -93
  82. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +1 -32
  83. package/eventcatalog/src/components/SchemaExplorer/DiffViewer.tsx +20 -67
  84. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -11
  85. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +11 -60
  86. package/eventcatalog/src/components/SchemaExplorer/SchemaExplorer.tsx +1 -3
  87. package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +0 -3
  88. package/eventcatalog/src/components/SchemaExplorer/VersionHistoryModal.tsx +2 -9
  89. package/eventcatalog/src/components/SchemaExplorer/parse-schema.ts +46 -0
  90. package/eventcatalog/src/components/SchemaExplorer/utils.ts +11 -0
  91. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +2 -9
  92. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +288 -0
  93. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +3 -19
  94. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +85 -30
  95. package/eventcatalog/src/components/Settings/SettingsShared.tsx +7 -75
  96. package/eventcatalog/src/components/SideNav/CustomDocsNav.astro +2 -2
  97. package/eventcatalog/src/components/TrialBadge.astro +82 -0
  98. package/eventcatalog/src/content.config.ts +9 -96
  99. package/eventcatalog/src/{enterprise → features}/ai/chat-api.ts +22 -34
  100. package/eventcatalog/src/{enterprise → features}/analytics/adapters/ga4.ts +0 -5
  101. package/eventcatalog/src/{enterprise → features}/analytics/adapters/gtm.ts +0 -5
  102. package/eventcatalog/src/{enterprise → features}/analytics/adapters/posthog.ts +0 -5
  103. package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsHead.astro +2 -4
  104. package/eventcatalog/src/{enterprise → features}/analytics/components/AnalyticsTracker.astro +2 -4
  105. package/eventcatalog/src/{enterprise → features}/analytics/tracker.ts +0 -5
  106. package/eventcatalog/src/{enterprise → features}/api/catalog.ts +0 -5
  107. package/eventcatalog/src/{enterprise → features}/auth/[...auth].ts +0 -5
  108. package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware-auth.ts +0 -5
  109. package/eventcatalog/src/{enterprise → features}/auth/middleware/middleware.ts +0 -5
  110. package/eventcatalog/src/{enterprise → features}/collections/custom-pages.ts +0 -5
  111. package/eventcatalog/src/{enterprise → features}/collections/index.ts +0 -5
  112. package/eventcatalog/src/{enterprise → features}/collections/resource-docs.ts +0 -5
  113. package/eventcatalog/src/{enterprise → features}/custom-documentation/collection.ts +0 -5
  114. package/eventcatalog/src/features/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +9 -0
  115. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/CustomDocsNavWrapper.tsx +0 -5
  116. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NestedItem.tsx +1 -6
  117. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/components/NoResultsFound.tsx +0 -5
  118. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/index.tsx +1 -6
  119. package/eventcatalog/src/{enterprise → features}/custom-documentation/components/CustomDocsNav/types.ts +0 -5
  120. package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/index.astro → features/custom-documentation/components/CustomDocumentationPage.astro} +5 -5
  121. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/badge-styles.ts +0 -5
  122. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/custom-docs.ts +1 -6
  123. package/eventcatalog/src/{enterprise → features}/custom-documentation/utils/docs-search.ts +0 -5
  124. package/eventcatalog/src/{enterprise → features}/custom-pages/routes.ts +0 -5
  125. package/eventcatalog/src/{enterprise → features}/directory/user-team-directory.ts +0 -5
  126. package/eventcatalog/src/{enterprise → features}/fields/field-extractor.ts +0 -5
  127. package/eventcatalog/src/{enterprise → features}/fields/field-indexer.ts +0 -5
  128. package/eventcatalog/src/{enterprise → features}/fields/fields-db.ts +0 -5
  129. package/eventcatalog/src/{enterprise → features}/fields/pages/api/fields.ts +1 -6
  130. package/eventcatalog/src/{enterprise → features}/fields/pages/fields.astro +1 -2
  131. package/eventcatalog/src/{enterprise → features}/integrations/eventcatalog-features.ts +17 -75
  132. package/eventcatalog/src/features/mcp/apps/architecture-diagram/links.ts +59 -0
  133. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +299 -0
  134. package/eventcatalog/src/features/mcp/apps/architecture-diagram/shared.ts +14 -0
  135. package/eventcatalog/src/features/mcp/apps/architecture-diagram/view.tsx +454 -0
  136. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +432 -0
  137. package/eventcatalog/src/features/mcp/apps/mermaid-stub.ts +10 -0
  138. package/eventcatalog/src/features/mcp/apps/schema-viewer/schema-code.tsx +65 -0
  139. package/eventcatalog/src/features/mcp/apps/schema-viewer/shared.ts +23 -0
  140. package/eventcatalog/src/features/mcp/apps/schema-viewer/view.tsx +170 -0
  141. package/eventcatalog/src/features/mcp/apps/shared/app-view.tsx +98 -0
  142. package/eventcatalog/src/features/mcp/apps/shared/resource-types.ts +15 -0
  143. package/eventcatalog/src/features/mcp/apps/viewer/shared.ts +24 -0
  144. package/eventcatalog/src/features/mcp/apps/viewer/styles.css +25 -0
  145. package/eventcatalog/src/features/mcp/apps/viewer/view.tsx +59 -0
  146. package/eventcatalog/src/features/mcp/mcp-app-icons.ts +63 -0
  147. package/eventcatalog/src/features/mcp/mcp-apps.ts +160 -0
  148. package/eventcatalog/src/{enterprise → features}/mcp/mcp-auth.ts +0 -5
  149. package/eventcatalog/src/{enterprise → features}/mcp/mcp-scope.ts +7 -7
  150. package/eventcatalog/src/{enterprise → features}/mcp/mcp-scoped-tools.ts +47 -40
  151. package/eventcatalog/src/{enterprise → features}/mcp/mcp-server.ts +347 -34
  152. package/eventcatalog/src/{enterprise → features}/mcp/oauth-protected-resource.ts +0 -5
  153. package/eventcatalog/src/features/mcp/schema-viewer.ts +24 -0
  154. package/eventcatalog/src/{enterprise → features}/tools/catalog-tools.ts +133 -102
  155. package/eventcatalog/src/features/tools/index.ts +5 -0
  156. package/eventcatalog/src/{enterprise → features}/visualizer-layout/reset.ts +0 -5
  157. package/eventcatalog/src/{enterprise → features}/visualizer-layout/save.ts +0 -5
  158. package/eventcatalog/src/layouts/BaseLayout.astro +2 -2
  159. package/eventcatalog/src/layouts/Footer.astro +31 -39
  160. package/eventcatalog/src/layouts/SettingsLayout.astro +6 -6
  161. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +7 -37
  162. package/eventcatalog/src/{enterprise → pages}/api/schemas/[collection]/[id]/[version]/index.ts +0 -22
  163. package/eventcatalog/src/{enterprise → pages}/api/schemas/services/[id]/[version]/[specification]/index.ts +0 -19
  164. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +2 -6
  165. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -5
  166. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +2 -6
  167. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -5
  168. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].md.ts +2 -6
  169. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId].mdx.ts +2 -6
  170. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +9 -5
  171. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +12 -0
  172. package/eventcatalog/src/{enterprise/custom-documentation/pages/docs/custom/root-index.astro → pages/docs/custom/index.astro} +1 -23
  173. package/eventcatalog/src/pages/docs/llm/llms-full.txt.ts +4 -9
  174. package/eventcatalog/src/pages/docs/llm/llms.txt.ts +4 -4
  175. package/eventcatalog/src/pages/docs/llm/schemas.txt.ts +0 -11
  176. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +2 -2
  177. package/eventcatalog/src/pages/index.astro +2 -2
  178. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +0 -3
  179. package/eventcatalog/src/pages/schemas/explorer/index.astro +1 -4
  180. package/eventcatalog/src/pages/settings/assistant.astro +2 -4
  181. package/eventcatalog/src/pages/settings/license.astro +18 -0
  182. package/eventcatalog/src/pages/settings/llm-access.astro +1 -4
  183. package/eventcatalog/src/pages/settings/mcp.astro +33 -4
  184. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +1 -2
  185. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +2 -45
  186. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -1
  187. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version].mermaid.ts +7 -109
  188. package/eventcatalog/src/pages/visualiser/_mermaid-route.ts +78 -0
  189. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/_index.data.ts +44 -0
  190. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -1
  191. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +56 -0
  192. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +3 -40
  193. package/eventcatalog/src/pages/visualiser/domains/[id]/[version].mermaid.ts +20 -0
  194. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/_index.data.ts +29 -0
  195. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +3 -38
  196. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +56 -0
  197. package/eventcatalog/src/pages/visualiser/systems/[id]/[version].mermaid.ts +20 -0
  198. package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +1 -1
  199. package/eventcatalog/src/stores/sidebar-store/builders/container.ts +1 -1
  200. package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +1 -1
  201. package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +7 -32
  202. package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +1 -1
  203. package/eventcatalog/src/stores/sidebar-store/builders/message.ts +1 -1
  204. package/eventcatalog/src/stores/sidebar-store/builders/service.ts +2 -8
  205. package/eventcatalog/src/stores/sidebar-store/builders/system.ts +2 -12
  206. package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +0 -10
  207. package/eventcatalog/src/stores/sidebar-store/state.ts +4 -6
  208. package/eventcatalog/src/styles/theme.css +22 -18
  209. package/eventcatalog/src/styles/themes/forest.css +8 -8
  210. package/eventcatalog/src/styles/themes/ocean.css +8 -8
  211. package/eventcatalog/src/styles/themes/sapphire.css +8 -8
  212. package/eventcatalog/src/styles/themes/sunset.css +8 -8
  213. package/eventcatalog/src/utils/clipboard.ts +4 -4
  214. package/eventcatalog/src/utils/collections/flow-step-schema.ts +117 -0
  215. package/eventcatalog/src/utils/collections/pointer-schema.ts +7 -0
  216. package/eventcatalog/src/utils/collections/resource-docs.ts +677 -14
  217. package/eventcatalog/src/utils/collections/schema-loader.ts +0 -5
  218. package/eventcatalog/src/utils/feature.ts +14 -23
  219. package/eventcatalog/src/utils/license.ts +114 -0
  220. package/eventcatalog/src/utils/node-graphs/architecture-diagram-types.ts +32 -0
  221. package/eventcatalog/src/utils/node-graphs/architecture-diagram.ts +84 -0
  222. package/eventcatalog/src/utils/node-graphs/channel-node-graph.ts +4 -25
  223. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +12 -39
  224. package/eventcatalog/src/utils/node-graphs/data-products-node-graph.ts +11 -27
  225. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +679 -0
  226. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +3 -20
  227. package/eventcatalog/src/utils/node-graphs/export-mermaid.ts +51 -4
  228. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +8 -23
  229. package/eventcatalog/src/utils/node-graphs/flow-lanes.ts +119 -0
  230. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +133 -47
  231. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +28 -0
  232. package/eventcatalog/src/utils/node-graphs/layout-persistence.ts +3 -3
  233. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +16 -34
  234. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +11 -25
  235. package/eventcatalog/src/utils/node-graphs/system-context-node-graph.ts +18 -54
  236. package/eventcatalog/src/utils/node-graphs/system-levels-node-graph.ts +59 -0
  237. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +20 -80
  238. package/eventcatalog/src/utils/node-graphs/utils/utils.ts +1 -78
  239. package/eventcatalog/src/utils/trial.ts +36 -0
  240. package/eventcatalog/tsconfig.json +1 -1
  241. package/package.json +11 -11
  242. package/dist/chunk-FV56YFM4.js +0 -7
  243. package/dist/federation/entitlement.cjs +0 -31
  244. package/dist/federation/entitlement.d.cts +0 -12
  245. package/dist/federation/entitlement.d.ts +0 -12
  246. package/dist/federation/entitlement.js +0 -6
  247. package/dist/runtime-dependencies/dagre.mjs +0 -3
  248. package/eventcatalog/src/components/Settings/BillingSettingsForm.tsx +0 -265
  249. package/eventcatalog/src/enterprise/LICENSE +0 -57
  250. package/eventcatalog/src/enterprise/README.md +0 -5
  251. package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +0 -691
  252. package/eventcatalog/src/enterprise/custom-documentation/components/CustomDocsNav/CustomDocsNav.astro +0 -9
  253. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/[...path]/index.astro +0 -18
  254. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/feature.astro +0 -171
  255. package/eventcatalog/src/enterprise/feature.ts +0 -75
  256. package/eventcatalog/src/enterprise/tools/index.ts +0 -10
  257. package/eventcatalog/src/hooks/eventcatalog-visualizer.ts +0 -126
  258. package/eventcatalog/src/pages/settings/billing.astro +0 -17
  259. package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +0 -26
  260. package/eventcatalog/src/types/mcp-modules.d.ts +0 -67
  261. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +0 -261
  262. package/eventcatalog/src/utils/node-graphs/export-node-graph.ts +0 -91
  263. /package/eventcatalog/src/{enterprise → features}/auth/error.astro +0 -0
  264. /package/eventcatalog/src/{enterprise → features}/auth/login.astro +0 -0
  265. /package/eventcatalog/src/{enterprise → features}/auth/unauthorized.astro +0 -0
  266. /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path]/_index.data.ts +0 -0
  267. /package/eventcatalog/src/{enterprise/custom-documentation/pages → pages}/docs/custom/[...path].mdx.ts +0 -0
@@ -0,0 +1,299 @@
1
+ /**
2
+ * A small modal shown next to a node clicked in the architecture diagram view, to ask a question
3
+ * about it. Nothing is sent until the user sends their question: it then goes to the conversation
4
+ * in the MCP host with the node it is about, so the model can answer it with the EventCatalog tools.
5
+ */
6
+ import { useEffect, useRef, useState, type FormEvent, type KeyboardEvent, type RefObject } from 'react';
7
+ import type { Node } from '@xyflow/react';
8
+ import { Check, Network, SendHorizontal, X } from 'lucide-react';
9
+ import type { ArchitectureDiagramCollection } from '@utils/node-graphs/architecture-diagram-types';
10
+ import type { DiagramLink } from './links';
11
+ import { RESOURCE_TYPE_LABELS } from '../shared/resource-types';
12
+
13
+ export type SelectedNode = {
14
+ /** The node's id in the diagram, to find it on screen */
15
+ nodeId: string;
16
+ type: string;
17
+ id: string;
18
+ name: string;
19
+ version?: string;
20
+ summary?: string;
21
+ /** The resource's own architecture diagram, when it has one */
22
+ diagram?: DiagramLink;
23
+ };
24
+
25
+ const NODE_TYPE_LABELS: Record<string, string> = {
26
+ ...RESOURCE_TYPE_LABELS,
27
+ data: 'Data store',
28
+ 'context-domain': 'Domain',
29
+ 'domain-group': 'Domain',
30
+ 'system-group': 'System',
31
+ 'context-actor': 'Actor',
32
+ actor: 'Actor',
33
+ user: 'User',
34
+ step: 'Step',
35
+ custom: 'Step',
36
+ externalSystem: 'External system',
37
+ };
38
+
39
+ // Where each node type keeps the resource it shows
40
+ const RESOURCE_DATA_KEYS = [
41
+ 'service',
42
+ 'agent',
43
+ 'message',
44
+ 'channel',
45
+ 'data',
46
+ 'dataProduct',
47
+ 'flow',
48
+ 'entity',
49
+ 'domain',
50
+ 'system',
51
+ 'custom',
52
+ ];
53
+
54
+ // The collection of each node type the architecture diagram tool can draw a diagram for
55
+ const DIAGRAM_COLLECTIONS: Record<string, ArchitectureDiagramCollection> = {
56
+ services: 'services',
57
+ agents: 'agents',
58
+ events: 'events',
59
+ commands: 'commands',
60
+ queries: 'queries',
61
+ flows: 'flows',
62
+ data: 'containers',
63
+ containers: 'containers',
64
+ 'data-products': 'data-products',
65
+ domains: 'domains',
66
+ 'context-domain': 'domains',
67
+ 'domain-group': 'domains',
68
+ systems: 'systems',
69
+ 'system-group': 'systems',
70
+ };
71
+
72
+ // Domain and system boundaries only have their catalog id in the node id: {kind}-group-{id}-{version}
73
+ const catalogIdOfGroup = (node: Node, version?: string) => {
74
+ const match = node.id.match(/^(?:domain|system)-group-(.+)$/);
75
+ if (!match) return undefined;
76
+ return version && match[1].endsWith(`-${version}`) ? match[1].slice(0, -(version.length + 1)) : match[1];
77
+ };
78
+
79
+ export function describeNode(node: Node): SelectedNode {
80
+ const data = (node.data ?? {}) as Record<string, any>;
81
+ const resource = RESOURCE_DATA_KEYS.map((key) => data[key]).find(Boolean) ?? data;
82
+ const details = resource?.data ?? resource;
83
+ const version: string | undefined = details?.version;
84
+ const id: string = details?.id ?? catalogIdOfGroup(node, version) ?? node.id;
85
+ const collection = DIAGRAM_COLLECTIONS[node.type ?? ''];
86
+
87
+ return {
88
+ nodeId: node.id,
89
+ type: NODE_TYPE_LABELS[node.type ?? ''] ?? node.type ?? 'Resource',
90
+ id,
91
+ name: details?.name ?? details?.title ?? details?.id ?? data.name ?? data.step?.title ?? node.id,
92
+ version,
93
+ summary: typeof details?.summary === 'string' ? details.summary.trim() : undefined,
94
+ diagram: collection && version ? { collection, id, version } : undefined,
95
+ };
96
+ }
97
+
98
+ /** How the node is described to the model, so it can look it up in EventCatalog */
99
+ export const describeNodeForModel = (node: Pick<SelectedNode, 'type' | 'id' | 'name' | 'version'>) =>
100
+ `the ${node.type.toLowerCase()} "${node.name}" (id: ${node.id}${node.version ? `, version: ${node.version}` : ''})`;
101
+
102
+ const MODAL_WIDTH = 300;
103
+ const GAP = 12;
104
+ const EDGE = 8;
105
+
106
+ type Anchor = { top: number; left: number; side: 'right' | 'left' };
107
+
108
+ /**
109
+ * Where to show the modal: next to the node (on its right, or its left when there is no room),
110
+ * kept inside the diagram and following the node as the diagram is panned or zoomed.
111
+ */
112
+ function useNodeAnchor(nodeId: string, containerRef: RefObject<HTMLElement | null>, modalRef: RefObject<HTMLElement | null>) {
113
+ const [anchor, setAnchor] = useState<Anchor | null>(null);
114
+
115
+ useEffect(() => {
116
+ let frame = 0;
117
+ const update = () => {
118
+ const container = containerRef.current;
119
+ const element = container?.querySelector<HTMLElement>(`.react-flow__node[data-id="${CSS.escape(nodeId)}"]`);
120
+ if (container && element) {
121
+ const bounds = container.getBoundingClientRect();
122
+ const rect = element.getBoundingClientRect();
123
+ const height = modalRef.current?.offsetHeight ?? 200;
124
+ const side = rect.right + GAP + MODAL_WIDTH <= bounds.right - EDGE ? 'right' : 'left';
125
+ const left = side === 'right' ? rect.right - bounds.left + GAP : rect.left - bounds.left - GAP - MODAL_WIDTH;
126
+ const clamp = (value: number, max: number) => Math.min(Math.max(value, EDGE), Math.max(max, EDGE));
127
+ const next: Anchor = {
128
+ side,
129
+ left: clamp(left, bounds.width - MODAL_WIDTH - EDGE),
130
+ top: clamp(rect.top - bounds.top, bounds.height - height - EDGE),
131
+ };
132
+ setAnchor((previous) =>
133
+ previous?.left === next.left && previous?.top === next.top && previous?.side === next.side ? previous : next
134
+ );
135
+ }
136
+ frame = requestAnimationFrame(update);
137
+ };
138
+ update();
139
+ return () => cancelAnimationFrame(frame);
140
+ }, [nodeId, containerRef, modalRef]);
141
+
142
+ return anchor;
143
+ }
144
+
145
+ type NodeChatProps = {
146
+ node: SelectedNode;
147
+ /** The diagram the node is in, to position the modal next to it */
148
+ containerRef: RefObject<HTMLElement | null>;
149
+ /** Whether the host lets the view send messages to the conversation */
150
+ canSend: boolean;
151
+ onSend: (question: string) => Promise<void>;
152
+ /** Opens the node's own diagram in the view, when it has one */
153
+ onOpenDiagram?: () => void;
154
+ onClose: () => void;
155
+ };
156
+
157
+ export function NodeChat({ node, containerRef, canSend, onSend, onOpenDiagram, onClose }: NodeChatProps) {
158
+ const [question, setQuestion] = useState('');
159
+ const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'failed'>('idle');
160
+ const modalRef = useRef<HTMLDivElement>(null);
161
+ const inputRef = useRef<HTMLTextAreaElement>(null);
162
+ const anchor = useNodeAnchor(node.nodeId, containerRef, modalRef);
163
+
164
+ useEffect(() => {
165
+ setQuestion('');
166
+ setStatus('idle');
167
+ }, [node.nodeId]);
168
+
169
+ // Focus the question once the modal is shown next to the node (it is hidden until then, and
170
+ // can't take focus). Waits a moment so a closing right-click menu doesn't take the focus back.
171
+ const isShown = anchor !== null;
172
+ useEffect(() => {
173
+ if (!isShown) return;
174
+ const timeout = setTimeout(() => inputRef.current?.focus({ preventScroll: true }), 50);
175
+ return () => clearTimeout(timeout);
176
+ }, [isShown, node.nodeId]);
177
+
178
+ // Close on Escape, or on a click on the empty diagram (but not when it is dragged to pan)
179
+ useEffect(() => {
180
+ let pressedAt: { x: number; y: number } | null = null;
181
+ const onPointerDown = (event: PointerEvent) => {
182
+ pressedAt = (event.target as Element).closest?.('.react-flow__pane') ? { x: event.clientX, y: event.clientY } : null;
183
+ };
184
+ const onPointerUp = (event: PointerEvent) => {
185
+ if (pressedAt && Math.hypot(event.clientX - pressedAt.x, event.clientY - pressedAt.y) < 4) onClose();
186
+ pressedAt = null;
187
+ };
188
+ const onKeyDown = (event: globalThis.KeyboardEvent) => event.key === 'Escape' && onClose();
189
+ document.addEventListener('pointerdown', onPointerDown, true);
190
+ document.addEventListener('pointerup', onPointerUp, true);
191
+ document.addEventListener('keydown', onKeyDown);
192
+ return () => {
193
+ document.removeEventListener('pointerdown', onPointerDown, true);
194
+ document.removeEventListener('pointerup', onPointerUp, true);
195
+ document.removeEventListener('keydown', onKeyDown);
196
+ };
197
+ }, [onClose]);
198
+
199
+ // Close shortly after the question is sent, once the user has seen it went
200
+ useEffect(() => {
201
+ if (status !== 'sent') return;
202
+ const timeout = setTimeout(onClose, 1500);
203
+ return () => clearTimeout(timeout);
204
+ }, [status, onClose]);
205
+
206
+ const send = async () => {
207
+ if (!question.trim() || status === 'sending' || status === 'sent') return;
208
+ setStatus('sending');
209
+ try {
210
+ await onSend(question.trim());
211
+ setStatus('sent');
212
+ } catch {
213
+ setStatus('failed');
214
+ }
215
+ };
216
+
217
+ const handleSubmit = (event: FormEvent) => {
218
+ event.preventDefault();
219
+ send();
220
+ };
221
+
222
+ // Enter sends, Shift+Enter adds a new line
223
+ const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
224
+ if (event.key === 'Enter' && !event.shiftKey) {
225
+ event.preventDefault();
226
+ send();
227
+ }
228
+ };
229
+
230
+ return (
231
+ <div
232
+ ref={modalRef}
233
+ className="ec-mcp-modal"
234
+ data-side={anchor?.side ?? 'right'}
235
+ role="dialog"
236
+ aria-label={`Ask a question about ${node.name}`}
237
+ style={{
238
+ width: MODAL_WIDTH,
239
+ top: anchor?.top ?? EDGE,
240
+ left: anchor?.left ?? EDGE,
241
+ visibility: anchor ? 'visible' : 'hidden',
242
+ }}
243
+ >
244
+ <div className="ec-mcp-modal-header">
245
+ <span className="ec-mcp-type">{node.type}</span>
246
+ <span className="ec-mcp-name">{node.name}</span>
247
+ {node.version && <span className="ec-mcp-version">v{node.version}</span>}
248
+ <button type="button" className="ec-mcp-modal-close" aria-label="Close" onClick={onClose}>
249
+ <X aria-hidden />
250
+ </button>
251
+ </div>
252
+ {node.summary && <p className="ec-mcp-modal-summary">{node.summary}</p>}
253
+ {onOpenDiagram && (
254
+ <button type="button" className="ec-mcp-modal-link" onClick={onOpenDiagram}>
255
+ <Network aria-hidden />
256
+ Open the {node.type.toLowerCase()} diagram
257
+ </button>
258
+ )}
259
+
260
+ {status === 'sent' ? (
261
+ <p className="ec-mcp-modal-sent">
262
+ <Check aria-hidden />
263
+ Sent to the chat
264
+ </p>
265
+ ) : canSend ? (
266
+ <form className="ec-mcp-modal-form" onSubmit={handleSubmit}>
267
+ <label htmlFor="ec-mcp-question">Ask a question</label>
268
+ <div className="ec-mcp-composer">
269
+ <textarea
270
+ id="ec-mcp-question"
271
+ ref={inputRef}
272
+ rows={2}
273
+ value={question}
274
+ placeholder={`Ask about ${node.name}…`}
275
+ disabled={status === 'sending'}
276
+ onChange={(event) => setQuestion(event.target.value)}
277
+ onKeyDown={handleKeyDown}
278
+ />
279
+ <div className="ec-mcp-composer-footer">
280
+ <span className="ec-mcp-composer-hint">Enter to send</span>
281
+ <button
282
+ type="submit"
283
+ className="ec-mcp-composer-send"
284
+ aria-label={status === 'sending' ? 'Sending' : 'Send to chat'}
285
+ title="Send to chat"
286
+ disabled={!question.trim() || status === 'sending'}
287
+ >
288
+ <SendHorizontal aria-hidden />
289
+ </button>
290
+ </div>
291
+ </div>
292
+ {status === 'failed' && <p className="ec-mcp-modal-error">Couldn't send this to the chat. Try again.</p>}
293
+ </form>
294
+ ) : (
295
+ <p className="ec-mcp-modal-hint">This app can't send questions here. Ask about {node.name} in the chat.</p>
296
+ )}
297
+ </div>
298
+ );
299
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared by the MCP server and the architecture diagram MCP App view (view.tsx, shown by the viewer in ../viewer).
3
+ * Kept free of server-only imports so it can be bundled into the view.
4
+ */
5
+ import type { ArchitectureDiagramView } from '@utils/node-graphs/architecture-diagram-types';
6
+
7
+ export type ArchitectureDiagramPayload = {
8
+ resource: { collection: string; id: string; version: string; name: string };
9
+ /** The EventCatalog the diagram came from, for links back to it */
10
+ catalogUrl: string;
11
+ /** Path of the resource's Diagram page in EventCatalog */
12
+ visualiserPath: string;
13
+ view: ArchitectureDiagramView;
14
+ };