@agent-native/core 0.145.4 → 0.145.6

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 (398) 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-tracking-and-chat-startup-no-longer-emit-avoidable.md +6 -0
  34. package/corpus/templates/analytics/changelog/2026-08-07-dashboard-panels-now-load-custom-api-data-programs-reliably.md +6 -0
  35. package/corpus/templates/analytics/changelog/2026-08-07-gong-searches-conserve-api-quota-and-report-incomplete-coverage.md +6 -0
  36. package/corpus/templates/analytics/changelog/2026-08-07-searchable-dashboards-make-personal-and-shared-folders-easie.md +6 -0
  37. package/corpus/templates/analytics/netlify.toml +3 -0
  38. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +112 -0
  39. package/corpus/templates/analytics/server/db/index.ts +12 -0
  40. package/corpus/templates/analytics/server/db/schema.ts +14 -0
  41. package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +4 -0
  42. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -0
  43. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +85 -15
  44. package/corpus/templates/analytics/server/lib/dashboard-folders-store.ts +168 -0
  45. package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +9 -4
  46. package/corpus/templates/analytics/server/lib/dashboards-store.ts +116 -1
  47. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +4 -8
  48. package/corpus/templates/analytics/server/lib/gong.ts +139 -78
  49. package/corpus/templates/analytics/server/plugins/db.ts +55 -15
  50. package/corpus/templates/analytics/server/plugins/session-replay-retention-jobs.ts +6 -2
  51. package/corpus/templates/analytics/server/routes/api/session-replay/retention.post.ts +65 -0
  52. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +18 -0
  53. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  54. package/corpus/templates/assets/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  55. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +1 -0
  56. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +76 -23
  57. package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  58. package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  59. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +18 -0
  60. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  61. package/corpus/templates/brain/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  62. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +1 -0
  63. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +76 -23
  64. package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  65. package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  66. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +18 -0
  67. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  68. package/corpus/templates/calendar/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  69. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +1 -0
  70. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +76 -23
  71. package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  72. package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  73. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  74. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  75. package/corpus/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  76. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  77. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  78. package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  79. package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  80. package/corpus/templates/chat/.env.example +3 -0
  81. package/corpus/templates/chat/AGENTS.md +4 -0
  82. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +18 -0
  83. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  84. package/corpus/templates/clips/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  85. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +1 -0
  86. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +76 -23
  87. package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  88. package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  89. package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +4 -0
  90. package/corpus/templates/clips/actions/request-transcript.ts +52 -3
  91. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +8 -3
  92. package/corpus/templates/clips/app/components/editor/waveform.tsx +2 -1
  93. package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -1
  94. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -10
  95. package/corpus/templates/clips/app/global.css +9 -0
  96. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
  97. package/corpus/templates/clips/changelog/2026-08-07-screen-recordings-now-capture-tab-and-system-audio-even-when.md +6 -0
  98. package/corpus/templates/clips/changelog/2026-08-07-transcription-now-retries-transient-cloud-failures-automatic.md +6 -0
  99. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +10 -11
  100. package/corpus/templates/clips/server/db/schema.ts +7 -0
  101. package/corpus/templates/clips/server/plugins/db.ts +8 -0
  102. package/corpus/templates/clips/shared/recording-capture.ts +38 -0
  103. package/corpus/templates/clips/shared/transcript-failure.ts +89 -0
  104. package/corpus/templates/content/.agents/skills/actions/SKILL.md +18 -0
  105. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  106. package/corpus/templates/content/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  107. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +1 -0
  108. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +76 -23
  109. package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  110. package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  111. package/corpus/templates/content/.env.example +9 -3
  112. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -0
  113. package/corpus/templates/content/changelog/2026-08-07-collapsed-sidebar-utility-buttons-stay-anchored-at-the-botto.md +6 -0
  114. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  115. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +76 -23
  116. package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  117. package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  118. package/corpus/templates/design/.agents/skills/actions/SKILL.md +18 -0
  119. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  120. package/corpus/templates/design/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  121. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +1 -0
  122. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +76 -23
  123. package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  124. package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  125. package/corpus/templates/design/actions/view-screen.ts +1 -0
  126. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +14 -1
  127. package/corpus/templates/design/changelog/2026-08-07-cmd-c-now-copies-selected-text-in-the-agent-panel-instead-of.md +6 -0
  128. package/corpus/templates/design/changelog/2026-08-07-real-time-voice-can-now-read-the-current-selection-and-edit-.md +6 -0
  129. package/corpus/templates/design/server/lib/reprompt-action-guard.ts +7 -3
  130. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +18 -0
  131. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  132. package/corpus/templates/dispatch/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  133. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +1 -0
  134. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +76 -23
  135. package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  136. package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  137. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +18 -0
  138. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  139. package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  140. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +1 -0
  141. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +76 -23
  142. package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  143. package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  144. package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +279 -0
  145. package/corpus/templates/factory/actions/get-factory-automation-health.ts +23 -4
  146. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +1 -1
  147. package/corpus/templates/factory/app/routes/factory.tsx +21 -3
  148. package/corpus/templates/factory/changelog/2026-08-07-factory-can-keep-builder-bot-pull-requests-moving-by-request.md +6 -0
  149. package/corpus/templates/factory/server/lib/require-factory-automation.ts +1 -0
  150. package/corpus/templates/factory/server/plugins/agent-chat.ts +4 -1
  151. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +81 -12
  152. package/corpus/templates/factory/server/triage/github-client.ts +31 -0
  153. package/corpus/templates/factory/server/triage/pr-babysit.ts +75 -1
  154. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +18 -0
  155. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  156. package/corpus/templates/forms/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  157. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +1 -0
  158. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +76 -23
  159. package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  160. package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  161. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  162. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +1 -0
  163. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +76 -23
  164. package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  165. package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  166. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +18 -0
  167. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  168. package/corpus/templates/mail/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  169. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +1 -0
  170. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +76 -23
  171. package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  172. package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  173. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +18 -0
  174. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  175. package/corpus/templates/plan/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  176. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +1 -0
  177. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +76 -23
  178. package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  179. package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  180. package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -1
  181. package/corpus/templates/plan/changelog/2026-08-07-inline-help-icons-now-stay-visually-balanced-with-nearby-tex.md +6 -0
  182. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +18 -0
  183. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  184. package/corpus/templates/slides/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  185. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +1 -0
  186. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +76 -23
  187. package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  188. package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  189. package/corpus/templates/slides/.env.example +5 -0
  190. package/corpus/templates/slides/changelog/2026-08-07-fixed-generated-slides-briefly-disappearing-while-they-are-b.md +6 -0
  191. package/corpus/templates/slides/server/plugins/collab.ts +20 -8
  192. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +18 -0
  193. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  194. package/corpus/templates/tasks/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  195. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +1 -0
  196. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +76 -23
  197. package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  198. package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  199. package/corpus/templates/tasks/.env.example +3 -0
  200. package/dist/agent/production-agent.js +24 -3
  201. package/dist/client/AgentPanel.d.ts +6 -0
  202. package/dist/client/AgentPanel.js +176 -30
  203. package/dist/client/AssistantChat.d.ts +2 -0
  204. package/dist/client/AssistantChat.js +4 -1
  205. package/dist/client/ConnectBuilderCard.js +6 -11
  206. package/dist/client/MultiTabAssistantChat.js +1 -1
  207. package/dist/client/RuntimeConfigNotice.d.ts +1 -0
  208. package/dist/client/RuntimeConfigNotice.js +94 -0
  209. package/dist/client/agent-chat/index.d.ts +1 -1
  210. package/dist/client/agent-chat/index.js +1 -1
  211. package/dist/client/agent-chat-adapter.js +85 -4
  212. package/dist/client/agent-page/AgentTabsPage.js +1 -1
  213. package/dist/client/agent-sidebar-state.d.ts +6 -0
  214. package/dist/client/agent-sidebar-state.js +25 -0
  215. package/dist/client/app-providers.js +2 -1
  216. package/dist/client/assistant-ui-recovery.js +1 -1
  217. package/dist/client/chat/index.d.ts +1 -1
  218. package/dist/client/chat/index.js +1 -1
  219. package/dist/client/chat/markdown-renderer.d.ts +2 -1
  220. package/dist/client/chat/markdown-renderer.js +48 -2
  221. package/dist/client/chat/message-components.d.ts +6 -0
  222. package/dist/client/chat/message-components.js +182 -53
  223. package/dist/client/chat/tool-call-display.d.ts +16 -4
  224. package/dist/client/chat/tool-call-display.js +225 -18
  225. package/dist/client/extensions/ExtensionsSidebarSection.js +1 -1
  226. package/dist/client/frame-protocol.d.ts +4 -0
  227. package/dist/client/i18n.js +9 -0
  228. package/dist/client/integrations/IntegrationsPanel.js +2 -5
  229. package/dist/client/onboarding/FirstRunOnboarding.js +2 -3
  230. package/dist/client/org/TeamPage.js +49 -6
  231. package/dist/client/org/hooks.d.ts +7 -2
  232. package/dist/client/org/hooks.js +11 -4
  233. package/dist/client/resources/McpConnectionSuggestion.js +2 -3
  234. package/dist/client/resources/McpIntegrationDialog.js +2 -16
  235. package/dist/client/resources/McpIntegrationLogo.d.ts +11 -0
  236. package/dist/client/resources/McpIntegrationLogo.js +14 -0
  237. package/dist/client/resources/ResourceTree.js +1 -1
  238. package/dist/client/resources/mcp-integration-logos.d.ts +1 -0
  239. package/dist/client/resources/mcp-integration-logos.js +47 -18
  240. package/dist/client/settings/useBuilderStatus.js +6 -0
  241. package/dist/client/ui/index.d.ts +1 -0
  242. package/dist/client/ui/index.js +1 -0
  243. package/dist/collab/struct-routes.d.ts +1 -1
  244. package/dist/config.d.ts +26 -3
  245. package/dist/config.js +106 -14
  246. package/dist/db/ddl-guard.d.ts +15 -2
  247. package/dist/db/ddl-guard.js +53 -5
  248. package/dist/jobs/scheduler.js +7 -0
  249. package/dist/localization/default-messages.d.ts +17 -0
  250. package/dist/localization/default-messages.js +17 -0
  251. package/dist/mcp/oauth-client-metadata.js +5 -1
  252. package/dist/mcp/oauth-route.d.ts +5 -4
  253. package/dist/mcp/oauth-route.js +25 -9
  254. package/dist/mcp/server.d.ts +1 -1
  255. package/dist/mcp/server.js +9 -10
  256. package/dist/notifications/routes.d.ts +3 -3
  257. package/dist/org/handlers.d.ts +1 -0
  258. package/dist/org/handlers.js +17 -2
  259. package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
  260. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  261. package/dist/provider-api/corpus-jobs.d.ts +12 -2
  262. package/dist/provider-api/corpus-jobs.js +31 -1
  263. package/dist/provider-api/index.d.ts +2 -0
  264. package/dist/provider-api/index.js +7 -1
  265. package/dist/secrets/routes.d.ts +6 -6
  266. package/dist/server/agent-chat/recurring-jobs-runtime.d.ts +1 -1
  267. package/dist/server/agent-chat/recurring-jobs-runtime.js +14 -2
  268. package/dist/server/agent-chat/script-entries.js +12 -1
  269. package/dist/server/agent-chat-plugin.js +2 -2
  270. package/dist/server/auth.d.ts +1 -0
  271. package/dist/server/auth.js +85 -1
  272. package/dist/server/better-auth-instance.d.ts +9 -0
  273. package/dist/server/better-auth-instance.js +25 -11
  274. package/dist/server/core-routes-plugin.d.ts +7 -0
  275. package/dist/server/core-routes-plugin.js +51 -5
  276. package/dist/server/create-server.js +23 -2
  277. package/dist/server/db-pressure.d.ts +38 -0
  278. package/dist/server/db-pressure.js +147 -0
  279. package/dist/server/index.d.ts +1 -0
  280. package/dist/server/index.js +1 -0
  281. package/dist/server/legacy-auth-migration.d.ts +10 -0
  282. package/dist/server/legacy-auth-migration.js +37 -0
  283. package/dist/server/onboarding-html.js +206 -2
  284. package/dist/server/poll.d.ts +26 -0
  285. package/dist/server/poll.js +108 -13
  286. package/dist/server/realtime-voice.d.ts +2 -1
  287. package/dist/server/realtime-voice.js +38 -56
  288. package/dist/server/short-lived-token.d.ts +43 -0
  289. package/dist/server/short-lived-token.js +74 -0
  290. package/dist/server/ssr-handler.js +4 -1
  291. package/dist/shared/index.d.ts +1 -0
  292. package/dist/shared/index.js +1 -0
  293. package/dist/shared/runtime-config.d.ts +44 -0
  294. package/dist/shared/runtime-config.js +284 -0
  295. package/dist/styles/agent-native.css +48 -1
  296. package/dist/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  297. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  298. package/dist/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  299. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  300. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  301. package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  302. package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  303. package/dist/templates/chat/.env.example +3 -0
  304. package/dist/templates/chat/AGENTS.md +4 -0
  305. package/dist/templates/default/.agents/skills/actions/SKILL.md +18 -0
  306. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  307. package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  308. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
  309. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
  310. package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  311. package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  312. package/dist/templates/default/AGENTS.md +6 -1
  313. package/dist/templates/default/app/i18n/ar-SA.ts +6 -0
  314. package/dist/templates/default/app/i18n/de-DE.ts +6 -0
  315. package/dist/templates/default/app/i18n/en-US.ts +6 -0
  316. package/dist/templates/default/app/i18n/es-ES.ts +6 -0
  317. package/dist/templates/default/app/i18n/fr-FR.ts +6 -0
  318. package/dist/templates/default/app/i18n/hi-IN.ts +6 -0
  319. package/dist/templates/default/app/i18n/ja-JP.ts +6 -0
  320. package/dist/templates/default/app/i18n/ko-KR.ts +6 -0
  321. package/dist/templates/default/app/i18n/pt-BR.ts +6 -0
  322. package/dist/templates/default/app/i18n/zh-CN.ts +6 -0
  323. package/dist/templates/default/app/i18n/zh-TW.ts +6 -0
  324. package/dist/templates/headless/.agents/skills/actions/SKILL.md +18 -0
  325. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  326. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
  327. package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  328. package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  329. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
  330. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  331. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  332. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
  333. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
  334. package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  335. package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  336. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
  337. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
  338. package/dist/templates/workspace-core/AGENTS.md +7 -2
  339. package/dist/templates/workspace-root/AGENTS.md +5 -0
  340. package/dist/vite/client.d.ts +3 -3
  341. package/dist/vite/client.js +47 -1
  342. package/dist/vite/index.d.ts +1 -1
  343. package/docs/content/agent-native-config.mdx +240 -139
  344. package/docs/content/authentication.mdx +17 -0
  345. package/docs/content/deployment.mdx +19 -14
  346. package/docs/content/drop-in-agent.mdx +19 -2
  347. package/docs/content/environment-variables.mdx +63 -38
  348. package/docs/content/getting-started-actions.mdx +15 -6
  349. package/docs/content/getting-started-database.mdx +14 -10
  350. package/docs/content/getting-started-pages.mdx +32 -35
  351. package/docs/content/getting-started.mdx +7 -6
  352. package/package.json +2 -2
  353. package/src/templates/chat/.agents/skills/actions/SKILL.md +18 -0
  354. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  355. package/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  356. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +1 -0
  357. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +76 -23
  358. package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  359. package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  360. package/src/templates/chat/.env.example +3 -0
  361. package/src/templates/chat/AGENTS.md +4 -0
  362. package/src/templates/default/.agents/skills/actions/SKILL.md +18 -0
  363. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  364. package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  365. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +1 -0
  366. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +76 -23
  367. package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  368. package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  369. package/src/templates/default/AGENTS.md +6 -1
  370. package/src/templates/default/app/i18n/ar-SA.ts +6 -0
  371. package/src/templates/default/app/i18n/de-DE.ts +6 -0
  372. package/src/templates/default/app/i18n/en-US.ts +6 -0
  373. package/src/templates/default/app/i18n/es-ES.ts +6 -0
  374. package/src/templates/default/app/i18n/fr-FR.ts +6 -0
  375. package/src/templates/default/app/i18n/hi-IN.ts +6 -0
  376. package/src/templates/default/app/i18n/ja-JP.ts +6 -0
  377. package/src/templates/default/app/i18n/ko-KR.ts +6 -0
  378. package/src/templates/default/app/i18n/pt-BR.ts +6 -0
  379. package/src/templates/default/app/i18n/zh-CN.ts +6 -0
  380. package/src/templates/default/app/i18n/zh-TW.ts +6 -0
  381. package/src/templates/headless/.agents/skills/actions/SKILL.md +18 -0
  382. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  383. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +76 -23
  384. package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  385. package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  386. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +18 -0
  387. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +5 -0
  388. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +45 -47
  389. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +1 -0
  390. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +76 -23
  391. package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +2 -2
  392. package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +64 -0
  393. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +4 -0
  394. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +8 -0
  395. package/src/templates/workspace-core/AGENTS.md +7 -2
  396. package/src/templates/workspace-root/AGENTS.md +5 -0
  397. package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +0 -1
  398. package/corpus/templates/dispatch/app/routes/admin.apps.tsx +0 -1
