@agent-native/core 0.137.7 → 0.138.0

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 (446) hide show
  1. package/agent-native.eject.json +2 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +23 -3
  4. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  5. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +15 -0
  6. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +23 -2
  7. package/corpus/templates/analytics/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  8. package/corpus/templates/analytics/AGENTS.md +2 -2
  9. package/corpus/templates/analytics/actions/get-first-party-analytics-health.ts +65 -0
  10. package/corpus/templates/analytics/actions/provider-api-catalog.ts +3 -6
  11. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -6
  12. package/corpus/templates/analytics/actions/provider-api-request.ts +3 -6
  13. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +3 -3
  14. package/corpus/templates/analytics/agent-native.json +12 -0
  15. package/corpus/templates/analytics/app/i18n-data.ts +162 -0
  16. package/corpus/templates/analytics/app/pages/DataSources.tsx +126 -1
  17. package/corpus/templates/analytics/changelog/2026-08-05-analytics-now-flags-neon-pressure-and-guides-high-volume-tra.md +6 -0
  18. package/corpus/templates/analytics/changelog/2026-08-05-first-party-analytics-uses-compact-rollups-for-faster-usage-.md +6 -0
  19. package/corpus/templates/analytics/server/db/schema.ts +52 -0
  20. package/corpus/templates/analytics/server/lib/credential-keys.ts +3 -0
  21. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +397 -0
  22. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +182 -0
  23. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +86 -15
  24. package/corpus/templates/analytics/server/lib/provider-api.ts +20 -1
  25. package/corpus/templates/analytics/server/lib/replay-storage.ts +1 -1
  26. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  27. package/corpus/templates/analytics/server/plugins/db.ts +60 -0
  28. package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +23 -3
  29. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  30. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +23 -2
  31. package/corpus/templates/assets/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  32. package/corpus/templates/assets/agent-native.json +12 -0
  33. package/corpus/templates/assets/server/lib/generation.ts +8 -8
  34. package/corpus/templates/assets/server/lib/storage.ts +1 -1
  35. package/corpus/templates/assets/server/plugins/onboarding.ts +1 -1
  36. package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +23 -3
  37. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  38. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +23 -2
  39. package/corpus/templates/brain/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  40. package/corpus/templates/brain/agent-native.json +12 -0
  41. package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +23 -3
  42. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  43. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +23 -2
  44. package/corpus/templates/calendar/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  45. package/corpus/templates/calendar/agent-native.json +12 -0
  46. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  47. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  48. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  49. package/corpus/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  50. package/corpus/templates/chat/AGENTS.md +3 -0
  51. package/corpus/templates/chat/DESIGN.md +28 -0
  52. package/corpus/templates/chat/agent-native.json +12 -0
  53. package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +23 -3
  54. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  55. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +23 -2
  56. package/corpus/templates/clips/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  57. package/corpus/templates/clips/actions/cleanup-transcript.ts +2 -2
  58. package/corpus/templates/clips/actions/delete-recording-permanent.ts +3 -0
  59. package/corpus/templates/clips/actions/get-playback-position.ts +68 -0
  60. package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
  61. package/corpus/templates/clips/actions/save-playback-position.ts +80 -0
  62. package/corpus/templates/clips/actions/set-thumbnail.ts +1 -1
  63. package/corpus/templates/clips/agent-native.json +12 -0
  64. package/corpus/templates/clips/app/components/player/video-player.tsx +54 -5
  65. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +65 -18
  66. package/corpus/templates/clips/app/hooks/use-playback-position.ts +188 -0
  67. package/corpus/templates/clips/app/hooks/use-view-tracking.ts +6 -24
  68. package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
  69. package/corpus/templates/clips/app/lib/playback-position.ts +99 -0
  70. package/corpus/templates/clips/app/lib/viewer-session.ts +29 -0
  71. package/corpus/templates/clips/changelog/2026-08-05-clip-buffering-now-uses-buffering-copy-after-playback.md +6 -0
  72. package/corpus/templates/clips/changelog/2026-08-05-clips-remembers-your-playback-position-when-you-reopen-a-cli.md +6 -0
  73. package/corpus/templates/clips/desktop/package.json +1 -0
  74. package/corpus/templates/clips/desktop/src/app.tsx +70 -6
  75. package/corpus/templates/clips/desktop/src/components/AlertDialog.tsx +131 -0
  76. package/corpus/templates/clips/desktop/src/styles.css +129 -0
  77. package/corpus/templates/clips/learnings.defaults.md +1 -1
  78. package/corpus/templates/clips/server/db/schema.ts +18 -0
  79. package/corpus/templates/clips/server/lib/public-agent-context.ts +1 -1
  80. package/corpus/templates/clips/server/lib/video-storage.ts +1 -1
  81. package/corpus/templates/clips/server/plugins/db.ts +15 -0
  82. package/corpus/templates/clips/server/routes/api/media/index.post.ts +1 -1
  83. package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +23 -3
  84. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  85. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +13 -0
  86. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +23 -2
  87. package/corpus/templates/content/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  88. package/corpus/templates/content/AGENTS.md +1 -0
  89. package/corpus/templates/content/actions/_content-database-mutation-lock.ts +41 -0
  90. package/corpus/templates/content/actions/_content-database-row-migration.ts +569 -0
  91. package/corpus/templates/content/actions/_database-source-utils.ts +82 -36
  92. package/corpus/templates/content/actions/_database-utils.ts +5 -0
  93. package/corpus/templates/content/actions/_delete-content-space.ts +25 -11
  94. package/corpus/templates/content/actions/add-database-item.ts +60 -42
  95. package/corpus/templates/content/actions/attach-content-database-source.ts +2 -0
  96. package/corpus/templates/content/actions/configure-document-property.ts +99 -104
  97. package/corpus/templates/content/actions/delete-content-database.ts +19 -7
  98. package/corpus/templates/content/actions/delete-document-property.ts +47 -58
  99. package/corpus/templates/content/actions/delete-document.ts +390 -167
  100. package/corpus/templates/content/actions/disconnect-content-database-source.ts +41 -24
  101. package/corpus/templates/content/actions/duplicate-database-item.ts +63 -31
  102. package/corpus/templates/content/actions/duplicate-database-items.ts +86 -43
  103. package/corpus/templates/content/actions/duplicate-document-property.ts +37 -14
  104. package/corpus/templates/content/actions/migrate-content-database-rows.ts +830 -0
  105. package/corpus/templates/content/actions/move-database-item.ts +14 -0
  106. package/corpus/templates/content/actions/permanently-delete-document.ts +27 -6
  107. package/corpus/templates/content/actions/remove-database-items.ts +13 -0
  108. package/corpus/templates/content/actions/reorder-document-property.ts +45 -46
  109. package/corpus/templates/content/actions/set-document-property.ts +68 -28
  110. package/corpus/templates/content/actions/submit-content-database-form.ts +49 -0
  111. package/corpus/templates/content/actions/transcribe-media.ts +1 -1
  112. package/corpus/templates/content/agent-native.json +12 -0
  113. package/corpus/templates/content/app/components/editor/image-upload.ts +2 -2
  114. package/corpus/templates/content/app/i18n-data.ts +1 -1
  115. package/corpus/templates/content/changelog/2026-08-01-content-can-reorganize-every-row-in-an-existing-database-as-.md +6 -0
  116. package/corpus/templates/content/parity/matrix.md +1 -1
  117. package/corpus/templates/content/parity/matrix.ts +4 -2
  118. package/corpus/templates/content/server/db/schema.ts +30 -0
  119. package/corpus/templates/content/server/plugins/db.ts +24 -0
  120. package/corpus/templates/content/server/plugins/onboarding.ts +2 -2
  121. package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +23 -3
  122. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  123. package/corpus/templates/crm/agent-native.json +12 -0
  124. package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +23 -3
  125. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  126. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +2 -0
  127. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +23 -2
  128. package/corpus/templates/design/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  129. package/corpus/templates/design/CODE_NATIVE_DESIGN_STUDIO_IMPLEMENTATION_PLAN.md +2 -2
  130. package/corpus/templates/design/DESIGN-STUDIO-PLAN.md +2 -2
  131. package/corpus/templates/design/actions/apply-design-token-edit.ts +1 -1
  132. package/corpus/templates/design/actions/capture-design-state.ts +1 -1
  133. package/corpus/templates/design/actions/connect-builder-app.ts +2 -2
  134. package/corpus/templates/design/actions/create-design-branch.ts +1 -1
  135. package/corpus/templates/design/actions/create-fusion-app.ts +3 -3
  136. package/corpus/templates/design/actions/deploy-design-preview.ts +1 -1
  137. package/corpus/templates/design/actions/generate-design.ts +3 -2
  138. package/corpus/templates/design/actions/get-component-details.ts +1 -1
  139. package/corpus/templates/design/actions/get-design-branch-diff.ts +1 -1
  140. package/corpus/templates/design/actions/index-components.ts +3 -3
  141. package/corpus/templates/design/actions/index-design-system-with-builder.ts +1 -1
  142. package/corpus/templates/design/actions/migrate-inline-design-to-app.ts +3 -3
  143. package/corpus/templates/design/actions/open-component-source.ts +1 -1
  144. package/corpus/templates/design/actions/update-design.ts +96 -14
  145. package/corpus/templates/design/agent-native.json +12 -0
  146. package/corpus/templates/design/app/components/design/DesignImportPanel.tsx +7 -2
  147. package/corpus/templates/design/app/components/design/FigmaHydrationDialog.tsx +11 -2
  148. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +1 -1
  149. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +8 -1
  150. package/corpus/templates/design/app/i18n-data.ts +53 -22
  151. package/corpus/templates/design/app/lib/design-file-upload.ts +2 -3
  152. package/corpus/templates/design/app/lib/upload-limits.ts +4 -0
  153. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +1 -1
  154. package/corpus/templates/design/changelog/2026-08-05-chat-attachments-now-warn-before-upload-when-they-exceed-the.md +6 -0
  155. package/corpus/templates/design/changelog/2026-08-05-figma-fig-uploads-now-show-a-clear-4-mb-limit-up-front-inste.md +6 -0
  156. package/corpus/templates/design/scripts/qa-figma-stress-import.ts +1 -1
  157. package/corpus/templates/design/server/handlers/import-design-file.ts +9 -5
  158. package/corpus/templates/design/server/handlers/uploads.ts +13 -9
  159. package/corpus/templates/design/server/lib/fig-file-limits.ts +2 -1
  160. package/corpus/templates/design/server/lib/figma-image-hydration.ts +1 -1
  161. package/corpus/templates/design/server/lib/figma-node-import.ts +1 -1
  162. package/corpus/templates/design/server/lib/request-body-limits.ts +11 -0
  163. package/corpus/templates/design/shared/canvas-frames.ts +81 -0
  164. package/corpus/templates/design/shared/design-source-capabilities.ts +25 -9
  165. package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +23 -3
  166. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  167. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +23 -2
  168. package/corpus/templates/dispatch/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  169. package/corpus/templates/dispatch/agent-native.json +12 -0
  170. package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +23 -3
  171. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  172. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +23 -2
  173. package/corpus/templates/factory/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  174. package/corpus/templates/factory/agent-native.json +12 -0
  175. package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +23 -3
  176. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  177. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +23 -2
  178. package/corpus/templates/forms/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  179. package/corpus/templates/forms/actions/export-responses.ts +1 -1
  180. package/corpus/templates/forms/agent-native.json +12 -0
  181. package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +23 -3
  182. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  183. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +23 -2
  184. package/corpus/templates/macros/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  185. package/corpus/templates/macros/agent-native.json +12 -0
  186. package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +23 -3
  187. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  188. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +23 -2
  189. package/corpus/templates/mail/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  190. package/corpus/templates/mail/agent-native.json +12 -0
  191. package/corpus/templates/mail/app/i18n/en-US.ts +1 -1
  192. package/corpus/templates/mail/server/lib/media-upload.ts +1 -1
  193. package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +23 -3
  194. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  195. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +23 -2
  196. package/corpus/templates/plan/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  197. package/corpus/templates/plan/agent-native.json +12 -0
  198. package/corpus/templates/plan/server/lib/plan-assets.ts +1 -1
  199. package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +23 -3
  200. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  201. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +23 -2
  202. package/corpus/templates/slides/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  203. package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
  204. package/corpus/templates/slides/actions/generate-slides-ai.ts +1 -1
  205. package/corpus/templates/slides/actions/import-file.ts +2 -2
  206. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +1 -1
  207. package/corpus/templates/slides/agent-native.json +12 -0
  208. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  209. package/corpus/templates/slides/app/i18n/en-US.ts +2 -2
  210. package/corpus/templates/slides/app/lib/deck-sorting.ts +19 -0
  211. package/corpus/templates/slides/app/lib/image-drop-to-agent.ts +1 -1
  212. package/corpus/templates/slides/app/pages/Index.tsx +7 -2
  213. package/corpus/templates/slides/changelog/2026-08-05-decks-are-now-sorted-by-most-recently-updated.md +6 -0
  214. package/corpus/templates/slides/server/handlers/assets.ts +1 -1
  215. package/corpus/templates/slides/server/handlers/uploads.ts +1 -1
  216. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +23 -3
  217. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  218. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +23 -2
  219. package/corpus/templates/tasks/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  220. package/corpus/templates/tasks/agent-native.json +12 -0
  221. package/dist/action.d.ts +6 -0
  222. package/dist/agent/engine/builder-engine.js +2 -2
  223. package/dist/agent/engine/credential-errors.d.ts +1 -1
  224. package/dist/agent/engine/credential-errors.js +2 -2
  225. package/dist/agent/production-agent.js +3 -2
  226. package/dist/brand-kit/fig/index.js +1 -1
  227. package/dist/cli/agent.js +45 -3
  228. package/dist/cli/code-agent-executor.js +2 -1
  229. package/dist/cli/create.d.ts +9 -1
  230. package/dist/cli/create.js +94 -1
  231. package/dist/cli/doctor.d.ts +8 -11
  232. package/dist/cli/doctor.js +92 -24
  233. package/dist/cli/index.js +6 -5
  234. package/dist/client/AgentAskPopover.d.ts +3 -1
  235. package/dist/client/AgentAskPopover.js +2 -2
  236. package/dist/client/AgentPanel.js +9 -3
  237. package/dist/client/AssistantChat.js +54 -33
  238. package/dist/client/MultiTabAssistantChat.js +1 -1
  239. package/dist/client/RouteTransitionIndicator.d.ts +7 -0
  240. package/dist/client/RouteTransitionIndicator.js +31 -0
  241. package/dist/client/agent-engine-key.js +1 -1
  242. package/dist/client/app-providers.js +11 -2
  243. package/dist/client/chat/message-components.js +1 -1
  244. package/dist/client/chat/run-recovery.js +1 -1
  245. package/dist/client/chat/tool-call-display.d.ts +3 -1
  246. package/dist/client/chat/tool-call-display.js +4 -3
  247. package/dist/client/chat-model-groups.d.ts +6 -0
  248. package/dist/client/chat-model-groups.js +11 -0
  249. package/dist/client/error-format.js +1 -1
  250. package/dist/client/i18n.js +1 -1
  251. package/dist/client/onboarding/FirstRunOnboarding.d.ts +5 -1
  252. package/dist/client/onboarding/FirstRunOnboarding.js +29 -13
  253. package/dist/client/onboarding/first-run-enabled.d.ts +6 -1
  254. package/dist/client/onboarding/first-run-enabled.js +33 -3
  255. package/dist/client/onboarding/use-onboarding.js +16 -11
  256. package/dist/client/require-session.js +13 -4
  257. package/dist/client/resources/mcp-integration-catalog.js +26 -0
  258. package/dist/client/resources/mcp-integration-logos.js +4 -0
  259. package/dist/client/route-warmup.js +56 -10
  260. package/dist/client/settings/AccountSettingsCard.js +78 -3
  261. package/dist/client/settings/SettingsPanel.js +1 -1
  262. package/dist/client/settings/VoiceTranscriptionSection.js +2 -2
  263. package/dist/client/settings/useBuilderStatus.js +1 -1
  264. package/dist/client/setup-connections/useBuilderConnectCardController.js +1 -1
  265. package/dist/client/ui/index.d.ts +1 -0
  266. package/dist/client/ui/index.js +1 -0
  267. package/dist/client/uploads/upload-editor-image.js +1 -1
  268. package/dist/client/use-chat-threads.js +3 -0
  269. package/dist/client/use-session.d.ts +11 -0
  270. package/dist/client/use-session.js +34 -6
  271. package/dist/collab/routes.d.ts +2 -2
  272. package/dist/config.d.ts +48 -0
  273. package/dist/config.js +111 -0
  274. package/dist/db/migrations.js +5 -0
  275. package/dist/eject/provider-api-definitions.d.ts +1 -1
  276. package/dist/eject/provider-api-definitions.js +1 -0
  277. package/dist/eject/remote-mcp-presets.js +1 -0
  278. package/dist/extensions/web-search-tool.js +2 -2
  279. package/dist/file-upload/actions/upload-image.js +1 -1
  280. package/dist/file-upload/registry.js +1 -1
  281. package/dist/guards/index.d.ts +3 -0
  282. package/dist/guards/index.js +2 -0
  283. package/dist/guards/no-empty-migrations.d.ts +14 -0
  284. package/dist/guards/no-empty-migrations.js +126 -0
  285. package/dist/index.browser.d.ts +1 -0
  286. package/dist/index.browser.js +3 -0
  287. package/dist/index.d.ts +1 -0
  288. package/dist/index.js +1 -0
  289. package/dist/localization/default-messages.d.ts +24 -0
  290. package/dist/localization/default-messages.js +26 -2
  291. package/dist/notifications/routes.d.ts +6 -6
  292. package/dist/onboarding/app-profile.js +1 -1
  293. package/dist/onboarding/plugin.d.ts +2 -0
  294. package/dist/onboarding/plugin.js +29 -2
  295. package/dist/progress/routes.d.ts +1 -1
  296. package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
  297. package/dist/provider-api/actions/provider-api.d.ts +13 -13
  298. package/dist/provider-api/index.d.ts +4 -4
  299. package/dist/provider-api/index.js +35 -0
  300. package/dist/resources/handlers.d.ts +1 -1
  301. package/dist/resources/handlers.js +1 -1
  302. package/dist/scripts/docs/framework-search.d.ts +9 -0
  303. package/dist/scripts/docs/framework-search.js +239 -0
  304. package/dist/scripts/docs/index.js +1 -0
  305. package/dist/scripts/docs/search.d.ts +10 -0
  306. package/dist/scripts/docs/search.js +1 -1
  307. package/dist/scripts/docs/source-search.d.ts +10 -2
  308. package/dist/scripts/docs/source-search.js +108 -41
  309. package/dist/search-utils/index.d.ts +11 -0
  310. package/dist/search-utils/index.js +72 -0
  311. package/dist/server/action-change.d.ts +6 -0
  312. package/dist/server/action-change.js +28 -14
  313. package/dist/server/action-discovery.js +9 -0
  314. package/dist/server/action-routes.js +1 -0
  315. package/dist/server/agent-chat/browser-team-tools.js +1 -1
  316. package/dist/server/agent-chat/script-entries.js +43 -2
  317. package/dist/server/auth-login-mode.d.ts +8 -0
  318. package/dist/server/auth-login-mode.js +17 -0
  319. package/dist/server/auth.js +100 -15
  320. package/dist/server/better-auth-instance.d.ts +36 -0
  321. package/dist/server/better-auth-instance.js +25 -3
  322. package/dist/server/builder-design-systems.js +1 -1
  323. package/dist/server/core-routes-plugin.js +17 -14
  324. package/dist/server/credential-provider.js +3 -3
  325. package/dist/server/email-templates.d.ts +7 -0
  326. package/dist/server/email-templates.js +24 -0
  327. package/dist/server/email.d.ts +17 -0
  328. package/dist/server/email.js +22 -1
  329. package/dist/server/framework-request-handler.js +6 -0
  330. package/dist/server/onboarding-html.d.ts +2 -0
  331. package/dist/server/onboarding-html.js +169 -8
  332. package/dist/server/realtime-token.d.ts +1 -1
  333. package/dist/server/realtime-voice.js +1 -1
  334. package/dist/server/sentry.d.ts +1 -1
  335. package/dist/server/transcribe-voice.js +3 -3
  336. package/dist/shared/first-run-onboarding.d.ts +1 -0
  337. package/dist/shared/first-run-onboarding.js +1 -0
  338. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  339. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  340. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  341. package/dist/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  342. package/dist/templates/chat/AGENTS.md +3 -0
  343. package/dist/templates/chat/DESIGN.md +28 -0
  344. package/dist/templates/chat/agent-native.json +12 -0
  345. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +23 -3
  346. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  347. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +23 -2
  348. package/dist/templates/default/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  349. package/dist/templates/default/AGENTS.md +4 -0
  350. package/dist/templates/default/DESIGN.md +30 -0
  351. package/dist/templates/default/agent-native.json +9 -0
  352. package/dist/templates/default/app/i18n/ar-SA.ts +2 -2
  353. package/dist/templates/default/app/i18n/de-DE.ts +2 -2
  354. package/dist/templates/default/app/i18n/en-US.ts +2 -2
  355. package/dist/templates/default/app/i18n/es-ES.ts +2 -2
  356. package/dist/templates/default/app/i18n/fr-FR.ts +2 -2
  357. package/dist/templates/default/app/i18n/hi-IN.ts +2 -2
  358. package/dist/templates/default/app/i18n/ja-JP.ts +2 -2
  359. package/dist/templates/default/app/i18n/ko-KR.ts +2 -2
  360. package/dist/templates/default/app/i18n/pt-BR.ts +2 -2
  361. package/dist/templates/default/app/i18n/zh-CN.ts +2 -2
  362. package/dist/templates/default/app/i18n/zh-TW.ts +1 -1
  363. package/dist/templates/default/package.json +1 -0
  364. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +23 -3
  365. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  366. package/dist/templates/headless/agent-native.json +9 -0
  367. package/dist/templates/headless/package.json +2 -0
  368. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +23 -3
  369. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  370. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +23 -2
  371. package/dist/templates/workspace-core/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  372. package/dist/templates/workspace-core/AGENTS.md +3 -0
  373. package/dist/templates/workspace-core/DESIGN.md +35 -0
  374. package/dist/templates/workspace-root/AGENTS.md +3 -0
  375. package/dist/templates/workspace-root/DESIGN.md +35 -0
  376. package/dist/templates/workspace-root/agent-native.json +9 -0
  377. package/dist/templates/workspace-root/package.json +3 -0
  378. package/dist/transcription/builder-transcription.js +1 -1
  379. package/dist/user-profile/actions/change-password.d.ts +8 -0
  380. package/dist/user-profile/actions/change-password.js +24 -0
  381. package/dist/user-profile/actions/get-auth-methods.d.ts +6 -0
  382. package/dist/user-profile/actions/get-auth-methods.js +23 -0
  383. package/dist/user-profile/actions/set-password.d.ts +7 -0
  384. package/dist/user-profile/actions/set-password.js +23 -0
  385. package/dist/vite/client.d.ts +8 -1
  386. package/dist/vite/client.js +63 -12
  387. package/dist/vite/index.d.ts +1 -0
  388. package/dist/vite/index.js +1 -0
  389. package/docs/AGENTS.md +7 -2
  390. package/docs/SKILL.md +7 -5
  391. package/docs/content/agent-native-config.mdx +165 -0
  392. package/docs/content/agent-native-toolkit.mdx +1 -1
  393. package/docs/content/deployment.mdx +7 -2
  394. package/docs/content/doctor.mdx +21 -13
  395. package/docs/content/environment-variables.mdx +158 -0
  396. package/docs/content/file-uploads.mdx +1 -1
  397. package/docs/content/getting-started.mdx +1 -1
  398. package/docs/content/key-concepts.mdx +1 -1
  399. package/docs/content/multi-app-workspace.mdx +1 -1
  400. package/docs/content/template-clips-ai-and-editing.mdx +6 -6
  401. package/docs/content/template-clips-developers.mdx +3 -3
  402. package/docs/content/toolkit-settings.mdx +1 -1
  403. package/docs/content/voice-input.mdx +4 -4
  404. package/package.json +6 -2
  405. package/src/eject/provider-api-definitions.ts +1 -0
  406. package/src/eject/remote-mcp-presets.ts +1 -0
  407. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +23 -3
  408. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  409. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +23 -2
  410. package/src/templates/chat/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  411. package/src/templates/chat/AGENTS.md +3 -0
  412. package/src/templates/chat/DESIGN.md +28 -0
  413. package/src/templates/chat/agent-native.json +12 -0
  414. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +23 -3
  415. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  416. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +23 -2
  417. package/src/templates/default/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  418. package/src/templates/default/AGENTS.md +4 -0
  419. package/src/templates/default/DESIGN.md +30 -0
  420. package/src/templates/default/agent-native.json +9 -0
  421. package/src/templates/default/app/i18n/ar-SA.ts +2 -2
  422. package/src/templates/default/app/i18n/de-DE.ts +2 -2
  423. package/src/templates/default/app/i18n/en-US.ts +2 -2
  424. package/src/templates/default/app/i18n/es-ES.ts +2 -2
  425. package/src/templates/default/app/i18n/fr-FR.ts +2 -2
  426. package/src/templates/default/app/i18n/hi-IN.ts +2 -2
  427. package/src/templates/default/app/i18n/ja-JP.ts +2 -2
  428. package/src/templates/default/app/i18n/ko-KR.ts +2 -2
  429. package/src/templates/default/app/i18n/pt-BR.ts +2 -2
  430. package/src/templates/default/app/i18n/zh-CN.ts +2 -2
  431. package/src/templates/default/app/i18n/zh-TW.ts +1 -1
  432. package/src/templates/default/package.json +1 -0
  433. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +23 -3
  434. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  435. package/src/templates/headless/agent-native.json +9 -0
  436. package/src/templates/headless/package.json +2 -0
  437. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +23 -3
  438. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +16 -0
  439. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +23 -2
  440. package/src/templates/workspace-core/.agents/skills/frontend-design/references/visual-direction.md +99 -0
  441. package/src/templates/workspace-core/AGENTS.md +3 -0
  442. package/src/templates/workspace-core/DESIGN.md +35 -0
  443. package/src/templates/workspace-root/AGENTS.md +3 -0
  444. package/src/templates/workspace-root/DESIGN.md +35 -0
  445. package/src/templates/workspace-root/agent-native.json +9 -0
  446. package/src/templates/workspace-root/package.json +3 -0
