@agent-native/core 0.134.1 → 0.135.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +113 -0
  3. package/corpus/core/package.json +3 -2
  4. package/corpus/core/src/automations/service.ts +41 -4
  5. package/corpus/core/src/cli/mcp-config-writers.ts +27 -21
  6. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +187 -85
  7. package/corpus/core/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
  8. package/corpus/core/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
  9. package/corpus/core/src/client/agent-page/TimezoneSelect.tsx +241 -0
  10. package/corpus/core/src/client/agent-page/use-jobs.ts +50 -10
  11. package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -0
  12. package/corpus/core/src/client/settings/AccountSettingsCard.tsx +35 -31
  13. package/corpus/core/src/client/settings/SchedulingTimezoneField.tsx +71 -0
  14. package/corpus/core/src/client/settings/SettingsRow.tsx +113 -0
  15. package/corpus/core/src/client/settings/agent-settings-search.ts +2 -1
  16. package/corpus/core/src/client/settings/index.ts +6 -0
  17. package/corpus/core/src/integrations/identity.ts +2 -12
  18. package/corpus/core/src/jobs/actions/list-automation-runs.ts +33 -0
  19. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +27 -6
  20. package/corpus/core/src/jobs/actions/manage-recurring-job.ts +41 -9
  21. package/corpus/core/src/jobs/background-automation-runner.ts +88 -0
  22. package/corpus/core/src/jobs/cron.ts +52 -6
  23. package/corpus/core/src/jobs/frontmatter.ts +20 -0
  24. package/corpus/core/src/jobs/run-history.ts +242 -0
  25. package/corpus/core/src/jobs/scheduler.ts +73 -18
  26. package/corpus/core/src/jobs/tools.ts +54 -6
  27. package/corpus/core/src/localization/actions/get-localization-preference.ts +2 -2
  28. package/corpus/core/src/localization/actions/set-localization-preference.ts +49 -11
  29. package/corpus/core/src/localization/default-messages.ts +27 -0
  30. package/corpus/core/src/localization/shared.ts +39 -6
  31. package/corpus/core/src/localization/user-timezone.ts +36 -0
  32. package/corpus/core/src/org/app-roles-handlers.ts +1 -9
  33. package/corpus/core/src/org/index.ts +2 -0
  34. package/corpus/core/src/org/membership.ts +18 -0
  35. package/corpus/core/src/review/actions/create-review-comment.ts +4 -1
  36. package/corpus/core/src/review/actions/reply-review-comment.ts +4 -1
  37. package/corpus/core/src/review/index.ts +5 -0
  38. package/corpus/core/src/review/notifications.ts +163 -0
  39. package/corpus/core/src/review/types.ts +7 -0
  40. package/corpus/core/src/server/action-discovery.ts +4 -0
  41. package/corpus/core/src/server/activity-notifications.ts +174 -0
  42. package/corpus/core/src/server/app-name.ts +31 -0
  43. package/corpus/core/src/server/better-auth-instance.ts +4 -4
  44. package/corpus/core/src/server/email-templates.ts +70 -14
  45. package/corpus/core/src/server/email.ts +66 -3
  46. package/corpus/core/src/server/index.ts +10 -0
  47. package/corpus/core/src/sharing/access.ts +44 -2
  48. package/corpus/core/src/sharing/index.ts +5 -0
  49. package/corpus/core/src/sharing/recipients.ts +67 -0
  50. package/corpus/core/src/triggers/actions/list-automations.ts +27 -8
  51. package/corpus/core/src/triggers/actions/manage-automation.ts +17 -6
  52. package/corpus/core/src/triggers/actions.ts +16 -4
  53. package/corpus/core/src/triggers/dispatcher.ts +44 -30
  54. package/corpus/core/src/triggers/routes.ts +19 -6
  55. package/corpus/core/src/vitest-config.ts +68 -0
  56. package/corpus/core/vitest.config.ts +5 -0
  57. package/corpus/templates/analytics/app/pages/Settings.tsx +37 -53
  58. package/corpus/templates/analytics/changelog/2026-08-01-new-error-alerts-now-reach-you-by-email-and-a-scheduled-dash.md +6 -0
  59. package/corpus/templates/analytics/server/jobs/dashboard-report.ts +43 -0
  60. package/corpus/templates/analytics/server/lib/error-capture.ts +5 -1
  61. package/corpus/templates/analytics/vitest.config.ts +16 -12
  62. package/corpus/templates/assets/actions/refresh-generation-run.ts +3 -0
  63. package/corpus/templates/assets/app/components/ui/switch.tsx +1 -0
  64. package/corpus/templates/assets/app/hooks/use-assets-prefs.ts +55 -0
  65. package/corpus/templates/assets/app/i18n-data.ts +30 -0
  66. package/corpus/templates/assets/app/routes/settings.tsx +58 -55
  67. package/corpus/templates/assets/changelog/2026-08-01-get-an-email-when-a-generation-you-started-finishes-or-fails.md +6 -0
  68. package/corpus/templates/assets/server/lib/generation-run-notifications.ts +89 -0
  69. package/corpus/templates/assets/server/lib/video-runs.ts +8 -1
  70. package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.get.ts +17 -0
  71. package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.put.ts +36 -0
  72. package/corpus/templates/assets/shared/assets-user-prefs.ts +10 -0
  73. package/corpus/templates/assets/vitest.config.ts +16 -12
  74. package/corpus/templates/brain/app/routes/settings.tsx +15 -15
  75. package/corpus/templates/brain/vitest.config.ts +16 -12
  76. package/corpus/templates/calendar/app/pages/Settings.tsx +32 -40
  77. package/corpus/templates/calendar/changelog/2026-08-01-language-and-appearance-now-sit-together-in-one-preferences-.md +6 -0
  78. package/corpus/templates/calendar/vitest.config.ts +16 -12
  79. package/corpus/templates/chat/app/routes/settings.tsx +14 -22
  80. package/corpus/templates/chat/vitest.config.ts +9 -0
  81. package/corpus/templates/clips/.agents/skills/video-editing/SKILL.md +31 -0
  82. package/corpus/templates/clips/AGENTS.md +1 -0
  83. package/corpus/templates/clips/actions/add-comment.ts +12 -1
  84. package/corpus/templates/clips/actions/create-meeting.ts +2 -2
  85. package/corpus/templates/clips/actions/create-recording.ts +2 -2
  86. package/corpus/templates/clips/actions/finalize-recording.ts +42 -6
  87. package/corpus/templates/clips/actions/generate-filmstrip.ts +154 -0
  88. package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -0
  89. package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
  90. package/corpus/templates/clips/actions/lib/ensure-recording-filmstrip.ts +258 -0
  91. package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +11 -3
  92. package/corpus/templates/clips/actions/react-to-comment.ts +13 -0
  93. package/corpus/templates/clips/actions/react-to-recording.ts +10 -1
  94. package/corpus/templates/clips/actions/reply-to-comment.ts +12 -1
  95. package/corpus/templates/clips/actions/stitch-recordings.ts +2 -2
  96. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +152 -23
  97. package/corpus/templates/clips/app/components/editor/waveform.tsx +237 -75
  98. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +23 -1
  99. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +441 -0
  100. package/corpus/templates/clips/app/components/settings/slack-section.tsx +329 -0
  101. package/corpus/templates/clips/app/components/settings/types.ts +14 -0
  102. package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +443 -0
  103. package/corpus/templates/clips/app/hooks/use-secret-status.ts +69 -0
  104. package/corpus/templates/clips/app/i18n/en-US.ts +9 -1
  105. package/corpus/templates/clips/app/lib/video-filmstrip.ts +262 -0
  106. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +165 -1351
  107. package/corpus/templates/clips/changelog/2026-07-27-saved-clips-now-resume-from-the-last-uploaded-byte-after-an-.md +6 -0
  108. package/corpus/templates/clips/changelog/2026-07-31-editor-timeline-now-shows-video-frames-behind-the-waveform-g.md +6 -0
  109. package/corpus/templates/clips/changelog/2026-07-31-email-notifications-now-go-out-when-someone-comments-on-or-r.md +6 -0
  110. package/corpus/templates/clips/changelog/2026-07-31-you-can-now-set-a-default-visibility-for-new-recordings-in-s.md +6 -0
  111. package/corpus/templates/clips/changelog/2026-08-01-email-notifications-for-comments-and-reactions-now-actually-.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-08-03-the-desktop-app-now-opens-directly-beneath-its-tray-icon-on-.md +6 -0
  113. package/corpus/templates/clips/chrome-extension/package.json +1 -0
  114. package/corpus/templates/clips/chrome-extension/vitest.config.ts +9 -0
  115. package/corpus/templates/clips/desktop/package.json +1 -0
  116. package/corpus/templates/clips/desktop/src/app.tsx +17 -1
  117. package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
  118. package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
  119. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +815 -15
  120. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +61 -11
  121. package/corpus/templates/clips/desktop/vitest.config.ts +9 -0
  122. package/corpus/templates/clips/server/db/schema.ts +17 -0
  123. package/corpus/templates/clips/server/jobs/media-verification.ts +4 -0
  124. package/corpus/templates/clips/server/lib/activity-notifications.ts +185 -0
  125. package/corpus/templates/clips/server/lib/recording-media-cleanup.ts +2 -0
  126. package/corpus/templates/clips/server/lib/recording-upload-state.ts +46 -9
  127. package/corpus/templates/clips/server/lib/recordings.ts +24 -0
  128. package/corpus/templates/clips/server/lib/resumable-session.ts +10 -4
  129. package/corpus/templates/clips/server/lib/transactional-email-templates.ts +109 -0
  130. package/corpus/templates/clips/server/lib/upload-interruption.ts +8 -0
  131. package/corpus/templates/clips/server/lib/upload-lease.ts +50 -4
  132. package/corpus/templates/clips/server/lib/video-filmstrip-sprite.ts +207 -0
  133. package/corpus/templates/clips/server/lib/video-remux.ts +13 -4
  134. package/corpus/templates/clips/server/plugins/db.ts +16 -0
  135. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +4 -0
  136. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +123 -36
  137. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +159 -29
  138. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +197 -0
  139. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +193 -39
  140. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +191 -12
  141. package/corpus/templates/clips/shared/clips-ai-prefs.ts +6 -0
  142. package/corpus/templates/clips/shared/feature-flags.ts +12 -0
  143. package/corpus/templates/clips/shared/recording-core.ts +4 -0
  144. package/corpus/templates/clips/vitest.config.ts +23 -19
  145. package/corpus/templates/content/actions/_database-utils.ts +113 -4
  146. package/corpus/templates/content/actions/add-comment.ts +15 -1
  147. package/corpus/templates/content/actions/get-document.ts +84 -3
  148. package/corpus/templates/content/actions/list-documents.ts +1 -0
  149. package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +9 -2
  150. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +34 -15
  151. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +55 -13
  152. package/corpus/templates/content/app/components/editor/body-hydration.ts +12 -6
  153. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2 -3
  154. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -12
  155. package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
  156. package/corpus/templates/content/app/hooks/use-content-database.ts +16 -27
  157. package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
  158. package/corpus/templates/content/app/hooks/use-create-page.ts +3 -6
  159. package/corpus/templates/content/app/hooks/use-document-properties.ts +9 -16
  160. package/corpus/templates/content/app/hooks/use-document-versions.ts +3 -3
  161. package/corpus/templates/content/app/hooks/use-documents.ts +85 -29
  162. package/corpus/templates/content/app/hooks/use-notion.ts +15 -13
  163. package/corpus/templates/content/app/i18n-data.ts +72 -1
  164. package/corpus/templates/content/app/lib/document-query.ts +36 -0
  165. package/corpus/templates/content/app/routes/_app.settings.tsx +47 -18
  166. package/corpus/templates/content/changelog/2026-07-30-breadcrumb-menus-now-hide-internal-system-pages.md +6 -0
  167. package/corpus/templates/content/changelog/2026-08-01-get-an-email-when-someone-comments-on-replies-in-or-mentions.md +6 -0
  168. package/corpus/templates/content/changelog/2026-08-02-pages-opened-from-a-database-now-keep-that-database-s-fields.md +6 -0
  169. package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
  170. package/corpus/templates/content/server/lib/document-context.ts +11 -6
  171. package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.get.ts +17 -0
  172. package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.put.ts +36 -0
  173. package/corpus/templates/content/shared/api.ts +8 -0
  174. package/corpus/templates/content/shared/content-user-prefs.ts +11 -0
  175. package/corpus/templates/content/vitest.config.ts +20 -16
  176. package/corpus/templates/crm/app/routes/settings.tsx +14 -22
  177. package/corpus/templates/crm/vitest.config.ts +8 -4
  178. package/corpus/templates/design/app/routes/settings.tsx +14 -22
  179. package/corpus/templates/design/changelog/2026-08-01-review-comments-replies-and-mentions-now-send-an-email-to-th.md +6 -0
  180. package/corpus/templates/design/vitest.config.ts +18 -12
  181. package/corpus/templates/dispatch/app/routes/settings.tsx +26 -40
  182. package/corpus/templates/dispatch/vitest.config.ts +11 -7
  183. package/corpus/templates/factory/app/routes/settings.tsx +14 -22
  184. package/corpus/templates/factory/vitest.config.ts +9 -0
  185. package/corpus/templates/forms/app/routes/_app.settings.tsx +14 -22
  186. package/corpus/templates/forms/vitest.config.ts +27 -23
  187. package/corpus/templates/macros/app/routes/settings.tsx +14 -22
  188. package/corpus/templates/macros/vitest.config.ts +16 -12
  189. package/corpus/templates/mail/app/pages/SettingsPage.tsx +14 -16
  190. package/corpus/templates/mail/vitest.config.ts +16 -12
  191. package/corpus/templates/plan/app/routes/settings.tsx +30 -44
  192. package/corpus/templates/plan/vitest.config.ts +24 -20
  193. package/corpus/templates/slides/actions/add-slide-comment.ts +12 -1
  194. package/corpus/templates/slides/app/components/ui/switch.tsx +1 -0
  195. package/corpus/templates/slides/app/hooks/use-slides-prefs.ts +55 -0
  196. package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
  197. package/corpus/templates/slides/app/routes/settings.tsx +45 -22
  198. package/corpus/templates/slides/changelog/2026-08-01-get-an-email-when-someone-comments-on-or-replies-in-your-dec.md +6 -0
  199. package/corpus/templates/slides/server/lib/comment-notifications.ts +182 -0
  200. package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.get.ts +16 -0
  201. package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.put.ts +36 -0
  202. package/corpus/templates/slides/shared/slides-user-prefs.ts +11 -0
  203. package/corpus/templates/slides/vitest.config.ts +17 -13
  204. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +2 -0
  205. package/corpus/templates/tasks/app/routes/settings.tsx +14 -22
  206. package/corpus/templates/tasks/vitest.config.ts +17 -13
  207. package/corpus/toolkit/CHANGELOG.md +9 -0
  208. package/corpus/toolkit/package.json +1 -1
  209. package/corpus/toolkit/vitest.config.ts +3 -0
  210. package/dist/automations/service.d.ts +2 -0
  211. package/dist/automations/service.d.ts.map +1 -1
  212. package/dist/automations/service.js +29 -4
  213. package/dist/automations/service.js.map +1 -1
  214. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  215. package/dist/cli/mcp-config-writers.js +24 -23
  216. package/dist/cli/mcp-config-writers.js.map +1 -1
  217. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  218. package/dist/client/agent-page/AgentJobsTab.js +86 -29
  219. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  220. package/dist/client/agent-page/AutomationDetailsDialog.d.ts +21 -0
  221. package/dist/client/agent-page/AutomationDetailsDialog.d.ts.map +1 -0
  222. package/dist/client/agent-page/AutomationDetailsDialog.js +33 -0
  223. package/dist/client/agent-page/AutomationDetailsDialog.js.map +1 -0
  224. package/dist/client/agent-page/AutomationScheduleDialog.d.ts +15 -0
  225. package/dist/client/agent-page/AutomationScheduleDialog.d.ts.map +1 -0
  226. package/dist/client/agent-page/AutomationScheduleDialog.js +46 -0
  227. package/dist/client/agent-page/AutomationScheduleDialog.js.map +1 -0
  228. package/dist/client/agent-page/TimezoneSelect.d.ts +17 -0
  229. package/dist/client/agent-page/TimezoneSelect.d.ts.map +1 -0
  230. package/dist/client/agent-page/TimezoneSelect.js +107 -0
  231. package/dist/client/agent-page/TimezoneSelect.js.map +1 -0
  232. package/dist/client/agent-page/use-jobs.d.ts +20 -7
  233. package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
  234. package/dist/client/agent-page/use-jobs.js +24 -4
  235. package/dist/client/agent-page/use-jobs.js.map +1 -1
  236. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  237. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  238. package/dist/client/org/OrgSwitcher.js +8 -2
  239. package/dist/client/org/OrgSwitcher.js.map +1 -1
  240. package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -1
  241. package/dist/client/settings/AccountSettingsCard.js +10 -9
  242. package/dist/client/settings/AccountSettingsCard.js.map +1 -1
  243. package/dist/client/settings/SchedulingTimezoneField.d.ts +10 -0
  244. package/dist/client/settings/SchedulingTimezoneField.d.ts.map +1 -0
  245. package/dist/client/settings/SchedulingTimezoneField.js +30 -0
  246. package/dist/client/settings/SchedulingTimezoneField.js.map +1 -0
  247. package/dist/client/settings/SettingsRow.d.ts +36 -0
  248. package/dist/client/settings/SettingsRow.d.ts.map +1 -0
  249. package/dist/client/settings/SettingsRow.js +15 -0
  250. package/dist/client/settings/SettingsRow.js.map +1 -0
  251. package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
  252. package/dist/client/settings/agent-settings-search.js +1 -1
  253. package/dist/client/settings/agent-settings-search.js.map +1 -1
  254. package/dist/client/settings/index.d.ts +1 -0
  255. package/dist/client/settings/index.d.ts.map +1 -1
  256. package/dist/client/settings/index.js +1 -0
  257. package/dist/client/settings/index.js.map +1 -1
  258. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  259. package/dist/integrations/identity.d.ts.map +1 -1
  260. package/dist/integrations/identity.js +2 -11
  261. package/dist/integrations/identity.js.map +1 -1
  262. package/dist/jobs/actions/list-automation-runs.d.ts +8 -0
  263. package/dist/jobs/actions/list-automation-runs.d.ts.map +1 -0
  264. package/dist/jobs/actions/list-automation-runs.js +29 -0
  265. package/dist/jobs/actions/list-automation-runs.js.map +1 -0
  266. package/dist/jobs/actions/list-recurring-jobs.d.ts +2 -0
  267. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
  268. package/dist/jobs/actions/list-recurring-jobs.js +20 -7
  269. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
  270. package/dist/jobs/actions/manage-recurring-job.d.ts +2 -0
  271. package/dist/jobs/actions/manage-recurring-job.js +30 -9
  272. package/dist/jobs/actions/manage-recurring-job.js.map +1 -1
  273. package/dist/jobs/background-automation-runner.d.ts.map +1 -1
  274. package/dist/jobs/background-automation-runner.js +60 -0
  275. package/dist/jobs/background-automation-runner.js.map +1 -1
  276. package/dist/jobs/cron.d.ts +16 -2
  277. package/dist/jobs/cron.d.ts.map +1 -1
  278. package/dist/jobs/cron.js +43 -6
  279. package/dist/jobs/cron.js.map +1 -1
  280. package/dist/jobs/frontmatter.d.ts +12 -0
  281. package/dist/jobs/frontmatter.d.ts.map +1 -1
  282. package/dist/jobs/frontmatter.js +8 -0
  283. package/dist/jobs/frontmatter.js.map +1 -1
  284. package/dist/jobs/run-history.d.ts +56 -0
  285. package/dist/jobs/run-history.d.ts.map +1 -0
  286. package/dist/jobs/run-history.js +169 -0
  287. package/dist/jobs/run-history.js.map +1 -0
  288. package/dist/jobs/scheduler.d.ts.map +1 -1
  289. package/dist/jobs/scheduler.js +51 -18
  290. package/dist/jobs/scheduler.js.map +1 -1
  291. package/dist/jobs/tools.d.ts.map +1 -1
  292. package/dist/jobs/tools.js +37 -6
  293. package/dist/jobs/tools.js.map +1 -1
  294. package/dist/localization/actions/get-localization-preference.d.ts +1 -2
  295. package/dist/localization/actions/get-localization-preference.d.ts.map +1 -1
  296. package/dist/localization/actions/get-localization-preference.js.map +1 -1
  297. package/dist/localization/actions/set-localization-preference.d.ts +3 -3
  298. package/dist/localization/actions/set-localization-preference.d.ts.map +1 -1
  299. package/dist/localization/actions/set-localization-preference.js +33 -8
  300. package/dist/localization/actions/set-localization-preference.js.map +1 -1
  301. package/dist/localization/default-messages.d.ts +25 -0
  302. package/dist/localization/default-messages.d.ts.map +1 -1
  303. package/dist/localization/default-messages.js +25 -0
  304. package/dist/localization/default-messages.js.map +1 -1
  305. package/dist/localization/shared.d.ts +16 -1
  306. package/dist/localization/shared.d.ts.map +1 -1
  307. package/dist/localization/shared.js +22 -4
  308. package/dist/localization/shared.js.map +1 -1
  309. package/dist/localization/user-timezone.d.ts +11 -0
  310. package/dist/localization/user-timezone.d.ts.map +1 -0
  311. package/dist/localization/user-timezone.js +31 -0
  312. package/dist/localization/user-timezone.js.map +1 -0
  313. package/dist/notifications/routes.d.ts +4 -4
  314. package/dist/observability/routes.d.ts +3 -3
  315. package/dist/org/app-roles-handlers.d.ts.map +1 -1
  316. package/dist/org/app-roles-handlers.js +1 -8
  317. package/dist/org/app-roles-handlers.js.map +1 -1
  318. package/dist/org/index.d.ts +1 -0
  319. package/dist/org/index.d.ts.map +1 -1
  320. package/dist/org/index.js +1 -0
  321. package/dist/org/index.js.map +1 -1
  322. package/dist/org/membership.d.ts +6 -0
  323. package/dist/org/membership.d.ts.map +1 -0
  324. package/dist/org/membership.js +16 -0
  325. package/dist/org/membership.js.map +1 -0
  326. package/dist/progress/routes.d.ts +1 -1
  327. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  328. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  329. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  330. package/dist/review/actions/create-review-comment.d.ts +32 -1
  331. package/dist/review/actions/create-review-comment.d.ts.map +1 -1
  332. package/dist/review/actions/create-review-comment.js +3 -1
  333. package/dist/review/actions/create-review-comment.js.map +1 -1
  334. package/dist/review/actions/reply-review-comment.d.ts +32 -1
  335. package/dist/review/actions/reply-review-comment.d.ts.map +1 -1
  336. package/dist/review/actions/reply-review-comment.js +3 -1
  337. package/dist/review/actions/reply-review-comment.js.map +1 -1
  338. package/dist/review/index.d.ts +1 -0
  339. package/dist/review/index.d.ts.map +1 -1
  340. package/dist/review/index.js +1 -0
  341. package/dist/review/index.js.map +1 -1
  342. package/dist/review/notifications.d.ts +24 -0
  343. package/dist/review/notifications.d.ts.map +1 -0
  344. package/dist/review/notifications.js +123 -0
  345. package/dist/review/notifications.js.map +1 -0
  346. package/dist/review/types.d.ts +5 -0
  347. package/dist/review/types.d.ts.map +1 -1
  348. package/dist/review/types.js.map +1 -1
  349. package/dist/server/action-discovery.d.ts.map +1 -1
  350. package/dist/server/action-discovery.js +4 -0
  351. package/dist/server/action-discovery.js.map +1 -1
  352. package/dist/server/activity-notifications.d.ts +61 -0
  353. package/dist/server/activity-notifications.d.ts.map +1 -0
  354. package/dist/server/activity-notifications.js +103 -0
  355. package/dist/server/activity-notifications.js.map +1 -0
  356. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  357. package/dist/server/app-name.d.ts +18 -0
  358. package/dist/server/app-name.d.ts.map +1 -1
  359. package/dist/server/app-name.js +31 -0
  360. package/dist/server/app-name.js.map +1 -1
  361. package/dist/server/better-auth-instance.js +4 -4
  362. package/dist/server/better-auth-instance.js.map +1 -1
  363. package/dist/server/email-templates.d.ts +12 -0
  364. package/dist/server/email-templates.d.ts.map +1 -1
  365. package/dist/server/email-templates.js +57 -14
  366. package/dist/server/email-templates.js.map +1 -1
  367. package/dist/server/email.d.ts +12 -0
  368. package/dist/server/email.d.ts.map +1 -1
  369. package/dist/server/email.js +52 -5
  370. package/dist/server/email.js.map +1 -1
  371. package/dist/server/index.d.ts +1 -0
  372. package/dist/server/index.d.ts.map +1 -1
  373. package/dist/server/index.js +1 -0
  374. package/dist/server/index.js.map +1 -1
  375. package/dist/server/transcribe-voice.d.ts +1 -1
  376. package/dist/sharing/access.d.ts.map +1 -1
  377. package/dist/sharing/access.js +32 -2
  378. package/dist/sharing/access.js.map +1 -1
  379. package/dist/sharing/index.d.ts +1 -0
  380. package/dist/sharing/index.d.ts.map +1 -1
  381. package/dist/sharing/index.js +1 -0
  382. package/dist/sharing/index.js.map +1 -1
  383. package/dist/sharing/recipients.d.ts +31 -0
  384. package/dist/sharing/recipients.d.ts.map +1 -0
  385. package/dist/sharing/recipients.js +40 -0
  386. package/dist/sharing/recipients.js.map +1 -0
  387. package/dist/templates/chat/app/routes/settings.tsx +14 -22
  388. package/dist/templates/chat/vitest.config.ts +9 -0
  389. package/dist/triggers/actions/list-automations.d.ts +2 -0
  390. package/dist/triggers/actions/list-automations.d.ts.map +1 -1
  391. package/dist/triggers/actions/list-automations.js +19 -8
  392. package/dist/triggers/actions/list-automations.js.map +1 -1
  393. package/dist/triggers/actions/manage-automation.d.ts +6 -0
  394. package/dist/triggers/actions/manage-automation.js +12 -6
  395. package/dist/triggers/actions/manage-automation.js.map +1 -1
  396. package/dist/triggers/actions.d.ts.map +1 -1
  397. package/dist/triggers/actions.js +15 -4
  398. package/dist/triggers/actions.js.map +1 -1
  399. package/dist/triggers/dispatcher.d.ts.map +1 -1
  400. package/dist/triggers/dispatcher.js +19 -17
  401. package/dist/triggers/dispatcher.js.map +1 -1
  402. package/dist/triggers/routes.d.ts.map +1 -1
  403. package/dist/triggers/routes.js +6 -6
  404. package/dist/triggers/routes.js.map +1 -1
  405. package/dist/vitest-config.d.ts +10 -0
  406. package/dist/vitest-config.d.ts.map +1 -0
  407. package/dist/vitest-config.js +55 -0
  408. package/dist/vitest-config.js.map +1 -0
  409. package/package.json +5 -4
  410. package/src/automations/service.ts +41 -4
  411. package/src/cli/mcp-config-writers.ts +27 -21
  412. package/src/client/agent-page/AgentJobsTab.tsx +187 -85
  413. package/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
  414. package/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
  415. package/src/client/agent-page/TimezoneSelect.tsx +241 -0
  416. package/src/client/agent-page/use-jobs.ts +50 -10
  417. package/src/client/org/OrgSwitcher.tsx +26 -0
  418. package/src/client/settings/AccountSettingsCard.tsx +35 -31
  419. package/src/client/settings/SchedulingTimezoneField.tsx +71 -0
  420. package/src/client/settings/SettingsRow.tsx +113 -0
  421. package/src/client/settings/agent-settings-search.ts +2 -1
  422. package/src/client/settings/index.ts +6 -0
  423. package/src/integrations/identity.ts +2 -12
  424. package/src/jobs/actions/list-automation-runs.ts +33 -0
  425. package/src/jobs/actions/list-recurring-jobs.ts +27 -6
  426. package/src/jobs/actions/manage-recurring-job.ts +41 -9
  427. package/src/jobs/background-automation-runner.ts +88 -0
  428. package/src/jobs/cron.ts +52 -6
  429. package/src/jobs/frontmatter.ts +20 -0
  430. package/src/jobs/run-history.ts +242 -0
  431. package/src/jobs/scheduler.ts +73 -18
  432. package/src/jobs/tools.ts +54 -6
  433. package/src/localization/actions/get-localization-preference.ts +2 -2
  434. package/src/localization/actions/set-localization-preference.ts +49 -11
  435. package/src/localization/default-messages.ts +27 -0
  436. package/src/localization/shared.ts +39 -6
  437. package/src/localization/user-timezone.ts +36 -0
  438. package/src/org/app-roles-handlers.ts +1 -9
  439. package/src/org/index.ts +2 -0
  440. package/src/org/membership.ts +18 -0
  441. package/src/review/actions/create-review-comment.ts +4 -1
  442. package/src/review/actions/reply-review-comment.ts +4 -1
  443. package/src/review/index.ts +5 -0
  444. package/src/review/notifications.ts +163 -0
  445. package/src/review/types.ts +7 -0
  446. package/src/server/action-discovery.ts +4 -0
  447. package/src/server/activity-notifications.ts +174 -0
  448. package/src/server/app-name.ts +31 -0
  449. package/src/server/better-auth-instance.ts +4 -4
  450. package/src/server/email-templates.ts +70 -14
  451. package/src/server/email.ts +66 -3
  452. package/src/server/index.ts +10 -0
  453. package/src/sharing/access.ts +44 -2
  454. package/src/sharing/index.ts +5 -0
  455. package/src/sharing/recipients.ts +67 -0
  456. package/src/templates/chat/app/routes/settings.tsx +14 -22
  457. package/src/templates/chat/vitest.config.ts +9 -0
  458. package/src/triggers/actions/list-automations.ts +27 -8
  459. package/src/triggers/actions/manage-automation.ts +17 -6
  460. package/src/triggers/actions.ts +16 -4
  461. package/src/triggers/dispatcher.ts +44 -30
  462. package/src/triggers/routes.ts +19 -6
  463. package/src/vitest-config.ts +68 -0
