@agent-native/core 0.141.7 → 0.144.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 (371) 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/migrate-first-party-analytics-to-bigquery.ts +1 -1
  12. package/corpus/templates/analytics/actions/navigate.ts +4 -5
  13. package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
  14. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
  15. package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
  16. package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
  17. package/corpus/templates/analytics/app/i18n-data.ts +680 -0
  18. package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
  19. package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
  20. package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
  21. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
  22. package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
  23. package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
  25. package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
  26. package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
  27. package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
  28. package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
  29. package/corpus/templates/analytics/netlify.toml +7 -0
  30. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
  31. package/corpus/templates/analytics/server/db/index.ts +27 -0
  32. package/corpus/templates/analytics/server/db/schema.ts +10 -0
  33. package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
  34. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +156 -45
  35. package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
  36. package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
  37. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
  38. package/corpus/templates/analytics/server/plugins/db.ts +52 -18
  39. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +28 -2
  40. package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
  41. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
  42. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  43. package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
  44. package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  45. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
  46. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  47. package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
  48. package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  49. package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
  50. package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
  51. package/corpus/templates/brain/app/routes/sources.tsx +15 -7
  52. package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
  53. package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
  54. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
  55. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
  56. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  57. package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
  58. package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  59. package/corpus/templates/calendar/AGENTS.md +11 -32
  60. package/corpus/templates/calendar/actions/update-event.ts +107 -1
  61. package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
  62. package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
  63. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
  64. package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
  65. package/corpus/templates/calendar/app/i18n-data.ts +20 -0
  66. package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  67. package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
  68. package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
  69. package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
  70. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  71. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  72. package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  73. package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  74. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
  75. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  76. package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
  77. package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  78. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
  79. package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
  80. package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
  81. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
  82. package/corpus/templates/clips/app/components/player/player-controls.tsx +0 -3
  83. package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -33
  84. package/corpus/templates/clips/app/components/player/video-player.tsx +58 -11
  85. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
  86. package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
  87. package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
  88. package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
  89. package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
  90. package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
  91. package/corpus/templates/clips/changelog/2026-08-06-trimmed-clips-play-on-a-clean-timeline-without-cut-markers.md +6 -0
  92. package/corpus/templates/clips/desktop/src/app.tsx +48 -20
  93. package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
  94. package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
  95. package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
  96. package/corpus/templates/clips/server/plugins/db.ts +214 -26
  97. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
  98. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  99. package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
  100. package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  101. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
  102. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  103. package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
  104. package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  105. package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
  106. package/corpus/templates/crm/server/plugins/db.ts +11 -8
  107. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
  108. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
  109. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  110. package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
  111. package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  112. package/corpus/templates/design/actions/import-from-url.ts +1 -1
  113. package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
  114. package/corpus/templates/design/app/pages/Index.tsx +6 -2
  115. package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
  116. package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
  117. package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
  118. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
  119. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  120. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
  121. package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  122. package/corpus/templates/dispatch/AGENTS.md +8 -1
  123. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -0
  124. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +30 -15
  125. package/corpus/templates/dispatch/app/i18n-data.ts +131 -0
  126. package/corpus/templates/dispatch/app/routes/admin._index.tsx +4 -0
  127. package/corpus/templates/dispatch/app/routes/admin.agents.tsx +1 -0
  128. package/corpus/templates/dispatch/app/routes/admin.approvals.tsx +1 -0
  129. package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +1 -0
  130. package/corpus/templates/dispatch/app/routes/admin.apps.tsx +1 -0
  131. package/corpus/templates/dispatch/app/routes/admin.audit.tsx +1 -0
  132. package/corpus/templates/dispatch/app/routes/admin.automations.tsx +1 -0
  133. package/corpus/templates/dispatch/app/routes/admin.destinations.tsx +4 -0
  134. package/corpus/templates/dispatch/app/routes/admin.dreams.tsx +1 -0
  135. package/corpus/templates/dispatch/app/routes/admin.identities.tsx +1 -0
  136. package/corpus/templates/dispatch/app/routes/admin.integrations.tsx +4 -0
  137. package/corpus/templates/dispatch/app/routes/admin.messaging.tsx +1 -0
  138. package/corpus/templates/dispatch/app/routes/admin.metrics.tsx +1 -0
  139. package/corpus/templates/dispatch/app/routes/admin.new-app.tsx +1 -0
  140. package/corpus/templates/dispatch/app/routes/admin.operations.tsx +1 -0
  141. package/corpus/templates/dispatch/app/routes/admin.thread-debug.tsx +4 -0
  142. package/corpus/templates/dispatch/app/routes/admin.transactional-email.$appId.$id.tsx +4 -0
  143. package/corpus/templates/dispatch/app/routes/admin.transactional-email.tsx +4 -0
  144. package/corpus/templates/dispatch/app/routes/admin.tsx +1 -0
  145. package/corpus/templates/dispatch/app/routes/admin.vault.tsx +1 -0
  146. package/corpus/templates/dispatch/app/routes/admin.workspace.tsx +1 -0
  147. package/corpus/templates/dispatch/changelog/2026-08-06-dispatch-keeps-everyday-navigation-focused-while-management-.md +6 -0
  148. package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
  149. package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
  150. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
  151. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  152. package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
  153. package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  154. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
  155. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  156. package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
  157. package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  158. package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  159. package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
  160. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
  161. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  162. package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
  163. package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  164. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
  165. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  166. package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
  167. package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  168. package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
  169. package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
  170. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
  171. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  172. package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
  173. package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  174. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
  175. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
  176. package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
  177. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
  178. package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
  179. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
  180. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  181. package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
  182. package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  183. package/corpus/templates/slides/AGENTS.md +17 -21
  184. package/corpus/templates/slides/_gitignore +1 -0
  185. package/corpus/templates/slides/actions/export-pptx.ts +470 -36
  186. package/corpus/templates/slides/actions/get-deck.ts +12 -0
  187. package/corpus/templates/slides/actions/import-file.ts +175 -139
  188. package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
  189. package/corpus/templates/slides/actions/import-pptx.ts +193 -68
  190. package/corpus/templates/slides/actions/patch-deck.ts +51 -0
  191. package/corpus/templates/slides/actions/update-slide.ts +29 -3
  192. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
  193. package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
  194. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
  195. package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
  196. package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
  197. package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
  198. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +173 -0
  199. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
  200. package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
  201. package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
  202. package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
  203. package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
  204. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +15 -0
  205. package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
  206. package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
  207. package/corpus/templates/slides/app/lib/create-deck-generation.ts +72 -11
  208. package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
  209. package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
  210. package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
  211. package/corpus/templates/slides/app/lib/import-uploaded-deck.ts +89 -0
  212. package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
  213. package/corpus/templates/slides/app/pages/Index.tsx +172 -15
  214. package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
  215. package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
  216. package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
  217. package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
  218. package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
  219. package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
  220. package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
  221. package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
  222. package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
  223. package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
  224. package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
  225. package/corpus/templates/slides/changelog/2026-08-06-uploaded-decks-keep-their-slides-and-visuals-when-you-improv.md +6 -0
  226. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
  227. package/corpus/templates/slides/server/handlers/import/html-converter.ts +247 -13
  228. package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
  229. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
  230. package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
  231. package/corpus/templates/slides/server/lib/chat-attachments.ts +7 -4
  232. package/corpus/templates/slides/server/lib/emails.ts +7 -2
  233. package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
  234. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
  235. package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
  236. package/corpus/templates/slides/server/lib/source-import.ts +167 -0
  237. package/corpus/templates/slides/server/plugins/agent-chat.ts +12 -3
  238. package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
  239. package/corpus/templates/slides/shared/upload-types.ts +3 -0
  240. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
  241. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  242. package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
  243. package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  244. package/dist/agent/production-agent.d.ts +17 -0
  245. package/dist/agent/production-agent.js +72 -1
  246. package/dist/cli/agent-plugin.d.ts +112 -0
  247. package/dist/cli/agent-plugin.js +1081 -0
  248. package/dist/cli/app-skill.js +39 -1
  249. package/dist/cli/code-agent-executor.d.ts +3 -0
  250. package/dist/cli/code-agent-executor.js +51 -13
  251. package/dist/cli/index.js +13 -0
  252. package/dist/cli/templates-meta.js +1 -1
  253. package/dist/client/AgentPanel.d.ts +3 -1
  254. package/dist/client/AgentPanel.js +9 -2
  255. package/dist/client/AssistantChat.d.ts +8 -0
  256. package/dist/client/AssistantChat.js +23 -8
  257. package/dist/client/NewWorkspaceAppFlow.js +1 -0
  258. package/dist/client/agent-chat-adapter.js +123 -4
  259. package/dist/client/assistant-ui-recovery.d.ts +2 -1
  260. package/dist/client/assistant-ui-recovery.js +7 -3
  261. package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
  262. package/dist/client/org/TeamPage.js +1 -1
  263. package/dist/client/require-session.js +1 -1
  264. package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
  265. package/dist/client/resources/McpConnectionSuggestion.js +27 -10
  266. package/dist/client/resources/McpIntegrationDialog.js +77 -45
  267. package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
  268. package/dist/client/resources/mcp-integration-catalog.js +255 -2
  269. package/dist/client/resources/mcp-integration-logos.js +18 -2
  270. package/dist/client/settings/AccountSettingsCard.js +2 -1
  271. package/dist/collab/struct-routes.d.ts +1 -1
  272. package/dist/db/client.d.ts +9 -0
  273. package/dist/db/client.js +51 -16
  274. package/dist/db/create-get-db.js +2 -2
  275. package/dist/db/ddl-guard.d.ts +11 -10
  276. package/dist/db/ddl-guard.js +40 -12
  277. package/dist/deploy/build.d.ts +2 -0
  278. package/dist/deploy/build.js +97 -4
  279. package/dist/deploy/workspace-deploy.js +0 -2
  280. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  281. package/dist/guards/no-env-credentials.js +9 -0
  282. package/dist/ingestion/index.d.ts +1 -1
  283. package/dist/ingestion/pptx.d.ts +68 -0
  284. package/dist/ingestion/pptx.js +660 -213
  285. package/dist/integrations/plugin.js +9 -6
  286. package/dist/jobs/scheduler.js +79 -23
  287. package/dist/localization/default-messages.d.ts +54 -0
  288. package/dist/localization/default-messages.js +57 -2
  289. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  290. package/dist/mcp-client/oauth-routes.d.ts +2 -0
  291. package/dist/mcp-client/oauth-routes.js +73 -6
  292. package/dist/observability/routes.d.ts +5 -5
  293. package/dist/onboarding/app-profile.js +11 -0
  294. package/dist/progress/routes.d.ts +1 -1
  295. package/dist/resources/handlers.d.ts +1 -1
  296. package/dist/resources/store.js +15 -1
  297. package/dist/scripts/call-agent.js +34 -4
  298. package/dist/secrets/routes.d.ts +3 -3
  299. package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
  300. package/dist/server/agent-chat/action-filters-a2a.js +36 -1
  301. package/dist/server/agent-chat-plugin.js +29 -8
  302. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  303. package/dist/server/auth.js +47 -11
  304. package/dist/server/better-auth-instance.js +5 -3
  305. package/dist/server/core-routes-plugin.d.ts +8 -1
  306. package/dist/server/core-routes-plugin.js +28 -3
  307. package/dist/server/credential-provider.d.ts +3 -3
  308. package/dist/server/credential-provider.js +90 -4
  309. package/dist/server/onboarding-html.d.ts +2 -0
  310. package/dist/server/onboarding-html.js +115 -29
  311. package/dist/server/realtime-token.d.ts +1 -1
  312. package/dist/server/self-dispatch.d.ts +5 -4
  313. package/dist/server/self-dispatch.js +25 -14
  314. package/dist/server/ssr-handler.d.ts +1 -1
  315. package/dist/server/ssr-handler.js +1 -1
  316. package/dist/server/transcribe-voice.d.ts +1 -1
  317. package/dist/shared/cache-control.d.ts +26 -2
  318. package/dist/shared/cache-control.js +43 -2
  319. package/dist/shared/password-policy.d.ts +3 -0
  320. package/dist/shared/password-policy.js +3 -0
  321. package/dist/sharing/actions/set-resource-visibility.js +16 -4
  322. package/dist/sharing/registry.d.ts +14 -0
  323. package/dist/styles/agent-native.css +6 -0
  324. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  325. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  326. package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  327. package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  328. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  329. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  330. package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  331. package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  332. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  333. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  334. package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  335. package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  336. package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  337. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  338. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  339. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  340. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  341. package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  342. package/dist/templates/workspace-root/AGENTS.md +7 -0
  343. package/dist/user-profile/actions/change-password.js +8 -3
  344. package/dist/user-profile/actions/set-password.js +5 -1
  345. package/dist/vite/action-types-plugin.js +59 -0
  346. package/docs/content/creating-templates.mdx +1 -1
  347. package/docs/content/getting-started-actions.mdx +38 -189
  348. package/docs/content/getting-started-database.mdx +80 -164
  349. package/docs/content/getting-started-pages.mdx +44 -155
  350. package/docs/content/getting-started.mdx +26 -106
  351. package/docs/content/skills-guide.mdx +13 -0
  352. package/package.json +6 -2
  353. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
  354. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  355. package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
  356. package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  357. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
  358. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  359. package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
  360. package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  361. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
  362. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  363. package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
  364. package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  365. package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
  366. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
  367. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
  368. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
  369. package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
  370. package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
  371. package/src/templates/workspace-root/AGENTS.md +7 -0
