@agent-native/core 0.80.4 → 0.80.5

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 (292) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -2
  3. package/corpus/core/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  4. package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -1
  5. package/corpus/core/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  6. package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -1
  7. package/corpus/core/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  8. package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -1
  9. package/corpus/core/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  10. package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -1
  11. package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -1
  12. package/corpus/core/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  13. package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -1
  14. package/corpus/core/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  15. package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -1
  16. package/corpus/core/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  17. package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -1
  18. package/corpus/core/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  19. package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -1
  20. package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  21. package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -1
  22. package/corpus/core/docs/content/real-time-collaboration.mdx +2 -2
  23. package/corpus/core/docs/content/template-design.mdx +1 -1
  24. package/corpus/core/package.json +3 -7
  25. package/corpus/core/src/action.ts +21 -0
  26. package/corpus/core/src/agent/durable-background.ts +32 -11
  27. package/corpus/core/src/agent/production-agent.ts +11 -1
  28. package/corpus/core/src/agent/run-loop-with-resume.ts +3 -1
  29. package/corpus/core/src/brand-kit/fig/index.ts +17 -37
  30. package/corpus/core/src/cli/index.ts +1 -1
  31. package/corpus/core/src/cli/mcp-config-writers.ts +187 -51
  32. package/corpus/core/src/cli/skills.ts +18 -3
  33. package/corpus/core/src/client/AssistantChat.tsx +11 -1
  34. package/corpus/core/src/client/agent-chat.ts +12 -1
  35. package/corpus/core/src/client/composer/PromptComposer.tsx +100 -41
  36. package/corpus/core/src/client/org/OrgSwitcher.tsx +1 -1
  37. package/corpus/core/src/client/sharing/ShareButton.tsx +3 -27
  38. package/corpus/core/src/collab/presence.ts +1 -1
  39. package/corpus/core/src/mcp/connect-route.ts +34 -5
  40. package/corpus/core/src/server/action-discovery.ts +4 -0
  41. package/corpus/core/src/server/agent-chat-plugin.ts +20 -0
  42. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -0
  43. package/corpus/templates/analytics/actions/update-dashboard.ts +8 -0
  44. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
  45. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +117 -33
  46. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
  47. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +7 -0
  48. package/corpus/templates/analytics/changelog/2026-06-27-dashboards-can-now-nest-under-a-parent-in-the-sidebar-via-a-.md +6 -0
  49. package/corpus/templates/analytics/changelog/2026-06-29-analytics-pages-now-sit-closer-under-the-header-with-tighter.md +6 -0
  50. package/corpus/templates/assets/actions/generate-image-batch.ts +3 -0
  51. package/corpus/templates/assets/actions/generate-image.ts +3 -0
  52. package/corpus/templates/assets/changelog/2026-06-29-longer-agent-generation-window.md +6 -0
  53. package/corpus/templates/assets/netlify.toml +3 -3
  54. package/corpus/templates/assets/server/plugins/agent-chat.ts +4 -1
  55. package/corpus/templates/clips/app/components/capture-install-options.tsx +7 -8
  56. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +1 -1
  57. package/corpus/templates/content/AGENTS.md +12 -0
  58. package/corpus/templates/content/app/blocks/BuilderDocsBlocks.tsx +10 -0
  59. package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -0
  60. package/corpus/templates/content/app/components/editor/ContentReferencePreview.tsx +185 -0
  61. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
  62. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
  63. package/corpus/templates/content/app/components/editor/extensions/ContentReferenceNode.tsx +82 -0
  64. package/corpus/templates/content/app/global.css +9 -0
  65. package/corpus/templates/content/app/i18n/zh-TW.ts +12 -0
  66. package/corpus/templates/content/app/i18n-data.ts +140 -0
  67. package/corpus/templates/content/changelog/2026-06-29-reusable-mdx-references-now-preview-linked-local-documents-i.md +6 -0
  68. package/corpus/templates/content/shared/builder-docs-blocks.ts +8 -0
  69. package/corpus/templates/content/shared/builder-mdx.ts +141 -4
  70. package/corpus/templates/content/shared/nfm.ts +62 -0
  71. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +10 -11
  72. package/corpus/templates/design/AGENTS.md +5 -0
  73. package/corpus/templates/design/_gitignore +7 -0
  74. package/corpus/templates/design/actions/apply-visual-edit.ts +22 -12
  75. package/corpus/templates/design/actions/create-design-system.ts +15 -4
  76. package/corpus/templates/design/actions/create-file.ts +20 -1
  77. package/corpus/templates/design/actions/delete-design-system.ts +2 -2
  78. package/corpus/templates/design/actions/duplicate-design.ts +35 -9
  79. package/corpus/templates/design/actions/generate-design.ts +146 -69
  80. package/corpus/templates/design/actions/generate-screens.ts +51 -19
  81. package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
  82. package/corpus/templates/design/actions/get-design.ts +2 -0
  83. package/corpus/templates/design/actions/import-design-project.ts +28 -9
  84. package/corpus/templates/design/actions/import-document.ts +22 -8
  85. package/corpus/templates/design/actions/index-design-system-with-builder.ts +6 -153
  86. package/corpus/templates/design/actions/navigate.ts +105 -54
  87. package/corpus/templates/design/actions/set-default-design-system.ts +17 -3
  88. package/corpus/templates/design/actions/show-design-questions.ts +2 -0
  89. package/corpus/templates/design/actions/update-design.ts +2 -1
  90. package/corpus/templates/design/actions/view-screen.ts +12 -6
  91. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +4 -4
  92. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +159 -41
  93. package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +8 -4
  94. package/corpus/templates/design/app/components/design/DrawOverlay.tsx +37 -42
  95. package/corpus/templates/design/app/components/design/EditPanel.tsx +336 -183
  96. package/corpus/templates/design/app/components/design/LayersPanel.tsx +153 -34
  97. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +135 -33
  98. package/corpus/templates/design/app/components/design/QuestionFlow.tsx +6 -0
  99. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
  100. package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +4 -10
  101. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +84 -43
  102. package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +4 -4
  103. package/corpus/templates/design/app/components/design/inspector/{FigmaColorPicker.tsx → DesignColorPicker.tsx} +89 -62
  104. package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +14 -26
  105. package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +40 -12
  106. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -4
  107. package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +13 -13
  108. package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -9
  109. package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +13 -4
  110. package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +6 -6
  111. package/corpus/templates/design/app/components/design/inspector/{figma-icons.tsx → design-icons.tsx} +2 -2
  112. package/corpus/templates/design/app/components/design/inspector/index.ts +12 -12
  113. package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +5 -2
  114. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -3
  115. package/corpus/templates/design/app/components/layout/Layout.tsx +5 -2
  116. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  117. package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +167 -91
  118. package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +16 -3
  119. package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +15 -0
  120. package/corpus/templates/design/app/global.css +4 -0
  121. package/corpus/templates/design/app/hooks/use-design-system.ts +4 -1
  122. package/corpus/templates/design/app/hooks/use-navigation-state.ts +38 -3
  123. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +9 -2
  124. package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
  125. package/corpus/templates/design/app/i18n-data.ts +527 -0
  126. package/corpus/templates/design/app/lib/design-systems.ts +6 -4
  127. package/corpus/templates/design/app/lib/design-templates.ts +15 -3
  128. package/corpus/templates/design/app/pages/DesignEditor.tsx +641 -158
  129. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +42 -34
  130. package/corpus/templates/design/app/pages/VisualEdit.tsx +100 -0
  131. package/corpus/templates/design/app/root.tsx +42 -9
  132. package/corpus/templates/design/app/routes/visual-edit.tsx +7 -0
  133. package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +1 -1
  134. package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +1 -1
  135. package/corpus/templates/design/changelog/2026-06-28-visual-code-design-mode.md +6 -0
  136. package/corpus/templates/design/changelog/2026-06-29-design-generation-prompts-now-show-connect-ai-before-sending.md +6 -0
  137. package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +1 -1
  138. package/corpus/templates/design/changelog/2026-06-29-fixed-design-editor-exports-and-gradient-edits-so-multi-scre.md +6 -0
  139. package/corpus/templates/design/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  140. package/corpus/templates/design/changelog/2026-06-29-png-export-handles-modern-css-color-functions-more-reliably.md +6 -0
  141. package/corpus/templates/design/changelog/2026-06-29-png-export-now-ignores-duplicate-clicks-while-a-download-is-.md +6 -0
  142. package/corpus/templates/design/changelog/2026-06-29-public-visual-edit-and-shared-design-links-now-invite-visito.md +6 -0
  143. package/corpus/templates/design/changelog/2026-06-29-visual-edit-actions-now-reject-missing-design-targets-before.md +6 -0
  144. package/corpus/templates/design/e2e/README.md +71 -0
  145. package/corpus/templates/design/e2e/global-setup.ts +157 -0
  146. package/corpus/templates/design/e2e/helpers.ts +148 -0
  147. package/corpus/templates/design/netlify.toml +3 -4
  148. package/corpus/templates/design/package.json +5 -1
  149. package/corpus/templates/design/playwright.config.ts +51 -0
  150. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +121 -0
  151. package/corpus/templates/design/server/handlers/uploads.ts +89 -38
  152. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +181 -0
  153. package/corpus/templates/design/server/lib/coding-handoff.ts +33 -4
  154. package/corpus/templates/design/server/lib/design-export.ts +35 -8
  155. package/corpus/templates/design/server/plugins/agent-chat.ts +4 -0
  156. package/corpus/templates/design/server/plugins/auth.ts +10 -1
  157. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  158. package/corpus/templates/design/shared/api.ts +2 -0
  159. package/corpus/templates/design/shared/apply-edits.ts +12 -8
  160. package/corpus/templates/design/shared/canvas-math.ts +19 -1
  161. package/corpus/templates/design/shared/code-layer.ts +87 -28
  162. package/corpus/templates/design/shared/generation-session.ts +1 -0
  163. package/corpus/templates/design/shared/resolve-tweaks.ts +4 -3
  164. package/corpus/templates/design/shared/shader-presets.ts +10 -0
  165. package/corpus/templates/design/shared/source-mode.ts +9 -0
  166. package/corpus/templates/design/vitest.config.ts +2 -1
  167. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
  168. package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +1 -1
  169. package/corpus/templates/plan/AGENTS.md +1 -1
  170. package/corpus/templates/plan/actions/create-plan-design.ts +1 -1
  171. package/corpus/templates/plan/actions/validate-local-plan-source.ts +2 -10
  172. package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -0
  173. package/corpus/templates/plan/docs/commenting-ux-plan.md +2 -2
  174. package/corpus/templates/plan/server/plan-content.ts +1 -1
  175. package/corpus/templates/plan/server/ui-plan-html.ts +2 -2
  176. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +6 -153
  177. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +53 -38
  178. package/corpus/templates/slides/app/components/design-system/{fig-import-response.ts → builder-index-response.ts} +9 -6
  179. package/corpus/templates/slides/app/components/visual-editor/MultiSelectChip.tsx +1 -1
  180. package/corpus/templates/slides/changelog/2026-06-29-design-system-setup-now-indexes-uploaded-design-files-throug.md +6 -0
  181. package/corpus/templates/slides/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
  182. package/corpus/templates/slides/netlify.toml +3 -6
  183. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +116 -0
  184. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +179 -0
  185. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -1
  186. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +1 -0
  187. package/dist/action.d.ts +15 -0
  188. package/dist/action.d.ts.map +1 -1
  189. package/dist/action.js +6 -0
  190. package/dist/action.js.map +1 -1
  191. package/dist/agent/durable-background.d.ts +9 -7
  192. package/dist/agent/durable-background.d.ts.map +1 -1
  193. package/dist/agent/durable-background.js +27 -11
  194. package/dist/agent/durable-background.js.map +1 -1
  195. package/dist/agent/production-agent.d.ts +7 -0
  196. package/dist/agent/production-agent.d.ts.map +1 -1
  197. package/dist/agent/production-agent.js +4 -1
  198. package/dist/agent/production-agent.js.map +1 -1
  199. package/dist/agent/run-loop-with-resume.d.ts +2 -1
  200. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  201. package/dist/agent/run-loop-with-resume.js +2 -2
  202. package/dist/agent/run-loop-with-resume.js.map +1 -1
  203. package/dist/brand-kit/fig/index.d.ts +4 -4
  204. package/dist/brand-kit/fig/index.d.ts.map +1 -1
  205. package/dist/brand-kit/fig/index.js +14 -27
  206. package/dist/brand-kit/fig/index.js.map +1 -1
  207. package/dist/cli/index.js +1 -1
  208. package/dist/cli/index.js.map +1 -1
  209. package/dist/cli/mcp-config-writers.d.ts +15 -7
  210. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  211. package/dist/cli/mcp-config-writers.js +198 -45
  212. package/dist/cli/mcp-config-writers.js.map +1 -1
  213. package/dist/cli/skills.d.ts +1 -1
  214. package/dist/cli/skills.d.ts.map +1 -1
  215. package/dist/cli/skills.js +18 -3
  216. package/dist/cli/skills.js.map +1 -1
  217. package/dist/client/AssistantChat.d.ts.map +1 -1
  218. package/dist/client/AssistantChat.js +11 -1
  219. package/dist/client/AssistantChat.js.map +1 -1
  220. package/dist/client/agent-chat.d.ts.map +1 -1
  221. package/dist/client/agent-chat.js +15 -2
  222. package/dist/client/agent-chat.js.map +1 -1
  223. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  224. package/dist/client/composer/PromptComposer.js +35 -1
  225. package/dist/client/composer/PromptComposer.js.map +1 -1
  226. package/dist/client/org/OrgSwitcher.js +1 -1
  227. package/dist/client/org/OrgSwitcher.js.map +1 -1
  228. package/dist/client/sharing/ShareButton.d.ts +1 -1
  229. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  230. package/dist/client/sharing/ShareButton.js +2 -15
  231. package/dist/client/sharing/ShareButton.js.map +1 -1
  232. package/dist/collab/presence.d.ts +1 -1
  233. package/dist/collab/presence.js +1 -1
  234. package/dist/collab/presence.js.map +1 -1
  235. package/dist/collab/routes.d.ts +1 -1
  236. package/dist/mcp/connect-route.d.ts.map +1 -1
  237. package/dist/mcp/connect-route.js +34 -5
  238. package/dist/mcp/connect-route.js.map +1 -1
  239. package/dist/notifications/routes.d.ts +3 -3
  240. package/dist/observability/routes.d.ts +3 -3
  241. package/dist/resources/handlers.d.ts +1 -1
  242. package/dist/server/action-discovery.d.ts.map +1 -1
  243. package/dist/server/action-discovery.js +5 -0
  244. package/dist/server/action-discovery.js.map +1 -1
  245. package/dist/server/agent-chat-plugin.d.ts +6 -0
  246. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  247. package/dist/server/agent-chat-plugin.js +12 -3
  248. package/dist/server/agent-chat-plugin.js.map +1 -1
  249. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  250. package/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
  251. package/docs/content/locales/ar-SA/template-design.mdx +1 -1
  252. package/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
  253. package/docs/content/locales/de-DE/template-design.mdx +1 -1
  254. package/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
  255. package/docs/content/locales/es-ES/template-design.mdx +1 -1
  256. package/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
  257. package/docs/content/locales/fr-FR/template-design.mdx +1 -1
  258. package/docs/content/locales/hi-IN/template-design.mdx +1 -1
  259. package/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
  260. package/docs/content/locales/ja-JP/template-design.mdx +1 -1
  261. package/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
  262. package/docs/content/locales/ko-KR/template-design.mdx +1 -1
  263. package/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
  264. package/docs/content/locales/pt-BR/template-design.mdx +1 -1
  265. package/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
  266. package/docs/content/locales/zh-CN/template-design.mdx +1 -1
  267. package/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
  268. package/docs/content/locales/zh-TW/template-design.mdx +1 -1
  269. package/docs/content/real-time-collaboration.mdx +2 -2
  270. package/docs/content/template-design.mdx +1 -1
  271. package/package.json +3 -7
  272. package/corpus/core/src/brand-kit/fig/decode.ts +0 -410
  273. package/corpus/core/src/brand-kit/fig/extract-design-system.ts +0 -947
  274. package/corpus/core/src/brand-kit/fig/fig-to-html.ts +0 -1906
  275. package/corpus/templates/design/actions/import-figma.ts +0 -55
  276. package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +0 -6
  277. package/corpus/templates/design/server/handlers/import-figma-system.ts +0 -86
  278. package/corpus/templates/design/server/routes/api/import-figma-system.post.ts +0 -1
  279. package/corpus/templates/slides/server/handlers/import-figma-system.ts +0 -101
  280. package/corpus/templates/slides/server/routes/api/import-figma-system.post.ts +0 -1
  281. package/dist/brand-kit/fig/decode.d.ts +0 -33
  282. package/dist/brand-kit/fig/decode.d.ts.map +0 -1
  283. package/dist/brand-kit/fig/decode.js +0 -358
  284. package/dist/brand-kit/fig/decode.js.map +0 -1
  285. package/dist/brand-kit/fig/extract-design-system.d.ts +0 -44
  286. package/dist/brand-kit/fig/extract-design-system.d.ts.map +0 -1
  287. package/dist/brand-kit/fig/extract-design-system.js +0 -752
  288. package/dist/brand-kit/fig/extract-design-system.js.map +0 -1
  289. package/dist/brand-kit/fig/fig-to-html.d.ts +0 -246
  290. package/dist/brand-kit/fig/fig-to-html.d.ts.map +0 -1
  291. package/dist/brand-kit/fig/fig-to-html.js +0 -1506
  292. package/dist/brand-kit/fig/fig-to-html.js.map +0 -1