@@ -0,0 +1,38 @@
1
+ /** Counters taken in one shot from `pg_stat_activity`. */
2
+ export interface DbPressureCounters {
3
+ connections: number;
4
+ idleInTxn: number;
5
+ oldestIdleTxnS: number;
6
+ maxSameQuery: number;
7
+ /** Round-trip of this statement on an already-open connection. */
8
+ trivialQueryMs: number;
9
+ }
10
+ /**
11
+ * Measured counters, or an explicit reason they could not be taken.
12
+ *
13
+ * A monitor must never read "not measured" as "healthy", so the two are
14
+ * different shapes rather than an empty warning list.
15
+ */
16
+ export type DbPressure = ({
17
+ measured: true;
18
+ warnings: string[];
19
+ } & DbPressureCounters) | {
20
+ measured: false;
21
+ reason: string;
22
+ };
23
+ export declare const MAX_IDLE_TXN_AGE_S = 60;
24
+ export declare const MAX_TRIVIAL_QUERY_MS = 1000;
25
+ export declare const MAX_SAME_QUERY_CONCURRENCY = 10;
26
+ export declare const DB_PRESSURE_SQL = "\nSELECT\n count(*)::int AS connections,\n count(*) FILTER (WHERE state = 'idle in transaction')::int AS idle_in_txn,\n coalesce(round(max(extract(epoch from (now() - state_change)))\n FILTER (WHERE state = 'idle in transaction'))::int, 0) AS oldest_idle_txn_s,\n coalesce((\n SELECT max(c) FROM (\n SELECT count(*)::int AS c FROM pg_stat_activity\n WHERE pid <> pg_backend_pid()\n AND state = 'active'\n AND query <> ''\n GROUP BY left(query, 60)\n ) q\n ), 0)::int AS max_same_query\nFROM pg_stat_activity\nWHERE pid <> pg_backend_pid()";
27
+ /** Reasons this database looks pressured, or [] when it looks fine. */
28
+ export declare function dbPressureWarnings(p: DbPressureCounters): string[];
29
+ /**
30
+ * Read the pressure counters. Postgres-only: `pg_stat_activity` does not exist
31
+ * on SQLite/libSQL/D1, and a dialect that cannot answer reports `measured:
32
+ * false` rather than a clean-looking zero.
33
+ */
34
+ export declare function probeDbPressure(exec: {
35
+ execute: (sql: string) => Promise<unknown>;
36
+ }, dialect: string, options?: {
37
+ trivialQueryMs?: number;
38
+ }): Promise<DbPressure>;
@@ -0,0 +1,147 @@
1
+ // Database pressure — the three signals that precede an outage, measured from
2
+ // inside the app that owns the database.
3
+ //
4
+ // The analytics app degraded for hours on 2026-08-06 before it fell over, and
5
+ // every check we had said UP until the moment it said DOWN. What was actually
6
+ // true, and visible in `pg_stat_activity` the whole time:
7
+ //
8
+ // - 11-20 connections stuck `idle in transaction` up to 283s, left behind by
9
+ // serverless workers killed mid-transaction. They hold locks; nothing
10
+ // reaped them.
11
+ // - `SELECT 1` drifting from ~0.2s to 6s as those locks accumulated.
12
+ // - 47-56 concurrent copies of one unprojected query, each dragging a JSON
13
+ // blob per row.
14
+ //
15
+ // None of that is "down". All of it is the hour before down. A monitor that
16
+ // only distinguishes 200 from 500 cannot see any of it.
17
+ //
18
+ // This lives in core rather than in a workstation script because the numbers
19
+ // require a database credential, and the app already has its own. Reading them
20
+ // here means the scheduled fleet audit needs no production credentials at all.
21
+ // `scripts/chat-health.mjs` measures the same three signals locally against
22
+ // every app at once; `db-pressure.spec.ts` pins the two threshold sets equal.
23
+ // Thresholds set from that outage, not intuition. Healthy analytics reads
24
+ // 0 / 128ms / 1; at the point it went down it read 20 / 6000ms / 56.
25
+ export const MAX_IDLE_TXN_AGE_S = 60;
26
+ export const MAX_TRIVIAL_QUERY_MS = 1_000;
27
+ export const MAX_SAME_QUERY_CONCURRENCY = 10;
28
+ /**
29
+ * A hung probe must not hang the health route — that is the defect that took
30
+ * the docs site permanently cold. Short because this runs on a connection the
31
+ * liveness probe just proved is answering.
32
+ */
33
+ const PRESSURE_PROBE_DEADLINE_MS = 3_000;
34
+ export const DB_PRESSURE_SQL = `
35
+ SELECT
36
+ count(*)::int AS connections,
37
+ count(*) FILTER (WHERE state = 'idle in transaction')::int AS idle_in_txn,
38
+ coalesce(round(max(extract(epoch from (now() - state_change)))
39
+ FILTER (WHERE state = 'idle in transaction'))::int, 0) AS oldest_idle_txn_s,
40
+ coalesce((
41
+ SELECT max(c) FROM (
42
+ SELECT count(*)::int AS c FROM pg_stat_activity
43
+ WHERE pid <> pg_backend_pid()
44
+ AND state = 'active'
45
+ AND query <> ''
46
+ GROUP BY left(query, 60)
47
+ ) q
48
+ ), 0)::int AS max_same_query
49
+ FROM pg_stat_activity
50
+ WHERE pid <> pg_backend_pid()`;
51
+ /** Reasons this database looks pressured, or [] when it looks fine. */
52
+ export function dbPressureWarnings(p) {
53
+ const out = [];
54
+ if (p.idleInTxn > 0 && p.oldestIdleTxnS > MAX_IDLE_TXN_AGE_S) {
55
+ out.push(`${p.idleInTxn} idle-in-transaction (oldest ${p.oldestIdleTxnS}s) — workers killed mid-transaction still holding locks`);
56
+ }
57
+ if (p.trivialQueryMs > MAX_TRIVIAL_QUERY_MS) {
58
+ out.push(`trivial query took ${p.trivialQueryMs}ms — the database itself is slow, not the app`);
59
+ }
60
+ if (p.maxSameQuery >= MAX_SAME_QUERY_CONCURRENCY) {
61
+ out.push(`${p.maxSameQuery} concurrent copies of one query — a hot path is stampeding`);
62
+ }
63
+ return out;
64
+ }
65
+ function readCount(row, key) {
66
+ const value = row[key];
67
+ if (typeof value === "number" && Number.isFinite(value))
68
+ return value;
69
+ // Some drivers hand back bigint-ish columns as strings.
70
+ if (typeof value === "string" && value.trim() !== "") {
71
+ const parsed = Number(value);
72
+ if (Number.isFinite(parsed))
73
+ return parsed;
74
+ }
75
+ return null;
76
+ }
77
+ /**
78
+ * Read the pressure counters. Postgres-only: `pg_stat_activity` does not exist
79
+ * on SQLite/libSQL/D1, and a dialect that cannot answer reports `measured:
80
+ * false` rather than a clean-looking zero.
81
+ */
82
+ export async function probeDbPressure(exec, dialect, options = {}) {
83
+ if (dialect !== "postgres") {
84
+ return {
85
+ measured: false,
86
+ reason: `dialect ${dialect} has no pg_stat_activity`,
87
+ };
88
+ }
89
+ let timer;
90
+ try {
91
+ const trivialQueryMs = options.trivialQueryMs ?? (await measureTrivialQuery(exec));
92
+ const deadline = new Promise((_, reject) => {
93
+ timer = setTimeout(() => reject(new Error("pressure probe deadline")), PRESSURE_PROBE_DEADLINE_MS);
94
+ });
95
+ const result = (await Promise.race([
96
+ exec.execute(DB_PRESSURE_SQL),
97
+ deadline,
98
+ ]));
99
+ const row = result?.rows?.[0];
100
+ if (!row) {
101
+ return { measured: false, reason: "pressure query returned no rows" };
102
+ }
103
+ const counters = {
104
+ connections: readCount(row, "connections") ?? -1,
105
+ idleInTxn: readCount(row, "idle_in_txn") ?? -1,
106
+ oldestIdleTxnS: readCount(row, "oldest_idle_txn_s") ?? -1,
107
+ maxSameQuery: readCount(row, "max_same_query") ?? -1,
108
+ trivialQueryMs,
109
+ };
110
+ if (Object.values(counters).some((n) => n < 0)) {
111
+ return {
112
+ measured: false,
113
+ reason: "pressure query returned unreadable counters",
114
+ };
115
+ }
116
+ return {
117
+ measured: true,
118
+ ...counters,
119
+ warnings: dbPressureWarnings(counters),
120
+ };
121
+ }
122
+ catch (err) {
123
+ return {
124
+ measured: false,
125
+ reason: err instanceof Error ? err.message : String(err),
126
+ };
127
+ }
128
+ finally {
129
+ if (timer)
130
+ clearTimeout(timer);
131
+ }
132
+ }
133
+ async function measureTrivialQuery(exec) {
134
+ let timer;
135
+ const startedAt = Date.now();
136
+ try {
137
+ const deadline = new Promise((_, reject) => {
138
+ timer = setTimeout(() => reject(new Error("trivial query deadline")), PRESSURE_PROBE_DEADLINE_MS);
139
+ });
140
+ await Promise.race([exec.execute("SELECT 1"), deadline]);
141
+ return Date.now() - startedAt;
142
+ }
143
+ finally {
144
+ if (timer)
145
+ clearTimeout(timer);
146
+ }
147
+ }
@@ -37,6 +37,7 @@ export { configureAgentNativeEmbeddedEnvironment, createAgentNativeEmbeddedAuthO
37
37
  export { createThread, getThread, listThreads, updateThreadData, deleteThread, setThreadArchived, setThreadPinned, setThreadScope, type ChatThread, type ChatThreadScope, type ChatThreadSummary, type ListThreadsOptions, } from "../chat-threads/store.js";
38
38
  export { createResourcesPlugin, defaultResourcesPlugin, } from "./resources-plugin.js";
39
39
  export { createCoreRoutesPlugin, defaultCoreRoutesPlugin, FRAMEWORK_ROUTE_PREFIX, type CoreRoutesPluginOptions, } from "./core-routes-plugin.js";
40
+ export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, type RuntimeConfigEnvironment, type RuntimeConfigIssue, type RuntimeConfigIssueCode, type RuntimeConfigIssueSeverity, type RuntimeConfigPhase, type RuntimeConfigReport, type RuntimeConfigRequirements, } from "../shared/runtime-config.js";
40
41
  export { AGENT_NATIVE_OG_IMAGE_CACHE_CONTROL, AGENT_NATIVE_OG_IMAGE_HEIGHT, AGENT_NATIVE_OG_IMAGE_NETLIFY_CACHE_CONTROL, AGENT_NATIVE_OG_IMAGE_WIDTH, agentNativeOgImageResponseHeaders, createAgentNativeOgImageHandler, renderAgentNativeOgImagePng, renderAgentNativeOgImageSvg, type AgentNativeOgImageInput, } from "./social-og-image.js";