@@ -73,6 +73,8 @@ const FIRST_PARTY_QUERY_TABLES = [
73
73
  "analytics_user_days",
74
74
  ] as const;
75
75
  const BACKEND_CONFIG_CACHE_TTL_MS = 30_000;
76
+ const MAX_BACKFILL_BATCH_SIZE = 5_000;
77
+ const MAX_INSERT_BATCH_SIZE = 200;
76
78
 
77
79
  const backendConfigCache = new Map<
78
80
  string,
@@ -222,6 +224,30 @@ const FIRST_PARTY_ANALYTICS_RAW_SCHEMA = [
222
224
  ["org_id", "STRING"],
223
225
  ] as const;
224
226
 
227
+ const FIRST_PARTY_ANALYTICS_BACKFILL_COLUMNS = [
228
+ "id",
229
+ "public_key_id",
230
+ "event_name",
231
+ "user_id",
232
+ "anonymous_id",
233
+ "user_key",
234
+ "session_id",
235
+ "timestamp",
236
+ "event_date",
237
+ "received_at",
238
+ "url",
239
+ "path",
240
+ "hostname",
241
+ "referrer",
242
+ "app",
243
+ "template",
244
+ "signed_in",
245
+ "properties",
246
+ "context",
247
+ "owner_email",
248
+ "org_id",
249
+ ] as const;
250
+
225
251
  const FIRST_PARTY_ANALYTICS_QUERY_SCHEMA = FIRST_PARTY_ANALYTICS_RAW_SCHEMA;
