@agent-native/core 0.145.5 → 0.145.7

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 (393) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +18 -0
  3. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  4. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +17 -1
  5. package/corpus/templates/analytics/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  6. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +1 -0
  7. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +22 -3
  8. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +76 -23
  9. package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  10. package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  11. package/corpus/templates/analytics/AGENTS.md +2 -1
  12. package/corpus/templates/analytics/actions/account-deep-dive.ts +83 -47
  13. package/corpus/templates/analytics/actions/create-dashboard-folder.ts +27 -0
  14. package/corpus/templates/analytics/actions/gong-calls.ts +3 -3
  15. package/corpus/templates/analytics/actions/list-dashboard-folders.ts +26 -0
  16. package/corpus/templates/analytics/actions/list-sql-dashboards.ts +1 -0
  17. package/corpus/templates/analytics/actions/set-dashboard-folder.ts +26 -0
  18. package/corpus/templates/analytics/app/components/ProviderCorpusJobNotifier.tsx +18 -3
  19. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +6 -4
  20. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  21. package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +12 -2
  22. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +35 -20
  23. package/corpus/templates/analytics/app/global.css +17 -0
  24. package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +29 -15
  25. package/corpus/templates/analytics/app/hooks/use-dashboard-views.ts +15 -3
  26. package/corpus/templates/analytics/app/i18n-data.ts +296 -0
  27. package/corpus/templates/analytics/app/lib/prefetch-keys.ts +23 -2
  28. package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +642 -0
  29. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +66 -31
  30. package/corpus/templates/analytics/app/root.tsx +4 -0
  31. package/corpus/templates/analytics/app/routes/dashboards._index.tsx +5 -1
  32. package/corpus/templates/analytics/changelog/2026-08-07-added-a-dashboards-overview-with-personal-and-shared-folders.md +6 -0
  33. package/corpus/templates/analytics/changelog/2026-08-07-analytics-no-longer-stalls-under-bursts-of-event-ingest-key-.md +6 -0
  34. package/corpus/templates/analytics/changelog/2026-08-07-analytics-tracking-and-chat-startup-no-longer-emit-avoidable.md +6 -0
  35. package/corpus/templates/analytics/changelog/2026-08-07-dashboard-panels-now-load-custom-api-data-programs-reliably.md +6 -0
  36. package/corpus/templates/analytics/changelog/2026-08-07-gong-searches-conserve-api-quota-and-report-incomplete-coverage.md +6 -0
  37. package/corpus/templates/analytics/changelog/2026-08-07-searchable-dashboards-make-personal-and-shared-folders-easie.md +6 -0
  38. package/corpus/templates/analytics/netlify.toml +3 -0
  39. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +112 -0
  40. package/corpus/templates/analytics/server/db/index.ts +12 -0
  41. package/corpus/templates/analytics/server/db/schema.ts +14 -0
  42. package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +4 -0
  43. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -0
  44. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +85 -15
  45. package/corpus/templates/analytics/server/lib/dashboard-folders-store.ts +168 -0
  46. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +9 -4
  47. package/corpus/templates/analytics/server/lib/dashboards-store.ts +116 -1
  48. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +4 -8
  49. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +65 -10
  50. package/corpus/templates/analytics/server/lib/gong.ts +139 -78
  51. package/corpus/templates/analytics/server/lib/session-replay.ts +5 -5
  52. package/corpus/templates/analytics/server/plugins/db.ts +55 -15
  53. package/corpus/templates/analytics/server/plugins/session-replay-retention-jobs.ts +6 -2
  54. package/corpus/templates/analytics/server/routes/api/session-replay/retention.post.ts +65 -0
  55. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +18 -0
  56. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  57. package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  58. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +1 -0
  59. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +76 -23
  60. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  61. package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  62. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +18 -0
  63. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  64. package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  65. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +1 -0
  66. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +76 -23
  67. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  68. package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  69. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +18 -0
  70. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  71. package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  72. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +1 -0
  73. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +76 -23
  74. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  75. package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  76. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  77. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  78. package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  79. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  80. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  81. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  82. package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  83. package/corpus/templates/chat/.env.example +3 -0
  84. package/corpus/templates/chat/AGENTS.md +4 -0
  85. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +18 -0
  86. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  87. package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  88. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +1 -0
  89. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +76 -23
  90. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  91. package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  92. package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +4 -0
  93. package/corpus/templates/clips/actions/request-transcript.ts +52 -3
  94. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -10
  95. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
  96. package/corpus/templates/clips/changelog/2026-08-07-screen-recordings-now-capture-tab-and-system-audio-even-when.md +6 -0
  97. package/corpus/templates/clips/changelog/2026-08-07-transcription-now-retries-transient-cloud-failures-automatic.md +6 -0
  98. package/corpus/templates/clips/server/db/schema.ts +7 -0
  99. package/corpus/templates/clips/server/plugins/db.ts +8 -0
  100. package/corpus/templates/clips/shared/recording-capture.ts +38 -0
  101. package/corpus/templates/clips/shared/transcript-failure.ts +89 -0
  102. package/corpus/templates/content/.agents/skills/actions/SKILL.md +18 -0
  103. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  104. package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  105. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +1 -0
  106. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +76 -23
  107. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  108. package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  109. package/corpus/templates/content/.env.example +9 -3
  110. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -0
  111. package/corpus/templates/content/changelog/2026-08-07-collapsed-sidebar-utility-buttons-stay-anchored-at-the-botto.md +6 -0
  112. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  113. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +76 -23
  114. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  115. package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  116. package/corpus/templates/design/.agents/skills/actions/SKILL.md +18 -0
  117. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  118. package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  119. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +1 -0
  120. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +76 -23
  121. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  122. package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  123. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +18 -0
  124. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  125. package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  126. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +1 -0
  127. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +76 -23
  128. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  129. package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  130. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +18 -0
  131. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  132. package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  133. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +1 -0
  134. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +76 -23
  135. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  136. package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  137. package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +279 -0
  138. package/corpus/templates/factory/actions/get-factory-automation-health.ts +23 -4
  139. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +1 -1
  140. package/corpus/templates/factory/app/routes/factory.tsx +21 -3
  141. package/corpus/templates/factory/changelog/2026-08-07-factory-can-keep-builder-bot-pull-requests-moving-by-request.md +6 -0
  142. package/corpus/templates/factory/server/lib/require-factory-automation.ts +1 -0
  143. package/corpus/templates/factory/server/plugins/agent-chat.ts +4 -1
  144. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +81 -12
  145. package/corpus/templates/factory/server/triage/github-client.ts +31 -0
  146. package/corpus/templates/factory/server/triage/pr-babysit.ts +75 -1
  147. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +18 -0
  148. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  149. package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  150. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +1 -0
  151. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +76 -23
  152. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  153. package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  154. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  155. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +1 -0
  156. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +76 -23
  157. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  158. package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  159. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +18 -0
  160. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  161. package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  162. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +1 -0
  163. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +76 -23
  164. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  165. package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  166. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +18 -0
  167. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  168. package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  169. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +1 -0
  170. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +76 -23
  171. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  172. package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  173. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -1
  174. package/corpus/templates/plan/changelog/2026-08-07-inline-help-icons-now-stay-visually-balanced-with-nearby-tex.md +6 -0
  175. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +18 -0
  176. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  177. package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  178. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +1 -0
  179. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +76 -23
  180. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  181. package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  182. package/corpus/templates/slides/.env.example +5 -0
  183. package/corpus/templates/slides/changelog/2026-08-07-fixed-generated-slides-briefly-disappearing-while-they-are-b.md +6 -0
  184. package/corpus/templates/slides/server/plugins/collab.ts +20 -8
  185. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +18 -0
  186. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  187. package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  188. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +1 -0
  189. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +76 -23
  190. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  191. package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  192. package/corpus/templates/tasks/.env.example +3 -0
  193. package/dist/agent/production-agent.js +24 -3
  194. package/dist/client/AgentPanel.d.ts +6 -0
  195. package/dist/client/AgentPanel.js +176 -30
  196. package/dist/client/AssistantChat.d.ts +2 -0
  197. package/dist/client/AssistantChat.js +4 -1
  198. package/dist/client/ConnectBuilderCard.js +6 -11
  199. package/dist/client/MultiTabAssistantChat.js +1 -1
  200. package/dist/client/RuntimeConfigNotice.d.ts +1 -0
  201. package/dist/client/RuntimeConfigNotice.js +94 -0
  202. package/dist/client/agent-chat/index.d.ts +1 -1
  203. package/dist/client/agent-chat/index.js +1 -1
  204. package/dist/client/agent-chat-adapter.js +85 -4
  205. package/dist/client/agent-page/AgentTabsPage.js +1 -1
  206. package/dist/client/agent-sidebar-state.d.ts +6 -0
  207. package/dist/client/agent-sidebar-state.js +25 -0
  208. package/dist/client/app-providers.js +2 -1
  209. package/dist/client/assistant-ui-recovery.js +1 -1
  210. package/dist/client/chat/index.d.ts +1 -1
  211. package/dist/client/chat/index.js +1 -1
  212. package/dist/client/chat/markdown-renderer.d.ts +2 -1
  213. package/dist/client/chat/markdown-renderer.js +48 -2
  214. package/dist/client/chat/message-components.d.ts +6 -0
  215. package/dist/client/chat/message-components.js +182 -53
  216. package/dist/client/chat/tool-call-display.d.ts +16 -4
  217. package/dist/client/chat/tool-call-display.js +225 -18
  218. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  219. package/dist/client/frame-protocol.d.ts +4 -0
  220. package/dist/client/i18n.js +9 -0
  221. package/dist/client/integrations/IntegrationsPanel.js +2 -5
  222. package/dist/client/onboarding/FirstRunOnboarding.js +2 -3
  223. package/dist/client/org/TeamPage.js +49 -6
  224. package/dist/client/org/hooks.d.ts +7 -2
  225. package/dist/client/org/hooks.js +11 -4
  226. package/dist/client/resources/McpConnectionSuggestion.js +2 -3
  227. package/dist/client/resources/McpIntegrationDialog.js +2 -16
  228. package/dist/client/resources/McpIntegrationLogo.d.ts +11 -0
  229. package/dist/client/resources/McpIntegrationLogo.js +14 -0
  230. package/dist/client/resources/ResourceTree.js +1 -1
  231. package/dist/client/resources/mcp-integration-logos.d.ts +1 -0
  232. package/dist/client/resources/mcp-integration-logos.js +47 -18
  233. package/dist/client/settings/useBuilderStatus.js +6 -0
  234. package/dist/client/ui/index.d.ts +1 -0
  235. package/dist/client/ui/index.js +1 -0
  236. package/dist/client/use-db-sync.js +4 -0
  237. package/dist/collab/struct-routes.d.ts +1 -1
  238. package/dist/config.d.ts +26 -3
  239. package/dist/config.js +106 -14
  240. package/dist/db/ddl-guard.d.ts +15 -2
  241. package/dist/db/ddl-guard.js +53 -5
  242. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  243. package/dist/jobs/scheduler.js +7 -0
  244. package/dist/localization/default-messages.d.ts +17 -0
  245. package/dist/localization/default-messages.js +17 -0
  246. package/dist/mcp/oauth-client-metadata.js +5 -1
  247. package/dist/mcp/oauth-route.d.ts +5 -4
  248. package/dist/mcp/oauth-route.js +25 -9
  249. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  250. package/dist/mcp/server.d.ts +1 -1
  251. package/dist/mcp/server.js +9 -10
  252. package/dist/notifications/routes.d.ts +2 -2
  253. package/dist/observability/routes.d.ts +3 -3
  254. package/dist/org/handlers.d.ts +1 -0
  255. package/dist/org/handlers.js +17 -2
  256. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  257. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  258. package/dist/provider-api/corpus-jobs.d.ts +12 -2
  259. package/dist/provider-api/corpus-jobs.js +31 -1
  260. package/dist/provider-api/index.d.ts +2 -0
  261. package/dist/provider-api/index.js +7 -1
  262. package/dist/secrets/routes.d.ts +3 -3
  263. package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +1 -1
  264. package/dist/server/agent-chat/recurring-jobs-runtime.js +14 -2
  265. package/dist/server/agent-chat/script-entries.js +12 -1
  266. package/dist/server/agent-chat-plugin.js +2 -2
  267. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  268. package/dist/server/auth.d.ts +1 -0
  269. package/dist/server/auth.js +85 -1
  270. package/dist/server/better-auth-instance.d.ts +9 -0
  271. package/dist/server/better-auth-instance.js +25 -11
  272. package/dist/server/core-routes-plugin.d.ts +7 -0
  273. package/dist/server/core-routes-plugin.js +51 -5
  274. package/dist/server/create-server.js +23 -2
  275. package/dist/server/db-pressure.d.ts +38 -0
  276. package/dist/server/db-pressure.js +147 -0
  277. package/dist/server/index.d.ts +1 -0
  278. package/dist/server/index.js +1 -0
  279. package/dist/server/legacy-auth-migration.d.ts +10 -0
  280. package/dist/server/legacy-auth-migration.js +37 -0
  281. package/dist/server/onboarding-html.js +206 -2
  282. package/dist/server/poll.d.ts +26 -0
  283. package/dist/server/poll.js +108 -13
  284. package/dist/server/ssr-handler.js +4 -1
  285. package/dist/server/transcribe-voice.d.ts +1 -1
  286. package/dist/shared/index.d.ts +1 -0
  287. package/dist/shared/index.js +1 -0
  288. package/dist/shared/runtime-config.d.ts +44 -0
  289. package/dist/shared/runtime-config.js +284 -0
  290. package/dist/styles/agent-native.css +48 -1
  291. package/dist/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  292. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  293. package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  294. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  295. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  296. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  297. package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  298. package/dist/templates/chat/.env.example +3 -0
  299. package/dist/templates/chat/AGENTS.md +4 -0
  300. package/dist/templates/default/.agents/skills/actions/SKILL.md +18 -0
  301. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  302. package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  303. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
  304. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
  305. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  306. package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  307. package/dist/templates/default/AGENTS.md +6 -1
  308. package/dist/templates/default/app/i18n/ar-SA.ts +6 -0
  309. package/dist/templates/default/app/i18n/de-DE.ts +6 -0
  310. package/dist/templates/default/app/i18n/en-US.ts +6 -0
  311. package/dist/templates/default/app/i18n/es-ES.ts +6 -0
  312. package/dist/templates/default/app/i18n/fr-FR.ts +6 -0
  313. package/dist/templates/default/app/i18n/hi-IN.ts +6 -0
  314. package/dist/templates/default/app/i18n/ja-JP.ts +6 -0
  315. package/dist/templates/default/app/i18n/ko-KR.ts +6 -0
  316. package/dist/templates/default/app/i18n/pt-BR.ts +6 -0
  317. package/dist/templates/default/app/i18n/zh-CN.ts +6 -0
  318. package/dist/templates/default/app/i18n/zh-TW.ts +6 -0
  319. package/dist/templates/headless/.agents/skills/actions/SKILL.md +18 -0
  320. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  321. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
  322. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  323. package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  324. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
  325. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  326. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  327. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
  328. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
  329. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  330. package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  331. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
  332. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
  333. package/dist/templates/workspace-core/AGENTS.md +7 -2
  334. package/dist/templates/workspace-root/AGENTS.md +5 -0
  335. package/dist/vite/client.d.ts +3 -3
  336. package/dist/vite/client.js +47 -1
  337. package/dist/vite/index.d.ts +1 -1
  338. package/docs/content/agent-native-config.mdx +240 -139
  339. package/docs/content/authentication.mdx +17 -0
  340. package/docs/content/deployment.mdx +19 -14
  341. package/docs/content/drop-in-agent.mdx +19 -2
  342. package/docs/content/environment-variables.mdx +63 -38
  343. package/docs/content/getting-started-actions.mdx +15 -6
  344. package/docs/content/getting-started-database.mdx +14 -10
  345. package/docs/content/getting-started-pages.mdx +32 -35
  346. package/docs/content/getting-started.mdx +7 -6
  347. package/package.json +1 -1
  348. package/src/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  349. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  350. package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  351. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  352. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  353. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  354. package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  355. package/src/templates/chat/.env.example +3 -0
  356. package/src/templates/chat/AGENTS.md +4 -0
  357. package/src/templates/default/.agents/skills/actions/SKILL.md +18 -0
  358. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  359. package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  360. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
  361. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
  362. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  363. package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  364. package/src/templates/default/AGENTS.md +6 -1
  365. package/src/templates/default/app/i18n/ar-SA.ts +6 -0
  366. package/src/templates/default/app/i18n/de-DE.ts +6 -0
  367. package/src/templates/default/app/i18n/en-US.ts +6 -0
  368. package/src/templates/default/app/i18n/es-ES.ts +6 -0
  369. package/src/templates/default/app/i18n/fr-FR.ts +6 -0
  370. package/src/templates/default/app/i18n/hi-IN.ts +6 -0
  371. package/src/templates/default/app/i18n/ja-JP.ts +6 -0
  372. package/src/templates/default/app/i18n/ko-KR.ts +6 -0
  373. package/src/templates/default/app/i18n/pt-BR.ts +6 -0
  374. package/src/templates/default/app/i18n/zh-CN.ts +6 -0
  375. package/src/templates/default/app/i18n/zh-TW.ts +6 -0
  376. package/src/templates/headless/.agents/skills/actions/SKILL.md +18 -0
  377. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  378. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
  379. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  380. package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  381. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
  382. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  383. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  384. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
  385. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
  386. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  387. package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  388. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
  389. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
  390. package/src/templates/workspace-core/AGENTS.md +7 -2
  391. package/src/templates/workspace-root/AGENTS.md +5 -0
  392. package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +0 -1
  393. package/corpus/templates/dispatch/app/routes/admin.apps.tsx +0 -1
