@agent-native/core 0.141.7 → 0.144.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 (328) hide show
  1. package/agent-native.eject.json +9 -0
  2. package/corpus/README.md +1 -1
  3. package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
  4. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
  5. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  6. package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
  7. package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  8. package/corpus/templates/analytics/AGENTS.md +35 -38
  9. package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
  10. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
  11. package/corpus/templates/analytics/actions/navigate.ts +4 -5
  12. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  13. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
  14. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  15. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  16. package/corpus/templates/analytics/app/i18n-data.ts +680 -0
  17. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  18. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  19. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  20. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  21. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  22. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  23. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  25. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  26. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  27. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  28. package/corpus/templates/analytics/netlify.toml +7 -0
  29. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  30. package/corpus/templates/analytics/server/db/index.ts +27 -0
  31. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  32. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  33. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +133 -44
  34. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  35. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  36. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  37. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  38. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
  39. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  40. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  41. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  42. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  43. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  44. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  45. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  46. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  47. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  48. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  49. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  50. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  51. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  52. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  53. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  54. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  55. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  56. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  57. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  58. package/corpus/templates/calendar/AGENTS.md +11 -32
  59. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  60. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  61. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  62. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  63. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  64. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  65. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  66. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  67. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  68. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  69. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  70. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  71. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  72. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  73. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  74. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  75. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  76. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  77. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  78. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  79. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  80. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  81. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  82. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  83. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  84. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  86. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  87. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  88. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  89. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  90. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  91. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  92. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  93. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  94. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  95. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  96. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  97. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  98. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  99. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  100. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  101. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  102. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  103. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  104. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  105. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  106. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  107. package/corpus/templates/design/actions/import-from-url.ts +1 -1
  108. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  109. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  110. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  111. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  112. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  113. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  114. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  115. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  116. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  117. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  118. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  119. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  120. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  121. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  122. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  123. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  124. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  125. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  126. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  127. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  128. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  129. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  130. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  131. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  132. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  133. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  134. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  135. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  136. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  137. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  138. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  139. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  140. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  141. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  142. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  143. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  144. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
  145. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  146. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  147. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  148. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  149. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  150. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  151. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  152. package/corpus/templates/slides/AGENTS.md +7 -9
  153. package/corpus/templates/slides/_gitignore +1 -0
  154. package/corpus/templates/slides/actions/export-pptx.ts +402 -36
  155. package/corpus/templates/slides/actions/import-file.ts +46 -85
  156. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  157. package/corpus/templates/slides/actions/import-pptx.ts +85 -60
  158. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  159. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  160. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  161. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  162. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  163. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  164. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
  165. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  166. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  167. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  168. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  169. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  170. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +4 -0
  171. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  172. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  173. package/corpus/templates/slides/app/lib/create-deck-generation.ts +1 -1
  174. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  175. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  176. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  177. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  178. package/corpus/templates/slides/app/pages/Index.tsx +91 -1
  179. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  180. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  181. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  182. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  183. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  184. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  185. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  186. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  187. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  188. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  189. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  190. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  191. package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
  192. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  193. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  194. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  195. package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
  196. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  197. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  198. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  199. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  200. package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
  201. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  202. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  203. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  204. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  205. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  206. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  207. package/dist/agent/production-agent.d.ts +17 -0
  208. package/dist/agent/production-agent.js +72 -1
  209. package/dist/cli/agent-plugin.d.ts +112 -0
  210. package/dist/cli/agent-plugin.js +1081 -0
  211. package/dist/cli/app-skill.js +39 -1
  212. package/dist/cli/code-agent-executor.d.ts +3 -0
  213. package/dist/cli/code-agent-executor.js +51 -13
  214. package/dist/cli/index.js +13 -0
  215. package/dist/cli/templates-meta.js +1 -1
  216. package/dist/client/AgentPanel.d.ts +3 -1
  217. package/dist/client/AgentPanel.js +9 -2
  218. package/dist/client/AssistantChat.d.ts +8 -0
  219. package/dist/client/AssistantChat.js +23 -8
  220. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  221. package/dist/client/agent-chat-adapter.js +123 -4
  222. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  223. package/dist/client/assistant-ui-recovery.js +7 -3
  224. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  225. package/dist/client/org/TeamPage.js +1 -1
  226. package/dist/client/require-session.js +1 -1
  227. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  228. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  229. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  230. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  231. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  232. package/dist/client/resources/mcp-integration-logos.js +18 -2
  233. package/dist/client/settings/AccountSettingsCard.js +2 -1
  234. package/dist/collab/routes.d.ts +1 -1
  235. package/dist/collab/struct-routes.d.ts +1 -1
  236. package/dist/db/client.d.ts +9 -0
  237. package/dist/db/client.js +51 -16
  238. package/dist/db/create-get-db.js +2 -2
  239. package/dist/db/ddl-guard.d.ts +11 -10
  240. package/dist/db/ddl-guard.js +40 -12
  241. package/dist/deploy/build.d.ts +2 -0
  242. package/dist/deploy/build.js +97 -4
  243. package/dist/deploy/workspace-deploy.js +0 -2
  244. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  245. package/dist/guards/no-env-credentials.js +9 -0
  246. package/dist/ingestion/index.d.ts +1 -1
  247. package/dist/ingestion/pptx.d.ts +68 -0
  248. package/dist/ingestion/pptx.js +660 -213
  249. package/dist/integrations/plugin.js +9 -6
  250. package/dist/localization/default-messages.d.ts +54 -0
  251. package/dist/localization/default-messages.js +57 -2
  252. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  253. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  254. package/dist/mcp-client/oauth-routes.js +73 -6
  255. package/dist/notifications/routes.d.ts +1 -1
  256. package/dist/observability/routes.d.ts +3 -3
  257. package/dist/onboarding/app-profile.js +11 -0
  258. package/dist/resources/handlers.d.ts +1 -1
  259. package/dist/resources/store.js +15 -1
  260. package/dist/scripts/call-agent.js +34 -4
  261. package/dist/secrets/routes.d.ts +9 -9
  262. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  263. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  264. package/dist/server/agent-chat-plugin.js +29 -8
  265. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  266. package/dist/server/auth.js +47 -11
  267. package/dist/server/better-auth-instance.js +5 -3
  268. package/dist/server/core-routes-plugin.d.ts +8 -1
  269. package/dist/server/core-routes-plugin.js +28 -3
  270. package/dist/server/credential-provider.d.ts +3 -3
  271. package/dist/server/credential-provider.js +90 -4
  272. package/dist/server/onboarding-html.d.ts +2 -0
  273. package/dist/server/onboarding-html.js +115 -29
  274. package/dist/server/self-dispatch.d.ts +5 -4
  275. package/dist/server/self-dispatch.js +25 -14
  276. package/dist/server/ssr-handler.d.ts +1 -1
  277. package/dist/server/ssr-handler.js +1 -1
  278. package/dist/server/transcribe-voice.d.ts +1 -1
  279. package/dist/shared/cache-control.d.ts +26 -2
  280. package/dist/shared/cache-control.js +43 -2
  281. package/dist/shared/password-policy.d.ts +3 -0
  282. package/dist/shared/password-policy.js +3 -0
  283. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  284. package/dist/sharing/registry.d.ts +14 -0
  285. package/dist/styles/agent-native.css +6 -0
  286. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  287. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  288. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  289. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  290. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  291. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  292. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  293. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  294. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  295. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  296. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  297. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  298. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  299. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  300. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  301. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  302. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  303. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  304. package/dist/templates/workspace-root/AGENTS.md +7 -0
  305. package/dist/user-profile/actions/change-password.js +8 -3
  306. package/dist/user-profile/actions/set-password.js +5 -1
  307. package/dist/vite/action-types-plugin.js +59 -0
  308. package/docs/content/skills-guide.mdx +13 -0
  309. package/package.json +6 -2
  310. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  311. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  312. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  313. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  314. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  315. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  316. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  317. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  318. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  319. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  320. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  321. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  322. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  323. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  324. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  325. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  326. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  327. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  328. package/src/templates/workspace-root/AGENTS.md +7 -0