41
42
  export { OG_FONT_FAMILY, resolveOgFontFiles } from "./og-fonts.js";
42
43
  export { createBrowserSessionActionEntries, type CreateBrowserSessionActionEntriesOptions, } from "../browser-sessions/actions.js";
@@ -38,6 +38,7 @@ export { configureAgentNativeEmbeddedEnvironment, createAgentNativeEmbeddedAuthO
38
38
  export { createThread, getThread, listThreads, updateThreadData, deleteThread, setThreadArchived, setThreadPinned, setThreadScope, } from "../chat-threads/store.js";
39
39
  export { createResourcesPlugin, defaultResourcesPlugin, } from "./resources-plugin.js";
40
40
  export { createCoreRoutesPlugin, defaultCoreRoutesPlugin, FRAMEWORK_ROUTE_PREFIX, } from "./core-routes-plugin.js";
41
+ export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, } from "../shared/runtime-config.js";
41
42
  export { AGENT_NATIVE_OG_IMAGE_CACHE_CONTROL, AGENT_NATIVE_OG_IMAGE_HEIGHT, AGENT_NATIVE_OG_IMAGE_NETLIFY_CACHE_CONTROL, AGENT_NATIVE_OG_IMAGE_WIDTH, agentNativeOgImageResponseHeaders, createAgentNativeOgImageHandler, renderAgentNativeOgImagePng, renderAgentNativeOgImageSvg, } from "./social-og-image.js";