@@ -1,19 +1,14 @@
1
1
  // Gong sales call intelligence API helper
2
2
  // Fetches calls, transcripts, and users
3
3
 
4
- import { resolveCredential } from "./credentials";
5
- import {
6
- requireRequestCredentialContext,
7
- scopedCredentialCacheKey,
8
- } from "./credentials-context";
4
+ import { scopedCredentialCacheKey } from "./credentials-context";
9
5
  import {
10
6
  DEFAULT_GONG_CALL_LIMIT,
11
7
  limitGongCalls,
12
8
  normalizeGongCallLimit,
13
9
  } from "./gong-limits";
14
- import { resolveAnalyticsGongCredentials } from "./provider-credentials";
10
+ import { executeProviderApiRequest } from "./provider-api";
15
11
 
16
- const DEFAULT_API_BASE = "https://api.gong.io/v2";
17
12
  const MAX_GONG_SEARCH_PAGES = 50;
18
13
  const MAX_GONG_CALL_LIST_PAGES = 50;
19
14
  const MAX_GONG_EXHAUSTIVE_RECORDS = 500;
@@ -24,38 +19,101 @@ const cache = new Map<string, { data: unknown; ts: number }>();
24
19
  const CACHE_TTL_MS = 10 * 60 * 1000;
25
20
  const MAX_CACHE = 120;