@@ -222,6 +222,30 @@ const FIRST_PARTY_ANALYTICS_RAW_SCHEMA = [
222
222
  ["org_id", "STRING"],
223
223
  ] as const;
224
224
 
225
+ const FIRST_PARTY_ANALYTICS_BACKFILL_COLUMNS = [
226
+ "id",
227
+ "public_key_id",
228
+ "event_name",
229
+ "user_id",
230
+ "anonymous_id",
231
+ "user_key",
232
+ "session_id",
233
+ "timestamp",
234
+ "event_date",
235
+ "received_at",
236
+ "url",
237
+ "path",
238
+ "hostname",
239
+ "referrer",
240
+ "app",
241
+ "template",
242
+ "signed_in",
243
+ "properties",
244
+ "context",
245
+ "owner_email",
246
+ "org_id",
247
+ ] as const;
248
+
225
249
  const FIRST_PARTY_ANALYTICS_QUERY_SCHEMA = FIRST_PARTY_ANALYTICS_RAW_SCHEMA;
226
250
  const FIRST_PARTY_ANALYTICS_DAILY_ROLLUP_SCHEMA = [
227
251
  ["id", "STRING"],
@@ -982,35 +1006,69 @@ function serializeBackfillCursor(
982
1006
  return JSON.stringify(cursor);
983
1007
  }
984
1008
 
985
- function backfillScopeSql(
986
- scope: FirstPartyAnalyticsScope,
1009
+ function backfillBranchSql(
1010
+ predicate: string,
1011
+ predicateArgs: string[],
987
1012
  cursor: FirstPartyAnalyticsBackfillCursor,
988
1013
  ): {
989
1014
  sql: string;
990
1015
  args: string[];
991
1016
  } {
992
- const cursorSql =
993
- "(received_at > ? OR (received_at = ? AND id > ?)) ORDER BY received_at ASC, id ASC LIMIT ?";
994
- if (scope.orgId) {
995
- return {
996
- sql:
997
- "WHERE (org_id = ? OR (org_id IS NULL AND owner_email = ?)) AND " +
998
- cursorSql,
999
- args: [
1000
- scope.orgId,
1001
- scope.userEmail,
1002
- cursor.receivedAt,
1003
- cursor.receivedAt,
1004
- cursor.id,
1005
- ],
1006
- };
1007
- }
1017
+ const cursorSql = cursor.receivedAt
1018
+ ? "(received_at > ? OR (received_at = ? AND id > ?))"
1019
+ : "";
1020
+ const cursorArgs = cursor.receivedAt
1021
+ ? [cursor.receivedAt, cursor.receivedAt, cursor.id]
1022
+ : [];
1008
1023
  return {
1009
- sql: "WHERE org_id IS NULL AND owner_email = ? AND " + cursorSql,
1010
- args: [scope.userEmail, cursor.receivedAt, cursor.receivedAt, cursor.id],
1024
+ sql: `SELECT id, received_at
1025
+ FROM analytics_events
1026
+ WHERE ${predicate}${cursorSql ? ` AND ${cursorSql}` : ""}
1027
+ ORDER BY received_at ASC, id ASC LIMIT ?`,
1028
+ args: [...predicateArgs, ...cursorArgs],
1011
1029
  };
1012
1030
  }
1013
1031
 
1032
+ function backfillRowsByIdsSql(ids: string[]): {
1033
+ sql: string;
1034
+ args: string[];
1035
+ } {
1036
+ return {
1037
+ sql: `SELECT ${FIRST_PARTY_ANALYTICS_BACKFILL_COLUMNS.join(", ")}
1038
+ FROM analytics_events
1039
+ WHERE id IN (${ids.map(() => "?").join(", ")})`,
1040
+ args: ids,
1041
+ };
1042
+ }
1043
+
1044
+ function backfillRowCursor(
1045
+ row: Record<string, unknown>,
1046
+ ): FirstPartyAnalyticsBackfillCursor {
1047
+ const id = row.id;
1048
+ const receivedAt = row.received_at ?? row.receivedAt;
1049
+ if (typeof id !== "string" || !id) {
1050
+ throw new Error("First-party analytics backfill row is missing its id");
1051
+ }
1052
+ if (typeof receivedAt !== "string" || !receivedAt) {
1053
+ throw new Error(
1054
+ "First-party analytics backfill row is missing its received_at",
1055
+ );
1056
+ }
1057
+ return { receivedAt, id };
1058
+ }
1059
+
1060
+ function compareBackfillRows(
1061
+ left: Record<string, unknown>,
1062
+ right: Record<string, unknown>,
1063
+ ): number {
1064
+ const leftCursor = backfillRowCursor(left);
1065
+ const rightCursor = backfillRowCursor(right);
1066
+ return (
1067
+ leftCursor.receivedAt.localeCompare(rightCursor.receivedAt) ||
1068
+ leftCursor.id.localeCompare(rightCursor.id)
1069
+ );
1070
+ }
1071
+
1014
1072
  export async function backfillFirstPartyAnalyticsBatch(
1015
1073
  scope: FirstPartyAnalyticsScope,
1016
1074
  cursor: string | null,
@@ -1020,39 +1078,70 @@ export async function backfillFirstPartyAnalyticsBatch(
1020
1078
  const boundedLimit = Math.min(Math.max(Math.floor(limit), 1), 500);
1021
1079
  const db = getDbExec();
1022
1080
  const parsedCursor = parseBackfillCursor(cursor);
1023
- const scoped = backfillScopeSql(scope, parsedCursor);
1024
- const result = await db.execute({
1025
- sql: `SELECT * FROM analytics_events ${scoped.sql}`,
1026
- args: [...scoped.args, boundedLimit],
1027
- timeoutMs: 20_000,
1028
- maxAttempts: 1,
1029
- });
1030
- const rows = result.rows as Record<string, unknown>[];
1031
- if (!rows.length) {
1081
+ const branches = scope.orgId
1082
+ ? [
1083
+ { predicate: "org_id = ?", args: [scope.orgId] },
1084
+ {
1085
+ predicate: "org_id IS NULL AND owner_email = ?",
1086
+ args: [scope.userEmail],
1087
+ },
1088
+ ]
1089
+ : [
1090
+ {
1091
+ predicate: "org_id IS NULL AND owner_email = ?",
1092
+ args: [scope.userEmail],
1093
+ },
1094
+ ];
1095
+ const rows: Record<string, unknown>[] = [];
1096
+ for (const branch of branches) {
1097
+ const scoped = backfillBranchSql(
1098
+ branch.predicate,
1099
+ branch.args,
1100
+ parsedCursor,
1101
+ );
1102
+ const result = await db.execute({
1103
+ sql: scoped.sql,
1104
+ args: [...scoped.args, boundedLimit],
1105
+ timeoutMs: 20_000,
1106
+ maxAttempts: 1,
1107
+ });
1108
+ rows.push(...(result.rows as Record<string, unknown>[]));
1109
+ }
1110
+ rows.sort(compareBackfillRows);
1111
+ const selectedRows = rows.slice(0, boundedLimit);
1112
+ if (!selectedRows.length) {
1032
1113
  return {
1033
1114
  nextCursor: serializeBackfillCursor(parsedCursor),
1034
1115
  copied: 0,
1035
1116
  complete: true,
1036
1117
  };
1037
1118
  }
1038
- await insertFirstPartyAnalyticsRows(rows, configuredTable);
1039
- const lastId = rows[rows.length - 1]?.id;
1040
- if (typeof lastId !== "string" || !lastId) {
1041
- throw new Error("First-party analytics backfill row is missing its id");
1042
- }
1043
- const lastReceivedAt =
1044
- rows[rows.length - 1]?.received_at ?? rows[rows.length - 1]?.receivedAt;
1045
- if (typeof lastReceivedAt !== "string" || !lastReceivedAt) {
1046
- throw new Error(
1047
- "First-party analytics backfill row is missing its received_at",
1048
- );
1049
- }
1119
+
1120
+ const selectedIds = selectedRows.map((row) => backfillRowCursor(row).id);
1121
+ const hydratedQuery = backfillRowsByIdsSql(selectedIds);
1122
+ const hydratedResult = await db.execute({
1123
+ sql: hydratedQuery.sql,
1124
+ args: hydratedQuery.args,
1125
+ timeoutMs: 20_000,
1126
+ maxAttempts: 1,
1127
+ });
1128
+ const hydratedById = new Map(
1129
+ (hydratedResult.rows as Record<string, unknown>[]).map((row) => [
1130
+ backfillRowCursor(row).id,
1131
+ row,
1132
+ ]),
1133
+ );
1134
+ const selectedEvents = selectedIds
1135
+ .map((id) => hydratedById.get(id))
1136
+ .filter((row): row is Record<string, unknown> => row !== undefined);
1137
+ await insertFirstPartyAnalyticsRows(selectedEvents, configuredTable);
1138
+ const lastCursor = backfillRowCursor(selectedRows[selectedRows.length - 1]!);
1050
1139
  return {
1051
1140
  nextCursor: serializeBackfillCursor({
1052
- receivedAt: lastReceivedAt,
1053
- id: lastId,
1141
+ receivedAt: lastCursor.receivedAt,
1142
+ id: lastCursor.id,
1054
1143
  }),
1055
- copied: rows.length,
1144
+ copied: selectedEvents.length,
1056
1145
  complete: rows.length < boundedLimit,
1057
1146
  };
1058
1147
  }
@@ -10,6 +10,7 @@ export const NATIVE_V2_DASHBOARD_IDS = [
10
10
  "account-engagement-v2",
11
11
  "cross-sell-v2",
12
12
  "win-loss-v2",
13
+ "on-demand-billing-v2",
13
14
  ] as const;
14
15
 
15
16
  export type NativeV2DashboardId = (typeof NATIVE_V2_DASHBOARD_IDS)[number];
@@ -29,7 +30,16 @@ export type NativeV2BindingKey =
29
30
  | "win_loss.summary"
30
31
  | "win_loss.reasons"
31
32
  | "win_loss.evidence"
32
- | "win_loss.alerts";
33
+ | "win_loss.alerts"
34
+ | "billing.visual_views.summary"
35
+ | "billing.visual_views.trend"
36
+ | "billing.visual_views.overage"
37
+ | "billing.visual_views.growth"
38
+ | "billing.visual_views.insights"
39
+ | "billing.agent_credits.summary"
40
+ | "billing.agent_credits.trend"
41
+ | "billing.agent_credits.overage"
42
+ | "billing.agent_credits.insights";
33
43
 
34
44
  export interface NativeV2Binding {
35
45
  programId: string;
@@ -387,6 +397,222 @@ export const nativeV2DashboardManifests: readonly NativeV2DashboardManifest[] =
387
397
  }),
388
398
  ],
389
399
  },
400
+ {
401
+ id: "on-demand-billing-v2",
402
+ name: "On Demand Billing v2",
403
+ description:
404
+ "Native on-demand billing dashboard for Visual Views and Agent Credits: usage, rollover, overage, growth signals, and billing insights.",
405
+ category: "Operations",
406
+ tags: [
407
+ "native",
408
+ "v2",
409
+ "billing",
410
+ "on-demand",
411
+ "visual-views",
412
+ "agent-credits",
413
+ ],
414
+ requiredBindings: [
415
+ "billing.visual_views.summary",
416
+ "billing.visual_views.trend",
417
+ "billing.visual_views.overage",
418
+ "billing.visual_views.growth",
419
+ "billing.visual_views.insights",
420
+ "billing.agent_credits.summary",
421
+ "billing.agent_credits.trend",
422
+ "billing.agent_credits.overage",
423
+ "billing.agent_credits.insights",
424
+ ],
425
+ panels: [
426
+ section(
427
+ "billing-visual-views-overview",
428
+ "Visual Views",
429
+ "Visual Views / Overview",
430
+ ),
431
+ boundPanel({
432
+ id: "billing-visual-views-summary",
433
+ title: "Visual Views summary",
434
+ bindingKey: "billing.visual_views.summary",
435
+ chartType: "metric",
436
+ width: 1,
437
+ tab: "Visual Views / Overview",
438
+ config: {
439
+ yKey: "value",
440
+ yFormatter: "number",
441
+ description:
442
+ "Current Visual Views usage or contracted allowance, as emitted by the bound program.",
443
+ },
444
+ requiredColumns: ["value"],
445
+ }),
446
+ boundPanel({
447
+ id: "billing-visual-views-trend",
448
+ title: "Usage over time",
449
+ bindingKey: "billing.visual_views.trend",
450
+ chartType: "area",
451
+ width: 3,
452
+ tab: "Visual Views / Overview",
453
+ config: {
454
+ xKey: "month",
455
+ yKeys: ["actual", "contracted", "rollover"],
456
+ yFormatter: "number",
457
+ legend: true,
458
+ },
459
+ requiredColumns: ["month", "actual", "contracted", "rollover"],
460
+ }),
461
+ boundPanel({
462
+ id: "billing-visual-views-insights",
463
+ title: "Billing insights",
464
+ bindingKey: "billing.visual_views.insights",
465
+ chartType: "callout",
466
+ width: 3,
467
+ tab: "Visual Views / Overview",
468
+ requiredColumns: ["severity", "message"],
469
+ }),
470
+ boundPanel({
471
+ id: "billing-visual-views-overage",
472
+ title: "Overage and rollover",
473
+ bindingKey: "billing.visual_views.overage",
474
+ chartType: "table",
475
+ width: 3,
476
+ tab: "Visual Views / Overage",
477
+ config: {
478
+ columns: [
479
+ { key: "company_name", label: "Company" },
480
+ { key: "month", label: "Month", format: "date" },
481
+ { key: "actual", label: "Actual", format: "number" },
482
+ { key: "contracted", label: "Contracted", format: "number" },
483
+ { key: "rollover", label: "Rollover", format: "number" },
484
+ {
485
+ key: "newAllowance",
486
+ label: "New allowance",
487
+ format: "number",
488
+ },
489
+ { key: "overage", label: "Overage", format: "number" },
490
+ {
491
+ key: "overageRate",
492
+ label: "Overage rate",
493
+ format: "currency",
494
+ },
495
+ {
496
+ key: "overageBilled",
497
+ label: "Overage billed",
498
+ format: "currency",
499
+ },
500
+ ],
501
+ limit: 100,
502
+ },
503
+ requiredColumns: [
504
+ "company_name",
505
+ "month",
506
+ "actual",
507
+ "contracted",
508
+ "rollover",
509
+ "newAllowance",
510
+ "overage",
511
+ "overageRate",
512
+ "overageBilled",
513
+ ],
514
+ }),
515
+ boundPanel({
516
+ id: "billing-visual-views-growth",
517
+ title: "High growth companies",
518
+ bindingKey: "billing.visual_views.growth",
519
+ chartType: "table",
520
+ width: 3,
521
+ tab: "Visual Views / Growth",
522
+ config: { limit: 100 },
523
+ requiredColumns: [],
524
+ }),
525
+ section(
526
+ "billing-agent-credits-overview",
527
+ "Agent Credits",
528
+ "Agent Credits / Overview",
529
+ ),
530
+ boundPanel({
531
+ id: "billing-agent-credits-summary",
532
+ title: "Agent Credits summary",
533
+ bindingKey: "billing.agent_credits.summary",
534
+ chartType: "metric",
535
+ width: 1,
536
+ tab: "Agent Credits / Overview",
537
+ config: {
538
+ yKey: "value",
539
+ yFormatter: "number",
540
+ description:
541
+ "Current Agent Credits usage or contracted allowance, as emitted by the bound program.",
542
+ },
543
+ requiredColumns: ["value"],
544
+ }),
545
+ boundPanel({
546
+ id: "billing-agent-credits-trend",
547
+ title: "Credits over time",
548
+ bindingKey: "billing.agent_credits.trend",
549
+ chartType: "area",
550
+ width: 3,
551
+ tab: "Agent Credits / Overview",
552
+ config: {
553
+ xKey: "month",
554
+ yKeys: ["actual", "contracted", "rollover"],
555
+ yFormatter: "number",
556
+ legend: true,
557
+ },
558
+ requiredColumns: ["month", "actual", "contracted", "rollover"],
559
+ }),
560
+ boundPanel({
561
+ id: "billing-agent-credits-insights",
562
+ title: "Billing insights",
563
+ bindingKey: "billing.agent_credits.insights",
564
+ chartType: "callout",
565
+ width: 3,
566
+ tab: "Agent Credits / Overview",
567
+ requiredColumns: ["severity", "message"],
568
+ }),
569
+ boundPanel({
570
+ id: "billing-agent-credits-overage",
571
+ title: "Overage and rollover",
572
+ bindingKey: "billing.agent_credits.overage",
573
+ chartType: "table",
574
+ width: 3,
575
+ tab: "Agent Credits / Overage",
576
+ config: {
577
+ columns: [
578
+ { key: "company_name", label: "Company" },
579
+ { key: "month", label: "Month", format: "date" },
580
+ { key: "actual", label: "Actual", format: "number" },
581
+ { key: "contracted", label: "Contracted", format: "number" },
582
+ { key: "rollover", label: "Rollover", format: "number" },
583
+ {
584
+ key: "newAllowance",
585
+ label: "New allowance",
586
+ format: "number",
587
+ },
588
+ { key: "overage", label: "Overage", format: "number" },
589
+ {
590
+ key: "overageRate",
591
+ label: "Overage rate",
592
+ format: "currency",
593
+ },
594
+ {
595
+ key: "overageBilled",
596
+ label: "Overage billed",
597
+ format: "currency",
598
+ },
599
+ ],
600
+ limit: 100,
601
+ },
602
+ requiredColumns: [
603
+ "company_name",
604
+ "month",
605
+ "actual",
606
+ "contracted",
607
+ "rollover",
608
+ "newAllowance",
609
+ "overage",
610
+ "overageRate",
611
+ "overageBilled",
612
+ ],
613
+ }),
614
+ ],
615
+ },
390
616
  ] as const;
