@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
@@ -1,13 +1,104 @@
1
- import { useEffect, useState } from 'react';
2
- import { Bot, Check, Copy, Globe, Link2, Mail, Pencil, X } from 'lucide-react';
1
+ import { useEffect, useState, type ReactNode } from 'react';
2
+ import {
3
+ ArrowLeft,
4
+ Bot,
5
+ Check,
6
+ Copy,
7
+ Globe,
8
+ Link2,
9
+ Mail,
10
+ MessageSquareText,
11
+ Pencil,
12
+ Plug,
13
+ UserPlus,
14
+ Users,
15
+ X,
16
+ } from 'lucide-react';
3
17
  import { usePeople, type Peer, type PresenceStore } from '../hooks/presence-store';
4
- import Picture from './Picture';
18
+ import { Picture, AgentMark } from '@eventcatalog/visualiser/studio';
5
19
 
6
20
  /**
7
- * Sharing a canvas, like Miro's and Excalidraw's share dialogs: the link to invite people with (copied, emailed
8
- * or as a ready-made message), who can join, who's on it now (jump to what they're looking at), your own name,
9
- * and bringing an AI agent in.
21
+ * Sharing a canvas, as Studio on the web does: first the ways to share, side by side (a link to it, working on it
22
+ * together live, pairing with an AI agent), then, for live collaboration, who's on it now (click someone to go to
23
+ * what they're looking at) and the link to invite people with (copied, emailed or as a ready-made message). A canvas
24
+ * here is always live and kept in the catalog: its link is the invite, so there's no session to start.
10
25
  */
