@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
|
@@ -263,6 +263,8 @@ export function Sidebar({
|
|
|
263
263
|
>
|
|
264
264
|
<OrgSwitcher
|
|
265
265
|
reserveSpace
|
|
266
|
+
// Tasks does not mount /agent, so the default link would 404.
|
|
267
|
+
agentPath={null}
|
|
266
268
|
className={
|
|
267
269
|
collapsed
|
|
268
270
|
? "h-8 justify-center px-0 [&>span]:sr-only [&>svg:last-child]:hidden"
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
2
2
|
import {
|
|
3
|
+
SettingsGroup,
|
|
4
|
+
SettingsRow,
|
|
3
5
|
SettingsTabsPage,
|
|
4
6
|
useAgentSettingsTabs,
|
|
5
7
|
} from "@agent-native/core/client/settings";
|
|
6
8
|
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
|
|
7
9
|
|
|
8
|
-
import {
|
|
9
|
-
Card,
|
|
10
|
-
CardContent,
|
|
11
|
-
CardDescription,
|
|
12
|
-
CardHeader,
|
|
13
|
-
CardTitle,
|
|
14
|
-
} from "@/components/ui/card";
|
|
15
|
-
import { Label } from "@/components/ui/label";
|
|
16
10
|
import { APP_TITLE } from "@/lib/app-config";
|
|
17
11
|
|
|
18
12
|
export function meta() {
|
|
@@ -33,20 +27,18 @@ export default function SettingsRoute() {
|
|
|
33
27
|
{t("header.pageSettings")}
|
|
34
28
|
</p>
|
|
35
29
|
|
|
36
|
-
<
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</CardContent>
|
|
49
|
-
</Card>
|
|
30
|
+
<SettingsGroup>
|
|
31
|
+
<SettingsRow
|
|
32
|
+
id="language"
|
|
33
|
+
label={t("settings.languageTitle")}
|
|
34
|
+
description={t("settings.languageDescription")}
|
|
35
|
+
control={
|
|
36
|
+
<div className="w-56">
|
|
37
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
38
|
+
</div>
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
</SettingsGroup>
|
|
50
42
|
</div>
|
|
51
43
|
}
|
|
52
44
|
/>
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import baseConfig from "@agent-native/core/vitest-config";
|
|
4
|
+
import { defineConfig, mergeConfig } from "vitest/config";
|
|
4
5
|
|
|
5
|
-
export default
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export default mergeConfig(
|
|
7
|
+
baseConfig,
|
|
8
|
+
defineConfig({
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": path.resolve(__dirname, "./app"),
|
|
12
|
+
"@shared": path.resolve(__dirname, "./shared"),
|
|
13
|
+
},
|
|
10
14
|
},
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
},
|
|
17
|
-
|
|
15
|
+
test: {
|
|
16
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
+
exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/e2e/**"],
|
|
18
|
+
environment: "node",
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
);
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @agent-native/toolkit
|
|
2
2
|
|
|
3
|
+
## 0.12.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f499dff: Add `@agent-native/core/vitest-config`, a base vitest config that caps a suite's
|
|
8
|
+
worker pool so concurrent test runs no longer oversubscribe the CPU. Defaults to
|
|
9
|
+
25% of cores; override with `VITEST_CONCURRENCY`. Every template and package
|
|
10
|
+
config merges it in.
|
|
11
|
+
|
|
3
12
|
## 0.12.1
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
|
@@ -29,6 +29,7 @@ export interface DefineAutomationInput {
|
|
|
29
29
|
triggerType: "schedule" | "event";
|
|
30
30
|
body: string;
|
|
31
31
|
schedule?: string;
|
|
32
|
+
timezone?: string;
|
|
32
33
|
event?: string;
|
|
33
34
|
condition?: string;
|
|
34
35
|
domain?: string;
|
|
@@ -46,6 +47,7 @@ export interface UpdateAutomationInput {
|
|
|
46
47
|
condition?: string | null;
|
|
47
48
|
delegatedPolicyId?: string | null;
|
|
48
49
|
schedule?: string;
|
|
50
|
+
timezone?: string;
|
|
49
51
|
model?: string | null;
|
|
50
52
|
mcpTools?: unknown;
|
|
51
53
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/automations/service.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/automations/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getDbExec } from "../db/client.js";
|
|
2
|
-
import { isValidCron, nextOccurrence } from "../jobs/cron.js";
|
|
2
|
+
import { isValidCron, isValidTimezone, nextOccurrence } from "../jobs/cron.js";
|
|
3
3
|
import { buildJobResourceContent, normalizeJobMcpTools, parseJobResource, } from "../jobs/frontmatter.js";
|
|
4
|
+
import { deleteAutomationRuns } from "../jobs/run-history.js";
|
|
5
|
+
import { resolveUserSchedulingTimezone } from "../localization/user-timezone.js";
|
|
4
6
|
import { organizationIdFromResourceOwner, organizationResourceOwner, resourceDelete, resourceGetByPath, resourceList, resourcePut, } from "../resources/store.js";
|
|
5
7
|
function httpError(message, statusCode) {
|
|
6
8
|
return Object.assign(new Error(message), { statusCode });
|
|
@@ -177,9 +179,18 @@ export async function defineAutomation(actorInput, input) {
|
|
|
177
179
|
if (input.triggerType === "event" && !event) {
|
|
178
180
|
throw httpError("event is required for event-triggered automations.", 400);
|
|
179
181
|
}
|
|
182
|
+
if (input.timezone && !isValidTimezone(input.timezone)) {
|
|
183
|
+
throw httpError(`Unknown timezone "${input.timezone}".`, 400);
|
|
184
|
+
}
|
|
185
|
+
// Resolve now and persist it: a schedule whose zone is implicit means
|
|
186
|
+
// something different the moment it is read on a differently-zoned host.
|
|
187
|
+
const timezone = input.triggerType === "schedule"
|
|
188
|
+
? input.timezone || (await resolveUserSchedulingTimezone(actor.userEmail))
|
|
189
|
+
: undefined;
|
|
180
190
|
const mcpTools = normalizeJobMcpTools(input.mcpTools);
|
|
181
191
|
const meta = {
|
|
182
192
|
schedule: input.triggerType === "schedule" ? schedule : "",
|
|
193
|
+
timezone,
|
|
183
194
|
enabled: true,
|
|
184
195
|
triggerType: input.triggerType,
|
|
185
196
|
event: input.triggerType === "event" ? event : undefined,
|
|
@@ -191,7 +202,7 @@ export async function defineAutomation(actorInput, input) {
|
|
|
191
202
|
orgId: input.scope === "organization" ? actor.orgId : undefined,
|
|
192
203
|
runAs: "creator",
|
|
193
204
|
nextRun: input.triggerType === "schedule"
|
|
194
|
-
? nextOccurrence(schedule).toISOString()
|
|
205
|
+
? nextOccurrence(schedule, undefined, timezone).toISOString()
|
|
195
206
|
: undefined,
|
|
196
207
|
model: input.model?.trim() || undefined,
|
|
197
208
|
mcpTools: mcpTools?.length ? mcpTools : undefined,
|
|
@@ -225,14 +236,25 @@ export async function updateAutomation(actorInput, input) {
|
|
|
225
236
|
throw httpError(`Invalid cron expression "${input.schedule}".`, 400);
|
|
226
237
|
}
|
|
227
238
|
meta.schedule = input.schedule;
|
|
228
|
-
|
|
239
|
+
}
|
|
240
|
+
if (input.timezone !== undefined) {
|
|
241
|
+
if (!isValidTimezone(input.timezone)) {
|
|
242
|
+
throw httpError(`Unknown timezone "${input.timezone}".`, 400);
|
|
243
|
+
}
|
|
244
|
+
if (meta.triggerType !== "schedule") {
|
|
245
|
+
throw httpError("Event automations do not have a timezone.", 400);
|
|
246
|
+
}
|
|
247
|
+
meta.timezone = input.timezone;
|
|
248
|
+
}
|
|
249
|
+
if (input.schedule !== undefined || input.timezone !== undefined) {
|
|
250
|
+
meta.nextRun = nextOccurrence(meta.schedule, undefined, meta.timezone).toISOString();
|
|
229
251
|
}
|
|
230
252
|
if (input.enabled !== undefined) {
|
|
231
253
|
meta.enabled = input.enabled;
|
|
232
254
|
if (input.enabled &&
|
|
233
255
|
meta.triggerType === "schedule" &&
|
|
234
256
|
isValidCron(meta.schedule)) {
|
|
235
|
-
meta.nextRun = nextOccurrence(meta.schedule).toISOString();
|
|
257
|
+
meta.nextRun = nextOccurrence(meta.schedule, undefined, meta.timezone).toISOString();
|
|
236
258
|
}
|
|
237
259
|
}
|
|
238
260
|
if (input.condition !== undefined) {
|
|
@@ -264,6 +286,9 @@ export async function deleteAutomation(actorInput, scope, name) {
|
|
|
264
286
|
throw httpError("Only the automation's creator or an organization admin can delete it.", 403);
|
|
265
287
|
}
|
|
266
288
|
await resourceDelete(definition.resource.id);
|
|
289
|
+
// Names are reusable, so leaving history behind would attach these runs to
|
|
290
|
+
// whatever automation is created under the same name next.
|
|
291
|
+
await deleteAutomationRuns(definition.resource.owner, name);
|
|
267
292
|
}
|
|
268
293
|
/**
|
|
269
294
|
* Resolve the identity used by an explicit automation run.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/automations/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec } from \"../db/client.js\";\nimport { isValidCron, nextOccurrence } from \"../jobs/cron.js\";\nimport {\n buildJobResourceContent,\n normalizeJobMcpTools,\n parseJobResource,\n type JobFrontmatter,\n} from \"../jobs/frontmatter.js\";\nimport {\n organizationIdFromResourceOwner,\n organizationResourceOwner,\n resourceDelete,\n resourceGetByPath,\n resourceList,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\n\nexport type AutomationScope = \"personal\" | \"organization\";\n\nexport interface AutomationActor {\n userEmail: string;\n orgId?: string | null;\n}\n\nexport interface AutomationDefinition {\n resource: Resource;\n name: string;\n scope: AutomationScope;\n meta: JobFrontmatter & {\n triggerType: \"schedule\" | \"event\";\n mode: \"agentic\" | \"deterministic\";\n };\n body: string;\n canUpdate: boolean;\n}\n\nexport interface AutomationDelivery {\n originScopeId?: string;\n platform?: string;\n destination?: string;\n threadRef?: string;\n tenantId?: string;\n}\n\nexport interface DefineAutomationInput {\n name: string;\n scope: AutomationScope;\n triggerType: \"schedule\" | \"event\";\n body: string;\n schedule?: string;\n event?: string;\n condition?: string;\n domain?: string;\n delegatedPolicyId?: string;\n model?: string;\n mcpTools?: unknown;\n delivery?: AutomationDelivery;\n}\n\nexport type DefinedAutomation = Omit<AutomationDefinition, \"resource\">;\n\nexport interface UpdateAutomationInput {\n name: string;\n scope: AutomationScope;\n enabled?: boolean;\n body?: string;\n condition?: string | null;\n delegatedPolicyId?: string | null;\n schedule?: string;\n model?: string | null;\n mcpTools?: unknown;\n}\n\ninterface OrganizationMembership {\n role: string;\n}\n\nfunction httpError(message: string, statusCode: number): Error {\n return Object.assign(new Error(message), { statusCode });\n}\n\nfunction normalizeActor(actor: AutomationActor): AutomationActor {\n const userEmail = actor.userEmail.trim().toLowerCase();\n if (!userEmail) throw httpError(\"Not authenticated.\", 401);\n return { userEmail, orgId: actor.orgId?.trim() || null };\n}\n\nfunction automationName(path: string): string {\n return path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n}\n\nfunction automationPath(name: string): string {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\");\n if (!normalized) {\n throw httpError(\"Automation name is required (lowercase, hyphens).\", 400);\n }\n return `jobs/${normalized}.md`;\n}\n\nfunction ownerForScope(actor: AutomationActor, scope: AutomationScope): string {\n if (scope === \"personal\") return actor.userEmail;\n if (!actor.orgId) {\n throw httpError(\n \"An organization is required for organization automations.\",\n 400,\n );\n }\n return organizationResourceOwner(actor.orgId);\n}\n\nasync function readOrganizationMembership(\n orgId: string,\n email: string,\n): Promise<OrganizationMembership | null> {\n const result = await getDbExec().execute({\n sql: \"SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1\",\n args: [orgId, email.toLowerCase()],\n });\n if (!result.rows.length) return null;\n return { role: String(result.rows[0]?.role ?? \"\").toLowerCase() };\n}\n\nasync function requireOrganizationMembership(\n actor: AutomationActor,\n): Promise<OrganizationMembership> {\n if (!actor.orgId) {\n throw httpError(\n \"An organization is required for organization automations.\",\n 400,\n );\n }\n const membership = await readOrganizationMembership(\n actor.orgId,\n actor.userEmail,\n );\n if (!membership) {\n throw httpError(\"You are no longer a member of this organization.\", 403);\n }\n return membership;\n}\n\nfunction isOrganizationAdmin(membership: OrganizationMembership): boolean {\n return membership.role === \"owner\" || membership.role === \"admin\";\n}\n\nasync function mutationAccess(\n actorInput: AutomationActor,\n resource: Resource,\n meta: JobFrontmatter,\n): Promise<{ actor: AutomationActor; canUpdate: boolean }> {\n const actor = normalizeActor(actorInput);\n const resourceOrgId = organizationIdFromResourceOwner(resource.owner);\n if (!resourceOrgId) {\n return {\n actor,\n canUpdate: resource.owner.toLowerCase() === actor.userEmail,\n };\n }\n if (actor.orgId !== resourceOrgId) {\n return { actor, canUpdate: false };\n }\n const membership = await requireOrganizationMembership(actor);\n const isCreator =\n meta.createdBy?.trim().toLowerCase() === actor.userEmail.toLowerCase();\n return {\n actor,\n canUpdate: isCreator || isOrganizationAdmin(membership),\n };\n}\n\n/**\n * Compatibility adapters may expose both explicit automations and legacy\n * scheduled jobs. Keep their mutation authorization on the same boundary as\n * the canonical service without forcing legacy resources through the explicit\n * automation classifier.\n */\nexport async function canUpdateAutomationResource(\n actorInput: AutomationActor,\n resource: Resource,\n): Promise<boolean> {\n const { meta } = parseJobResource(resource.content);\n return (await mutationAccess(actorInput, resource, meta)).canUpdate;\n}\n\nfunction assertExplicitAutomation(\n resource: Resource,\n): Omit<AutomationDefinition, \"name\" | \"scope\" | \"canUpdate\"> {\n const parsed = parseJobResource(resource.content);\n if (parsed.classification.kind !== \"automation\") {\n throw httpError(\n `\"${automationName(resource.path)}\" is a legacy scheduled job. Use manage-jobs for compatibility.`,\n 400,\n );\n }\n return {\n resource,\n meta: {\n ...parsed.meta,\n triggerType: parsed.classification.triggerType,\n mode: parsed.meta.mode ?? \"agentic\",\n },\n body: parsed.body,\n };\n}\n\nasync function readDefinition(\n actorInput: AutomationActor,\n scope: AutomationScope,\n name: string,\n): Promise<AutomationDefinition> {\n const actor = normalizeActor(actorInput);\n if (scope === \"organization\") await requireOrganizationMembership(actor);\n const owner = ownerForScope(actor, scope);\n const path = automationPath(name);\n const resource = await resourceGetByPath(owner, path);\n if (!resource) {\n throw httpError(`Automation \"${automationName(path)}\" not found.`, 404);\n }\n const definition = assertExplicitAutomation(resource);\n const access = await mutationAccess(actor, resource, definition.meta);\n return {\n ...definition,\n name: automationName(resource.path),\n scope,\n canUpdate: access.canUpdate,\n };\n}\n\nexport async function listAutomationDefinitions(\n actorInput: AutomationActor,\n scope: AutomationScope,\n): Promise<AutomationDefinition[]> {\n const actor = normalizeActor(actorInput);\n const membership =\n scope === \"organization\"\n ? await requireOrganizationMembership(actor)\n : undefined;\n const owner = ownerForScope(actor, scope);\n const resources = await resourceList(owner, \"jobs/\");\n const automations: AutomationDefinition[] = [];\n\n for (const resourceMeta of resources) {\n if (\n !resourceMeta.path.endsWith(\".md\") ||\n resourceMeta.path.endsWith(\".keep\")\n ) {\n continue;\n }\n const resource = await resourceGetByPath(owner, resourceMeta.path);\n if (!resource) continue;\n const parsed = parseJobResource(resource.content);\n if (parsed.classification.kind !== \"automation\") continue;\n const isCreator =\n parsed.meta.createdBy?.trim().toLowerCase() === actor.userEmail;\n automations.push({\n resource,\n name: automationName(resource.path),\n scope,\n meta: {\n ...parsed.meta,\n triggerType: parsed.classification.triggerType,\n mode: parsed.meta.mode ?? \"agentic\",\n },\n body: parsed.body,\n canUpdate:\n scope === \"personal\" ||\n isCreator ||\n (membership ? isOrganizationAdmin(membership) : false),\n });\n }\n\n return automations;\n}\n\nexport async function defineAutomation(\n actorInput: AutomationActor,\n input: DefineAutomationInput,\n): Promise<DefinedAutomation> {\n const actor = normalizeActor(actorInput);\n if (input.scope === \"organization\") {\n await requireOrganizationMembership(actor);\n }\n const owner = ownerForScope(actor, input.scope);\n const path = automationPath(input.name);\n if (await resourceGetByPath(owner, path)) {\n throw httpError(\n `An automation named \"${automationName(path)}\" already exists.`,\n 409,\n );\n }\n const body = input.body.trim();\n if (!body) throw httpError(\"body is required.\", 400);\n\n const schedule = input.schedule?.trim() ?? \"\";\n const event = input.event?.trim() ?? \"\";\n if (input.triggerType === \"schedule\" && !isValidCron(schedule)) {\n throw httpError(\n schedule\n ? `invalid cron expression \"${schedule}\".`\n : \"schedule is required for scheduled automations.\",\n 400,\n );\n }\n if (input.triggerType === \"event\" && !event) {\n throw httpError(\"event is required for event-triggered automations.\", 400);\n }\n\n const mcpTools = normalizeJobMcpTools(input.mcpTools);\n const meta: JobFrontmatter = {\n schedule: input.triggerType === \"schedule\" ? schedule : \"\",\n enabled: true,\n triggerType: input.triggerType,\n event: input.triggerType === \"event\" ? event : undefined,\n condition: input.condition?.trim() || undefined,\n mode: \"agentic\",\n domain: input.domain?.trim() || undefined,\n delegatedPolicyId: input.delegatedPolicyId?.trim() || undefined,\n createdBy: actor.userEmail,\n orgId: input.scope === \"organization\" ? actor.orgId! : undefined,\n runAs: \"creator\",\n nextRun:\n input.triggerType === \"schedule\"\n ? nextOccurrence(schedule).toISOString()\n : undefined,\n model: input.model?.trim() || undefined,\n mcpTools: mcpTools?.length ? mcpTools : undefined,\n originScopeId: input.delivery?.originScopeId,\n deliveryPlatform: input.delivery?.platform,\n deliveryDestination: input.delivery?.destination,\n deliveryThreadRef: input.delivery?.threadRef,\n deliveryTenantId: input.delivery?.tenantId,\n };\n const content = buildJobResourceContent(meta, body);\n await resourcePut(owner, path, content);\n return {\n name: automationName(path),\n scope: input.scope,\n meta: { ...meta, triggerType: input.triggerType, mode: \"agentic\" },\n body,\n canUpdate: true,\n };\n}\n\nexport async function updateAutomation(\n actorInput: AutomationActor,\n input: UpdateAutomationInput,\n): Promise<AutomationDefinition> {\n const definition = await readDefinition(actorInput, input.scope, input.name);\n if (!definition.canUpdate) {\n throw httpError(\n \"Only the automation's creator or an organization admin can update it.\",\n 403,\n );\n }\n const { meta } = definition;\n if (input.schedule !== undefined) {\n if (meta.triggerType !== \"schedule\") {\n throw httpError(\"Event automations do not have a cron schedule.\", 400);\n }\n if (!isValidCron(input.schedule)) {\n throw httpError(`Invalid cron expression \"${input.schedule}\".`, 400);\n }\n meta.schedule = input.schedule;\n meta.nextRun = nextOccurrence(input.schedule).toISOString();\n }\n if (input.enabled !== undefined) {\n meta.enabled = input.enabled;\n if (\n input.enabled &&\n meta.triggerType === \"schedule\" &&\n isValidCron(meta.schedule)\n ) {\n meta.nextRun = nextOccurrence(meta.schedule).toISOString();\n }\n }\n if (input.condition !== undefined) {\n meta.condition = input.condition?.trim() || undefined;\n }\n if (input.delegatedPolicyId !== undefined) {\n meta.delegatedPolicyId = input.delegatedPolicyId?.trim() || undefined;\n }\n if (input.model !== undefined) {\n meta.model = input.model?.trim() || undefined;\n }\n if (input.mcpTools !== undefined) {\n const mcpTools = normalizeJobMcpTools(input.mcpTools);\n meta.mcpTools = mcpTools?.length ? mcpTools : undefined;\n }\n if (input.scope === \"organization\") {\n meta.orgId = organizationIdFromResourceOwner(definition.resource.owner)!;\n meta.runAs = \"creator\";\n }\n const body = input.body === undefined ? definition.body : input.body.trim();\n if (!body) throw httpError(\"Automation body is required.\", 400);\n await resourcePut(\n definition.resource.owner,\n definition.resource.path,\n buildJobResourceContent(meta, body),\n );\n return { ...definition, meta, body };\n}\n\nexport async function deleteAutomation(\n actorInput: AutomationActor,\n scope: AutomationScope,\n name: string,\n): Promise<void> {\n const definition = await readDefinition(actorInput, scope, name);\n if (!definition.canUpdate) {\n throw httpError(\n \"Only the automation's creator or an organization admin can delete it.\",\n 403,\n );\n }\n await resourceDelete(definition.resource.id);\n}\n\nexport interface AutomationExecutionIdentity {\n userEmail: string;\n orgId?: string;\n eventOwner: string;\n}\n\nexport type AutomationExecutionIdentityResult =\n | { ok: true; identity: AutomationExecutionIdentity }\n | { ok: false; reason: string };\n\n/**\n * Resolve the identity used by an explicit automation run.\n *\n * Organization automations are visible through their organization owner, but\n * always execute as their immutable creator. Event dispatchers must also\n * require EventMeta.owner to equal `eventOwner`; organization visibility does\n * not make an event organization-wide.\n */\nexport async function resolveAutomationExecutionIdentity(\n resourceOwner: string,\n meta: JobFrontmatter,\n): Promise<AutomationExecutionIdentityResult> {\n const orgId = organizationIdFromResourceOwner(resourceOwner);\n if (!orgId) {\n const userEmail = (meta.createdBy || resourceOwner).trim().toLowerCase();\n if (!userEmail || userEmail !== resourceOwner.trim().toLowerCase()) {\n return {\n ok: false,\n reason: \"Personal automation creator does not match its owner.\",\n };\n }\n return { ok: true, identity: { userEmail, eventOwner: userEmail } };\n }\n\n const userEmail = meta.createdBy?.trim().toLowerCase();\n if (!userEmail) {\n return {\n ok: false,\n reason: \"Organization automation has no creator identity.\",\n };\n }\n if (meta.runAs !== \"creator\") {\n return {\n ok: false,\n reason: \"Organization automations must run as their creator.\",\n };\n }\n if (meta.orgId && meta.orgId !== orgId) {\n return {\n ok: false,\n reason: \"Organization automation metadata does not match its owner.\",\n };\n }\n\n const user = await getDbExec().execute({\n sql: `SELECT 1 FROM \"user\" WHERE LOWER(email) = ? LIMIT 1`,\n args: [userEmail],\n });\n if (!user.rows.length) {\n return {\n ok: false,\n reason: `Automation creator \"${userEmail}\" no longer exists.`,\n };\n }\n if (!(await readOrganizationMembership(orgId, userEmail))) {\n return {\n ok: false,\n reason: `Automation creator \"${userEmail}\" is no longer a member of organization \"${orgId}\".`,\n };\n }\n return {\n ok: true,\n identity: { userEmail, orgId, eventOwner: userEmail },\n };\n}\n\nexport function automationMatchesEventOwner(\n identity: AutomationExecutionIdentity,\n eventOwner: string | undefined,\n): boolean {\n return (\n typeof eventOwner === \"string\" &&\n eventOwner.trim().toLowerCase() === identity.eventOwner\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/automations/service.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDbExec } from \"../db/client.js\";\nimport { isValidCron, isValidTimezone, nextOccurrence } from \"../jobs/cron.js\";\nimport {\n buildJobResourceContent,\n normalizeJobMcpTools,\n parseJobResource,\n type JobFrontmatter,\n} from \"../jobs/frontmatter.js\";\nimport { deleteAutomationRuns } from \"../jobs/run-history.js\";\nimport { resolveUserSchedulingTimezone } from \"../localization/user-timezone.js\";\nimport {\n organizationIdFromResourceOwner,\n organizationResourceOwner,\n resourceDelete,\n resourceGetByPath,\n resourceList,\n resourcePut,\n type Resource,\n} from \"../resources/store.js\";\n\nexport type AutomationScope = \"personal\" | \"organization\";\n\nexport interface AutomationActor {\n userEmail: string;\n orgId?: string | null;\n}\n\nexport interface AutomationDefinition {\n resource: Resource;\n name: string;\n scope: AutomationScope;\n meta: JobFrontmatter & {\n triggerType: \"schedule\" | \"event\";\n mode: \"agentic\" | \"deterministic\";\n };\n body: string;\n canUpdate: boolean;\n}\n\nexport interface AutomationDelivery {\n originScopeId?: string;\n platform?: string;\n destination?: string;\n threadRef?: string;\n tenantId?: string;\n}\n\nexport interface DefineAutomationInput {\n name: string;\n scope: AutomationScope;\n triggerType: \"schedule\" | \"event\";\n body: string;\n schedule?: string;\n timezone?: string;\n event?: string;\n condition?: string;\n domain?: string;\n delegatedPolicyId?: string;\n model?: string;\n mcpTools?: unknown;\n delivery?: AutomationDelivery;\n}\n\nexport type DefinedAutomation = Omit<AutomationDefinition, \"resource\">;\n\nexport interface UpdateAutomationInput {\n name: string;\n scope: AutomationScope;\n enabled?: boolean;\n body?: string;\n condition?: string | null;\n delegatedPolicyId?: string | null;\n schedule?: string;\n timezone?: string;\n model?: string | null;\n mcpTools?: unknown;\n}\n\ninterface OrganizationMembership {\n role: string;\n}\n\nfunction httpError(message: string, statusCode: number): Error {\n return Object.assign(new Error(message), { statusCode });\n}\n\nfunction normalizeActor(actor: AutomationActor): AutomationActor {\n const userEmail = actor.userEmail.trim().toLowerCase();\n if (!userEmail) throw httpError(\"Not authenticated.\", 401);\n return { userEmail, orgId: actor.orgId?.trim() || null };\n}\n\nfunction automationName(path: string): string {\n return path.replace(/^jobs\\//, \"\").replace(/\\.md$/, \"\");\n}\n\nfunction automationPath(name: string): string {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\");\n if (!normalized) {\n throw httpError(\"Automation name is required (lowercase, hyphens).\", 400);\n }\n return `jobs/${normalized}.md`;\n}\n\nfunction ownerForScope(actor: AutomationActor, scope: AutomationScope): string {\n if (scope === \"personal\") return actor.userEmail;\n if (!actor.orgId) {\n throw httpError(\n \"An organization is required for organization automations.\",\n 400,\n );\n }\n return organizationResourceOwner(actor.orgId);\n}\n\nasync function readOrganizationMembership(\n orgId: string,\n email: string,\n): Promise<OrganizationMembership | null> {\n const result = await getDbExec().execute({\n sql: \"SELECT role FROM org_members WHERE org_id = ? AND LOWER(email) = ? LIMIT 1\",\n args: [orgId, email.toLowerCase()],\n });\n if (!result.rows.length) return null;\n return { role: String(result.rows[0]?.role ?? \"\").toLowerCase() };\n}\n\nasync function requireOrganizationMembership(\n actor: AutomationActor,\n): Promise<OrganizationMembership> {\n if (!actor.orgId) {\n throw httpError(\n \"An organization is required for organization automations.\",\n 400,\n );\n }\n const membership = await readOrganizationMembership(\n actor.orgId,\n actor.userEmail,\n );\n if (!membership) {\n throw httpError(\"You are no longer a member of this organization.\", 403);\n }\n return membership;\n}\n\nfunction isOrganizationAdmin(membership: OrganizationMembership): boolean {\n return membership.role === \"owner\" || membership.role === \"admin\";\n}\n\nasync function mutationAccess(\n actorInput: AutomationActor,\n resource: Resource,\n meta: JobFrontmatter,\n): Promise<{ actor: AutomationActor; canUpdate: boolean }> {\n const actor = normalizeActor(actorInput);\n const resourceOrgId = organizationIdFromResourceOwner(resource.owner);\n if (!resourceOrgId) {\n return {\n actor,\n canUpdate: resource.owner.toLowerCase() === actor.userEmail,\n };\n }\n if (actor.orgId !== resourceOrgId) {\n return { actor, canUpdate: false };\n }\n const membership = await requireOrganizationMembership(actor);\n const isCreator =\n meta.createdBy?.trim().toLowerCase() === actor.userEmail.toLowerCase();\n return {\n actor,\n canUpdate: isCreator || isOrganizationAdmin(membership),\n };\n}\n\n/**\n * Compatibility adapters may expose both explicit automations and legacy\n * scheduled jobs. Keep their mutation authorization on the same boundary as\n * the canonical service without forcing legacy resources through the explicit\n * automation classifier.\n */\nexport async function canUpdateAutomationResource(\n actorInput: AutomationActor,\n resource: Resource,\n): Promise<boolean> {\n const { meta } = parseJobResource(resource.content);\n return (await mutationAccess(actorInput, resource, meta)).canUpdate;\n}\n\nfunction assertExplicitAutomation(\n resource: Resource,\n): Omit<AutomationDefinition, \"name\" | \"scope\" | \"canUpdate\"> {\n const parsed = parseJobResource(resource.content);\n if (parsed.classification.kind !== \"automation\") {\n throw httpError(\n `\"${automationName(resource.path)}\" is a legacy scheduled job. Use manage-jobs for compatibility.`,\n 400,\n );\n }\n return {\n resource,\n meta: {\n ...parsed.meta,\n triggerType: parsed.classification.triggerType,\n mode: parsed.meta.mode ?? \"agentic\",\n },\n body: parsed.body,\n };\n}\n\nasync function readDefinition(\n actorInput: AutomationActor,\n scope: AutomationScope,\n name: string,\n): Promise<AutomationDefinition> {\n const actor = normalizeActor(actorInput);\n if (scope === \"organization\") await requireOrganizationMembership(actor);\n const owner = ownerForScope(actor, scope);\n const path = automationPath(name);\n const resource = await resourceGetByPath(owner, path);\n if (!resource) {\n throw httpError(`Automation \"${automationName(path)}\" not found.`, 404);\n }\n const definition = assertExplicitAutomation(resource);\n const access = await mutationAccess(actor, resource, definition.meta);\n return {\n ...definition,\n name: automationName(resource.path),\n scope,\n canUpdate: access.canUpdate,\n };\n}\n\nexport async function listAutomationDefinitions(\n actorInput: AutomationActor,\n scope: AutomationScope,\n): Promise<AutomationDefinition[]> {\n const actor = normalizeActor(actorInput);\n const membership =\n scope === \"organization\"\n ? await requireOrganizationMembership(actor)\n : undefined;\n const owner = ownerForScope(actor, scope);\n const resources = await resourceList(owner, \"jobs/\");\n const automations: AutomationDefinition[] = [];\n\n for (const resourceMeta of resources) {\n if (\n !resourceMeta.path.endsWith(\".md\") ||\n resourceMeta.path.endsWith(\".keep\")\n ) {\n continue;\n }\n const resource = await resourceGetByPath(owner, resourceMeta.path);\n if (!resource) continue;\n const parsed = parseJobResource(resource.content);\n if (parsed.classification.kind !== \"automation\") continue;\n const isCreator =\n parsed.meta.createdBy?.trim().toLowerCase() === actor.userEmail;\n automations.push({\n resource,\n name: automationName(resource.path),\n scope,\n meta: {\n ...parsed.meta,\n triggerType: parsed.classification.triggerType,\n mode: parsed.meta.mode ?? \"agentic\",\n },\n body: parsed.body,\n canUpdate:\n scope === \"personal\" ||\n isCreator ||\n (membership ? isOrganizationAdmin(membership) : false),\n });\n }\n\n return automations;\n}\n\nexport async function defineAutomation(\n actorInput: AutomationActor,\n input: DefineAutomationInput,\n): Promise<DefinedAutomation> {\n const actor = normalizeActor(actorInput);\n if (input.scope === \"organization\") {\n await requireOrganizationMembership(actor);\n }\n const owner = ownerForScope(actor, input.scope);\n const path = automationPath(input.name);\n if (await resourceGetByPath(owner, path)) {\n throw httpError(\n `An automation named \"${automationName(path)}\" already exists.`,\n 409,\n );\n }\n const body = input.body.trim();\n if (!body) throw httpError(\"body is required.\", 400);\n\n const schedule = input.schedule?.trim() ?? \"\";\n const event = input.event?.trim() ?? \"\";\n if (input.triggerType === \"schedule\" && !isValidCron(schedule)) {\n throw httpError(\n schedule\n ? `invalid cron expression \"${schedule}\".`\n : \"schedule is required for scheduled automations.\",\n 400,\n );\n }\n if (input.triggerType === \"event\" && !event) {\n throw httpError(\"event is required for event-triggered automations.\", 400);\n }\n\n if (input.timezone && !isValidTimezone(input.timezone)) {\n throw httpError(`Unknown timezone \"${input.timezone}\".`, 400);\n }\n // Resolve now and persist it: a schedule whose zone is implicit means\n // something different the moment it is read on a differently-zoned host.\n const timezone =\n input.triggerType === \"schedule\"\n ? input.timezone || (await resolveUserSchedulingTimezone(actor.userEmail))\n : undefined;\n\n const mcpTools = normalizeJobMcpTools(input.mcpTools);\n const meta: JobFrontmatter = {\n schedule: input.triggerType === \"schedule\" ? schedule : \"\",\n timezone,\n enabled: true,\n triggerType: input.triggerType,\n event: input.triggerType === \"event\" ? event : undefined,\n condition: input.condition?.trim() || undefined,\n mode: \"agentic\",\n domain: input.domain?.trim() || undefined,\n delegatedPolicyId: input.delegatedPolicyId?.trim() || undefined,\n createdBy: actor.userEmail,\n orgId: input.scope === \"organization\" ? actor.orgId! : undefined,\n runAs: \"creator\",\n nextRun:\n input.triggerType === \"schedule\"\n ? nextOccurrence(schedule, undefined, timezone).toISOString()\n : undefined,\n model: input.model?.trim() || undefined,\n mcpTools: mcpTools?.length ? mcpTools : undefined,\n originScopeId: input.delivery?.originScopeId,\n deliveryPlatform: input.delivery?.platform,\n deliveryDestination: input.delivery?.destination,\n deliveryThreadRef: input.delivery?.threadRef,\n deliveryTenantId: input.delivery?.tenantId,\n };\n const content = buildJobResourceContent(meta, body);\n await resourcePut(owner, path, content);\n return {\n name: automationName(path),\n scope: input.scope,\n meta: { ...meta, triggerType: input.triggerType, mode: \"agentic\" },\n body,\n canUpdate: true,\n };\n}\n\nexport async function updateAutomation(\n actorInput: AutomationActor,\n input: UpdateAutomationInput,\n): Promise<AutomationDefinition> {\n const definition = await readDefinition(actorInput, input.scope, input.name);\n if (!definition.canUpdate) {\n throw httpError(\n \"Only the automation's creator or an organization admin can update it.\",\n 403,\n );\n }\n const { meta } = definition;\n if (input.schedule !== undefined) {\n if (meta.triggerType !== \"schedule\") {\n throw httpError(\"Event automations do not have a cron schedule.\", 400);\n }\n if (!isValidCron(input.schedule)) {\n throw httpError(`Invalid cron expression \"${input.schedule}\".`, 400);\n }\n meta.schedule = input.schedule;\n }\n if (input.timezone !== undefined) {\n if (!isValidTimezone(input.timezone)) {\n throw httpError(`Unknown timezone \"${input.timezone}\".`, 400);\n }\n if (meta.triggerType !== \"schedule\") {\n throw httpError(\"Event automations do not have a timezone.\", 400);\n }\n meta.timezone = input.timezone;\n }\n if (input.schedule !== undefined || input.timezone !== undefined) {\n meta.nextRun = nextOccurrence(\n meta.schedule,\n undefined,\n meta.timezone,\n ).toISOString();\n }\n if (input.enabled !== undefined) {\n meta.enabled = input.enabled;\n if (\n input.enabled &&\n meta.triggerType === \"schedule\" &&\n isValidCron(meta.schedule)\n ) {\n meta.nextRun = nextOccurrence(\n meta.schedule,\n undefined,\n meta.timezone,\n ).toISOString();\n }\n }\n if (input.condition !== undefined) {\n meta.condition = input.condition?.trim() || undefined;\n }\n if (input.delegatedPolicyId !== undefined) {\n meta.delegatedPolicyId = input.delegatedPolicyId?.trim() || undefined;\n }\n if (input.model !== undefined) {\n meta.model = input.model?.trim() || undefined;\n }\n if (input.mcpTools !== undefined) {\n const mcpTools = normalizeJobMcpTools(input.mcpTools);\n meta.mcpTools = mcpTools?.length ? mcpTools : undefined;\n }\n if (input.scope === \"organization\") {\n meta.orgId = organizationIdFromResourceOwner(definition.resource.owner)!;\n meta.runAs = \"creator\";\n }\n const body = input.body === undefined ? definition.body : input.body.trim();\n if (!body) throw httpError(\"Automation body is required.\", 400);\n await resourcePut(\n definition.resource.owner,\n definition.resource.path,\n buildJobResourceContent(meta, body),\n );\n return { ...definition, meta, body };\n}\n\nexport async function deleteAutomation(\n actorInput: AutomationActor,\n scope: AutomationScope,\n name: string,\n): Promise<void> {\n const definition = await readDefinition(actorInput, scope, name);\n if (!definition.canUpdate) {\n throw httpError(\n \"Only the automation's creator or an organization admin can delete it.\",\n 403,\n );\n }\n await resourceDelete(definition.resource.id);\n // Names are reusable, so leaving history behind would attach these runs to\n // whatever automation is created under the same name next.\n await deleteAutomationRuns(definition.resource.owner, name);\n}\n\nexport interface AutomationExecutionIdentity {\n userEmail: string;\n orgId?: string;\n eventOwner: string;\n}\n\nexport type AutomationExecutionIdentityResult =\n | { ok: true; identity: AutomationExecutionIdentity }\n | { ok: false; reason: string };\n\n/**\n * Resolve the identity used by an explicit automation run.\n *\n * Organization automations are visible through their organization owner, but\n * always execute as their immutable creator. Event dispatchers must also\n * require EventMeta.owner to equal `eventOwner`; organization visibility does\n * not make an event organization-wide.\n */\nexport async function resolveAutomationExecutionIdentity(\n resourceOwner: string,\n meta: JobFrontmatter,\n): Promise<AutomationExecutionIdentityResult> {\n const orgId = organizationIdFromResourceOwner(resourceOwner);\n if (!orgId) {\n const userEmail = (meta.createdBy || resourceOwner).trim().toLowerCase();\n if (!userEmail || userEmail !== resourceOwner.trim().toLowerCase()) {\n return {\n ok: false,\n reason: \"Personal automation creator does not match its owner.\",\n };\n }\n return { ok: true, identity: { userEmail, eventOwner: userEmail } };\n }\n\n const userEmail = meta.createdBy?.trim().toLowerCase();\n if (!userEmail) {\n return {\n ok: false,\n reason: \"Organization automation has no creator identity.\",\n };\n }\n if (meta.runAs !== \"creator\") {\n return {\n ok: false,\n reason: \"Organization automations must run as their creator.\",\n };\n }\n if (meta.orgId && meta.orgId !== orgId) {\n return {\n ok: false,\n reason: \"Organization automation metadata does not match its owner.\",\n };\n }\n\n const user = await getDbExec().execute({\n sql: `SELECT 1 FROM \"user\" WHERE LOWER(email) = ? LIMIT 1`,\n args: [userEmail],\n });\n if (!user.rows.length) {\n return {\n ok: false,\n reason: `Automation creator \"${userEmail}\" no longer exists.`,\n };\n }\n if (!(await readOrganizationMembership(orgId, userEmail))) {\n return {\n ok: false,\n reason: `Automation creator \"${userEmail}\" is no longer a member of organization \"${orgId}\".`,\n };\n }\n return {\n ok: true,\n identity: { userEmail, orgId, eventOwner: userEmail },\n };\n}\n\nexport function automationMatchesEventOwner(\n identity: AutomationExecutionIdentity,\n eventOwner: string | undefined,\n): boolean {\n return (\n typeof eventOwner === \"string\" &&\n eventOwner.trim().toLowerCase() === identity.eventOwner\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-config-writers.d.ts","sourceRoot":"","sources":["../../src/cli/mcp-config-writers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AASH,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,iBAAiB,GACjB,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,gBAAgB,CAAC;AAErB,eAAO,MAAM,OAAO,EAAE,QAAQ,EAQ7B,CAAC;AAEF,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,YAAY,CAUd;AAYD,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6BzB;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,QAAQ,EAChB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,SAAiB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAIxC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAmBhD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,CAwBR;
|
|
1
|
+
{"version":3,"file":"mcp-config-writers.d.ts","sourceRoot":"","sources":["../../src/cli/mcp-config-writers.ts"],"names":[],"mappings":"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"}
|
|
@@ -191,6 +191,23 @@ export function configPathFor(client, baseDir, scope) {
|
|
|
191
191
|
// ---------------------------------------------------------------------------
|
|
192
192
|
// JSON client configs (Claude Code, Claude Code CLI, Cowork)
|
|
193
193
|
// ---------------------------------------------------------------------------
|
|
194
|
+
/**
|
|
195
|
+
* Read an existing MCP config without conflating missing and unreadable files.
|
|
196
|
+
* Only ENOENT means the config is absent; any other read failure must abort
|
|
197
|
+
* before a caller can overwrite existing user configuration.
|
|
198
|
+
*/
|
|
199
|
+
function readExistingConfigFile(file) {
|
|
200
|
+
try {
|
|
201
|
+
return fs.readFileSync(file, "utf-8");
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
if (error.code === "ENOENT")
|
|
205
|
+
return undefined;
|
|
206
|
+
const detail = error instanceof Error ? ` (${error.message})` : "";
|
|
207
|
+
throw new Error(`Cannot read MCP config file: ${file}\n` +
|
|
208
|
+
`Check that the file is readable and re-run. The file has not been modified.${detail}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
194
211
|
/**
|
|
195
212
|
* Read and parse a JSON config file.
|
|
196
213
|
*
|
|
@@ -201,14 +218,9 @@ export function configPathFor(client, baseDir, scope) {
|
|
|
201
218
|
* file with only the new MCP entry (data-loss hazard).
|
|
202
219
|
*/
|
|
203
220
|
function readJsonFile(file) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
raw = fs.readFileSync(file, "utf-8");
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
// Missing (ENOENT) or unreadable file — treat as empty.
|
|
221
|
+
const raw = readExistingConfigFile(file);
|
|
222
|
+
if (raw === undefined)
|
|
210
223
|
return {};
|
|
211
|
-
}
|
|
212
224
|
if (!raw.trim())
|
|
213
225
|
return {};
|
|
214
226
|
try {
|
|
@@ -480,13 +492,7 @@ export function buildCodexLocalBlock(name, args, env, command = "agent-native")
|
|
|
480
492
|
* Identical algorithm to `mcp.ts`'s `writeCodexBlock` so the two never diverge.
|
|
481
493
|
*/
|
|
482
494
|
export function writeCodexBlock(file, name, block) {
|
|
483
|
-
|
|
484
|
-
try {
|
|
485
|
-
content = fs.readFileSync(file, "utf-8");
|
|
486
|
-
}
|
|
487
|
-
catch {
|
|
488
|
-
content = "";
|
|
489
|
-
}
|
|
495
|
+
const content = readExistingConfigFile(file) ?? "";
|
|
490
496
|
const lines = content.split(/\r?\n/);
|
|
491
497
|
const out = [];
|
|
492
498
|
let i = 0;
|
|
@@ -520,15 +526,10 @@ export function writeCodexBlock(file, name, block) {
|
|
|
520
526
|
writeFileAtomic(file, next);
|
|
521
527
|
}
|
|
522
528
|
export function codexHasBlock(file, name) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
.some((line) => codexServerNameOfHeader(line) === name);
|
|
528
|
-
}
|
|
529
|
-
catch {
|
|
530
|
-
return false;
|
|
531
|
-
}
|
|
529
|
+
const content = readExistingConfigFile(file);
|
|
530
|
+
return (content
|
|
531
|
+
?.split(/\r?\n/)
|
|
532
|
+
.some((line) => codexServerNameOfHeader(line) === name) ?? false);
|
|
532
533
|
}
|
|
533
534
|
// ---------------------------------------------------------------------------
|
|
534
535
|
// Unified write helper
|