@@ -1,4 +1,9 @@
1
1
  import { defineAction, embedApp } from "@agent-native/core";
2
+ import {
3
+ deleteAppState,
4
+ readAppState,
5
+ writeAppState,
6
+ } from "@agent-native/core/application-state";
2
7
  import {
3
8
  hasCollabState,
4
9
  applyText,
@@ -18,6 +23,10 @@ import {
18
23
  mergeCanvasFramePlacements,
19
24
  type CanvasFramePlacement,
20
25
  } from "../shared/canvas-frames.js";
26
+ import {
27
+ designGenerationSessionKey,
28
+ type DesignGenerationSession,
29
+ } from "../shared/generation-session.js";
21
30
 
22
31
  /** Editor deep link so external agents can surface "Open design". */
23
32
  function designDeepLink(designId: string): string {
@@ -28,6 +37,50 @@ function designDeepLink(designId: string): string {
28
37
  });
29
38
  }
30
39
 
40
+ function isRenderableDesignFile(file: {
41
+ fileType?: string | null;
42
+ content?: string | null;
43
+ }): boolean {
44
+ const fileType = file.fileType ?? "html";
45
+ return (
46
+ (fileType === "html" || fileType === "jsx") && Boolean(file.content?.trim())
47
+ );
48
+ }
49
+
50
+ async function updateGenerationSessionForSavedFiles(
51
+ designId: string,
52
+ savedFilenames: string[],
53
+ ) {
54
+ const key = designGenerationSessionKey(designId);
55
+ const rawSession = await readAppState(key).catch(() => null);
56
+ if (!rawSession || typeof rawSession !== "object") return;
57
+ const session = rawSession as unknown as DesignGenerationSession;
58
+ if (session.designId !== designId || !Array.isArray(session.frames)) return;
59
+
60
+ const saved = new Set(savedFilenames);
61
+ const frames = session.frames.map((frame) =>
62
+ frame.filename && saved.has(frame.filename)
63
+ ? {
64
+ ...frame,
65
+ status: "done" as const,
66
+ step: "Saved",
67
+ progress: 1,
68
+ }
69
+ : frame,
70
+ );
71
+ const allDone = frames.every((frame) => frame.status === "done");
72
+ if (allDone) {
73
+ await deleteAppState(key);
74
+ return;
75
+ }
76
+
77
+ await writeAppState(key, {
78
+ ...session,
79
+ status: "generating",
80
+ frames,
81
+ } as unknown as Record<string, unknown>);
82
+ }
83
+
31
84
  export default defineAction({
32
85
  description:
33
86
  "Save generated design content to a design project. " +
@@ -181,19 +234,6 @@ export default defineAction({
181
234
  }
182
235
  }
183
236
 
184
- const hasRenderableFile = files.some((file) => {
185
- const fileType = file.fileType ?? "html";
186
- return (
187
- (fileType === "html" || fileType === "jsx") &&
188
- file.content.trim().length > 0
189
- );
190
- });
191
- if (!hasRenderableFile) {
192
- throw new Error(
193
- "generate-design requires at least one non-empty HTML or JSX file before the design can be reported as ready",
194
- );
195
- }
196
-
197
237
  const savedFiles: Array<{
198
238
  id: string;
199
239
  filename: string;
@@ -206,6 +246,15 @@ export default defineAction({
206
246
  .from(schema.designFiles)
207
247
  .where(eq(schema.designFiles.designId, designId));
208
248
 
249
+ const hasRenderableFile =
250
+ files.some(isRenderableDesignFile) ||
251
+ existingFiles.some(isRenderableDesignFile);
252
+ if (!hasRenderableFile) {
253
+ throw new Error(
254
+ "generate-design requires at least one non-empty HTML or JSX file before the design can be reported as ready",
255
+ );
256
+ }
257
+
209
258
  const existingByName = new Map(existingFiles.map((f) => [f.filename, f]));
210
259
 
211
260
  for (const file of files) {
@@ -270,6 +319,19 @@ export default defineAction({
270
319
  agentLeaveDocument(fileId);
271
320
  }
272
321
 
322
+ // Update the in-memory map so a second entry with the same filename
323
+ // in the same `files` array hits the UPDATE branch instead of
324
+ // inserting a duplicate row.
325
+ existingByName.set(file.filename, {
326
+ id: fileId,
327
+ designId,
328
+ filename: file.filename,
329
+ fileType: file.fileType ?? "html",
330
+ content: file.content,
331
+ createdAt: now,
332
+ updatedAt: now,
333
+ });
334
+
273
335
  savedFiles.push({
274
336
  id: fileId,
275
337
  filename: file.filename,
@@ -290,31 +352,12 @@ export default defineAction({
290
352
  // Merge with existing data so tweak definitions survive content updates.
291
353
  // The data column is a free-form JSON blob; we own these keys here and
292
354
  // leave anything else intact.
293
- const [existingDesign] = await db
294
- .select({ data: schema.designs.data })
295
- .from(schema.designs)
296
- .where(eq(schema.designs.id, designId));
297
- let prevData: Record<string, unknown> = {};
298
- if (existingDesign?.data) {
299
- try {
300
- const parsed = JSON.parse(existingDesign.data);
301
- if (parsed && typeof parsed === "object") prevData = parsed;
302
- } catch {
303
- // Stale or invalid JSON — start fresh.
304
- }
305
- }
306
- const mergedData: Record<string, unknown> = {
307
- ...prevData,
308
- lastPrompt: prompt,
309
- generatedAt: now,
310
- fileCount: files.length,
311
- };
312
- if (tweaks !== undefined) {
313
- mergedData.tweaks = tweaks.map((tweak) => ({
314
- ...tweak,
315
- type: tweak.type === "color-swatches" ? "color-swatch" : tweak.type,
316
- }));
317
- }
355
+ //
356
+ // Wrapped in a transaction so that concurrent generate-design calls for the
357
+ // same design (e.g. the parallel fan-out from generate-screens) each read
358
+ // the latest canvasFrames and merge their own placement on top, rather than
359
+ // all reading the same stale snapshot and the last writer silently
360
+ // discarding the others' frame coordinates.
318
361
  let placedFrames:
319
362
  | Array<{
320
363
  fileId: string;
@@ -322,39 +365,73 @@ export default defineAction({
322
365
  frame: CanvasFramePlacement;
323
366
  }>
324
367
  | undefined;
325
- if (canvasFrames !== undefined) {
326
- const savedByFileId = new Map(savedFiles.map((file) => [file.id, file]));
327
- const savedByFilename = new Map(
328
- savedFiles.map((file) => [file.filename, file]),
329
- );
330
- const existingByFileId = new Map(
331
- existingFiles.map((file) => [file.id, file]),
332
- );
333
- const merged = mergeCanvasFramePlacements({
334
- existing: prevData.canvasFrames,
335
- placements: canvasFrames,
336
- resolveFileId: (placement) => {
337
- if (placement.fileId) {
338
- return savedByFileId.has(placement.fileId) ||
339
- existingByFileId.has(placement.fileId)
340
- ? placement.fileId
368
+ await db.transaction(async (tx) => {
369
+ const [existingDesign] = await tx
370
+ .select({ data: schema.designs.data })
371
+ .from(schema.designs)
372
+ .where(eq(schema.designs.id, designId));
373
+ let prevData: Record<string, unknown> = {};
374
+ if (existingDesign?.data) {
375
+ try {
376
+ const parsed = JSON.parse(existingDesign.data);
377
+ if (parsed && typeof parsed === "object") prevData = parsed;
378
+ } catch {
379
+ // Stale or invalid JSON — start fresh.
380
+ }
381
+ }
382
+ const mergedData: Record<string, unknown> = {
383
+ ...prevData,
384
+ lastPrompt: prompt,
385
+ generatedAt: now,
386
+ fileCount: files.length,
387
+ };
388
+ if (tweaks !== undefined) {
389
+ mergedData.tweaks = tweaks.map((tweak) => ({
390
+ ...tweak,
391
+ type: tweak.type === "color-swatches" ? "color-swatch" : tweak.type,
392
+ }));
393
+ }
394
+ if (canvasFrames !== undefined) {
395
+ const savedByFileId = new Map(
396
+ savedFiles.map((file) => [file.id, file]),
397
+ );
398
+ const savedByFilename = new Map(
399
+ savedFiles.map((file) => [file.filename, file]),
400
+ );
401
+ const existingByFileId = new Map(
402
+ existingFiles.map((file) => [file.id, file]),
403
+ );
404
+ const merged = mergeCanvasFramePlacements({
405
+ existing: prevData.canvasFrames,
406
+ placements: canvasFrames,
407
+ resolveFileId: (placement) => {
408
+ if (placement.fileId) {
409
+ return savedByFileId.has(placement.fileId) ||
410
+ existingByFileId.has(placement.fileId)
411
+ ? placement.fileId
412
+ : undefined;
413
+ }
414
+ return placement.filename
415
+ ? (savedByFilename.get(placement.filename)?.id ??
416
+ existingByName.get(placement.filename)?.id)
341
417
  : undefined;
342
- }
343
- return placement.filename
344
- ? (savedByFilename.get(placement.filename)?.id ??
345
- existingByName.get(placement.filename)?.id)
346
- : undefined;
347
- },
348
- });
349
- mergedData.canvasFrames = merged.canvasFrames;
350
- placedFrames = merged.placedFrames;
351
- }
352
- designUpdates.data = JSON.stringify(mergedData);
418
+ },
419
+ });
420
+ mergedData.canvasFrames = merged.canvasFrames;
421
+ placedFrames = merged.placedFrames;
422
+ }
423
+ designUpdates.data = JSON.stringify(mergedData);
353
424
 
354
- await db
355
- .update(schema.designs)
356
- .set(designUpdates)
357
- .where(eq(schema.designs.id, designId));
425
+ await tx
426
+ .update(schema.designs)
427
+ .set(designUpdates)
428
+ .where(eq(schema.designs.id, designId));
429
+ });
430
+
431
+ await updateGenerationSessionForSavedFiles(
432
+ designId,
433
+ savedFiles.map((file) => file.filename),
434
+ );
358
435
 
359
436
  return {
360
437
  designId,
@@ -42,16 +42,27 @@ function designDeepLink(designId: string): string {
42
42
  });
43
43
  }
44
44
 
45
- const requestedScreenSchema = z.object({
46
- frameId: z.string().optional(),
47
- title: z.string().min(1),
48
- filename: z
49
- .string()
50
- .optional()
51
- .describe("Target filename for this screen, such as onboarding.html"),
52
- role: z.enum(["screen", "variant"]).optional().default("screen"),
53
- variantOf: z.string().optional(),
54
- });
45
+ const requestedScreenSchema = z
46
+ .object({
47
+ frameId: z.string().optional(),
48
+ title: z.string().min(1),
49
+ filename: z
50
+ .string()
51
+ .optional()
52
+ .describe("Target filename for this screen, such as onboarding.html"),
53
+ role: z.enum(["screen", "variant"]).optional().default("screen"),
54
+ variantOf: z.string().optional(),
55
+ })
56
+ .superRefine((screen, ctx) => {
57
+ if (screen.role === "variant" && !screen.variantOf) {
58
+ ctx.addIssue({
59
+ code: z.ZodIssueCode.custom,
60
+ path: ["variantOf"],
61
+ message:
62
+ "variant screens require variantOf to identify the base screen",
63
+ });
64
+ }
65
+ });
55
66
 
56
67
  export default defineAction({
57
68
  description:
@@ -101,10 +112,39 @@ export default defineAction({
101
112
  origin: { x: 0, y: 0 },
102
113
  columns: screens.length <= 3 ? screens.length : 3,
103
114
  });
115
+
116
+ const seenFilenames = new Map<string, number>();
117
+ // Dedupe any filename (explicit or auto-generated) so two screens can never
118
+ // resolve to the same target file — otherwise generate-design silently
119
+ // overwrites the first screen's output with the second's.
120
+ const dedupeFilename = (base: string): string => {
121
+ if (!seenFilenames.has(base)) {
122
+ seenFilenames.set(base, 1);
123
+ return base;
124
+ }
125
+ const count = seenFilenames.get(base)! + 1;
126
+ seenFilenames.set(base, count);
127
+ const dot = base.lastIndexOf(".");
128
+ return dot > 0
129
+ ? `${base.slice(0, dot)}-${count}${base.slice(dot)}`
130
+ : `${base}-${count}`;
131
+ };
132
+ const requestedTargets = screens.map((screen, index) => {
133
+ if (screen.filename) return dedupeFilename(screen.filename);
134
+ const slug =
135
+ screen.title
136
+ .toLowerCase()
137
+ .replace(/[^a-z0-9]+/g, "-")
138
+ .replace(/^-+|-+$/g, "")
139
+ .slice(0, 48) || `screen-${index + 1}`;
140
+ return dedupeFilename(`${slug}.html`);
141
+ });
142
+
104
143
  const frames: DesignGenerationFrame[] = screens.map((screen, index) => {
105
144
  const frameId = screen.frameId ?? nanoid();
106
145
  return {
107
146
  frameId,
147
+ filename: requestedTargets[index],
108
148
  agentId: `agent-${frameId}`,
109
149
  agentName: AGENT_NAMES[index % AGENT_NAMES.length] ?? "Agent",
110
150
  agentColor:
@@ -142,15 +182,7 @@ export default defineAction({
142
182
 
143
183
  const targets = frames.map((frame, index) => {
144
184
  const requested = screens[index]!;
145
- const filename =
146
- requested.filename ??
147
- `${
148
- requested.title
149
- .toLowerCase()
150
- .replace(/[^a-z0-9]+/g, "-")
151
- .replace(/^-+|-+$/g, "")
152
- .slice(0, 48) || `screen-${index + 1}`
153
- }.html`;
185
+ const filename = requestedTargets[index]!;
154
186
  return {
155
187
  frameId: frame.frameId,
156
188
  title: requested.title,
@@ -43,7 +43,11 @@ export default defineAction({
43
43
  run: async ({ designId }) => {
44
44
  const access = await resolveAccess("design", designId);
45
45
  if (!access) {
46
- throw new Error("Design not found");
46
+ const err = new Error("Design not found") as Error & {
47
+ statusCode: number;
48
+ };
49
+ err.statusCode = 404;
50
+ throw err;
47
51
  }
48
52
  const design = access.resource as typeof schema.designs.$inferSelect;
49
53
 
@@ -13,6 +13,7 @@ export default defineAction({
13
13
  id: z.string().describe("Design ID"),
14
14
  }),
15
15
  readOnly: true,
16
+ requiresAuth: false,
16
17
  http: { method: "GET" },
17
18
  run: async ({ id }) => {
18
19
  const access = await resolveAccess("design", id);
@@ -39,6 +40,7 @@ export default defineAction({
39
40
  visibility: row.visibility,
40
41
  createdAt: row.createdAt,
41
42
  updatedAt: row.updatedAt,
43
+ accessRole: access.role,
42
44
  files: files.map((f) => ({
43
45
  id: f.id,
44
46
  filename: f.filename,
@@ -12,15 +12,28 @@ export default defineAction({
12
12
  "has good styling (CSS custom properties, fonts, colors), this extracts those " +
13
13
  "into reusable design tokens. Alternatively, import from an existing design system " +
14
14
  "for cloning/forking. Returns extracted tokens plus raw CSS for agent refinement.",
15
- schema: z.object({
16
- designId: z.string().describe("Design project ID to extract tokens from"),
17
- designSystemId: z
18
- .string()
19
- .optional()
20
- .describe(
21
- "If provided, import from this existing design system instead of extracting from the design project",
22
- ),
23
- }),
15
+ schema: z
16
+ .object({
17
+ designId: z
18
+ .string()
19
+ .optional()
20
+ .describe("Design project ID to extract tokens from"),
21
+ designSystemId: z
22
+ .string()
23
+ .optional()
24
+ .describe(
25
+ "If provided, import from this existing design system instead of extracting from the design project",
26
+ ),
27
+ })
28
+ .superRefine((args, ctx) => {
29
+ if (!args.designId && !args.designSystemId) {
30
+ ctx.addIssue({
31
+ code: z.ZodIssueCode.custom,
32
+ path: ["designId"],
33
+ message: "designId or designSystemId is required",
34
+ });
35
+ }
36
+ }),
24
37
  readOnly: true,
25
38
  http: { method: "GET" },
26
39
  run: async ({ designId, designSystemId }) => {
@@ -55,6 +68,12 @@ export default defineAction({
55
68
  };
56
69
  }
57
70
 
71
+ if (!designId) {
72
+ throw new Error(
73
+ "designId is required when designSystemId is not provided",
74
+ );
75
+ }
76
+
58
77
  // Extract tokens from the design project
59
78
  await assertAccess("design", designId, "viewer");
60
79
 
@@ -8,6 +8,9 @@ import {
8
8
  } from "@agent-native/core/server/design-token-utils";
9
9
  import { z } from "zod";
10
10
 
11
+ const DOC_MAX_FILES = 20;
12
+ const DOC_MAX_TEXT_BYTES = 500 * 1024;
13
+
11
14
  export default defineAction({
12
15
  description:
13
16
  "Process uploaded document metadata (DOCX, PPTX, PDF, XLSX) and return " +
@@ -44,16 +47,29 @@ export default defineAction({
44
47
  }),
45
48
  readOnly: true,
46
49
  run: async ({ files }) => {
47
- const processedFiles = files.map((file) => {
50
+ const capped = files.slice(0, DOC_MAX_FILES);
51
+ const processedFiles = capped.map((file) => {
48
52
  const contentType = classifyFile(file.fileType);
49
- const hasText = !!file.textContent && file.textContent.trim().length > 0;
53
+
54
+ // Truncate textContent before regex scanning to bound CPU/memory usage.
55
+ let text = file.textContent;
56
+ if (text) {
57
+ const encoded = new TextEncoder().encode(text);
58
+ if (encoded.byteLength > DOC_MAX_TEXT_BYTES) {
59
+ text = new TextDecoder().decode(
60
+ encoded.subarray(0, DOC_MAX_TEXT_BYTES),
61
+ );
62
+ }
63
+ }
64
+
65
+ const hasText = !!text && text.trim().length > 0;
50
66
 
51
67
  let likelyColors: string[] = [];
52
68
  let likelyFonts: string[] = [];
53
69
 
54
- if (file.textContent) {
55
- likelyColors = extractDocumentColors(file.textContent);
56
- likelyFonts = extractDocumentFonts(file.textContent);
70
+ if (text) {
71
+ likelyColors = extractDocumentColors(text);
72
+ likelyFonts = extractDocumentFonts(text);
57
73
  }
58
74
 
59
75
  if (file.metadata) {
@@ -80,9 +96,7 @@ export default defineAction({
80
96
  likelyColors,
81
97
  likelyFonts,
82
98
  contentType,
83
- extractedText: file.textContent
84
- ? file.textContent.slice(0, 2000)
85
- : undefined,
99
+ extractedText: text ? text.slice(0, 2000) : undefined,
86
100
  suggestions,
87
101
  },
88
102
  };
@@ -7,11 +7,9 @@ import {
7
7
  getRequestOrgId,
8
8
  getRequestUserEmail,
9
9
  } from "@agent-native/core/server/request-context";
10
- import { eq } from "drizzle-orm";
11
- import { nanoid } from "nanoid";
12
10
  import { z } from "zod";
13
11
 
14
- import { getDb, schema } from "../server/db/index.js";
12
+ import { upsertBuilderProxyDesignSystem } from "../server/lib/builder-design-system-proxy.js";
15
13
 
16
14
  const MAX_CODE_FILES = 50;
17
15
  const MAX_TOTAL_CODE_BYTES = 2 * 1024 * 1024;
@@ -52,83 +50,6 @@ function makeFiles(
52
50
  return files;
53
51
  }
54
52
 
55
- function localBuilderDesignSystemId(builderDesignSystemId: string): string {
56
- const slug = builderDesignSystemId
57
- .replace(/[^a-zA-Z0-9_-]+/g, "-")
58
- .replace(/^-+|-+$/g, "")
59
- .slice(0, 96);
60
- return `builder-${slug || "design-system"}`;
61
- }
62
-
63
- function builderProxyData({
64
- builderDesignSystemId,
65
- jobId,
66
- builderUrl,
67
- projectName,
68
- description,
69
- }: {
70
- builderDesignSystemId: string;
71
- jobId: string;
72
- builderUrl: string;
73
- projectName?: string;
74
- description?: string;
75
- }) {
76
- return JSON.stringify({
77
- source: "builder",
78
- builderDesignSystemId,
79
- builderJobId: jobId,
80
- builderUrl,
81
- colors: {
82
- primary: "var(--primary)",
83
- secondary: "var(--secondary)",
84
- accent: "var(--accent)",
85
- background: "var(--background)",
86
- surface: "var(--card)",
87
- text: "var(--foreground)",
88
- textMuted: "var(--muted-foreground)",
89
- },
90
- typography: {
91
- headingFont: "inherit",
92
- bodyFont: "inherit",
93
- headingWeight: "700",
94
- bodyWeight: "400",
95
- headingSizes: { h1: "48px", h2: "32px", h3: "24px" },
96
- },
97
- spacing: { elementGap: "24px", pagePadding: "48px" },
98
- borders: { radius: "12px", accentWidth: "1px" },
99
- logos: [],
100
- notes: [
101
- "This is a local proxy for a Builder-indexed design system.",
102
- `Builder design system id: ${builderDesignSystemId}`,
103
- `Builder indexing job id: ${jobId}`,
104
- `Builder URL: ${builderUrl}`,
105
- projectName ? `Requested name: ${projectName}` : "",
106
- description ? `Context: ${description}` : "",
107
- "Use Builder as the source of truth for extracted tokens and guidance.",
108
- ]
109
- .filter(Boolean)
110
- .join("\n"),
111
- });
112
- }
113
-
114
- function builderProxyInstructions({
115
- builderDesignSystemId,
116
- jobId,
117
- builderUrl,
118
- }: {
119
- builderDesignSystemId: string;
120
- jobId: string;
121
- builderUrl: string;
122
- }) {
123
- return [
124
- "This design system is indexed and owned by Builder.",
125
- `Builder design system id: ${builderDesignSystemId}`,
126
- `Builder job id: ${jobId}`,
127
- `Builder URL: ${builderUrl}`,
128
- "When generating designs, treat Builder as the source of truth for the final extracted tokens, assets, and guidance.",
129
- ].join("\n");
130
- }
131
-
132
53
  export default defineAction({
133
54
  description:
134
55
  "Start Builder design-system indexing from a GitHub repository and/or code files. " +
@@ -174,86 +95,18 @@ export default defineAction({
174
95
  const ownerEmail = getRequestUserEmail();
175
96
  if (!ownerEmail) throw new Error("no authenticated user");
176
97
 
177
- const db = getDb();
178
- const now = new Date().toISOString();
179
- const orgId = getRequestOrgId();
180
- const baseLocalDesignSystemId = localBuilderDesignSystemId(
181
- result.designSystemId,
182
- );
183
- const title = projectName?.trim() || "Builder indexed design system";
184
- const localData = builderProxyData({
185
- builderDesignSystemId: result.designSystemId,
186
- jobId: result.jobId,
187
- builderUrl: result.builderUrl,
98
+ const proxy = await upsertBuilderProxyDesignSystem({
99
+ result,
100
+ ownerEmail,
101
+ orgId: getRequestOrgId(),
188
102
  projectName,
189
103
  description,
190
104
  });
191
- const customInstructions = builderProxyInstructions({
192
- builderDesignSystemId: result.designSystemId,
193
- jobId: result.jobId,
194
- builderUrl: result.builderUrl,
195
- });
196
- const [existing] = await db
197
- .select({
198
- id: schema.designSystems.id,
199
- ownerEmail: schema.designSystems.ownerEmail,
200
- })
201
- .from(schema.designSystems)
202
- .where(eq(schema.designSystems.id, baseLocalDesignSystemId))
203
- .limit(1);
204
- const localDesignSystemId =
205
- existing && existing.ownerEmail !== ownerEmail
206
- ? `${baseLocalDesignSystemId}-${nanoid(8)}`
207
- : baseLocalDesignSystemId;
208
- if (existing && existing.ownerEmail === ownerEmail) {
209
- await db
210
- .update(schema.designSystems)
211
- .set({
212
- title,
213
- description:
214
- description ??
215
- `Builder indexed design system ${result.designSystemId}`,
216
- data: localData,
217
- assets: "[]",
218
- customInstructions,
219
- updatedAt: now,
220
- })
221
- .where(eq(schema.designSystems.id, existing.id));
222
- } else {
223
- const [ownedSystem] = await db
224
- .select({ id: schema.designSystems.id })
225
- .from(schema.designSystems)
226
- .where(eq(schema.designSystems.ownerEmail, ownerEmail))
227
- .limit(1);
228
- await db.insert(schema.designSystems).values({
229
- id: localDesignSystemId,
230
- title,
231
- description:
232
- description ??
233
- `Builder indexed design system ${result.designSystemId}`,
234
- data: localData,
235
- assets: "[]",
236
- customInstructions,
237
- isDefault: !ownedSystem,
238
- ownerEmail,
239
- orgId,
240
- createdAt: now,
241
- updatedAt: now,
242
- });
243
- }
244
105
 
245
106
  return {
246
107
  ...result,
247
- localDesignSystemId,
108
+ ...proxy,
248
109
  uploadedFileCount: files.length,
249
- instructions: [
250
- "Builder design-system indexing has started.",
251
- `Builder design system: ${result.designSystemId}`,
252
- `Local selectable design system: ${localDesignSystemId}`,
253
- `Builder job: ${result.jobId}`,
254
- `Open: ${result.builderUrl}`,
255
- "Use the local design system id in Design flows; Builder remains the source of truth for the indexed brand kit.",
256
- ].join("\n"),
257
110
  };
258
111
  },
259
112
  });