26
+
27
+ const button =
28
+ 'inline-flex h-9 flex-none items-center gap-2 rounded-lg px-4 text-sm font-medium transition-colors [&_svg]:h-4 [&_svg]:w-4';
29
+ const primary = `${button} bg-[rgb(var(--ec-page-text))] text-[rgb(var(--ec-page-bg))] hover:bg-[rgb(var(--ec-page-text)/0.85)]`;
30
+ const secondary = `${button} border border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text))] hover:bg-[rgb(var(--ec-content-hover))]`;
31
+ const sectionLabel = 'text-[11px] font-semibold uppercase tracking-wide text-[rgb(var(--ec-page-text-muted))]';
32
+
33
+ /** e.g. catalog.example.com/studio/9b1d… */
34
+ function shortened(url: string) {
35
+ try {
36
+ const { host, pathname } = new URL(url);
37
+ return `${host}${pathname}`;
38
+ } catch {
39
+ return url;
40
+ }
41
+ }
42
+
43
+ const copyText = async (text: string) => {
44
+ try {
45
+ await navigator.clipboard.writeText(text);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ };
51
+
52
+ /** One of the ways to share, as a card: what it is, what it gives them, and what to do */
53
+ function Choice({
54
+ icon,
55
+ title,
56
+ description,
57
+ points,
58
+ children,
59
+ }: {
60
+ icon: ReactNode;
61
+ title: string;
62
+ description: string;
63
+ points: string[];
64
+ children: ReactNode;
65
+ }) {
66
+ return (
67
+ <section className="flex flex-col rounded-xl border border-[rgb(var(--ec-page-border))] p-5 text-left transition-colors hover:border-[color-mix(in_srgb,rgb(var(--ec-accent))_45%,rgb(var(--ec-page-border)))]">
68
+ <span className="flex h-9 w-9 items-center justify-center rounded-lg bg-[color-mix(in_srgb,rgb(var(--ec-accent))_12%,transparent)] text-[rgb(var(--ec-accent))] [&_svg]:h-[18px] [&_svg]:w-[18px]">
69
+ {icon}
70
+ </span>
71
+ <h3 className="mt-4 text-sm font-semibold text-[rgb(var(--ec-page-text))]">{title}</h3>
72
+ <p className="mt-1 text-[13px] leading-relaxed text-[rgb(var(--ec-page-text-muted))]">{description}</p>
73
+ <ul className="mt-4 space-y-2">
74
+ {points.map((point) => (
75
+ <li key={point} className="flex items-start gap-2 text-xs leading-snug text-[rgb(var(--ec-page-text-muted))]">
76
+ <Check aria-hidden className="mt-px h-3.5 w-3.5 flex-none text-emerald-500" />
77
+ {point}
78
+ </li>
79
+ ))}
80
+ </ul>
81
+ <div className="mt-auto pt-6">{children}</div>
82
+ </section>
83
+ );
84
+ }
85
+
86
+ /** Copies some text, saying it did (or that it couldn't) */
87
+ function CopyButton({ text, label, icon, className }: { text: string; label: string; icon: ReactNode; className: string }) {
88
+ const [copied, setCopied] = useState<boolean | null>(null);
89
+ useEffect(() => {
90
+ if (copied === null) return;
91
+ const timer = setTimeout(() => setCopied(null), 1500);
92
+ return () => clearTimeout(timer);
93
+ }, [copied]);
94
+ return (
95
+ <button type="button" onClick={async () => setCopied(await copyText(text))} className={className}>
96
+ {copied ? <Check aria-hidden /> : icon}
97
+ {copied ? 'Copied' : copied === false ? "Couldn't copy" : label}
98
+ </button>
99
+ );
100
+ }
101
+
11
102
  export default function ShareDialog({
12
103
  url,
13
104
  title,
@@ -18,7 +109,10 @@ export default function ShareDialog({
18
109
  onJumpTo,
19
110
  onConnectAgent,
20
111
  onClose,
112
+ initialView = 'choose',
21
113
  }: {
114
+ /** Straight to live collaboration (who's here, and the invite), e.g. from the menu */
115
+ initialView?: 'choose' | 'invite';
22
116
  url: string;
23
117
  title?: string;
24
118
  /** Canvases are lost when the server restarts */
@@ -37,6 +131,10 @@ export default function ShareDialog({
37
131
  const name = title || 'this canvas';
38
132
  const invite = `I'm designing ${title ? `"${title}"` : 'an architecture'} in EventCatalog Studio. Join me, we can work on it together live: ${url}`;
39
133
  const email = `mailto:?subject=${encodeURIComponent(`Join me on ${name} in EventCatalog Studio`)}&body=${encodeURIComponent(invite)}`;
134
+ // The ways to share first; live collaboration opens who's here and the invite
135
+ const [view, setView] = useState<'choose' | 'invite'>(initialView);
136
+ const choosing = view === 'choose';
137
+ const wide = 'w-full justify-center';
40
138
 
41
139
  useEffect(() => {
42
140
  const onKeyDown = (event: KeyboardEvent) => event.key === 'Escape' && onClose();
@@ -45,125 +143,182 @@ export default function ShareDialog({
45
143
  }, [onClose]);
46
144
 
47
145
  return (
48
- <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4" onClick={onClose}>
146
+ <div className="fixed inset-0 z-[80] flex items-center justify-center bg-black/40 p-4" onClick={onClose}>
49
147
  <div
50
148
  role="dialog"
51
- aria-label="Share canvas"
149
+ aria-modal="true"
150
+ aria-labelledby="share-canvas-title"
52
151
  onClick={(event) => event.stopPropagation()}
53
- className="w-full max-w-md rounded-xl border shadow-2xl bg-[rgb(var(--ec-card-bg))] border-[rgb(var(--ec-page-border))] text-[rgb(var(--ec-page-text))]"
152
+ className={`w-full ${choosing ? 'max-w-4xl' : 'max-w-lg'} rounded-xl border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] shadow-2xl`}
54
153
  >
55
- <header className="flex items-start justify-between gap-3 border-b px-5 py-4 border-[rgb(var(--ec-page-border))]">
56
- <div className="min-w-0">
57
- <h2 className="truncate text-base font-semibold">Share {title ? `"${title}"` : 'this canvas'}</h2>
58
- <p className="mt-0.5 text-xs text-[rgb(var(--ec-page-text-muted))]">
59
- Invite your team to design with you. Everyone with the link joins live: you'll see each other's pointers and changes
60
- as they happen.
61
- </p>
154
+ <div className="flex items-start justify-between gap-3 px-6 pt-5">
155
+ <div className="flex min-w-0 items-start gap-2">
156
+ {!choosing && (
157
+ <button
158
+ type="button"
159
+ aria-label="Back to the ways to share"
160
+ onClick={() => setView('choose')}
161
+ className="-ml-1.5 mt-0.5 rounded-md p-1 text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))]"
162
+ >
163
+ <ArrowLeft aria-hidden className="h-4 w-4" />
164
+ </button>
165
+ )}
166
+ <div className="min-w-0">
167
+ <h2 id="share-canvas-title" className="truncate text-base font-semibold">
168
+ {choosing ? 'Share' : 'Live collaboration'}
169
+ </h2>
170
+ <p className="mt-1 text-sm text-[rgb(var(--ec-page-text-muted))]">
171
+ {choosing
172
+ ? `Choose how to work on ${title ? `"${title}"` : 'this canvas'} with others.`
173
+ : "Everyone with the link joins live: you see each other's pointers and changes as they happen."}
174
+ </p>
175
+ </div>
62
176
  </div>
63
177
  <button
64
- onClick={onClose}
178
+ type="button"
65
179
  aria-label="Close"
66
- className="shrink-0 rounded-md p-1 text-[rgb(var(--ec-icon-color))] hover:bg-[rgb(var(--ec-page-border)/0.5)] hover:text-[rgb(var(--ec-icon-hover))]"
180
+ onClick={onClose}
181
+ className="-mr-1 rounded-md p-1.5 text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))]"
67
182
  >
68
- <X size={16} />
183
+ <X aria-hidden className="h-4 w-4" />
69
184
  </button>
70
- </header>
185
+ </div>
71
186
 
72
- <div className="space-y-5 px-5 py-4">
73
- <section className="space-y-2">
74
- <h3 className="text-xs font-semibold">Invite link</h3>
75
- <div className="flex items-center gap-2">
76
- <div className="flex min-w-0 flex-1 items-center gap-2 rounded-lg border px-2.5 py-1.5 bg-[rgb(var(--ec-input-bg))] border-[rgb(var(--ec-input-border))]">
77
- <Link2 size={14} className="shrink-0 text-[rgb(var(--ec-icon-color))]" />
78
- <input
79
- readOnly
80
- value={url}
81
- onFocus={(event) => event.currentTarget.select()}
82
- aria-label="Canvas link"
83
- className="min-w-0 flex-1 bg-transparent text-xs text-[rgb(var(--ec-input-text))] focus:outline-none"
84
- />
85
- </div>
86
- <CopyButton text={url} label="Copy link" primary />
87
- </div>
88
- <div className="flex flex-wrap gap-2">
89
- <a
90
- href={email}
91
- className="flex items-center gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs font-medium border-[rgb(var(--ec-page-border))] hover:bg-[rgb(var(--ec-page-border)/0.4)]"
187
+ {choosing ? (
188
+ <div className="grid gap-4 px-6 pb-6 pt-5 md:grid-cols-3">
189
+ <Choice
190
+ icon={<Link2 aria-hidden />}
191
+ title="Share a link"
192
+ description="A link to this canvas, in your catalog."
193
+ points={[
194
+ 'Teammates open it in EventCatalog',
195
+ 'Paste it to your AI agent to build on',
196
+ keptInMemory ? "Kept in this EventCatalog's memory, until it restarts" : 'Kept in your catalog',
197
+ ]}
198
+ >
199
+ <CopyButton text={url} label="Copy link" icon={<Link2 aria-hidden />} className={`${secondary} ${wide}`} />
200
+ </Choice>
201
+
202
+ <Choice
203
+ icon={<Users aria-hidden />}
204
+ title="Live collaboration"
205
+ description="Work on this canvas together, in real time."
206
+ points={[
207
+ "See each other's pointers and edits",
208
+ 'Comment and talk it through',
209
+ `${people.length} ${people.length === 1 ? 'person' : 'people'} here now`,
210
+ ]}
211
+ >
212
+ <button type="button" onClick={() => setView('invite')} className={`${primary} ${wide}`}>
213
+ <UserPlus aria-hidden /> Invite people
214
+ </button>
215
+ </Choice>
216
+
217
+ <Choice
218
+ icon={<Bot aria-hidden />}
219
+ title="Pair with your AI agent"
220
+ description="Sketch ideas with your agent, or have it explain how something works."
221
+ points={['Draws and edits the canvas with you', 'Claude, ChatGPT, Cursor and more']}
222
+ >
223
+ <button
224
+ type="button"
225
+ onClick={() => {
226
+ onClose();
227
+ onConnectAgent();
228
+ }}
229
+ className={`${secondary} ${wide}`}
92
230
  >
93
- <Mail size={14} />
94
- Email an invite
95
- </a>
96
- <CopyButton text={invite} label="Copy invite message" />
97
- </div>
98
- <p className="flex items-start gap-1.5 pt-1 text-[11px] text-[rgb(var(--ec-page-text-muted))]">
99
- <Globe size={13} className="mt-px shrink-0" />
100
- Anyone with the link can view and edit.
101
- {keptInMemory && " Canvases are kept in this EventCatalog's memory, so they're lost when it restarts."}
102
- </p>
103
- </section>
231
+ <Plug aria-hidden /> Connect agent
232
+ </button>
233
+ </Choice>
234
+ </div>
235
+ ) : (
236
+ <>
237
+ <div className="space-y-5 px-6 pb-5 pt-4">
238
+ {/* Who's here */}
239
+ <section>
240
+ <div className="flex items-center justify-between">
241
+ <h3 className={sectionLabel}>On this canvas</h3>
242
+ <span className="inline-flex items-center gap-1.5 text-xs text-[rgb(var(--ec-page-text-muted))]">
243
+ <span className="h-2 w-2 rounded-full bg-emerald-500" /> {people.length}{' '}
244
+ {people.length === 1 ? 'person' : 'people'} here
245
+ </span>
246
+ </div>
247
+ <ul className="mt-2 flex max-h-40 flex-wrap gap-2 overflow-y-auto">
248
+ {you && <YouChip peer={you} onRename={onRename} />}
249
+ {others.map((peer) => (
250
+ <li key={peer.clientId}>
251
+ <button
252
+ type="button"
253
+ title={`Go to what ${peer.name} is looking at${peer.activity ? ` (${peer.activity})` : ''}`}
254
+ onClick={() => {
255
+ onJumpTo(peer);
256
+ onClose();
257
+ }}
258
+ className="inline-flex items-center gap-2 rounded-full border border-[rgb(var(--ec-page-border))] py-1 pl-1 pr-3 text-sm hover:border-[rgb(var(--ec-accent))]"
259
+ >
260
+ <Avatar peer={peer} />
261
+ {peer.name}
262
+ {peer.agent && (
263
+ <span className="rounded px-1 py-px text-[10px] font-medium bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))]">
264
+ AI agent
265
+ </span>
266
+ )}
267
+ </button>
268
+ </li>
269
+ ))}
270
+ </ul>
271
+ {others.length === 0 && (
272
+ <p className="mt-2 text-xs text-[rgb(var(--ec-page-text-muted))]">
273
+ Just you so far. Send the link to bring people in.
274
+ </p>
275
+ )}
276
+ </section>
104
277
 
105
- <section className="space-y-2">
106
- <h3 className="text-xs font-semibold">On this canvas now ({people.length})</h3>
107
- <ul className="max-h-48 space-y-1 overflow-y-auto">
108
- {you && <YouRow peer={you} onRename={onRename} />}
109
- {others.map((peer) => (
110
- <li key={peer.clientId} className="flex items-center gap-2.5 rounded-lg px-1.5 py-1">
111
- <Avatar peer={peer} />
112
- <div className="min-w-0 flex-1">
113
- <p className="truncate text-xs font-medium">
114
- {peer.name}
115
- {peer.agent && (
116
- <span className="ml-1.5 rounded px-1 py-px text-[10px] font-medium bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))]">
117
- AI agent
118
- </span>
119
- )}
120
- </p>
121
- {peer.activity && (
122
- <p className="truncate text-[11px] text-[rgb(var(--ec-page-text-muted))]">{peer.activity}</p>
123
- )}
278
+ {/* Inviting people */}
279
+ <section>
280
+ <h3 className={sectionLabel}>Invite people</h3>
281
+ <p className="mt-1 text-sm text-[rgb(var(--ec-page-text-muted))]">
282
+ Anyone with this link joins and edits this canvas with you.
283
+ </p>
284
+ <div className="mt-2 flex w-full items-center gap-2">
285
+ <div
286
+ title={url}
287
+ className="flex h-9 min-w-0 flex-1 items-center gap-2 rounded-lg border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-content-hover))] px-3 text-sm text-[rgb(var(--ec-page-text-muted))]"
288
+ >
289
+ <Link2 aria-hidden className="h-4 w-4 flex-none" />
290
+ <span className="truncate font-mono text-xs">{shortened(url)}</span>
124
291
  </div>
125
- {peer.viewport && (
126
- <button
127
- onClick={() => {
128
- onJumpTo(peer);
129
- onClose();
130
- }}
131
- className="shrink-0 rounded-md px-2 py-1 text-[11px] font-medium text-[rgb(var(--ec-accent))] hover:bg-[rgb(var(--ec-accent-subtle))]"
132
- >
133
- Go to
134
- </button>
135
- )}
136
- </li>
137
- ))}
138
- {others.length === 0 && (
139
- <li className="px-1.5 py-1 text-xs text-[rgb(var(--ec-page-text-muted))]">
140
- Just you so far. Send the link to bring people in.
141
- </li>
142
- )}
143
- </ul>
144
- </section>
292
+ <CopyButton text={url} label="Copy invite" icon={<Copy aria-hidden />} className={primary} />
293
+ </div>
294
+ <div className="mt-2 flex flex-wrap gap-2">
295
+ <a href={email} className={`${secondary} h-8 px-3 text-xs`}>
296
+ <Mail aria-hidden /> Email an invite
297
+ </a>
298
+ <CopyButton
299
+ text={invite}
300
+ label="Copy invite message"
301
+ icon={<MessageSquareText aria-hidden />}
302
+ className={`${secondary} h-8 px-3 text-xs`}
303
+ />
304
+ </div>
305
+ </section>
306
+ </div>
145
307
 
146
- <section className="flex items-center gap-3 rounded-lg border p-3 border-[rgb(var(--ec-page-border))]">
147
- <span className="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-[rgb(var(--ec-accent-subtle))] text-[rgb(var(--ec-accent))]">
148
- <Bot size={16} />
149
- </span>
150
- <div className="min-w-0 flex-1">
151
- <p className="text-xs font-semibold">Bring in an AI agent</p>
152
- <p className="text-[11px] text-[rgb(var(--ec-page-text-muted))]">
153
- Claude, ChatGPT or another agent can join and design with you, with its own pointer.
308
+ <div className="flex items-center justify-between gap-3 border-t border-[rgb(var(--ec-page-border))] px-6 py-3">
309
+ <p className="flex items-start gap-1.5 text-[11px] text-[rgb(var(--ec-page-text-muted))]">
310
+ <Globe aria-hidden className="mt-px h-3 w-3 flex-none" />
311
+ <span>
312
+ Anyone with the link can view and edit.
313
+ {keptInMemory && " Canvases are kept in this EventCatalog's memory, so they're lost when it restarts."}
314
+ </span>
154
315
  </p>
316
+ <button type="button" onClick={onClose} className={secondary}>
317
+ Done
318
+ </button>
155
319
  </div>
156
- <button
157
- onClick={() => {
158
- onClose();
159
- onConnectAgent();
160
- }}
161
- className="shrink-0 rounded-lg border px-2.5 py-1.5 text-xs font-medium border-[rgb(var(--ec-page-border))] hover:bg-[rgb(var(--ec-page-border)/0.4)]"
162
- >
163
- Connect agent
164
- </button>
165
- </section>
166
- </div>
320
+ </>
321
+ )}
167
322
  </div>
168
323
  </div>
169
324
  );
@@ -180,17 +335,17 @@ const initials = (name: string) =>
180
335
  function Avatar({ peer }: { peer: Peer }) {
181
336
  return (
182
337
  <span
183
- className="relative flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-[11px] font-semibold text-white"
338
+ className="relative flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[10px] font-semibold text-white"
184
339
  style={{ backgroundColor: peer.color }}
185
340
  >
186
- {peer.agent ? <Bot size={14} /> : initials(peer.name)}
341
+ {peer.agent ? <AgentMark name={peer.name} size={12} /> : initials(peer.name)}
187
342
  <Picture src={peer.picture} />
188
343
  </span>
189
344
  );
190
345
  }
191
346
 
192
347
  /** You, with your name (the name others see you by, which you can change unless you're signed in) */
193
- function YouRow({ peer, onRename }: { peer: Peer; onRename?: (name: string) => void }) {
348
+ function YouChip({ peer, onRename }: { peer: Peer; onRename?: (name: string) => void }) {
194
349
  const [editing, setEditing] = useState(false);
195
350
  const [draft, setDraft] = useState(peer.name);
196
351
  const save = () => {
@@ -199,7 +354,7 @@ function YouRow({ peer, onRename }: { peer: Peer; onRename?: (name: string) => v
199
354
  setEditing(false);
200
355
  };
201
356
  return (
202
- <li className="flex items-center gap-2.5 rounded-lg px-1.5 py-1">
357
+ <li className="inline-flex items-center gap-2 rounded-full border border-[rgb(var(--ec-page-border))] py-1 pl-1 pr-2 text-sm">
203
358
  <Avatar peer={peer} />
204
359
  {editing ? (
205
360
  <input
@@ -215,46 +370,27 @@ function YouRow({ peer, onRename }: { peer: Peer; onRename?: (name: string) => v
215
370
  }
216
371
  }}
217
372
  aria-label="Your name"
218
- className="min-w-0 flex-1 rounded-md border px-2 py-1 text-xs bg-[rgb(var(--ec-input-bg))] border-[rgb(var(--ec-input-border))] text-[rgb(var(--ec-input-text))]"
373
+ className="w-36 rounded-md border px-2 py-0.5 text-xs bg-[rgb(var(--ec-input-bg))] border-[rgb(var(--ec-input-border))] text-[rgb(var(--ec-input-text))]"
219
374
  />
220
375
  ) : (
221
- <p className="min-w-0 flex-1 truncate text-xs font-medium">
222
- {peer.name} <span className="font-normal text-[rgb(var(--ec-page-text-muted))]">(you)</span>
223
- </p>
376
+ <>
377
+ {peer.name} <span className="text-xs text-[rgb(var(--ec-page-text-muted))]">(you)</span>
378
+ </>
224
379
  )}
225
380
  {!editing && onRename && (
226
381
  <button
382
+ type="button"
383
+ aria-label="Change your name"
384
+ title="Change the name others see you by"
227
385
  onClick={() => {
228
386
  setDraft(peer.name);
229
387
  setEditing(true);
230
388
  }}
231
- className="flex shrink-0 items-center gap-1 rounded-md px-2 py-1 text-[11px] font-medium text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-page-border)/0.5)]"
389
+ className="rounded-full p-1 text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))]"
232
390
  >
233
- <Pencil size={11} />
234
- Rename
391
+ <Pencil aria-hidden className="h-3 w-3" />
235
392
  </button>
236
393
  )}
237
394
  </li>
238
395
  );
239
396
  }
240
-
241
- function CopyButton({ text, label, primary = false }: { text: string; label: string; primary?: boolean }) {
242
- const [copied, setCopied] = useState(false);
243
- return (
244
- <button
245
- onClick={async () => {
246
- await navigator.clipboard.writeText(text);
247
- setCopied(true);
248
- setTimeout(() => setCopied(false), 1500);
249
- }}
250
- className={`flex shrink-0 items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-xs font-medium ${
251
- primary
252
- ? 'bg-[rgb(var(--ec-button-bg))] text-[rgb(var(--ec-button-text))] hover:bg-[rgb(var(--ec-button-bg-hover))]'
253
- : 'border border-[rgb(var(--ec-page-border))] hover:bg-[rgb(var(--ec-page-border)/0.4)]'
254
- }`}
255
- >
256
- {copied ? <Check size={14} /> : <Copy size={14} />}
257
- {copied ? 'Copied' : label}
258
- </button>
259
- );
260
- }
@@ -0,0 +1,41 @@
1
+ import { useEffect } from 'react';
2
+ import { X } from 'lucide-react';
3
+ import { ShortcutsList } from '@eventcatalog/visualiser/studio';
4
+
5
+ /** What Studio here doesn't have of the shortcuts Studio on the web lists */
6
+ const NOT_HERE = ['Command palette', 'Find on canvas'];
7
+
8
+ /** Help: the keyboard shortcuts, as Studio on the web lists them */
9
+ export default function ShortcutsDialog({ onClose }: { onClose: () => void }) {
10
+ useEffect(() => {
11
+ const onKeyDown = (event: KeyboardEvent) => event.key === 'Escape' && onClose();
12
+ window.addEventListener('keydown', onKeyDown);
13
+ return () => window.removeEventListener('keydown', onKeyDown);
14
+ }, [onClose]);
15
+ return (
16
+ <div className="fixed inset-0 z-[80] flex items-center justify-center bg-black/40 p-4" onClick={onClose}>
17
+ <div
18
+ role="dialog"
19
+ aria-modal="true"
20
+ aria-labelledby="shortcuts-title"
21
+ onClick={(event) => event.stopPropagation()}
22
+ className="flex max-h-[calc(100vh-2rem)] w-full max-w-3xl flex-col rounded-xl border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-card-bg))] text-[rgb(var(--ec-page-text))] shadow-2xl"
23
+ >
24
+ <div className="flex flex-none items-center justify-between border-b border-[rgb(var(--ec-page-border))] px-5 py-4">
25
+ <h2 id="shortcuts-title" className="text-base font-semibold">
26
+ Keyboard shortcuts
27
+ </h2>
28
+ <button
29
+ type="button"
30
+ aria-label="Close"
31
+ onClick={onClose}
32
+ className="rounded-md p-1.5 text-[rgb(var(--ec-page-text-muted))] hover:bg-[rgb(var(--ec-content-hover))] hover:text-[rgb(var(--ec-page-text))]"
33
+ >
34
+ <X aria-hidden className="h-4 w-4" />
35
+ </button>
36
+ </div>
37
+ <ShortcutsList omit={NOT_HERE} />
38
+ </div>
39
+ </div>
40
+ );
41
+ }