42
43
  export { OG_FONT_FAMILY, resolveOgFontFiles } from "./og-fonts.js";
43
44
  export { createBrowserSessionActionEntries, } from "../browser-sessions/actions.js";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Backfill the canonical Better Auth user for a verified legacy session.
3
+ *
4
+ * Older OAuth sessions were keyed by email in the framework `sessions` table
5
+ * before every deployment required a Better Auth `user` row. Keep the legacy
6
+ * session as the authentication proof, and use Better Auth's adapter only to
7
+ * create the missing canonical user. Do not invent a provider account: the
8
+ * next provider sign-in owns that link.
9
+ */
10
+ export declare function ensureCanonicalUserForLegacySession(email: string): Promise<boolean>;
@@ -0,0 +1,37 @@
1
+ import { getBetterAuthInternalAdapter } from "./better-auth-instance.js";
2
+ /**
3
+ * Backfill the canonical Better Auth user for a verified legacy session.
4
+ *
5
+ * Older OAuth sessions were keyed by email in the framework `sessions` table
6
+ * before every deployment required a Better Auth `user` row. Keep the legacy
7
+ * session as the authentication proof, and use Better Auth's adapter only to
8
+ * create the missing canonical user. Do not invent a provider account: the
9
+ * next provider sign-in owns that link.
10
+ */
11
+ export async function ensureCanonicalUserForLegacySession(email) {
12
+ const normalizedEmail = email.trim().toLowerCase();
13
+ if (!normalizedEmail || !normalizedEmail.includes("@"))
14
+ return false;
15
+ const adapter = await getBetterAuthInternalAdapter();
16
+ if (!adapter) {
17
+ throw new Error("Better Auth internal adapter is unavailable");
18
+ }
19
+ const findExisting = () => adapter.findUserByEmail(normalizedEmail, { includeAccounts: false });
20
+ if (await findExisting())
21
+ return false;
22
+ try {
23
+ await adapter.createUser({
24
+ email: normalizedEmail,
25
+ name: normalizedEmail.split("@")[0] || "User",
26
+ emailVerified: true,
27
+ });
28
+ return true;
29
+ }
30
+ catch (error) {
31
+ // A concurrent request may have created the same canonical user. Treat
32
+ // that race as success only after the adapter can read the winner.
33
+ if (await findExisting())
34
+ return false;
35
+ throw error;
36
+ }
37
+ }
@@ -97,6 +97,12 @@ const EN_AUTH_COPY = {
97
97
  backToSignIn: "Back to sign in",
98
98
  localNotePrefix: "Your account is stored in this app's own DB",
99
99
  localNoteSuffix: ", not a third-party service.",
100
+ localDevButton: "Continue as local dev",
101
+ localDevDescription: "Only works in local development on this computer.",
102
+ localDevHelp: "Learn about local development sign-in",
103
+ localDevSigningIn: "Signing in locally…",
104
+ localDevFailed: "Local development sign-in is unavailable.",
105
+ localDevFullOptions: "Show full sign in options",
100
106
  runLocally: "Run Locally",
101
107
  runLocallySentence: "Run locally",
102
108
  openSource: "100% free and open source",
@@ -193,6 +199,12 @@ const AUTH_LOCALE_COPY = {
193
199
  backToSignIn: "返回登录",
194
200
  localNotePrefix: "你的账户存储在此应用自己的数据库中",
195
201
  localNoteSuffix: ",而不是第三方服务。",
202
+ localDevButton: "以本地开发身份继续",
203
+ localDevDescription: "仅在此计算机的本地开发环境中有效。",
204
+ localDevHelp: "了解本地开发登录",
205
+ localDevSigningIn: "正在本地登录…",
206
+ localDevFailed: "本地开发登录不可用。",
207
+ localDevFullOptions: "显示完整登录选项",
196
208
  runLocally: "本地运行",
197
209
  runLocallySentence: "本地运行",
198
210
  openSource: "100% 免费且开源",
@@ -287,6 +299,12 @@ const AUTH_LOCALE_COPY = {
287
299
  backToSignIn: "返回登入",
288
300
  localNotePrefix: "你的帳號儲存在此應用程式自己的資料庫中",
289
301
  localNoteSuffix: ",而不是第三方服務。",
302
+ localDevButton: "以本機開發身分繼續",
303
+ localDevDescription: "僅在這台電腦的本機開發環境中有效。",
304
+ localDevHelp: "了解本機開發登入",
305
+ localDevSigningIn: "正在本機登入…",
306
+ localDevFailed: "本機開發登入無法使用。",
307
+ localDevFullOptions: "顯示完整登入選項",
290
308
  runLocally: "在本機執行",
291
309
  runLocallySentence: "在本機執行",
292
310
  openSource: "100% 免費且開源",
@@ -381,6 +399,12 @@ const AUTH_LOCALE_COPY = {
381
399
  backToSignIn: "Volver a iniciar sesión",
382
400
  localNotePrefix: "Tu cuenta se almacena en la propia base de datos de esta app",
383
401
  localNoteSuffix: ", no en un servicio de terceros.",
402
+ localDevButton: "Continuar como desarrollador local",
403
+ localDevDescription: "Solo funciona en el desarrollo local de este equipo.",
404
+ localDevHelp: "Más información sobre el inicio de sesión local",
405
+ localDevSigningIn: "Iniciando sesión localmente…",
406
+ localDevFailed: "El inicio de sesión de desarrollo local no está disponible.",
407
+ localDevFullOptions: "Mostrar todas las opciones de inicio de sesión",
384
408
  runLocally: "Ejecutar localmente",
385
409
  runLocallySentence: "Ejecutar localmente",
386
410
  openSource: "100% gratis y de código abierto",
@@ -475,6 +499,12 @@ const AUTH_LOCALE_COPY = {
475
499
  backToSignIn: "Retour à la connexion",
476
500
  localNotePrefix: "Votre compte est stocké dans la base de données propre à cette app",
477
501
  localNoteSuffix: ", pas dans un service tiers.",
502
+ localDevButton: "Continuer comme développeur local",
503
+ localDevDescription: "Fonctionne uniquement en développement local sur cet ordinateur.",
504
+ localDevHelp: "En savoir plus sur la connexion locale",
505
+ localDevSigningIn: "Connexion locale…",
506
+ localDevFailed: "La connexion de développement local est indisponible.",
507
+ localDevFullOptions: "Afficher toutes les options de connexion",
478
508
  runLocally: "Exécuter localement",
479
509
  runLocallySentence: "Exécuter localement",
480
510
  openSource: "100 % gratuit et open source",
@@ -569,6 +599,12 @@ const AUTH_LOCALE_COPY = {
569
599
  backToSignIn: "Zurück zur Anmeldung",
570
600
  localNotePrefix: "Dein Konto wird in der eigenen Datenbank dieser App gespeichert",
571
601
  localNoteSuffix: ", nicht bei einem Drittanbieter.",
602
+ localDevButton: "Als lokale Entwicklung fortfahren",
603
+ localDevDescription: "Funktioniert nur in der lokalen Entwicklung auf diesem Computer.",
604
+ localDevHelp: "Mehr über die lokale Anmeldung erfahren",
605
+ localDevSigningIn: "Lokale Anmeldung…",
606
+ localDevFailed: "Die lokale Entwicklungsanmeldung ist nicht verfügbar.",
607
+ localDevFullOptions: "Alle Anmeldeoptionen anzeigen",
572
608
  runLocally: "Lokal ausführen",
573
609
  runLocallySentence: "Lokal ausführen",
574
610
  openSource: "100 % kostenlos und Open Source",
@@ -663,6 +699,12 @@ const AUTH_LOCALE_COPY = {
663
699
  backToSignIn: "サインインに戻る",
664
700
  localNotePrefix: "アカウントはこのアプリ自身の DB に保存されます",
665
701
  localNoteSuffix: "。サードパーティサービスには保存されません。",
702
+ localDevButton: "ローカル開発として続行",
703
+ localDevDescription: "このコンピューターのローカル開発でのみ利用できます。",
704
+ localDevHelp: "ローカル開発サインインについて詳しく見る",
705
+ localDevSigningIn: "ローカルでサインイン中…",
706
+ localDevFailed: "ローカル開発のサインインは利用できません。",
707
+ localDevFullOptions: "完全なサインイン オプションを表示",
666
708
  runLocally: "ローカルで実行",
667
709
  runLocallySentence: "ローカルで実行",
668
710
  openSource: "100% 無料でオープンソース",
@@ -757,6 +799,12 @@ const AUTH_LOCALE_COPY = {
757
799
  backToSignIn: "로그인으로 돌아가기",
758
800
  localNotePrefix: "계정은 이 앱의 자체 DB에 저장됩니다",
759
801
  localNoteSuffix: ", 타사 서비스가 아닙니다.",
802
+ localDevButton: "로컬 개발자로 계속",
803
+ localDevDescription: "이 컴퓨터의 로컬 개발 환경에서만 작동합니다.",
804
+ localDevHelp: "로컬 개발 로그인 자세히 보기",
805
+ localDevSigningIn: "로컬로 로그인하는 중…",
806
+ localDevFailed: "로컬 개발 로그인을 사용할 수 없습니다.",
807
+ localDevFullOptions: "전체 로그인 옵션 보기",
760
808
  runLocally: "로컬에서 실행",
761
809
  runLocallySentence: "로컬에서 실행",
762
810
  openSource: "100% 무료 오픈 소스",
@@ -851,6 +899,12 @@ const AUTH_LOCALE_COPY = {
851
899
  backToSignIn: "Voltar para entrar",
852
900
  localNotePrefix: "Sua conta fica armazenada no banco de dados próprio deste app",
853
901
  localNoteSuffix: ", não em um serviço de terceiros.",
902
+ localDevButton: "Continuar como desenvolvedor local",
903
+ localDevDescription: "Funciona apenas no desenvolvimento local deste computador.",
904
+ localDevHelp: "Saiba mais sobre o login de desenvolvimento local",
905
+ localDevSigningIn: "Entrando localmente…",
906
+ localDevFailed: "O login de desenvolvimento local não está disponível.",
907
+ localDevFullOptions: "Mostrar todas as opções de login",
854
908
  runLocally: "Executar localmente",
855
909
  runLocallySentence: "Executar localmente",
856
910
  openSource: "100% grátis e open source",
@@ -945,6 +999,12 @@ const AUTH_LOCALE_COPY = {
945
999
  backToSignIn: "साइन इन पर वापस जाएं",
946
1000
  localNotePrefix: "आपका खाता इस ऐप के अपने DB में संग्रहीत है",
947
1001
  localNoteSuffix: ", किसी third-party सेवा में नहीं।",
1002
+ localDevButton: "स्थानीय डेवलपर के रूप में जारी रखें",
1003
+ localDevDescription: "यह केवल इस कंप्यूटर के स्थानीय विकास में काम करता है।",
1004
+ localDevHelp: "स्थानीय विकास साइन-इन के बारे में जानें",
1005
+ localDevSigningIn: "स्थानीय रूप से साइन इन हो रहा है…",
1006
+ localDevFailed: "स्थानीय विकास साइन-इन उपलब्ध नहीं है।",
1007
+ localDevFullOptions: "साइन-इन के सभी विकल्प दिखाएं",
948
1008
  runLocally: "लोकल चलाएं",
949
1009
  runLocallySentence: "लोकल चलाएं",
950
1010
  openSource: "100% मुफ्त और open source",
@@ -1039,6 +1099,12 @@ const AUTH_LOCALE_COPY = {
1039
1099
  backToSignIn: "العودة إلى تسجيل الدخول",
1040
1100
  localNotePrefix: "يتم تخزين حسابك في قاعدة بيانات هذا التطبيق",
1041
1101
  localNoteSuffix: "، وليس في خدمة خارجية.",
1102
+ localDevButton: "المتابعة كمطور محلي",
1103
+ localDevDescription: "يعمل فقط أثناء التطوير المحلي على هذا الكمبيوتر.",
1104
+ localDevHelp: "تعرف على تسجيل دخول التطوير المحلي",
1105
+ localDevSigningIn: "جارٍ تسجيل الدخول محليًا…",
1106
+ localDevFailed: "تسجيل دخول التطوير المحلي غير متاح.",
1107
+ localDevFullOptions: "عرض خيارات تسجيل الدخول الكاملة",
1042
1108
  runLocally: "تشغيل محليًا",
1043
1109
  runLocallySentence: "تشغيل محليًا",
1044
1110
  openSource: "مجاني ومفتوح المصدر 100%",
@@ -1380,6 +1446,16 @@ ${googleNoticeRunLocalPanelHtml}
1380
1446
  </div>`
1381
1447
  : "";
1382
1448
  const identitySsoHtml = identitySsoLoginButtonHtml();
1449
+ const localDevHtml = `
1450
+ <div class="local-dev-signin" id="local-dev-signin" hidden>
1451
+ <button type="button" class="btn-local-dev btn-primary" id="local-dev-btn" title="${esc(t("localDevDescription"))}"${i18nAttr("localDevButton")} data-i18n-title="localDevDescription" aria-describedby="local-dev-description">${esc(t("localDevButton"))}</button>
1452
+ <p class="local-dev-description" id="local-dev-description">
1453
+ <span${i18nAttr("localDevDescription")}>${esc(t("localDevDescription"))}</span>
1454
+ <a class="local-dev-help" id="local-dev-help" href="https://www.agent-native.com/docs/authentication#local-development-sign-in" target="_blank" rel="noreferrer" aria-label="${esc(t("localDevHelp"))}" title="${esc(t("localDevHelp"))}" data-i18n-title="localDevHelp"${i18nAriaAttr("localDevHelp")}><span class="local-dev-help-glyph" aria-hidden="true">?</span></a>
1455
+ </p>
1456
+ <button type="button" class="local-dev-full-options" id="local-dev-full-options" hidden${i18nAttr("localDevFullOptions")}>${esc(t("localDevFullOptions"))}</button>
1457
+ <p class="msg error" id="local-dev-msg" role="status" aria-live="polite"></p>
1458
+ </div>`;
1383
1459
  const identitySsoMagicLinkSelector = identitySsoHtml
1384
1460
  ? " .card.magic-link-complete #identity-sso-btn,\n"
1385
1461
  : "";
@@ -1993,6 +2069,70 @@ ${hasMarketing
1993
2069
  cursor: pointer;
1994
2070
  }
1995
2071
  .btn-secondary:hover { color: #bbb; border-color: rgba(255,255,255,0.2); }
2072
+ .local-dev-signin {
2073
+ margin: 1.25rem 0 0.25rem;
2074
+ padding-top: 1rem;
2075
+ border-top: 1px solid color-mix(in srgb, currentColor 12%, transparent);
2076
+ }
2077
+ .btn-local-dev {
2078
+ margin-top: 0.25rem;
2079
+ }
2080
+ .btn-local-dev:disabled { opacity: 0.5; cursor: wait; }
2081
+ .local-dev-description {
2082
+ display: flex;
2083
+ align-items: center;
2084
+ justify-content: center;
2085
+ gap: 0.35rem;
2086
+ margin: 0.5rem 0 0;
2087
+ color: color-mix(in srgb, currentColor 50%, transparent);
2088
+ font-size: 0.6875rem;
2089
+ line-height: 1.45;
2090
+ text-align: center;
2091
+ }
2092
+ .local-dev-help {
2093
+ display: inline-flex;
2094
+ align-items: center;
2095
+ justify-content: center;
2096
+ flex: 0 0 auto;
2097
+ width: 1.5rem;
2098
+ height: 1.5rem;
2099
+ margin: -0.375rem;
2100
+ color: inherit;
2101
+ text-decoration: none;
2102
+ }
2103
+ .local-dev-help-glyph {
2104
+ display: inline-flex;
2105
+ align-items: center;
2106
+ justify-content: center;
2107
+ width: 0.625rem;
2108
+ height: 0.625rem;
2109
+ border: 1px solid currentColor;
2110
+ border-radius: 50%;
2111
+ font-size: 0.4375rem;
2112
+ font-weight: 600;
2113
+ line-height: 1;
2114
+ }
2115
+ .local-dev-help:hover { color: currentColor; }
2116
+ .local-dev-help:focus-visible {
2117
+ outline: 2px solid currentColor;
2118
+ outline-offset: 2px;
2119
+ }
2120
+ .local-dev-full-options {
2121
+ display: block;
2122
+ margin: 0.75rem auto 0;
2123
+ padding: 0;
2124
+ background: transparent;
2125
+ border: 0;
2126
+ color: color-mix(in srgb, currentColor 62%, transparent);
2127
+ font-size: 0.75rem;
2128
+ cursor: pointer;
2129
+ text-decoration: underline;
2130
+ text-underline-offset: 2px;
2131
+ }
2132
+ .local-dev-full-options:hover { color: currentColor; }
2133
+ .local-dev-full-options[hidden] { display: none; }
2134
+ .full-auth-options { margin-top: 1rem; }
2135
+ .full-auth-options[hidden] { display: none; }
1996
2136
  .legal-note {
1997
2137
  margin-top: 0.375rem;
1998
2138
  margin-bottom: 0.875rem;
@@ -2393,6 +2533,8 @@ ${marketingPanelHtml}
2393
2533
  ${i18nDataAttr("data-upgrade-copy", "upgradeCopy").trim()}
2394
2534
  ></p>
2395
2535
  ${identitySsoHtml}
2536
+ ${localDevHtml}
2537
+ <div id="full-auth-options" class="full-auth-options">
2396
2538
  ${renderGoogleButton
2397
2539
  ? `
2398
2540
  <div class="google-signin" id="google-signin">
@@ -2469,6 +2611,7 @@ ${signupLocalModeNoteHtml}
2469
2611
  </p>
2470
2612
  </form>`}
2471
2613
  </div>
2614
+ </div>
2472
2615
  <p class="local-note" id="local-note">
2473
2616
  <span${i18nAttr("localNotePrefix")}>${esc(t("localNotePrefix"))}</span> (<strong>${getConnectionLabel()}</strong>)<span${i18nAttr("localNoteSuffix")}>${esc(t("localNoteSuffix"))}</span>
2474
2617
  </p>${marketingCloseHtml}
@@ -2810,6 +2953,66 @@ ${signInJourneyInlineScript()}
2810
2953
  return false;
2811
2954
  });
2812
2955
  }
2956
+ function __anIsLoopbackHostname() {
2957
+ var hostname = (window.location.hostname || '').toLowerCase();
2958
+ return hostname === 'localhost' || hostname === '::1' || hostname === '127.0.0.1' || hostname.indexOf('127.') === 0;
2959
+ }
2960
+ function __anShouldStartWithLocalDev() {
2961
+ if (!__anIsLoopbackHostname()) return false;
2962
+ var params = new URLSearchParams(window.location.search);
2963
+ var explicitTab = params.get('tab');
2964
+ var verifiedRedirect = typeof __anIsVerifiedRedirectSuccess === 'function' && __anIsVerifiedRedirectSuccess();
2965
+ return explicitTab !== 'login' && explicitTab !== 'signup' && !verifiedRedirect;
2966
+ }
2967
+ function __anSetFullAuthOptionsVisible(visible) {
2968
+ var options = document.getElementById('full-auth-options');
2969
+ var toggle = document.getElementById('local-dev-full-options');
2970
+ if (!options) return;
2971
+ if (visible) {
2972
+ options.removeAttribute('hidden');
2973
+ if (toggle) toggle.setAttribute('hidden', '');
2974
+ } else {
2975
+ options.setAttribute('hidden', '');
2976
+ if (toggle) toggle.removeAttribute('hidden');
2977
+ }
2978
+ }
2979
+ (function __anPrepareLocalDevButton() {
2980
+ var container = document.getElementById('local-dev-signin');
2981
+ var button = document.getElementById('local-dev-btn');
2982
+ var fullOptionsButton = document.getElementById('local-dev-full-options');
2983
+ var message = document.getElementById('local-dev-msg');
2984
+ if (!container || !button || !__anIsLoopbackHostname()) return;
2985
+ container.hidden = false;
2986
+ var startWithLocalDev = __anShouldStartWithLocalDev();
2987
+ __anSetFullAuthOptionsVisible(!startWithLocalDev);
2988
+ if (startWithLocalDev) button.focus();
2989
+ if (fullOptionsButton) fullOptionsButton.addEventListener('click', function() {
2990
+ __anSetFullAuthOptionsVisible(true);
2991
+ var firstInput = document.querySelector('#full-auth-options input, #full-auth-options button, #full-auth-options a');
2992
+ if (firstInput) firstInput.focus();
2993
+ });
2994
+ button.addEventListener('click', function() {
2995
+ button.disabled = true;
2996
+ button.textContent = __anT('localDevSigningIn');
2997
+ fetch(__anPath('/_agent-native/auth/local-dev'), {
2998
+ method: 'POST',
2999
+ credentials: 'include',
3000
+ headers: { 'Accept': 'application/json' },
3001
+ }).then(function(response) {
3002
+ if (!response.ok) throw new Error('local-dev-auth-failed');
3003
+ }).then(function() {
3004
+ __anRedirectToSignedInApp(__anResumeHref());
3005
+ }).catch(function() {
3006
+ button.disabled = false;
3007
+ button.textContent = __anT('localDevButton');
3008
+ __anSetFullAuthOptionsVisible(true);
3009
+ if (message) {
3010
+ message.textContent = __anT('localDevFailed');
3011
+ message.classList.add('show');
3012
+ }
3013
+ });
3014
+ });
3015
+ })();
2813
3016
  ${identitySsoScript}
2814
3017
  (function __anRedirectIfAlreadySignedIn() {
2815
3018
  __anMaybeRedirectSignedIn();
@@ -3498,7 +3701,7 @@ ${googleOnly
3498
3701
  }
3499
3702
  }
3500
3703
  (function initActiveTab() {
3501
- var initial = 'signup';
3704
+ var initial = __AN_AUTH_MODE === 'magic-link' ? 'magicLink' : 'signup';
3502
3705
  try {
3503
3706
  var params = new URLSearchParams(location.search);
3504
3707
  var qp = params.get('tab');
@@ -3517,7 +3720,8 @@ ${googleOnly
3517
3720
  if (stored === 'login' || stored === 'signup') initial = stored;
3518
3721
  }
3519
3722
  } catch (e) {}
3520
- setActiveTab(initial, { persist: false });
3723
+ if (initial === 'magicLink') showMagicLinkForm();
3724
+ else setActiveTab(initial, { persist: false });
3521
3725
  try {
3522
3726
  if (__anIsVerifiedRedirectSuccess()) {
3523
3727
  var rememberedEmail = readRememberedPendingSignupEmail();
@@ -147,6 +147,7 @@ export declare class AppSyncState {
147
147
  private readonly pollEmitter;
148
148
  private syncEventsInitPromise;
149
149
  private lastDurablePrune;
150
+ private durablePruneFailures;
150
151
  /**
151
152
  * Whether we've seeded `version` from the DB. In serverless (Netlify,
152
153
  * Vercel, etc.) each invocation starts fresh — without seeding, `version`
@@ -212,6 +213,31 @@ export declare class AppSyncState {
212
213
  */
213
214
  wireLocalEmitters(): void;
214
215
  ensureSyncEventsTable(): Promise<boolean>;
216
+ /**
217
+ * Drop events past the retention window, in bounded batches.
218
+ *
219
+ * Three things here are load-bearing, all of them learned from a 47 GB
220
+ * `sync_events` table on a live app:
221
+ *
222
+ * - Prune by `created_at`, the actual retention timestamp, with the
223
+ * additive `(created_at, id)` index created above. A version can move
224
+ * ahead of the clock under bursty writes, so it is not a retention
225
+ * timestamp and cannot define a 24-hour boundary safely.
226
+ * - Batch it. One statement deleting an unbounded slice is a long
227
+ * transaction, and a long transaction killed mid-flight by a serverless
228
+ * worker shutdown is what leaves connections `idle in transaction`
229
+ * holding locks — the shape of the 2026-08-06 outage.
230
+ * - `ORDER BY version` inside the subquery. Without it the planner
231
+ * prefers a sequential scan even with a LIMIT; with it, the existing
232
+ * `sync_events_version_idx` drives the batch and the delete is a
233
+ * bounded index range scan.
234
+ *
235
+ * The `lastDurablePrune` throttle below is per-process, so every serverless
236
+ * worker prunes on its first poll. That was survivable only once the work
237
+ * itself became bounded and indexed; if concurrency is still a problem,
238
+ * the next step is a `pg_try_advisory_xact_lock` so one worker prunes at a
239
+ * time. Deliberately not done yet — measure before adding a lock.
240
+ */
215
241
  private pruneDurableEvents;
216
242
  persistSyncEvent(event: ChangeEvent, dedupeKey?: string, presetId?: string): Promise<void>;
217
243
  /**