@agent-native/core 0.134.0 → 0.135.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (493) hide show
  1. package/corpus/README.md +3 -3
  2. package/corpus/core/CHANGELOG.md +113 -0
  3. package/corpus/core/docs/content/template-content-developers.mdx +1 -1
  4. package/corpus/core/package.json +3 -2
  5. package/corpus/core/src/automations/service.ts +41 -4
  6. package/corpus/core/src/cli/mcp-config-writers.ts +27 -21
  7. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +187 -85
  8. package/corpus/core/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
  9. package/corpus/core/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
  10. package/corpus/core/src/client/agent-page/TimezoneSelect.tsx +241 -0
  11. package/corpus/core/src/client/agent-page/use-jobs.ts +50 -10
  12. package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -0
  13. package/corpus/core/src/client/settings/AccountSettingsCard.tsx +35 -31
  14. package/corpus/core/src/client/settings/SchedulingTimezoneField.tsx +71 -0
  15. package/corpus/core/src/client/settings/SettingsRow.tsx +113 -0
  16. package/corpus/core/src/client/settings/agent-settings-search.ts +2 -1
  17. package/corpus/core/src/client/settings/index.ts +6 -0
  18. package/corpus/core/src/integrations/identity.ts +2 -12
  19. package/corpus/core/src/jobs/actions/list-automation-runs.ts +33 -0
  20. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +27 -6
  21. package/corpus/core/src/jobs/actions/manage-recurring-job.ts +41 -9
  22. package/corpus/core/src/jobs/background-automation-runner.ts +88 -0
  23. package/corpus/core/src/jobs/cron.ts +52 -6
  24. package/corpus/core/src/jobs/frontmatter.ts +20 -0
  25. package/corpus/core/src/jobs/run-history.ts +242 -0
  26. package/corpus/core/src/jobs/scheduler.ts +73 -18
  27. package/corpus/core/src/jobs/tools.ts +54 -6
  28. package/corpus/core/src/localization/actions/get-localization-preference.ts +2 -2
  29. package/corpus/core/src/localization/actions/set-localization-preference.ts +49 -11
  30. package/corpus/core/src/localization/default-messages.ts +27 -0
  31. package/corpus/core/src/localization/shared.ts +39 -6
  32. package/corpus/core/src/localization/user-timezone.ts +36 -0
  33. package/corpus/core/src/org/app-roles-handlers.ts +1 -9
  34. package/corpus/core/src/org/index.ts +2 -0
  35. package/corpus/core/src/org/membership.ts +18 -0
  36. package/corpus/core/src/review/actions/create-review-comment.ts +4 -1
  37. package/corpus/core/src/review/actions/reply-review-comment.ts +4 -1
  38. package/corpus/core/src/review/index.ts +5 -0
  39. package/corpus/core/src/review/notifications.ts +163 -0
  40. package/corpus/core/src/review/types.ts +7 -0
  41. package/corpus/core/src/server/action-discovery.ts +4 -0
  42. package/corpus/core/src/server/activity-notifications.ts +174 -0
  43. package/corpus/core/src/server/app-name.ts +31 -0
  44. package/corpus/core/src/server/better-auth-instance.ts +4 -4
  45. package/corpus/core/src/server/email-templates.ts +70 -14
  46. package/corpus/core/src/server/email.ts +66 -3
  47. package/corpus/core/src/server/index.ts +10 -0
  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-29-meeting-notes-no-longer-transcribe-the-other-side-twice-when.md +6 -0
  109. package/corpus/templates/clips/changelog/2026-07-31-editor-timeline-now-shows-video-frames-behind-the-waveform-g.md +6 -0
  110. package/corpus/templates/clips/changelog/2026-07-31-email-notifications-now-go-out-when-someone-comments-on-or-r.md +6 -0
  111. package/corpus/templates/clips/changelog/2026-07-31-you-can-now-set-a-default-visibility-for-new-recordings-in-s.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-08-01-email-notifications-for-comments-and-reactions-now-actually-.md +6 -0
  113. package/corpus/templates/clips/changelog/2026-08-03-the-desktop-app-now-opens-directly-beneath-its-tray-icon-on-.md +6 -0
  114. package/corpus/templates/clips/chrome-extension/package.json +1 -0
  115. package/corpus/templates/clips/chrome-extension/vitest.config.ts +9 -0
  116. package/corpus/templates/clips/desktop/package.json +1 -0
  117. package/corpus/templates/clips/desktop/src/app.tsx +17 -1
  118. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +37 -48
  119. package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
  120. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +7 -5
  121. package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +182 -106
  122. package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
  123. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +43 -14
  124. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +3 -3
  125. package/corpus/templates/clips/desktop/src-tauri/src/echo_guard.rs +443 -0
  126. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  127. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +815 -15
  128. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +61 -11
  129. package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +125 -16
  130. package/corpus/templates/clips/desktop/vitest.config.ts +9 -0
  131. package/corpus/templates/clips/server/db/schema.ts +17 -0
  132. package/corpus/templates/clips/server/jobs/media-verification.ts +4 -0
  133. package/corpus/templates/clips/server/lib/activity-notifications.ts +185 -0
  134. package/corpus/templates/clips/server/lib/recording-media-cleanup.ts +2 -0
  135. package/corpus/templates/clips/server/lib/recording-upload-state.ts +46 -9
  136. package/corpus/templates/clips/server/lib/recordings.ts +24 -0
  137. package/corpus/templates/clips/server/lib/resumable-session.ts +10 -4
  138. package/corpus/templates/clips/server/lib/transactional-email-templates.ts +109 -0
  139. package/corpus/templates/clips/server/lib/upload-interruption.ts +8 -0
  140. package/corpus/templates/clips/server/lib/upload-lease.ts +50 -4
  141. package/corpus/templates/clips/server/lib/video-filmstrip-sprite.ts +207 -0
  142. package/corpus/templates/clips/server/lib/video-remux.ts +13 -4
  143. package/corpus/templates/clips/server/plugins/db.ts +16 -0
  144. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +4 -0
  145. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +123 -36
  146. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +159 -29
  147. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +197 -0
  148. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +193 -39
  149. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +191 -12
  150. package/corpus/templates/clips/shared/clips-ai-prefs.ts +6 -0
  151. package/corpus/templates/clips/shared/feature-flags.ts +12 -0
  152. package/corpus/templates/clips/shared/recording-core.ts +4 -0
  153. package/corpus/templates/clips/vitest.config.ts +23 -19
  154. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +6 -4
  155. package/corpus/templates/content/actions/_database-membership-lock.ts +25 -0
  156. package/corpus/templates/content/actions/_database-row-batch.ts +6 -2
  157. package/corpus/templates/content/actions/_database-source-utils.ts +289 -129
  158. package/corpus/templates/content/actions/_database-utils.ts +12 -3
  159. package/corpus/templates/content/actions/add-comment.ts +15 -1
  160. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +39 -21
  161. package/corpus/templates/content/actions/attach-content-database-source.ts +4 -1
  162. package/corpus/templates/content/actions/change-content-database-source-role.ts +3 -5
  163. package/corpus/templates/content/actions/duplicate-document-property.ts +59 -46
  164. package/corpus/templates/content/actions/execute-builder-source-execution.ts +77 -71
  165. package/corpus/templates/content/actions/list-documents.ts +1 -0
  166. package/corpus/templates/content/actions/materialize-builder-required-fields.ts +7 -0
  167. package/corpus/templates/content/actions/remove-database-items.ts +183 -0
  168. package/corpus/templates/content/actions/set-document-property.ts +57 -39
  169. package/corpus/templates/content/actions/sync-local-folder-source.ts +7 -0
  170. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +5 -2
  171. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +50 -1
  172. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +471 -329
  173. package/corpus/templates/content/app/components/editor/database/row-access.ts +45 -0
  174. package/corpus/templates/content/app/components/editor/database/shared.tsx +141 -38
  175. package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
  176. package/corpus/templates/content/app/hooks/use-content-database.ts +2 -2
  177. package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
  178. package/corpus/templates/content/app/i18n-data.ts +170 -0
  179. package/corpus/templates/content/app/routes/_app.settings.tsx +47 -18
  180. package/corpus/templates/content/changelog/2026-07-30-breadcrumb-menus-now-hide-internal-system-pages.md +6 -0
  181. package/corpus/templates/content/changelog/2026-07-30-database-rows-can-now-be-removed-without-deleting-their-page.md +6 -0
  182. package/corpus/templates/content/changelog/2026-08-01-get-an-email-when-someone-comments-on-replies-in-or-mentions.md +6 -0
  183. package/corpus/templates/content/parity/eval-scenarios.ts +2 -2
  184. package/corpus/templates/content/parity/matrix.md +1 -1
  185. package/corpus/templates/content/parity/matrix.ts +4 -5
  186. package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
  187. package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.get.ts +17 -0
  188. package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.put.ts +36 -0
  189. package/corpus/templates/content/shared/api.ts +4 -0
  190. package/corpus/templates/content/shared/content-user-prefs.ts +11 -0
  191. package/corpus/templates/content/vitest.config.ts +20 -16
  192. package/corpus/templates/crm/app/routes/settings.tsx +14 -22
  193. package/corpus/templates/crm/vitest.config.ts +8 -4
  194. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +26 -11
  195. package/corpus/templates/design/actions/take-design-screenshot.ts +7 -0
  196. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +11 -3
  197. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +4 -1
  198. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +54 -17
  199. package/corpus/templates/design/app/components/design/design-canvas/local-runtime.ts +126 -0
  200. package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +2 -0
  201. package/corpus/templates/design/app/pages/Index.tsx +3 -1
  202. package/corpus/templates/design/app/pages/Present.tsx +2 -1
  203. package/corpus/templates/design/app/routes/settings.tsx +14 -22
  204. package/corpus/templates/design/changelog/2026-07-30-a-broken-inline-script-in-a-generated-screen-is-now-caught-o.md +6 -0
  205. package/corpus/templates/design/changelog/2026-07-30-design-html-is-now-validated-with-a-spec-grade-html-parser-i.md +6 -0
  206. package/corpus/templates/design/changelog/2026-07-30-designs-now-load-their-tailwind-and-alpine-runtimes-from-the.md +6 -0
  207. package/corpus/templates/design/changelog/2026-07-30-designs-with-a-broken-alpine-expression-are-now-caught-on-sa.md +6 -0
  208. package/corpus/templates/design/changelog/2026-07-30-editing-a-design-no-longer-strips-its-styling-the-canvas-kep.md +6 -0
  209. package/corpus/templates/design/changelog/2026-08-01-review-comments-replies-and-mentions-now-send-an-email-to-th.md +6 -0
  210. package/corpus/templates/design/package.json +4 -0
  211. package/corpus/templates/design/shared/html-integrity.ts +802 -556
  212. package/corpus/templates/design/vitest.config.ts +18 -12
  213. package/corpus/templates/dispatch/app/routes/settings.tsx +26 -40
  214. package/corpus/templates/dispatch/vitest.config.ts +11 -7
  215. package/corpus/templates/factory/app/routes/settings.tsx +14 -22
  216. package/corpus/templates/factory/vitest.config.ts +9 -0
  217. package/corpus/templates/forms/app/routes/_app.settings.tsx +14 -22
  218. package/corpus/templates/forms/vitest.config.ts +27 -23
  219. package/corpus/templates/macros/app/routes/settings.tsx +14 -22
  220. package/corpus/templates/macros/vitest.config.ts +16 -12
  221. package/corpus/templates/mail/app/pages/SettingsPage.tsx +14 -16
  222. package/corpus/templates/mail/vitest.config.ts +16 -12
  223. package/corpus/templates/plan/app/routes/settings.tsx +30 -44
  224. package/corpus/templates/plan/vitest.config.ts +24 -20
  225. package/corpus/templates/slides/actions/add-slide-comment.ts +12 -1
  226. package/corpus/templates/slides/app/components/ui/switch.tsx +1 -0
  227. package/corpus/templates/slides/app/hooks/use-slides-prefs.ts +55 -0
  228. package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
  229. package/corpus/templates/slides/app/routes/settings.tsx +45 -22
  230. package/corpus/templates/slides/changelog/2026-08-01-get-an-email-when-someone-comments-on-or-replies-in-your-dec.md +6 -0
  231. package/corpus/templates/slides/server/lib/comment-notifications.ts +182 -0
  232. package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.get.ts +16 -0
  233. package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.put.ts +36 -0
  234. package/corpus/templates/slides/shared/slides-user-prefs.ts +11 -0
  235. package/corpus/templates/slides/vitest.config.ts +17 -13
  236. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +2 -0
  237. package/corpus/templates/tasks/app/routes/settings.tsx +14 -22
  238. package/corpus/templates/tasks/vitest.config.ts +17 -13
  239. package/corpus/toolkit/CHANGELOG.md +9 -0
  240. package/corpus/toolkit/package.json +1 -1
  241. package/corpus/toolkit/vitest.config.ts +3 -0
  242. package/dist/automations/service.d.ts +2 -0
  243. package/dist/automations/service.d.ts.map +1 -1
  244. package/dist/automations/service.js +29 -4
  245. package/dist/automations/service.js.map +1 -1
  246. package/dist/cli/mcp-config-writers.d.ts.map +1 -1
  247. package/dist/cli/mcp-config-writers.js +24 -23
  248. package/dist/cli/mcp-config-writers.js.map +1 -1
  249. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  250. package/dist/client/agent-page/AgentJobsTab.js +86 -29
  251. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  252. package/dist/client/agent-page/AutomationDetailsDialog.d.ts +21 -0
  253. package/dist/client/agent-page/AutomationDetailsDialog.d.ts.map +1 -0
  254. package/dist/client/agent-page/AutomationDetailsDialog.js +33 -0
  255. package/dist/client/agent-page/AutomationDetailsDialog.js.map +1 -0
  256. package/dist/client/agent-page/AutomationScheduleDialog.d.ts +15 -0
  257. package/dist/client/agent-page/AutomationScheduleDialog.d.ts.map +1 -0
  258. package/dist/client/agent-page/AutomationScheduleDialog.js +46 -0
  259. package/dist/client/agent-page/AutomationScheduleDialog.js.map +1 -0
  260. package/dist/client/agent-page/TimezoneSelect.d.ts +17 -0
  261. package/dist/client/agent-page/TimezoneSelect.d.ts.map +1 -0
  262. package/dist/client/agent-page/TimezoneSelect.js +107 -0
  263. package/dist/client/agent-page/TimezoneSelect.js.map +1 -0
  264. package/dist/client/agent-page/use-jobs.d.ts +20 -7
  265. package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
  266. package/dist/client/agent-page/use-jobs.js +24 -4
  267. package/dist/client/agent-page/use-jobs.js.map +1 -1
  268. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  269. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  270. package/dist/client/org/OrgSwitcher.js +8 -2
  271. package/dist/client/org/OrgSwitcher.js.map +1 -1
  272. package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -1
  273. package/dist/client/settings/AccountSettingsCard.js +10 -9
  274. package/dist/client/settings/AccountSettingsCard.js.map +1 -1
  275. package/dist/client/settings/SchedulingTimezoneField.d.ts +10 -0
  276. package/dist/client/settings/SchedulingTimezoneField.d.ts.map +1 -0
  277. package/dist/client/settings/SchedulingTimezoneField.js +30 -0
  278. package/dist/client/settings/SchedulingTimezoneField.js.map +1 -0
  279. package/dist/client/settings/SettingsRow.d.ts +36 -0
  280. package/dist/client/settings/SettingsRow.d.ts.map +1 -0
  281. package/dist/client/settings/SettingsRow.js +15 -0
  282. package/dist/client/settings/SettingsRow.js.map +1 -0
  283. package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
  284. package/dist/client/settings/agent-settings-search.js +1 -1
  285. package/dist/client/settings/agent-settings-search.js.map +1 -1
  286. package/dist/client/settings/index.d.ts +1 -0
  287. package/dist/client/settings/index.d.ts.map +1 -1
  288. package/dist/client/settings/index.js +1 -0
  289. package/dist/client/settings/index.js.map +1 -1
  290. package/dist/collab/struct-routes.d.ts +1 -1
  291. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  292. package/dist/integrations/identity.d.ts.map +1 -1
  293. package/dist/integrations/identity.js +2 -11
  294. package/dist/integrations/identity.js.map +1 -1
  295. package/dist/jobs/actions/list-automation-runs.d.ts +8 -0
  296. package/dist/jobs/actions/list-automation-runs.d.ts.map +1 -0
  297. package/dist/jobs/actions/list-automation-runs.js +29 -0
  298. package/dist/jobs/actions/list-automation-runs.js.map +1 -0
  299. package/dist/jobs/actions/list-recurring-jobs.d.ts +2 -0
  300. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
  301. package/dist/jobs/actions/list-recurring-jobs.js +20 -7
  302. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
  303. package/dist/jobs/actions/manage-recurring-job.d.ts +2 -0
  304. package/dist/jobs/actions/manage-recurring-job.js +30 -9
  305. package/dist/jobs/actions/manage-recurring-job.js.map +1 -1
  306. package/dist/jobs/background-automation-runner.d.ts.map +1 -1
  307. package/dist/jobs/background-automation-runner.js +60 -0
  308. package/dist/jobs/background-automation-runner.js.map +1 -1
  309. package/dist/jobs/cron.d.ts +16 -2
  310. package/dist/jobs/cron.d.ts.map +1 -1
  311. package/dist/jobs/cron.js +43 -6
  312. package/dist/jobs/cron.js.map +1 -1
  313. package/dist/jobs/frontmatter.d.ts +12 -0
  314. package/dist/jobs/frontmatter.d.ts.map +1 -1
  315. package/dist/jobs/frontmatter.js +8 -0
  316. package/dist/jobs/frontmatter.js.map +1 -1
  317. package/dist/jobs/run-history.d.ts +56 -0
  318. package/dist/jobs/run-history.d.ts.map +1 -0
  319. package/dist/jobs/run-history.js +169 -0
  320. package/dist/jobs/run-history.js.map +1 -0
  321. package/dist/jobs/scheduler.d.ts.map +1 -1
  322. package/dist/jobs/scheduler.js +51 -18
  323. package/dist/jobs/scheduler.js.map +1 -1
  324. package/dist/jobs/tools.d.ts.map +1 -1
  325. package/dist/jobs/tools.js +37 -6
  326. package/dist/jobs/tools.js.map +1 -1
  327. package/dist/localization/actions/get-localization-preference.d.ts +1 -2
  328. package/dist/localization/actions/get-localization-preference.d.ts.map +1 -1
  329. package/dist/localization/actions/get-localization-preference.js.map +1 -1
  330. package/dist/localization/actions/set-localization-preference.d.ts +3 -3
  331. package/dist/localization/actions/set-localization-preference.d.ts.map +1 -1
  332. package/dist/localization/actions/set-localization-preference.js +33 -8
  333. package/dist/localization/actions/set-localization-preference.js.map +1 -1
  334. package/dist/localization/default-messages.d.ts +25 -0
  335. package/dist/localization/default-messages.d.ts.map +1 -1
  336. package/dist/localization/default-messages.js +25 -0
  337. package/dist/localization/default-messages.js.map +1 -1
  338. package/dist/localization/shared.d.ts +16 -1
  339. package/dist/localization/shared.d.ts.map +1 -1
  340. package/dist/localization/shared.js +22 -4
  341. package/dist/localization/shared.js.map +1 -1
  342. package/dist/localization/user-timezone.d.ts +11 -0
  343. package/dist/localization/user-timezone.d.ts.map +1 -0
  344. package/dist/localization/user-timezone.js +31 -0
  345. package/dist/localization/user-timezone.js.map +1 -0
  346. package/dist/notifications/routes.d.ts +2 -2
  347. package/dist/observability/routes.d.ts +1 -1
  348. package/dist/org/app-roles-handlers.d.ts.map +1 -1
  349. package/dist/org/app-roles-handlers.js +1 -8
  350. package/dist/org/app-roles-handlers.js.map +1 -1
  351. package/dist/org/index.d.ts +1 -0
  352. package/dist/org/index.d.ts.map +1 -1
  353. package/dist/org/index.js +1 -0
  354. package/dist/org/index.js.map +1 -1
  355. package/dist/org/membership.d.ts +6 -0
  356. package/dist/org/membership.d.ts.map +1 -0
  357. package/dist/org/membership.js +16 -0
  358. package/dist/org/membership.js.map +1 -0
  359. package/dist/provider-api/actions/custom-provider-registration.d.ts +10 -10
  360. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  361. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  362. package/dist/resources/handlers.d.ts +1 -1
  363. package/dist/review/actions/create-review-comment.d.ts +32 -1
  364. package/dist/review/actions/create-review-comment.d.ts.map +1 -1
  365. package/dist/review/actions/create-review-comment.js +3 -1
  366. package/dist/review/actions/create-review-comment.js.map +1 -1
  367. package/dist/review/actions/reply-review-comment.d.ts +32 -1
  368. package/dist/review/actions/reply-review-comment.d.ts.map +1 -1
  369. package/dist/review/actions/reply-review-comment.js +3 -1
  370. package/dist/review/actions/reply-review-comment.js.map +1 -1
  371. package/dist/review/index.d.ts +1 -0
  372. package/dist/review/index.d.ts.map +1 -1
  373. package/dist/review/index.js +1 -0
  374. package/dist/review/index.js.map +1 -1
  375. package/dist/review/notifications.d.ts +24 -0
  376. package/dist/review/notifications.d.ts.map +1 -0
  377. package/dist/review/notifications.js +123 -0
  378. package/dist/review/notifications.js.map +1 -0
  379. package/dist/review/types.d.ts +5 -0
  380. package/dist/review/types.d.ts.map +1 -1
  381. package/dist/review/types.js.map +1 -1
  382. package/dist/server/action-discovery.d.ts.map +1 -1
  383. package/dist/server/action-discovery.js +4 -0
  384. package/dist/server/action-discovery.js.map +1 -1
  385. package/dist/server/activity-notifications.d.ts +61 -0
  386. package/dist/server/activity-notifications.d.ts.map +1 -0
  387. package/dist/server/activity-notifications.js +103 -0
  388. package/dist/server/activity-notifications.js.map +1 -0
  389. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  390. package/dist/server/app-name.d.ts +18 -0
  391. package/dist/server/app-name.d.ts.map +1 -1
  392. package/dist/server/app-name.js +31 -0
  393. package/dist/server/app-name.js.map +1 -1
  394. package/dist/server/better-auth-instance.js +4 -4
  395. package/dist/server/better-auth-instance.js.map +1 -1
  396. package/dist/server/email-templates.d.ts +12 -0
  397. package/dist/server/email-templates.d.ts.map +1 -1
  398. package/dist/server/email-templates.js +57 -14
  399. package/dist/server/email-templates.js.map +1 -1
  400. package/dist/server/email.d.ts +12 -0
  401. package/dist/server/email.d.ts.map +1 -1
  402. package/dist/server/email.js +52 -5
  403. package/dist/server/email.js.map +1 -1
  404. package/dist/server/index.d.ts +1 -0
  405. package/dist/server/index.d.ts.map +1 -1
  406. package/dist/server/index.js +1 -0
  407. package/dist/server/index.js.map +1 -1
  408. package/dist/sharing/index.d.ts +1 -0
  409. package/dist/sharing/index.d.ts.map +1 -1
  410. package/dist/sharing/index.js +1 -0
  411. package/dist/sharing/index.js.map +1 -1
  412. package/dist/sharing/recipients.d.ts +31 -0
  413. package/dist/sharing/recipients.d.ts.map +1 -0
  414. package/dist/sharing/recipients.js +40 -0
  415. package/dist/sharing/recipients.js.map +1 -0
  416. package/dist/templates/chat/app/routes/settings.tsx +14 -22
  417. package/dist/templates/chat/vitest.config.ts +9 -0
  418. package/dist/triggers/actions/list-automations.d.ts +2 -0
  419. package/dist/triggers/actions/list-automations.d.ts.map +1 -1
  420. package/dist/triggers/actions/list-automations.js +19 -8
  421. package/dist/triggers/actions/list-automations.js.map +1 -1
  422. package/dist/triggers/actions/manage-automation.d.ts +6 -0
  423. package/dist/triggers/actions/manage-automation.js +12 -6
  424. package/dist/triggers/actions/manage-automation.js.map +1 -1
  425. package/dist/triggers/actions.d.ts.map +1 -1
  426. package/dist/triggers/actions.js +15 -4
  427. package/dist/triggers/actions.js.map +1 -1
  428. package/dist/triggers/dispatcher.d.ts.map +1 -1
  429. package/dist/triggers/dispatcher.js +19 -17
  430. package/dist/triggers/dispatcher.js.map +1 -1
  431. package/dist/triggers/routes.d.ts.map +1 -1
  432. package/dist/triggers/routes.js +6 -6
  433. package/dist/triggers/routes.js.map +1 -1
  434. package/dist/vitest-config.d.ts +10 -0
  435. package/dist/vitest-config.d.ts.map +1 -0
  436. package/dist/vitest-config.js +55 -0
  437. package/dist/vitest-config.js.map +1 -0
  438. package/docs/content/template-content-developers.mdx +1 -1
  439. package/package.json +5 -4
  440. package/src/automations/service.ts +41 -4
  441. package/src/cli/mcp-config-writers.ts +27 -21
  442. package/src/client/agent-page/AgentJobsTab.tsx +187 -85
  443. package/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
  444. package/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
  445. package/src/client/agent-page/TimezoneSelect.tsx +241 -0
  446. package/src/client/agent-page/use-jobs.ts +50 -10
  447. package/src/client/org/OrgSwitcher.tsx +26 -0
  448. package/src/client/settings/AccountSettingsCard.tsx +35 -31
  449. package/src/client/settings/SchedulingTimezoneField.tsx +71 -0
  450. package/src/client/settings/SettingsRow.tsx +113 -0
  451. package/src/client/settings/agent-settings-search.ts +2 -1
  452. package/src/client/settings/index.ts +6 -0
  453. package/src/integrations/identity.ts +2 -12
  454. package/src/jobs/actions/list-automation-runs.ts +33 -0
  455. package/src/jobs/actions/list-recurring-jobs.ts +27 -6
  456. package/src/jobs/actions/manage-recurring-job.ts +41 -9
  457. package/src/jobs/background-automation-runner.ts +88 -0
  458. package/src/jobs/cron.ts +52 -6
  459. package/src/jobs/frontmatter.ts +20 -0
  460. package/src/jobs/run-history.ts +242 -0
  461. package/src/jobs/scheduler.ts +73 -18
  462. package/src/jobs/tools.ts +54 -6
  463. package/src/localization/actions/get-localization-preference.ts +2 -2
  464. package/src/localization/actions/set-localization-preference.ts +49 -11
  465. package/src/localization/default-messages.ts +27 -0
  466. package/src/localization/shared.ts +39 -6
  467. package/src/localization/user-timezone.ts +36 -0
  468. package/src/org/app-roles-handlers.ts +1 -9
  469. package/src/org/index.ts +2 -0
  470. package/src/org/membership.ts +18 -0
  471. package/src/review/actions/create-review-comment.ts +4 -1
  472. package/src/review/actions/reply-review-comment.ts +4 -1
  473. package/src/review/index.ts +5 -0
  474. package/src/review/notifications.ts +163 -0
  475. package/src/review/types.ts +7 -0
  476. package/src/server/action-discovery.ts +4 -0
  477. package/src/server/activity-notifications.ts +174 -0
  478. package/src/server/app-name.ts +31 -0
  479. package/src/server/better-auth-instance.ts +4 -4
  480. package/src/server/email-templates.ts +70 -14
  481. package/src/server/email.ts +66 -3
  482. package/src/server/index.ts +10 -0
  483. package/src/sharing/index.ts +5 -0
  484. package/src/sharing/recipients.ts +67 -0
  485. package/src/templates/chat/app/routes/settings.tsx +14 -22
  486. package/src/templates/chat/vitest.config.ts +9 -0
  487. package/src/triggers/actions/list-automations.ts +27 -8
  488. package/src/triggers/actions/manage-automation.ts +17 -6
  489. package/src/triggers/actions.ts +16 -4
  490. package/src/triggers/dispatcher.ts +44 -30
  491. package/src/triggers/routes.ts +19 -6
  492. package/src/vitest-config.ts +68 -0
  493. package/corpus/templates/content/actions/delete-database-items.ts +0 -89