@@ -3055,6 +3055,10 @@ const enUS = {
3055
3055
  metaTitle: "Settings - Content",
3056
3056
  title: "Settings",
3057
3057
  description: "Language and workspace preferences for Content.",
3058
+ emailNotifications: "Email notifications",
3059
+ emailNotificationsDescription:
3060
+ "Get an email when someone comments on, replies in, or mentions you on your document.",
3061
+ saveFailed: "Failed to save",
3058
3062
  languageTitle: "Language",
3059
3063
  languageDescription:
3060
3064
  "Choose the interface language. This preference is saved for your account.",
@@ -3116,9 +3120,12 @@ const enUS = {
3116
3120
  liveDocumentSaveBeforeSyncFailed:
3117
3121
  "The live document could not be saved before syncing.",
3118
3122
  documentTitle: "Document title",
3119
- builderBodySyncing: "Content is still syncing from Builder",
3123
+ builderBodySyncing: "This page's content is still syncing from Builder",
3120
3124
  builderBodySyncingDescription:
3121
3125
  "Editing is paused until the Builder body finishes syncing, so the existing article content is not overwritten.",
3126
+ pageBodySyncing: "This page's content is still syncing",
3127
+ pageBodySyncingDescription:
3128
+ "Editing is paused until the page body finishes syncing, so existing content is not overwritten.",
3122
3129
  localFileSavedHistoryNotUpdated:
3123
3130
  "Local file saved, but history was not updated",
3124
3131
  reorderField: "Reorder {{name}}",
@@ -5611,6 +5618,9 @@ const editorMessagesByLocale = {
5611
5618
  builderBodySyncing: "内容仍在从 Builder 同步",
5612
5619
  builderBodySyncingDescription:
5613
5620
  "同步 Builder 正文完成前会暂停编辑,避免覆盖现有文章内容。",
5621
+ pageBodySyncing: "此页面的内容仍在同步",
5622
+ pageBodySyncingDescription:
5623
+ "在页面正文完成同步之前,编辑会暂停,以免覆盖现有内容。",
5614
5624
  creatingDatabase: "正在创建内联数据库...",
5615
5625
  databaseCreated: "内联数据库已创建",
5616
5626
  emptyBlockPlaceholder: "按“/”使用命令",
@@ -5956,6 +5966,9 @@ const editorMessagesByLocale = {
5956
5966
  builderBodySyncing: "El contenido aún se está sincronizando desde Builder",
5957
5967
  builderBodySyncingDescription:
5958
5968
  "La edición está en pausa hasta que el cuerpo de Builder termine de sincronizarse, para no sobrescribir el contenido existente del artículo.",
5969
+ pageBodySyncing: "El contenido de esta página aún se está sincronizando",
5970
+ pageBodySyncingDescription:
5971
+ "La edición está en pausa hasta que el contenido de la página termine de sincronizarse, para no sobrescribir el contenido existente.",
5959
5972
  creatingDatabase: "Creando base de datos integrada...",
5960
5973
  databaseCreated: "Base de datos integrada creada",
5961
5974
  emptyBlockPlaceholder: "Pulsa «/» para ver los comandos",
@@ -6313,6 +6326,10 @@ const editorMessagesByLocale = {
6313
6326
  "Le contenu est encore en cours de synchronisation depuis Builder",
6314
6327
  builderBodySyncingDescription:
6315
6328
  "La modification est suspendue jusqu'à la fin de la synchronisation du corps Builder, afin de ne pas écraser le contenu existant de l'article.",
6329
+ pageBodySyncing:
6330
+ "Le contenu de cette page est encore en cours de synchronisation",
6331
+ pageBodySyncingDescription:
6332
+ "La modification est suspendue jusqu'à la fin de la synchronisation du contenu de la page, afin de ne pas écraser le contenu existant.",
6316
6333
  creatingDatabase: "Création d'une base de données intégrée...",
6317
6334
  databaseCreated: "Base de données intégrée créée",
6318
6335
  emptyBlockPlaceholder: "Appuyez sur « / » pour afficher les commandes",
@@ -6672,6 +6689,9 @@ const editorMessagesByLocale = {
6672
6689
  builderBodySyncing: "Inhalte werden noch von Builder synchronisiert",
6673
6690
  builderBodySyncingDescription:
6674
6691
  "Die Bearbeitung ist pausiert, bis der Builder-Textkörper fertig synchronisiert ist, damit der bestehende Artikelinhalt nicht überschrieben wird.",
6692
+ pageBodySyncing: "Der Inhalt dieser Seite wird noch synchronisiert",
6693
+ pageBodySyncingDescription:
6694
+ "Die Bearbeitung ist pausiert, bis der Seiteninhalt fertig synchronisiert ist, damit bestehende Inhalte nicht überschrieben werden.",
6675
6695
  creatingDatabase: "Inline-Datenbank wird erstellt...",
6676
6696
  databaseCreated: "Inline-Datenbank erstellt",
6677
6697
  emptyBlockPlaceholder: "Drücke „/“ für Befehle",
@@ -7036,6 +7056,9 @@ const editorMessagesByLocale = {
7036
7056
  builderBodySyncing: "コンテンツはまだ Builder から同期中です",
7037
7057
  builderBodySyncingDescription:
7038
7058
  "既存の記事内容を上書きしないよう、Builder 本文の同期が完了するまで編集は一時停止されます。",
7059
+ pageBodySyncing: "このページのコンテンツはまだ同期中です",
7060
+ pageBodySyncingDescription:
7061
+ "既存のコンテンツを上書きしないよう、ページ本文の同期が完了するまで編集は一時停止されます。",
7039
7062
  creatingDatabase: "インラインデータベースを作成しています...",
7040
7063
  databaseCreated: "インラインデータベースが作成されました",
7041
7064
  emptyBlockPlaceholder: "「/」でコマンドを表示",
@@ -7389,6 +7412,9 @@ const editorMessagesByLocale = {
7389
7412
  builderBodySyncing: "콘텐츠가 아직 Builder에서 동기화되는 중입니다",
7390
7413
  builderBodySyncingDescription:
7391
7414
  "기존 문서 내용을 덮어쓰지 않도록 Builder 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
7415
+ pageBodySyncing: "이 페이지의 콘텐츠가 아직 동기화 중입니다",
7416
+ pageBodySyncingDescription:
7417
+ "기존 콘텐츠를 덮어쓰지 않도록 페이지 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
7392
7418
  creatingDatabase: "인라인 데이터베이스 생성 중...",
7393
7419
  databaseCreated: "인라인 데이터베이스가 생성되었습니다.",
7394
7420
  emptyBlockPlaceholder: "‘/’를 눌러 명령 사용",
@@ -7741,6 +7767,9 @@ const editorMessagesByLocale = {
7741
7767
  builderBodySyncing: "O conteúdo ainda está sincronizando do Builder",
7742
7768
  builderBodySyncingDescription:
7743
7769
  "A edição fica pausada até o corpo do Builder terminar de sincronizar, para não sobrescrever o conteúdo existente do artigo.",
7770
+ pageBodySyncing: "O conteúdo desta página ainda está sincronizando",
7771
+ pageBodySyncingDescription:
7772
+ "A edição fica pausada até o conteúdo da página terminar de sincronizar, para não sobrescrever o conteúdo existente.",
7744
7773
  creatingDatabase: "Criando banco de dados embutido...",
7745
7774
  databaseCreated: "Banco de dados embutido criado",
7746
7775
  emptyBlockPlaceholder: "Pressione “/” para comandos",
@@ -8099,6 +8128,9 @@ const editorMessagesByLocale = {
8099
8128
  builderBodySyncing: "सामग्री अभी भी Builder से सिंक हो रही है",
8100
8129
  builderBodySyncingDescription:
8101
8130
  "Builder का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा लेख सामग्री अधिलेखित न हो।",
8131
+ pageBodySyncing: "इस पेज की सामग्री अभी भी सिंक हो रही है",
8132
+ pageBodySyncingDescription:
8133
+ "पेज का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा सामग्री अधिलेखित न हो।",
8102
8134
  creatingDatabase: "इनलाइन डेटाबेस बनाया जा रहा है...",
8103
8135
  databaseCreated: "इनलाइन डेटाबेस बनाया गया",
8104
8136
  emptyBlockPlaceholder: "कमांड के लिए '/' दबाएं",
@@ -8446,6 +8478,9 @@ const editorMessagesByLocale = {
8446
8478
  builderBodySyncing: "لا يزال المحتوى قيد المزامنة من Builder",
8447
8479
  builderBodySyncingDescription:
8448
8480
  "يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة نص Builder، حتى لا يتم استبدال محتوى المقالة الحالي.",
8481
+ pageBodySyncing: "لا يزال محتوى هذه الصفحة قيد المزامنة",
8482
+ pageBodySyncingDescription:
8483
+ "يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة محتوى الصفحة، حتى لا تتم الكتابة فوق المحتوى الحالي.",
8449
8484
  creatingDatabase: "جارٍ إنشاء قاعدة بيانات مضمنة...",
8450
8485
  databaseCreated: "تم إنشاء قاعدة البيانات المضمنة",
8451
8486
  emptyBlockPlaceholder: 'اضغط على "/" للأوامر',
@@ -9133,6 +9168,10 @@ export const messagesByLocale = {
9133
9168
  settings: {
9134
9169
  title: "设置",
9135
9170
  description: "Content 的语言和工作区偏好设置。",
9171
+ emailNotifications: "邮件通知",
9172
+ emailNotificationsDescription:
9173
+ "当有人评论你的文档、在讨论串中回复或提到你时,收到邮件通知。",
9174
+ saveFailed: "保存失败",
9136
9175
  languageTitle: "语言",
9137
9176
  languageDescription: "选择界面语言。此偏好会保存到你的账户。",
9138
9177
  languageLabel: "界面语言",
@@ -9325,6 +9364,10 @@ export const messagesByLocale = {
9325
9364
  settings: {
9326
9365
  title: "Ajustes",
9327
9366
  description: "Preferencias de idioma y espacio de trabajo para Content.",
9367
+ emailNotifications: "Notificaciones por correo",
9368
+ emailNotificationsDescription:
9369
+ "Recibe un correo cuando alguien comente, responda o te mencione en tu documento.",
9370
+ saveFailed: "No se pudo guardar",
9328
9371
  languageTitle: "Idioma",
9329
9372
  languageDescription:
9330
9373
  "Elige el idioma de la interfaz. Esta preferencia se guarda en tu cuenta.",
@@ -9524,6 +9567,10 @@ export const messagesByLocale = {
9524
9567
  settings: {
9525
9568
  title: "Paramètres",
9526
9569
  description: "Préférences de langue et d’espace de travail pour Content.",
9570
+ emailNotifications: "Notifications par e-mail",
9571
+ emailNotificationsDescription:
9572
+ "Recevez un e-mail lorsqu’une personne commente, répond ou vous mentionne dans votre document.",
9573
+ saveFailed: "Échec de l’enregistrement",
9527
9574
  languageTitle: "Langue",
9528
9575
  languageDescription:
9529
9576
  "Choisissez la langue de l’interface. Cette préférence est enregistrée dans votre compte.",
@@ -9721,6 +9768,10 @@ export const messagesByLocale = {
9721
9768
  settings: {
9722
9769
  title: "Einstellungen",
9723
9770
  description: "Sprach- und Arbeitsbereichseinstellungen für Content.",
9771
+ emailNotifications: "E-Mail-Benachrichtigungen",
9772
+ emailNotificationsDescription:
9773
+ "Erhalte eine E-Mail, wenn jemand dein Dokument kommentiert, antwortet oder dich erwähnt.",
9774
+ saveFailed: "Speichern fehlgeschlagen",
9724
9775
  languageTitle: "Sprache",
9725
9776
  languageDescription:
9726
9777
  "Wähle die Sprache der Oberfläche. Diese Einstellung wird in deinem Konto gespeichert.",
@@ -9917,6 +9968,10 @@ export const messagesByLocale = {
9917
9968
  settings: {
9918
9969
  title: "設定",
9919
9970
  description: "Content の言語とワークスペース設定。",
9971
+ emailNotifications: "メール通知",
9972
+ emailNotificationsDescription:
9973
+ "誰かがあなたのドキュメントにコメント、返信、またはあなたにメンションしたときにメールを受け取ります。",
9974
+ saveFailed: "保存に失敗しました",
9920
9975
  languageTitle: "言語",
9921
9976
  languageDescription:
9922
9977
  "インターフェース言語を選択します。この設定はアカウントに保存されます。",
@@ -10105,6 +10160,10 @@ export const messagesByLocale = {
10105
10160
  settings: {
10106
10161
  title: "설정",
10107
10162
  description: "Content의 언어 및 워크스페이스 환경설정입니다.",
10163
+ emailNotifications: "이메일 알림",
10164
+ emailNotificationsDescription:
10165
+ "누군가 내 문서에 댓글을 달거나 답글을 남기거나 나를 멘션하면 이메일을 받습니다.",
10166
+ saveFailed: "저장 실패",
10108
10167
  languageTitle: "언어",
10109
10168
  languageDescription:
10110
10169
  "인터페이스 언어를 선택하세요. 이 기본 설정은 계정에 저장됩니다.",
@@ -10299,6 +10358,10 @@ export const messagesByLocale = {
10299
10358
  settings: {
10300
10359
  title: "Configurações",
10301
10360
  description: "Preferências de idioma e espaço de trabalho do Content.",
10361
+ emailNotifications: "Notificações por e-mail",
10362
+ emailNotificationsDescription:
10363
+ "Receba um e-mail quando alguém comentar, responder ou mencionar você no seu documento.",
10364
+ saveFailed: "Falha ao salvar",
10302
10365
  languageTitle: "Idioma",
10303
10366
  languageDescription:
10304
10367
  "Escolha o idioma da interface. Essa preferência é salva na sua conta.",
@@ -10486,6 +10549,10 @@ export const messagesByLocale = {
10486
10549
  settings: {
10487
10550
  title: "सेटिंग्स",
10488
10551
  description: "Content के लिए भाषा और कार्यस्थान प्राथमिकताएं।",
10552
+ emailNotifications: "ईमेल सूचनाएँ",
10553
+ emailNotificationsDescription:
10554
+ "जब कोई आपके दस्तावेज़ पर टिप्पणी करे, जवाब दे या आपका उल्लेख करे तो ईमेल पाएँ।",
10555
+ saveFailed: "सहेजने में विफल",
10489
10556
  languageTitle: "भाषा",
10490
10557
  languageDescription: "इंटरफ़ेस भाषा चुनें। यह पसंद आपके खाते में सहेजी जाती है।",
10491
10558
  languageLabel: "इंटरफ़ेस भाषा",
@@ -10672,6 +10739,10 @@ export const messagesByLocale = {
10672
10739
  settings: {
10673
10740
  title: "الإعدادات",
10674
10741
  description: "تفضيلات اللغة ومساحة العمل في Content.",
10742
+ emailNotifications: "إشعارات البريد الإلكتروني",
10743
+ emailNotificationsDescription:
10744
+ "احصل على بريد إلكتروني عندما يعلّق شخص على مستندك أو يرد أو يذكرك.",
10745
+ saveFailed: "فشل الحفظ",
10675
10746
  languageTitle: "اللغة",
10676
10747
  languageDescription: "اختر لغة الواجهة. يتم حفظ هذا التفضيل في حسابك.",
10677
10748
  languageLabel: "لغة الواجهة",
@@ -0,0 +1,36 @@
1
+ export interface DocumentQueryContext {
2
+ databaseId?: string | null;
3
+ databaseDocumentId?: string | null;
4
+ }
5
+
6
+ export function documentQueryKey(
7
+ documentId: string,
8
+ context: DocumentQueryContext = {},
9
+ ) {
10
+ return [
11
+ "action",
12
+ "get-document",
13
+ {
14
+ id: documentId,
15
+ ...(context.databaseId ? { databaseId: context.databaseId } : {}),
16
+ ...(context.databaseDocumentId
17
+ ? { databaseDocumentId: context.databaseDocumentId }
18
+ : {}),
19
+ },
20
+ ] as const;
21
+ }
22
+
23
+ export function documentQueryFilter(documentId: string) {
24
+ return {
25
+ queryKey: ["action", "get-document"] as const,
26
+ predicate: (query: { queryKey: readonly unknown[] }) => {
27
+ const args = query.queryKey[2];
28
+ return (
29
+ !!args &&
30
+ typeof args === "object" &&
31
+ "id" in args &&
32
+ args.id === documentId
33
+ );
34
+ },
35
+ };
36
+ }
@@ -3,6 +3,8 @@ import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
3
3
  import { TeamPage } from "@agent-native/core/client/org";
4
4
  import {
5
5
  AccountSettingsCard,
6
+ SettingsGroup,
7
+ SettingsRow,
6
8
  SettingsTabsPage,
7
9
  useAgentSettingsTabs,
8
10
  type SettingsSearchEntry,
@@ -10,8 +12,10 @@ import {
10
12
  import { CreativeContextSettingsLink } from "@agent-native/creative-context/client";
11
13
  import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
12
14
  import { useMemo } from "react";
15
+ import { toast } from "sonner";
13
16
 
14
- import { Label } from "@/components/ui/label";
17
+ import { Switch } from "@/components/ui/switch";
18
+ import { useContentPrefs } from "@/hooks/use-content-prefs";
15
19
  import { messagesByLocale } from "@/i18n-data";
16
20
 
17
21
  import changelog from "../../CHANGELOG.md?raw";
@@ -24,6 +28,7 @@ export default function SettingsRoute() {
24
28
  const t = useT();
25
29
  const agentSettingsTabs = useAgentSettingsTabs();
26
30
  useSetPageTitle(t("settings.title"));
31
+ const { prefs, loading: prefsLoading, save: savePrefs } = useContentPrefs();
27
32
 
28
33
  const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
29
34
  () => [
@@ -33,6 +38,12 @@ export default function SettingsRoute() {
33
38
  keywords: "language locale translation i18n",
34
39
  hash: "language",
35
40
  },
41
+ {
42
+ id: "content-notifications",
43
+ label: t("settings.emailNotifications"),
44
+ keywords: "email notifications comments replies mentions alerts",
45
+ hash: "notifications",
46
+ },
36
47
  ],
37
48
  [t],
38
49
  );
@@ -52,23 +63,41 @@ export default function SettingsRoute() {
52
63
 
53
64
  <CreativeContextSettingsLink />
54
65
 
55
- <section
56
- id="language"
57
- className="scroll-mt-16 rounded-lg border border-border bg-card p-5"
58
- >
59
- <div className="space-y-1">
60
- <h2 className="text-base font-semibold">
61
- {t("settings.languageTitle")}
62
- </h2>
63
- <p className="text-sm leading-6 text-muted-foreground">
64
- {t("settings.languageDescription")}
65
- </p>
66
- </div>
67
- <div className="mt-4 max-w-xs space-y-1.5">
68
- <Label>{t("settings.languageLabel")}</Label>
69
- <LanguagePicker label={t("settings.languageLabel")} />
70
- </div>
71
- </section>
66
+ <SettingsGroup>
67
+ <SettingsRow
68
+ id="language"
69
+ label={t("settings.languageTitle")}
70
+ description={t("settings.languageDescription")}
71
+ control={
72
+ <div className="w-56">
73
+ <LanguagePicker label={t("settings.languageLabel")} />
74
+ </div>
75
+ }
76
+ />
77
+ <SettingsRow
78
+ id="notifications"
79
+ label={t("settings.emailNotifications")}
80
+ description={t("settings.emailNotificationsDescription")}
81
+ control={
82
+ <Switch
83
+ aria-label={t("settings.emailNotifications")}
84
+ checked={prefs.emailNotifications !== false}
85
+ disabled={prefsLoading}
86
+ onCheckedChange={(checked) => {
87
+ savePrefs({ emailNotifications: checked }).catch(
88
+ (err) => {
89
+ toast.error(
90
+ err instanceof Error
91
+ ? err.message
92
+ : t("settings.saveFailed"),
93
+ );
94
+ },
95
+ );
96
+ }}
97
+ />
98
+ }
99
+ />
100
+ </SettingsGroup>
72
101
  </main>
73
102
  }
74
103
  team={
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-30
4
+ ---
5
+
6
+ Breadcrumb menus now show only relevant page peers instead of internal system pages, with reliable keyboard selection between pages.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-01
4
+ ---
5
+
6
+ Get an email when someone comments on, replies in, or mentions you on your document, with a new toggle in Settings
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-08-02
4
+ ---
5
+
6
+ Pages opened from a database now keep that database’s fields and loading state, even when the page also belongs to a Builder-connected database.
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Email notifications for document comments, replies, and mentions.
3
+ *
4
+ * Recipient resolution, preference filtering, and delivery reporting come from
5
+ * `@agent-native/core/server`; this module owns only the Documents rows and the
6
+ * email copy. Share invites are not routed through the `emailNotifications`
7
+ * preference — they have their own delivery path.
8
+ */
9
+
10
+ import {
11
+ emailStrong,
12
+ getAppProductionUrl,
13
+ notifyActivity,
14
+ renderEmail,
15
+ runActivityNotification,
16
+ sendEmail,
17
+ type ActivityNotificationResult,
18
+ } from "@agent-native/core/server";
19
+ import { filterRecipientsByResourceAccess } from "@agent-native/core/sharing";
20
+ import { and, eq } from "drizzle-orm";
21
+
22
+ import { CONTENT_USER_PREFS_KEY } from "../../shared/content-user-prefs.js";
23
+ import { getDb, schema } from "../db/index.js";
24
+
25
+ export type DocumentCommentNotificationResult = ActivityNotificationResult;
26
+
27
+ const LOG_LABEL = "[content] comment notification";
28
+ const EXCERPT_LIMIT = 240;
29
+
30
+ function excerpt(content: string): string {
31
+ const collapsed = content.replace(/\s+/g, " ").trim();
32
+ return collapsed.length > EXCERPT_LIMIT
33
+ ? `${collapsed.slice(0, EXCERPT_LIMIT - 1)}…`
34
+ : collapsed;
35
+ }
36
+
37
+ function documentUrl(documentId: string): string {
38
+ const base = getAppProductionUrl().replace(/\/+$/, "");
39
+ return `${base}/page/${encodeURIComponent(documentId)}`;
40
+ }
41
+
42
+ async function threadParticipants(
43
+ documentId: string,
44
+ threadId: string,
45
+ ): Promise<string[]> {
46
+ const rows = await getDb()
47
+ .select({ authorEmail: schema.documentComments.authorEmail })
48
+ .from(schema.documentComments)
49
+ .where(
50
+ and(
51
+ eq(schema.documentComments.documentId, documentId),
52
+ eq(schema.documentComments.threadId, threadId),
53
+ ),
54
+ );
55
+ return rows.map((row) => row.authorEmail);
56
+ }
57
+
58
+ export interface DocumentCommentNotificationInput {
59
+ documentId: string;
60
+ /** Read from the access-checked resource by the caller, never re-queried. */
61
+ documentTitle: string;
62
+ /** The document's org, so `org` visibility resolves for its members. */
63
+ orgId?: string | null;
64
+ threadId: string;
65
+ ownerEmail: string;
66
+ authorEmail: string;
67
+ authorName?: string | null;
68
+ content: string;
69
+ mentions: { email: string; name: string }[];
70
+ isReply: boolean;
71
+ }
72
+
73
+ export async function notifyDocumentComment(
74
+ input: DocumentCommentNotificationInput,
75
+ ): Promise<DocumentCommentNotificationResult> {
76
+ return runActivityNotification(LOG_LABEL, () =>
77
+ deliverDocumentCommentEmails(input),
78
+ );
79
+ }
80
+
81
+ async function deliverDocumentCommentEmails(
82
+ input: DocumentCommentNotificationInput,
83
+ ): Promise<DocumentCommentNotificationResult> {
84
+ const title = input.documentTitle.trim() || "Untitled";
85
+ const mentioned = new Set(
86
+ input.mentions.map((mention) => mention.email.trim().toLowerCase()),
87
+ );
88
+
89
+ const candidates = [input.ownerEmail, ...mentioned];
90
+ if (input.isReply) {
91
+ candidates.push(
92
+ ...(await threadParticipants(input.documentId, input.threadId)),
93
+ );
94
+ }
95
+
96
+ // Mentions are caller-supplied and thread rows are historical; re-check both
97
+ // against the document's live ACL before mailing anyone its contents.
98
+ const allowed = await filterRecipientsByResourceAccess({
99
+ resourceType: "document",
100
+ resourceId: input.documentId,
101
+ emails: candidates,
102
+ orgId: input.orgId,
103
+ });
104
+
105
+ const actor = input.authorName?.trim() || input.authorEmail;
106
+ const url = documentUrl(input.documentId);
107
+
108
+ return notifyActivity({
109
+ candidates: allowed,
110
+ actorEmail: input.authorEmail,
111
+ preferenceKey: CONTENT_USER_PREFS_KEY,
112
+ logLabel: LOG_LABEL,
113
+ send: async (to) => {
114
+ const wasMentioned = mentioned.has(to);
115
+ const lead = wasMentioned
116
+ ? `${emailStrong(actor)} mentioned you in a comment on ${emailStrong(title)}.`
117
+ : input.isReply
118
+ ? `${emailStrong(actor)} replied in a comment thread on ${emailStrong(title)}.`
119
+ : `${emailStrong(actor)} commented on ${emailStrong(title)}.`;
120
+
121
+ const { html, text } = renderEmail({
122
+ preheader: `${actor} commented on ${title}.`,
123
+ heading: wasMentioned
124
+ ? "You were mentioned"
125
+ : input.isReply
126
+ ? "New reply on your document"
127
+ : "New comment",
128
+ paragraphs: [lead, `"${excerpt(input.content)}"`],
129
+ cta: { label: "Open document", url },
130
+ footer:
131
+ "You received this because you own, were mentioned in, or participated in this thread. Turn these off in Documents settings.",
132
+ });
133
+
134
+ await sendEmail({
135
+ to,
136
+ subject: wasMentioned
137
+ ? `${actor} mentioned you on "${title}"`
138
+ : input.isReply
139
+ ? `${actor} replied to a comment on "${title}"`
140
+ : `${actor} commented on "${title}"`,
141
+ html,
142
+ text,
143
+ });
144
+ },
145
+ });
146
+ }
@@ -14,6 +14,7 @@ export type DocumentContextPathEntry = {
14
14
  * assembles the live path without copying ancestor prose into descendants. */
15
15
  export async function getDocumentContextPath(
16
16
  document: Pick<typeof schema.documents.$inferSelect, "id" | "parentId">,
17
+ options: { databaseId?: string } = {},
17
18
  ): Promise<DocumentContextPathEntry[]> {
18
19
  const db = getDb();
19
20
  const path: DocumentContextPathEntry[] = [];
@@ -43,6 +44,15 @@ export async function getDocumentContextPath(
43
44
  parentId = parent.parentId;
44
45
  }
45
46
 
47
+ const membershipClauses = [
48
+ eq(schema.contentDatabaseItems.documentId, document.id),
49
+ isNull(schema.contentDatabases.deletedAt),
50
+ ];
51
+ if (options.databaseId) {
52
+ membershipClauses.push(
53
+ eq(schema.contentDatabaseItems.databaseId, options.databaseId),
54
+ );
55
+ }
46
56
  const [membership] = await db
47
57
  .select({ database: schema.contentDatabases })
48
58
  .from(schema.contentDatabaseItems)
@@ -50,12 +60,7 @@ export async function getDocumentContextPath(
50
60
  schema.contentDatabases,
51
61
  eq(schema.contentDatabases.id, schema.contentDatabaseItems.databaseId),
52
62
  )
53
- .where(
54
- and(
55
- eq(schema.contentDatabaseItems.documentId, document.id),
56
- isNull(schema.contentDatabases.deletedAt),
57
- ),
58
- )
63
+ .where(and(...membershipClauses))
59
64
  .orderBy(
60
65
  sql`CASE WHEN ${schema.contentDatabases.systemRole} IS NULL THEN 0 ELSE 1 END`,
61
66
  asc(schema.contentDatabases.id),
@@ -0,0 +1,17 @@
1
+ import { getSession } from "@agent-native/core/server";
2
+ import { getUserSetting } from "@agent-native/core/settings";
3
+ import { defineEventHandler, setResponseStatus } from "h3";
4
+
5
+ import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ const session = await getSession(event);
9
+ if (!session?.email) {
10
+ setResponseStatus(event, 401);
11
+ return { error: "unauthorized" };
12
+ }
13
+
14
+ const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
15
+ // coercion-ok: a null read means this user has no preferences yet, which is a real state.
16
+ return stored ?? {};
17
+ });
@@ -0,0 +1,36 @@
1
+ import { getSession } from "@agent-native/core/server";
2
+ import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
3
+ import { defineEventHandler, getHeader, readBody, setResponseStatus } from "h3";
4
+
5
+ import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ const session = await getSession(event);
9
+ if (!session?.email) {
10
+ setResponseStatus(event, 401);
11
+ return { error: "unauthorized" };
12
+ }
13
+
14
+ // coercion-ok: an unparsable body is rejected with 400 immediately below.
15
+ const body = await readBody(event).catch(() => null);
16
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
17
+ setResponseStatus(event, 400);
18
+ return { error: "Invalid settings payload" };
19
+ }
20
+
21
+ // Merge so a partial save never wipes preferences written elsewhere.
22
+ const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
23
+ // coercion-ok: a null read means this user has no preferences yet, which is a real state.
24
+ const existing = stored ?? {};
25
+ const next = {
26
+ ...(typeof existing === "object" && !Array.isArray(existing)
27
+ ? existing
28
+ : {}),
29
+ ...(body as Record<string, unknown>),
30
+ };
31
+
32
+ await putUserSetting(session.email, CONTENT_USER_PREFS_KEY, next, {
33
+ requestSource: getHeader(event, "x-request-source") || undefined,
34
+ });
35
+ return next;
36
+ });
@@ -36,6 +36,7 @@ export interface Document {
36
36
  properties?: DocumentProperty[];
37
37
  database?: ContentDatabase;
38
38
  databaseMembership?: ContentDatabaseMembership;
39
+ bodyHydration?: ContentDocumentBodyHydration;
39
40
  contextPath?: ContentContextPathEntry[];
40
41
  createdAt: string;
41
42
  updatedAt: string;
@@ -407,6 +408,13 @@ export interface ContentDatabaseMembership {
407
408
  bodyHydration?: ContentDatabaseBodyHydration;
408
409
  }
409
410
 
411
+ export interface ContentDocumentBodyHydration {
412
+ provider?: "builder";
413
+ hydration?: ContentDatabaseBodyHydration;
414
+ sourceId?: string;
415
+ databaseDocumentId?: string;
416
+ }
417
+
410
418
  export type ContentDatabaseBodyHydrationState =
411
419
  | "pending"
412
420
  | "hydrating"
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Per-user Documents preferences, stored under one user-setting key so
3
+ * Settings and the notification senders read and write the same object.
4
+ */
5
+
6
+ export const CONTENT_USER_PREFS_KEY = "content-user-prefs";
7
+
8
+ export type ContentUserPrefs = {
9
+ /** Comment, reply, and mention emails only — never share invites. */
10
+ emailNotifications?: boolean;
11
+ };