391
617
 
392
618
  export function getNativeV2DashboardManifest(
@@ -10,6 +10,7 @@ import actionsRegistry from "../../.generated/actions-registry.js";
10
10
  import { INITIAL_TOOL_NAMES } from "../lib/agent-chat-plan-mode";
11
11
  import { ANALYTICS_CONNECTOR_CATALOG } from "../lib/analytics-connector-catalog";
12
12
  import { credentialProviderConfigs } from "../lib/credential-keys";
13
+ import { isProductionServerlessRuntime } from "../lib/production-serverless-runtime.js";
13
14
  import {
14
15
  draftClaimsAnalyticsMetrics,
15
16
  failedDataQueryAttemptMessage,
@@ -881,6 +882,10 @@ export async function searchDashboardMentions(query: string, event?: any) {
881
882
 
882
883
  export default createAgentChatPlugin({
883
884
  appId: "analytics",
885
+ // Resource prompt hydration performs additive schema checks. Keep that
886
+ // work out of production serverless cold starts; it is not needed for the
887
+ // dashboard's domain prompt and can contend with the request's DB queries.
888
+ leanPrompt: isProductionServerlessRuntime(),
884
889
  actions: loadActionsFromStaticRegistry(actionsRegistry),
885
890
  initialToolNames: INITIAL_TOOL_NAMES,
886
891
  corpusTools: "lazy",
@@ -13,6 +13,7 @@ function platformSchedulerOwnsBackfill(): boolean {
13
13
  return (
14
14
  process.env.NETLIFY === "true" ||
15
15
  Boolean(process.env.NETLIFY_FUNCTION_NAME) ||
16
+ process.env.NITRO_PRESET === "netlify" ||
16
17
  globalThis.__AGENT_NATIVE_ANALYTICS_ROLLUP_BACKFILL_SCHEDULED_RUNTIME__ ===
17
18
  true
18
19
  );
@@ -1,5 +1,4 @@
1
1
  import {
2
- deferMigration,
3
2
  ensureAdditiveColumns,
4
3
  getDbExec,
5
4
  runMigrations,
@@ -10,8 +9,7 @@ import { isInBackgroundFunctionRuntime } from "@agent-native/core/server";
10
9
  // startup so the dashboard / analysis share actions know where to dispatch.
11
10
  import "../db/index.js";
12
11
  import * as schema from "../db/schema.js";
13
- import { isHistoricalAnalyticsRollupBackfillComplete } from "../jobs/analytics-rollup-backfill.js";
14
- import { repairPersistedFirstPartyDashboardQueries } from "../lib/first-party-dashboard-repair.js";
12
+ import { isProductionServerlessRuntime } from "../lib/production-serverless-runtime.js";
15
13
 
16
14
  /**
17
15
  * Every Drizzle table exported from schema.ts. Filters out type-only and
@@ -1407,11 +1405,9 @@ const runAnalyticsMigrations = runMigrations(
1407
1405
  version: 134,
1408
1406
  name: "analytics-rollups-historical-backfill-repair",
1409
1407
  sql: {},
1410
- run: async () => {
1411
- if (!(await isHistoricalAnalyticsRollupBackfillComplete())) {
1412
- return deferMigration();
1413
- }
1414
- },
1408
+ // The historical rebuild is an out-of-band job. Do not defer this
1409
+ // marker until it completes: a pending named migration is retried by
1410
+ // every cold start and turns a recoverable backfill into a boot blocker.
1415
1411
  },
1416
1412
  {
1417
1413
  version: 135,
@@ -1421,6 +1417,28 @@ const runAnalyticsMigrations = runMigrations(
1421
1417
  ALTER TABLE analytics_rollup_backfill_state ADD COLUMN IF NOT EXISTS lease_expires_at TEXT;
1422
1418
  `,
1423
1419
  },
1420
+ {
1421
+ version: 136,
1422
+ name: "analytics-events-backfill-cursor-indexes",
1423
+ sql: {
1424
+ postgres: `CREATE INDEX CONCURRENTLY IF NOT EXISTS analytics_events_org_received_id_idx ON analytics_events (org_id, received_at, id); CREATE INDEX CONCURRENTLY IF NOT EXISTS analytics_events_owner_received_id_idx ON analytics_events (owner_email, received_at, id) WHERE org_id IS NULL`,
1425
+ sqlite: `CREATE INDEX IF NOT EXISTS analytics_events_org_received_id_idx ON analytics_events (org_id, received_at, id); CREATE INDEX IF NOT EXISTS analytics_events_owner_received_id_idx ON analytics_events (owner_email, received_at, id) WHERE org_id IS NULL`,
1426
+ },
1427
+ },
1428
+ {
1429
+ version: 137,
1430
+ name: "dashboard-name-locks",
1431
+ sql: {
1432
+ postgres: `CREATE TABLE IF NOT EXISTS dashboard_name_locks (
1433
+ name_key TEXT PRIMARY KEY,
1434
+ created_at TEXT NOT NULL DEFAULT (now()::text)
1435
+ )`,
1436
+ sqlite: `CREATE TABLE IF NOT EXISTS dashboard_name_locks (
1437
+ name_key TEXT PRIMARY KEY,
1438
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
1439
+ )`,
1440
+ },
1441
+ },
1424
1442
  ],
1425
1443
  { table: "analytics_migrations" },
1426
1444
  );
@@ -1452,18 +1470,34 @@ export default async (nitroApp: any): Promise<void> => {
1452
1470
  );
1453
1471
  return;
1454
1472
  }
1473
+ const isNetlifyServerlessRuntime =
1474
+ isProductionServerlessRuntime() ||
1475
+ process.env.NETLIFY === "true" ||
1476
+ Boolean(process.env.NETLIFY_FUNCTION_NAME) ||
1477
+ Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME) ||
1478
+ Boolean(process.env.LAMBDA_TASK_ROOT);
1479
+ if (
1480
+ isNetlifyServerlessRuntime &&
1481
+ process.env.ANALYTICS_SKIP_BOOT_MIGRATIONS === "1"
1482
+ ) {
1483
+ console.info(
1484
+ "[db] Skipping Analytics migrations in production serverless runtime by explicit incident flag",
1485
+ );
1486
+ return;
1487
+ }
1488
+ // The schema must exist before the first query. Measured cost on this
1489
+ // database (180 tables): ~5.5s for the version check alone, which is why the
1490
+ // serverless runtime skips this entirely via ANALYTICS_SKIP_BOOT_MIGRATIONS
1491
+ // above rather than paying it on every cold start.
1492
+ // guard:allow-boot-data-work — schema must exist before the first query
1455
1493
  await runAnalyticsMigrations(nitroApp);
1456
- try {
1457
- if (await repairPersistedFirstPartyDashboardQueries()) {
1458
- console.info(
1459
- "[db] Repaired bounded recurring-user queries on the canonical first-party dashboard.",
1460
- );
1461
- }
1462
- } catch (err) {
1463
- console.warn(
1464
- "[db] Failed to repair canonical first-party dashboard queries (non-fatal):",
1465
- err instanceof Error ? err.message : err,
1494
+ if (isNetlifyServerlessRuntime) {
1495
+ // The migration list is authoritative; repeating repair and schema
1496
+ // introspection on every function cold start only adds pool pressure.
1497
+ console.info(
1498
+ "[db] Skipping post-migration schema convergence in production serverless runtime",
1466
1499
  );
1500
+ return;
1467
1501
  }
1468
1502
  try {
1469
1503
  const summary = await ensureAdditiveColumns({
@@ -2,7 +2,8 @@
2
2
  name: asset-generation
3
3
  description: >-
4
4
  Use Assets for brand-safe image or video generation, human picker UI,
5
- search/list/export actions, and cross-app asset selection.
5
+ search/list/export actions, and cross-app asset selection. Use when a visual
6
+ needs to be generated, refined, found, or handed off to another app.
6
7
  metadata:
7
8
  visibility: both
8
9
  ---
@@ -14,6 +15,24 @@ metadata:
14
15
  Use the Assets app when a workflow needs reusable brand media, a human picker,
15
16
  or generated image/video assets that another app can reference by ID and URL.
16
17
 
18
+ ## Visual authority and brief
19
+
20
+ Assets produces media; it does not invent a replacement brand language. Before
21
+ generating, resolve the user's explicit subject, audience, message, format, and
22
+ must-preserve constraints, then the active library, preset, or linked design
23
+ system and its custom instructions, then approved Creative Context references.
24
+ Impeccable-inspired guidance is a quality lens for composition, hierarchy,
25
+ restraint, and finish — never a reason to override those sources.
26
+
27
+ Compile the request into a short art-direction brief: visual role, subject,
28
+ composition and crop, palette or material treatment, lighting or medium,
29
+ exact visible text if any, semantic constraints, and exclusions. Classify the
30
+ slot as `produce` (new media), `direct` (an existing approved asset), or
31
+ `semantic` (a UI/icon/diagram the caller should build with its own primitives).
32
+ Do not generate a decorative photo where the caller needs a semantic graphic.
33
+ If brand context is missing, make the result clearly exploratory rather than
34
+ claiming a brand match.
35
+
17
36
  ## Choose The Path
18
37
 
19
38
  - Use `generate-asset` when a person should get newly generated, on-brand image
@@ -76,7 +95,9 @@ or generated image/video assets that another app can reference by ID and URL.
76
95
  6. Let the server choose a small deterministic reference set unless the user
77
96
  named exact assets. Canonical style anchors come from
78
97
  `assetLibraries.settings.canonicalStyleAssetIds` and
79
- `assets.metadata.isStyleAnchor`.
98
+ `assets.metadata.isStyleAnchor`; they must remain subordinate to explicit
99
+ library, preset, and per-run constraints rather than introducing a second
100
+ visual language.
80
101
  7. Pass `tier: "fast"` for exploration, `tier: "best"` for final/high-value
81
102
  output, or `tier: "auto"` when there is no clear preference.
82
103
  - Model/ratio compatibility: Gemini image models accept any `aspectRatio`, but
@@ -101,6 +122,11 @@ hydrated browser-derived design brief. Use `analyze-collection-style` when a
101
122
  collection needs upgraded vision brand analysis from image references before
102
123
  generation. Brand QA scoring and best-of-N selection are deferred.
103
124
 
125
+ Generation success confirms a run and its provenance, not visual quality or
126
+ brand match. Report the selected library, preset, style anchors, and whether
127
+ the result used an Assets-grounded or fallback path. Claim a quality evaluator
128
+ only when one actually ran.
129
+
104
130
  ## Video Workflows
105
131
 
106
132
  1. Call `generate-video` with `16:9` or `9:16` and relevant image references.
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  name: image-generation
3
- description: Generate and refine brand-consistent images from libraries, references, and prior candidates.
3
+ description: >-
4
+ Generate and refine brand-consistent images from libraries, references, and
5
+ prior candidates. Use before calling image-generation or refinement actions.
4
6
  ---
5
7
 
6
8
  # Image Generation
@@ -8,6 +10,19 @@ description: Generate and refine brand-consistent images from libraries, referen
8
10
  Use this skill before calling `generate-image`, `generate-image-batch`, or
9
11
  `refine-image`.
10
12
 
13
+ ## Prompt contract
14
+
15
+ Treat references as evidence, not decoration. The prompt should explain the
16
+ asset's job, subject, framing, medium, lighting, palette, exact text policy,
17
+ and what must not change. Keep the active library or preset's style brief and
18
+ the caller's design-system constraints authoritative; Impeccable-style
19
+ composition guidance may improve the result but must not replace them.
20
+
21
+ Before generating, decide whether the slot needs a produced image, a direct
22
+ reuse of an approved asset, or a semantic UI/icon/diagram owned by the caller.
23
+ Do not use image generation to paper over missing product facts, customer
24
+ evidence, screenshots, or exact logos.
25
+
11
26
  ## Rules
12
27
 
13
28
  - Start from composer `@` mentions when the user tags generation inputs.