26
21
 
27
- async function getAuthHeader(): Promise<string> {
28
- const ctx = requireRequestCredentialContext("GONG_ACCESS_KEY");
29
- const credentials = await resolveAnalyticsGongCredentials({ ctx });
30
- if (!credentials)
31
- throw new Error("GONG_ACCESS_KEY and GONG_ACCESS_SECRET not configured");
32
- return `Basic ${Buffer.from(
33
- `${credentials.accessKey}:${credentials.accessSecret}`,
34
- ).toString("base64")}`;
35
- }
36
-
37
- async function getApiBase(): Promise<string> {
38
- const ctx = requireRequestCredentialContext("GONG_ACCESS_KEY");
39
- const configured = await resolveCredential("GONG_API_BASE", ctx);
40
- return (configured || DEFAULT_API_BASE).replace(/\/+$/, "");
41
- }
42
-
43
22
  export interface GongRequestOptions {
44
23
  signal?: AbortSignal;
45
24
  deadlineAt?: number;
46
25
  }
47
26
 
48
- function requestSignal(options?: GongRequestOptions): AbortSignal {
49
- const remainingMs = options?.deadlineAt
27
+ function requestTimeoutMs(options?: GongRequestOptions): number {
28
+ return options?.deadlineAt
50
29
  ? Math.max(
51
30
  1,
52
31
  Math.min(GONG_API_REQUEST_TIMEOUT_MS, options.deadlineAt - Date.now()),
53
32
  )
54
33
  : GONG_API_REQUEST_TIMEOUT_MS;
55
- const timeoutSignal = AbortSignal.timeout(remainingMs);
56
- return options?.signal
57
- ? AbortSignal.any([options.signal, timeoutSignal])
58
- : timeoutSignal;
34
+ }
35
+
36
+ interface GongProviderResponse {
37
+ response: {
38
+ ok: boolean;
39
+ status: number;
40
+ headers?: Record<string, string>;
41
+ json?: unknown;
42
+ text?: string;
43
+ };
44
+ }
45
+
46
+ function splitGongPath(path: string): {
47
+ path: string;
48
+ query?: Record<string, string>;
49
+ } {
50
+ const separator = path.indexOf("?");
51
+ if (separator < 0) return { path };
52
+ const query = Object.fromEntries(
53
+ new URLSearchParams(path.slice(separator + 1)).entries(),
54
+ );
55
+ return {
56
+ path: path.slice(0, separator),
57
+ ...(Object.keys(query).length > 0 ? { query } : {}),
58
+ };
59
+ }
60
+
61
+ function responseHeader(
62
+ headers: Record<string, string> | undefined,
63
+ name: string,
64
+ ): string | undefined {
65
+ const lowerName = name.toLowerCase();
66
+ return Object.entries(headers ?? {}).find(
67
+ ([key]) => key.toLowerCase() === lowerName,
68
+ )?.[1];
69
+ }
70
+
71
+ function responseDetail(response: GongProviderResponse["response"]): string {
72
+ if (typeof response.text === "string" && response.text.trim()) {
73
+ return response.text.replace(/\s+/g, " ").trim().slice(0, 2_000);
74
+ }
75
+ if (response.json !== undefined) {
76
+ return JSON.stringify(response.json).slice(0, 2_000);
77
+ }
78
+ return "";
79
+ }
80
+
81
+ function gongApiError(response: GongProviderResponse["response"]): Error {
82
+ const requestId =
83
+ responseHeader(response.headers, "x-request-id") ??
84
+ responseHeader(response.headers, "request-id");
85
+ const retryAfter = responseHeader(response.headers, "retry-after");
86
+ const metadata = [
87
+ requestId ? `requestId ${requestId}` : "",
88
+ response.status === 429 && retryAfter ? `retry-after ${retryAfter}` : "",
89
+ ]
90
+ .filter(Boolean)
91
+ .join(", ");
92
+ const detail = responseDetail(response);
93
+ return new Error(
94
+ `Gong API error ${response.status}${metadata ? ` (${metadata})` : ""}${detail ? `: ${detail}` : ""}`,
95
+ );
96
+ }
97
+
98
+ async function executeGongRequest<T>(options: {
99
+ method: "GET" | "POST";
100
+ path: string;
101
+ body?: unknown;
102
+ requestOptions?: GongRequestOptions;
103
+ }): Promise<T> {
104
+ const request = splitGongPath(options.path);
105
+ const result = (await executeProviderApiRequest({
106
+ provider: "gong",
107
+ method: options.method,
108
+ path: request.path,
109
+ ...(request.query ? { query: request.query } : {}),
110
+ ...(options.body !== undefined ? { body: options.body } : {}),
111
+ timeoutMs: requestTimeoutMs(options.requestOptions),
112
+ signal: options.requestOptions?.signal,
113
+ })) as GongProviderResponse;
114
+
115
+ if (!result.response.ok) throw gongApiError(result.response);
116
+ return result.response.json as T;
59
117
  }
60
118
 
61
119
  async function apiGet<T>(
@@ -69,21 +127,12 @@ async function apiGet<T>(
69
127
  return cached.data as T;
70
128
  }
71
129
 
72
- const res = await fetch(`${await getApiBase()}${path}`, {
73
- headers: {
74
- Authorization: await getAuthHeader(),
75
- "Content-Type": "application/json",
76
- },
77
- signal: requestSignal(options),
130
+ const data = await executeGongRequest<T>({
131
+ method: "GET",
132
+ path,
133
+ requestOptions: options,
78
134
  });
79
135
 
80
- if (!res.ok) {
81
- const text = await res.text();
82
- throw new Error(`Gong API error ${res.status}: ${text}`);
83
- }
84
-
85
- const data = await res.json();
86
-
87
136
  if (cache.size >= MAX_CACHE) {
88
137
  const oldest = cache.keys().next().value;
89
138
  if (oldest) cache.delete(oldest);
@@ -108,23 +157,13 @@ async function apiPost<T>(
108
157
  return cached.data as T;
109
158
  }
110
159
 
111
- const res = await fetch(`${await getApiBase()}${path}`, {
160
+ const data = await executeGongRequest<T>({
112
161
  method: "POST",
113
- headers: {
114
- Authorization: await getAuthHeader(),
115
- "Content-Type": "application/json",
116
- },
117
- body: JSON.stringify(body),
118
- signal: requestSignal(options),
162
+ path,
163
+ body,
164
+ requestOptions: options,
119
165
  });
120
166
 
121
- if (!res.ok) {
122
- const text = await res.text();
123
- throw new Error(`Gong API error ${res.status}: ${text}`);
124
- }
125
-
126
- const data = await res.json();
127
-
128
167
  if (cache.size >= MAX_CACHE) {
129
168
  const oldest = cache.keys().next().value;
130
169
  if (oldest) cache.delete(oldest);
@@ -298,29 +337,9 @@ export async function getCall(
298
337
  return data.calls?.[0] ?? null;
299
338
  }
300
339
 
301
- export async function getCallDetail(
302
- callId: string,
303
- options?: GongRequestOptions,
304
- ): Promise<GongCallDetail | null> {
305
- const body = {
306
- filter: { callIds: [callId] },
307
- contentSelector: {
308
- exposedFields: {
309
- parties: true,
310
- content: { brief: true, keyPoints: true, outline: true },
311
- },
312
- },
313
- };
314
- const data = await apiPost<{ calls?: any[] }>(
315
- "/calls/extensive",
316
- body,
317
- `detail:${callId}`,
318
- options,
319
- );
320
- const call = data.calls?.[0];
321
- if (!call) return null;
340
+ function normalizeCallDetail(call: any, fallbackId: string): GongCallDetail {
322
341
  return {
323
- id: call.metaData?.id ?? callId,
342
+ id: call.metaData?.id ?? fallbackId,
324
343
  title: call.metaData?.title || "Untitled",
325
344
  url: call.metaData?.url || "",
326
345
  started: call.metaData?.started || "",
@@ -340,6 +359,48 @@ export async function getCallDetail(
340
359
  };
341
360
  }
342
361
 
362
+ export async function getCallDetails(
363
+ callIds: string[],
364
+ options?: GongRequestOptions,
365
+ ): Promise<GongCallDetail[]> {
366
+ const ids = Array.from(
367
+ new Set(
368
+ callIds
369
+ .map((id) => (typeof id === "string" ? id.trim() : ""))
370
+ .filter(Boolean),
371
+ ),
372
+ );
373
+ if (!ids.length) return [];
374
+
375
+ const body = {
376
+ filter: { callIds: ids },
377
+ contentSelector: {
378
+ exposedFields: {
379
+ parties: true,
380
+ content: { brief: true, keyPoints: true, outline: true },
381
+ },
382
+ },
383
+ };
384
+ const data = await apiPost<{ calls?: any[] }>(
385
+ "/calls/extensive",
386
+ body,
387
+ `details:${ids.join(",")}`,
388
+ options,
389
+ );
390
+ return (data.calls ?? []).map((call, index) =>
391
+ normalizeCallDetail(call, ids[index] ?? ""),
392
+ );
393
+ }
394
+
395
+ export async function getCallDetail(
396
+ callId: string,
397
+ options?: GongRequestOptions,
398
+ ): Promise<GongCallDetail | null> {
399
+ const details = await getCallDetails([callId], options);
400
+ const detail = details[0];
401
+ return detail === undefined ? null : detail;
402
+ }
403
+
343
404
  export async function getCallTranscripts(
344
405
  callIds: string[],
345
406
  options?: GongRequestOptions,
@@ -39,7 +39,10 @@ import {
39
39
  SESSION_REPLAY_NETWORK_EVENT_TAG,
40
40
  } from "../../shared/session-replay-diagnostics.js";
41
41
  import { getDb, schema } from "../db/index.js";
42
- import { resolveAnalyticsEventDimensions } from "./first-party-analytics.js";
42
+ import {
43
+ resolveAnalyticsEventDimensions,
44
+ touchPublicKeyLastUsedAt,
45
+ } from "./first-party-analytics.js";
43
46
 
44
47
  export type ReplayRange = "24h" | "7d" | "30d" | "90d" | "all";
45
48
 
@@ -1654,10 +1657,7 @@ export async function recordSessionReplayChunks(
1654
1657
  })
1655
1658
  .where(eq(schema.sessionRecordings.id, recording.id));
1656
1659
 
1657
- await db
1658
- .update(schema.analyticsPublicKeys)
1659
- .set({ lastUsedAt: ingestedAt })
1660
- .where(eq(schema.analyticsPublicKeys.id, key.id));
1660
+ await touchPublicKeyLastUsedAt(key.id, ingestedAt);
1661
1661
 
1662
1662
  recordChange({
1663
1663
  source: "session-recordings",
@@ -1439,6 +1439,58 @@ const runAnalyticsMigrations = runMigrations(
1439
1439
  )`,
1440
1440
  },
1441
1441
  },
1442
+ {
1443
+ version: 138,
1444
+ name: "analytics-dashboard-folders",
1445
+ sql: {
1446
+ postgres: `CREATE TABLE IF NOT EXISTS dashboard_folders (
1447
+ id TEXT PRIMARY KEY,
1448
+ name TEXT NOT NULL,
1449
+ scope TEXT NOT NULL,
1450
+ created_at TEXT NOT NULL DEFAULT (now()::text),
1451
+ updated_at TEXT NOT NULL DEFAULT (now()::text),
1452
+ owner_email TEXT NOT NULL DEFAULT 'local@localhost',
1453
+ org_id TEXT,
1454
+ visibility TEXT NOT NULL DEFAULT 'private'
1455
+ );
1456
+ CREATE TABLE IF NOT EXISTS dashboard_folder_shares (
1457
+ id TEXT PRIMARY KEY,
1458
+ resource_id TEXT NOT NULL,
1459
+ principal_type TEXT NOT NULL,
1460
+ principal_id TEXT NOT NULL,
1461
+ role TEXT NOT NULL DEFAULT 'viewer',
1462
+ created_by TEXT NOT NULL,
1463
+ created_at TEXT NOT NULL DEFAULT (now()::text)
1464
+ );
1465
+ ALTER TABLE dashboards ADD COLUMN IF NOT EXISTS folder_id TEXT;
1466
+ CREATE INDEX IF NOT EXISTS dashboard_folders_owner_org_idx ON dashboard_folders (owner_email, org_id);
1467
+ CREATE INDEX IF NOT EXISTS dashboard_folder_shares_resource_idx ON dashboard_folder_shares (resource_id);
1468
+ CREATE INDEX IF NOT EXISTS dashboards_folder_idx ON dashboards (folder_id)`,
1469
+ sqlite: `CREATE TABLE IF NOT EXISTS dashboard_folders (
1470
+ id TEXT PRIMARY KEY,
1471
+ name TEXT NOT NULL,
1472
+ scope TEXT NOT NULL,
1473
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
1474
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
1475
+ owner_email TEXT NOT NULL DEFAULT 'local@localhost',
1476
+ org_id TEXT,
1477
+ visibility TEXT NOT NULL DEFAULT 'private'
1478
+ );
1479
+ CREATE TABLE IF NOT EXISTS dashboard_folder_shares (
1480
+ id TEXT PRIMARY KEY,
1481
+ resource_id TEXT NOT NULL,
1482
+ principal_type TEXT NOT NULL,
1483
+ principal_id TEXT NOT NULL,
1484
+ role TEXT NOT NULL DEFAULT 'viewer',
1485
+ created_by TEXT NOT NULL,
1486
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
1487
+ );
1488
+ ALTER TABLE dashboards ADD COLUMN IF NOT EXISTS folder_id TEXT;
1489
+ CREATE INDEX IF NOT EXISTS dashboard_folders_owner_org_idx ON dashboard_folders (owner_email, org_id);
1490
+ CREATE INDEX IF NOT EXISTS dashboard_folder_shares_resource_idx ON dashboard_folder_shares (resource_id);
1491
+ CREATE INDEX IF NOT EXISTS dashboards_folder_idx ON dashboards (folder_id)`,
1492
+ },
1493
+ },
1442
1494
  ],
1443
1495
  { table: "analytics_migrations" },
1444
1496
  );
@@ -1476,29 +1528,17 @@ export default async (nitroApp: any): Promise<void> => {
1476
1528
  Boolean(process.env.NETLIFY_FUNCTION_NAME) ||
1477
1529
  Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME) ||
1478
1530
  Boolean(process.env.LAMBDA_TASK_ROOT);
1479
- if (
1480
- isNetlifyServerlessRuntime &&
1481
- process.env.ANALYTICS_SKIP_BOOT_MIGRATIONS === "1"
1482
- ) {
1531
+ if (isNetlifyServerlessRuntime && !isScheduledRollupRuntime) {
1483
1532
  console.info(
1484
- "[db] Skipping Analytics migrations in production serverless runtime by explicit incident flag",
1533
+ "[db] Skipping Analytics migrations in production serverless runtime",
1485
1534
  );
1486
1535
  return;
1487
1536
  }
1488
1537
  // The schema must exist before the first query. Measured cost on this
1489
1538
  // 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.
1539
+ // serverless runtime never runs it on cold starts.
1492
1540
  // guard:allow-boot-data-work — schema must exist before the first query
1493
1541
  await runAnalyticsMigrations(nitroApp);
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",
1499
- );
1500
- return;
1501
- }
1502
1542
  try {
1503
1543
  const summary = await ensureAdditiveColumns({
1504
1544
  db: getDbExec(),
@@ -1,19 +1,23 @@
1
1
  import { runSessionReplayRetentionOnce } from "../jobs/session-replay-retention";
2
+ import { isProductionServerlessRuntime } from "../lib/production-serverless-runtime";
2
3
 
3
4
  const ONE_DAY_MS = 24 * 60 * 60 * 1000;
4
5
  let skippingLogged = false;
5
6
 
6
7
  export default function registerSessionReplayRetentionJobs(): void {
7
8
  const isProd = process.env.NODE_ENV === "production";
9
+ const isServerless = isProductionServerlessRuntime();
8
10
  const flag =
9
11
  process.env.ANALYTICS_SESSION_REPLAY_RETENTION_JOBS ??
10
12
  process.env.RUN_BACKGROUND_JOBS;
11
- const enabled = flag === "1" || (isProd && flag !== "0");
13
+ const enabled = !isServerless && (flag === "1" || (isProd && flag !== "0"));
12
14
 
13
15
  if (!enabled) {
14
16
  if (!skippingLogged) {
15
17
  console.log(
16
- "[session-replay] Skipping retention job (set ANALYTICS_SESSION_REPLAY_RETENTION_JOBS=1 or RUN_BACKGROUND_JOBS=1 to enable in dev; on by default in production)",
18
+ isServerless
19
+ ? "[session-replay] Skipping in-process retention job because production serverless runtimes rely on scheduled/background sweeps."
20
+ : "[session-replay] Skipping retention job (set ANALYTICS_SESSION_REPLAY_RETENTION_JOBS=1 or RUN_BACKGROUND_JOBS=1 to enable in dev; on by default in production)",
17
21
  );
18
22
  skippingLogged = true;
19
23
  }
@@ -0,0 +1,65 @@
1
+ import { timingSafeEqual } from "node:crypto";
2
+
3
+ import { createError, defineEventHandler, getHeader } from "h3";
4
+
5
+ // guard:allow-action-twin — external scheduler endpoint authenticates before invoking retention job logic.
6
+ import { runSessionReplayRetentionOnce } from "../../../jobs/session-replay-retention";
7
+
8
+ declare global {
9
+ var __AGENT_NATIVE_SESSION_REPLAY_RETENTION_SCHEDULED_RUNTIME__:
10
+ | boolean
11
+ | undefined;
12
+ }
13
+
14
+ function productionLike(): boolean {
15
+ return (
16
+ process.env.NODE_ENV === "production" ||
17
+ process.env.NETLIFY === "true" ||
18
+ process.env.VERCEL === "1" ||
19
+ Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME)
20
+ );
21
+ }
22
+
23
+ function scheduledFunctionRuntime(): boolean {
24
+ return (
25
+ globalThis.__AGENT_NATIVE_SESSION_REPLAY_RETENTION_SCHEDULED_RUNTIME__ ===
26
+ true
27
+ );
28
+ }
29
+
30
+ function cronSecret(): string | null {
31
+ const secret = process.env.SESSION_REPLAY_RETENTION_CRON_SECRET?.trim();
32
+ return secret ? secret : null;
33
+ }
34
+
35
+ function headerMatchesSecret(
36
+ header: string | undefined,
37
+ secret: string,
38
+ ): boolean {
39
+ const expected = `Bearer ${secret}`;
40
+ const value = header?.trim() ?? "";
41
+ if (value.length !== expected.length) return false;
42
+ return timingSafeEqual(Buffer.from(value), Buffer.from(expected));
43
+ }
44
+
45
+ export default defineEventHandler(async (event) => {
46
+ const secret = cronSecret();
47
+ const scheduledRuntime = scheduledFunctionRuntime();
48
+ if (!secret && productionLike() && !scheduledRuntime) {
49
+ throw createError({
50
+ statusCode: 503,
51
+ statusMessage: "SESSION_REPLAY_RETENTION_CRON_SECRET is required",
52
+ });
53
+ }
54
+
55
+ if (
56
+ secret &&
57
+ !scheduledRuntime &&
58
+ !headerMatchesSecret(getHeader(event, "authorization"), secret)
59
+ ) {
60
+ throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
61
+ }
62
+
63
+ const result = await runSessionReplayRetentionOnce();
64
+ return { ok: true, ...result };
65
+ });
@@ -20,6 +20,24 @@ Before creating any custom REST/API route for app data, inspect `actions/` and t
20
20
 
21
21
  **Stop trigger:** the moment you are about to create a file under `server/routes/api/` — or add server middleware to guard one — stop and check it against the exception list in *When You Still Need Custom `/api/` Routes* below. If it is not on that list, write a `defineAction` instead. This applies even when you already started the route; abandoning a half-written action to hand-roll routes is the exact failure this rule exists to prevent.
22
22
 
23
+ ## Keep actions deterministic and composable
24
+
25
+ An action may call a provider API, validate or normalize data, and persist
26
+ records without being an AI feature. Keep those operations deterministic,
27
+ focused, and independently useful to the agent. Do not put LLM calls or a
28
+ second model runtime in ordinary actions. The only narrow exception is the
29
+ `completeText()` text-in/text-out escape hatch described in
30
+ `delegate-to-agent`; it must not own tools, chat history, run state, side
31
+ effects, or user steering.
32
+
33
+ When a workflow is framed as research, analysis, generation, recommendation,
34
+ or synthesis, or spans several provider calls and writes, route the user into
35
+ the AgentSidebar and let the agent orchestrate focused actions. Do not hide an
36
+ AI-shaped workflow behind one opaque `generate-*` or `create-*` action just
37
+ because its implementation is deterministic. A visible user-initiated run
38
+ should use `sendToAgentChat({ openSidebar: true })`, and its follow-ups should
39
+ continue in the same thread rather than a separate freeform input.
40
+
23
41
  ## Why
24
42
 
25
43
  Actions give the agent callable tools with structured input/output, AND they give the frontend a typed client contract through hooks. One implementation serves both the agent and the UI. They keep the agent's chat context clean, they're reusable, and they can be tested independently.
@@ -56,6 +56,11 @@ The repeated app shell has two distinct navigation surfaces:
56
56
  labeled as local, preview, or analyze. For original/generated review, stack
57
57
  the source above the result by default and use side-by-side only for short,
58
58
  highly scannable content.
59
+ - Deterministic implementation does not make an AI-shaped experience
60
+ deterministic. If the user expects research, analysis, generation,
61
+ recommendation, synthesis, visible progress, or steering, route the button
62
+ to the AgentSidebar and let the agent call focused actions. Keep revisions in
63
+ the same thread instead of adding a second freeform prompt box.
59
64
  - Standalone apps with `AgentSidebar` must resolve one assistant-ui runtime
60
65
  context. Match direct assistant-ui pins to the installed core/toolkit peer
61
66
  graph, use Vite dedupe/aliases when linked dependencies can split contexts,
@@ -14,11 +14,21 @@ metadata:
14
14
 
15
15
  ## Rule
16
16
 
17
- The UI never calls an LLM directly. Product workflows are delegated to the
18
- agent through the chat bridge so users can see, steer, and audit the work.
19
- Server-side one-shot model calls are an explicit escape hatch for narrow text
20
- transforms only; use `completeText()` from `@agent-native/core/server` when the
21
- work intentionally does not need tools, chat history, or run state.
17
+ The app's default AI surface is the agent chat. Any user-facing work that asks
18
+ the model to research, analyze, generate, recommend, synthesize, or reason over
19
+ multiple steps must start or continue in the AgentSidebar so users can see,
20
+ steer, and audit the work. UI buttons use `sendToAgentChat()` with
21
+ `openSidebar: true`, and follow-up or revision text belongs in that same thread
22
+ instead of a second app-local textbox.
23
+
24
+ Actions are tools, not alternate AI runtimes. Keep them deterministic and
25
+ focused: provider reads, validation, deterministic transforms, CRUD, and
26
+ persistence are good action work. Let the agent orchestrate several such tools
27
+ when the workflow is AI-shaped or user-steerable. Server-side one-shot model
28
+ calls are a rare escape hatch for narrow text transforms only; use
29
+ `completeText()` from `@agent-native/core/server` only when the work
30
+ intentionally does not need tools, chat history, run state, side effects, or
31
+ user steering.
22
32
 
23
33
  ## Why
24
34
 
@@ -35,6 +45,7 @@ sendToAgentChat({
35
45
  message: "Generate a summary of this document",
36
46
  context: documentContent, // optional hidden context (not shown in chat UI)
37
47
  submit: true, // auto-submit to the agent
48
+ openSidebar: true,
38
49
  });
39
50
  ```
40
51
 
@@ -56,6 +67,10 @@ sendToAgentChat({
56
67
  This is still a full agent run: tools, actions, thread state, and run tracking
57
68
  all remain active. It simply does not focus or open the sidebar.
58
69
 
70
+ Use this silent form only for explicitly background or system-initiated work.
71
+ It is not the default for a user clicking an AI-labeled button; visible work
72
+ should open the sidebar so the user can follow and redirect the run.
73
+
59
74
  **From scripts (Node):**
60
75
 
61
76
  ```ts
@@ -77,8 +92,9 @@ const result = await completeText({
77
92
  });
78
93
  ```
79
94
 
80
- Wrap user-facing uses in actions so the UI and agent share the same operation.
81
- Do not call provider SDKs directly.
95
+ If the narrow exception is exposed to the UI, wrap it in an action so the UI
96
+ and agent share the same operation. Keep it clearly non-conversational and do
97
+ not call provider SDKs directly.
82
98
 
83
99
  **From the UI, detecting when agent is done:**
84
100
 
@@ -97,9 +113,9 @@ The `submit` option controls whether the message is sent automatically or placed
97
113
 
98
114
  | `submit` value | Behavior | Use when |
99
115
  | -------------- | --------------------------------------- | ----------------------------------------------------------------------------------- |
100
- | `true` | Auto-submits to the agent immediately | Routine operations the user has already approved |
101
- | `false` | Prefills the chat input for user review | High-stakes operations (deleting data, modifying code, API calls with side effects) |
102
- | omitted | Uses the project's default setting | General-purpose delegation |
116
+ | `true` | Auto-submits to the agent immediately | Routine operations with clear intent; keep `openSidebar: true` for visible work |
117
+ | `false` | Prefills the AgentSidebar composer | Review, edit, or add detail before the run; use the existing sidebar thread |
118
+ | omitted | Uses the project's default setting | General-purpose delegation |
103
119
 
104
120
  ```ts
105
121
  // Auto-submit: routine operation
@@ -109,61 +125,43 @@ sendToAgentChat({ message: "Update the project summary", submit: true });
109
125
  sendToAgentChat({
110
126
  message: "Delete all projects older than 30 days",
111
127
  submit: false,
128
+ openSidebar: true,
112
129
  });
113
130
  ```
114
131
 
115
- ## Capture user input first when generating from a prompt
116
-
117
- Buttons that produce new content ("New Design", "Create Dashboard", "Make Deck", "Generate Form") need the user's prompt as input. **Never hardcode a generic message** — the result will be a generic generation the user didn't actually ask for.
132
+ ## Capture user input in the sidebar
118
133
 
119
- **Bad** — auto-submits a placeholder message; the user never said what they wanted:
134
+ The AgentSidebar composer is the default prompt surface. When a button needs
135
+ the user to describe what to create, prefill that same composer and let the
136
+ user edit or complete it:
120
137
 
121
138
  ```tsx
122
139
  <Button
123
140
  onClick={() =>
124
- sendToAgentChat({ message: "make a design", submit: true })
141
+ sendToAgentChat({
142
+ message: "Help me create a research report from this brief:",
143
+ context: researchBrief,
144
+ submit: false,
145
+ openSidebar: true,
146
+ })
125
147
  }
126
148
  >
127
- New Design
149
+ Start in agent
128
150
  </Button>
129
151
  ```
130
152
 
131
- **Good** — Popover anchored to the button captures the prompt, then submits it:
132
-
133
- ```tsx
134
- <Popover open={open} onOpenChange={setOpen}>
135
- <PopoverTrigger asChild>
136
- <Button>New Design</Button>
137
- </PopoverTrigger>
138
- <PopoverContent className="w-96">
139
- <Textarea
140
- autoFocus
141
- value={prompt}
142
- onChange={(e) => setPrompt(e.target.value)}
143
- placeholder="What do you want to design?"
144
- />
145
- <Button
146
- onClick={() => {
147
- sendToAgentChat({ message: prompt, submit: true });
148
- setOpen(false);
149
- setPrompt("");
150
- }}
151
- >
152
- Create
153
- </Button>
154
- </PopoverContent>
155
- </Popover>
156
- ```
157
-
158
- **Always ask for input first when** the output depends on a prompt the user must provide — "design what?", "deck about what?", "dashboard for which metric?", "form for which use case?".
159
-
160
- **Auto-submit without input is fine when intent is unambiguous:**
153
+ Never auto-submit a generic creative prompt when the user has not said what
154
+ they want. Auto-submit without additional input is fine when intent is
155
+ unambiguous:
161
156
 
162
157
  - "Try to fix" on a tool error — submits the error details with a clear fix instruction
163
158
  - "Retry the last operation" after a transient failure
164
159
  - Single-purpose buttons where there is nothing meaningful for the user to add
165
160
 
166
- If you find yourself writing `submit: true` with a hardcoded creative verb (`"design a..."`, `"write a..."`, `"build a..."`), stop and add a Popover.
161
+ Use a Popover only for compact, structured parameters the UI must validate,
162
+ such as a date range, target, or approval choice. Do not add a second freeform
163
+ prompt or follow-up textbox for an AI workflow; keep the conversation and
164
+ revisions in the AgentSidebar thread.
167
165
 
168
166
  ## Delegating to a Sub-Agent (Agent Teams)
169
167