@eventcatalog/core 5.0.0-beta.9 → 5.0.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 (458) hide show
  1. package/LICENSE +13 -12
  2. package/README.md +5 -5
  3. package/dist/analytics/analytics.cjs +1 -1
  4. package/dist/analytics/analytics.js +2 -2
  5. package/dist/analytics/log-build.cjs +91 -44
  6. package/dist/analytics/log-build.d.cts +2 -2
  7. package/dist/analytics/log-build.d.ts +2 -2
  8. package/dist/analytics/log-build.js +6 -5
  9. package/dist/analytics/studio-usage.cjs +90 -0
  10. package/dist/analytics/studio-usage.d.cts +5 -0
  11. package/dist/analytics/studio-usage.d.ts +5 -0
  12. package/dist/analytics/studio-usage.js +10 -0
  13. package/dist/catalog-runtime.cjs +1 -1
  14. package/dist/{chunk-ZEY2XUJN.js → chunk-46TBJZC3.js} +1 -1
  15. package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
  16. package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
  17. package/dist/chunk-CA6WCQ2T.js +54 -0
  18. package/dist/{chunk-GAHKCOQM.js → chunk-DVHJTQWQ.js} +1 -1
  19. package/dist/{chunk-TZVDMWQX.js → chunk-HFR5OPHV.js} +4 -2
  20. package/dist/{chunk-4CFZUHGG.js → chunk-KTXSCPEK.js} +1 -1
  21. package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
  22. package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
  23. package/dist/chunk-S5GWAUG5.js +29 -0
  24. package/dist/{chunk-EUNQJO3J.js → chunk-UWAXRTAJ.js} +1 -1
  25. package/dist/{chunk-JQMYHZWI.js → chunk-YPWK5ITM.js} +15 -7
  26. package/dist/constants.cjs +1 -1
  27. package/dist/constants.js +1 -1
  28. package/dist/docs/api/02-config.md +57 -7
  29. package/dist/docs/development/00-why-eventcatalog.md +11 -11
  30. package/dist/docs/development/01-fundamentals.md +20 -13
  31. package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
  32. package/dist/docs/development/01-getting-started/installation.md +9 -1
  33. package/dist/docs/development/_getting-started.mdx +1 -1
  34. package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
  35. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
  36. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
  37. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
  38. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
  39. package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
  40. package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
  41. package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
  42. package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
  43. package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
  44. package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
  45. package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
  46. package/dist/docs/development/authentication/01-introduction.md +2 -23
  47. package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
  48. package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
  49. package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
  50. package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
  51. package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
  52. package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
  53. package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
  54. package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
  55. package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
  56. package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
  57. package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
  58. package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
  59. package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
  60. package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
  61. package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
  62. package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
  63. package/dist/docs/development/components/components/11-flow.md +17 -0
  64. package/dist/docs/development/components/components/15-nodegraph.md +43 -10
  65. package/dist/docs/development/components/components/18-remote-schema.md +1 -4
  66. package/dist/docs/development/components/custom-components/07-reference.md +14 -0
  67. package/dist/docs/development/customization/02-themes.md +0 -5
  68. package/dist/docs/development/customization/03-search.md +1 -1
  69. package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
  70. package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
  71. package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
  72. package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
  73. package/dist/docs/development/deployment/hosting-options.md +7 -2
  74. package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
  75. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
  76. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
  77. package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
  78. package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
  79. package/dist/docs/development/guides/97-architecture-graph.md +1 -1
  80. package/dist/docs/development/guides/99-adding-analytics.md +0 -7
  81. package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
  82. package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
  83. package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
  84. package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
  85. package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
  86. package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
  87. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
  88. package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
  89. package/dist/docs/development/guides/domains/09-reference.md +4 -4
  90. package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
  91. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
  92. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
  93. package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
  94. package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
  95. package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
  96. package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
  97. package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
  98. package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
  99. package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
  100. package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
  101. package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
  102. package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
  103. package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
  104. package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
  105. package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
  106. package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
  107. package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
  108. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
  109. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
  110. package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
  111. package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
  112. package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
  113. package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
  114. package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
  115. package/dist/docs/development/guides/systems/01-introduction.md +1 -1
  116. package/dist/docs/development/guides/systems/02-create-system.md +2 -2
  117. package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
  118. package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
  119. package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
  120. package/dist/docs/development/guides/systems/06-reference.md +4 -4
  121. package/dist/docs/development/license/01-license-file.md +151 -0
  122. package/dist/docs/development/license/_category_.json +12 -0
  123. package/dist/docs/development/license-keys/_category_.json +3 -3
  124. package/dist/docs/development/license-keys/integrations.md +7 -37
  125. package/dist/docs/development/license-keys/license-validation.md +4 -0
  126. package/dist/docs/development/license-keys/overview.md +5 -1
  127. package/dist/docs/development/license-keys/plans.md +4 -2
  128. package/dist/docs/development/studio/01-introduction.md +60 -0
  129. package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
  130. package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
  131. package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
  132. package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
  133. package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
  134. package/dist/docs/development/studio/07-reference.md +294 -0
  135. package/dist/docs/development/studio/_category_.json +12 -0
  136. package/dist/docs/development/upgrading/v5.md +345 -0
  137. package/dist/docs/federation/00-overview.md +2 -8
  138. package/dist/docs/federation/01-first-federation.md +6 -18
  139. package/dist/docs/federation/explanation/how-it-works.md +0 -4
  140. package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
  141. package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
  142. package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
  143. package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
  144. package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
  145. package/dist/docs/federation/how-to/run-in-ci.md +2 -9
  146. package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
  147. package/dist/docs/federation/how-to/use-local-sources.md +0 -4
  148. package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
  149. package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
  150. package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
  151. package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
  152. package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
  153. package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
  154. package/dist/docs/federation/reference/cli.md +2 -8
  155. package/dist/docs/federation/reference/configuration.md +0 -4
  156. package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
  157. package/dist/docs/federation/reference/generated-output.md +0 -4
  158. package/dist/docs/federation/reference/supported-content.md +0 -4
  159. package/dist/docs/federation/reference/troubleshooting.md +0 -14
  160. package/dist/docs/plugins/02-generators.md +1 -1
  161. package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
  162. package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
  163. package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
  164. package/dist/docs/plugins/apicurio/00-intro.md +2 -31
  165. package/dist/docs/plugins/apicurio/01-installation.md +2 -26
  166. package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
  167. package/dist/docs/plugins/apicurio/03-features.md +1 -3
  168. package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
  169. package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
  170. package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
  171. package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
  172. package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
  173. package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
  174. package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
  175. package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
  176. package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
  177. package/dist/docs/plugins/backstage/00-overview.md +1 -7
  178. package/dist/docs/plugins/backstage/01-get-started.md +6 -15
  179. package/dist/docs/plugins/backstage/06-configuration.md +2 -8
  180. package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
  181. package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
  182. package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
  183. package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
  184. package/dist/docs/plugins/eventbridge/03-api.md +2 -20
  185. package/dist/docs/plugins/github/00-intro.md +0 -31
  186. package/dist/docs/plugins/github/01-installation.md +2 -34
  187. package/dist/docs/plugins/graphql/00-intro.md +0 -30
  188. package/dist/docs/plugins/graphql/01-installation.md +1 -53
  189. package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
  190. package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
  191. package/dist/docs/plugins/openapi/00-intro.md +0 -30
  192. package/dist/docs/plugins/openapi/01-installation.md +1 -57
  193. package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
  194. package/dist/docs/plugins/openapi/03-features.md +0 -4
  195. package/dist/eventcatalog-config-file-utils.cjs +34 -41
  196. package/dist/eventcatalog-config-file-utils.d.cts +56 -58
  197. package/dist/eventcatalog-config-file-utils.d.ts +56 -58
  198. package/dist/eventcatalog-config-file-utils.js +1 -1
  199. package/dist/eventcatalog.cjs +340 -249
  200. package/dist/eventcatalog.config.d.cts +18 -15
  201. package/dist/eventcatalog.config.d.ts +18 -15
  202. package/dist/eventcatalog.js +46 -28
  203. package/dist/features.cjs +36 -49
  204. package/dist/features.d.cts +1 -3
  205. package/dist/features.d.ts +1 -3
  206. package/dist/features.js +4 -6
  207. package/dist/federation/federate.cjs +37 -44
  208. package/dist/federation/federate.js +2 -2
  209. package/dist/generate.cjs +37 -42
  210. package/dist/generate.js +4 -4
  211. package/dist/resolve-catalog-dependencies.cjs +34 -41
  212. package/dist/resolve-catalog-dependencies.js +2 -2
  213. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
  214. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
  215. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
  216. package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
  217. package/dist/runtime-dependencies/manifest.json +5 -1
  218. package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
  219. package/dist/utils/child-process-signals.cjs +53 -0
  220. package/dist/utils/child-process-signals.d.cts +19 -0
  221. package/dist/utils/child-process-signals.d.ts +19 -0
  222. package/dist/utils/child-process-signals.js +6 -0
  223. package/dist/utils/cli-logger.cjs +1 -1
  224. package/dist/utils/cli-logger.js +2 -2
  225. package/dist/utils/license-status.cjs +11 -4
  226. package/dist/utils/license-status.d.cts +3 -2
  227. package/dist/utils/license-status.d.ts +3 -2
  228. package/dist/utils/license-status.js +1 -1
  229. package/eventcatalog/astro.config.mjs +21 -1
  230. package/eventcatalog/integrations/config-loader.mjs +56 -58
  231. package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
  232. package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
  233. package/eventcatalog/integrations/storage.mjs +20 -0
  234. package/eventcatalog/integrations/studio-server.mjs +4 -1
  235. package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
  236. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
  237. package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
  238. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
  239. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
  240. package/eventcatalog/src/components/NavigationProgress.astro +7 -0
  241. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
  242. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
  243. package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
  244. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
  245. package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
  246. package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
  247. package/eventcatalog/src/components/Search/search-utils.ts +26 -0
  248. package/eventcatalog/src/components/Seo.astro +5 -1
  249. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
  250. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
  251. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
  252. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
  253. package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
  254. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
  255. package/eventcatalog/src/components/Settings/Row.tsx +7 -4
  256. package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
  257. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
  258. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
  259. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
  260. package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
  261. package/eventcatalog/src/components/TrialBadge.astro +20 -9
  262. package/eventcatalog/src/content.config.ts +19 -2
  263. package/eventcatalog/src/features/auth/error.astro +4 -2
  264. package/eventcatalog/src/features/auth/login.astro +2 -1
  265. package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
  266. package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
  267. package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
  268. package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
  269. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
  270. package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
  271. package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
  272. package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
  273. package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
  274. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
  275. package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
  276. package/eventcatalog/src/features/server/start.ts +25 -0
  277. package/eventcatalog/src/features/storage/database.ts +88 -0
  278. package/eventcatalog/src/features/storage/migrations.ts +85 -0
  279. package/eventcatalog/src/features/storage/sql/database.sql +5 -0
  280. package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
  281. package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
  282. package/eventcatalog/src/features/storage/sql.ts +28 -0
  283. package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
  284. package/eventcatalog/src/features/studio/agents.ts +28 -0
  285. package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
  286. package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
  287. package/eventcatalog/src/features/studio/api/client.ts +40 -0
  288. package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
  289. package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
  290. package/eventcatalog/src/features/studio/catalog.ts +16 -14
  291. package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
  292. package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
  293. package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
  294. package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
  295. package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
  296. package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
  297. package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
  298. package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
  299. package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
  300. package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
  301. package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
  302. package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
  303. package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
  304. package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
  305. package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
  306. package/eventcatalog/src/features/studio/document-name.ts +7 -0
  307. package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
  308. package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
  309. package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
  310. package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
  311. package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
  312. package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
  313. package/eventcatalog/src/features/studio/identity.ts +25 -1
  314. package/eventcatalog/src/features/studio/limits.ts +2 -0
  315. package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
  316. package/eventcatalog/src/features/studio/pages/index.astro +596 -373
  317. package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
  318. package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
  319. package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
  320. package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
  321. package/eventcatalog/src/features/studio/server/storage.ts +53 -73
  322. package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
  323. package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
  324. package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
  325. package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
  326. package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
  327. package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
  328. package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
  329. package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
  330. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
  331. package/eventcatalog/src/pages/_index.astro +5 -342
  332. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
  333. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
  334. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
  335. package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
  336. package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
  337. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
  338. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
  339. package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
  340. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
  341. package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
  342. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
  343. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
  344. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
  345. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
  346. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
  347. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
  348. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
  349. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
  350. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
  351. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
  352. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
  353. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
  354. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
  355. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
  356. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
  357. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
  358. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
  359. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
  360. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
  361. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
  362. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
  363. package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
  364. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
  365. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
  366. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
  367. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
  368. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
  369. package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
  370. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
  371. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
  372. package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
  373. package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
  374. package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
  375. package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
  376. package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
  377. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
  378. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
  379. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
  380. package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
  381. package/eventcatalog/src/pages/index.astro +4 -2
  382. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
  383. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
  384. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
  385. package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
  386. package/eventcatalog/src/pages/settings/license.astro +9 -1
  387. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
  388. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
  389. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
  390. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
  391. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
  392. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
  393. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
  394. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
  395. package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
  396. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
  397. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
  398. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
  399. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
  400. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
  401. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
  402. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
  403. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
  404. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
  405. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
  406. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
  407. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
  408. package/eventcatalog/src/utils/collections/flows.ts +20 -7
  409. package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
  410. package/eventcatalog/src/utils/collections/resources.ts +2 -0
  411. package/eventcatalog/src/utils/collections/util.ts +8 -4
  412. package/eventcatalog/src/utils/git.ts +11 -0
  413. package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
  414. package/eventcatalog/src/utils/license.ts +1 -1
  415. package/eventcatalog/src/utils/link-validation.ts +25 -19
  416. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
  417. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
  418. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
  419. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
  420. package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
  421. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
  422. package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
  423. package/eventcatalog/src/utils/page-title.ts +15 -0
  424. package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
  425. package/eventcatalog/src/utils/trial.ts +13 -0
  426. package/package.json +12 -12
  427. package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
  428. package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
  429. package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
  430. package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
  431. package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
  432. package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
  433. package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
  434. package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
  435. package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
  436. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
  437. package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
  438. package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
  439. package/eventcatalog/src/features/studio/clipboard.ts +0 -97
  440. package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
  441. package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
  442. package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
  443. package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
  444. package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
  445. package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
  446. package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
  447. package/eventcatalog/src/features/studio/components/icons.ts +0 -53
  448. package/eventcatalog/src/features/studio/components/status.ts +0 -51
  449. package/eventcatalog/src/features/studio/edges.ts +0 -56
  450. package/eventcatalog/src/features/studio/flow-state.ts +0 -92
  451. package/eventcatalog/src/features/studio/grouping.ts +0 -226
  452. package/eventcatalog/src/features/studio/layout.ts +0 -42
  453. package/eventcatalog/src/features/studio/levels.ts +0 -282
  454. package/eventcatalog/src/features/studio/node-types.ts +0 -205
  455. package/eventcatalog/src/features/studio/pages/new.astro +0 -24
  456. package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
  457. package/eventcatalog/src/features/studio/placement.ts +0 -197
  458. package/eventcatalog/src/features/studio/studio.css +0 -273