@@ -4,6 +4,7 @@ import { and, eq, isNull } from "drizzle-orm";
4
4
  import { z } from "zod";
5
5
 
6
6
  import { getDb, schema } from "../server/db/index.js";
7
+ import { numericDesignDataWriteError } from "../shared/canvas-frames.js";
7
8
 
8
9
  const MAX_DATA_CAS_ATTEMPTS = 5;
9
10
  const MAX_DATA_OPERATION_SOURCES = 128;
@@ -26,17 +27,63 @@ const dataPathSchema = z
26
27
  .min(1)
27
28
  .max(8);
28
29
 
29
- const dataOperationSchema = z.discriminatedUnion("op", [
30
- z.object({
31
- op: z.literal("set"),
32
- path: dataPathSchema,
33
- value: z.json(),
34
- }),
35
- z.object({
36
- op: z.literal("delete"),
37
- path: dataPathSchema,
38
- }),
39
- ]);
30
+ const dataOperationSchema = z
31
+ .discriminatedUnion("op", [
32
+ z.object({
33
+ op: z.literal("set"),
34
+ path: dataPathSchema,
35
+ value: z.json(),
36
+ }),
37
+ z.object({
38
+ op: z.literal("delete"),
39
+ path: dataPathSchema,
40
+ }),
41
+ ])
42
+ .superRefine((operation, context) => {
43
+ if (operation.op !== "set") return;
44
+ const message = numericDesignDataWriteError(
45
+ operation.path,
46
+ operation.value,
47
+ );
48
+ if (message) {
49
+ context.addIssue({ code: "custom", path: ["value"], message });
50
+ }
51
+ });
52
+
53
+ const agentDataOperationSchema = z
54
+ .discriminatedUnion("op", [
55
+ z.object({
56
+ op: z.literal("set"),
57
+ path: dataPathSchema,
58
+ value: z
59
+ .union([
60
+ z.number(),
61
+ z.boolean(),
62
+ z.string(),
63
+ z.null(),
64
+ z.array(z.unknown()),
65
+ z.record(z.string(), z.unknown()),
66
+ ])
67
+ .describe(
68
+ "Value to set. Geometry and dimensions (x, y, width, height, rotation, z) " +
69
+ 'are JSON numbers: 800, never "800" or "800px".',
70
+ ),
71
+ }),
72
+ z.object({
73
+ op: z.literal("delete"),
74
+ path: dataPathSchema,
75
+ }),
76
+ ])
77
+ .superRefine((operation, context) => {
78
+ if (operation.op !== "set") return;
79
+ const message = numericDesignDataWriteError(
80
+ operation.path,
81
+ operation.value,
82
+ );
83
+ if (message) {
84
+ context.addIssue({ code: "custom", path: ["value"], message });
85
+ }
86
+ });
40
87
 
