@agent-native/core 0.127.3 → 0.128.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +101 -0
  3. package/corpus/core/README.md +5 -26
  4. package/corpus/core/docs/content/actions.mdx +47 -4
  5. package/corpus/core/docs/content/native-chat-ui.mdx +7 -0
  6. package/corpus/core/docs/content/organizations-teams-permissions.mdx +109 -3
  7. package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  8. package/corpus/core/docs/content/toolkit-org-team.mdx +72 -12
  9. package/corpus/core/package.json +2 -1
  10. package/corpus/core/src/a2a/artifact-response.ts +36 -29
  11. package/corpus/core/src/action.ts +83 -2
  12. package/corpus/core/src/chat-threads/store.ts +48 -43
  13. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  14. package/corpus/core/src/client/AgentPanel.tsx +26 -6
  15. package/corpus/core/src/client/AssistantChat.tsx +63 -7
  16. package/corpus/core/src/client/DefaultSpinner.tsx +29 -0
  17. package/corpus/core/src/client/org/TeamPage.tsx +161 -6
  18. package/corpus/core/src/client/org/hooks.ts +67 -0
  19. package/corpus/core/src/client/org/index.ts +9 -0
  20. package/corpus/core/src/client/transcription/use-live-transcription.ts +62 -10
  21. package/corpus/core/src/db/client.ts +42 -3
  22. package/corpus/core/src/db/ensure-additive-columns.ts +60 -33
  23. package/corpus/core/src/deploy/build.ts +31 -2
  24. package/corpus/core/src/mcp-client/routes.ts +10 -1
  25. package/corpus/core/src/org/app-roles-handlers.ts +152 -0
  26. package/corpus/core/src/org/app-roles.ts +355 -0
  27. package/corpus/core/src/org/index.ts +27 -1
  28. package/corpus/core/src/org/migrations.ts +22 -0
  29. package/corpus/core/src/org/plugin.ts +27 -0
  30. package/corpus/core/src/org/schema.ts +15 -0
  31. package/corpus/core/src/scripts/docs/search.ts +17 -0
  32. package/corpus/core/src/scripts/docs/source-search.ts +10 -0
  33. package/corpus/core/src/server/agent-chat/script-entries.ts +3 -0
  34. package/corpus/core/src/server/agent-chat-plugin.ts +53 -52
  35. package/corpus/core/src/server/builder-design-systems.ts +299 -82
  36. package/corpus/core/src/server/core-routes-plugin.ts +6 -1
  37. package/corpus/core/src/server/framework-request-handler.ts +44 -6
  38. package/corpus/core/src/server/index.ts +8 -0
  39. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  40. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  41. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  42. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  43. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  44. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  45. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  46. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  47. package/corpus/core/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  48. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -0
  49. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +31 -0
  50. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +4 -0
  51. package/corpus/templates/analytics/_gitignore +2 -0
  52. package/corpus/templates/analytics/actions/data-source-status.ts +21 -12
  53. package/corpus/templates/analytics/app/global.css +7 -7
  54. package/corpus/templates/analytics/app/i18n-data.ts +30 -0
  55. package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -1
  56. package/corpus/templates/analytics/app/pages/DataSources.tsx +54 -10
  57. package/corpus/templates/analytics/changelog/2026-07-28-analytics-pages-load-reliably-with-large-dashboard-workspaces.md +6 -0
  58. package/corpus/templates/analytics/changelog/2026-07-28-dashboard-loading-shimmer-now-flows-smoothly-in-one-directi.md +6 -0
  59. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +5 -4
  60. package/corpus/templates/analytics/server/plugins/agent-chat.ts +54 -42
  61. package/corpus/templates/analytics/server/plugins/db.ts +1 -18
  62. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -0
  63. package/corpus/templates/assets/.agents/skills/security/SKILL.md +31 -0
  64. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +4 -0
  65. package/corpus/templates/assets/_gitignore +2 -0
  66. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -0
  67. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +7 -0
  68. package/corpus/templates/brain/.agents/skills/security/SKILL.md +31 -0
  69. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +4 -0
  70. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -0
  71. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +31 -0
  72. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +4 -0
  73. package/corpus/templates/calendar/_gitignore +2 -0
  74. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  75. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  76. package/corpus/templates/chat/.agents/skills/security/SKILL.md +31 -0
  77. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  78. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -0
  79. package/corpus/templates/clips/.agents/skills/security/SKILL.md +31 -0
  80. package/corpus/templates/clips/_gitignore +2 -0
  81. package/corpus/templates/clips/actions/request-transcript.ts +77 -11
  82. package/corpus/templates/clips/actions/save-browser-transcript.ts +28 -7
  83. package/corpus/templates/clips/app/routes/record.tsx +11 -3
  84. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-save-a-truncated-transcript-as-.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-stop-transcribing-partway-throu.md +6 -0
  86. package/corpus/templates/clips/changelog/2026-07-28-desktop-full-screen-clips-now-get-an-instant-local-transcrip.md +6 -0
  87. package/corpus/templates/clips/changelog/2026-07-28-long-transcriptions-no-longer-show-a-false-transcription-sto.md +6 -0
  88. package/corpus/templates/clips/changelog/2026-07-28-restarting-for-an-update-now-installs-the-newest-release-ins.md +6 -0
  89. package/corpus/templates/clips/changelog/2026-07-28-the-meeting-recording-pill-now-anchors-to-the-right-edge-of-.md +6 -0
  90. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +31 -2
  91. package/corpus/templates/clips/desktop/src/lib/recorder.ts +114 -13
  92. package/corpus/templates/clips/desktop/src/lib/updater.ts +12 -4
  93. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +40 -15
  94. package/corpus/templates/clips/desktop/src/styles.css +10 -7
  95. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -14
  96. package/corpus/templates/clips/shared/transcript-status.ts +10 -0
  97. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -0
  98. package/corpus/templates/content/.agents/skills/security/SKILL.md +31 -0
  99. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +4 -0
  100. package/corpus/templates/content/_gitignore +2 -0
  101. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +4 -0
  102. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -0
  103. package/corpus/templates/design/.agents/skills/security/SKILL.md +31 -0
  104. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +4 -0
  105. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +46 -3
  106. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +7 -5
  107. package/corpus/templates/design/_gitignore +2 -0
  108. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
  109. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -4
  110. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
  111. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +10 -4
  112. package/corpus/templates/design/app/i18n-data.ts +10 -0
  113. package/corpus/templates/design/app/lib/builder-design-system-upload.ts +280 -0
  114. package/corpus/templates/design/app/lib/design-ui-events.ts +5 -0
  115. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +90 -54
  116. package/corpus/templates/design/app/root.tsx +18 -1
  117. package/corpus/templates/design/changelog/2026-07-28-figma-fig-uploads-now-show-indexing-progress-and-an-open-in-.md +6 -0
  118. package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +6 -0
  119. package/corpus/templates/design/server/handlers/design-system-decode-job-status.ts +49 -0
  120. package/corpus/templates/design/server/handlers/design-system-upload-start.ts +87 -0
  121. package/corpus/templates/design/server/handlers/index-design-system-sources.ts +82 -0
  122. package/corpus/templates/design/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  123. package/corpus/templates/design/server/routes/api/design-system-upload-start.post.ts +1 -0
  124. package/corpus/templates/design/server/routes/api/index-design-system-sources.post.ts +1 -0
  125. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -0
  126. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +31 -0
  127. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +4 -0
  128. package/corpus/templates/dispatch/_gitignore +2 -0
  129. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -0
  130. package/corpus/templates/forms/.agents/skills/security/SKILL.md +31 -0
  131. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +4 -0
  132. package/corpus/templates/forms/_gitignore +2 -0
  133. package/corpus/templates/macros/.agents/skills/security/SKILL.md +31 -0
  134. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +4 -0
  135. package/corpus/templates/macros/_gitignore +2 -0
  136. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -0
  137. package/corpus/templates/mail/.agents/skills/security/SKILL.md +31 -0
  138. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +4 -0
  139. package/corpus/templates/mail/_gitignore +2 -0
  140. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -0
  141. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +7 -0
  142. package/corpus/templates/plan/.agents/skills/security/SKILL.md +31 -0
  143. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +4 -0
  144. package/corpus/templates/plan/_gitignore +2 -0
  145. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -0
  146. package/corpus/templates/slides/.agents/skills/security/SKILL.md +31 -0
  147. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +4 -0
  148. package/corpus/templates/slides/_gitignore +2 -0
  149. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +126 -53
  150. package/corpus/templates/slides/app/components/design-system/builder-design-system-upload.ts +271 -0
  151. package/corpus/templates/slides/app/components/design-system/builder-index-response.ts +1 -1
  152. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  153. package/corpus/templates/slides/server/handlers/design-system-decode-job-status.ts +49 -0
  154. package/corpus/templates/slides/server/handlers/design-system-upload-start.ts +87 -0
  155. package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +79 -0
  156. package/corpus/templates/slides/server/routes/api/design-system-decode-job-status.get.ts +1 -0
  157. package/corpus/templates/slides/server/routes/api/design-system-upload-start.post.ts +1 -0
  158. package/corpus/templates/slides/server/routes/api/index-design-system-sources.post.ts +1 -0
  159. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -0
  160. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +7 -0
  161. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +31 -0
  162. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +4 -0
  163. package/corpus/templates/tasks/_gitignore +2 -0
  164. package/dist/a2a/artifact-response.d.ts.map +1 -1
  165. package/dist/a2a/artifact-response.js +30 -29
  166. package/dist/a2a/artifact-response.js.map +1 -1
  167. package/dist/action.d.ts +36 -0
  168. package/dist/action.d.ts.map +1 -1
  169. package/dist/action.js +37 -2
  170. package/dist/action.js.map +1 -1
  171. package/dist/chat-threads/store.d.ts +12 -0
  172. package/dist/chat-threads/store.d.ts.map +1 -1
  173. package/dist/chat-threads/store.js +48 -42
  174. package/dist/chat-threads/store.js.map +1 -1
  175. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  176. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  177. package/dist/cli/skills-content/design-visual-edit-skill.js +46 -3
  178. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  179. package/dist/client/AgentPanel.d.ts +3 -1
  180. package/dist/client/AgentPanel.d.ts.map +1 -1
  181. package/dist/client/AgentPanel.js +11 -9
  182. package/dist/client/AgentPanel.js.map +1 -1
  183. package/dist/client/AssistantChat.d.ts.map +1 -1
  184. package/dist/client/AssistantChat.js +57 -6
  185. package/dist/client/AssistantChat.js.map +1 -1
  186. package/dist/client/DefaultSpinner.d.ts +7 -0
  187. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  188. package/dist/client/DefaultSpinner.js +25 -1
  189. package/dist/client/DefaultSpinner.js.map +1 -1
  190. package/dist/client/org/TeamPage.d.ts +13 -1
  191. package/dist/client/org/TeamPage.d.ts.map +1 -1
  192. package/dist/client/org/TeamPage.js +41 -11
  193. package/dist/client/org/TeamPage.js.map +1 -1
  194. package/dist/client/org/hooks.d.ts +37 -0
  195. package/dist/client/org/hooks.d.ts.map +1 -1
  196. package/dist/client/org/hooks.js +37 -0
  197. package/dist/client/org/hooks.js.map +1 -1
  198. package/dist/client/org/index.d.ts +3 -2
  199. package/dist/client/org/index.d.ts.map +1 -1
  200. package/dist/client/org/index.js +1 -1
  201. package/dist/client/org/index.js.map +1 -1
  202. package/dist/client/transcription/use-live-transcription.d.ts +8 -0
  203. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  204. package/dist/client/transcription/use-live-transcription.js +38 -11
  205. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  206. package/dist/collab/routes.d.ts +1 -1
  207. package/dist/db/client.d.ts +12 -0
  208. package/dist/db/client.d.ts.map +1 -1
  209. package/dist/db/client.js +40 -3
  210. package/dist/db/client.js.map +1 -1
  211. package/dist/db/ensure-additive-columns.d.ts.map +1 -1
  212. package/dist/db/ensure-additive-columns.js +54 -32
  213. package/dist/db/ensure-additive-columns.js.map +1 -1
  214. package/dist/deploy/build.d.ts +1 -0
  215. package/dist/deploy/build.d.ts.map +1 -1
  216. package/dist/deploy/build.js +23 -2
  217. package/dist/deploy/build.js.map +1 -1
  218. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  219. package/dist/mcp-client/routes.d.ts +3 -1
  220. package/dist/mcp-client/routes.d.ts.map +1 -1
  221. package/dist/mcp-client/routes.js +8 -2
  222. package/dist/mcp-client/routes.js.map +1 -1
  223. package/dist/notifications/routes.d.ts +1 -1
  224. package/dist/org/app-roles-handlers.d.ts +27 -0
  225. package/dist/org/app-roles-handlers.d.ts.map +1 -0
  226. package/dist/org/app-roles-handlers.js +125 -0
  227. package/dist/org/app-roles-handlers.js.map +1 -0
  228. package/dist/org/app-roles.d.ts +136 -0
  229. package/dist/org/app-roles.d.ts.map +1 -0
  230. package/dist/org/app-roles.js +216 -0
  231. package/dist/org/app-roles.js.map +1 -0
  232. package/dist/org/index.d.ts +4 -1
  233. package/dist/org/index.d.ts.map +1 -1
  234. package/dist/org/index.js +3 -1
  235. package/dist/org/index.js.map +1 -1
  236. package/dist/org/migrations.d.ts.map +1 -1
  237. package/dist/org/migrations.js +22 -0
  238. package/dist/org/migrations.js.map +1 -1
  239. package/dist/org/plugin.d.ts +2 -0
  240. package/dist/org/plugin.d.ts.map +1 -1
  241. package/dist/org/plugin.js +20 -0
  242. package/dist/org/plugin.js.map +1 -1
  243. package/dist/org/schema.d.ts +143 -0
  244. package/dist/org/schema.d.ts.map +1 -1
  245. package/dist/org/schema.js +14 -0
  246. package/dist/org/schema.js.map +1 -1
  247. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  248. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  249. package/dist/scripts/docs/search.d.ts.map +1 -1
  250. package/dist/scripts/docs/search.js +15 -0
  251. package/dist/scripts/docs/search.js.map +1 -1
  252. package/dist/scripts/docs/source-search.d.ts +7 -0
  253. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  254. package/dist/scripts/docs/source-search.js +9 -0
  255. package/dist/scripts/docs/source-search.js.map +1 -1
  256. package/dist/secrets/routes.d.ts +9 -9
  257. package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
  258. package/dist/server/agent-chat/script-entries.js +3 -0
  259. package/dist/server/agent-chat/script-entries.js.map +1 -1
  260. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  261. package/dist/server/agent-chat-plugin.js +46 -48
  262. package/dist/server/agent-chat-plugin.js.map +1 -1
  263. package/dist/server/builder-design-systems.d.ts +49 -0
  264. package/dist/server/builder-design-systems.d.ts.map +1 -1
  265. package/dist/server/builder-design-systems.js +221 -69
  266. package/dist/server/builder-design-systems.js.map +1 -1
  267. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  268. package/dist/server/core-routes-plugin.js +6 -1
  269. package/dist/server/core-routes-plugin.js.map +1 -1
  270. package/dist/server/framework-request-handler.d.ts.map +1 -1
  271. package/dist/server/framework-request-handler.js +42 -6
  272. package/dist/server/framework-request-handler.js.map +1 -1
  273. package/dist/server/index.d.ts +1 -1
  274. package/dist/server/index.d.ts.map +1 -1
  275. package/dist/server/index.js +1 -1
  276. package/dist/server/index.js.map +1 -1
  277. package/dist/server/realtime-token.d.ts +1 -1
  278. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  279. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  280. package/dist/templates/chat/.agents/skills/security/SKILL.md +31 -0
  281. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  282. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -0
  283. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  284. package/dist/templates/default/.agents/skills/security/SKILL.md +31 -0
  285. package/dist/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  286. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  287. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  288. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  289. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  290. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  291. package/docs/content/actions.mdx +47 -4
  292. package/docs/content/native-chat-ui.mdx +7 -0
  293. package/docs/content/organizations-teams-permissions.mdx +109 -3
  294. package/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  295. package/docs/content/toolkit-org-team.mdx +72 -12
  296. package/package.json +2 -1
  297. package/src/a2a/artifact-response.ts +36 -29
  298. package/src/action.ts +83 -2
  299. package/src/chat-threads/store.ts +48 -43
  300. package/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  301. package/src/client/AgentPanel.tsx +26 -6
  302. package/src/client/AssistantChat.tsx +63 -7
  303. package/src/client/DefaultSpinner.tsx +29 -0
  304. package/src/client/org/TeamPage.tsx +161 -6
  305. package/src/client/org/hooks.ts +67 -0
  306. package/src/client/org/index.ts +9 -0
  307. package/src/client/transcription/use-live-transcription.ts +62 -10
  308. package/src/db/client.ts +42 -3
  309. package/src/db/ensure-additive-columns.ts +60 -33
  310. package/src/deploy/build.ts +31 -2
  311. package/src/mcp-client/routes.ts +10 -1
  312. package/src/org/app-roles-handlers.ts +152 -0
  313. package/src/org/app-roles.ts +355 -0
  314. package/src/org/index.ts +27 -1
  315. package/src/org/migrations.ts +22 -0
  316. package/src/org/plugin.ts +27 -0
  317. package/src/org/schema.ts +15 -0
  318. package/src/scripts/docs/search.ts +17 -0
  319. package/src/scripts/docs/source-search.ts +10 -0
  320. package/src/server/agent-chat/script-entries.ts +3 -0
  321. package/src/server/agent-chat-plugin.ts +53 -52
  322. package/src/server/builder-design-systems.ts +299 -82
  323. package/src/server/core-routes-plugin.ts +6 -1
  324. package/src/server/framework-request-handler.ts +44 -6
  325. package/src/server/index.ts +8 -0
  326. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  327. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  328. package/src/templates/chat/.agents/skills/security/SKILL.md +31 -0
  329. package/src/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  330. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  331. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  332. package/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  333. package/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  334. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  335. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  336. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  337. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  338. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  339. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +0 -530
  340. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +0 -191
  341. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +0 -115
  342. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  343. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +0 -89
  344. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +0 -221
  345. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  346. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  347. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +0 -169
  348. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +0 -174
  349. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +0 -232
  350. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +0 -282
  351. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +0 -119
  352. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +0 -123
  353. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +0 -122
  354. package/corpus/core/src/templates/chat/.env.example +0 -5
  355. package/corpus/core/src/templates/chat/.ignore +0 -0
  356. package/corpus/core/src/templates/chat/.oxfmtrc.json +0 -8
  357. package/corpus/core/src/templates/chat/AGENTS.md +0 -77
  358. package/corpus/core/src/templates/chat/CHANGELOG.md +0 -10
  359. package/corpus/core/src/templates/chat/DEVELOPING.md +0 -185
  360. package/corpus/core/src/templates/chat/README.md +0 -32
  361. package/corpus/core/src/templates/chat/_gitignore +0 -46
  362. package/corpus/core/src/templates/chat/actions/hello.ts +0 -13
  363. package/corpus/core/src/templates/chat/actions/navigate.ts +0 -41
  364. package/corpus/core/src/templates/chat/actions/run.ts +0 -2
  365. package/corpus/core/src/templates/chat/actions/view-screen.ts +0 -31
  366. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +0 -60
  367. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +0 -188
  368. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -505
  369. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +0 -1
  370. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +0 -1
  371. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +0 -1
  372. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +0 -1
  373. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +0 -1
  374. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +0 -1
  375. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +0 -17
  376. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +0 -1
  377. package/corpus/core/src/templates/chat/app/design-system.ts +0 -3
  378. package/corpus/core/src/templates/chat/app/entry.client.tsx +0 -22
  379. package/corpus/core/src/templates/chat/app/entry.server.tsx +0 -10
  380. package/corpus/core/src/templates/chat/app/global.css +0 -93
  381. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +0 -93
  382. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +0 -68
  383. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +0 -71
  384. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +0 -70
  385. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +0 -71
  386. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +0 -71
  387. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +0 -69
  388. package/corpus/core/src/templates/chat/app/i18n/index.ts +0 -34
  389. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +0 -70
  390. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +0 -70
  391. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +0 -71
  392. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +0 -66
  393. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +0 -66
  394. package/corpus/core/src/templates/chat/app/i18n-data.ts +0 -556
  395. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +0 -49
  396. package/corpus/core/src/templates/chat/app/lib/app-config.ts +0 -11
  397. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +0 -1
  398. package/corpus/core/src/templates/chat/app/lib/utils.ts +0 -1
  399. package/corpus/core/src/templates/chat/app/root.tsx +0 -173
  400. package/corpus/core/src/templates/chat/app/routes/_index.tsx +0 -94
  401. package/corpus/core/src/templates/chat/app/routes/agent.tsx +0 -24
  402. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +0 -1
  403. package/corpus/core/src/templates/chat/app/routes/database.tsx +0 -17
  404. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +0 -2
  405. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +0 -11
  406. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +0 -11
  407. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +0 -5
  408. package/corpus/core/src/templates/chat/app/routes/observability.tsx +0 -19
  409. package/corpus/core/src/templates/chat/app/routes/settings.tsx +0 -89
  410. package/corpus/core/src/templates/chat/app/routes/team.tsx +0 -11
  411. package/corpus/core/src/templates/chat/app/routes.ts +0 -4
  412. package/corpus/core/src/templates/chat/app/vite-env.d.ts +0 -6
  413. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  414. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  415. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  416. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +0 -6
  417. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  418. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +0 -5
  419. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +0 -6
  420. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +0 -6
  421. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +0 -6
  422. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +0 -6
  423. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +0 -6
  424. package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +0 -6
  425. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +0 -6
  426. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  427. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +0 -6
  428. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +0 -6
  429. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +0 -6
  430. package/corpus/core/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +0 -6
  431. package/corpus/core/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +0 -6
  432. package/corpus/core/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +0 -6
  433. package/corpus/core/src/templates/chat/components.json +0 -20
  434. package/corpus/core/src/templates/chat/learnings.defaults.md +0 -5
  435. package/corpus/core/src/templates/chat/netlify.toml +0 -11
  436. package/corpus/core/src/templates/chat/package.json +0 -92
  437. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +0 -10
  438. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +0 -10
  439. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +0 -21
  440. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +0 -21
  441. package/corpus/core/src/templates/chat/public/favicon.svg +0 -1
  442. package/corpus/core/src/templates/chat/public/icon-180.svg +0 -1
  443. package/corpus/core/src/templates/chat/public/icon-192.svg +0 -1
  444. package/corpus/core/src/templates/chat/public/icon-512.svg +0 -1
  445. package/corpus/core/src/templates/chat/public/manifest.json +0 -21
  446. package/corpus/core/src/templates/chat/react-router.config.ts +0 -7
  447. package/corpus/core/src/templates/chat/server/middleware/auth.ts +0 -15
  448. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +0 -21
  449. package/corpus/core/src/templates/chat/server/plugins/auth.ts +0 -17
  450. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +0 -5
  451. package/corpus/core/src/templates/chat/ssr-entry.ts +0 -15
  452. package/corpus/core/src/templates/chat/tsconfig.json +0 -21
  453. package/corpus/core/src/templates/chat/vite.config.ts +0 -19
  454. package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +0 -151
  455. package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +0 -1
  456. package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +0 -119
  457. package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +0 -1