@@ -0,0 +1,183 @@
1
+ import { memo, type RefObject } from 'react';
2
+ import type { Node } from '@xyflow/react';
3
+ import { Box, ExternalLink, Library } from 'lucide-react';
4
+ import { getCatalogLink } from '../catalog';
5
+ import {
6
+ EditableText,
7
+ EditStatus,
8
+ Field,
9
+ NodeCard,
10
+ getNodeLabel,
11
+ getResource,
12
+ isVersioned,
13
+ updateResource,
14
+ useSavedFlash,
15
+ type UpdateNodeData,
16
+ NODE_ICONS,
17
+ } from '@eventcatalog/visualiser/studio';
18
+
19
+ /** Something it's connected to: the node at the other end, and the connection's label */
20
+ export type NodeConnection = { id: string; name: string; type?: string; label?: string; outgoing: boolean };
21
+
22
+ /**
23
+ * A node's details, in a card next to it (as Studio on the web's): its type and where it is, and its name, version
24
+ * and summary, saved as they're typed, and what it's connected to (click one to go to it). Catalog resources are read only (they're changed in the catalog), as is
25
+ * everything on a locked canvas. Notes and text are edited on the canvas.
26
+ */
27
+ export default memo(function NodeDetails({
28
+ node,
29
+ parentName,
30
+ connections,
31
+ onOpenNode,
32
+ containerRef,
33
+ locked,
34
+ onChange,
35
+ onClose,
36
+ }: {
37
+ /** What's shown of the node (not its position: the card follows the node on screen by itself) */
38
+ node: Pick<Node, 'id' | 'type' | 'data'>;
39
+ /** The domain or system it's in, if it's in one */
40
+ parentName?: string;
41
+ connections: NodeConnection[];
42
+ /** Goes to a node it's connected to (and shows its card) */
43
+ onOpenNode: (id: string) => void;
44
+ /** The canvas, to put the card next to the node */
45
+ containerRef: RefObject<HTMLElement | null>;
46
+ locked: boolean;
47
+ onChange: UpdateNodeData;
48
+ onClose: () => void;
49
+ }) {
50
+ const { saved, showSaved } = useSavedFlash();
51
+ const resource = getResource(node.type, node.data);
52
+ const link = getCatalogLink(node);
53
+ const label = getNodeLabel(node.type);
54
+ const { icon: Icon, className: iconClassName } = NODE_ICONS[node.type ?? ''] ?? { icon: Box, className: '' };
55
+ const versioned = isVersioned(node.type);
56
+ const name = String(resource.name ?? '');
57
+ const version = String(link?.version ?? resource.version ?? '');
58
+ const summary = String(resource.summary ?? '');
59
+ const save = (fields: Record<string, string>) => onChange(node.id, (data) => updateResource(node.type, data, fields));
60
+
61
+ return (
62
+ <NodeCard
63
+ nodeId={node.id}
64
+ containerRef={containerRef}
65
+ label={name || label}
66
+ onClose={onClose}
67
+ kicker={
68
+ <>
69
+ {/* Its type, in its colour (as the web's type pill) */}
70
+ <span className={`flex-none ${iconClassName}`}>
71
+ <span className="inline-flex items-center gap-1 rounded bg-current px-1.5 text-[9px] font-bold uppercase leading-4 tracking-wider">
72
+ <Icon aria-hidden size={10} className="text-white" />
73
+ <span className="text-white">{label}</span>
74
+ </span>
75
+ </span>
76
+ {parentName && <span className="ec-doc-card-breadcrumb">in {parentName}</span>}
77
+ </>
78
+ }
79
+ header={
80
+ link || locked ? (
81
+ <>
82
+ <h2 className="ec-doc-card-title">
83
+ {name}
84
+ {version && <span className="ec-doc-card-version">v{version}</span>}
85
+ </h2>
86
+ {summary && <p className="ec-doc-card-summary">{summary}</p>}
87
+ {link && (
88
+ <div className="mt-3 flex flex-wrap items-center gap-x-3 gap-y-1.5 text-xs text-[rgb(var(--ec-page-text-muted))]">
89
+ <span className="inline-flex items-center gap-1.5">
90
+ <Library aria-hidden size={13} className="text-[rgb(var(--ec-accent))]" />
91
+ From your catalog: change it there
92
+ </span>
93
+ <a
94
+ href={link.url}
95
+ target="_blank"
96
+ rel="noreferrer"
97
+ className="inline-flex items-center gap-1 font-medium text-[rgb(var(--ec-accent))] hover:underline"
98
+ >
99
+ Open in EventCatalog <ExternalLink aria-hidden size={12} />
100
+ </a>
101
+ </div>
102
+ )}
103
+ </>
104
+ ) : (
105
+ // A small form: what's typed is saved as it's typed (there's nothing to press), and shown on the node
106
+ <div className="ec-edit-form" key={node.id}>
107
+ <Field label="Name">
108
+ <EditableText
109
+ label="Name"
110
+ value={name}
111
+ onSave={(next) => save({ name: next })}
112
+ onSaved={showSaved}
113
+ placeholder={`Name this ${label.toLowerCase()}`}
114
+ className="ec-editable-title"
115
+ required
116
+ />
117
+ </Field>
118
+ {versioned && (
119
+ <Field label="Version" className="ec-field-version">
120
+ <EditableText
121
+ label="Version"
122
+ value={version || '0.0.1'}
123
+ onSave={(next) => save({ version: next })}
124
+ onSaved={showSaved}
125
+ placeholder="0.0.1"
126
+ required
127
+ />
128
+ </Field>
129
+ )}
130
+ <Field label="Summary">
131
+ <EditableText
132
+ label="Summary"
133
+ value={summary}
134
+ onSave={(next) => save({ summary: next })}
135
+ onSaved={showSaved}
136
+ placeholder="What it does, in a sentence or two"
137
+ className="ec-editable-summary"
138
+ multiline
139
+ />
140
+ </Field>
141
+ <EditStatus saved={saved} />
142
+ </div>
143
+ )
144
+ }
145
+ >
146
+ <div className="ec-doc-card-body px-4 pb-3.5 pt-1 empty:hidden">
147
+ {(['Connects to', 'Connected from'] as const).map((heading) => {
148
+ const items = connections.filter((connection) => connection.outgoing === (heading === 'Connects to'));
149
+ if (!items.length) return null;
150
+ return (
151
+ <section key={heading} className="mt-3">
152
+ <h3 className="mb-1.5 text-xs font-semibold text-[rgb(var(--ec-page-text-muted))]">{heading}</h3>
153
+ <ul className="space-y-0.5">
154
+ {items.map((item) => {
155
+ const { icon: ItemIcon, className: itemIconClassName } = NODE_ICONS[item.type ?? ''] ?? {
156
+ icon: Box,
157
+ className: '',
158
+ };
159
+ return (
160
+ <li key={`${item.id}-${item.label}`}>
161
+ <button
162
+ type="button"
163
+ title={`Go to ${item.name}`}
164
+ onClick={() => onOpenNode(item.id)}
165
+ className="flex w-full items-center gap-2 rounded-md px-1.5 py-1 text-left text-sm hover:bg-[rgb(var(--ec-content-hover))]"
166
+ >
167
+ <ItemIcon aria-hidden size={15} className={`flex-none ${itemIconClassName}`} />
168
+ <span className="min-w-0 flex-1 truncate">{item.name}</span>
169
+ {item.label && (
170
+ <span className="flex-none text-[11px] text-[rgb(var(--ec-page-text-muted))]">{item.label}</span>
171
+ )}
172
+ </button>
173
+ </li>
174
+ );
175
+ })}
176
+ </ul>
177
+ </section>
178
+ );
179
+ })}
180
+ </div>
181
+ </NodeCard>
182
+ );
183
+ });
@@ -0,0 +1,79 @@
1
+ import { useState, type FormEvent } from 'react';
2
+ import { MAX_TITLE_LENGTH } from '../limits';
3
+ import Dialog, { PRIMARY_BUTTON, SECONDARY_BUTTON } from './Dialog';
4
+ import { STATUS } from '@eventcatalog/visualiser/studio';
5
+
6
+ /**
7
+ * Naming the canvas a diagram is opened in (the visualiser's "Open in Studio"), named after the diagram to start
8
+ * with, like a new canvas on the Studio page. Loaded with the visualiser, so it imports nothing that loads a canvas.
9
+ */
10
+ export default function OpenInStudioDialog({
11
+ title,
12
+ onOpen,
13
+ onClose,
14
+ }: {
15
+ /** The diagram's title */
16
+ title?: string;
17
+ /** Makes the canvas with this name and opens it (rejects with what went wrong) */
18
+ onOpen: (title: string | undefined) => Promise<void>;
19
+ onClose: () => void;
20
+ }) {
21
+ const [name, setName] = useState((title ?? '').slice(0, MAX_TITLE_LENGTH));
22
+ const [opening, setOpening] = useState(false);
23
+ const [error, setError] = useState<string>();
24
+
25
+ const submit = async (event: FormEvent) => {
26
+ event.preventDefault();
27
+ setOpening(true);
28
+ setError(undefined);
29
+ try {
30
+ // Stays open (and busy) while the canvas page loads
31
+ await onOpen(name.trim() || undefined);
32
+ } catch (failure) {
33
+ setError((failure as Error).message);
34
+ setOpening(false);
35
+ }
36
+ };
37
+
38
+ return (
39
+ <Dialog labelledBy="open-in-studio-title" busy={opening} onClose={onClose}>
40
+ <form onSubmit={submit}>
41
+ <div className="border-b px-5 py-4 border-[rgb(var(--ec-page-border))]">
42
+ <h2 id="open-in-studio-title" className="text-base font-semibold">
43
+ Open in Studio
44
+ </h2>
45
+ <p className="mt-0.5 text-sm text-[rgb(var(--ec-page-text-muted))]">
46
+ A new canvas starts with this diagram. Name it for what you're designing, so your team can find it.
47
+ </p>
48
+ </div>
49
+ <div className="px-5 py-4">
50
+ <label htmlFor="open-in-studio-name" className="block text-sm font-semibold">
51
+ Name
52
+ </label>
53
+ <input
54
+ id="open-in-studio-name"
55
+ // Ready to type a new name, or keep the diagram's
56
+ autoFocus
57
+ onFocus={(event) => event.target.select()}
58
+ value={name}
59
+ onChange={(event) => setName(event.target.value)}
60
+ maxLength={MAX_TITLE_LENGTH}
61
+ autoComplete="off"
62
+ placeholder="e.g. Payments redesign"
63
+ disabled={opening}
64
+ className="mt-2 w-full rounded-lg border px-3 py-2 text-sm shadow-sm bg-[rgb(var(--ec-input-bg))] border-[rgb(var(--ec-input-border))] text-[rgb(var(--ec-input-text))] placeholder:text-[rgb(var(--ec-page-text-muted))] focus:outline-none focus:border-[rgb(var(--ec-accent))] focus:ring-2 focus:ring-[rgb(var(--ec-accent)/0.25)]"
65
+ />
66
+ {error && <p className={`mt-2 text-sm ${STATUS.danger.text}`}>{error}</p>}
67
+ </div>
68
+ <div className="flex justify-end gap-2 border-t px-5 py-4 border-[rgb(var(--ec-page-border))]">
69
+ <button type="button" onClick={onClose} disabled={opening} className={SECONDARY_BUTTON}>
70
+ Cancel
71
+ </button>
72
+ <button type="submit" disabled={opening} className={PRIMARY_BUTTON}>
73
+ {opening ? 'Opening…' : 'Open in Studio'}
74
+ </button>
75
+ </div>
76
+ </form>
77
+ </Dialog>
78
+ );
79
+ }
@@ -1,16 +1,15 @@
1
1
  import { Fragment, memo, useEffect, useLayoutEffect, useRef, useSyncExternalStore, type MutableRefObject } from 'react';