226
252
  const FIRST_PARTY_ANALYTICS_DAILY_ROLLUP_SCHEMA = [
227
253
  ["id", "STRING"],
@@ -337,8 +363,16 @@ export async function insertFirstPartyAnalyticsRows(
337
363
  getAccessToken(),
338
364
  ]);
339
365
  const payloadRows = rows.map(firstPartyEventRowToBigQuery);
340
- for (let offset = 0; offset < payloadRows.length; offset += 50) {
341
- await insertBatch(table, token, payloadRows.slice(offset, offset + 50));
366
+ for (
367
+ let offset = 0;
368
+ offset < payloadRows.length;
369
+ offset += MAX_INSERT_BATCH_SIZE
370
+ ) {
371
+ await insertBatch(
372
+ table,
373
+ token,
374
+ payloadRows.slice(offset, offset + MAX_INSERT_BATCH_SIZE),
375
+ );
342
376
  }
343
377
  return payloadRows.length;
344
378
  }
@@ -982,77 +1016,154 @@ function serializeBackfillCursor(
982
1016
  return JSON.stringify(cursor);
983
1017
  }
984
1018
 
985
- function backfillScopeSql(
986
- scope: FirstPartyAnalyticsScope,
1019
+ function backfillBranchSql(
1020
+ predicate: string,
1021
+ predicateArgs: string[],
987
1022
  cursor: FirstPartyAnalyticsBackfillCursor,
988
1023
  ): {
989
1024
  sql: string;
990
1025
  args: string[];
991
1026
  } {
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
- }
1027
+ const cursorSql = cursor.receivedAt
1028
+ ? "(received_at > ? OR (received_at = ? AND id > ?))"
1029
+ : "";
1030
+ const cursorArgs = cursor.receivedAt
1031
+ ? [cursor.receivedAt, cursor.receivedAt, cursor.id]
1032
+ : [];
1008
1033
  return {
1009
- sql: "WHERE org_id IS NULL AND owner_email = ? AND " + cursorSql,
1010
- args: [scope.userEmail, cursor.receivedAt, cursor.receivedAt, cursor.id],
1034
+ sql: `SELECT id, received_at
1035
+ FROM analytics_events
1036
+ WHERE ${predicate}${cursorSql ? ` AND ${cursorSql}` : ""}
1037
+ ORDER BY received_at ASC, id ASC LIMIT ?`,
1038
+ args: [...predicateArgs, ...cursorArgs],
1011
1039
  };
1012
1040
  }