@@ -502,21 +502,9 @@ export function createAgentChatPlugin(
502
502
  const { awaitBootstrap } = await import("./framework-request-handler.js");
503
503
  await awaitBootstrap(nitroApp);
504
504
 
505
- // Reap phantom runs left over from the previous process (HMR restart,
506
- // process crash, isolate eviction). Any run whose heartbeat is already
507
- // stale by startup time had a dead producer; mark it errored so the
508
- // next /runs/active check returns a terminal status and reconnecting
509
- // clients don't spin on "Thinking...". Runs owned by OTHER live
510
- // isolates are protected by their fresh heartbeats.
511
- try {
512
- const { reapAllStaleRuns } = await import("../agent/run-store.js");
513
- const reaped = await reapAllStaleRuns();
514
- if (reaped > 0) {
515
- console.log(`[agent-chat] reaped ${reaped} stale run(s) on startup`);
516
- }
517
- } catch {
518
- // Best effort — don't block plugin init if SQL isn't ready yet.
519
- }
505
+ // Never make route readiness wait on an org-global stale-run sweep.
506
+ // `/runs/active` reaps the requested run on demand, and the periodic
507
+ // recovery sweep below handles abandoned runs with no connected client.
520
508
 
521
509
  const env = process.env.NODE_ENV;
522
510
  // AGENT_MODE=production forces production agent constraints even in dev
@@ -561,44 +549,47 @@ export function createAgentChatPlugin(
561
549
  extensionTools: options?.extensionTools,
562
550
  });