2
- import { useInternalNode, useStore, useStoreApi, ViewportPortal, type XYPosition } from '@xyflow/react';
3
- import { Bot, Eye, EyeOff } from 'lucide-react';
4
- import { sizeOf } from '../grouping';
2
+ import { useInternalNode, useStore, useStoreApi, type XYPosition } from '@xyflow/react';
3
+ import { Eye, EyeOff } from 'lucide-react';
4
+ import { CanvasPortal, sizeOf, COUNTER_SCALE, useCounterScale, Picture, AgentMark } from '@eventcatalog/visualiser/studio';
5
5
  import { usePeople, type Peer, type PresenceStore } from '../hooks/presence-store';
6
6
  import { useFollowCamera } from '../hooks/use-follow-camera';
7
- import Picture from './Picture';
8
7
 
9
8
  /**
10
9
  * Other people on the canvas: their pointers, selections and the connections they're dragging. Drawn in the
11
10
  * canvas's own coordinates (React Flow's viewport portal), so panning and zooming move them without
12
- * re-rendering, and counter-scaled so they stay the same size on screen. Each person's pointer and marks follow
13
- * them on their own, so one pointer moving doesn't re-render anyone else's.
11
+ * re-rendering, and counter-scaled (COUNTER_SCALE, set outside React) so they stay the same size on screen. Each
12
+ * person's pointer and marks follow them on their own, so one pointer moving doesn't re-render anyone else's.
14
13
  */