@@ -1 +1 @@
1
- {"version":3,"file":"list-automations.d.ts","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,GAAG,cAAc,CAAC;IACnC,WAAW,EAAE,OAAO,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,OAAO,CAAC;CACpB"}
1
+ {"version":3,"file":"list-automations.d.ts","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"AAuCA,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,GAAG,cAAc,CAAC;IACnC,WAAW,EAAE,OAAO,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,EAAE,OAAO,CAAC;CACpB"}
@@ -1,19 +1,26 @@
1
1
  import { z } from "zod";
2
2
  import { defineAction } from "../../action.js";
3
3
  import { listAutomationDefinitions, } from "../../automations/service.js";
4
- import { describeCron, isValidCron, nextOccurrence } from "../../jobs/cron.js";
4
+ import { describeCron, effectiveTimezone, isValidCron, nextOccurrence, } from "../../jobs/cron.js";
5
5
  const scopeSchema = z.enum(["personal", "organization"]);
6
6
  function nextRun(meta) {
7
7
  if (!meta.enabled)
8
8
  return null;
9
- if (meta.nextRun)
10
- return meta.nextRun;
11
- if (meta.triggerType === "schedule" &&
9
+ const scheduled = Boolean(meta.triggerType === "schedule" &&
12
10
  meta.schedule &&
13
- isValidCron(meta.schedule)) {
14
- return nextOccurrence(meta.schedule).toISOString();
11
+ isValidCron(meta.schedule));
12
+ // A stored `nextRun` in the past means the dispatcher kept declining to run
13
+ // this automation, not that it is overdue. Report the real next occurrence
14
+ // and let `lastError` carry the reason it keeps being passed over.
15
+ if (meta.nextRun) {
16
+ const stored = new Date(meta.nextRun).getTime();
17
+ if (!Number.isFinite(stored) || stored > Date.now() || !scheduled) {
18
+ return meta.nextRun;
19
+ }
15
20
  }
16
- return null;
21
+ return scheduled
22
+ ? nextOccurrence(meta.schedule, undefined, meta.timezone).toISOString()
23
+ : null;
17
24
  }
18
25
  export default defineAction({
19
26
  description: "List event-triggered and schedule-triggered automations in the selected personal or organization scope.",
@@ -37,11 +44,15 @@ export default defineAction({
37
44
  triggerType: meta.triggerType,
38
45
  event: meta.event ?? null,
39
46
  schedule: meta.schedule || null,
40
- scheduleDescription: meta.schedule ? describeCron(meta.schedule) : null,
47
+ timezone: meta.schedule ? effectiveTimezone(meta.timezone) : null,
48
+ scheduleDescription: meta.schedule
49
+ ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
50
+ : null,
41
51
  condition: meta.condition ?? null,
42
52
  body,
43
53
  enabled: meta.enabled,
44
54
  lastRun: meta.lastRun ?? null,
55
+ lastCheck: meta.lastCheck ?? null,
45
56
  lastStatus: meta.lastStatus ?? null,
46
57
  lastError: meta.lastError ?? null,
47
58
  nextRun: nextRun(meta),
@@ -1 +1 @@
1
- {"version":3,"file":"list-automations.js","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n listAutomationDefinitions,\n type AutomationScope,\n} from \"../../automations/service.js\";\nimport { describeCron, isValidCron, nextOccurrence } from \"../../jobs/cron.js\";\n\nconst scopeSchema = z.enum([\"personal\", \"organization\"]);\n\nfunction nextRun(\n meta: Awaited<ReturnType<typeof listAutomationDefinitions>>[number][\"meta\"],\n): string | null {\n if (!meta.enabled) return null;\n if (meta.nextRun) return meta.nextRun;\n if (\n meta.triggerType === \"schedule\" &&\n meta.schedule &&\n isValidCron(meta.schedule)\n ) {\n return nextOccurrence(meta.schedule).toISOString();\n }\n return null;\n}\n\nexport interface AutomationActionItem {\n id: string;\n name: string;\n path: string;\n scope: \"personal\" | \"organization\";\n triggerType: \"event\" | \"schedule\";\n event: string | null;\n schedule: string | null;\n scheduleDescription: string | null;\n condition: string | null;\n body: string;\n enabled: boolean;\n lastRun: string | null;\n lastStatus: string | null;\n lastError: string | null;\n nextRun: string | null;\n createdBy: string | null;\n model: string | null;\n mcpTools: string[];\n originScopeId: string | null;\n deliveryPlatform: string | null;\n deliveryDestination: string | null;\n deliveryThreadRef: string | null;\n deliveryTenantId: string | null;\n canUpdate: boolean;\n}\n\nexport default defineAction({\n description:\n \"List event-triggered and schedule-triggered automations in the selected personal or organization scope.\",\n agentTool: false,\n schema: z.object({\n scope: scopeSchema.default(\"personal\"),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n parallelSafe: true,\n run: async ({ scope }, ctx): Promise<AutomationActionItem[]> => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const definitions = await listAutomationDefinitions(\n { userEmail, orgId: ctx?.orgId },\n scope as AutomationScope,\n );\n return definitions.map(({ resource, name, meta, body, canUpdate }) => ({\n id: resource.id,\n name,\n path: resource.path,\n scope: scope as AutomationScope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n scheduleDescription: meta.schedule ? describeCron(meta.schedule) : null,\n condition: meta.condition ?? null,\n body,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: nextRun(meta),\n createdBy: meta.createdBy ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n canUpdate,\n }));\n },\n});\n"]}
1
+ {"version":3,"file":"list-automations.js","sourceRoot":"","sources":["../../../src/triggers/actions/list-automations.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n listAutomationDefinitions,\n type AutomationScope,\n} from \"../../automations/service.js\";\nimport {\n describeCron,\n effectiveTimezone,\n isValidCron,\n nextOccurrence,\n} from \"../../jobs/cron.js\";\n\nconst scopeSchema = z.enum([\"personal\", \"organization\"]);\n\nfunction nextRun(\n meta: Awaited<ReturnType<typeof listAutomationDefinitions>>[number][\"meta\"],\n): string | null {\n if (!meta.enabled) return null;\n const scheduled = Boolean(\n meta.triggerType === \"schedule\" &&\n meta.schedule &&\n isValidCron(meta.schedule),\n );\n // A stored `nextRun` in the past means the dispatcher kept declining to run\n // this automation, not that it is overdue. Report the real next occurrence\n // and let `lastError` carry the reason it keeps being passed over.\n if (meta.nextRun) {\n const stored = new Date(meta.nextRun).getTime();\n if (!Number.isFinite(stored) || stored > Date.now() || !scheduled) {\n return meta.nextRun;\n }\n }\n return scheduled\n ? nextOccurrence(meta.schedule!, undefined, meta.timezone).toISOString()\n : null;\n}\n\nexport interface AutomationActionItem {\n id: string;\n name: string;\n path: string;\n scope: \"personal\" | \"organization\";\n triggerType: \"event\" | \"schedule\";\n event: string | null;\n schedule: string | null;\n timezone: string | null;\n scheduleDescription: string | null;\n condition: string | null;\n body: string;\n enabled: boolean;\n lastRun: string | null;\n lastCheck: string | null;\n lastStatus: string | null;\n lastError: string | null;\n nextRun: string | null;\n createdBy: string | null;\n model: string | null;\n mcpTools: string[];\n originScopeId: string | null;\n deliveryPlatform: string | null;\n deliveryDestination: string | null;\n deliveryThreadRef: string | null;\n deliveryTenantId: string | null;\n canUpdate: boolean;\n}\n\nexport default defineAction({\n description:\n \"List event-triggered and schedule-triggered automations in the selected personal or organization scope.\",\n agentTool: false,\n schema: z.object({\n scope: scopeSchema.default(\"personal\"),\n }),\n http: { method: \"GET\" },\n readOnly: true,\n parallelSafe: true,\n run: async ({ scope }, ctx): Promise<AutomationActionItem[]> => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const definitions = await listAutomationDefinitions(\n { userEmail, orgId: ctx?.orgId },\n scope as AutomationScope,\n );\n return definitions.map(({ resource, name, meta, body, canUpdate }) => ({\n id: resource.id,\n name,\n path: resource.path,\n scope: scope as AutomationScope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n timezone: meta.schedule ? effectiveTimezone(meta.timezone) : null,\n scheduleDescription: meta.schedule\n ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))\n : null,\n condition: meta.condition ?? null,\n body,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastCheck: meta.lastCheck ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: nextRun(meta),\n createdBy: meta.createdBy ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n canUpdate,\n }));\n },\n});\n"]}
@@ -3,15 +3,21 @@ declare const _default: import("../../action.js").ActionDefinition<{
3
3
  name: string;
4
4
  scope?: "organization" | "personal";
5
5
  enabled?: boolean;
6
+ schedule?: string;
7
+ timezone?: string;
6
8
  }, {
7
9
  deleted: boolean;
8
10
  name: string;
9
11
  enabled?: undefined;
12
+ schedule?: undefined;
13
+ timezone?: undefined;
10
14
  nextRun?: undefined;
11
15
  } | {
12
16
  deleted?: undefined;
13
17
  name: string;
14
18
  enabled: boolean;
19
+ schedule: string;
20
+ timezone: string;
15
21
  nextRun: string;
16
22
  }>;
17
23
  export default _default;
@@ -10,8 +10,10 @@ export default defineAction({
10
10
  name: z.string().min(1),
11
11
  scope: z.enum(["personal", "organization"]).default("personal"),
12
12
  enabled: z.boolean().optional(),
13
+ schedule: z.string().min(1).optional(),
14
+ timezone: z.string().min(1).optional(),
13
15
  }),
14
- run: async ({ operation, name, scope, enabled }, ctx) => {
16
+ run: async ({ operation, name, scope, enabled, schedule, timezone }, ctx) => {
15
17
  const userEmail = ctx?.userEmail;
16
18
  if (!userEmail)
17
19
  throw new Error("Not authenticated.");
@@ -21,20 +23,24 @@ export default defineAction({
21
23
  await refreshEventSubscriptions();
22
24
  return { deleted: true, name };
23
25
  }
24
- if (enabled === undefined) {
25
- throw Object.assign(new Error("enabled is required for update."), {
26
- statusCode: 400,
27
- });
26
+ if (enabled === undefined &&
27
+ schedule === undefined &&
28
+ timezone === undefined) {
29
+ throw Object.assign(new Error("enabled, schedule, or timezone is required for update."), { statusCode: 400 });
28
30
  }
29
31
  const definition = await updateAutomation(actor, {
30
32
  name,
31
33
  scope,
32
- enabled,
34
+ ...(enabled === undefined ? {} : { enabled }),
35
+ ...(schedule === undefined ? {} : { schedule }),
36
+ ...(timezone === undefined ? {} : { timezone }),
33
37
  });
34
38
  await refreshEventSubscriptions();
35
39
  return {
36
40
  name,
37
41
  enabled: definition.meta.enabled,
42
+ schedule: definition.meta.schedule || null,
43
+ timezone: definition.meta.timezone ?? null,
38
44
  nextRun: definition.meta.nextRun ?? null,
39
45
  };
40
46
  },
@@ -1 +1 @@
1
- {"version":3,"file":"manage-automation.js","sourceRoot":"","sources":["../../../src/triggers/actions/manage-automation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,mGAAmG;IACrG,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;KAChC,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE;QACtD,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAE/C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3C,MAAM,yBAAyB,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,EAAE;gBAChE,UAAU,EAAE,GAAG;aAChB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE;YAC/C,IAAI;YACJ,KAAK;YACL,OAAO;SACR,CAAC,CAAC;QACH,MAAM,yBAAyB,EAAE,CAAC;QAClC,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO;YAChC,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI;SACzC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n deleteAutomation,\n updateAutomation,\n} from \"../../automations/service.js\";\nimport { refreshEventSubscriptions } from \"../dispatcher.js\";\n\nexport default defineAction({\n description:\n \"Enable, disable, or delete a personal or organization automation from the Agent Automations page.\",\n agentTool: false,\n schema: z.object({\n operation: z.enum([\"update\", \"delete\"]),\n name: z.string().min(1),\n scope: z.enum([\"personal\", \"organization\"]).default(\"personal\"),\n enabled: z.boolean().optional(),\n }),\n run: async ({ operation, name, scope, enabled }, ctx) => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const actor = { userEmail, orgId: ctx?.orgId };\n\n if (operation === \"delete\") {\n await deleteAutomation(actor, scope, name);\n await refreshEventSubscriptions();\n return { deleted: true, name };\n }\n if (enabled === undefined) {\n throw Object.assign(new Error(\"enabled is required for update.\"), {\n statusCode: 400,\n });\n }\n const definition = await updateAutomation(actor, {\n name,\n scope,\n enabled,\n });\n await refreshEventSubscriptions();\n return {\n name,\n enabled: definition.meta.enabled,\n nextRun: definition.meta.nextRun ?? null,\n };\n },\n});\n"]}
1
+ {"version":3,"file":"manage-automation.js","sourceRoot":"","sources":["../../../src/triggers/actions/manage-automation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,mGAAmG;IACrG,SAAS,EAAE,KAAK;IAChB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;QAC/B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;QACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;KACvC,CAAC;IACF,GAAG,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,EAAE;QAC1E,MAAM,SAAS,GAAG,GAAG,EAAE,SAAS,CAAC;QACjC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAE/C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC3C,MAAM,yBAAyB,EAAE,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QACD,IACE,OAAO,KAAK,SAAS;YACrB,QAAQ,KAAK,SAAS;YACtB,QAAQ,KAAK,SAAS,EACtB,CAAC;YACD,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,wDAAwD,CAAC,EACnE,EAAE,UAAU,EAAE,GAAG,EAAE,CACpB,CAAC;QACJ,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,KAAK,EAAE;YAC/C,IAAI;YACJ,KAAK;YACL,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;YAC/C,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,yBAAyB,EAAE,CAAC;QAClC,OAAO;YACL,IAAI;YACJ,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO;YAChC,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC1C,QAAQ,EAAE,UAAU,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI;YAC1C,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI;SACzC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\n\nimport { defineAction } from \"../../action.js\";\nimport {\n deleteAutomation,\n updateAutomation,\n} from \"../../automations/service.js\";\nimport { refreshEventSubscriptions } from \"../dispatcher.js\";\n\nexport default defineAction({\n description:\n \"Enable, disable, or delete a personal or organization automation from the Agent Automations page.\",\n agentTool: false,\n schema: z.object({\n operation: z.enum([\"update\", \"delete\"]),\n name: z.string().min(1),\n scope: z.enum([\"personal\", \"organization\"]).default(\"personal\"),\n enabled: z.boolean().optional(),\n schedule: z.string().min(1).optional(),\n timezone: z.string().min(1).optional(),\n }),\n run: async ({ operation, name, scope, enabled, schedule, timezone }, ctx) => {\n const userEmail = ctx?.userEmail;\n if (!userEmail) throw new Error(\"Not authenticated.\");\n const actor = { userEmail, orgId: ctx?.orgId };\n\n if (operation === \"delete\") {\n await deleteAutomation(actor, scope, name);\n await refreshEventSubscriptions();\n return { deleted: true, name };\n }\n if (\n enabled === undefined &&\n schedule === undefined &&\n timezone === undefined\n ) {\n throw Object.assign(\n new Error(\"enabled, schedule, or timezone is required for update.\"),\n { statusCode: 400 },\n );\n }\n const definition = await updateAutomation(actor, {\n name,\n scope,\n ...(enabled === undefined ? {} : { enabled }),\n ...(schedule === undefined ? {} : { schedule }),\n ...(timezone === undefined ? {} : { timezone }),\n });\n await refreshEventSubscriptions();\n return {\n name,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n };\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA8RhE,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,MAAM,GAC3B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAqI7B"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAqShE,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,MAAM,MAAM,GAC3B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA0I7B"}
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import { defineAutomation, deleteAutomation, listAutomationDefinitions, updateAutomation, } from "../automations/service.js";
12
12
  import { listEvents } from "../event-bus/index.js";
13
- import { describeCron } from "../jobs/cron.js";
13
+ import { describeCron, effectiveTimezone } from "../jobs/cron.js";
14
14
  import { getIntegrationRequestContext, getRequestOrgId, } from "../server/request-context.js";
15
15
  import { refreshEventSubscriptions } from "./dispatcher.js";
16
16
  /* ------------------------------------------------------------------ */
@@ -52,7 +52,10 @@ async function handleList(args, getCurrentUser) {
52
52
  triggerType: meta.triggerType,
53
53
  event: meta.event ?? null,
54
54
  schedule: meta.schedule || null,
55
- scheduleDescription: meta.schedule ? describeCron(meta.schedule) : null,
55
+ timezone: meta.timezone ? effectiveTimezone(meta.timezone) : null,
56
+ scheduleDescription: meta.schedule
57
+ ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
58
+ : null,
56
59
  condition: meta.condition ?? null,
57
60
  mode: meta.mode,
58
61
  domain: meta.domain ?? null,
@@ -101,6 +104,7 @@ async function handleDefine(args, getCurrentUser) {
101
104
  triggerType: automationTriggerType(args.trigger_type),
102
105
  body: typeof args.body === "string" ? args.body : "",
103
106
  schedule: typeof args.schedule === "string" ? args.schedule : undefined,
107
+ timezone: typeof args.timezone === "string" ? args.timezone : undefined,
104
108
  event: typeof args.event === "string" ? args.event : undefined,
105
109
  condition: typeof args.condition === "string" ? args.condition : undefined,
106
110
  domain: typeof args.domain === "string" ? args.domain : undefined,
@@ -132,6 +136,7 @@ async function handleDefine(args, getCurrentUser) {
132
136
  triggerType: definition.meta.triggerType,
133
137
  event: definition.meta.event ?? null,
134
138
  schedule: definition.meta.schedule || null,
139
+ timezone: definition.meta.timezone ?? null,
135
140
  nextRun: definition.meta.nextRun ?? null,
136
141
  createdBy: definition.meta.createdBy,
137
142
  runAs: definition.meta.runAs,
@@ -168,6 +173,7 @@ async function handleUpdate(args, getCurrentUser) {
168
173
  : null,
169
174
  body: typeof args.body === "string" ? args.body : undefined,
170
175
  schedule: typeof args.schedule === "string" ? args.schedule : undefined,
176
+ timezone: typeof args.timezone === "string" ? args.timezone : undefined,
171
177
  model: args.model === undefined
172
178
  ? undefined
173
179
  : typeof args.model === "string"
@@ -183,6 +189,7 @@ async function handleUpdate(args, getCurrentUser) {
183
189
  triggerType: definition.meta.triggerType,
184
190
  enabled: definition.meta.enabled,
185
191
  schedule: definition.meta.schedule || null,
192
+ timezone: definition.meta.timezone ?? null,
186
193
  nextRun: definition.meta.nextRun ?? null,
187
194
  createdBy: definition.meta.createdBy,
188
195
  runAs: definition.meta.runAs,
@@ -247,8 +254,8 @@ export function createAutomationToolEntries(getCurrentUser) {
247
254
 
248
255
  - **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.
249
256
  - **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.
250
- - **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, condition, mode, domain, delegated_policy_id, model, mcpTools.
251
- - **update**: Update an existing automation's settings without changing its creator (enabled, schedule, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.
257
+ - **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, timezone, condition, mode, domain, delegated_policy_id, model, mcpTools.
258
+ - **update**: Update an existing automation's settings without changing its creator (enabled, schedule, timezone, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.
252
259
  - **delete**: Delete an automation. Always confirm with the user first. Required param: name.
253
260
  - **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,
254
261
  parameters: {
@@ -277,6 +284,10 @@ export function createAutomationToolEntries(getCurrentUser) {
277
284
  type: "string",
278
285
  description: "For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.",
279
286
  },
287
+ timezone: {
288
+ type: "string",
289
+ description: "IANA timezone the cron clock time is read in, e.g. 'America/New_York'. Optional; defaults to the user's saved scheduling timezone, then the caller's browser zone. Always pass this when the user names a time of day.",
290
+ },
280
291
  schedule: {
281
292
  type: "string",
282
293
  description: 'For schedule triggers: cron expression. Example: "0 9 * * 1-5" (9am weekdays).',
@@ -1 +1 @@
1
- {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Framework-level agent actions for the automations system.\n *\n * These are registered as native tools (not template actions) so they're\n * available in every template. The agent uses them to create, list, and\n * manage automations from chat.\n *\n * All six operations are consolidated into a single `manage-automations` tool\n * with an `action` discriminator to keep the tool registry compact.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport {\n defineAutomation,\n deleteAutomation,\n listAutomationDefinitions,\n updateAutomation,\n type AutomationScope,\n} from \"../automations/service.js\";\nimport { listEvents } from \"../event-bus/index.js\";\nimport { describeCron } from \"../jobs/cron.js\";\nimport {\n getIntegrationRequestContext,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { refreshEventSubscriptions } from \"./dispatcher.js\";\n\n/* ------------------------------------------------------------------ */\n/* Individual action handlers */\n/* ------------------------------------------------------------------ */\n\nasync function handleListEvents(): Promise<string> {\n const events = listEvents();\n if (events.length === 0) {\n return \"No events registered yet. Events are registered by integrations (mail, calendar, clips, etc.).\";\n }\n const lines = events.map((e) => {\n let schemaStr = \"\";\n try {\n const s = e.payloadSchema as any;\n if (s?._zod?.def?.shape) {\n const fields = Object.keys(s._zod.def.shape);\n schemaStr = ` Fields: ${fields.join(\", \")}`;\n }\n } catch {\n // ignore\n }\n const example = e.example\n ? `\\n Example: ${JSON.stringify(e.example)}`\n : \"\";\n return `- **${e.name}**: ${e.description}${schemaStr}${example}`;\n });\n return lines.join(\"\\n\");\n}\n\nasync function handleList(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const scope = automationScope(args.scope);\n const definitions = await listAutomationDefinitions(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n scope,\n );\n const automations = definitions\n .filter(({ meta }) => !args.domain || meta.domain === args.domain)\n .filter(({ meta }) => args.enabled_only !== \"true\" || meta.enabled)\n .map(({ name, meta, body, canUpdate }) => ({\n name,\n scope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n scheduleDescription: meta.schedule ? describeCron(meta.schedule) : null,\n condition: meta.condition ?? null,\n mode: meta.mode,\n domain: meta.domain ?? null,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: meta.nextRun ?? null,\n createdBy: meta.createdBy ?? null,\n runAs: meta.runAs ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n body,\n canUpdate,\n }));\n return JSON.stringify(automations, null, 2);\n}\n\nfunction automationScope(value: unknown): AutomationScope {\n if (value === undefined || value === null || value === \"\") return \"personal\";\n if (value === \"personal\" || value === \"organization\") return value;\n throw new Error('scope must be \"personal\" or \"organization\".');\n}\n\nfunction automationTriggerType(value: unknown): \"schedule\" | \"event\" {\n if (value === \"schedule\" || value === \"event\") return value;\n throw new Error('trigger_type must be \"schedule\" or \"event\".');\n}\n\nasync function handleDefine(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n if (args.mode === \"deterministic\") {\n return (\n \"Error: Deterministic mode was removed — it was never implemented and \" +\n \"automations that set it never fired. Create the automation without \" +\n \"mode (agentic), and describe the exact fixed steps in the automation body.\"\n );\n }\n const integration = getIntegrationRequestContext();\n try {\n const definition = await defineAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n triggerType: automationTriggerType(args.trigger_type),\n body: typeof args.body === \"string\" ? args.body : \"\",\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n event: typeof args.event === \"string\" ? args.event : undefined,\n condition:\n typeof args.condition === \"string\" ? args.condition : undefined,\n domain: typeof args.domain === \"string\" ? args.domain : undefined,\n delegatedPolicyId:\n typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n mcpTools: args.mcpTools,\n delivery: integration\n ? {\n originScopeId: integration.scopeId,\n platform: integration.incoming.platform,\n destination:\n typeof integration.incoming.platformContext.channelId ===\n \"string\"\n ? integration.incoming.platformContext.channelId\n : undefined,\n threadRef:\n typeof integration.incoming.threadRef === \"string\"\n ? integration.incoming.threadRef\n : undefined,\n tenantId: integration.incoming.tenantId,\n }\n : undefined,\n },\n );\n\n await refreshEventSubscriptions();\n return JSON.stringify({\n created: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n event: definition.meta.event ?? null,\n schedule: definition.meta.schedule || null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleUpdate(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n try {\n const definition = await updateAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n enabled:\n args.enabled === undefined\n ? undefined\n : args.enabled === true || args.enabled === \"true\",\n condition:\n args.condition === undefined\n ? undefined\n : typeof args.condition === \"string\"\n ? args.condition\n : null,\n delegatedPolicyId:\n args.delegated_policy_id === undefined\n ? undefined\n : typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : null,\n body: typeof args.body === \"string\" ? args.body : undefined,\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n model:\n args.model === undefined\n ? undefined\n : typeof args.model === \"string\"\n ? args.model\n : null,\n mcpTools: args.mcpTools,\n },\n );\n await refreshEventSubscriptions();\n return JSON.stringify({\n updated: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleDelete(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n try {\n await deleteAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n automationScope(args.scope),\n name,\n );\n await refreshEventSubscriptions();\n return JSON.stringify({ deleted: true, name });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleFireTest(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n // Dynamic import to avoid circular dependency at module load time\n const { emit } = await import(\"../event-bus/index.js\");\n\n let data: Record<string, unknown> = {};\n if (typeof args.data === \"string\" && args.data) {\n try {\n data = JSON.parse(args.data);\n } catch {\n return \"Error: invalid JSON in data parameter.\";\n }\n }\n\n // Scope the test event to the current user so only their automations fire,\n // not automations owned by other users in the same process.\n const owner = getCurrentUser();\n emit(\"test.event.fired\", { data }, { owner });\n return `Test event fired with payload: ${JSON.stringify({ data })}. Any automations subscribed to \"test.event.fired\" will be evaluated.`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Consolidated tool entry */\n/* ------------------------------------------------------------------ */\n\nconst VALID_ACTIONS = [\n \"list-events\",\n \"list\",\n \"define\",\n \"update\",\n \"delete\",\n \"fire-test\",\n] as const;\n\nexport function createAutomationToolEntries(\n getCurrentUser: () => string,\n): Record<string, ActionEntry> {\n return {\n \"manage-automations\": {\n tool: {\n description: `Manage automations (event-triggered and scheduled tasks). Use the \"action\" parameter to choose an operation:\n\n- **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.\n- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.\n- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, condition, mode, domain, delegated_policy_id, model, mcpTools.\n- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.\n- **delete**: Delete an automation. Always confirm with the user first. Required param: name.\n- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,\n parameters: {\n type: \"object\" as const,\n properties: {\n action: {\n type: \"string\",\n description:\n \"The operation to perform: list-events, list, define, update, delete, or fire-test.\",\n enum: [...VALID_ACTIONS],\n },\n name: {\n type: \"string\",\n description:\n \"Slug name for the automation (lowercase, hyphens). Used by define, update, and delete.\",\n },\n scope: {\n type: \"string\",\n description:\n \"Personal or organization scope. Organization automations are visible to the active organization but always execute as their creator.\",\n enum: [\"personal\", \"organization\"],\n },\n trigger_type: {\n type: \"string\",\n description: '\"event\" or \"schedule\". Required for define.',\n enum: [\"event\", \"schedule\"],\n },\n event: {\n type: \"string\",\n description:\n \"For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.\",\n },\n schedule: {\n type: \"string\",\n description:\n 'For schedule triggers: cron expression. Example: \"0 9 * * 1-5\" (9am weekdays).',\n },\n condition: {\n type: \"string\",\n description:\n 'Natural-language condition. Example: \"attendee email ends with @builder.io\". Leave empty for unconditional. Used by define and update.',\n },\n mode: {\n type: \"string\",\n description:\n '\"agentic\" (full agent loop, can use tools) — the only supported mode. Used by define.',\n enum: [\"agentic\"],\n },\n domain: {\n type: \"string\",\n description:\n \"Domain tag for grouping (mail, calendar, clips, etc.). Used by define and list.\",\n },\n model: {\n type: \"string\",\n description:\n \"Optional model id for this automation. The default model is used when omitted.\",\n },\n mcpTools: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n 'Optional explicit MCP capabilities. Use exact advertised tool names, for example [\"mcp__meeting-notes__list_meetings\"]. Credentials stay in the connector.',\n },\n delegated_policy_id: {\n type: \"string\",\n description:\n \"Optional app-owned stored policy id. It is passed by the trusted trigger runtime, never as action input. Only use an id documented by the app.\",\n },\n body: {\n type: \"string\",\n description:\n \"The natural-language instructions for what to do when the automation fires. This becomes the agent's prompt in agentic mode. Used by define and update.\",\n },\n enabled: {\n type: \"string\",\n description:\n '\"true\" or \"false\" to enable/disable. Used by update.',\n },\n enabled_only: {\n type: \"string\",\n description:\n '\"true\" to show only enabled automations. Used by list.',\n },\n data: {\n type: \"string\",\n description:\n 'JSON data to include as the test event payload. Used by fire-test. Example: \\'{\"email\": \"test@example.com\"}\\'.',\n },\n },\n required: [\"action\"],\n },\n },\n planMode: {\n effect: (args) =>\n args.action === \"list\" || args.action === \"list-events\"\n ? \"read\"\n : \"write\",\n allowedValues: { action: [\"list-events\", \"list\"] },\n description: \"Plan mode allows listing automations and event types.\",\n },\n run: async (args: Record<string, unknown>) => {\n const action = args.action;\n\n switch (action) {\n case \"list-events\":\n return handleListEvents();\n case \"list\":\n return handleList(args, getCurrentUser);\n case \"define\":\n return handleDefine(args, getCurrentUser);\n case \"update\":\n return handleUpdate(args, getCurrentUser);\n case \"delete\":\n return handleDelete(args, getCurrentUser);\n case \"fire-test\":\n return handleFireTest(args, getCurrentUser);\n default:\n return `Error: unknown action \"${action}\". Valid actions: ${VALID_ACTIONS.join(\", \")}.`;\n }\n },\n },\n };\n}\n"]}
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/triggers/actions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Framework-level agent actions for the automations system.\n *\n * These are registered as native tools (not template actions) so they're\n * available in every template. The agent uses them to create, list, and\n * manage automations from chat.\n *\n * All six operations are consolidated into a single `manage-automations` tool\n * with an `action` discriminator to keep the tool registry compact.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport {\n defineAutomation,\n deleteAutomation,\n listAutomationDefinitions,\n updateAutomation,\n type AutomationScope,\n} from \"../automations/service.js\";\nimport { listEvents } from \"../event-bus/index.js\";\nimport { describeCron, effectiveTimezone } from \"../jobs/cron.js\";\nimport {\n getIntegrationRequestContext,\n getRequestOrgId,\n} from \"../server/request-context.js\";\nimport { refreshEventSubscriptions } from \"./dispatcher.js\";\n\n/* ------------------------------------------------------------------ */\n/* Individual action handlers */\n/* ------------------------------------------------------------------ */\n\nasync function handleListEvents(): Promise<string> {\n const events = listEvents();\n if (events.length === 0) {\n return \"No events registered yet. Events are registered by integrations (mail, calendar, clips, etc.).\";\n }\n const lines = events.map((e) => {\n let schemaStr = \"\";\n try {\n const s = e.payloadSchema as any;\n if (s?._zod?.def?.shape) {\n const fields = Object.keys(s._zod.def.shape);\n schemaStr = ` Fields: ${fields.join(\", \")}`;\n }\n } catch {\n // ignore\n }\n const example = e.example\n ? `\\n Example: ${JSON.stringify(e.example)}`\n : \"\";\n return `- **${e.name}**: ${e.description}${schemaStr}${example}`;\n });\n return lines.join(\"\\n\");\n}\n\nasync function handleList(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const scope = automationScope(args.scope);\n const definitions = await listAutomationDefinitions(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n scope,\n );\n const automations = definitions\n .filter(({ meta }) => !args.domain || meta.domain === args.domain)\n .filter(({ meta }) => args.enabled_only !== \"true\" || meta.enabled)\n .map(({ name, meta, body, canUpdate }) => ({\n name,\n scope,\n triggerType: meta.triggerType,\n event: meta.event ?? null,\n schedule: meta.schedule || null,\n timezone: meta.timezone ? effectiveTimezone(meta.timezone) : null,\n scheduleDescription: meta.schedule\n ? describeCron(meta.schedule, effectiveTimezone(meta.timezone))\n : null,\n condition: meta.condition ?? null,\n mode: meta.mode,\n domain: meta.domain ?? null,\n enabled: meta.enabled,\n lastRun: meta.lastRun ?? null,\n lastStatus: meta.lastStatus ?? null,\n lastError: meta.lastError ?? null,\n nextRun: meta.nextRun ?? null,\n createdBy: meta.createdBy ?? null,\n runAs: meta.runAs ?? null,\n model: meta.model ?? null,\n mcpTools: meta.mcpTools ?? [],\n originScopeId: meta.originScopeId ?? null,\n deliveryPlatform: meta.deliveryPlatform ?? null,\n deliveryDestination: meta.deliveryDestination ?? null,\n deliveryThreadRef: meta.deliveryThreadRef ?? null,\n deliveryTenantId: meta.deliveryTenantId ?? null,\n body,\n canUpdate,\n }));\n return JSON.stringify(automations, null, 2);\n}\n\nfunction automationScope(value: unknown): AutomationScope {\n if (value === undefined || value === null || value === \"\") return \"personal\";\n if (value === \"personal\" || value === \"organization\") return value;\n throw new Error('scope must be \"personal\" or \"organization\".');\n}\n\nfunction automationTriggerType(value: unknown): \"schedule\" | \"event\" {\n if (value === \"schedule\" || value === \"event\") return value;\n throw new Error('trigger_type must be \"schedule\" or \"event\".');\n}\n\nasync function handleDefine(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n if (args.mode === \"deterministic\") {\n return (\n \"Error: Deterministic mode was removed — it was never implemented and \" +\n \"automations that set it never fired. Create the automation without \" +\n \"mode (agentic), and describe the exact fixed steps in the automation body.\"\n );\n }\n const integration = getIntegrationRequestContext();\n try {\n const definition = await defineAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n triggerType: automationTriggerType(args.trigger_type),\n body: typeof args.body === \"string\" ? args.body : \"\",\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n timezone: typeof args.timezone === \"string\" ? args.timezone : undefined,\n event: typeof args.event === \"string\" ? args.event : undefined,\n condition:\n typeof args.condition === \"string\" ? args.condition : undefined,\n domain: typeof args.domain === \"string\" ? args.domain : undefined,\n delegatedPolicyId:\n typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : undefined,\n model: typeof args.model === \"string\" ? args.model : undefined,\n mcpTools: args.mcpTools,\n delivery: integration\n ? {\n originScopeId: integration.scopeId,\n platform: integration.incoming.platform,\n destination:\n typeof integration.incoming.platformContext.channelId ===\n \"string\"\n ? integration.incoming.platformContext.channelId\n : undefined,\n threadRef:\n typeof integration.incoming.threadRef === \"string\"\n ? integration.incoming.threadRef\n : undefined,\n tenantId: integration.incoming.tenantId,\n }\n : undefined,\n },\n );\n\n await refreshEventSubscriptions();\n return JSON.stringify({\n created: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n event: definition.meta.event ?? null,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleUpdate(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n try {\n const definition = await updateAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n {\n name: typeof args.name === \"string\" ? args.name : \"\",\n scope: automationScope(args.scope),\n enabled:\n args.enabled === undefined\n ? undefined\n : args.enabled === true || args.enabled === \"true\",\n condition:\n args.condition === undefined\n ? undefined\n : typeof args.condition === \"string\"\n ? args.condition\n : null,\n delegatedPolicyId:\n args.delegated_policy_id === undefined\n ? undefined\n : typeof args.delegated_policy_id === \"string\"\n ? args.delegated_policy_id\n : null,\n body: typeof args.body === \"string\" ? args.body : undefined,\n schedule: typeof args.schedule === \"string\" ? args.schedule : undefined,\n timezone: typeof args.timezone === \"string\" ? args.timezone : undefined,\n model:\n args.model === undefined\n ? undefined\n : typeof args.model === \"string\"\n ? args.model\n : null,\n mcpTools: args.mcpTools,\n },\n );\n await refreshEventSubscriptions();\n return JSON.stringify({\n updated: true,\n name: definition.name,\n scope: definition.scope,\n triggerType: definition.meta.triggerType,\n enabled: definition.meta.enabled,\n schedule: definition.meta.schedule || null,\n timezone: definition.meta.timezone ?? null,\n nextRun: definition.meta.nextRun ?? null,\n createdBy: definition.meta.createdBy,\n runAs: definition.meta.runAs,\n model: definition.meta.model ?? null,\n mcpTools: definition.meta.mcpTools ?? [],\n originScopeId: definition.meta.originScopeId ?? null,\n deliveryPlatform: definition.meta.deliveryPlatform ?? null,\n deliveryDestination: definition.meta.deliveryDestination ?? null,\n deliveryThreadRef: definition.meta.deliveryThreadRef ?? null,\n deliveryTenantId: definition.meta.deliveryTenantId ?? null,\n });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleDelete(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n const name = typeof args.name === \"string\" ? args.name : \"\";\n try {\n await deleteAutomation(\n { userEmail: getCurrentUser(), orgId: getRequestOrgId() },\n automationScope(args.scope),\n name,\n );\n await refreshEventSubscriptions();\n return JSON.stringify({ deleted: true, name });\n } catch (error) {\n return `Error: ${(error as Error).message}`;\n }\n}\n\nasync function handleFireTest(\n args: Record<string, unknown>,\n getCurrentUser: () => string,\n): Promise<string> {\n // Dynamic import to avoid circular dependency at module load time\n const { emit } = await import(\"../event-bus/index.js\");\n\n let data: Record<string, unknown> = {};\n if (typeof args.data === \"string\" && args.data) {\n try {\n data = JSON.parse(args.data);\n } catch {\n return \"Error: invalid JSON in data parameter.\";\n }\n }\n\n // Scope the test event to the current user so only their automations fire,\n // not automations owned by other users in the same process.\n const owner = getCurrentUser();\n emit(\"test.event.fired\", { data }, { owner });\n return `Test event fired with payload: ${JSON.stringify({ data })}. Any automations subscribed to \"test.event.fired\" will be evaluated.`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Consolidated tool entry */\n/* ------------------------------------------------------------------ */\n\nconst VALID_ACTIONS = [\n \"list-events\",\n \"list\",\n \"define\",\n \"update\",\n \"delete\",\n \"fire-test\",\n] as const;\n\nexport function createAutomationToolEntries(\n getCurrentUser: () => string,\n): Record<string, ActionEntry> {\n return {\n \"manage-automations\": {\n tool: {\n description: `Manage automations (event-triggered and scheduled tasks). Use the \"action\" parameter to choose an operation:\n\n- **list-events**: List all registered event types that automations can subscribe to. Returns event names, descriptions, and payload schemas. Call this BEFORE defining an automation to discover available events.\n- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.\n- **define**: Create a new automation. IMPORTANT: Always confirm with the user before calling — show them a summary of what will be created. Required params: name, trigger_type, body. Optional: scope, event, schedule, timezone, condition, mode, domain, delegated_policy_id, model, mcpTools.\n- **update**: Update an existing automation's settings without changing its creator (enabled, schedule, timezone, condition, body, policy, model, MCP allowlist). Required param: name. Use the same scope it was created in.\n- **delete**: Delete an automation. Always confirm with the user first. Required param: name.\n- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,\n parameters: {\n type: \"object\" as const,\n properties: {\n action: {\n type: \"string\",\n description:\n \"The operation to perform: list-events, list, define, update, delete, or fire-test.\",\n enum: [...VALID_ACTIONS],\n },\n name: {\n type: \"string\",\n description:\n \"Slug name for the automation (lowercase, hyphens). Used by define, update, and delete.\",\n },\n scope: {\n type: \"string\",\n description:\n \"Personal or organization scope. Organization automations are visible to the active organization but always execute as their creator.\",\n enum: [\"personal\", \"organization\"],\n },\n trigger_type: {\n type: \"string\",\n description: '\"event\" or \"schedule\". Required for define.',\n enum: [\"event\", \"schedule\"],\n },\n event: {\n type: \"string\",\n description:\n \"For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.\",\n },\n timezone: {\n type: \"string\",\n description:\n \"IANA timezone the cron clock time is read in, e.g. 'America/New_York'. Optional; defaults to the user's saved scheduling timezone, then the caller's browser zone. Always pass this when the user names a time of day.\",\n },\n schedule: {\n type: \"string\",\n description:\n 'For schedule triggers: cron expression. Example: \"0 9 * * 1-5\" (9am weekdays).',\n },\n condition: {\n type: \"string\",\n description:\n 'Natural-language condition. Example: \"attendee email ends with @builder.io\". Leave empty for unconditional. Used by define and update.',\n },\n mode: {\n type: \"string\",\n description:\n '\"agentic\" (full agent loop, can use tools) — the only supported mode. Used by define.',\n enum: [\"agentic\"],\n },\n domain: {\n type: \"string\",\n description:\n \"Domain tag for grouping (mail, calendar, clips, etc.). Used by define and list.\",\n },\n model: {\n type: \"string\",\n description:\n \"Optional model id for this automation. The default model is used when omitted.\",\n },\n mcpTools: {\n type: \"array\",\n items: { type: \"string\" },\n description:\n 'Optional explicit MCP capabilities. Use exact advertised tool names, for example [\"mcp__meeting-notes__list_meetings\"]. Credentials stay in the connector.',\n },\n delegated_policy_id: {\n type: \"string\",\n description:\n \"Optional app-owned stored policy id. It is passed by the trusted trigger runtime, never as action input. Only use an id documented by the app.\",\n },\n body: {\n type: \"string\",\n description:\n \"The natural-language instructions for what to do when the automation fires. This becomes the agent's prompt in agentic mode. Used by define and update.\",\n },\n enabled: {\n type: \"string\",\n description:\n '\"true\" or \"false\" to enable/disable. Used by update.',\n },\n enabled_only: {\n type: \"string\",\n description:\n '\"true\" to show only enabled automations. Used by list.',\n },\n data: {\n type: \"string\",\n description:\n 'JSON data to include as the test event payload. Used by fire-test. Example: \\'{\"email\": \"test@example.com\"}\\'.',\n },\n },\n required: [\"action\"],\n },\n },\n planMode: {\n effect: (args) =>\n args.action === \"list\" || args.action === \"list-events\"\n ? \"read\"\n : \"write\",\n allowedValues: { action: [\"list-events\", \"list\"] },\n description: \"Plan mode allows listing automations and event types.\",\n },\n run: async (args: Record<string, unknown>) => {\n const action = args.action;\n\n switch (action) {\n case \"list-events\":\n return handleListEvents();\n case \"list\":\n return handleList(args, getCurrentUser);\n case \"define\":\n return handleDefine(args, getCurrentUser);\n case \"update\":\n return handleUpdate(args, getCurrentUser);\n case \"delete\":\n return handleDelete(args, getCurrentUser);\n case \"fire-test\":\n return handleFireTest(args, getCurrentUser);\n default:\n return `Error: unknown action \"${action}\". Valid actions: ${VALID_ACTIONS.join(\", \")}.`;\n }\n },\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,yCAAyC,CAAC;AAWjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAID,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CACpB,UAAU,CAAC,EAAE,2BAA2B,KACrC,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3B;AAgBD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgC/D"}
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,EAGL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,yCAAyC,CAAC;AAWjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IACxD,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,CAUA;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,kBAAkB,EACxB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAID,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,CACpB,UAAU,CAAC,EAAE,2BAA2B,KACrC,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3B;AAyCD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAgC/D"}
@@ -39,6 +39,21 @@ const _eventSubscriptions = new Map();
39
39
  // deployments; multi-instance would need a conditional DB update.
40
40
  const _dispatchingTriggers = new Set();
41
41
  let _deps = null;
42
+ /**
43
+ * Record that a tick evaluated this trigger and declined to dispatch it.
44
+ * `lastRun` stays untouched — nothing ran — and an unchanged outcome is not
45
+ * re-persisted, so a permanently blocked trigger neither reports phantom runs
46
+ * nor rewrites its resource on every matching event.
47
+ */
48
+ async function recordTriggerSkip(resource, meta, body, status, reason) {
49
+ const unchanged = meta.lastStatus === status && meta.lastError === reason;
50
+ meta.lastCheck = new Date().toISOString();
51
+ meta.lastStatus = status;
52
+ meta.lastError = reason;
53
+ if (unchanged)
54
+ return;
55
+ await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
56
+ }
42
57
  /**
43
58
  * Initialize the trigger dispatcher. Call once at server startup.
44
59
  * Loads all event-triggered jobs and subscribes to their events.
@@ -116,18 +131,11 @@ async function handleEvent(eventName, payload, eventMeta) {
116
131
  resolved = await resolveAutomationExecutionIdentity(resource.owner, meta);
117
132
  }
118
133
  catch {
119
- meta.lastRun = new Date().toISOString();
120
- meta.lastStatus = "skipped";
121
- meta.lastError =
122
- "Could not verify the automation execution identity.";
123
- await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
134
+ await recordTriggerSkip(resource, meta, body, "skipped", "Could not verify the automation execution identity.");
124
135
  continue;
125
136
  }
126
137
  if (!resolved.ok) {
127
- meta.lastRun = new Date().toISOString();
128
- meta.lastStatus = "skipped";
129
- meta.lastError = resolved.reason;
130
- await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
138
+ await recordTriggerSkip(resource, meta, body, "skipped", resolved.reason);
131
139
  continue;
132
140
  }
133
141
  if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {
@@ -140,20 +148,14 @@ async function handleEvent(eventName, payload, eventMeta) {
140
148
  const userApiKey = await getOwnerActiveApiKey(owner);
141
149
  const apiKey = userApiKey || _deps.apiKey;
142
150
  if (!apiKey) {
143
- meta.lastRun = new Date().toISOString();
144
- meta.lastStatus = "error";
145
- meta.lastError = "No API key is available for this automation";
146
- await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
151
+ await recordTriggerSkip(resource, meta, body, "error", "No API key is available for this automation");
147
152
  console.warn(`[triggers] ${meta.lastError}: "${resource.path}"`);
148
153
  continue;
149
154
  }
150
155
  // Evaluate condition
151
156
  const matches = await evaluateCondition(meta.condition, payload, apiKey);
152
157
  if (!matches) {
153
- meta.lastRun = new Date().toISOString();
154
- meta.lastStatus = "skipped";
155
- meta.lastError = undefined;
156
- await resourcePut(resource.owner, resource.path, buildTriggerContent(meta, body));
158
+ await recordTriggerSkip(resource, meta, body, "skipped", undefined);
157
159
  continue;
158
160
  }
159
161
  // Dispatch. Guard against concurrent duplicate dispatch of the same
@@ -1 +1 @@
1
- {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Trigger dispatcher — bridges the event bus to the automation system.\n *\n * On startup, loads all event-triggered jobs from the resources store,\n * subscribes to their events, and dispatches them (condition eval → agent\n * loop) when matching events fire.\n */\n\nimport { getOwnerActiveApiKey } from \"../agent/production-agent.js\";\nimport {\n automationMatchesEventOwner,\n resolveAutomationExecutionIdentity,\n type AutomationExecutionIdentity,\n} from \"../automations/service.js\";\nimport { subscribe, unsubscribe } from \"../event-bus/index.js\";\nimport type { EventMeta } from \"../event-bus/types.js\";\nimport {\n isBackgroundAutomationRunActive,\n runBackgroundAutomation,\n type BackgroundAutomationContext,\n type BackgroundAutomationDeps,\n} from \"../jobs/background-automation-runner.js\";\nimport {\n buildJobResourceContent,\n parseJobResource,\n} from \"../jobs/frontmatter.js\";\nimport {\n resourceListAllOwners,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\nimport { evaluateCondition } from \"./condition-evaluator.js\";\nimport type { TriggerFrontmatter } from \"./types.js\";\n\nexport function parseTriggerFrontmatter(content: string): {\n meta: TriggerFrontmatter;\n body: string;\n} {\n const { meta, body } = parseJobResource(content);\n return {\n meta: {\n ...meta,\n triggerType: meta.triggerType ?? \"schedule\",\n mode: meta.mode ?? \"agentic\",\n },\n body,\n };\n}\n\nexport function buildTriggerContent(\n meta: TriggerFrontmatter,\n body: string,\n): string {\n return buildJobResourceContent(meta, body);\n}\n\n// ─── Dispatcher deps (same pattern as SchedulerDeps) ────────────────────────\n\nexport interface TriggerDispatcherDeps extends BackgroundAutomationDeps {\n /**\n * Tool names to expose on the FIRST engine request for a trigger run. See\n * `SchedulerDeps.getInitialToolNames` (`jobs/scheduler.ts`) — same\n * semantics. Omit to keep the full `getActions()` set visible up front\n * (current behavior).\n */\n getInitialToolNames?: (\n automation?: BackgroundAutomationContext,\n ) => string[] | undefined;\n}\n\n// Track active subscriptions (eventName -> subscription id) to avoid\n// double-subscribing AND so subscriptions for events that no longer have any\n// enabled trigger can be torn down — otherwise deleted/disabled triggers leave\n// phantom bus listeners that fire handleEvent forever.\nconst _eventSubscriptions = new Map<string, string>();\n// In-flight agentic dispatches keyed by `${owner}:${path}`. Guards against the\n// check-then-write TOCTOU window in handleEvent: two near-simultaneous fires of\n// the same event both pass the `lastStatus !== \"running\"` check (which has\n// several awaits before the DB is marked running) and would otherwise launch\n// two concurrent agent runs for one trigger. Sufficient for single-process\n// deployments; multi-instance would need a conditional DB update.\nconst _dispatchingTriggers = new Set<string>();\nlet _deps: TriggerDispatcherDeps | null = null;\n\n/**\n * Initialize the trigger dispatcher. Call once at server startup.\n * Loads all event-triggered jobs and subscribes to their events.\n */\nexport async function initTriggerDispatcher(\n deps: TriggerDispatcherDeps,\n): Promise<void> {\n _deps = deps;\n await refreshEventSubscriptions();\n}\n\n/**\n * Refresh event subscriptions from the resource store.\n * Call after creating/updating triggers.\n */\nexport async function refreshEventSubscriptions(): Promise<void> {\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const eventNames = new Set<string>();\n\n for (const resource of jobResources) {\n if (!resource.path.endsWith(\".md\")) continue;\n const { meta } = parseTriggerFrontmatter(resource.content);\n if (meta.triggerType === \"event\" && meta.event && meta.enabled) {\n eventNames.add(meta.event);\n }\n }\n\n // Tear down subscriptions whose event no longer has any enabled trigger.\n for (const [eventName, subId] of [..._eventSubscriptions]) {\n if (!eventNames.has(eventName)) {\n unsubscribe(subId);\n _eventSubscriptions.delete(eventName);\n }\n }\n\n for (const eventName of eventNames) {\n if (!_eventSubscriptions.has(eventName)) {\n const subId = subscribe(eventName, (payload, eventMeta) =>\n handleEvent(eventName, payload, eventMeta),\n );\n _eventSubscriptions.set(eventName, subId);\n }\n }\n } catch (err) {\n console.error(\"[triggers] Failed to refresh event subscriptions:\", err);\n }\n}\n\nasync function handleEvent(\n eventName: string,\n payload: unknown,\n eventMeta: EventMeta,\n): Promise<void> {\n if (!_deps) return;\n\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const matchingTriggers = jobResources.filter((r) => {\n if (!r.path.endsWith(\".md\")) return false;\n const { meta } = parseTriggerFrontmatter(r.content);\n return (\n meta.triggerType === \"event\" &&\n meta.event === eventName &&\n meta.enabled &&\n !isBackgroundAutomationRunActive(meta)\n );\n });\n\n for (const resource of matchingTriggers) {\n const { meta, body } = parseTriggerFrontmatter(resource.content);\n if (!body.trim()) continue;\n\n let identity: AutomationExecutionIdentity;\n if (resource.owner === \"__shared__\") {\n // Compatibility for old workspace-wide event resources. New personal\n // and organization automations always require an event owner.\n const userEmail = meta.createdBy || resource.owner;\n identity = {\n userEmail,\n orgId: meta.orgId,\n eventOwner: userEmail.toLowerCase(),\n };\n } else {\n let resolved;\n try {\n resolved = await resolveAutomationExecutionIdentity(\n resource.owner,\n meta,\n );\n } catch {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError =\n \"Could not verify the automation execution identity.\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n if (!resolved.ok) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError = resolved.reason;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {\n continue;\n }\n identity = resolved.identity;\n }\n\n // Resolve API key for condition evaluation\n const owner = identity.userEmail;\n const userApiKey = await getOwnerActiveApiKey(owner);\n const apiKey = userApiKey || _deps.apiKey;\n if (!apiKey) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"error\";\n meta.lastError = \"No API key is available for this automation\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.warn(`[triggers] ${meta.lastError}: \"${resource.path}\"`);\n continue;\n }\n\n // Evaluate condition\n const matches = await evaluateCondition(meta.condition, payload, apiKey);\n if (!matches) {\n meta.lastRun = new Date().toISOString();\n meta.lastStatus = \"skipped\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n continue;\n }\n\n // Dispatch. Guard against concurrent duplicate dispatch of the same\n // trigger (TOCTOU on lastStatus) with an in-process lock keyed on the\n // trigger's identity.\n const dispatchKey = `${resource.owner}:${resource.path}`;\n if (_dispatchingTriggers.has(dispatchKey)) continue;\n if (meta.mode === \"agentic\") {\n _dispatchingTriggers.add(dispatchKey);\n try {\n await dispatchAgentic(\n resource,\n meta,\n body,\n payload,\n eventMeta,\n identity,\n );\n } finally {\n _dispatchingTriggers.delete(dispatchKey);\n }\n } else {\n console.warn(\n `[triggers] Deterministic mode not yet implemented for \"${resource.path}\" — skipping`,\n );\n }\n }\n } catch (err) {\n console.error(`[triggers] Error handling event \"${eventName}\":`, err);\n }\n}\n\nasync function dispatchAgentic(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n payload: unknown,\n eventMeta: EventMeta,\n identity: AutomationExecutionIdentity,\n): Promise<void> {\n if (!_deps) return;\n\n const triggerName = resource.path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n const now = new Date();\n\n const jobUserEmail = identity.userEmail;\n const jobOrgId = identity.orgId;\n\n // Mark as running\n meta.lastRun = now.toISOString();\n meta.lastStatus = \"running\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n\n let payloadStr: string;\n try {\n payloadStr = JSON.stringify(payload, null, 2);\n } catch {\n payloadStr = String(payload);\n }\n\n const automation: BackgroundAutomationContext = {\n name: triggerName,\n meta,\n body,\n resource,\n };\n const requestContext =\n meta.originScopeId && meta.deliveryPlatform && meta.deliveryDestination\n ? {\n isIntegrationCaller: true as const,\n integration: {\n taskId: `automation:${triggerName}:${eventMeta.eventId}`,\n scopeId: meta.originScopeId,\n principalType: \"service\" as const,\n incoming: {\n platform: meta.deliveryPlatform,\n externalThreadId: `${meta.deliveryTenantId || \"unknown\"}:${meta.deliveryDestination}:${meta.deliveryThreadRef || \"root\"}`,\n text: \"\",\n tenantId: meta.deliveryTenantId,\n integrationScopeId: meta.originScopeId,\n platformContext: {\n channelId: meta.deliveryDestination,\n threadTs: meta.deliveryThreadRef,\n teamId: meta.deliveryTenantId,\n },\n threadRef: meta.deliveryThreadRef,\n timestamp: now.getTime(),\n },\n },\n }\n : undefined;\n\n try {\n await runBackgroundAutomation(\n {\n automation,\n ownerEmail: jobUserEmail,\n orgId: jobOrgId,\n prompt: `[Automation Trigger: ${triggerName}]\nEvent: ${meta.event}\nEvent ID: ${eventMeta.eventId}\nFired at: ${eventMeta.emittedAt}\n\nEvent payload:\n${payloadStr}\n\nExecute the following automation instructions:\n\n${body}`,\n threadTitle: `Trigger: ${triggerName} — ${now.toLocaleDateString()}`,\n runIdPrefix: `automation-${triggerName}`,\n usageLabel: `automation:${triggerName}`,\n usageRefId: eventMeta.eventId,\n requestContext,\n actionCaller: \"automation\",\n actionAutomation: {\n triggerId: resource.id,\n triggerName,\n policyId: meta.delegatedPolicyId,\n },\n },\n _deps,\n );\n\n meta.lastStatus = \"success\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.log(`[triggers] \"${triggerName}\" completed successfully`);\n } catch (err) {\n meta.lastStatus = \"error\";\n meta.lastError =\n err instanceof Error ? err.message.slice(0, 200) : \"Unknown error\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.error(`[triggers] \"${triggerName}\" failed:`, meta.lastError);\n }\n}\n"]}
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/triggers/dispatcher.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Trigger dispatcher — bridges the event bus to the automation system.\n *\n * On startup, loads all event-triggered jobs from the resources store,\n * subscribes to their events, and dispatches them (condition eval → agent\n * loop) when matching events fire.\n */\n\nimport { getOwnerActiveApiKey } from \"../agent/production-agent.js\";\nimport {\n automationMatchesEventOwner,\n resolveAutomationExecutionIdentity,\n type AutomationExecutionIdentity,\n} from \"../automations/service.js\";\nimport { subscribe, unsubscribe } from \"../event-bus/index.js\";\nimport type { EventMeta } from \"../event-bus/types.js\";\nimport {\n isBackgroundAutomationRunActive,\n runBackgroundAutomation,\n type BackgroundAutomationContext,\n type BackgroundAutomationDeps,\n} from \"../jobs/background-automation-runner.js\";\nimport {\n buildJobResourceContent,\n parseJobResource,\n} from \"../jobs/frontmatter.js\";\nimport {\n resourceListAllOwners,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\nimport { evaluateCondition } from \"./condition-evaluator.js\";\nimport type { TriggerFrontmatter } from \"./types.js\";\n\nexport function parseTriggerFrontmatter(content: string): {\n meta: TriggerFrontmatter;\n body: string;\n} {\n const { meta, body } = parseJobResource(content);\n return {\n meta: {\n ...meta,\n triggerType: meta.triggerType ?? \"schedule\",\n mode: meta.mode ?? \"agentic\",\n },\n body,\n };\n}\n\nexport function buildTriggerContent(\n meta: TriggerFrontmatter,\n body: string,\n): string {\n return buildJobResourceContent(meta, body);\n}\n\n// ─── Dispatcher deps (same pattern as SchedulerDeps) ────────────────────────\n\nexport interface TriggerDispatcherDeps extends BackgroundAutomationDeps {\n /**\n * Tool names to expose on the FIRST engine request for a trigger run. See\n * `SchedulerDeps.getInitialToolNames` (`jobs/scheduler.ts`) — same\n * semantics. Omit to keep the full `getActions()` set visible up front\n * (current behavior).\n */\n getInitialToolNames?: (\n automation?: BackgroundAutomationContext,\n ) => string[] | undefined;\n}\n\n// Track active subscriptions (eventName -> subscription id) to avoid\n// double-subscribing AND so subscriptions for events that no longer have any\n// enabled trigger can be torn down — otherwise deleted/disabled triggers leave\n// phantom bus listeners that fire handleEvent forever.\nconst _eventSubscriptions = new Map<string, string>();\n// In-flight agentic dispatches keyed by `${owner}:${path}`. Guards against the\n// check-then-write TOCTOU window in handleEvent: two near-simultaneous fires of\n// the same event both pass the `lastStatus !== \"running\"` check (which has\n// several awaits before the DB is marked running) and would otherwise launch\n// two concurrent agent runs for one trigger. Sufficient for single-process\n// deployments; multi-instance would need a conditional DB update.\nconst _dispatchingTriggers = new Set<string>();\nlet _deps: TriggerDispatcherDeps | null = null;\n\n/**\n * Record that a tick evaluated this trigger and declined to dispatch it.\n * `lastRun` stays untouched — nothing ran — and an unchanged outcome is not\n * re-persisted, so a permanently blocked trigger neither reports phantom runs\n * nor rewrites its resource on every matching event.\n */\nasync function recordTriggerSkip(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n status: \"skipped\" | \"error\",\n reason: string | undefined,\n): Promise<void> {\n const unchanged = meta.lastStatus === status && meta.lastError === reason;\n meta.lastCheck = new Date().toISOString();\n meta.lastStatus = status;\n meta.lastError = reason;\n if (unchanged) return;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n}\n\n/**\n * Initialize the trigger dispatcher. Call once at server startup.\n * Loads all event-triggered jobs and subscribes to their events.\n */\nexport async function initTriggerDispatcher(\n deps: TriggerDispatcherDeps,\n): Promise<void> {\n _deps = deps;\n await refreshEventSubscriptions();\n}\n\n/**\n * Refresh event subscriptions from the resource store.\n * Call after creating/updating triggers.\n */\nexport async function refreshEventSubscriptions(): Promise<void> {\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const eventNames = new Set<string>();\n\n for (const resource of jobResources) {\n if (!resource.path.endsWith(\".md\")) continue;\n const { meta } = parseTriggerFrontmatter(resource.content);\n if (meta.triggerType === \"event\" && meta.event && meta.enabled) {\n eventNames.add(meta.event);\n }\n }\n\n // Tear down subscriptions whose event no longer has any enabled trigger.\n for (const [eventName, subId] of [..._eventSubscriptions]) {\n if (!eventNames.has(eventName)) {\n unsubscribe(subId);\n _eventSubscriptions.delete(eventName);\n }\n }\n\n for (const eventName of eventNames) {\n if (!_eventSubscriptions.has(eventName)) {\n const subId = subscribe(eventName, (payload, eventMeta) =>\n handleEvent(eventName, payload, eventMeta),\n );\n _eventSubscriptions.set(eventName, subId);\n }\n }\n } catch (err) {\n console.error(\"[triggers] Failed to refresh event subscriptions:\", err);\n }\n}\n\nasync function handleEvent(\n eventName: string,\n payload: unknown,\n eventMeta: EventMeta,\n): Promise<void> {\n if (!_deps) return;\n\n try {\n const jobResources = await resourceListAllOwners(\"jobs/\");\n const matchingTriggers = jobResources.filter((r) => {\n if (!r.path.endsWith(\".md\")) return false;\n const { meta } = parseTriggerFrontmatter(r.content);\n return (\n meta.triggerType === \"event\" &&\n meta.event === eventName &&\n meta.enabled &&\n !isBackgroundAutomationRunActive(meta)\n );\n });\n\n for (const resource of matchingTriggers) {\n const { meta, body } = parseTriggerFrontmatter(resource.content);\n if (!body.trim()) continue;\n\n let identity: AutomationExecutionIdentity;\n if (resource.owner === \"__shared__\") {\n // Compatibility for old workspace-wide event resources. New personal\n // and organization automations always require an event owner.\n const userEmail = meta.createdBy || resource.owner;\n identity = {\n userEmail,\n orgId: meta.orgId,\n eventOwner: userEmail.toLowerCase(),\n };\n } else {\n let resolved;\n try {\n resolved = await resolveAutomationExecutionIdentity(\n resource.owner,\n meta,\n );\n } catch {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"skipped\",\n \"Could not verify the automation execution identity.\",\n );\n continue;\n }\n if (!resolved.ok) {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"skipped\",\n resolved.reason,\n );\n continue;\n }\n if (!automationMatchesEventOwner(resolved.identity, eventMeta.owner)) {\n continue;\n }\n identity = resolved.identity;\n }\n\n // Resolve API key for condition evaluation\n const owner = identity.userEmail;\n const userApiKey = await getOwnerActiveApiKey(owner);\n const apiKey = userApiKey || _deps.apiKey;\n if (!apiKey) {\n await recordTriggerSkip(\n resource,\n meta,\n body,\n \"error\",\n \"No API key is available for this automation\",\n );\n console.warn(`[triggers] ${meta.lastError}: \"${resource.path}\"`);\n continue;\n }\n\n // Evaluate condition\n const matches = await evaluateCondition(meta.condition, payload, apiKey);\n if (!matches) {\n await recordTriggerSkip(resource, meta, body, \"skipped\", undefined);\n continue;\n }\n\n // Dispatch. Guard against concurrent duplicate dispatch of the same\n // trigger (TOCTOU on lastStatus) with an in-process lock keyed on the\n // trigger's identity.\n const dispatchKey = `${resource.owner}:${resource.path}`;\n if (_dispatchingTriggers.has(dispatchKey)) continue;\n if (meta.mode === \"agentic\") {\n _dispatchingTriggers.add(dispatchKey);\n try {\n await dispatchAgentic(\n resource,\n meta,\n body,\n payload,\n eventMeta,\n identity,\n );\n } finally {\n _dispatchingTriggers.delete(dispatchKey);\n }\n } else {\n console.warn(\n `[triggers] Deterministic mode not yet implemented for \"${resource.path}\" — skipping`,\n );\n }\n }\n } catch (err) {\n console.error(`[triggers] Error handling event \"${eventName}\":`, err);\n }\n}\n\nasync function dispatchAgentic(\n resource: Resource,\n meta: TriggerFrontmatter,\n body: string,\n payload: unknown,\n eventMeta: EventMeta,\n identity: AutomationExecutionIdentity,\n): Promise<void> {\n if (!_deps) return;\n\n const triggerName = resource.path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n const now = new Date();\n\n const jobUserEmail = identity.userEmail;\n const jobOrgId = identity.orgId;\n\n // Mark as running\n meta.lastRun = now.toISOString();\n meta.lastStatus = \"running\";\n meta.lastError = undefined;\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n\n let payloadStr: string;\n try {\n payloadStr = JSON.stringify(payload, null, 2);\n } catch {\n payloadStr = String(payload);\n }\n\n const automation: BackgroundAutomationContext = {\n name: triggerName,\n meta,\n body,\n resource,\n };\n const requestContext =\n meta.originScopeId && meta.deliveryPlatform && meta.deliveryDestination\n ? {\n isIntegrationCaller: true as const,\n integration: {\n taskId: `automation:${triggerName}:${eventMeta.eventId}`,\n scopeId: meta.originScopeId,\n principalType: \"service\" as const,\n incoming: {\n platform: meta.deliveryPlatform,\n externalThreadId: `${meta.deliveryTenantId || \"unknown\"}:${meta.deliveryDestination}:${meta.deliveryThreadRef || \"root\"}`,\n text: \"\",\n tenantId: meta.deliveryTenantId,\n integrationScopeId: meta.originScopeId,\n platformContext: {\n channelId: meta.deliveryDestination,\n threadTs: meta.deliveryThreadRef,\n teamId: meta.deliveryTenantId,\n },\n threadRef: meta.deliveryThreadRef,\n timestamp: now.getTime(),\n },\n },\n }\n : undefined;\n\n try {\n await runBackgroundAutomation(\n {\n automation,\n ownerEmail: jobUserEmail,\n orgId: jobOrgId,\n prompt: `[Automation Trigger: ${triggerName}]\nEvent: ${meta.event}\nEvent ID: ${eventMeta.eventId}\nFired at: ${eventMeta.emittedAt}\n\nEvent payload:\n${payloadStr}\n\nExecute the following automation instructions:\n\n${body}`,\n threadTitle: `Trigger: ${triggerName} — ${now.toLocaleDateString()}`,\n runIdPrefix: `automation-${triggerName}`,\n usageLabel: `automation:${triggerName}`,\n usageRefId: eventMeta.eventId,\n requestContext,\n actionCaller: \"automation\",\n actionAutomation: {\n triggerId: resource.id,\n triggerName,\n policyId: meta.delegatedPolicyId,\n },\n },\n _deps,\n );\n\n meta.lastStatus = \"success\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.log(`[triggers] \"${triggerName}\" completed successfully`);\n } catch (err) {\n meta.lastStatus = \"error\";\n meta.lastError =\n err instanceof Error ? err.message.slice(0, 200) : \"Unknown error\";\n await resourcePut(\n resource.owner,\n resource.path,\n buildTriggerContent(meta, body),\n );\n console.error(`[triggers] \"${triggerName}\" failed:`, meta.lastError);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/triggers/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AAuBZ,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,yBAAyB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAyJD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA4BhC;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA0D9B;AAWD,wBAAgB,wBAAwB;;;;IA8DvC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/triggers/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,IAAI,CAAC;AA4BZ,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,yBAAyB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6JD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA4BhC;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA8D9B;AAWD,wBAAgB,wBAAwB;;;;IA8DvC"}