563
551
 
564
- // Initialize MCP client. Merges file/env config + auto-detected binaries
565
- // + any remote servers users have added through the settings UI (persisted
566
- // in the settings table, scanned across all scopes so we never drop
567
- // another user's entries). Graceful-degrade: any failure yields zero MCP
568
- // tools and agent-chat keeps working as before.
569
- let mcpConfig = await buildMergedConfig().catch((err) => {
570
- console.warn(
571
- `[mcp-client] buildMergedConfig failed: ${err?.message ?? err}`,
572
- );
573
- return null;
574
- });
575
- if (!mcpConfig) {
576
- const fileOrEnv = loadMcpConfig() ?? autoDetectMcpConfig();
577
- mcpConfig = fileOrEnv;
578
- if (mcpConfig?.source) {
579
- console.log(
580
- `[mcp-client] loaded config from ${mcpConfig.source} (${Object.keys(mcpConfig.servers).length} server(s))`,
552
+ // Route readiness must not wait on settings scans, remote hub fetches, or
553
+ // third-party MCP handshakes. Build the action surface against an empty
554
+ // manager, then hydrate it after every live action registry has subscribed
555
+ // to manager changes.
556
+ const mcpManager = new McpClientManager(null);
557
+ setGlobalMcpManager(mcpManager);
558
+ const mcpActionEntries: Record<string, ActionEntry> = {};
559
+ let mcpInitializationPromise: Promise<void> | null = null;
560
+ const initializeMcpManager = async (): Promise<void> => {
561
+ let mcpConfig = await buildMergedConfig().catch((err) => {
562
+ console.warn(
563
+ `[mcp-client] buildMergedConfig failed: ${err?.message ?? err}`,
581
564
  );
582
- } else if (process.env.DEBUG) {
565
+ return null;
566
+ });
567
+ if (!mcpConfig) {
568
+ mcpConfig = loadMcpConfig() ?? autoDetectMcpConfig();
569
+ if (mcpConfig?.source) {
570
+ console.log(
571
+ `[mcp-client] loaded config from ${mcpConfig.source} (${Object.keys(mcpConfig.servers).length} server(s))`,
572
+ );
573
+ } else if (process.env.DEBUG) {
574
+ console.log(
575
+ "[mcp-client] no configured MCP servers — skipping MCP tools",
576
+ );
577
+ }
578
+ } else if (mcpConfig.source) {
583
579
  console.log(
584
- "[mcp-client] no configured MCP servers skipping MCP tools",
580
+ `[mcp-client] merged config (${Object.keys(mcpConfig.servers).length} server(s), source: ${mcpConfig.source})`,
585
581
  );
586
582
  }
587
- } else if (mcpConfig.source) {
588
- console.log(
589
- `[mcp-client] merged config (${Object.keys(mcpConfig.servers).length} server(s), source: ${mcpConfig.source})`,
590
- );
591
- }
592
- const mcpManager = new McpClientManager(mcpConfig);
593
- try {
594
- await mcpManager.start();
595
- } catch (err: any) {
596
- console.warn(
597
- `[mcp-client] start() failed: ${err?.message ?? err}. Continuing without MCP tools.`,
598
- );
599
- }
600
- setGlobalMcpManager(mcpManager);
601
- const mcpActionEntries = mcpToolsToActionEntries(mcpManager);
583
+ try {
584
+ await mcpManager.reconfigure(mcpConfig);
585
+ } catch (err: any) {
586
+ console.warn(
587
+ `[mcp-client] initialization failed: ${err?.message ?? err}. Continuing without MCP tools.`,
588
+ );
589
+ } finally {
590
+ startMcpConfigRefresh(mcpManager);
591
+ }
592
+ };
602
593
  const getJobMcpActionEntries = (
603
594
  job?: RecurringJobContext,
604
595
  ): Record<string, ActionEntry> => {
@@ -619,8 +610,11 @@ export function createAgentChatPlugin(
619
610
  // Mount status + management routes so the settings UI can list / add /
620
611
  // remove remote MCP servers and hot-reload the running manager.
621
612
  mountMcpStatusRoute(nitroApp, mcpManager);
622
- mountMcpServersRoutes(nitroApp, mcpManager);
623
- startMcpConfigRefresh(mcpManager);
613
+ mountMcpServersRoutes(nitroApp, mcpManager, {
614
+ // Serialize an unusually early settings mutation behind the initial
615
+ // config snapshot so stale startup data cannot overwrite the write.
616
+ waitUntilReady: () => mcpInitializationPromise ?? Promise.resolve(),
617
+ });
624
618
  // Hub-serve: expose org-scope servers to other agent-native apps in the
625
619
  // workspace when `AGENT_NATIVE_MCP_HUB_TOKEN` is set (dispatch, by
626
620
  // convention). Gated by the env var so mounting is a no-op otherwise.
@@ -5694,6 +5688,13 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5694
5688
  }
5695
5689
  }
5696
5690
 
5691
+ mcpInitializationPromise = initializeMcpManager().catch((err) => {
5692
+ console.warn(
5693
+ `[mcp-client] deferred initialization failed: ${err?.message ?? err}`,
5694
+ );
5695
+ });
5696
+ void mcpInitializationPromise;
5697
+
5697
5698
  // ─── Agent Teams orphan sweep ─────────────────────────────────────
5698
5699
  // Re-fires stuck/queued dispatches when the browser is closed and the
5699
5700
  // RunsTray's per-user reconciliation never triggers. Runs every 2 minutes
@@ -6001,7 +6002,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6001
6002
  });
