@agent-native/core 0.134.1 → 0.135.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +113 -0
- package/corpus/core/package.json +3 -2
- package/corpus/core/src/automations/service.ts +41 -4
- package/corpus/core/src/cli/mcp-config-writers.ts +27 -21
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/corpus/core/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/corpus/core/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/corpus/core/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/corpus/core/src/client/agent-page/use-jobs.ts +50 -10
- package/corpus/core/src/client/org/OrgSwitcher.tsx +26 -0
- package/corpus/core/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/corpus/core/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/corpus/core/src/client/settings/SettingsRow.tsx +113 -0
- package/corpus/core/src/client/settings/agent-settings-search.ts +2 -1
- package/corpus/core/src/client/settings/index.ts +6 -0
- package/corpus/core/src/integrations/identity.ts +2 -12
- package/corpus/core/src/jobs/actions/list-automation-runs.ts +33 -0
- package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/corpus/core/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/corpus/core/src/jobs/background-automation-runner.ts +88 -0
- package/corpus/core/src/jobs/cron.ts +52 -6
- package/corpus/core/src/jobs/frontmatter.ts +20 -0
- package/corpus/core/src/jobs/run-history.ts +242 -0
- package/corpus/core/src/jobs/scheduler.ts +73 -18
- package/corpus/core/src/jobs/tools.ts +54 -6
- package/corpus/core/src/localization/actions/get-localization-preference.ts +2 -2
- package/corpus/core/src/localization/actions/set-localization-preference.ts +49 -11
- package/corpus/core/src/localization/default-messages.ts +27 -0
- package/corpus/core/src/localization/shared.ts +39 -6
- package/corpus/core/src/localization/user-timezone.ts +36 -0
- package/corpus/core/src/org/app-roles-handlers.ts +1 -9
- package/corpus/core/src/org/index.ts +2 -0
- package/corpus/core/src/org/membership.ts +18 -0
- package/corpus/core/src/review/actions/create-review-comment.ts +4 -1
- package/corpus/core/src/review/actions/reply-review-comment.ts +4 -1
- package/corpus/core/src/review/index.ts +5 -0
- package/corpus/core/src/review/notifications.ts +163 -0
- package/corpus/core/src/review/types.ts +7 -0
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/activity-notifications.ts +174 -0
- package/corpus/core/src/server/app-name.ts +31 -0
- package/corpus/core/src/server/better-auth-instance.ts +4 -4
- package/corpus/core/src/server/email-templates.ts +70 -14
- package/corpus/core/src/server/email.ts +66 -3
- package/corpus/core/src/server/index.ts +10 -0
- package/corpus/core/src/sharing/access.ts +44 -2
- package/corpus/core/src/sharing/index.ts +5 -0
- package/corpus/core/src/sharing/recipients.ts +67 -0
- package/corpus/core/src/triggers/actions/list-automations.ts +27 -8
- package/corpus/core/src/triggers/actions/manage-automation.ts +17 -6
- package/corpus/core/src/triggers/actions.ts +16 -4
- package/corpus/core/src/triggers/dispatcher.ts +44 -30
- package/corpus/core/src/triggers/routes.ts +19 -6
- package/corpus/core/src/vitest-config.ts +68 -0
- package/corpus/core/vitest.config.ts +5 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +37 -53
- package/corpus/templates/analytics/changelog/2026-08-01-new-error-alerts-now-reach-you-by-email-and-a-scheduled-dash.md +6 -0
- package/corpus/templates/analytics/server/jobs/dashboard-report.ts +43 -0
- package/corpus/templates/analytics/server/lib/error-capture.ts +5 -1
- package/corpus/templates/analytics/vitest.config.ts +16 -12
- package/corpus/templates/assets/actions/refresh-generation-run.ts +3 -0
- package/corpus/templates/assets/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/assets/app/hooks/use-assets-prefs.ts +55 -0
- package/corpus/templates/assets/app/i18n-data.ts +30 -0
- package/corpus/templates/assets/app/routes/settings.tsx +58 -55
- package/corpus/templates/assets/changelog/2026-08-01-get-an-email-when-a-generation-you-started-finishes-or-fails.md +6 -0
- package/corpus/templates/assets/server/lib/generation-run-notifications.ts +89 -0
- package/corpus/templates/assets/server/lib/video-runs.ts +8 -1
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.get.ts +17 -0
- package/corpus/templates/assets/server/routes/_agent-native/assets/user-prefs.put.ts +36 -0
- package/corpus/templates/assets/shared/assets-user-prefs.ts +10 -0
- package/corpus/templates/assets/vitest.config.ts +16 -12
- package/corpus/templates/brain/app/routes/settings.tsx +15 -15
- package/corpus/templates/brain/vitest.config.ts +16 -12
- package/corpus/templates/calendar/app/pages/Settings.tsx +32 -40
- package/corpus/templates/calendar/changelog/2026-08-01-language-and-appearance-now-sit-together-in-one-preferences-.md +6 -0
- package/corpus/templates/calendar/vitest.config.ts +16 -12
- package/corpus/templates/chat/app/routes/settings.tsx +14 -22
- package/corpus/templates/chat/vitest.config.ts +9 -0
- package/corpus/templates/clips/.agents/skills/video-editing/SKILL.md +31 -0
- package/corpus/templates/clips/AGENTS.md +1 -0
- package/corpus/templates/clips/actions/add-comment.ts +12 -1
- package/corpus/templates/clips/actions/create-meeting.ts +2 -2
- package/corpus/templates/clips/actions/create-recording.ts +2 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +42 -6
- package/corpus/templates/clips/actions/generate-filmstrip.ts +154 -0
- package/corpus/templates/clips/actions/get-recording-player-data.ts +6 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +2 -2
- package/corpus/templates/clips/actions/lib/ensure-recording-filmstrip.ts +258 -0
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +11 -3
- package/corpus/templates/clips/actions/react-to-comment.ts +13 -0
- package/corpus/templates/clips/actions/react-to-recording.ts +10 -1
- package/corpus/templates/clips/actions/reply-to-comment.ts +12 -1
- package/corpus/templates/clips/actions/stitch-recordings.ts +2 -2
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +152 -23
- package/corpus/templates/clips/app/components/editor/waveform.tsx +237 -75
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +23 -1
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +441 -0
- package/corpus/templates/clips/app/components/settings/slack-section.tsx +329 -0
- package/corpus/templates/clips/app/components/settings/types.ts +14 -0
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +443 -0
- package/corpus/templates/clips/app/hooks/use-secret-status.ts +69 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +9 -1
- package/corpus/templates/clips/app/lib/video-filmstrip.ts +262 -0
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +165 -1351
- package/corpus/templates/clips/changelog/2026-07-27-saved-clips-now-resume-from-the-last-uploaded-byte-after-an-.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-editor-timeline-now-shows-video-frames-behind-the-waveform-g.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-email-notifications-now-go-out-when-someone-comments-on-or-r.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-31-you-can-now-set-a-default-visibility-for-new-recordings-in-s.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-01-email-notifications-for-comments-and-reactions-now-actually-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-03-the-desktop-app-now-opens-directly-beneath-its-tray-icon-on-.md +6 -0
- package/corpus/templates/clips/chrome-extension/package.json +1 -0
- package/corpus/templates/clips/chrome-extension/vitest.config.ts +9 -0
- package/corpus/templates/clips/desktop/package.json +1 -0
- package/corpus/templates/clips/desktop/src/app.tsx +17 -1
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
- package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +815 -15
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +61 -11
- package/corpus/templates/clips/desktop/vitest.config.ts +9 -0
- package/corpus/templates/clips/server/db/schema.ts +17 -0
- package/corpus/templates/clips/server/jobs/media-verification.ts +4 -0
- package/corpus/templates/clips/server/lib/activity-notifications.ts +185 -0
- package/corpus/templates/clips/server/lib/recording-media-cleanup.ts +2 -0
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +46 -9
- package/corpus/templates/clips/server/lib/recordings.ts +24 -0
- package/corpus/templates/clips/server/lib/resumable-session.ts +10 -4
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +109 -0
- package/corpus/templates/clips/server/lib/upload-interruption.ts +8 -0
- package/corpus/templates/clips/server/lib/upload-lease.ts +50 -4
- package/corpus/templates/clips/server/lib/video-filmstrip-sprite.ts +207 -0
- package/corpus/templates/clips/server/lib/video-remux.ts +13 -4
- package/corpus/templates/clips/server/plugins/db.ts +16 -0
- package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +4 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +123 -36
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +159 -29
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +197 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +193 -39
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +191 -12
- package/corpus/templates/clips/shared/clips-ai-prefs.ts +6 -0
- package/corpus/templates/clips/shared/feature-flags.ts +12 -0
- package/corpus/templates/clips/shared/recording-core.ts +4 -0
- package/corpus/templates/clips/vitest.config.ts +23 -19
- package/corpus/templates/content/actions/_database-utils.ts +113 -4
- package/corpus/templates/content/actions/add-comment.ts +15 -1
- package/corpus/templates/content/actions/get-document.ts +84 -3
- package/corpus/templates/content/actions/list-documents.ts +1 -0
- package/corpus/templates/content/app/components/editor/BuilderBodySyncingNotice.tsx +9 -2
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +34 -15
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +55 -13
- package/corpus/templates/content/app/components/editor/body-hydration.ts +12 -6
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2 -3
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -12
- package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +16 -27
- package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
- package/corpus/templates/content/app/hooks/use-create-page.ts +3 -6
- package/corpus/templates/content/app/hooks/use-document-properties.ts +9 -16
- package/corpus/templates/content/app/hooks/use-document-versions.ts +3 -3
- package/corpus/templates/content/app/hooks/use-documents.ts +85 -29
- package/corpus/templates/content/app/hooks/use-notion.ts +15 -13
- package/corpus/templates/content/app/i18n-data.ts +72 -1
- package/corpus/templates/content/app/lib/document-query.ts +36 -0
- package/corpus/templates/content/app/routes/_app.settings.tsx +47 -18
- package/corpus/templates/content/changelog/2026-07-30-breadcrumb-menus-now-hide-internal-system-pages.md +6 -0
- package/corpus/templates/content/changelog/2026-08-01-get-an-email-when-someone-comments-on-replies-in-or-mentions.md +6 -0
- package/corpus/templates/content/changelog/2026-08-02-pages-opened-from-a-database-now-keep-that-database-s-fields.md +6 -0
- package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
- package/corpus/templates/content/server/lib/document-context.ts +11 -6
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.get.ts +17 -0
- package/corpus/templates/content/server/routes/_agent-native/content/user-prefs.put.ts +36 -0
- package/corpus/templates/content/shared/api.ts +8 -0
- package/corpus/templates/content/shared/content-user-prefs.ts +11 -0
- package/corpus/templates/content/vitest.config.ts +20 -16
- package/corpus/templates/crm/app/routes/settings.tsx +14 -22
- package/corpus/templates/crm/vitest.config.ts +8 -4
- package/corpus/templates/design/app/routes/settings.tsx +14 -22
- package/corpus/templates/design/changelog/2026-08-01-review-comments-replies-and-mentions-now-send-an-email-to-th.md +6 -0
- package/corpus/templates/design/vitest.config.ts +18 -12
- package/corpus/templates/dispatch/app/routes/settings.tsx +26 -40
- package/corpus/templates/dispatch/vitest.config.ts +11 -7
- package/corpus/templates/factory/app/routes/settings.tsx +14 -22
- package/corpus/templates/factory/vitest.config.ts +9 -0
- package/corpus/templates/forms/app/routes/_app.settings.tsx +14 -22
- package/corpus/templates/forms/vitest.config.ts +27 -23
- package/corpus/templates/macros/app/routes/settings.tsx +14 -22
- package/corpus/templates/macros/vitest.config.ts +16 -12
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +14 -16
- package/corpus/templates/mail/vitest.config.ts +16 -12
- package/corpus/templates/plan/app/routes/settings.tsx +30 -44
- package/corpus/templates/plan/vitest.config.ts +24 -20
- package/corpus/templates/slides/actions/add-slide-comment.ts +12 -1
- package/corpus/templates/slides/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/slides/app/hooks/use-slides-prefs.ts +55 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/routes/settings.tsx +45 -22
- package/corpus/templates/slides/changelog/2026-08-01-get-an-email-when-someone-comments-on-or-replies-in-your-dec.md +6 -0
- package/corpus/templates/slides/server/lib/comment-notifications.ts +182 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.get.ts +16 -0
- package/corpus/templates/slides/server/routes/_agent-native/slides/user-prefs.put.ts +36 -0
- package/corpus/templates/slides/shared/slides-user-prefs.ts +11 -0
- package/corpus/templates/slides/vitest.config.ts +17 -13
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +2 -0
- package/corpus/templates/tasks/app/routes/settings.tsx +14 -22
- package/corpus/templates/tasks/vitest.config.ts +17 -13
- package/corpus/toolkit/CHANGELOG.md +9 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/vitest.config.ts +3 -0
- package/dist/automations/service.d.ts +2 -0
- package/dist/automations/service.d.ts.map +1 -1
- package/dist/automations/service.js +29 -4
- package/dist/automations/service.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +24 -23
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +86 -29
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts +21 -0
- package/dist/client/agent-page/AutomationDetailsDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js +33 -0
- package/dist/client/agent-page/AutomationDetailsDialog.js.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts +15 -0
- package/dist/client/agent-page/AutomationScheduleDialog.d.ts.map +1 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js +46 -0
- package/dist/client/agent-page/AutomationScheduleDialog.js.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts +17 -0
- package/dist/client/agent-page/TimezoneSelect.d.ts.map +1 -0
- package/dist/client/agent-page/TimezoneSelect.js +107 -0
- package/dist/client/agent-page/TimezoneSelect.js.map +1 -0
- package/dist/client/agent-page/use-jobs.d.ts +20 -7
- package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/client/agent-page/use-jobs.js +24 -4
- package/dist/client/agent-page/use-jobs.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts +8 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +8 -2
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/settings/AccountSettingsCard.d.ts.map +1 -1
- package/dist/client/settings/AccountSettingsCard.js +10 -9
- package/dist/client/settings/AccountSettingsCard.js.map +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +10 -0
- package/dist/client/settings/SchedulingTimezoneField.d.ts.map +1 -0
- package/dist/client/settings/SchedulingTimezoneField.js +30 -0
- package/dist/client/settings/SchedulingTimezoneField.js.map +1 -0
- package/dist/client/settings/SettingsRow.d.ts +36 -0
- package/dist/client/settings/SettingsRow.d.ts.map +1 -0
- package/dist/client/settings/SettingsRow.js +15 -0
- package/dist/client/settings/SettingsRow.js.map +1 -0
- package/dist/client/settings/agent-settings-search.d.ts.map +1 -1
- package/dist/client/settings/agent-settings-search.js +1 -1
- package/dist/client/settings/agent-settings-search.js.map +1 -1
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.d.ts.map +1 -1
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/index.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/integrations/identity.d.ts.map +1 -1
- package/dist/integrations/identity.js +2 -11
- package/dist/integrations/identity.js.map +1 -1
- package/dist/jobs/actions/list-automation-runs.d.ts +8 -0
- package/dist/jobs/actions/list-automation-runs.d.ts.map +1 -0
- package/dist/jobs/actions/list-automation-runs.js +29 -0
- package/dist/jobs/actions/list-automation-runs.js.map +1 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts +2 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
- package/dist/jobs/actions/list-recurring-jobs.js +20 -7
- package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
- package/dist/jobs/actions/manage-recurring-job.d.ts +2 -0
- package/dist/jobs/actions/manage-recurring-job.js +30 -9
- package/dist/jobs/actions/manage-recurring-job.js.map +1 -1
- package/dist/jobs/background-automation-runner.d.ts.map +1 -1
- package/dist/jobs/background-automation-runner.js +60 -0
- package/dist/jobs/background-automation-runner.js.map +1 -1
- package/dist/jobs/cron.d.ts +16 -2
- package/dist/jobs/cron.d.ts.map +1 -1
- package/dist/jobs/cron.js +43 -6
- package/dist/jobs/cron.js.map +1 -1
- package/dist/jobs/frontmatter.d.ts +12 -0
- package/dist/jobs/frontmatter.d.ts.map +1 -1
- package/dist/jobs/frontmatter.js +8 -0
- package/dist/jobs/frontmatter.js.map +1 -1
- package/dist/jobs/run-history.d.ts +56 -0
- package/dist/jobs/run-history.d.ts.map +1 -0
- package/dist/jobs/run-history.js +169 -0
- package/dist/jobs/run-history.js.map +1 -0
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +51 -18
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +37 -6
- package/dist/jobs/tools.js.map +1 -1
- package/dist/localization/actions/get-localization-preference.d.ts +1 -2
- package/dist/localization/actions/get-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/get-localization-preference.js.map +1 -1
- package/dist/localization/actions/set-localization-preference.d.ts +3 -3
- package/dist/localization/actions/set-localization-preference.d.ts.map +1 -1
- package/dist/localization/actions/set-localization-preference.js +33 -8
- package/dist/localization/actions/set-localization-preference.js.map +1 -1
- package/dist/localization/default-messages.d.ts +25 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +25 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/localization/shared.d.ts +16 -1
- package/dist/localization/shared.d.ts.map +1 -1
- package/dist/localization/shared.js +22 -4
- package/dist/localization/shared.js.map +1 -1
- package/dist/localization/user-timezone.d.ts +11 -0
- package/dist/localization/user-timezone.d.ts.map +1 -0
- package/dist/localization/user-timezone.js +31 -0
- package/dist/localization/user-timezone.js.map +1 -0
- package/dist/notifications/routes.d.ts +4 -4
- package/dist/observability/routes.d.ts +3 -3
- package/dist/org/app-roles-handlers.d.ts.map +1 -1
- package/dist/org/app-roles-handlers.js +1 -8
- package/dist/org/app-roles-handlers.js.map +1 -1
- package/dist/org/index.d.ts +1 -0
- package/dist/org/index.d.ts.map +1 -1
- package/dist/org/index.js +1 -0
- package/dist/org/index.js.map +1 -1
- package/dist/org/membership.d.ts +6 -0
- package/dist/org/membership.d.ts.map +1 -0
- package/dist/org/membership.js +16 -0
- package/dist/org/membership.js.map +1 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/review/actions/create-review-comment.d.ts +32 -1
- package/dist/review/actions/create-review-comment.d.ts.map +1 -1
- package/dist/review/actions/create-review-comment.js +3 -1
- package/dist/review/actions/create-review-comment.js.map +1 -1
- package/dist/review/actions/reply-review-comment.d.ts +32 -1
- package/dist/review/actions/reply-review-comment.d.ts.map +1 -1
- package/dist/review/actions/reply-review-comment.js +3 -1
- package/dist/review/actions/reply-review-comment.js.map +1 -1
- package/dist/review/index.d.ts +1 -0
- package/dist/review/index.d.ts.map +1 -1
- package/dist/review/index.js +1 -0
- package/dist/review/index.js.map +1 -1
- package/dist/review/notifications.d.ts +24 -0
- package/dist/review/notifications.d.ts.map +1 -0
- package/dist/review/notifications.js +123 -0
- package/dist/review/notifications.js.map +1 -0
- package/dist/review/types.d.ts +5 -0
- package/dist/review/types.d.ts.map +1 -1
- package/dist/review/types.js.map +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +4 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/activity-notifications.d.ts +61 -0
- package/dist/server/activity-notifications.d.ts.map +1 -0
- package/dist/server/activity-notifications.js +103 -0
- package/dist/server/activity-notifications.js.map +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/app-name.d.ts +18 -0
- package/dist/server/app-name.d.ts.map +1 -1
- package/dist/server/app-name.js +31 -0
- package/dist/server/app-name.js.map +1 -1
- package/dist/server/better-auth-instance.js +4 -4
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/email-templates.d.ts +12 -0
- package/dist/server/email-templates.d.ts.map +1 -1
- package/dist/server/email-templates.js +57 -14
- package/dist/server/email-templates.js.map +1 -1
- package/dist/server/email.d.ts +12 -0
- package/dist/server/email.d.ts.map +1 -1
- package/dist/server/email.js +52 -5
- package/dist/server/email.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/sharing/access.d.ts.map +1 -1
- package/dist/sharing/access.js +32 -2
- package/dist/sharing/access.js.map +1 -1
- package/dist/sharing/index.d.ts +1 -0
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +1 -0
- package/dist/sharing/index.js.map +1 -1
- package/dist/sharing/recipients.d.ts +31 -0
- package/dist/sharing/recipients.d.ts.map +1 -0
- package/dist/sharing/recipients.js +40 -0
- package/dist/sharing/recipients.js.map +1 -0
- package/dist/templates/chat/app/routes/settings.tsx +14 -22
- package/dist/templates/chat/vitest.config.ts +9 -0
- package/dist/triggers/actions/list-automations.d.ts +2 -0
- package/dist/triggers/actions/list-automations.d.ts.map +1 -1
- package/dist/triggers/actions/list-automations.js +19 -8
- package/dist/triggers/actions/list-automations.js.map +1 -1
- package/dist/triggers/actions/manage-automation.d.ts +6 -0
- package/dist/triggers/actions/manage-automation.js +12 -6
- package/dist/triggers/actions/manage-automation.js.map +1 -1
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +15 -4
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +19 -17
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/routes.d.ts.map +1 -1
- package/dist/triggers/routes.js +6 -6
- package/dist/triggers/routes.js.map +1 -1
- package/dist/vitest-config.d.ts +10 -0
- package/dist/vitest-config.d.ts.map +1 -0
- package/dist/vitest-config.js +55 -0
- package/dist/vitest-config.js.map +1 -0
- package/package.json +5 -4
- package/src/automations/service.ts +41 -4
- package/src/cli/mcp-config-writers.ts +27 -21
- package/src/client/agent-page/AgentJobsTab.tsx +187 -85
- package/src/client/agent-page/AutomationDetailsDialog.tsx +208 -0
- package/src/client/agent-page/AutomationScheduleDialog.tsx +180 -0
- package/src/client/agent-page/TimezoneSelect.tsx +241 -0
- package/src/client/agent-page/use-jobs.ts +50 -10
- package/src/client/org/OrgSwitcher.tsx +26 -0
- package/src/client/settings/AccountSettingsCard.tsx +35 -31
- package/src/client/settings/SchedulingTimezoneField.tsx +71 -0
- package/src/client/settings/SettingsRow.tsx +113 -0
- package/src/client/settings/agent-settings-search.ts +2 -1
- package/src/client/settings/index.ts +6 -0
- package/src/integrations/identity.ts +2 -12
- package/src/jobs/actions/list-automation-runs.ts +33 -0
- package/src/jobs/actions/list-recurring-jobs.ts +27 -6
- package/src/jobs/actions/manage-recurring-job.ts +41 -9
- package/src/jobs/background-automation-runner.ts +88 -0
- package/src/jobs/cron.ts +52 -6
- package/src/jobs/frontmatter.ts +20 -0
- package/src/jobs/run-history.ts +242 -0
- package/src/jobs/scheduler.ts +73 -18
- package/src/jobs/tools.ts +54 -6
- package/src/localization/actions/get-localization-preference.ts +2 -2
- package/src/localization/actions/set-localization-preference.ts +49 -11
- package/src/localization/default-messages.ts +27 -0
- package/src/localization/shared.ts +39 -6
- package/src/localization/user-timezone.ts +36 -0
- package/src/org/app-roles-handlers.ts +1 -9
- package/src/org/index.ts +2 -0
- package/src/org/membership.ts +18 -0
- package/src/review/actions/create-review-comment.ts +4 -1
- package/src/review/actions/reply-review-comment.ts +4 -1
- package/src/review/index.ts +5 -0
- package/src/review/notifications.ts +163 -0
- package/src/review/types.ts +7 -0
- package/src/server/action-discovery.ts +4 -0
- package/src/server/activity-notifications.ts +174 -0
- package/src/server/app-name.ts +31 -0
- package/src/server/better-auth-instance.ts +4 -4
- package/src/server/email-templates.ts +70 -14
- package/src/server/email.ts +66 -3
- package/src/server/index.ts +10 -0
- package/src/sharing/access.ts +44 -2
- package/src/sharing/index.ts +5 -0
- package/src/sharing/recipients.ts +67 -0
- package/src/templates/chat/app/routes/settings.tsx +14 -22
- package/src/templates/chat/vitest.config.ts +9 -0
- package/src/triggers/actions/list-automations.ts +27 -8
- package/src/triggers/actions/manage-automation.ts +17 -6
- package/src/triggers/actions.ts +16 -4
- package/src/triggers/dispatcher.ts +44 -30
- package/src/triggers/routes.ts +19 -6
- package/src/vitest-config.ts +68 -0
|
@@ -3,6 +3,8 @@ import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
|
3
3
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
4
4
|
import {
|
|
5
5
|
AccountSettingsCard,
|
|
6
|
+
SettingsGroup,
|
|
7
|
+
SettingsRow,
|
|
6
8
|
SettingsTabsPage,
|
|
7
9
|
useAgentSettingsTabs,
|
|
8
10
|
type SettingsSearchEntry,
|
|
@@ -10,14 +12,6 @@ import {
|
|
|
10
12
|
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
|
|
11
13
|
import { useMemo } from "react";
|
|
12
14
|
|
|
13
|
-
import {
|
|
14
|
-
Card,
|
|
15
|
-
CardContent,
|
|
16
|
-
CardDescription,
|
|
17
|
-
CardHeader,
|
|
18
|
-
CardTitle,
|
|
19
|
-
} from "@/components/ui/card";
|
|
20
|
-
import { Label } from "@/components/ui/label";
|
|
21
15
|
import { APP_TITLE } from "@/lib/app-config";
|
|
22
16
|
|
|
23
17
|
import changelog from "../../CHANGELOG.md?raw";
|
|
@@ -55,20 +49,18 @@ export default function SettingsRoute() {
|
|
|
55
49
|
{t("settings.description")}
|
|
56
50
|
</p>
|
|
57
51
|
|
|
58
|
-
<
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</CardContent>
|
|
71
|
-
</Card>
|
|
52
|
+
<SettingsGroup>
|
|
53
|
+
<SettingsRow
|
|
54
|
+
id="language"
|
|
55
|
+
label={t("settings.languageTitle")}
|
|
56
|
+
description={t("settings.languageDescription")}
|
|
57
|
+
control={
|
|
58
|
+
<div className="w-56">
|
|
59
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
60
|
+
</div>
|
|
61
|
+
}
|
|
62
|
+
/>
|
|
63
|
+
</SettingsGroup>
|
|
72
64
|
</div>
|
|
73
65
|
}
|
|
74
66
|
team={
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import baseConfig from "@agent-native/core/vitest-config";
|
|
2
|
+
import { mergeConfig } from "vitest/config";
|
|
3
|
+
|
|
4
|
+
import viteConfig from "./vite.config";
|
|
5
|
+
|
|
6
|
+
// Kept separate from vite.config.ts so the production config never imports
|
|
7
|
+
// vitest: `agent-native build` loads vite.config.ts in installs where vitest
|
|
8
|
+
// is absent.
|
|
9
|
+
export default mergeConfig(viteConfig, baseConfig);
|
|
@@ -5,7 +5,12 @@ import {
|
|
|
5
5
|
listAutomationDefinitions,
|
|
6
6
|
type AutomationScope,
|
|
7
7
|
} from "../../automations/service.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
describeCron,
|
|
10
|
+
effectiveTimezone,
|
|
11
|
+
isValidCron,
|
|
12
|
+
nextOccurrence,
|
|
13
|
+
} from "../../jobs/cron.js";
|
|
9
14
|
|
|
10
15
|
const scopeSchema = z.enum(["personal", "organization"]);
|
|
11
16
|
|
|
@@ -13,15 +18,23 @@ function nextRun(
|
|
|
13
18
|
meta: Awaited<ReturnType<typeof listAutomationDefinitions>>[number]["meta"],
|
|
14
19
|
): string | null {
|
|
15
20
|
if (!meta.enabled) return null;
|
|
16
|
-
|
|
17
|
-
if (
|
|
21
|
+
const scheduled = Boolean(
|
|
18
22
|
meta.triggerType === "schedule" &&
|
|
19
23
|
meta.schedule &&
|
|
20
|
-
isValidCron(meta.schedule)
|
|
21
|
-
)
|
|
22
|
-
|
|
24
|
+
isValidCron(meta.schedule),
|
|
25
|
+
);
|
|
26
|
+
// A stored `nextRun` in the past means the dispatcher kept declining to run
|
|
27
|
+
// this automation, not that it is overdue. Report the real next occurrence
|
|
28
|
+
// and let `lastError` carry the reason it keeps being passed over.
|
|
29
|
+
if (meta.nextRun) {
|
|
30
|
+
const stored = new Date(meta.nextRun).getTime();
|
|
31
|
+
if (!Number.isFinite(stored) || stored > Date.now() || !scheduled) {
|
|
32
|
+
return meta.nextRun;
|
|
33
|
+
}
|
|
23
34
|
}
|
|
24
|
-
return
|
|
35
|
+
return scheduled
|
|
36
|
+
? nextOccurrence(meta.schedule!, undefined, meta.timezone).toISOString()
|
|
37
|
+
: null;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
export interface AutomationActionItem {
|
|
@@ -32,11 +45,13 @@ export interface AutomationActionItem {
|
|
|
32
45
|
triggerType: "event" | "schedule";
|
|
33
46
|
event: string | null;
|
|
34
47
|
schedule: string | null;
|
|
48
|
+
timezone: string | null;
|
|
35
49
|
scheduleDescription: string | null;
|
|
36
50
|
condition: string | null;
|
|
37
51
|
body: string;
|
|
38
52
|
enabled: boolean;
|
|
39
53
|
lastRun: string | null;
|
|
54
|
+
lastCheck: string | null;
|
|
40
55
|
lastStatus: string | null;
|
|
41
56
|
lastError: string | null;
|
|
42
57
|
nextRun: string | null;
|
|
@@ -76,11 +91,15 @@ export default defineAction({
|
|
|
76
91
|
triggerType: meta.triggerType,
|
|
77
92
|
event: meta.event ?? null,
|
|
78
93
|
schedule: meta.schedule || null,
|
|
79
|
-
|
|
94
|
+
timezone: meta.schedule ? effectiveTimezone(meta.timezone) : null,
|
|
95
|
+
scheduleDescription: meta.schedule
|
|
96
|
+
? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
|
|
97
|
+
: null,
|
|
80
98
|
condition: meta.condition ?? null,
|
|
81
99
|
body,
|
|
82
100
|
enabled: meta.enabled,
|
|
83
101
|
lastRun: meta.lastRun ?? null,
|
|
102
|
+
lastCheck: meta.lastCheck ?? null,
|
|
84
103
|
lastStatus: meta.lastStatus ?? null,
|
|
85
104
|
lastError: meta.lastError ?? null,
|
|
86
105
|
nextRun: nextRun(meta),
|
|
@@ -16,8 +16,10 @@ export default defineAction({
|
|
|
16
16
|
name: z.string().min(1),
|
|
17
17
|
scope: z.enum(["personal", "organization"]).default("personal"),
|
|
18
18
|
enabled: z.boolean().optional(),
|
|
19
|
+
schedule: z.string().min(1).optional(),
|
|
20
|
+
timezone: z.string().min(1).optional(),
|
|
19
21
|
}),
|
|
20
|
-
run: async ({ operation, name, scope, enabled }, ctx) => {
|
|
22
|
+
run: async ({ operation, name, scope, enabled, schedule, timezone }, ctx) => {
|
|
21
23
|
const userEmail = ctx?.userEmail;
|
|
22
24
|
if (!userEmail) throw new Error("Not authenticated.");
|
|
23
25
|
const actor = { userEmail, orgId: ctx?.orgId };
|
|
@@ -27,20 +29,29 @@ export default defineAction({
|
|
|
27
29
|
await refreshEventSubscriptions();
|
|
28
30
|
return { deleted: true, name };
|
|
29
31
|
}
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if (
|
|
33
|
+
enabled === undefined &&
|
|
34
|
+
schedule === undefined &&
|
|
35
|
+
timezone === undefined
|
|
36
|
+
) {
|
|
37
|
+
throw Object.assign(
|
|
38
|
+
new Error("enabled, schedule, or timezone is required for update."),
|
|
39
|
+
{ statusCode: 400 },
|
|
40
|
+
);
|
|
34
41
|
}
|
|
35
42
|
const definition = await updateAutomation(actor, {
|
|
36
43
|
name,
|
|
37
44
|
scope,
|
|
38
|
-
enabled,
|
|
45
|
+
...(enabled === undefined ? {} : { enabled }),
|
|
46
|
+
...(schedule === undefined ? {} : { schedule }),
|
|
47
|
+
...(timezone === undefined ? {} : { timezone }),
|
|
39
48
|
});
|
|
40
49
|
await refreshEventSubscriptions();
|
|
41
50
|
return {
|
|
42
51
|
name,
|
|
43
52
|
enabled: definition.meta.enabled,
|
|
53
|
+
schedule: definition.meta.schedule || null,
|
|
54
|
+
timezone: definition.meta.timezone ?? null,
|
|
44
55
|
nextRun: definition.meta.nextRun ?? null,
|
|
45
56
|
};
|
|
46
57
|
},
|
package/src/triggers/actions.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
type AutomationScope,
|
|
19
19
|
} from "../automations/service.js";
|
|
20
20
|
import { listEvents } from "../event-bus/index.js";
|
|
21
|
-
import { describeCron } from "../jobs/cron.js";
|
|
21
|
+
import { describeCron, effectiveTimezone } from "../jobs/cron.js";
|
|
22
22
|
import {
|
|
23
23
|
getIntegrationRequestContext,
|
|
24
24
|
getRequestOrgId,
|
|
@@ -71,7 +71,10 @@ async function handleList(
|
|
|
71
71
|
triggerType: meta.triggerType,
|
|
72
72
|
event: meta.event ?? null,
|
|
73
73
|
schedule: meta.schedule || null,
|
|
74
|
-
|
|
74
|
+
timezone: meta.timezone ? effectiveTimezone(meta.timezone) : null,
|
|
75
|
+
scheduleDescription: meta.schedule
|
|
76
|
+
? describeCron(meta.schedule, effectiveTimezone(meta.timezone))
|
|
77
|
+
: null,
|
|
75
78
|
condition: meta.condition ?? null,
|
|
76
79
|
mode: meta.mode,
|
|
77
80
|
domain: meta.domain ?? null,
|
|
@@ -127,6 +130,7 @@ async function handleDefine(
|
|
|
127
130
|
triggerType: automationTriggerType(args.trigger_type),
|
|
128
131
|
body: typeof args.body === "string" ? args.body : "",
|
|
129
132
|
schedule: typeof args.schedule === "string" ? args.schedule : undefined,
|
|
133
|
+
timezone: typeof args.timezone === "string" ? args.timezone : undefined,
|
|
130
134
|
event: typeof args.event === "string" ? args.event : undefined,
|
|
131
135
|
condition:
|
|
132
136
|
typeof args.condition === "string" ? args.condition : undefined,
|
|
@@ -164,6 +168,7 @@ async function handleDefine(
|
|
|
164
168
|
triggerType: definition.meta.triggerType,
|
|
165
169
|
event: definition.meta.event ?? null,
|
|
166
170
|
schedule: definition.meta.schedule || null,
|
|
171
|
+
timezone: definition.meta.timezone ?? null,
|
|
167
172
|
nextRun: definition.meta.nextRun ?? null,
|
|
168
173
|
createdBy: definition.meta.createdBy,
|
|
169
174
|
runAs: definition.meta.runAs,
|
|
@@ -208,6 +213,7 @@ async function handleUpdate(
|
|
|
208
213
|
: null,
|
|
209
214
|
body: typeof args.body === "string" ? args.body : undefined,
|
|
210
215
|
schedule: typeof args.schedule === "string" ? args.schedule : undefined,
|
|
216
|
+
timezone: typeof args.timezone === "string" ? args.timezone : undefined,
|
|
211
217
|
model:
|
|
212
218
|
args.model === undefined
|
|
213
219
|
? undefined
|
|
@@ -225,6 +231,7 @@ async function handleUpdate(
|
|
|
225
231
|
triggerType: definition.meta.triggerType,
|
|
226
232
|
enabled: definition.meta.enabled,
|
|
227
233
|
schedule: definition.meta.schedule || null,
|
|
234
|
+
timezone: definition.meta.timezone ?? null,
|
|
228
235
|
nextRun: definition.meta.nextRun ?? null,
|
|
229
236
|
createdBy: definition.meta.createdBy,
|
|
230
237
|
runAs: definition.meta.runAs,
|
|
@@ -305,8 +312,8 @@ export function createAutomationToolEntries(
|
|
|
305
312
|
|
|
306
313
|
- **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.
|
|
307
314
|
- **list**: List all automations (triggers). Shows trigger, status, model, MCP allowlist, and delivery metadata. Optional params: scope, domain, enabled_only.
|
|
308
|
-
- **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.
|
|
309
|
-
- **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.
|
|
315
|
+
- **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.
|
|
316
|
+
- **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.
|
|
310
317
|
- **delete**: Delete an automation. Always confirm with the user first. Required param: name.
|
|
311
318
|
- **fire-test**: Fire a test event to validate automations. Emits a test.event.fired event. Optional param: data (JSON string).`,
|
|
312
319
|
parameters: {
|
|
@@ -339,6 +346,11 @@ export function createAutomationToolEntries(
|
|
|
339
346
|
description:
|
|
340
347
|
"For event triggers: the event name to subscribe to. Call with action=list-events first to see available events.",
|
|
341
348
|
},
|
|
349
|
+
timezone: {
|
|
350
|
+
type: "string",
|
|
351
|
+
description:
|
|
352
|
+
"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.",
|
|
353
|
+
},
|
|
342
354
|
schedule: {
|
|
343
355
|
type: "string",
|
|
344
356
|
description:
|
|
@@ -82,6 +82,31 @@ const _eventSubscriptions = new Map<string, string>();
|
|
|
82
82
|
const _dispatchingTriggers = new Set<string>();
|
|
83
83
|
let _deps: TriggerDispatcherDeps | null = null;
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Record that a tick evaluated this trigger and declined to dispatch it.
|
|
87
|
+
* `lastRun` stays untouched — nothing ran — and an unchanged outcome is not
|
|
88
|
+
* re-persisted, so a permanently blocked trigger neither reports phantom runs
|
|
89
|
+
* nor rewrites its resource on every matching event.
|
|
90
|
+
*/
|
|
91
|
+
async function recordTriggerSkip(
|
|
92
|
+
resource: Resource,
|
|
93
|
+
meta: TriggerFrontmatter,
|
|
94
|
+
body: string,
|
|
95
|
+
status: "skipped" | "error",
|
|
96
|
+
reason: string | undefined,
|
|
97
|
+
): Promise<void> {
|
|
98
|
+
const unchanged = meta.lastStatus === status && meta.lastError === reason;
|
|
99
|
+
meta.lastCheck = new Date().toISOString();
|
|
100
|
+
meta.lastStatus = status;
|
|
101
|
+
meta.lastError = reason;
|
|
102
|
+
if (unchanged) return;
|
|
103
|
+
await resourcePut(
|
|
104
|
+
resource.owner,
|
|
105
|
+
resource.path,
|
|
106
|
+
buildTriggerContent(meta, body),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
85
110
|
/**
|
|
86
111
|
* Initialize the trigger dispatcher. Call once at server startup.
|
|
87
112
|
* Loads all event-triggered jobs and subscribes to their events.
|
|
@@ -173,25 +198,22 @@ async function handleEvent(
|
|
|
173
198
|
meta,
|
|
174
199
|
);
|
|
175
200
|
} catch {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
resource.path,
|
|
183
|
-
buildTriggerContent(meta, body),
|
|
201
|
+
await recordTriggerSkip(
|
|
202
|
+
resource,
|
|
203
|
+
meta,
|
|
204
|
+
body,
|
|
205
|
+
"skipped",
|
|
206
|
+
"Could not verify the automation execution identity.",
|
|
184
207
|
);
|
|
185
208
|
continue;
|
|
186
209
|
}
|
|
187
210
|
if (!resolved.ok) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
buildTriggerContent(meta, body),
|
|
211
|
+
await recordTriggerSkip(
|
|
212
|
+
resource,
|
|
213
|
+
meta,
|
|
214
|
+
body,
|
|
215
|
+
"skipped",
|
|
216
|
+
resolved.reason,
|
|
195
217
|
);
|
|
196
218
|
continue;
|
|
197
219
|
}
|
|
@@ -206,13 +228,12 @@ async function handleEvent(
|
|
|
206
228
|
const userApiKey = await getOwnerActiveApiKey(owner);
|
|
207
229
|
const apiKey = userApiKey || _deps.apiKey;
|
|
208
230
|
if (!apiKey) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
buildTriggerContent(meta, body),
|
|
231
|
+
await recordTriggerSkip(
|
|
232
|
+
resource,
|
|
233
|
+
meta,
|
|
234
|
+
body,
|
|
235
|
+
"error",
|
|
236
|
+
"No API key is available for this automation",
|
|
216
237
|
);
|
|
217
238
|
console.warn(`[triggers] ${meta.lastError}: "${resource.path}"`);
|
|
218
239
|
continue;
|
|
@@ -221,14 +242,7 @@ async function handleEvent(
|
|
|
221
242
|
// Evaluate condition
|
|
222
243
|
const matches = await evaluateCondition(meta.condition, payload, apiKey);
|
|
223
244
|
if (!matches) {
|
|
224
|
-
meta
|
|
225
|
-
meta.lastStatus = "skipped";
|
|
226
|
-
meta.lastError = undefined;
|
|
227
|
-
await resourcePut(
|
|
228
|
-
resource.owner,
|
|
229
|
-
resource.path,
|
|
230
|
-
buildTriggerContent(meta, body),
|
|
231
|
-
);
|
|
245
|
+
await recordTriggerSkip(resource, meta, body, "skipped", undefined);
|
|
232
246
|
continue;
|
|
233
247
|
}
|
|
234
248
|
|
package/src/triggers/routes.ts
CHANGED
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import { canUpdateAutomationResource } from "../automations/service.js";
|
|
9
9
|
import { getDbExec } from "../db/client.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
nextOccurrence,
|
|
12
|
+
describeCron,
|
|
13
|
+
effectiveTimezone,
|
|
14
|
+
isValidCron,
|
|
15
|
+
} from "../jobs/cron.js";
|
|
11
16
|
import {
|
|
12
17
|
buildJobResourceContent,
|
|
13
18
|
parseJobResource,
|
|
@@ -88,10 +93,10 @@ function normalizeAutomationPath(input: SetAutomationEnabledInput): string {
|
|
|
88
93
|
return path;
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
function scheduleDescription(schedule
|
|
96
|
+
function scheduleDescription(schedule?: string, timezone?: string) {
|
|
92
97
|
if (!schedule) return undefined;
|
|
93
98
|
try {
|
|
94
|
-
return describeCron(schedule);
|
|
99
|
+
return describeCron(schedule, effectiveTimezone(timezone));
|
|
95
100
|
} catch {
|
|
96
101
|
return schedule;
|
|
97
102
|
}
|
|
@@ -106,7 +111,11 @@ function nextRunForMeta(meta: TriggerFrontmatter): string | undefined {
|
|
|
106
111
|
isValidCron(meta.schedule)
|
|
107
112
|
) {
|
|
108
113
|
try {
|
|
109
|
-
return nextOccurrence(
|
|
114
|
+
return nextOccurrence(
|
|
115
|
+
meta.schedule,
|
|
116
|
+
undefined,
|
|
117
|
+
meta.timezone,
|
|
118
|
+
).toISOString();
|
|
110
119
|
} catch {
|
|
111
120
|
return undefined;
|
|
112
121
|
}
|
|
@@ -194,7 +203,7 @@ async function resourceToAutomationItem(
|
|
|
194
203
|
triggerType: meta.triggerType,
|
|
195
204
|
event: meta.event,
|
|
196
205
|
schedule: meta.schedule || undefined,
|
|
197
|
-
scheduleDescription: scheduleDescription(meta.schedule),
|
|
206
|
+
scheduleDescription: scheduleDescription(meta.schedule, meta.timezone),
|
|
198
207
|
condition: meta.condition,
|
|
199
208
|
mode: meta.mode,
|
|
200
209
|
domain: meta.domain,
|
|
@@ -292,7 +301,11 @@ export async function setAutomationEnabledForOwner(
|
|
|
292
301
|
meta.schedule &&
|
|
293
302
|
isValidCron(meta.schedule)
|
|
294
303
|
) {
|
|
295
|
-
parsed.meta.nextRun = nextOccurrence(
|
|
304
|
+
parsed.meta.nextRun = nextOccurrence(
|
|
305
|
+
meta.schedule,
|
|
306
|
+
undefined,
|
|
307
|
+
meta.timezone,
|
|
308
|
+
).toISOString();
|
|
296
309
|
}
|
|
297
310
|
|
|
298
311
|
const updatedContent = buildJobResourceContent(parsed.meta, parsed.body);
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ViteUserConfig } from "vitest/config";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base vitest config that caps a suite's worker pool at a share of the machine.
|
|
5
|
+
*
|
|
6
|
+
* Vitest sizes its pool at `cores - 1` with no awareness of peer processes, so
|
|
7
|
+
* several suites running at once — concurrent agent sessions, or a workspace
|
|
8
|
+
* running packages in parallel — each try to claim the whole box. Set
|
|
9
|
+
* `VITEST_CONCURRENCY` to a percentage or a worker count to change the lid; a
|
|
10
|
+
* package that needs its own value sets `test.maxWorkers` in its own config,
|
|
11
|
+
* which wins the merge.
|
|
12
|
+
*
|
|
13
|
+
* This ships from core rather than living at the monorepo root because template
|
|
14
|
+
* directories are scaffolded out verbatim as standalone apps — a config that
|
|
15
|
+
* reaches above the template would resolve to nothing in the generated app.
|
|
16
|
+
*
|
|
17
|
+
* Keep this module free of runtime imports so loading it costs a config file
|
|
18
|
+
* nothing beyond reading the environment.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const DEFAULT_MAX_WORKERS = "25%";
|
|
22
|
+
const ENV_KEYS = ["VITEST_CONCURRENCY", "AGENT_NATIVE_VITEST_CONCURRENCY"];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the worker lid from the environment, throwing on anything that is
|
|
26
|
+
* neither a percentage nor a worker count. A bad value must not quietly become
|
|
27
|
+
* the default — that reads as "configured" while running at some other size.
|
|
28
|
+
*/
|
|
29
|
+
export function resolveMaxWorkers(
|
|
30
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
31
|
+
): string | number {
|
|
32
|
+
const rawMaxWorkers = env.VITEST_MAX_WORKERS;
|
|
33
|
+
if (rawMaxWorkers?.includes("%")) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`VITEST_MAX_WORKERS=${rawMaxWorkers} is not a percentage to vitest — it parses as ` +
|
|
36
|
+
`${Number.parseInt(rawMaxWorkers)} workers. Use VITEST_CONCURRENCY for percentages, ` +
|
|
37
|
+
`or an integer for VITEST_MAX_WORKERS.`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const key = ENV_KEYS.find((name) => env[name]);
|
|
42
|
+
if (!key) return DEFAULT_MAX_WORKERS;
|
|
43
|
+
|
|
44
|
+
const value = env[key]!.trim();
|
|
45
|
+
if (/^\d+%$/.test(value)) {
|
|
46
|
+
const percent = Number.parseInt(value);
|
|
47
|
+
if (percent < 1 || percent > 100) {
|
|
48
|
+
throw new Error(`${key}=${value} is out of range — use 1% to 100%.`);
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const count = Number(value);
|
|
54
|
+
if (!Number.isInteger(count) || count < 1) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
`${key}=${value} is not a percentage like "25%" or a worker count like "2".`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return count;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const vitestBaseConfig: ViteUserConfig = {
|
|
63
|
+
test: {
|
|
64
|
+
maxWorkers: resolveMaxWorkers(),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default vitestBaseConfig;
|