15
14
  export const RemotePresence = memo(function RemotePresence({
16
15
  store,
@@ -20,22 +19,22 @@ export const RemotePresence = memo(function RemotePresence({
20
19
  clientId: number | null;
21
20
  }) {
22
21
  const people = usePeople(store);
23
- const zoom = useStore((state) => state.transform[2]);
24
- const scale = 1 / zoom;
22
+ const layer = useRef<HTMLDivElement>(null);
23
+ useCounterScale(layer);
25
24
  const others = store ? people.filter((peer) => peer.clientId !== clientId) : [];
26
25
 
27
26
  return (
28
- <ViewportPortal>
27
+ <CanvasPortal>
29
28
  {/* Above nodes (selected ones are raised to 1000) */}
30
- <div className="pointer-events-none absolute left-0 top-0" style={{ zIndex: 2000 }}>
29
+ <div ref={layer} className="pointer-events-none absolute left-0 top-0" style={{ zIndex: 2000 }}>
31
30
  {others.map((peer) => (
32
31
  <Fragment key={peer.clientId}>
33
- <PeerMarks store={store!} clientId={peer.clientId} scale={scale} />
34
- {peer.pointer && <PeerPointer store={store!} peer={peer} scale={scale} />}
32
+ <PeerMarks store={store!} clientId={peer.clientId} />
33
+ {peer.pointer && <PeerPointer store={store!} peer={peer} />}
35
34
  </Fragment>
36
35
  ))}
37
36
  </div>
38
- </ViewportPortal>
37
+ </CanvasPortal>
39
38
  );
40
39
  });
41
40
 
@@ -51,33 +50,39 @@ const marksKey = (peer: Peer | undefined) =>
51
50
  : '';
52
51
 
53
52
  /** Someone's selection, and the connection they're dragging (a dashed line from where it starts to their pointer) */
54
- const PeerMarks = memo(function PeerMarks({ store, clientId, scale }: { store: PresenceStore; clientId: number; scale: number }) {
53
+ const PeerMarks = memo(function PeerMarks({ store, clientId }: { store: PresenceStore; clientId: number }) {
55
54
  useSyncExternalStore(store.subscribe, () => marksKey(findPeer(store, clientId)));
56
55
  const peer = findPeer(store, clientId);
57
56
  if (!peer) return null;
58
57
  return (
59
58
  <>
60
59
  {peer.selection.map((id) => (
61
- <SelectionOutline key={id} nodeId={id} name={peer.name} color={peer.color} scale={scale} />
60
+ <SelectionOutline key={id} nodeId={id} name={peer.name} color={peer.color} />
62
61
  ))}
63
- {peer.pointer && peer.connecting && (
64
- <svg className="absolute left-0 top-0 overflow-visible" width={1} height={1}>
65
- <line
66
- x1={peer.connecting.x}
67
- y1={peer.connecting.y}
68
- x2={peer.pointer.x}
69
- y2={peer.pointer.y}
70
- stroke={peer.color}
71
- strokeWidth={2 * scale}
72
- strokeDasharray={`${6 * scale} ${4 * scale}`}
73
- />
74
- <circle cx={peer.connecting.x} cy={peer.connecting.y} r={4 * scale} fill={peer.color} />
75
- </svg>
76
- )}
62
+ {peer.pointer && peer.connecting && <ConnectingLine from={peer.connecting} to={peer.pointer} color={peer.color} />}
77
63
  </>
78
64
  );
79
65
  });
80
66
 
67
+ /** A connection someone's dragging: only shown while they drag one, so it can follow the zoom itself */
68
+ function ConnectingLine({ from, to, color }: { from: XYPosition; to: XYPosition; color: string }) {
69
+ const scale = 1 / useStore((state) => state.transform[2]);
70
+ return (
71
+ <svg className="absolute left-0 top-0 overflow-visible" width={1} height={1}>
72
+ <line
73
+ x1={from.x}
74
+ y1={from.y}
75
+ x2={to.x}
76
+ y2={to.y}
77
+ stroke={color}
78
+ strokeWidth={2 * scale}
79
+ strokeDasharray={`${6 * scale} ${4 * scale}`}
80
+ />
81
+ <circle cx={from.x} cy={from.y} r={4 * scale} fill={color} />
82
+ </svg>
83
+ );
84
+ }
85
+
81
86
  /** Longest a pointer takes to glide to where it was last seen (updates come about every 33 ms) */
82
87
  const MAX_GLIDE_MS = 120;
83
88
 
@@ -85,19 +90,15 @@ const MAX_GLIDE_MS = 120;
85
90
  * Someone's pointer, gliding from where it was to each new position over the time since the last one (so a
86
91
  * steady stream of updates looks like steady movement). Moved with a transform outside React: no re-renders.
87
92
  */
88
- const PeerPointer = memo(function PeerPointer({ store, peer, scale }: { store: PresenceStore; peer: Peer; scale: number }) {
93
+ const PeerPointer = memo(function PeerPointer({ store, peer }: { store: PresenceStore; peer: Peer }) {
89
94
  const ref = useRef<HTMLDivElement>(null);
90
95
  const shown = useRef<XYPosition | null>(null);
91
- const scaleRef = useRef(scale);
92
- scaleRef.current = scale;
93
96
 
94
97
  const draw = () => {
95
98
  if (ref.current && shown.current)
96
- ref.current.style.transform = `translate(${shown.current.x}px, ${shown.current.y}px) scale(${scaleRef.current})`;
99
+ ref.current.style.transform = `translate(${shown.current.x}px, ${shown.current.y}px) scale(var(${COUNTER_SCALE}, 1))`;
97
100
  };
98
101
 
99
- useLayoutEffect(draw, [scale]);
100
-
101
102
  useLayoutEffect(() => {
102
103
  let target: XYPosition | null = null;
103
104
  let from: XYPosition = { x: 0, y: 0 };
@@ -148,7 +149,7 @@ const PeerPointer = memo(function PeerPointer({ store, peer, scale }: { store: P
148
149
  className="absolute left-4 top-4 flex items-center gap-1 whitespace-nowrap rounded px-1.5 py-0.5 text-[11px] font-medium text-white"
149
150
  style={{ backgroundColor: peer.color }}
150
151
  >
151
- {peer.agent && <Bot size={12} />}
152
+ {peer.agent && <AgentMark name={peer.name} size={12} />}
152
153
  <Picture src={peer.picture} className="-ml-0.5 h-4 w-4 shrink-0" />
153
154
  {peer.name}
154
155
  {peer.activity && <span className="font-normal opacity-90">· {peer.activity}</span>}
@@ -157,17 +158,18 @@ const PeerPointer = memo(function PeerPointer({ store, peer, scale }: { store: P
157
158
  );
158
159
  });
159
160
 
161
+ // Screen pixels, in the canvas's coordinates (counter-scaled by the layer's COUNTER_SCALE)
162
+ const onScreen = (px: number) => `calc(${px}px * var(${COUNTER_SCALE}, 1))`;
163
+
160
164
  /** Someone's selection around a node: follows that node only, so other nodes moving don't re-render it */
161
165
  const SelectionOutline = memo(function SelectionOutline({
162
166
  nodeId,
163
167
  name,
164
168
  color,
165
- scale,
166
169
  }: {
167
170
  nodeId: string;
168
171
  name: string;
169
172
  color: string;
170
- scale: number;
171
173
  }) {
172
174
  const node = useInternalNode(nodeId);
173
175
  if (!node) return null;
@@ -177,17 +179,21 @@ const SelectionOutline = memo(function SelectionOutline({
177
179
  <div
178
180
  className="absolute"
179
181
  style={{
180
- left: x - 4 * scale,
181
- top: y - 4 * scale,
182
- width: width + 8 * scale,
183
- height: height + 8 * scale,
184
- border: `${2 * scale}px solid ${color}`,
185
- borderRadius: 8 * scale,
182
+ left: `calc(${x}px - ${onScreen(4)})`,
183
+ top: `calc(${y}px - ${onScreen(4)})`,
184
+ width: `calc(${width}px + ${onScreen(8)})`,
185
+ height: `calc(${height}px + ${onScreen(8)})`,
186
+ border: `${onScreen(2)} solid ${color}`,
187
+ borderRadius: onScreen(8),
186
188
  }}
187
189
  >
188
190
  <span
189
191
  className="absolute right-0 top-0 whitespace-nowrap rounded px-1.5 text-[10px] leading-4 text-white"
190
- style={{ backgroundColor: color, transform: `translateY(-100%) scale(${scale})`, transformOrigin: 'bottom right' }}
192
+ style={{
193
+ backgroundColor: color,
194
+ transform: `translateY(-100%) scale(var(${COUNTER_SCALE}, 1))`,
195
+ transformOrigin: 'bottom right',
196
+ }}
191
197
  >
192
198
  {name}
193
199
  </span>
@@ -253,6 +259,7 @@ export const AgentActivity = memo(function AgentActivity({
253
259
  const working = people.filter((peer) => peer.clientId !== clientId && peer.agent && peer.pointer);
254
260
  const camera = useFollowCamera({
255
261
  enabled: following && enabled,
262
+ fitsContent: enabled,
256
263
  agentsWorking: working.length > 0,
257
264
  getAgents: () => (store?.getPeers() ?? []).filter((peer: Peer) => peer.clientId !== clientId && peer.agent && peer.pointer),
258
265
  });