@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
|
@@ -3055,6 +3055,10 @@ const enUS = {
|
|
|
3055
3055
|
metaTitle: "Settings - Content",
|
|
3056
3056
|
title: "Settings",
|
|
3057
3057
|
description: "Language and workspace preferences for Content.",
|
|
3058
|
+
emailNotifications: "Email notifications",
|
|
3059
|
+
emailNotificationsDescription:
|
|
3060
|
+
"Get an email when someone comments on, replies in, or mentions you on your document.",
|
|
3061
|
+
saveFailed: "Failed to save",
|
|
3058
3062
|
languageTitle: "Language",
|
|
3059
3063
|
languageDescription:
|
|
3060
3064
|
"Choose the interface language. This preference is saved for your account.",
|
|
@@ -3116,9 +3120,12 @@ const enUS = {
|
|
|
3116
3120
|
liveDocumentSaveBeforeSyncFailed:
|
|
3117
3121
|
"The live document could not be saved before syncing.",
|
|
3118
3122
|
documentTitle: "Document title",
|
|
3119
|
-
builderBodySyncing: "
|
|
3123
|
+
builderBodySyncing: "This page's content is still syncing from Builder",
|
|
3120
3124
|
builderBodySyncingDescription:
|
|
3121
3125
|
"Editing is paused until the Builder body finishes syncing, so the existing article content is not overwritten.",
|
|
3126
|
+
pageBodySyncing: "This page's content is still syncing",
|
|
3127
|
+
pageBodySyncingDescription:
|
|
3128
|
+
"Editing is paused until the page body finishes syncing, so existing content is not overwritten.",
|
|
3122
3129
|
localFileSavedHistoryNotUpdated:
|
|
3123
3130
|
"Local file saved, but history was not updated",
|
|
3124
3131
|
reorderField: "Reorder {{name}}",
|
|
@@ -5611,6 +5618,9 @@ const editorMessagesByLocale = {
|
|
|
5611
5618
|
builderBodySyncing: "内容仍在从 Builder 同步",
|
|
5612
5619
|
builderBodySyncingDescription:
|
|
5613
5620
|
"同步 Builder 正文完成前会暂停编辑,避免覆盖现有文章内容。",
|
|
5621
|
+
pageBodySyncing: "此页面的内容仍在同步",
|
|
5622
|
+
pageBodySyncingDescription:
|
|
5623
|
+
"在页面正文完成同步之前,编辑会暂停,以免覆盖现有内容。",
|
|
5614
5624
|
creatingDatabase: "正在创建内联数据库...",
|
|
5615
5625
|
databaseCreated: "内联数据库已创建",
|
|
5616
5626
|
emptyBlockPlaceholder: "按“/”使用命令",
|
|
@@ -5956,6 +5966,9 @@ const editorMessagesByLocale = {
|
|
|
5956
5966
|
builderBodySyncing: "El contenido aún se está sincronizando desde Builder",
|
|
5957
5967
|
builderBodySyncingDescription:
|
|
5958
5968
|
"La edición está en pausa hasta que el cuerpo de Builder termine de sincronizarse, para no sobrescribir el contenido existente del artículo.",
|
|
5969
|
+
pageBodySyncing: "El contenido de esta página aún se está sincronizando",
|
|
5970
|
+
pageBodySyncingDescription:
|
|
5971
|
+
"La edición está en pausa hasta que el contenido de la página termine de sincronizarse, para no sobrescribir el contenido existente.",
|
|
5959
5972
|
creatingDatabase: "Creando base de datos integrada...",
|
|
5960
5973
|
databaseCreated: "Base de datos integrada creada",
|
|
5961
5974
|
emptyBlockPlaceholder: "Pulsa «/» para ver los comandos",
|
|
@@ -6313,6 +6326,10 @@ const editorMessagesByLocale = {
|
|
|
6313
6326
|
"Le contenu est encore en cours de synchronisation depuis Builder",
|
|
6314
6327
|
builderBodySyncingDescription:
|
|
6315
6328
|
"La modification est suspendue jusqu'à la fin de la synchronisation du corps Builder, afin de ne pas écraser le contenu existant de l'article.",
|
|
6329
|
+
pageBodySyncing:
|
|
6330
|
+
"Le contenu de cette page est encore en cours de synchronisation",
|
|
6331
|
+
pageBodySyncingDescription:
|
|
6332
|
+
"La modification est suspendue jusqu'à la fin de la synchronisation du contenu de la page, afin de ne pas écraser le contenu existant.",
|
|
6316
6333
|
creatingDatabase: "Création d'une base de données intégrée...",
|
|
6317
6334
|
databaseCreated: "Base de données intégrée créée",
|
|
6318
6335
|
emptyBlockPlaceholder: "Appuyez sur « / » pour afficher les commandes",
|
|
@@ -6672,6 +6689,9 @@ const editorMessagesByLocale = {
|
|
|
6672
6689
|
builderBodySyncing: "Inhalte werden noch von Builder synchronisiert",
|
|
6673
6690
|
builderBodySyncingDescription:
|
|
6674
6691
|
"Die Bearbeitung ist pausiert, bis der Builder-Textkörper fertig synchronisiert ist, damit der bestehende Artikelinhalt nicht überschrieben wird.",
|
|
6692
|
+
pageBodySyncing: "Der Inhalt dieser Seite wird noch synchronisiert",
|
|
6693
|
+
pageBodySyncingDescription:
|
|
6694
|
+
"Die Bearbeitung ist pausiert, bis der Seiteninhalt fertig synchronisiert ist, damit bestehende Inhalte nicht überschrieben werden.",
|
|
6675
6695
|
creatingDatabase: "Inline-Datenbank wird erstellt...",
|
|
6676
6696
|
databaseCreated: "Inline-Datenbank erstellt",
|
|
6677
6697
|
emptyBlockPlaceholder: "Drücke „/“ für Befehle",
|
|
@@ -7036,6 +7056,9 @@ const editorMessagesByLocale = {
|
|
|
7036
7056
|
builderBodySyncing: "コンテンツはまだ Builder から同期中です",
|
|
7037
7057
|
builderBodySyncingDescription:
|
|
7038
7058
|
"既存の記事内容を上書きしないよう、Builder 本文の同期が完了するまで編集は一時停止されます。",
|
|
7059
|
+
pageBodySyncing: "このページのコンテンツはまだ同期中です",
|
|
7060
|
+
pageBodySyncingDescription:
|
|
7061
|
+
"既存のコンテンツを上書きしないよう、ページ本文の同期が完了するまで編集は一時停止されます。",
|
|
7039
7062
|
creatingDatabase: "インラインデータベースを作成しています...",
|
|
7040
7063
|
databaseCreated: "インラインデータベースが作成されました",
|
|
7041
7064
|
emptyBlockPlaceholder: "「/」でコマンドを表示",
|
|
@@ -7389,6 +7412,9 @@ const editorMessagesByLocale = {
|
|
|
7389
7412
|
builderBodySyncing: "콘텐츠가 아직 Builder에서 동기화되는 중입니다",
|
|
7390
7413
|
builderBodySyncingDescription:
|
|
7391
7414
|
"기존 문서 내용을 덮어쓰지 않도록 Builder 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
|
|
7415
|
+
pageBodySyncing: "이 페이지의 콘텐츠가 아직 동기화 중입니다",
|
|
7416
|
+
pageBodySyncingDescription:
|
|
7417
|
+
"기존 콘텐츠를 덮어쓰지 않도록 페이지 본문 동기화가 완료될 때까지 편집이 일시 중지됩니다.",
|
|
7392
7418
|
creatingDatabase: "인라인 데이터베이스 생성 중...",
|
|
7393
7419
|
databaseCreated: "인라인 데이터베이스가 생성되었습니다.",
|
|
7394
7420
|
emptyBlockPlaceholder: "‘/’를 눌러 명령 사용",
|
|
@@ -7741,6 +7767,9 @@ const editorMessagesByLocale = {
|
|
|
7741
7767
|
builderBodySyncing: "O conteúdo ainda está sincronizando do Builder",
|
|
7742
7768
|
builderBodySyncingDescription:
|
|
7743
7769
|
"A edição fica pausada até o corpo do Builder terminar de sincronizar, para não sobrescrever o conteúdo existente do artigo.",
|
|
7770
|
+
pageBodySyncing: "O conteúdo desta página ainda está sincronizando",
|
|
7771
|
+
pageBodySyncingDescription:
|
|
7772
|
+
"A edição fica pausada até o conteúdo da página terminar de sincronizar, para não sobrescrever o conteúdo existente.",
|
|
7744
7773
|
creatingDatabase: "Criando banco de dados embutido...",
|
|
7745
7774
|
databaseCreated: "Banco de dados embutido criado",
|
|
7746
7775
|
emptyBlockPlaceholder: "Pressione “/” para comandos",
|
|
@@ -8099,6 +8128,9 @@ const editorMessagesByLocale = {
|
|
|
8099
8128
|
builderBodySyncing: "सामग्री अभी भी Builder से सिंक हो रही है",
|
|
8100
8129
|
builderBodySyncingDescription:
|
|
8101
8130
|
"Builder का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा लेख सामग्री अधिलेखित न हो।",
|
|
8131
|
+
pageBodySyncing: "इस पेज की सामग्री अभी भी सिंक हो रही है",
|
|
8132
|
+
pageBodySyncingDescription:
|
|
8133
|
+
"पेज का मुख्य भाग सिंक पूरा होने तक संपादन रोका गया है, ताकि मौजूदा सामग्री अधिलेखित न हो।",
|
|
8102
8134
|
creatingDatabase: "इनलाइन डेटाबेस बनाया जा रहा है...",
|
|
8103
8135
|
databaseCreated: "इनलाइन डेटाबेस बनाया गया",
|
|
8104
8136
|
emptyBlockPlaceholder: "कमांड के लिए '/' दबाएं",
|
|
@@ -8446,6 +8478,9 @@ const editorMessagesByLocale = {
|
|
|
8446
8478
|
builderBodySyncing: "لا يزال المحتوى قيد المزامنة من Builder",
|
|
8447
8479
|
builderBodySyncingDescription:
|
|
8448
8480
|
"يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة نص Builder، حتى لا يتم استبدال محتوى المقالة الحالي.",
|
|
8481
|
+
pageBodySyncing: "لا يزال محتوى هذه الصفحة قيد المزامنة",
|
|
8482
|
+
pageBodySyncingDescription:
|
|
8483
|
+
"يتم إيقاف التحرير مؤقتًا حتى تكتمل مزامنة محتوى الصفحة، حتى لا تتم الكتابة فوق المحتوى الحالي.",
|
|
8449
8484
|
creatingDatabase: "جارٍ إنشاء قاعدة بيانات مضمنة...",
|
|
8450
8485
|
databaseCreated: "تم إنشاء قاعدة البيانات المضمنة",
|
|
8451
8486
|
emptyBlockPlaceholder: 'اضغط على "/" للأوامر',
|
|
@@ -9133,6 +9168,10 @@ export const messagesByLocale = {
|
|
|
9133
9168
|
settings: {
|
|
9134
9169
|
title: "设置",
|
|
9135
9170
|
description: "Content 的语言和工作区偏好设置。",
|
|
9171
|
+
emailNotifications: "邮件通知",
|
|
9172
|
+
emailNotificationsDescription:
|
|
9173
|
+
"当有人评论你的文档、在讨论串中回复或提到你时,收到邮件通知。",
|
|
9174
|
+
saveFailed: "保存失败",
|
|
9136
9175
|
languageTitle: "语言",
|
|
9137
9176
|
languageDescription: "选择界面语言。此偏好会保存到你的账户。",
|
|
9138
9177
|
languageLabel: "界面语言",
|
|
@@ -9325,6 +9364,10 @@ export const messagesByLocale = {
|
|
|
9325
9364
|
settings: {
|
|
9326
9365
|
title: "Ajustes",
|
|
9327
9366
|
description: "Preferencias de idioma y espacio de trabajo para Content.",
|
|
9367
|
+
emailNotifications: "Notificaciones por correo",
|
|
9368
|
+
emailNotificationsDescription:
|
|
9369
|
+
"Recibe un correo cuando alguien comente, responda o te mencione en tu documento.",
|
|
9370
|
+
saveFailed: "No se pudo guardar",
|
|
9328
9371
|
languageTitle: "Idioma",
|
|
9329
9372
|
languageDescription:
|
|
9330
9373
|
"Elige el idioma de la interfaz. Esta preferencia se guarda en tu cuenta.",
|
|
@@ -9524,6 +9567,10 @@ export const messagesByLocale = {
|
|
|
9524
9567
|
settings: {
|
|
9525
9568
|
title: "Paramètres",
|
|
9526
9569
|
description: "Préférences de langue et d’espace de travail pour Content.",
|
|
9570
|
+
emailNotifications: "Notifications par e-mail",
|
|
9571
|
+
emailNotificationsDescription:
|
|
9572
|
+
"Recevez un e-mail lorsqu’une personne commente, répond ou vous mentionne dans votre document.",
|
|
9573
|
+
saveFailed: "Échec de l’enregistrement",
|
|
9527
9574
|
languageTitle: "Langue",
|
|
9528
9575
|
languageDescription:
|
|
9529
9576
|
"Choisissez la langue de l’interface. Cette préférence est enregistrée dans votre compte.",
|
|
@@ -9721,6 +9768,10 @@ export const messagesByLocale = {
|
|
|
9721
9768
|
settings: {
|
|
9722
9769
|
title: "Einstellungen",
|
|
9723
9770
|
description: "Sprach- und Arbeitsbereichseinstellungen für Content.",
|
|
9771
|
+
emailNotifications: "E-Mail-Benachrichtigungen",
|
|
9772
|
+
emailNotificationsDescription:
|
|
9773
|
+
"Erhalte eine E-Mail, wenn jemand dein Dokument kommentiert, antwortet oder dich erwähnt.",
|
|
9774
|
+
saveFailed: "Speichern fehlgeschlagen",
|
|
9724
9775
|
languageTitle: "Sprache",
|
|
9725
9776
|
languageDescription:
|
|
9726
9777
|
"Wähle die Sprache der Oberfläche. Diese Einstellung wird in deinem Konto gespeichert.",
|
|
@@ -9917,6 +9968,10 @@ export const messagesByLocale = {
|
|
|
9917
9968
|
settings: {
|
|
9918
9969
|
title: "設定",
|
|
9919
9970
|
description: "Content の言語とワークスペース設定。",
|
|
9971
|
+
emailNotifications: "メール通知",
|
|
9972
|
+
emailNotificationsDescription:
|
|
9973
|
+
"誰かがあなたのドキュメントにコメント、返信、またはあなたにメンションしたときにメールを受け取ります。",
|
|
9974
|
+
saveFailed: "保存に失敗しました",
|
|
9920
9975
|
languageTitle: "言語",
|
|
9921
9976
|
languageDescription:
|
|
9922
9977
|
"インターフェース言語を選択します。この設定はアカウントに保存されます。",
|
|
@@ -10105,6 +10160,10 @@ export const messagesByLocale = {
|
|
|
10105
10160
|
settings: {
|
|
10106
10161
|
title: "설정",
|
|
10107
10162
|
description: "Content의 언어 및 워크스페이스 환경설정입니다.",
|
|
10163
|
+
emailNotifications: "이메일 알림",
|
|
10164
|
+
emailNotificationsDescription:
|
|
10165
|
+
"누군가 내 문서에 댓글을 달거나 답글을 남기거나 나를 멘션하면 이메일을 받습니다.",
|
|
10166
|
+
saveFailed: "저장 실패",
|
|
10108
10167
|
languageTitle: "언어",
|
|
10109
10168
|
languageDescription:
|
|
10110
10169
|
"인터페이스 언어를 선택하세요. 이 기본 설정은 계정에 저장됩니다.",
|
|
@@ -10299,6 +10358,10 @@ export const messagesByLocale = {
|
|
|
10299
10358
|
settings: {
|
|
10300
10359
|
title: "Configurações",
|
|
10301
10360
|
description: "Preferências de idioma e espaço de trabalho do Content.",
|
|
10361
|
+
emailNotifications: "Notificações por e-mail",
|
|
10362
|
+
emailNotificationsDescription:
|
|
10363
|
+
"Receba um e-mail quando alguém comentar, responder ou mencionar você no seu documento.",
|
|
10364
|
+
saveFailed: "Falha ao salvar",
|
|
10302
10365
|
languageTitle: "Idioma",
|
|
10303
10366
|
languageDescription:
|
|
10304
10367
|
"Escolha o idioma da interface. Essa preferência é salva na sua conta.",
|
|
@@ -10486,6 +10549,10 @@ export const messagesByLocale = {
|
|
|
10486
10549
|
settings: {
|
|
10487
10550
|
title: "सेटिंग्स",
|
|
10488
10551
|
description: "Content के लिए भाषा और कार्यस्थान प्राथमिकताएं।",
|
|
10552
|
+
emailNotifications: "ईमेल सूचनाएँ",
|
|
10553
|
+
emailNotificationsDescription:
|
|
10554
|
+
"जब कोई आपके दस्तावेज़ पर टिप्पणी करे, जवाब दे या आपका उल्लेख करे तो ईमेल पाएँ।",
|
|
10555
|
+
saveFailed: "सहेजने में विफल",
|
|
10489
10556
|
languageTitle: "भाषा",
|
|
10490
10557
|
languageDescription: "इंटरफ़ेस भाषा चुनें। यह पसंद आपके खाते में सहेजी जाती है।",
|
|
10491
10558
|
languageLabel: "इंटरफ़ेस भाषा",
|
|
@@ -10672,6 +10739,10 @@ export const messagesByLocale = {
|
|
|
10672
10739
|
settings: {
|
|
10673
10740
|
title: "الإعدادات",
|
|
10674
10741
|
description: "تفضيلات اللغة ومساحة العمل في Content.",
|
|
10742
|
+
emailNotifications: "إشعارات البريد الإلكتروني",
|
|
10743
|
+
emailNotificationsDescription:
|
|
10744
|
+
"احصل على بريد إلكتروني عندما يعلّق شخص على مستندك أو يرد أو يذكرك.",
|
|
10745
|
+
saveFailed: "فشل الحفظ",
|
|
10675
10746
|
languageTitle: "اللغة",
|
|
10676
10747
|
languageDescription: "اختر لغة الواجهة. يتم حفظ هذا التفضيل في حسابك.",
|
|
10677
10748
|
languageLabel: "لغة الواجهة",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface DocumentQueryContext {
|
|
2
|
+
databaseId?: string | null;
|
|
3
|
+
databaseDocumentId?: string | null;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function documentQueryKey(
|
|
7
|
+
documentId: string,
|
|
8
|
+
context: DocumentQueryContext = {},
|
|
9
|
+
) {
|
|
10
|
+
return [
|
|
11
|
+
"action",
|
|
12
|
+
"get-document",
|
|
13
|
+
{
|
|
14
|
+
id: documentId,
|
|
15
|
+
...(context.databaseId ? { databaseId: context.databaseId } : {}),
|
|
16
|
+
...(context.databaseDocumentId
|
|
17
|
+
? { databaseDocumentId: context.databaseDocumentId }
|
|
18
|
+
: {}),
|
|
19
|
+
},
|
|
20
|
+
] as const;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function documentQueryFilter(documentId: string) {
|
|
24
|
+
return {
|
|
25
|
+
queryKey: ["action", "get-document"] as const,
|
|
26
|
+
predicate: (query: { queryKey: readonly unknown[] }) => {
|
|
27
|
+
const args = query.queryKey[2];
|
|
28
|
+
return (
|
|
29
|
+
!!args &&
|
|
30
|
+
typeof args === "object" &&
|
|
31
|
+
"id" in args &&
|
|
32
|
+
args.id === documentId
|
|
33
|
+
);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -3,6 +3,8 @@ import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
|
3
3
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
4
4
|
import {
|
|
5
5
|
AccountSettingsCard,
|
|
6
|
+
SettingsGroup,
|
|
7
|
+
SettingsRow,
|
|
6
8
|
SettingsTabsPage,
|
|
7
9
|
useAgentSettingsTabs,
|
|
8
10
|
type SettingsSearchEntry,
|
|
@@ -10,8 +12,10 @@ import {
|
|
|
10
12
|
import { CreativeContextSettingsLink } from "@agent-native/creative-context/client";
|
|
11
13
|
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
|
|
12
14
|
import { useMemo } from "react";
|
|
15
|
+
import { toast } from "sonner";
|
|
13
16
|
|
|
14
|
-
import {
|
|
17
|
+
import { Switch } from "@/components/ui/switch";
|
|
18
|
+
import { useContentPrefs } from "@/hooks/use-content-prefs";
|
|
15
19
|
import { messagesByLocale } from "@/i18n-data";
|
|
16
20
|
|
|
17
21
|
import changelog from "../../CHANGELOG.md?raw";
|
|
@@ -24,6 +28,7 @@ export default function SettingsRoute() {
|
|
|
24
28
|
const t = useT();
|
|
25
29
|
const agentSettingsTabs = useAgentSettingsTabs();
|
|
26
30
|
useSetPageTitle(t("settings.title"));
|
|
31
|
+
const { prefs, loading: prefsLoading, save: savePrefs } = useContentPrefs();
|
|
27
32
|
|
|
28
33
|
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
29
34
|
() => [
|
|
@@ -33,6 +38,12 @@ export default function SettingsRoute() {
|
|
|
33
38
|
keywords: "language locale translation i18n",
|
|
34
39
|
hash: "language",
|
|
35
40
|
},
|
|
41
|
+
{
|
|
42
|
+
id: "content-notifications",
|
|
43
|
+
label: t("settings.emailNotifications"),
|
|
44
|
+
keywords: "email notifications comments replies mentions alerts",
|
|
45
|
+
hash: "notifications",
|
|
46
|
+
},
|
|
36
47
|
],
|
|
37
48
|
[t],
|
|
38
49
|
);
|
|
@@ -52,23 +63,41 @@ export default function SettingsRoute() {
|
|
|
52
63
|
|
|
53
64
|
<CreativeContextSettingsLink />
|
|
54
65
|
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
<SettingsGroup>
|
|
67
|
+
<SettingsRow
|
|
68
|
+
id="language"
|
|
69
|
+
label={t("settings.languageTitle")}
|
|
70
|
+
description={t("settings.languageDescription")}
|
|
71
|
+
control={
|
|
72
|
+
<div className="w-56">
|
|
73
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
74
|
+
</div>
|
|
75
|
+
}
|
|
76
|
+
/>
|
|
77
|
+
<SettingsRow
|
|
78
|
+
id="notifications"
|
|
79
|
+
label={t("settings.emailNotifications")}
|
|
80
|
+
description={t("settings.emailNotificationsDescription")}
|
|
81
|
+
control={
|
|
82
|
+
<Switch
|
|
83
|
+
aria-label={t("settings.emailNotifications")}
|
|
84
|
+
checked={prefs.emailNotifications !== false}
|
|
85
|
+
disabled={prefsLoading}
|
|
86
|
+
onCheckedChange={(checked) => {
|
|
87
|
+
savePrefs({ emailNotifications: checked }).catch(
|
|
88
|
+
(err) => {
|
|
89
|
+
toast.error(
|
|
90
|
+
err instanceof Error
|
|
91
|
+
? err.message
|
|
92
|
+
: t("settings.saveFailed"),
|
|
93
|
+
);
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
}}
|
|
97
|
+
/>
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
</SettingsGroup>
|
|
72
101
|
</main>
|
|
73
102
|
}
|
|
74
103
|
team={
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email notifications for document comments, replies, and mentions.
|
|
3
|
+
*
|
|
4
|
+
* Recipient resolution, preference filtering, and delivery reporting come from
|
|
5
|
+
* `@agent-native/core/server`; this module owns only the Documents rows and the
|
|
6
|
+
* email copy. Share invites are not routed through the `emailNotifications`
|
|
7
|
+
* preference — they have their own delivery path.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
emailStrong,
|
|
12
|
+
getAppProductionUrl,
|
|
13
|
+
notifyActivity,
|
|
14
|
+
renderEmail,
|
|
15
|
+
runActivityNotification,
|
|
16
|
+
sendEmail,
|
|
17
|
+
type ActivityNotificationResult,
|
|
18
|
+
} from "@agent-native/core/server";
|
|
19
|
+
import { filterRecipientsByResourceAccess } from "@agent-native/core/sharing";
|
|
20
|
+
import { and, eq } from "drizzle-orm";
|
|
21
|
+
|
|
22
|
+
import { CONTENT_USER_PREFS_KEY } from "../../shared/content-user-prefs.js";
|
|
23
|
+
import { getDb, schema } from "../db/index.js";
|
|
24
|
+
|
|
25
|
+
export type DocumentCommentNotificationResult = ActivityNotificationResult;
|
|
26
|
+
|
|
27
|
+
const LOG_LABEL = "[content] comment notification";
|
|
28
|
+
const EXCERPT_LIMIT = 240;
|
|
29
|
+
|
|
30
|
+
function excerpt(content: string): string {
|
|
31
|
+
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
32
|
+
return collapsed.length > EXCERPT_LIMIT
|
|
33
|
+
? `${collapsed.slice(0, EXCERPT_LIMIT - 1)}…`
|
|
34
|
+
: collapsed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function documentUrl(documentId: string): string {
|
|
38
|
+
const base = getAppProductionUrl().replace(/\/+$/, "");
|
|
39
|
+
return `${base}/page/${encodeURIComponent(documentId)}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function threadParticipants(
|
|
43
|
+
documentId: string,
|
|
44
|
+
threadId: string,
|
|
45
|
+
): Promise<string[]> {
|
|
46
|
+
const rows = await getDb()
|
|
47
|
+
.select({ authorEmail: schema.documentComments.authorEmail })
|
|
48
|
+
.from(schema.documentComments)
|
|
49
|
+
.where(
|
|
50
|
+
and(
|
|
51
|
+
eq(schema.documentComments.documentId, documentId),
|
|
52
|
+
eq(schema.documentComments.threadId, threadId),
|
|
53
|
+
),
|
|
54
|
+
);
|
|
55
|
+
return rows.map((row) => row.authorEmail);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DocumentCommentNotificationInput {
|
|
59
|
+
documentId: string;
|
|
60
|
+
/** Read from the access-checked resource by the caller, never re-queried. */
|
|
61
|
+
documentTitle: string;
|
|
62
|
+
/** The document's org, so `org` visibility resolves for its members. */
|
|
63
|
+
orgId?: string | null;
|
|
64
|
+
threadId: string;
|
|
65
|
+
ownerEmail: string;
|
|
66
|
+
authorEmail: string;
|
|
67
|
+
authorName?: string | null;
|
|
68
|
+
content: string;
|
|
69
|
+
mentions: { email: string; name: string }[];
|
|
70
|
+
isReply: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function notifyDocumentComment(
|
|
74
|
+
input: DocumentCommentNotificationInput,
|
|
75
|
+
): Promise<DocumentCommentNotificationResult> {
|
|
76
|
+
return runActivityNotification(LOG_LABEL, () =>
|
|
77
|
+
deliverDocumentCommentEmails(input),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function deliverDocumentCommentEmails(
|
|
82
|
+
input: DocumentCommentNotificationInput,
|
|
83
|
+
): Promise<DocumentCommentNotificationResult> {
|
|
84
|
+
const title = input.documentTitle.trim() || "Untitled";
|
|
85
|
+
const mentioned = new Set(
|
|
86
|
+
input.mentions.map((mention) => mention.email.trim().toLowerCase()),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const candidates = [input.ownerEmail, ...mentioned];
|
|
90
|
+
if (input.isReply) {
|
|
91
|
+
candidates.push(
|
|
92
|
+
...(await threadParticipants(input.documentId, input.threadId)),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Mentions are caller-supplied and thread rows are historical; re-check both
|
|
97
|
+
// against the document's live ACL before mailing anyone its contents.
|
|
98
|
+
const allowed = await filterRecipientsByResourceAccess({
|
|
99
|
+
resourceType: "document",
|
|
100
|
+
resourceId: input.documentId,
|
|
101
|
+
emails: candidates,
|
|
102
|
+
orgId: input.orgId,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const actor = input.authorName?.trim() || input.authorEmail;
|
|
106
|
+
const url = documentUrl(input.documentId);
|
|
107
|
+
|
|
108
|
+
return notifyActivity({
|
|
109
|
+
candidates: allowed,
|
|
110
|
+
actorEmail: input.authorEmail,
|
|
111
|
+
preferenceKey: CONTENT_USER_PREFS_KEY,
|
|
112
|
+
logLabel: LOG_LABEL,
|
|
113
|
+
send: async (to) => {
|
|
114
|
+
const wasMentioned = mentioned.has(to);
|
|
115
|
+
const lead = wasMentioned
|
|
116
|
+
? `${emailStrong(actor)} mentioned you in a comment on ${emailStrong(title)}.`
|
|
117
|
+
: input.isReply
|
|
118
|
+
? `${emailStrong(actor)} replied in a comment thread on ${emailStrong(title)}.`
|
|
119
|
+
: `${emailStrong(actor)} commented on ${emailStrong(title)}.`;
|
|
120
|
+
|
|
121
|
+
const { html, text } = renderEmail({
|
|
122
|
+
preheader: `${actor} commented on ${title}.`,
|
|
123
|
+
heading: wasMentioned
|
|
124
|
+
? "You were mentioned"
|
|
125
|
+
: input.isReply
|
|
126
|
+
? "New reply on your document"
|
|
127
|
+
: "New comment",
|
|
128
|
+
paragraphs: [lead, `"${excerpt(input.content)}"`],
|
|
129
|
+
cta: { label: "Open document", url },
|
|
130
|
+
footer:
|
|
131
|
+
"You received this because you own, were mentioned in, or participated in this thread. Turn these off in Documents settings.",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await sendEmail({
|
|
135
|
+
to,
|
|
136
|
+
subject: wasMentioned
|
|
137
|
+
? `${actor} mentioned you on "${title}"`
|
|
138
|
+
: input.isReply
|
|
139
|
+
? `${actor} replied to a comment on "${title}"`
|
|
140
|
+
: `${actor} commented on "${title}"`,
|
|
141
|
+
html,
|
|
142
|
+
text,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -14,6 +14,7 @@ export type DocumentContextPathEntry = {
|
|
|
14
14
|
* assembles the live path without copying ancestor prose into descendants. */
|
|
15
15
|
export async function getDocumentContextPath(
|
|
16
16
|
document: Pick<typeof schema.documents.$inferSelect, "id" | "parentId">,
|
|
17
|
+
options: { databaseId?: string } = {},
|
|
17
18
|
): Promise<DocumentContextPathEntry[]> {
|
|
18
19
|
const db = getDb();
|
|
19
20
|
const path: DocumentContextPathEntry[] = [];
|
|
@@ -43,6 +44,15 @@ export async function getDocumentContextPath(
|
|
|
43
44
|
parentId = parent.parentId;
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
const membershipClauses = [
|
|
48
|
+
eq(schema.contentDatabaseItems.documentId, document.id),
|
|
49
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
50
|
+
];
|
|
51
|
+
if (options.databaseId) {
|
|
52
|
+
membershipClauses.push(
|
|
53
|
+
eq(schema.contentDatabaseItems.databaseId, options.databaseId),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
46
56
|
const [membership] = await db
|
|
47
57
|
.select({ database: schema.contentDatabases })
|
|
48
58
|
.from(schema.contentDatabaseItems)
|
|
@@ -50,12 +60,7 @@ export async function getDocumentContextPath(
|
|
|
50
60
|
schema.contentDatabases,
|
|
51
61
|
eq(schema.contentDatabases.id, schema.contentDatabaseItems.databaseId),
|
|
52
62
|
)
|
|
53
|
-
.where(
|
|
54
|
-
and(
|
|
55
|
-
eq(schema.contentDatabaseItems.documentId, document.id),
|
|
56
|
-
isNull(schema.contentDatabases.deletedAt),
|
|
57
|
-
),
|
|
58
|
-
)
|
|
63
|
+
.where(and(...membershipClauses))
|
|
59
64
|
.orderBy(
|
|
60
65
|
sql`CASE WHEN ${schema.contentDatabases.systemRole} IS NULL THEN 0 ELSE 1 END`,
|
|
61
66
|
asc(schema.contentDatabases.id),
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getSession } from "@agent-native/core/server";
|
|
2
|
+
import { getUserSetting } from "@agent-native/core/settings";
|
|
3
|
+
import { defineEventHandler, setResponseStatus } from "h3";
|
|
4
|
+
|
|
5
|
+
import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
|
|
6
|
+
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const session = await getSession(event);
|
|
9
|
+
if (!session?.email) {
|
|
10
|
+
setResponseStatus(event, 401);
|
|
11
|
+
return { error: "unauthorized" };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
|
|
15
|
+
// coercion-ok: a null read means this user has no preferences yet, which is a real state.
|
|
16
|
+
return stored ?? {};
|
|
17
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getSession } from "@agent-native/core/server";
|
|
2
|
+
import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
|
|
3
|
+
import { defineEventHandler, getHeader, readBody, setResponseStatus } from "h3";
|
|
4
|
+
|
|
5
|
+
import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
|
|
6
|
+
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const session = await getSession(event);
|
|
9
|
+
if (!session?.email) {
|
|
10
|
+
setResponseStatus(event, 401);
|
|
11
|
+
return { error: "unauthorized" };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// coercion-ok: an unparsable body is rejected with 400 immediately below.
|
|
15
|
+
const body = await readBody(event).catch(() => null);
|
|
16
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
17
|
+
setResponseStatus(event, 400);
|
|
18
|
+
return { error: "Invalid settings payload" };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Merge so a partial save never wipes preferences written elsewhere.
|
|
22
|
+
const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
|
|
23
|
+
// coercion-ok: a null read means this user has no preferences yet, which is a real state.
|
|
24
|
+
const existing = stored ?? {};
|
|
25
|
+
const next = {
|
|
26
|
+
...(typeof existing === "object" && !Array.isArray(existing)
|
|
27
|
+
? existing
|
|
28
|
+
: {}),
|
|
29
|
+
...(body as Record<string, unknown>),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
await putUserSetting(session.email, CONTENT_USER_PREFS_KEY, next, {
|
|
33
|
+
requestSource: getHeader(event, "x-request-source") || undefined,
|
|
34
|
+
});
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
@@ -36,6 +36,7 @@ export interface Document {
|
|
|
36
36
|
properties?: DocumentProperty[];
|
|
37
37
|
database?: ContentDatabase;
|
|
38
38
|
databaseMembership?: ContentDatabaseMembership;
|
|
39
|
+
bodyHydration?: ContentDocumentBodyHydration;
|
|
39
40
|
contextPath?: ContentContextPathEntry[];
|
|
40
41
|
createdAt: string;
|
|
41
42
|
updatedAt: string;
|
|
@@ -407,6 +408,13 @@ export interface ContentDatabaseMembership {
|
|
|
407
408
|
bodyHydration?: ContentDatabaseBodyHydration;
|
|
408
409
|
}
|
|
409
410
|
|
|
411
|
+
export interface ContentDocumentBodyHydration {
|
|
412
|
+
provider?: "builder";
|
|
413
|
+
hydration?: ContentDatabaseBodyHydration;
|
|
414
|
+
sourceId?: string;
|
|
415
|
+
databaseDocumentId?: string;
|
|
416
|
+
}
|
|
417
|
+
|
|
410
418
|
export type ContentDatabaseBodyHydrationState =
|
|
411
419
|
| "pending"
|
|
412
420
|
| "hydrating"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-user Documents preferences, stored under one user-setting key so
|
|
3
|
+
* Settings and the notification senders read and write the same object.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const CONTENT_USER_PREFS_KEY = "content-user-prefs";
|
|
7
|
+
|
|
8
|
+
export type ContentUserPrefs = {
|
|
9
|
+
/** Comment, reply, and mention emails only — never share invites. */
|
|
10
|
+
emailNotifications?: boolean;
|
|
11
|
+
};
|