41
88
  type DataOperation = z.infer<typeof dataOperationSchema>;
42
89
 
@@ -195,7 +242,9 @@ export default defineAction({
195
242
  "Update an existing design project. Requires editor access. " +
196
243
  "Only provided fields are updated; omitted fields are left unchanged. " +
197
244
  "For map entries such as canvasFrames, use dataOperations " +
198
- "with explicit set/delete paths instead of a full data snapshot.",
245
+ "with explicit set/delete paths instead of a full data snapshot. " +
246
+ "Dimensions and positions (x, y, width, height, rotation, z) are " +
247
+ "numbers. String values are rejected.",
199
248
  schema: z
200
249
  .object({
201
250
  id: z.string().describe("Design ID"),
@@ -213,7 +262,7 @@ export default defineAction({
213
262
  .max(500)
214
263
  .optional()
215
264
  .describe(
216
- "Atomic path-addressed set/delete operations for design data. Safe to CAS-retry across concurrent writers.",
265
+ "Atomic path-addressed set/delete operations for design data. Safe to CAS-retry across concurrent writers. Geometry values must be numbers, not strings.",
217
266
  ),
218
267
  operationSource: z
219
268
  .string()
@@ -272,6 +321,32 @@ export default defineAction({
272
321
  });
273
322
  }
274
323
  }),
324
+ // Advertised to the model only; `schema` above stays the validator. Drops
325
+ // operationSource/operationRevision, which order writes from one browser tab
326
+ // and have no meaning for an agent call.
327
+ agentInputSchema: z.object({
328
+ id: z.string().describe("Design ID"),
329
+ title: z.string().optional().describe("New title"),
330
+ description: z.string().optional().describe("New description"),
331
+ dataOperations: z
332
+ .array(agentDataOperationSchema)
333
+ .min(1)
334
+ .max(500)
335
+ .optional()
336
+ .describe(
337
+ "Atomic path-addressed set/delete operations for design data. Geometry values must be numbers, not strings.",
338
+ ),
339
+ projectType: z
340
+ .enum(["prototype", "other"])
341
+ .optional()
342
+ .describe("Updated project type"),
343
+ designSystemId: z
344
+ .string()
345
+ .min(1)
346
+ .nullable()
347
+ .optional()
348
+ .describe("Design system ID to link, or null to unlink"),
349
+ }),
275
350
  run: async ({
276
351
  id,
277
352
  title,
@@ -284,11 +359,18 @@ export default defineAction({
284
359
  designSystemId,
285
360
  }) => {
286
361
  if (data !== undefined) {
362
+ let parsedSnapshot: unknown;
287
363
  try {
288
- JSON.parse(data);
364
+ parsedSnapshot = JSON.parse(data);
289
365
  } catch {
290
366
  throw new Error("data must be a valid JSON string");
291
367
  }
368
+ if (isRecord(parsedSnapshot)) {
369
+ for (const [key, value] of Object.entries(parsedSnapshot)) {
370
+ const message = numericDesignDataWriteError([key], value);
371
+ if (message) throw new Error(message);
372
+ }
373
+ }
292
374
  }
293
375
 
294
376
  await assertAccess("design", id, "editor");
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 1,
3
+ "onboarding": {
4
+ "firstRun": {
5
+ "development": "off",
6
+ "production": "connect-and-integrations"
7
+ }
8
+ },
9
+ "doctor": {
10
+ "failOnBuild": false
11
+ }
12
+ }
@@ -37,6 +37,7 @@ import {
37
37
  getFigmaConnectionStatus,
38
38
  saveFigmaAccessToken,
39
39
  } from "@/lib/figma-connection";
40
+ import { MAX_UPLOAD_MB } from "@/lib/upload-limits";
40
41
  import { cn } from "@/lib/utils";
41
42
 
42
43
  import type { DesignExtensionSlotContext } from "./DesignExtensionsPanel";
@@ -307,7 +308,9 @@ export function DesignImportPanel(p: DesignImportPanelProps) {
307
308
  }
308
309
  if (validationError === "too-large") {
309
310
  toast.error(t("designEditor.import.errors.uploadFailed"), {
310
- description: t("designEditor.import.errors.figFileTooLarge"),
311
+ description: t("designEditor.import.errors.figFileTooLarge", {
312
+ max: MAX_UPLOAD_MB,
313
+ }),
311
314
  });
312
315
  if (figFileInputRef.current) figFileInputRef.current.value = "";
313
316
  return;
@@ -566,7 +569,9 @@ export function DesignImportPanel(p: DesignImportPanelProps) {
566
569
  >
567
570
  <div className="space-y-2 p-2">
568
571
  <p className="text-[11px] leading-snug text-muted-foreground">
569
- {t("designEditor.import.figUploadDescription")}
572
+ {t("designEditor.import.figUploadDescription", {
573
+ max: MAX_UPLOAD_MB,
574
+ })}
570
575
  </p>
571
576
  <input
572
577
  ref={figFileInputRef}
@@ -29,6 +29,7 @@ import {
29
29
  getFigmaConnectionStatus,
30
30
  saveFigmaAccessToken,
31
31
  } from "@/lib/figma-connection";
32
+ import { MAX_UPLOAD_MB } from "@/lib/upload-limits";
32
33
 
33
34
  interface FigmaHydrationDialogProps {
34
35
  open: boolean;
@@ -70,8 +71,16 @@ export function FigmaHydrationDialog({
70
71
  const file = e.target.files?.[0];
71
72
  e.target.value = "";
72
73
  if (!file) return;
73
- if (validateFigUploadFile(file)) {
74
- setError(t("designEditor.import.figmaHydrationInvalidFig"));
74
+ const validationError = validateFigUploadFile(file);
75
+ if (validationError) {
76
+ setError(
77
+ t(
78
+ validationError === "too-large"
79
+ ? "designEditor.import.errors.figFileTooLarge"
80
+ : "designEditor.import.figmaHydrationInvalidFig",
81
+ { max: MAX_UPLOAD_MB },
82
+ ),
83
+ );
75
84
  return;
76
85
  }
77
86
  setBusy(true);
@@ -187,7 +187,7 @@ function MakeItRealCard({
187
187
  const summary =
188
188
  cta.kind === "configure-project"
189
189
  ? `Choose a Builder project to enable ${featureLabel}.`
190
- : `Connect Builder to enable ${featureLabel}.`;
190
+ : `Connect Builder (free tier available) to enable ${featureLabel}.`;
191
191
  const primaryLabel =
192
192
  cta.kind === "configure-project"
193
193
  ? t("designEditor.makeItRealCard.choose")
@@ -52,6 +52,7 @@ import {
52
52
  TooltipContent,
53
53
  TooltipTrigger,
54
54
  } from "@/components/ui/tooltip";
55
+ import { MAX_UPLOAD_BYTES, MAX_UPLOAD_MB } from "@/lib/upload-limits";
55
56
  import { cn } from "@/lib/utils";
56
57
 
57
58
  export interface UploadedFile {
@@ -513,6 +514,12 @@ export default function PromptPopover({
513
514
  const uploadFiles = useCallback(
514
515
  async (files: File[]): Promise<UploadedFile[]> => {
515
516
  if (files.length === 0) return [];
517
+ const totalBytes = files.reduce((sum, file) => sum + file.size, 0);
518
+ if (totalBytes > MAX_UPLOAD_BYTES) {
519
+ throw new Error(
520
+ t("promptDialog.attachmentsTooLarge", { max: MAX_UPLOAD_MB }),
521
+ );
522
+ }
516
523
  setUploading(true);
517
524
  try {
518
525
  const formData = new FormData();
@@ -552,7 +559,7 @@ export default function PromptPopover({
552
559
  setUploading(false);
553
560
  }
554
561
  },
555
- [],
562
+ [t],
556
563
  );
557
564
 
558
565
  const handleSubmit = useCallback(
@@ -635,7 +635,7 @@ const enUS = {
635
635
  figmaHydrationFigError: "Couldn't read images from that .fig file.",
636
636
  figUploadTitle: "Upload .fig",
637
637
  figUploadDescription:
638
- "Local import using Figma's .fig format — no API quota. Embedded images are included. Format may change between Figma versions. Maximum 50 MB.",
638
+ "Local import using Figma's .fig format — no API quota. Embedded images are included. Format may change between Figma versions. Maximum {{max}} MB.",
639
639
  chooseFigFile: "Choose .fig file",
640
640
  figUploadUploading: "Uploading {{progress}}%",
641
641
  figUploadProcessing: "Converting…",
@@ -683,7 +683,8 @@ const enUS = {
683
683
  figmaPasteFailed: "Figma paste import failed",
684
684
  uploadFailed: "File upload failed",
685
685
  invalidFigFile: "Choose a file ending in .fig.",
686
- figFileTooLarge: ".fig files must be 50 MB or smaller.",
686
+ figFileTooLarge:
687
+ "That .fig is too large — uploads are limited to {{max}} MB. In Figma, copy just the frame you want into a new file and export that as .fig, or use Paste from Figma instead.",
687
688
  },
688
689
  },
689
690
  generationMayHaveStopped:
@@ -1249,6 +1250,8 @@ const enUS = {
1249
1250
  assetAdded: "Asset added",
1250
1251
  assetsNoImageUrl: "Assets did not return an image URL.",
1251
1252
  failedToUploadFile: "Failed to upload file",
1253
+ attachmentsTooLarge:
1254
+ "Those attachments are too large. Uploads are limited to {{max}} MB in total — attach fewer or smaller files.",
1252
1255
  failedToSubmitPrompt: "Failed to submit prompt",
1253
1256
  skipPrompt: "Skip prompt",
1254
1257
  designSystem: "Design system",
@@ -5590,6 +5593,8 @@ const designRawLiteralOverrides = {
5590
5593
  assetAdded: "添加资产",
5591
5594
  assetsNoImageUrl: "Assets 未返回图片 URL。",
5592
5595
  failedToUploadFile: "上传文件失败",
5596
+ attachmentsTooLarge:
5597
+ "这些附件太大。上传总大小上限为 {{max}} MB — 请减少文件数量或使用更小的文件。",
5593
5598
  designSystem: "Design系统",
5594
5599
  noDesignSystem: "没有设计系统",
5595
5600
  newDesignSystem: "新",
@@ -5749,6 +5754,8 @@ const designRawLiteralOverrides = {
5749
5754
  assetAdded: "Activo agregado",
5750
5755
  assetsNoImageUrl: "Assets no devolvió una URL de imagen.",
5751
5756
  failedToUploadFile: "No se pudo cargar el archivo",
5757
+ attachmentsTooLarge:
5758
+ "Esos adjuntos son demasiado grandes. Las subidas están limitadas a {{max}} MB en total: adjunta menos archivos o más pequeños.",
5752
5759
  designSystem: "sistema Design",
5753
5760
  noDesignSystem: "Sin sistema de diseño",
5754
5761
  newDesignSystem: "Nuevo",
@@ -5912,6 +5919,8 @@ const designRawLiteralOverrides = {
5912
5919
  assetAdded: "Actif ajouté",
5913
5920
  assetsNoImageUrl: "Assets n'a pas renvoyé d'URL d'image.",
5914
5921
  failedToUploadFile: "Échec du téléchargement du fichier",
5922
+ attachmentsTooLarge:
5923
+ "Ces pièces jointes sont trop volumineuses. Les téléversements sont limités à {{max}} Mo au total : joignez moins de fichiers ou des fichiers plus petits.",
5915
5924
  designSystem: "Système Design",
5916
5925
  noDesignSystem: "Aucun système de conception",
5917
5926
  newDesignSystem: "Nouveau",
@@ -6075,6 +6084,8 @@ const designRawLiteralOverrides = {
6075
6084
  assetAdded: "Asset hinzugefügt",
6076
6085
  assetsNoImageUrl: "Assets hat keine Bild-URL zurückgegeben.",
6077
6086
  failedToUploadFile: "Datei konnte nicht hochgeladen werden",
6087
+ attachmentsTooLarge:
6088
+ "Diese Anhänge sind zu groß. Uploads sind auf insgesamt {{max}} MB begrenzt – hänge weniger oder kleinere Dateien an.",
6078
6089
  designSystem: "Design-System",
6079
6090
  noDesignSystem: "Kein Designsystem",
6080
6091
  newDesignSystem: "Neu",
@@ -6238,6 +6249,8 @@ const designRawLiteralOverrides = {
6238
6249
  assetAdded: "アセットが追加されました",
6239
6250
  assetsNoImageUrl: "Assets が画像 URL を返しませんでした。",
6240
6251
  failedToUploadFile: "ファイルのアップロードに失敗しました",
6252
+ attachmentsTooLarge:
6253
+ "添付ファイルが大きすぎます。アップロードは合計 {{max}} MB までです。ファイル数を減らすか、より小さいファイルを添付してください。",
6241
6254
  designSystem: "Designシステム",
6242
6255
  noDesignSystem: "デザインシステムがない",
6243
6256
  newDesignSystem: "新しい",
@@ -6396,6 +6409,8 @@ const designRawLiteralOverrides = {
6396
6409
  assetAdded: "자산이 추가됨",
6397
6410
  assetsNoImageUrl: "Assets에서 이미지 URL을 반환하지 않았습니다.",
6398
6411
  failedToUploadFile: "파일을 업로드하지 못했습니다.",
6412
+ attachmentsTooLarge:
6413
+ "첨부 파일이 너무 큽니다. 업로드는 총 {{max}}MB까지 지원됩니다. 파일 수를 줄이거나 더 작은 파일을 첨부하세요.",
6399
6414
  designSystem: "Design 시스템",
6400
6415
  noDesignSystem: "디자인 시스템 없음",
6401
6416
  newDesignSystem: "새로운",
@@ -6556,6 +6571,8 @@ const designRawLiteralOverrides = {
6556
6571
  assetAdded: "Recurso adicionado",
6557
6572
  assetsNoImageUrl: "Assets não retornou uma URL de imagem.",
6558
6573
  failedToUploadFile: "Falha ao carregar o arquivo",
6574
+ attachmentsTooLarge:
6575
+ "Esses anexos são grandes demais. Os envios são limitados a {{max}} MB no total — anexe menos arquivos ou arquivos menores.",
6559
6576
  designSystem: "Sistema Design",
6560
6577
  noDesignSystem: "Nenhum sistema de design",
6561
6578
  newDesignSystem: "Novo",
@@ -6717,6 +6734,8 @@ const designRawLiteralOverrides = {
6717
6734
  assetAdded: "संपत्ति जोड़ी गई",
6718
6735
  assetsNoImageUrl: "Assets ने कोई छवि URL नहीं लौटाया।",
6719
6736
  failedToUploadFile: "फ़ाइल अपलोड करने में विफल",
6737
+ attachmentsTooLarge:
6738
+ "ये attachments बहुत बड़े हैं। Uploads की कुल सीमा {{max}} MB है — कम या छोटी files attach करें।",
6720
6739
  designSystem: "Design प्रणाली",
6721
6740
  noDesignSystem: "कोई डिज़ाइन प्रणाली नहीं",
6722
6741
  newDesignSystem: "नया",
@@ -6875,6 +6894,8 @@ const designRawLiteralOverrides = {
6875
6894
  assetAdded: "تمت إضافة الأصول",
6876
6895
  assetsNoImageUrl: "لم تُرجع Assets عنوان URL للصورة.",
6877
6896
  failedToUploadFile: "فشل تحميل الملف",
6897
+ attachmentsTooLarge:
6898
+ "المرفقات كبيرة جدًا. الحد الأقصى للرفع هو {{max}} ميغابايت إجمالًا — أرفق ملفات أقل أو أصغر.",
6878
6899
  designSystem: "نظام Design",
6879
6900
  noDesignSystem: "لا يوجد نظام التصميم",
6880
6901
  newDesignSystem: "جديد",
@@ -12233,7 +12254,7 @@ const designImportOverrides = {
12233
12254
  "已從 Figma 填入 {{count}} 個圖片{{plural}}。",
12234
12255
  figUploadTitle: "上傳 .fig",
12235
12256
  figUploadDescription:
12236
- "實驗性功能:Figma 的 .fig 格式為專有格式且可能變更。支援的圖層會轉為可編輯螢幕,部分功能可能不同。上限為 50 MB。",
12257
+ "實驗性功能:Figma 的 .fig 格式為專有格式且可能變更。支援的圖層會轉為可編輯螢幕,部分功能可能不同。上限為 {{max}} MB。",
12237
12258
  chooseFigFile: "選擇 .fig 檔案",
12238
12259
  figUploadUploading: "上傳中 {{progress}}%",
12239
12260
  figUploadProcessing: "轉換中…",
@@ -12265,7 +12286,8 @@ const designImportOverrides = {
12265
12286
  figmaPasteFailed: "Figma 貼上匯入失敗",
12266
12287
  uploadFailed: "檔案上傳失敗",
12267
12288
  invalidFigFile: "請選擇副檔名為 .fig 的檔案。",
12268
- figFileTooLarge: ".fig 檔案必須為 50 MB 或更小。",
12289
+ figFileTooLarge:
12290
+ "此 .fig 檔案太大 — 上傳上限為 {{max}} MB。請在 Figma 中將要匯入的畫框複製到新檔案,並匯出該檔案為 .fig,或改用「從 Figma 貼上」。",
12269
12291
  },
12270
12292
  },
12271
12293
  },
@@ -12296,7 +12318,7 @@ const designImportOverrides = {
12296
12318
  "已从 Figma 填入 {{count}} 张图片{{plural}}。",
12297
12319
  figUploadTitle: "上传 .fig",
12298
12320
  figUploadDescription:
12299
- "实验性功能:Figma 的 .fig 格式为专有格式且可能变化。支持的图层会转换为可编辑屏幕,部分功能可能有所不同。最大 50 MB。",
12321
+ "实验性功能:Figma 的 .fig 格式为专有格式且可能变化。支持的图层会转换为可编辑屏幕,部分功能可能有所不同。最大 {{max}} MB。",
12300
12322
  chooseFigFile: "选择 .fig 文件",
12301
12323
  figUploadUploading: "正在上传 {{progress}}%",
12302
12324
  figUploadProcessing: "正在转换…",
@@ -12328,7 +12350,8 @@ const designImportOverrides = {
12328
12350
  figmaPasteFailed: "Figma 粘贴导入失败",
12329
12351
  uploadFailed: "文件上传失败",
12330
12352
  invalidFigFile: "请选择以 .fig 结尾的文件。",
12331
- figFileTooLarge: ".fig 文件必须为 50 MB 或更小。",
12353
+ figFileTooLarge:
12354
+ "该 .fig 文件太大 — 上传上限为 {{max}} MB。请在 Figma 中将需要导入的画板复制到新文件,然后导出该文件为 .fig,或改用“从 Figma 粘贴”。",
12332
12355
  },
12333
12356
  },
12334
12357
  },
@@ -12362,7 +12385,7 @@ const designImportOverrides = {
12362
12385
  "{{count}} imagen{{plural}} rellenada{{plural}} desde Figma.",
12363
12386
  figUploadTitle: "Subir .fig",
12364
12387
  figUploadDescription:
12365
- "Experimental: el formato .fig de Figma es propietario y puede cambiar. Las capas compatibles se convierten en pantallas editables; algunas funciones pueden variar. Máximo 50 MB.",
12388
+ "Experimental: el formato .fig de Figma es propietario y puede cambiar. Las capas compatibles se convierten en pantallas editables; algunas funciones pueden variar. Máximo {{max}} MB.",
12366
12389
  chooseFigFile: "Elegir archivo .fig",
12367
12390
  figUploadUploading: "Subiendo {{progress}}%",
12368
12391
  figUploadProcessing: "Convirtiendo…",
@@ -12396,7 +12419,8 @@ const designImportOverrides = {
12396
12419
  figmaPasteFailed: "Error al importar el pegado de Figma",
12397
12420
  uploadFailed: "Error al subir el archivo",
12398
12421
  invalidFigFile: "Elige un archivo que termine en .fig.",
12399
- figFileTooLarge: "Los archivos .fig deben tener 50 MB o menos.",
12422
+ figFileTooLarge:
12423
+ "Ese .fig es demasiado grande: las subidas están limitadas a {{max}} MB. En Figma, copia solo el frame que quieras a un archivo nuevo y exporta ese archivo como .fig, o usa Pegar desde Figma.",
12400
12424
  },
12401
12425
  },
12402
12426
  },
@@ -12430,7 +12454,7 @@ const designImportOverrides = {
12430
12454
  "{{count}} image{{plural}} remplie{{plural}} depuis Figma.",
12431
12455
  figUploadTitle: "Téléverser .fig",
12432
12456
  figUploadDescription:
12433
- "Expérimental : le format .fig de Figma est propriétaire et peut évoluer. Les calques pris en charge deviennent des écrans modifiables ; certaines fonctions peuvent différer. Maximum 50 Mo.",
12457
+ "Expérimental : le format .fig de Figma est propriétaire et peut évoluer. Les calques pris en charge deviennent des écrans modifiables ; certaines fonctions peuvent différer. Maximum {{max}} Mo.",
12434
12458
  chooseFigFile: "Choisir un fichier .fig",
12435
12459
  figUploadUploading: "Téléversement {{progress}} %",
12436
12460
  figUploadProcessing: "Conversion…",
@@ -12464,7 +12488,8 @@ const designImportOverrides = {
12464
12488
  figmaPasteFailed: "Échec de l’import du collage Figma",
12465
12489
  uploadFailed: "Échec du téléversement",
12466
12490
  invalidFigFile: "Choisissez un fichier se terminant par .fig.",
12467
- figFileTooLarge: "Les fichiers .fig doivent faire 50 Mo ou moins.",
12491
+ figFileTooLarge:
12492
+ "Ce .fig est trop volumineux : les téléversements sont limités à {{max}} Mo. Dans Figma, copiez uniquement le frame souhaité dans un nouveau fichier et exportez ce fichier en .fig, ou utilisez Coller depuis Figma.",
12468
12493
  },
12469
12494
  },
12470
12495
  },
@@ -12498,7 +12523,7 @@ const designImportOverrides = {
12498
12523
  "{{count}} Bild{{plural}} aus Figma ausgefüllt.",
12499
12524
  figUploadTitle: ".fig hochladen",
12500
12525
  figUploadDescription:
12501
- "Experimentell: Das .fig-Format von Figma ist proprietär und kann sich ändern. Unterstützte Ebenen werden zu bearbeitbaren Screens; einige Funktionen können abweichen. Maximal 50 MB.",
12526
+ "Experimentell: Das .fig-Format von Figma ist proprietär und kann sich ändern. Unterstützte Ebenen werden zu bearbeitbaren Screens; einige Funktionen können abweichen. Maximal {{max}} MB.",
12502
12527
  chooseFigFile: ".fig-Datei wählen",
12503
12528
  figUploadUploading: "Wird hochgeladen: {{progress}} %",
12504
12529
  figUploadProcessing: "Wird konvertiert…",
@@ -12531,7 +12556,8 @@ const designImportOverrides = {
12531
12556
  figmaPasteFailed: "Figma-Einfügeimport fehlgeschlagen",
12532
12557
  uploadFailed: "Dateiupload fehlgeschlagen",
12533
12558
  invalidFigFile: "Wähle eine Datei mit der Endung .fig.",
12534
- figFileTooLarge: ".fig-Dateien dürfen höchstens 50 MB groß sein.",
12559
+ figFileTooLarge:
12560
+ "Diese .fig-Datei ist zu groß – Uploads sind auf {{max}} MB begrenzt. Kopiere in Figma nur den gewünschten Frame in eine neue Datei und exportiere diese als .fig, oder nutze „Aus Figma einfügen“.",
12535
12561
  },
12536
12562
  },
12537
12563
  },
@@ -12565,7 +12591,7 @@ const designImportOverrides = {
12565
12591
  "Figma から {{count}} 枚の画像{{plural}}が入力されました。",
12566
12592
  figUploadTitle: ".fig をアップロード",
12567
12593
  figUploadDescription:
12568
- "試験的機能:Figma の .fig 形式は独自仕様で、変更される可能性があります。対応レイヤーは編集可能な画面になりますが、一部の機能は異なる場合があります。最大 50 MB。",
12594
+ "試験的機能:Figma の .fig 形式は独自仕様で、変更される可能性があります。対応レイヤーは編集可能な画面になりますが、一部の機能は異なる場合があります。最大 {{max}} MB。",
12569
12595
  chooseFigFile: ".fig ファイルを選択",
12570
12596
  figUploadUploading: "アップロード中 {{progress}}%",
12571
12597
  figUploadProcessing: "変換中…",
@@ -12599,7 +12625,8 @@ const designImportOverrides = {
12599
12625
  figmaPasteFailed: "Figma 貼り付けのインポートに失敗しました",
12600
12626
  uploadFailed: "ファイルのアップロードに失敗しました",
12601
12627
  invalidFigFile: ".fig で終わるファイルを選択してください。",
12602
- figFileTooLarge: ".fig ファイルは 50 MB 以下にしてください。",
12628
+ figFileTooLarge:
12629
+ "この .fig ファイルは大きすぎます。アップロードは {{max}} MB までです。Figma で目的のフレームだけを新しいファイルにコピーし、そのファイルを .fig として書き出すか、「Figma から貼り付け」をご利用ください。",
12603
12630
  },
12604
12631
  },
12605
12632
  },
@@ -12632,7 +12659,7 @@ const designImportOverrides = {
12632
12659
  "Figma에서 {{count}}개의 이미지{{plural}}가 채워졌습니다.",
12633
12660
  figUploadTitle: ".fig 업로드",
12634
12661
  figUploadDescription:
12635
- "실험적 기능: Figma의 .fig 형식은 독점 형식이며 변경될 수 있습니다. 지원되는 레이어는 편집 가능한 화면으로 변환되지만 일부 기능은 다를 수 있습니다. 최대 50MB.",
12662
+ "실험적 기능: Figma의 .fig 형식은 독점 형식이며 변경될 수 있습니다. 지원되는 레이어는 편집 가능한 화면으로 변환되지만 일부 기능은 다를 수 있습니다. 최대 {{max}}MB.",
12636
12663
  chooseFigFile: ".fig 파일 선택",
12637
12664
  figUploadUploading: "업로드 중 {{progress}}%",
12638
12665
  figUploadProcessing: "변환 중…",
@@ -12666,7 +12693,8 @@ const designImportOverrides = {
12666
12693
  figmaPasteFailed: "Figma 붙여넣기 가져오기 실패",
12667
12694
  uploadFailed: "파일 업로드 실패",
12668
12695
  invalidFigFile: ".fig로 끝나는 파일을 선택하세요.",
12669
- figFileTooLarge: ".fig 파일은 50MB 이하여야 합니다.",
12696
+ figFileTooLarge:
12697
+ "이 .fig 파일은 너무 큽니다. 업로드는 {{max}}MB까지 지원됩니다. Figma에서 원하는 프레임만 새 파일로 복사한 뒤 그 파일을 .fig로 내보내거나, 'Figma에서 붙여넣기'를 사용하세요.",
12670
12698
  },
12671
12699
  },
12672
12700
  },
@@ -12701,7 +12729,7 @@ const designImportOverrides = {
12701
12729
  "{{count}} imagem{{plural}} preenchida{{plural}} do Figma.",
12702
12730
  figUploadTitle: "Enviar .fig",
12703
12731
  figUploadDescription:
12704
- "Experimental: o formato .fig do Figma é proprietário e pode mudar. As camadas compatíveis viram telas editáveis; alguns recursos podem ser diferentes. Máximo de 50 MB.",
12732
+ "Experimental: o formato .fig do Figma é proprietário e pode mudar. As camadas compatíveis viram telas editáveis; alguns recursos podem ser diferentes. Máximo de {{max}} MB.",
12705
12733
  chooseFigFile: "Escolher arquivo .fig",
12706
12734
  figUploadUploading: "Enviando {{progress}}%",
12707
12735
  figUploadProcessing: "Convertendo…",
@@ -12735,7 +12763,8 @@ const designImportOverrides = {
12735
12763
  figmaPasteFailed: "Falha ao importar colagem do Figma",
12736
12764
  uploadFailed: "Falha no upload do arquivo",
12737
12765
  invalidFigFile: "Escolha um arquivo que termine em .fig.",
12738
- figFileTooLarge: "Arquivos .fig devem ter 50 MB ou menos.",
12766
+ figFileTooLarge:
12767
+ "Esse .fig é grande demais — os envios são limitados a {{max}} MB. No Figma, copie apenas o frame desejado para um novo arquivo e exporte esse arquivo como .fig, ou use Colar do Figma.",
12739
12768
  },
12740
12769
  },
12741
12770
  },
@@ -12769,7 +12798,7 @@ const designImportOverrides = {
12769
12798
  "Figma से {{count}} छवि{{plural}} भरी गई{{plural}}।",
12770
12799
  figUploadTitle: ".fig अपलोड करें",
12771
12800
  figUploadDescription:
12772
- "प्रायोगिक: Figma का .fig format proprietary है और बदल सकता है। समर्थित layers editable screens बनती हैं; कुछ features अलग हो सकते हैं। अधिकतम 50 MB।",
12801
+ "प्रायोगिक: Figma का .fig format proprietary है और बदल सकता है। समर्थित layers editable screens बनती हैं; कुछ features अलग हो सकते हैं। अधिकतम {{max}} MB।",
12773
12802
  chooseFigFile: ".fig file चुनें",
12774
12803
  figUploadUploading: "अपलोड हो रहा है {{progress}}%",
12775
12804
  figUploadProcessing: "बदला जा रहा है…",
@@ -12803,7 +12832,8 @@ const designImportOverrides = {
12803
12832
  figmaPasteFailed: "Figma paste आयात विफल रहा",
12804
12833
  uploadFailed: "File upload विफल रहा",
12805
12834
  invalidFigFile: ".fig पर समाप्त होने वाली file चुनें।",
12806
- figFileTooLarge: ".fig files 50 MB या उससे छोटी होनी चाहिए।",
12835
+ figFileTooLarge:
12836
+ "यह .fig बहुत बड़ी है — uploads की सीमा {{max}} MB है। Figma में जिस frame को import करना है उसे एक नई file में copy करें और उस file को .fig के रूप में export करें, या Paste from Figma का उपयोग करें।",
12807
12837
  },
12808
12838
  },
12809
12839
  },
@@ -12836,7 +12866,7 @@ const designImportOverrides = {
12836
12866
  "تم ملء {{count}} صورة{{plural}} من Figma.",
12837
12867
  figUploadTitle: "رفع .fig",
12838
12868
  figUploadDescription:
12839
- "ميزة تجريبية: تنسيق .fig في Figma مملوك وقد يتغير. تتحول الطبقات المدعومة إلى شاشات قابلة للتحرير، وقد تختلف بعض الميزات. الحد الأقصى 50 ميغابايت.",
12869
+ "ميزة تجريبية: تنسيق .fig في Figma مملوك وقد يتغير. تتحول الطبقات المدعومة إلى شاشات قابلة للتحرير، وقد تختلف بعض الميزات. الحد الأقصى {{max}} ميغابايت.",
12840
12870
  chooseFigFile: "اختر ملف .fig",
12841
12871
  figUploadUploading: "جار الرفع {{progress}}%",
12842
12872
  figUploadProcessing: "جار التحويل…",
@@ -12869,7 +12899,8 @@ const designImportOverrides = {
12869
12899
  figmaPasteFailed: "فشل استيراد لصق Figma",
12870
12900
  uploadFailed: "فشل رفع الملف",
12871
12901
  invalidFigFile: "اختر ملفا ينتهي بـ .fig.",
12872
- figFileTooLarge: "يجب ألا يتجاوز ملف .fig حجم 50 ميغابايت.",
12902
+ figFileTooLarge:
12903
+ "ملف ‎.fig‎ كبير جدًا — الحد الأقصى للرفع {{max}} ميغابايت. في Figma، انسخ الإطار المطلوب فقط إلى ملف جديد وصدّر ذلك الملف بصيغة ‎.fig‎، أو استخدم اللصق من Figma.",
12873
12904
  },
12874
12905
  },
12875
12906
  },
@@ -1,6 +1,5 @@
1
1
  import { parseUploadResponse, type ImportResult } from "@/lib/design-import";
2
-
3
- export const MAX_FIG_UPLOAD_BYTES = 50 * 1024 * 1024;
2
+ import { MAX_UPLOAD_BYTES } from "@/lib/upload-limits";
4
3
 
5
4
  export type FigUploadValidationError = "invalid-extension" | "too-large";
6
5
 
@@ -8,7 +7,7 @@ export function validateFigUploadFile(
8
7
  file: Pick<File, "name" | "size">,
9
8
  ): FigUploadValidationError | null {
10
9
  if (!file.name.toLowerCase().endsWith(".fig")) return "invalid-extension";
11
- if (file.size > MAX_FIG_UPLOAD_BYTES) return "too-large";
10
+ if (file.size > MAX_UPLOAD_BYTES) return "too-large";
12
11
  return null;
13
12
  }
14
13
 
@@ -0,0 +1,4 @@
1
+ /** Mirrors the server wire cap in `server/lib/request-body-limits.ts`; the two
2
+ * are held together by the alignment test in `design-file-upload.test.ts`. */
3
+ export const MAX_UPLOAD_BYTES = 4 * 1024 * 1024;
4
+ export const MAX_UPLOAD_MB = MAX_UPLOAD_BYTES / 1024 / 1024;
@@ -450,7 +450,7 @@ export default function DesignSystemSetup() {
450
450
 
451
451
  if (normalizedGithubLinks.length > 0) {
452
452
  parts.push(
453
- `\n## Connect Code: GitHub Repositories\nStart Builder DSI indexing for each repository with \`index-design-system-with-builder\`:\n${normalizedGithubLinks.map((l) => `- ${l.url}`).join("\n")}\n\nBuilder is the source of truth for repo/code design-system indexing. The action also creates a local selectable proxy design system for Design flows. If Builder is not connected, stop and tell me to connect Builder from Settings instead of asking me to paste repository credentials into chat.`,
453
+ `\n## Connect Code: GitHub Repositories\nStart Builder DSI indexing for each repository with \`index-design-system-with-builder\`:\n${normalizedGithubLinks.map((l) => `- ${l.url}`).join("\n")}\n\nBuilder is the source of truth for repo/code design-system indexing. The action also creates a local selectable proxy design system for Design flows. If Builder is not connected, stop and tell me to connect Builder (free tier available) from Settings instead of asking me to paste repository credentials into chat.`,
454
454
  );
455
455
  }
456
456
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-05
4
+ ---
5
+
6
+ Chat attachments now warn before upload when they exceed the 4 MB total limit, instead of failing with an unexplained error.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-05
4
+ ---
5
+
6
+ Figma .fig uploads now show a clear 4 MB limit up front instead of failing partway through the upload.
@@ -48,7 +48,7 @@ const evidence = await runWithRequestContext({ userEmail, orgId }, async () => {
48
48
  const localQaStorageEnabled = isLocalFigmaQaUploadEnabled();
49
49
  if (!builderCredential && !localQaStorageEnabled) {
50
50
  throw new Error(
51
- "This QA account has no request-scoped durable upload provider. Connect Builder in Design and retry.",
51
+ "This QA account has no request-scoped durable upload provider. Connect Builder (free tier available) in Design and retry.",
52
52
  );
53
53
  }
54
54
  // The explicit QA flag must deterministically exercise this provider even
@@ -10,15 +10,17 @@ import {
10
10
  setResponseStatus,
11
11
  } from "h3";
12
12
 
13
- import { MAX_FIG_FILE_BYTES } from "../lib/fig-file-limits.js";
14
13
  import {
15
14
  normalizeImportedHtmlDocument,
16
15
  saveImportedDesignFiles,
17
16
  } from "../lib/import-design-files.js";
17
+ import {
18
+ MAX_UPLOAD_BYTES,
19
+ MAX_UPLOAD_MB,
20
+ TOTAL_BODY_LIMIT,
21
+ } from "../lib/request-body-limits.js";
18
22
 
19
23
  const MAX_HTML_BYTES = 2 * 1024 * 1024;
20
- const MULTIPART_OVERHEAD_BYTES = 1024 * 1024;
21
- const TOTAL_BODY_LIMIT = MAX_FIG_FILE_BYTES + MULTIPART_OVERHEAD_BYTES;
22
24
 
23
25
  // Matches the local-kiwi clipboard frame cap so a token-free .fig hydration of
24
26
  // a multi-frame paste can fill every imported screen in one upload.
@@ -130,8 +132,10 @@ export const importDesignFile = defineEventHandler(async (event) => {
130
132
  }
131
133
 
132
134
  if (ext === ".fig") {
133
- if (data.length > MAX_FIG_FILE_BYTES) {
134
- throw new Error(".fig file is too large (max 50 MB).");
135
+ if (data.length > MAX_UPLOAD_BYTES) {
136
+ throw new Error(
137
+ `.fig file is too large (max ${MAX_UPLOAD_MB} MB). In Figma, copy just the frame you want into a new file and export that as .fig.`,
138
+ );
135
139
  }
136
140
 
137
141
  // Token-free hydration: fill the image placeholders left by a no-token