@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
|
@@ -1,23 +1,27 @@
|
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
|
|
15
|
+
test: {
|
|
16
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
+
exclude: [
|
|
18
|
+
"**/node_modules/**",
|
|
19
|
+
"**/.git/**",
|
|
20
|
+
"**/dist/**",
|
|
21
|
+
"**/.output/**",
|
|
22
|
+
"**/.react-router/**",
|
|
23
|
+
"**/e2e/**",
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
);
|
|
@@ -1234,10 +1234,15 @@ export async function getDatabaseByDocumentId(
|
|
|
1234
1234
|
|
|
1235
1235
|
export async function getDatabaseItemByDocumentId(
|
|
1236
1236
|
documentId: string,
|
|
1237
|
-
options: { includeDeleted?: boolean } = {},
|
|
1237
|
+
options: { includeDeleted?: boolean; databaseId?: string } = {},
|
|
1238
1238
|
db = getDb(),
|
|
1239
1239
|
) {
|
|
1240
1240
|
const clauses = [eq(schema.contentDatabaseItems.documentId, documentId)];
|
|
1241
|
+
if (options.databaseId) {
|
|
1242
|
+
clauses.push(
|
|
1243
|
+
eq(schema.contentDatabaseItems.databaseId, options.databaseId),
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1241
1246
|
if (!options.includeDeleted) {
|
|
1242
1247
|
clauses.push(isNull(schema.contentDatabases.deletedAt));
|
|
1243
1248
|
}
|
|
@@ -1262,13 +1267,33 @@ export async function getDatabaseItemByDocumentId(
|
|
|
1262
1267
|
)
|
|
1263
1268
|
.leftJoin(
|
|
1264
1269
|
schema.contentDatabaseBodyHydrationQueue,
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1270
|
+
and(
|
|
1271
|
+
eq(
|
|
1272
|
+
schema.contentDatabaseBodyHydrationQueue.databaseItemId,
|
|
1273
|
+
schema.contentDatabaseItems.id,
|
|
1274
|
+
),
|
|
1275
|
+
eq(
|
|
1276
|
+
schema.contentDatabaseBodyHydrationQueue.sourceId,
|
|
1277
|
+
schema.contentDatabaseSourceRows.sourceId,
|
|
1278
|
+
),
|
|
1279
|
+
eq(
|
|
1280
|
+
schema.contentDatabaseBodyHydrationQueue.sourceRowId,
|
|
1281
|
+
schema.contentDatabaseSourceRows.sourceRowId,
|
|
1282
|
+
),
|
|
1268
1283
|
),
|
|
1269
1284
|
)
|
|
1270
1285
|
.where(and(...clauses))
|
|
1271
1286
|
.orderBy(
|
|
1287
|
+
sql`CASE
|
|
1288
|
+
WHEN ${schema.contentDatabaseSourceRows.sourceId} IS NOT NULL
|
|
1289
|
+
AND (
|
|
1290
|
+
${schema.contentDatabaseItems.bodyHydrationStatus} IN ('pending', 'hydrating')
|
|
1291
|
+
OR ${schema.contentDatabaseBodyHydrationQueue.id} IS NOT NULL
|
|
1292
|
+
) THEN 0
|
|
1293
|
+
WHEN ${schema.contentDatabaseSourceRows.sourceId} IS NOT NULL
|
|
1294
|
+
AND ${schema.contentDatabaseItems.bodyHydrationStatus} = 'error' THEN 1
|
|
1295
|
+
ELSE 2
|
|
1296
|
+
END`,
|
|
1272
1297
|
sql`CASE WHEN ${schema.contentDatabaseSourceRows.sourceId} IS NOT NULL THEN 0 ELSE 1 END`,
|
|
1273
1298
|
sql`CASE WHEN ${schema.contentDatabases.systemRole} IS NULL THEN 0 ELSE 1 END`,
|
|
1274
1299
|
sql`CASE WHEN ${schema.contentDatabases.systemRole} = 'files' THEN 0 ELSE 1 END`,
|
|
@@ -1277,6 +1302,90 @@ export async function getDatabaseItemByDocumentId(
|
|
|
1277
1302
|
return row ?? null;
|
|
1278
1303
|
}
|
|
1279
1304
|
|
|
1305
|
+
export async function getBuilderBodyHydrationMembershipByDocumentId(
|
|
1306
|
+
documentId: string,
|
|
1307
|
+
db = getDb(),
|
|
1308
|
+
) {
|
|
1309
|
+
const rows = await db
|
|
1310
|
+
.select({
|
|
1311
|
+
item: schema.contentDatabaseItems,
|
|
1312
|
+
database: schema.contentDatabases,
|
|
1313
|
+
sourceId: schema.contentDatabaseSourceRows.sourceId,
|
|
1314
|
+
sourceRowId: schema.contentDatabaseSourceRows.sourceRowId,
|
|
1315
|
+
bodyHydrationQueueId: schema.contentDatabaseBodyHydrationQueue.id,
|
|
1316
|
+
queueSourceId: schema.contentDatabaseBodyHydrationQueue.sourceId,
|
|
1317
|
+
queueSourceRowId: schema.contentDatabaseBodyHydrationQueue.sourceRowId,
|
|
1318
|
+
})
|
|
1319
|
+
.from(schema.contentDatabaseSourceRows)
|
|
1320
|
+
.innerJoin(
|
|
1321
|
+
schema.contentDatabaseSources,
|
|
1322
|
+
eq(
|
|
1323
|
+
schema.contentDatabaseSources.id,
|
|
1324
|
+
schema.contentDatabaseSourceRows.sourceId,
|
|
1325
|
+
),
|
|
1326
|
+
)
|
|
1327
|
+
.innerJoin(
|
|
1328
|
+
schema.contentDatabaseItems,
|
|
1329
|
+
eq(
|
|
1330
|
+
schema.contentDatabaseItems.id,
|
|
1331
|
+
schema.contentDatabaseSourceRows.databaseItemId,
|
|
1332
|
+
),
|
|
1333
|
+
)
|
|
1334
|
+
.innerJoin(
|
|
1335
|
+
schema.contentDatabases,
|
|
1336
|
+
eq(schema.contentDatabases.id, schema.contentDatabaseItems.databaseId),
|
|
1337
|
+
)
|
|
1338
|
+
.leftJoin(
|
|
1339
|
+
schema.contentDatabaseBodyHydrationQueue,
|
|
1340
|
+
eq(
|
|
1341
|
+
schema.contentDatabaseBodyHydrationQueue.databaseItemId,
|
|
1342
|
+
schema.contentDatabaseItems.id,
|
|
1343
|
+
),
|
|
1344
|
+
)
|
|
1345
|
+
.where(
|
|
1346
|
+
and(
|
|
1347
|
+
eq(schema.contentDatabaseSourceRows.documentId, documentId),
|
|
1348
|
+
eq(schema.contentDatabaseItems.documentId, documentId),
|
|
1349
|
+
eq(schema.contentDatabaseSources.sourceType, "builder-cms"),
|
|
1350
|
+
isNull(schema.contentDatabases.deletedAt),
|
|
1351
|
+
),
|
|
1352
|
+
);
|
|
1353
|
+
|
|
1354
|
+
const boundRows = rows.filter(
|
|
1355
|
+
(row) =>
|
|
1356
|
+
!row.bodyHydrationQueueId ||
|
|
1357
|
+
(row.queueSourceId === row.sourceId &&
|
|
1358
|
+
row.queueSourceRowId === row.sourceRowId),
|
|
1359
|
+
);
|
|
1360
|
+
if (boundRows.length === 0) return null;
|
|
1361
|
+
|
|
1362
|
+
const priority = (row: (typeof boundRows)[number]) => {
|
|
1363
|
+
if (
|
|
1364
|
+
row.bodyHydrationQueueId ||
|
|
1365
|
+
row.item.bodyHydrationStatus === "pending" ||
|
|
1366
|
+
row.item.bodyHydrationStatus === "hydrating"
|
|
1367
|
+
) {
|
|
1368
|
+
return 0;
|
|
1369
|
+
}
|
|
1370
|
+
if (row.item.bodyHydrationStatus === "error") return 1;
|
|
1371
|
+
return 2;
|
|
1372
|
+
};
|
|
1373
|
+
const topPriority = Math.min(...boundRows.map(priority));
|
|
1374
|
+
const candidates = boundRows
|
|
1375
|
+
.filter((row) => priority(row) === topPriority)
|
|
1376
|
+
.sort((left, right) =>
|
|
1377
|
+
`${left.database.id}:${left.sourceId}:${left.sourceRowId}`.localeCompare(
|
|
1378
|
+
`${right.database.id}:${right.sourceId}:${right.sourceRowId}`,
|
|
1379
|
+
),
|
|
1380
|
+
);
|
|
1381
|
+
const sourceIds = new Set(candidates.map((row) => row.sourceId));
|
|
1382
|
+
|
|
1383
|
+
return {
|
|
1384
|
+
membership: candidates[0]!,
|
|
1385
|
+
hydrationSourceId: sourceIds.size === 1 ? candidates[0]!.sourceId : null,
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1280
1389
|
export async function deleteDatabaseDataForDocument(
|
|
1281
1390
|
documentId: string,
|
|
1282
1391
|
ownerEmail: string,
|
|
@@ -4,6 +4,7 @@ import { assertAccess } from "@agent-native/core/sharing";
|
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
6
6
|
import { getDb, schema } from "../server/db/index.js";
|
|
7
|
+
import { notifyDocumentComment } from "../server/lib/comment-notifications.js";
|
|
7
8
|
|
|
8
9
|
type Mention = { email: string; name: string };
|
|
9
10
|
|
|
@@ -115,6 +116,19 @@ export default defineAction({
|
|
|
115
116
|
authorName: name,
|
|
116
117
|
});
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
const notified = await notifyDocumentComment({
|
|
120
|
+
documentId,
|
|
121
|
+
documentTitle: (access.resource.title as string | null) ?? "",
|
|
122
|
+
orgId: (access.resource.orgId as string | null) ?? null,
|
|
123
|
+
threadId,
|
|
124
|
+
ownerEmail,
|
|
125
|
+
authorEmail: email,
|
|
126
|
+
authorName: name,
|
|
127
|
+
content,
|
|
128
|
+
mentions,
|
|
129
|
+
isReply: Boolean(parentId ?? args.threadId),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
return { id, threadId, notified };
|
|
119
133
|
},
|
|
120
134
|
});
|
|
@@ -11,6 +11,7 @@ import { favoriteDocumentIds } from "./_content-favorites.js";
|
|
|
11
11
|
import { resolveContentSpaceAccess } from "./_content-space-access.js";
|
|
12
12
|
import {
|
|
13
13
|
getDatabaseByDocumentId,
|
|
14
|
+
getBuilderBodyHydrationMembershipByDocumentId,
|
|
14
15
|
getDocumentContextPath,
|
|
15
16
|
getDatabaseItemByDocumentId,
|
|
16
17
|
isSoftDeletedDatabaseDocument,
|
|
@@ -18,7 +19,9 @@ import {
|
|
|
18
19
|
} from "./_database-utils.js";
|
|
19
20
|
import { serializeDocumentSource } from "./_document-source.js";
|
|
20
21
|
import {
|
|
22
|
+
getDatabaseById,
|
|
21
23
|
listPropertiesForDocument,
|
|
24
|
+
resolvePropertyDatabaseForDocument,
|
|
22
25
|
serializeDatabase,
|
|
23
26
|
} from "./_property-utils.js";
|
|
24
27
|
|
|
@@ -54,6 +57,14 @@ export default defineAction({
|
|
|
54
57
|
description: "Get a single document by ID with full content.",
|
|
55
58
|
schema: z.object({
|
|
56
59
|
id: z.string().optional().describe("Document ID (required)"),
|
|
60
|
+
databaseId: z
|
|
61
|
+
.string()
|
|
62
|
+
.optional()
|
|
63
|
+
.describe("Exact Database context for membership-local data"),
|
|
64
|
+
databaseDocumentId: z
|
|
65
|
+
.string()
|
|
66
|
+
.optional()
|
|
67
|
+
.describe("Backing document ID for the exact Database context"),
|
|
57
68
|
}),
|
|
58
69
|
http: { method: "GET" },
|
|
59
70
|
readOnly: true,
|
|
@@ -79,8 +90,54 @@ export default defineAction({
|
|
|
79
90
|
});
|
|
80
91
|
}
|
|
81
92
|
const doc = access.resource;
|
|
93
|
+
if (args.databaseDocumentId && !args.databaseId) {
|
|
94
|
+
throw Object.assign(new Error("databaseDocumentId requires databaseId"), {
|
|
95
|
+
statusCode: 404,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
const database = await getDatabaseByDocumentId(doc.id);
|
|
83
|
-
const databaseMembership =
|
|
100
|
+
const databaseMembership = args.databaseId
|
|
101
|
+
? await getDatabaseItemByDocumentId(doc.id, {
|
|
102
|
+
databaseId: args.databaseId,
|
|
103
|
+
})
|
|
104
|
+
: await getDatabaseItemByDocumentId(doc.id);
|
|
105
|
+
const propertyDatabase = args.databaseId
|
|
106
|
+
? await getDatabaseById(args.databaseId)
|
|
107
|
+
: await resolvePropertyDatabaseForDocument(doc);
|
|
108
|
+
const propertyDatabaseAccess =
|
|
109
|
+
args.databaseId && propertyDatabase
|
|
110
|
+
? await resolveDocumentAccess(propertyDatabase.documentId)
|
|
111
|
+
: null;
|
|
112
|
+
if (
|
|
113
|
+
args.databaseId &&
|
|
114
|
+
(!propertyDatabase ||
|
|
115
|
+
!propertyDatabaseAccess ||
|
|
116
|
+
(propertyDatabase.documentId !== doc.id && !databaseMembership))
|
|
117
|
+
) {
|
|
118
|
+
throw Object.assign(new Error("Database context not found"), {
|
|
119
|
+
statusCode: 404,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (
|
|
123
|
+
args.databaseDocumentId &&
|
|
124
|
+
propertyDatabase?.documentId !== args.databaseDocumentId
|
|
125
|
+
) {
|
|
126
|
+
throw Object.assign(new Error("Database context not found"), {
|
|
127
|
+
statusCode: 404,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
const bodyHydrationTarget =
|
|
131
|
+
await getBuilderBodyHydrationMembershipByDocumentId(doc.id);
|
|
132
|
+
const bodyHydrationMembership = bodyHydrationTarget?.membership;
|
|
133
|
+
const bodyHydrationAccess = bodyHydrationTarget?.hydrationSourceId
|
|
134
|
+
? await resolveDocumentAccess(
|
|
135
|
+
bodyHydrationMembership!.database.documentId,
|
|
136
|
+
)
|
|
137
|
+
: null;
|
|
138
|
+
const bodyHydration = bodyHydrationMembership
|
|
139
|
+
? serializeDatabaseMembership(bodyHydrationMembership).bodyHydration
|
|
140
|
+
: null;
|
|
84
141
|
const userEmail = getRequestUserEmail();
|
|
85
142
|
const favoriteIds = userEmail
|
|
86
143
|
? await favoriteDocumentIds(getDb(), userEmail, [doc.id])
|
|
@@ -112,10 +169,34 @@ export default defineAction({
|
|
|
112
169
|
databaseMembership: databaseMembership
|
|
113
170
|
? serializeDatabaseMembership(databaseMembership)
|
|
114
171
|
: undefined,
|
|
172
|
+
bodyHydration: bodyHydrationMembership
|
|
173
|
+
? {
|
|
174
|
+
hydration: bodyHydrationAccess
|
|
175
|
+
? bodyHydration!
|
|
176
|
+
: {
|
|
177
|
+
status: bodyHydration!.status,
|
|
178
|
+
attemptedAt: null,
|
|
179
|
+
error: null,
|
|
180
|
+
version: null,
|
|
181
|
+
},
|
|
182
|
+
...(bodyHydrationAccess &&
|
|
183
|
+
canEditRole(bodyHydrationAccess.role) &&
|
|
184
|
+
bodyHydrationTarget?.hydrationSourceId
|
|
185
|
+
? {
|
|
186
|
+
provider: "builder" as const,
|
|
187
|
+
sourceId: bodyHydrationTarget.hydrationSourceId,
|
|
188
|
+
databaseDocumentId:
|
|
189
|
+
bodyHydrationMembership.database.documentId,
|
|
190
|
+
}
|
|
191
|
+
: {}),
|
|
192
|
+
}
|
|
193
|
+
: undefined,
|
|
115
194
|
createdAt: doc.createdAt,
|
|
116
195
|
updatedAt: doc.updatedAt,
|
|
117
|
-
properties: await listPropertiesForDocument(doc),
|
|
118
|
-
contextPath: await getDocumentContextPath(doc
|
|
196
|
+
properties: await listPropertiesForDocument(doc, args.databaseId),
|
|
197
|
+
contextPath: await getDocumentContextPath(doc, {
|
|
198
|
+
databaseId: args.databaseId,
|
|
199
|
+
}),
|
|
119
200
|
};
|
|
120
201
|
},
|
|
121
202
|
link: ({ result }) => {
|
|
@@ -337,6 +337,7 @@ export default defineAction({
|
|
|
337
337
|
id: database.id,
|
|
338
338
|
documentId: database.documentId,
|
|
339
339
|
title: database.title,
|
|
340
|
+
systemRole: database.systemRole,
|
|
340
341
|
description: d.description,
|
|
341
342
|
viewConfig: parseDatabaseViewConfig(database.viewConfigJson),
|
|
342
343
|
createdAt: database.createdAt,
|
|
@@ -8,9 +8,16 @@ export function BuilderBodySyncingNotice({
|
|
|
8
8
|
description: string;
|
|
9
9
|
}) {
|
|
10
10
|
return (
|
|
11
|
-
<div
|
|
11
|
+
<div
|
|
12
|
+
className="rounded-lg border border-dashed border-border bg-muted/35 px-4 py-5 text-sm"
|
|
13
|
+
role="status"
|
|
14
|
+
aria-live="polite"
|
|
15
|
+
>
|
|
12
16
|
<div className="flex items-center gap-2 font-medium text-foreground">
|
|
13
|
-
<IconLoader2
|
|
17
|
+
<IconLoader2
|
|
18
|
+
className="size-4 animate-spin text-muted-foreground"
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
/>
|
|
14
21
|
{title}
|
|
15
22
|
</div>
|
|
16
23
|
<p className="mt-2 max-w-2xl leading-6 text-muted-foreground">
|
|
@@ -62,8 +62,10 @@ import {
|
|
|
62
62
|
type ContentSpaceSummary,
|
|
63
63
|
} from "@/hooks/use-content-spaces";
|
|
64
64
|
import {
|
|
65
|
+
mergeDocumentIntoDocumentCache,
|
|
65
66
|
isDocumentUpdateConflict,
|
|
66
67
|
patchDocumentCaches,
|
|
68
|
+
documentQueryFilter,
|
|
67
69
|
useDocument,
|
|
68
70
|
useDeleteDocument,
|
|
69
71
|
useDocuments,
|
|
@@ -247,7 +249,10 @@ export function DocumentEditor({
|
|
|
247
249
|
databaseId,
|
|
248
250
|
databaseDocumentId,
|
|
249
251
|
}: DocumentEditorProps) {
|
|
250
|
-
const documentQuery = useDocument(documentId
|
|
252
|
+
const documentQuery = useDocument(documentId, {
|
|
253
|
+
databaseId,
|
|
254
|
+
databaseDocumentId,
|
|
255
|
+
});
|
|
251
256
|
const {
|
|
252
257
|
data: queriedDocument,
|
|
253
258
|
isError,
|
|
@@ -445,6 +450,7 @@ export function documentEditorBreadcrumbNavigationItems(
|
|
|
445
450
|
| "title"
|
|
446
451
|
| "icon"
|
|
447
452
|
| "position"
|
|
453
|
+
| "database"
|
|
448
454
|
| "databaseMembership"
|
|
449
455
|
| "source"
|
|
450
456
|
>[], // i18n-ignore type expression
|
|
@@ -457,6 +463,9 @@ export function documentEditorBreadcrumbNavigationItems(
|
|
|
457
463
|
workspacesTitle: string;
|
|
458
464
|
},
|
|
459
465
|
): ToolbarBreadcrumbItem[] {
|
|
466
|
+
const peerDocuments = documents.filter(
|
|
467
|
+
(item) => !item.database?.systemRole && item.source?.kind !== "folder",
|
|
468
|
+
);
|
|
460
469
|
const documentById = new Map(documents.map((item) => [item.id, item]));
|
|
461
470
|
const workspaceDocumentIds = new Set(
|
|
462
471
|
spaces.map((space) => space.filesDocumentId),
|
|
@@ -480,9 +489,8 @@ export function documentEditorBreadcrumbNavigationItems(
|
|
|
480
489
|
if (!current) return item;
|
|
481
490
|
const membershipDocumentId =
|
|
482
491
|
current.databaseMembership?.databaseDocumentId ?? null;
|
|
483
|
-
const siblings =
|
|
492
|
+
const siblings = peerDocuments
|
|
484
493
|
.filter((candidate) => {
|
|
485
|
-
if (candidate.source?.kind === "folder") return false;
|
|
486
494
|
if (candidate.parentId !== current.parentId) return false;
|
|
487
495
|
if (current.parentId) return true;
|
|
488
496
|
return (
|
|
@@ -536,7 +544,7 @@ function DocumentEditorBody({
|
|
|
536
544
|
const deleteDocument = useDeleteDocument();
|
|
537
545
|
const queryClient = useQueryClient();
|
|
538
546
|
const processBuilderBodies = useProcessBuilderBodyHydration(
|
|
539
|
-
document.
|
|
547
|
+
document.bodyHydration?.databaseDocumentId ?? documentId,
|
|
540
548
|
);
|
|
541
549
|
const canEdit = document.canEdit ?? true;
|
|
542
550
|
const canEditRef = useRef(canEdit);
|
|
@@ -661,24 +669,30 @@ function DocumentEditorBody({
|
|
|
661
669
|
);
|
|
662
670
|
|
|
663
671
|
useEffect(() => {
|
|
664
|
-
const
|
|
665
|
-
const hydration =
|
|
672
|
+
const hydrationContext = document.bodyHydration;
|
|
673
|
+
const hydration = hydrationContext?.hydration;
|
|
666
674
|
if (
|
|
667
|
-
!
|
|
675
|
+
!canEdit ||
|
|
676
|
+
!hydrationContext?.sourceId ||
|
|
668
677
|
!hydration ||
|
|
669
678
|
(hydration.status !== "pending" && hydration.status !== "error")
|
|
670
679
|
) {
|
|
671
680
|
return;
|
|
672
681
|
}
|
|
673
|
-
const promotionKey = `${
|
|
682
|
+
const promotionKey = `${hydrationContext.sourceId}:${documentId}:${hydration.status}:${hydration.version ?? ""}`;
|
|
674
683
|
if (promotedBuilderBodyRef.current === promotionKey) return;
|
|
675
684
|
promotedBuilderBodyRef.current = promotionKey;
|
|
676
685
|
processBuilderBodies.mutate({
|
|
677
|
-
sourceId:
|
|
686
|
+
sourceId: hydrationContext.sourceId,
|
|
678
687
|
documentId,
|
|
679
688
|
limit: 1,
|
|
680
689
|
});
|
|
681
|
-
}, [
|
|
690
|
+
}, [
|
|
691
|
+
canEdit,
|
|
692
|
+
document.bodyHydration,
|
|
693
|
+
documentId,
|
|
694
|
+
processBuilderBodies.mutate,
|
|
695
|
+
]);
|
|
682
696
|
const titleFocusedRef = useRef(false);
|
|
683
697
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
684
698
|
const titleInputRef = useRef<HTMLTextAreaElement>(null);
|
|
@@ -973,9 +987,8 @@ function DocumentEditorBody({
|
|
|
973
987
|
description:
|
|
974
988
|
error instanceof Error ? error.message : t("empty.genericError"),
|
|
975
989
|
});
|
|
976
|
-
queryClient.
|
|
977
|
-
|
|
978
|
-
fileFirstDocument,
|
|
990
|
+
queryClient.setQueriesData(documentQueryFilter(documentId), (old) =>
|
|
991
|
+
mergeDocumentIntoDocumentCache(old, fileFirstDocument),
|
|
979
992
|
);
|
|
980
993
|
queryClient.invalidateQueries({
|
|
981
994
|
queryKey: ["action", "list-documents"],
|
|
@@ -1887,9 +1900,15 @@ function DocumentEditorBody({
|
|
|
1887
1900
|
if (bodyHydrationPending) {
|
|
1888
1901
|
return (
|
|
1889
1902
|
<BuilderBodySyncingNotice
|
|
1890
|
-
title={t(
|
|
1903
|
+
title={t(
|
|
1904
|
+
document.bodyHydration?.provider === "builder"
|
|
1905
|
+
? "editor.builderBodySyncing"
|
|
1906
|
+
: "editor.pageBodySyncing",
|
|
1907
|
+
)}
|
|
1891
1908
|
description={t(
|
|
1892
|
-
|
|
1909
|
+
document.bodyHydration?.provider === "builder"
|
|
1910
|
+
? "editor.builderBodySyncingDescription"
|
|
1911
|
+
: "editor.pageBodySyncingDescription",
|
|
1893
1912
|
)}
|
|
1894
1913
|
/>
|
|
1895
1914
|
);
|
|
@@ -90,6 +90,7 @@ import {
|
|
|
90
90
|
useSearchNotionPages,
|
|
91
91
|
useCreateAndLinkNotionPage,
|
|
92
92
|
} from "@/hooks/use-notion";
|
|
93
|
+
import { documentQueryFilter } from "@/lib/document-query";
|
|
93
94
|
import {
|
|
94
95
|
localSourceAbsolutePath,
|
|
95
96
|
revealLinkedLocalSourceFile,
|
|
@@ -318,6 +319,15 @@ export function compactToolbarBreadcrumbItems(
|
|
|
318
319
|
];
|
|
319
320
|
}
|
|
320
321
|
|
|
322
|
+
export function firstSelectableBreadcrumbMenuItemId(
|
|
323
|
+
menuItems: ToolbarBreadcrumbItem["menuItems"],
|
|
324
|
+
currentDocumentId: string,
|
|
325
|
+
): string | null {
|
|
326
|
+
return (
|
|
327
|
+
menuItems?.find((menuItem) => menuItem.id !== currentDocumentId)?.id ?? null
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
321
331
|
function ToolbarBreadcrumbMenu({
|
|
322
332
|
item,
|
|
323
333
|
label,
|
|
@@ -337,6 +347,12 @@ function ToolbarBreadcrumbMenu({
|
|
|
337
347
|
}) {
|
|
338
348
|
const [open, setOpen] = useState(false);
|
|
339
349
|
const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
350
|
+
const openedWithKeyboardRef = useRef(false);
|
|
351
|
+
const firstSelectableItemRef = useRef<HTMLDivElement | null>(null);
|
|
352
|
+
const firstSelectableItemId = firstSelectableBreadcrumbMenuItemId(
|
|
353
|
+
item.menuItems,
|
|
354
|
+
currentDocumentId,
|
|
355
|
+
);
|
|
340
356
|
|
|
341
357
|
function cancelClose() {
|
|
342
358
|
if (!closeTimerRef.current) return;
|
|
@@ -349,8 +365,25 @@ function ToolbarBreadcrumbMenu({
|
|
|
349
365
|
closeTimerRef.current = setTimeout(() => setOpen(false), 140);
|
|
350
366
|
}
|
|
351
367
|
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
if (!open || !openedWithKeyboardRef.current) return;
|
|
370
|
+
openedWithKeyboardRef.current = false;
|
|
371
|
+
const frame = requestAnimationFrame(() => {
|
|
372
|
+
firstSelectableItemRef.current?.focus();
|
|
373
|
+
});
|
|
374
|
+
return () => cancelAnimationFrame(frame);
|
|
375
|
+
}, [open]);
|
|
376
|
+
|
|
352
377
|
return (
|
|
353
|
-
<DropdownMenu
|
|
378
|
+
<DropdownMenu
|
|
379
|
+
modal={false}
|
|
380
|
+
open={open}
|
|
381
|
+
onOpenChange={(nextOpen) => {
|
|
382
|
+
if (nextOpen) cancelClose();
|
|
383
|
+
else openedWithKeyboardRef.current = false;
|
|
384
|
+
setOpen(nextOpen);
|
|
385
|
+
}}
|
|
386
|
+
>
|
|
354
387
|
<DropdownMenuTrigger asChild>
|
|
355
388
|
<button
|
|
356
389
|
type="button"
|
|
@@ -364,6 +397,16 @@ function ToolbarBreadcrumbMenu({
|
|
|
364
397
|
setOpen(true);
|
|
365
398
|
}}
|
|
366
399
|
onPointerLeave={scheduleClose}
|
|
400
|
+
onKeyDown={(event) => {
|
|
401
|
+
if (
|
|
402
|
+
event.key === "Enter" ||
|
|
403
|
+
event.key === " " ||
|
|
404
|
+
event.key === "ArrowDown"
|
|
405
|
+
) {
|
|
406
|
+
openedWithKeyboardRef.current = true;
|
|
407
|
+
cancelClose();
|
|
408
|
+
}
|
|
409
|
+
}}
|
|
367
410
|
>
|
|
368
411
|
{children}
|
|
369
412
|
</button>
|
|
@@ -371,6 +414,7 @@ function ToolbarBreadcrumbMenu({
|
|
|
371
414
|
<DropdownMenuContent
|
|
372
415
|
align="start"
|
|
373
416
|
className="w-64"
|
|
417
|
+
onKeyDown={cancelClose}
|
|
374
418
|
onPointerEnter={cancelClose}
|
|
375
419
|
onPointerLeave={scheduleClose}
|
|
376
420
|
>
|
|
@@ -379,7 +423,13 @@ function ToolbarBreadcrumbMenu({
|
|
|
379
423
|
return (
|
|
380
424
|
<DropdownMenuItem
|
|
381
425
|
key={menuItem.id}
|
|
426
|
+
ref={
|
|
427
|
+
menuItem.id === firstSelectableItemId
|
|
428
|
+
? firstSelectableItemRef
|
|
429
|
+
: undefined
|
|
430
|
+
}
|
|
382
431
|
className="gap-2"
|
|
432
|
+
disabled={menuItem.id === currentDocumentId}
|
|
383
433
|
onSelect={() => onOpen(menuItem.id)}
|
|
384
434
|
>
|
|
385
435
|
<span className="flex size-4 shrink-0 items-center justify-center">
|
|
@@ -523,12 +573,8 @@ export function DocumentToolbar({
|
|
|
523
573
|
const previous = hideFromSearch;
|
|
524
574
|
setPendingHideFromSearch(next);
|
|
525
575
|
|
|
526
|
-
queryClient.
|
|
527
|
-
|
|
528
|
-
(old: any) =>
|
|
529
|
-
old && typeof old === "object"
|
|
530
|
-
? { ...old, hideFromSearch: next }
|
|
531
|
-
: old,
|
|
576
|
+
queryClient.setQueriesData(documentQueryFilter(documentId), (old: any) =>
|
|
577
|
+
old && typeof old === "object" ? { ...old, hideFromSearch: next } : old,
|
|
532
578
|
);
|
|
533
579
|
queryClient.setQueryData(
|
|
534
580
|
["action", "list-documents", undefined],
|
|
@@ -552,9 +598,7 @@ export function DocumentToolbar({
|
|
|
552
598
|
});
|
|
553
599
|
} catch (err) {
|
|
554
600
|
setPendingHideFromSearch(previous);
|
|
555
|
-
queryClient.invalidateQueries(
|
|
556
|
-
queryKey: ["action", "get-document", { id: documentId }],
|
|
557
|
-
});
|
|
601
|
+
queryClient.invalidateQueries(documentQueryFilter(documentId));
|
|
558
602
|
queryClient.invalidateQueries({
|
|
559
603
|
queryKey: ["action", "list-documents"],
|
|
560
604
|
});
|
|
@@ -565,9 +609,7 @@ export function DocumentToolbar({
|
|
|
565
609
|
throw err;
|
|
566
610
|
} finally {
|
|
567
611
|
setPendingHideFromSearch(null);
|
|
568
|
-
queryClient.invalidateQueries(
|
|
569
|
-
queryKey: ["action", "get-document", { id: documentId }],
|
|
570
|
-
});
|
|
612
|
+
queryClient.invalidateQueries(documentQueryFilter(documentId));
|
|
571
613
|
queryClient.invalidateQueries({
|
|
572
614
|
queryKey: ["action", "list-documents"],
|
|
573
615
|
});
|
|
@@ -54,12 +54,12 @@ export function databaseItemBodyHydrationIsPending(
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
export function documentBodyHydrationIsPending(
|
|
57
|
-
document: Pick<Document, "content" | "
|
|
57
|
+
document: Pick<Document, "content" | "bodyHydration">,
|
|
58
58
|
) {
|
|
59
|
-
const hydration = document.
|
|
59
|
+
const hydration = document.bodyHydration?.hydration;
|
|
60
60
|
if (
|
|
61
61
|
sourceBackedEmptyBodyNeedsHydration({
|
|
62
|
-
sourceId: document.
|
|
62
|
+
sourceId: document.bodyHydration ? "source-backed" : undefined,
|
|
63
63
|
content: document.content,
|
|
64
64
|
hydration,
|
|
65
65
|
})
|
|
@@ -81,7 +81,10 @@ export function newDocumentPageChoiceIsDisabled(args: {
|
|
|
81
81
|
|
|
82
82
|
export function previewBodyHydrationIsPending(args: {
|
|
83
83
|
item: Pick<ContentDatabaseItem, "bodyHydration" | "document">;
|
|
84
|
-
document:
|
|
84
|
+
document:
|
|
85
|
+
| Pick<Document, "content" | "databaseMembership" | "bodyHydration">
|
|
86
|
+
| null
|
|
87
|
+
| undefined;
|
|
85
88
|
}) {
|
|
86
89
|
const membership =
|
|
87
90
|
args.document?.databaseMembership ?? args.item.document.databaseMembership;
|
|
@@ -128,11 +131,14 @@ export function previewDraftConflictsWithHydratedBody(args: {
|
|
|
128
131
|
|
|
129
132
|
export function previewBodyHydrationIsTerminalError(args: {
|
|
130
133
|
item: Pick<ContentDatabaseItem, "bodyHydration" | "document">;
|
|
131
|
-
document:
|
|
134
|
+
document:
|
|
135
|
+
| Pick<Document, "databaseMembership" | "bodyHydration">
|
|
136
|
+
| null
|
|
137
|
+
| undefined;
|
|
132
138
|
}) {
|
|
133
139
|
return (
|
|
134
140
|
builderBodyHydrationIsTerminalError(
|
|
135
|
-
args.document?.
|
|
141
|
+
args.document?.bodyHydration?.hydration,
|
|
136
142
|
) ||
|
|
137
143
|
builderBodyHydrationIsTerminalError(
|
|
138
144
|
args.item.bodyHydration ??
|