6002
6003
  if (process.env.DEBUG)
6003
6004
  console.log("[triggers] Trigger dispatcher initialized");
6004
- } catch (err) {
6005
+ } catch {
6005
6006
  // Triggers module not available — skip silently
6006
6007
  }
6007
6008
  }
@@ -1,3 +1,5 @@
1
+ import type { DesignSystemSourceInput } from "@builder.io/ai-utils";
2
+
1
3
  import { withBuilderUtmTrackingParams } from "../shared/builder-link-tracking.js";
2
4
  import { FeatureNotConfiguredError } from "./credential-provider.js";
3
5
  import {
@@ -7,6 +9,12 @@ import {
7
9
 
8
10
  const DEFAULT_TIMEOUT_MS = 120_000;
9
11
 
12
+ // GCS resumable uploads require every chunk except the last to be a multiple
13
+ // of 256 KiB. 16 MiB is the recommended default and keeps very large `.fig`
14
+ // files off a single unbounded request body.
15
+ const GCS_CHUNK_SIZE = 16 * 1024 * 1024;
16
+ const MAX_CHUNK_RETRIES = 5;
17
+
10
18
  export interface BuilderDesignSystemIndexFile {
11
19
  name: string;
12
20
  data: Uint8Array;
@@ -123,16 +131,65 @@ interface UploadStartResponse {
123
131
  uploads?: Array<{ idx: number; uploadUrl: string; uploadToken: string }>;
124
132
  }
125
133
 
126
- interface GenerateResponse {
127
- projectId?: string;
128
- jobId?: string;
134
+ interface IndexResponse {
129
135
  designSystemId?: string;
136
+ jobId?: string;
137
+ projectId?: string;
138
+ branchUrl?: string;
139
+ branchName?: string;
140
+ }
141
+
142
+ export interface BuilderDesignSystemUploadAttachment {
143
+ name: string;
144
+ mimetype: string;
145
+ declaredSize: number;
146
+ }
147
+
148
+ export interface BuilderDesignSystemUploadSlot {
149
+ idx: number;
150
+ uploadUrl: string;
151
+ uploadToken: string;
152
+ }
153
+
154
+ export interface BuilderDesignSystemIndexFromSourcesOptions {
155
+ sources: DesignSystemSourceInput[];
156
+ projectName?: string;
157
+ devToolsVersion?: string;
158
+ }
159
+
160
+ export interface BuilderDesignSystemDecodeJobStatus {
161
+ jobId: string;
162
+ status: "pending" | "processing" | "complete" | "error";
163
+ framesProcessed: number;
164
+ totalFrames: number;
165
+ branchName: string | null;
166
+ branchUrl: string | null;
167
+ error: string | null;
168
+ partialFailure?: boolean;
169
+ createdAt: number;
170
+ updatedAt: number;
130
171
  }
131
172
 
132
173
  const DEFAULT_MAX_CODE_FILES = 50;
133
174
  const DEFAULT_MAX_TOTAL_CODE_BYTES = 2 * 1024 * 1024;
134
175
  const MAX_DOC_CONTENT_CHARS = 4_000;
135
176
 
177
+ export async function fetchBuilderDesignSystemDecodeJobStatus(
178
+ jobId: string,
179
+ ): Promise<BuilderDesignSystemDecodeJobStatus> {
180
+ const credentials = await resolveBuilderDesignSystemCredentials();
181
+ const url = makeBuilderDesignSystemUrl(
182
+ "decode-jobs/" + encodeURIComponent(jobId),
183
+ credentials,
184
+ );
185
+ const response = await fetchWithTimeout(url, {
186
+ method: "GET",
187
+ headers: makeBuilderHeaders(credentials),
188
+ });
189
+ await assertOk(response, "Builder design-system decode-job status failed");
190
+ return (await response.json()) as BuilderDesignSystemDecodeJobStatus;
191
+ }
192
+
136
193
  function trimTrailingSlash(value: string): string {
137
194
  return value.replace(/\/+$/, "");
138
195
  }
@@ -318,17 +375,45 @@ async function assertOk(response: Response, label: string): Promise<void> {
318
375
  );
319
376
  }
320
377
 
378
+ // GCS reports the highest committed byte in a `Range: bytes=0-<end>` header.
379
+ function committedOffsetFromRange(response: Response): number | null {
380
+ const match = response.headers.get("Range")?.match(/bytes=0-(\d+)/);
381
+ return match ? parseInt(match[1], 10) + 1 : null;
382
+ }
383
+
384
+ async function queryCommittedOffset(
385
+ sessionUrl: string,
386
+ total: number,
387
+ ): Promise<number> {
388
+ const response = await fetchWithTimeout(sessionUrl, {
389
+ method: "PUT",
390
+ headers: { "Content-Range": `bytes */${total}` },
391
+ });
392
+ if (response.status === 200 || response.status === 201) return total;
393
+ if (response.status === 308) {
394
+ return committedOffsetFromRange(response) ?? 0;
395
+ }
396
+ throw new Error(
397
+ `Builder design-system upload status query failed (${response.status}).`,
398
+ );
399
+ }
400
+
401
+ function delay(ms: number): Promise<void> {
402
+ return new Promise((resolve) => setTimeout(resolve, ms));
403
+ }
404
+
321
405
  async function uploadToResumableUrl(
322
406
  slot: { uploadUrl: string },
323
407
  file: BuilderDesignSystemIndexFile,
324
408
  ): Promise<void> {
325
409
  const mimeType = mimeTypeForFile(file);
326
410
  const bytes = file.data;
411
+ const total = bytes.byteLength;
327
412
  const start = await fetchWithTimeout(slot.uploadUrl, {
328
413
  method: "POST",
329
414
  headers: {
330
415
  "x-goog-resumable": "start",
331
- "x-goog-content-length-range": `0,${bytes.byteLength}`,
416
+ "x-goog-content-length-range": `0,${total}`,
332
417
  "Content-Type": mimeType,
333
418
  },
334
419
  });
@@ -338,15 +423,60 @@ async function uploadToResumableUrl(
338
423
  throw new Error("Builder design-system upload session returned no URL.");
339
424
  }
340
425
 
341
- const response = await fetchWithTimeout(sessionUrl, {
342
- method: "PUT",
343
- headers: {
344
- "Content-Range": `bytes 0-${bytes.byteLength - 1}/${bytes.byteLength}`,
345
- "Content-Type": mimeType,
346
- },
347
- body: makeBody(bytes, mimeType),
348
- });
349
- await assertOk(response, "Builder design-system file upload failed");
426
+ if (total === 0) {
427
+ const response = await fetchWithTimeout(sessionUrl, {
428
+ method: "PUT",
429
+ headers: { "Content-Range": "bytes */0" },
430
+ body: makeBody(bytes, mimeType),
431
+ });
432
+ await assertOk(response, "Builder design-system file upload failed");
433
+ return;
434
+ }
435
+
436
+ // A failed PUT may have still landed at GCS, so the local offset can't be
437
+ // trusted after an error — only GCS's committed-offset response is
438
+ // authoritative.
439
+ let offset = 0;
440
+ let retries = 0;
441
+ while (offset < total) {
442
+ const end = Math.min(offset + GCS_CHUNK_SIZE, total);
443
+ const isLast = end === total;
444
+ try {
445
+ const response = await fetchWithTimeout(sessionUrl, {
446
+ method: "PUT",
447
+ headers: {
448
+ "Content-Range": `bytes ${offset}-${end - 1}/${total}`,
449
+ "Content-Type": mimeType,
450
+ },
451
+ body: makeBody(bytes.subarray(offset, end), mimeType),
452
+ });
453
+ if (response.status === 200 || response.status === 201) {
454
+ offset = total;
455
+ } else if (!isLast && response.status === 308) {
456
+ const nextOffset = committedOffsetFromRange(response) ?? offset;
457
+ if (nextOffset <= offset) {
458
+ throw new Error(
459
+ `Builder design-system upload stalled at byte ${offset}.`,
460
+ );
461
+ }
462
+ offset = nextOffset;
463
+ } else {
464
+ throw new Error(
465
+ `Builder design-system file upload failed (${response.status}).`,
466
+ );
467
+ }
468
+ retries = 0;
469
+ } catch (err) {
470
+ if (++retries > MAX_CHUNK_RETRIES) throw err;
471
+ await delay(500 * retries);
472
+ try {
473
+ offset = await queryCommittedOffset(sessionUrl, total);
474
+ } catch {
475
+ // If the offset query also fails, retry from the last local offset —
476
+ // GCS's resumable PUT safely re-acknowledges bytes it already has.
477
+ }
478
+ }
479
+ }
350
480
  }
351
481
 
352
482
  function nonEmptyFiles(
@@ -368,6 +498,25 @@ export function builderDesignSystemUrl(designSystemId?: string | null): string {
368
498
  });
369
499
  }
370
500
 
501
+ export function builderProjectBranchUrl(
502
+ projectId?: string | null,
503
+ branchName?: string | null,
504
+ ): string | undefined {
505
+ const project = projectId?.trim();
506
+ const branch = branchName?.trim();
507
+ if (!project || !branch) return undefined;
508
+ const host = trimTrailingSlash(getBuilderAppHost());
509
+ const path =
510
+ "/app/projects/" +
511
+ encodeURIComponent(project) +
512
+ "/" +
513
+ encodeURIComponent(branch);
514
+ return withBuilderUtmTrackingParams(host + path, {
515
+ campaign: "product",
516
+ content: "design_system_intelligence",
517
+ });
518
+ }
519
+
371
520
  export function localBuilderDesignSystemId(
372
521
  builderDesignSystemId: string,
373
522
  ): string {
@@ -569,65 +718,58 @@ export async function hydrateBuilderDesignSystemReference(
569
718
  };
570
719
  }
571
720
 
572
- export async function startBuilderDesignSystemIndex(
573
- options: BuilderDesignSystemIndexOptions,
574
- ): Promise<BuilderDesignSystemIndexResult> {
575
- const files = nonEmptyFiles(options.files);
576
- const description = options.description?.trim();
577
- if (description) {
578
- files.unshift({
579
- name: "additional-context.txt",
580
- data: new TextEncoder().encode(description),
581
- mimeType: "text/plain",
582
- });
721
+ /**
722
+ * Opens signed resumable-upload slots for `.fig`/code/design attachments so
723
+ * the browser can stream each file's bytes straight to GCS. Large `.fig`
724
+ * files must not ride through the app server as one request body -- the
725
+ * serverless host caps request bodies well below Figma export sizes.
726
+ */
727
+ export async function startBuilderDesignSystemUpload(
728
+ attachments: BuilderDesignSystemUploadAttachment[],
729
+ ): Promise<BuilderDesignSystemUploadSlot[]> {
730
+ if (attachments.length === 0) return [];
731
+ const credentials = await resolveBuilderDesignSystemCredentials();
732
+ const uploadStart = await fetchWithTimeout(
733
+ makeBuilderDesignSystemUrl("upload/start", credentials),
734
+ {
735
+ method: "POST",
736
+ headers: {
737
+ ...makeBuilderHeaders(credentials),
738
+ "Content-Type": "application/json",
739
+ },
740
+ body: JSON.stringify({ attachments }),
741
+ },
742
+ );
743
+ await assertOk(uploadStart, "Builder design-system upload start failed");
744
+ const uploadJson = (await uploadStart.json()) as UploadStartResponse;
745
+ const slots = [...(uploadJson.uploads ?? [])].sort((a, b) => a.idx - b.idx);
746
+ if (slots.length !== attachments.length) {
747
+ throw new Error("Builder did not return upload slots for all files.");
583
748
  }
584
- if (
585
- files.length === 0 &&
586
- !options.githubRepoUrl &&
587
- !options.connectedProjectId
588
- ) {
749
+ for (let i = 0; i < slots.length; i++) {
750
+ if (slots[i].idx !== i) {
751
+ throw new Error("Builder upload slot mismatch: expected " + i + ".");
752
+ }
753
+ }
754
+ return slots;
755
+ }
756
+
757
+ /**
758
+ * Finalizes indexing from already-resolved sources (uploaded file tokens,
759
+ * public repos, connected projects). Callers that stream uploads from the
760
+ * browser pass the returned `uploadToken`s as `file` sources here.
761
+ */
762
+ export async function indexBuilderDesignSystem(
763
+ options: BuilderDesignSystemIndexFromSourcesOptions,
764
+ ): Promise<BuilderDesignSystemIndexResult> {
765
+ if (options.sources.length === 0) {
589
766
  throw new Error(
590
767
  "Provide at least one .fig/code/text file or a GitHub repository URL to index with Builder.",
591
768
  );
592
769
  }
593
-
594
770
  const credentials = await resolveBuilderDesignSystemCredentials();
595
- let uploadTokens: string[] = [];
596
- if (files.length > 0) {
597
- const uploadStart = await fetchWithTimeout(
598
- makeBuilderDesignSystemUrl("upload/start", credentials),
599
- {
600
- method: "POST",
601
- headers: {
602
- ...makeBuilderHeaders(credentials),
603
- "Content-Type": "application/json",
604
- },
605
- body: JSON.stringify({
606
- attachments: files.map((file) => ({
607
- name: file.name,
608
- mimetype: mimeTypeForFile(file),
609
- declaredSize: file.data.byteLength,
610
- })),
611
- }),
612
- },
613
- );
614
- await assertOk(uploadStart, "Builder design-system upload start failed");
615
- const uploadJson = (await uploadStart.json()) as UploadStartResponse;
616
- const slots = [...(uploadJson.uploads ?? [])].sort((a, b) => a.idx - b.idx);
617
- if (slots.length !== files.length) {
618
- throw new Error("Builder did not return upload slots for all files.");
619
- }
620
- for (let i = 0; i < slots.length; i++) {
621
- if (slots[i].idx !== i) {
622
- throw new Error(`Builder upload slot mismatch: expected ${i}.`);
623
- }
624
- await uploadToResumableUrl(slots[i], files[i]);
625
- }
626
- uploadTokens = slots.map((slot) => slot.uploadToken);
627
- }
628
-
629
- const generate = await fetchWithTimeout(
630
- makeBuilderDesignSystemUrl("generate", credentials),
771
+ const index = await fetchWithTimeout(
772
+ makeBuilderDesignSystemUrl("index", credentials),
631
773
  {
632
774
  method: "POST",
633
775
  headers: {
@@ -635,39 +777,114 @@ export async function startBuilderDesignSystemIndex(
635
777
  "Content-Type": "application/json",
636
778
  },
637
779
  body: JSON.stringify({
638
- uploads: uploadTokens,
780
+ sources: options.sources,
639
781
  ...(options.projectName?.trim()
640
- ? { projectName: options.projectName.trim() }
641
- : {}),
642
- ...(options.githubRepoUrl?.trim()
643
- ? { githubRepoUrl: options.githubRepoUrl.trim() }
782
+ ? { designSystemName: options.projectName.trim() }
644
783
  : {}),
645
- ...(options.connectedProjectId?.trim()
646
- ? { connectedProjectId: options.connectedProjectId.trim() }
647
- : {}),
648
- ...(options.selection ? { selection: options.selection } : {}),
649
784
  ...(options.devToolsVersion?.trim()
650
785
  ? { devToolsVersion: options.devToolsVersion.trim() }
651
786
  : {}),
652
787
  }),
653
788
  },
654
789
  );
655
- await assertOk(generate, "Builder design-system indexing failed");
656
- const generated = (await generate.json()) as GenerateResponse;
657
- if (!generated.projectId || !generated.jobId || !generated.designSystemId) {
790
+ await assertOk(index, "Builder design-system indexing failed");
791
+ const indexed = (await index.json()) as IndexResponse;
792
+ if (!indexed.designSystemId) {
658
793
  throw new Error(
659
794
  "Builder design-system indexing returned an incomplete response.",
660
795
  );
661
796
  }
662
797
 
798
+ const jobId = indexed.jobId ?? "";
799
+ // The `.fig` decode job creates the Fusion branch asynchronously, so
800
+ // `/index` usually can't return a branchUrl yet — the caller polls the
801
+ // decode-job status endpoint for it once the job completes.
802
+ const branchUrl = indexed.branchUrl?.trim() || null;
803
+
663
804
  return {
664
805
  ok: true,
665
806
  source: "builder",
666
- projectId: generated.projectId,
667
- jobId: generated.jobId,
668
- designSystemId: generated.designSystemId,
807
+ projectId: indexed.projectId ?? "",
808
+ jobId,
809
+ designSystemId: indexed.designSystemId,
669
810
  suggestedTitle: options.projectName?.trim() || null,
670
- builderUrl: builderDesignSystemUrl(generated.designSystemId),
811
+ builderUrl:
812
+ branchUrl ||
813
+ builderProjectBranchUrl(indexed.projectId, indexed.branchName) ||
814
+ builderDesignSystemUrl(indexed.designSystemId),
671
815
  status: "in-progress",
672
816
  };
673
817
  }
818
+
819
+ /**
820
+ * Server-side indexing for in-memory files (the agent action's small inline
821
+ * payloads). Uploads each file server->GCS in resumable chunks, then
822
+ * finalizes. Browser callers should instead stream via
823
+ * `startBuilderDesignSystemUpload` + `indexBuilderDesignSystem`.
824
+ */
825
+ export async function startBuilderDesignSystemIndex(
826
+ options: BuilderDesignSystemIndexOptions,
827
+ ): Promise<BuilderDesignSystemIndexResult> {
828
+ const files = nonEmptyFiles(options.files);
829
+ const description = options.description?.trim();
830
+ if (description) {
831
+ files.unshift({
832
+ name: "additional-context.txt",
833
+ data: new TextEncoder().encode(description),
834
+ mimeType: "text/plain",
835
+ });
836
+ }
837
+ if (
838
+ files.length === 0 &&
839
+ !options.githubRepoUrl &&
840
+ !options.connectedProjectId
841
+ ) {
842
+ throw new Error(
843
+ "Provide at least one .fig/code/text file or a GitHub repository URL to index with Builder.",
844
+ );
845
+ }
846
+
847
+ const sources: DesignSystemSourceInput[] = [];
848
+ if (files.length > 0) {
849
+ const slots = await startBuilderDesignSystemUpload(
850
+ files.map((file) => ({
851
+ name: file.name,
852
+ mimetype: mimeTypeForFile(file),
853
+ declaredSize: file.data.byteLength,
854
+ })),
855
+ );
856
+ for (let i = 0; i < slots.length; i++) {
857
+ await uploadToResumableUrl(slots[i], files[i]);
858
+ }
859
+ for (let i = 0; i < slots.length; i++) {
860
+ const name = files[i].name;
861
+ const fileSelection = options.selection?.[name];
862
+ sources.push({
863
+ kind: "file",
864
+ uploadToken: slots[i].uploadToken,
865
+ ...(fileSelection && fileSelection.length > 0
866
+ ? { selection: { [name]: fileSelection } }
867
+ : {}),
868
+ });
869
+ }
870
+ }
871
+
872
+ if (options.githubRepoUrl?.trim()) {
873
+ sources.push({
874
+ kind: "public-repo",
875
+ repoUrl: options.githubRepoUrl.trim(),
876
+ });
877
+ }
878
+ if (options.connectedProjectId?.trim()) {
879
+ sources.push({
880
+ kind: "connected-repo",
881
+ fusionProjectId: options.connectedProjectId.trim(),
882
+ });
883
+ }
884
+
885
+ return indexBuilderDesignSystem({
886
+ sources,
887
+ projectName: options.projectName,
888
+ devToolsVersion: options.devToolsVersion,
889
+ });
890
+ }
@@ -4251,8 +4251,13 @@ export function createCoreRoutesPlugin(
4251
4251
  }
4252
4252
  resolveInit();
4253
4253
  } catch (error) {
4254
+ // Do NOT rethrow. Nitro invokes plugins as `try { plugin(app) } catch`,
4255
+ // which cannot catch an async rejection, so rethrowing here surfaces as
4256
+ // an unhandledRejection: Node exits, the serverless container dies, and
4257
+ // every in-flight request on it returns a bare 502. `rejectInit` already
4258
+ // routes this failure to the readiness gate, which answers the affected
4259
+ // paths with a retryable 503 instead.
4254
4260
  rejectInit(error);
4255
- throw error;
4256
4261
  }
4257
4262
  };
4258
4263
  }