1013
1041
 
1042
+ function backfillRowsByIdsSql(ids: string[]): {
1043
+ sql: string;
1044
+ args: string[];
1045
+ } {
1046
+ return {
1047
+ sql: `SELECT ${FIRST_PARTY_ANALYTICS_BACKFILL_COLUMNS.join(", ")}
1048
+ FROM analytics_events
1049
+ WHERE id IN (${ids.map(() => "?").join(", ")})`,
1050
+ args: ids,
1051
+ };
1052
+ }
1053
+
1054
+ const MAX_SQLITE_BIND_VARIABLES = 900;
1055
+
1056
+ function backfillRowCursor(
1057
+ row: Record<string, unknown>,
1058
+ ): FirstPartyAnalyticsBackfillCursor {
1059
+ const id = row.id;
1060
+ const receivedAt = row.received_at ?? row.receivedAt;
1061
+ if (typeof id !== "string" || !id) {
1062
+ throw new Error("First-party analytics backfill row is missing its id");
1063
+ }
1064
+ if (typeof receivedAt !== "string" || !receivedAt) {
1065
+ throw new Error(
1066
+ "First-party analytics backfill row is missing its received_at",
1067
+ );
1068
+ }
1069
+ return { receivedAt, id };
1070
+ }
1071
+
1072
+ function compareBackfillRows(
1073
+ left: Record<string, unknown>,
1074
+ right: Record<string, unknown>,
1075
+ ): number {
1076
+ const leftCursor = backfillRowCursor(left);
1077
+ const rightCursor = backfillRowCursor(right);
1078
+ return (
1079
+ leftCursor.receivedAt.localeCompare(rightCursor.receivedAt) ||
1080
+ leftCursor.id.localeCompare(rightCursor.id)
1081
+ );
1082
+ }
1083
+
1014
1084
  export async function backfillFirstPartyAnalyticsBatch(
1015
1085
  scope: FirstPartyAnalyticsScope,
1016
1086
  cursor: string | null,
1017
1087
  limit: number,
1018
1088
  configuredTable?: string | null,
1019
1089
  ): Promise<FirstPartyAnalyticsBackfillBatch> {
1020
- const boundedLimit = Math.min(Math.max(Math.floor(limit), 1), 500);
1090
+ const boundedLimit = Math.min(
1091
+ Math.max(Math.floor(limit), 1),
1092
+ MAX_BACKFILL_BATCH_SIZE,
1093
+ );
1021
1094
  const db = getDbExec();
1022
1095
  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) {
1096
+ const branches = scope.orgId
1097
+ ? [
1098
+ { predicate: "org_id = ?", args: [scope.orgId] },
1099
+ {
1100
+ predicate: "org_id IS NULL AND owner_email = ?",
1101
+ args: [scope.userEmail],
1102
+ },
1103
+ ]
1104
+ : [
1105
+ {
1106
+ predicate: "org_id IS NULL AND owner_email = ?",
1107
+ args: [scope.userEmail],
1108
+ },
1109
+ ];
1110
+ const rows: Record<string, unknown>[] = [];
1111
+ for (const branch of branches) {
1112
+ const scoped = backfillBranchSql(
1113
+ branch.predicate,
1114
+ branch.args,
1115
+ parsedCursor,
1116
+ );
1117
+ const result = await db.execute({
1118
+ sql: scoped.sql,
1119
+ args: [...scoped.args, boundedLimit],
1120
+ timeoutMs: 20_000,
1121
+ maxAttempts: 1,
1122
+ });
1123
+ rows.push(...(result.rows as Record<string, unknown>[]));
1124
+ }
1125
+ rows.sort(compareBackfillRows);
1126
+ const selectedRows = rows.slice(0, boundedLimit);
1127
+ if (!selectedRows.length) {
1032
1128
  return {
1033
1129
  nextCursor: serializeBackfillCursor(parsedCursor),
1034
1130
  copied: 0,
1035
1131
  complete: true,
1036
1132
  };
1037
1133
  }
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",
1134
+
1135
+ const selectedIds = selectedRows.map((row) => backfillRowCursor(row).id);
1136
+ const hydratedRows: Record<string, unknown>[] = [];
1137
+ for (
1138
+ let offset = 0;
1139
+ offset < selectedIds.length;
1140
+ offset += MAX_SQLITE_BIND_VARIABLES
1141
+ ) {
1142
+ const hydratedQuery = backfillRowsByIdsSql(
1143
+ selectedIds.slice(offset, offset + MAX_SQLITE_BIND_VARIABLES),
1048
1144
  );
1145
+ const hydratedResult = await db.execute({
1146
+ sql: hydratedQuery.sql,
1147
+ args: hydratedQuery.args,
1148
+ timeoutMs: 20_000,
1149
+ maxAttempts: 1,
1150
+ });
1151
+ hydratedRows.push(...(hydratedResult.rows as Record<string, unknown>[]));
1049
1152
  }
1153
+ const hydratedById = new Map(
1154
+ hydratedRows.map((row) => [backfillRowCursor(row).id, row]),
1155
+ );
1156
+ const selectedEvents = selectedIds
1157
+ .map((id) => hydratedById.get(id))
1158
+ .filter((row): row is Record<string, unknown> => row !== undefined);
1159
+ await insertFirstPartyAnalyticsRows(selectedEvents, configuredTable);
1160
+ const lastCursor = backfillRowCursor(selectedRows[selectedRows.length - 1]!);
1050
1161
  return {
1051
1162
  nextCursor: serializeBackfillCursor({
1052
- receivedAt: lastReceivedAt,
1053
- id: lastId,
1163
+ receivedAt: lastCursor.receivedAt,
1164
+ id: lastCursor.id,
1054
1165
  }),
1055
- copied: rows.length,
1166
+ copied: selectedEvents.length,
1056
1167
  complete: rows.length < boundedLimit,
1057
1168
  };
1058
1169
  }
@@ -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({