@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
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
11
11
|
import {
|
|
12
12
|
AccountSettingsCard,
|
|
13
|
+
SettingsGroup,
|
|
14
|
+
SettingsRow,
|
|
13
15
|
SettingsTabsPage,
|
|
14
16
|
useAgentSettingsTabs,
|
|
15
17
|
useBuilderConnectFlow,
|
|
@@ -36,6 +38,7 @@ import {
|
|
|
36
38
|
type FormEvent,
|
|
37
39
|
type ReactNode,
|
|
38
40
|
} from "react";
|
|
41
|
+
import { toast } from "sonner";
|
|
39
42
|
|
|
40
43
|
import { PageShell } from "@/components/layout/PageShell";
|
|
41
44
|
import { Button } from "@/components/ui/button";
|
|
@@ -56,6 +59,8 @@ import {
|
|
|
56
59
|
SelectTrigger,
|
|
57
60
|
SelectValue,
|
|
58
61
|
} from "@/components/ui/select";
|
|
62
|
+
import { Switch } from "@/components/ui/switch";
|
|
63
|
+
import { useAssetsPrefs } from "@/hooks/use-assets-prefs";
|
|
59
64
|
import { cn } from "@/lib/utils";
|
|
60
65
|
|
|
61
66
|
import changelog from "../../CHANGELOG.md?raw";
|
|
@@ -81,6 +86,7 @@ export default function SettingsPage() {
|
|
|
81
86
|
const { data } = useActionQuery("list-libraries", { compact: true }) as {
|
|
82
87
|
data?: { count?: number };
|
|
83
88
|
};
|
|
89
|
+
const { prefs, loading: prefsLoading, save: savePrefs } = useAssetsPrefs();
|
|
84
90
|
|
|
85
91
|
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
86
92
|
() => [
|
|
@@ -90,6 +96,12 @@ export default function SettingsPage() {
|
|
|
90
96
|
keywords: "language locale translation i18n",
|
|
91
97
|
hash: "language",
|
|
92
98
|
},
|
|
99
|
+
{
|
|
100
|
+
id: "assets-notifications",
|
|
101
|
+
label: t("settings.emailNotifications"),
|
|
102
|
+
keywords: "email notification generation finished failed alert",
|
|
103
|
+
hash: "notifications",
|
|
104
|
+
},
|
|
93
105
|
{
|
|
94
106
|
id: "assets-generation-setup",
|
|
95
107
|
label: t("settings.setupTitle"),
|
|
@@ -125,20 +137,41 @@ export default function SettingsPage() {
|
|
|
125
137
|
</p>
|
|
126
138
|
</div>
|
|
127
139
|
|
|
128
|
-
<
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
<SettingsGroup className="scroll-mt-4">
|
|
141
|
+
<SettingsRow
|
|
142
|
+
id="language"
|
|
143
|
+
label={t("settings.languageTitle")}
|
|
144
|
+
description={t("settings.languageDescription")}
|
|
145
|
+
control={
|
|
146
|
+
<div className="w-56">
|
|
147
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
148
|
+
</div>
|
|
149
|
+
}
|
|
150
|
+
/>
|
|
151
|
+
<SettingsRow
|
|
152
|
+
id="notifications"
|
|
153
|
+
label={t("settings.emailNotifications")}
|
|
154
|
+
description={t("settings.emailNotificationsDescription")}
|
|
155
|
+
control={
|
|
156
|
+
<Switch
|
|
157
|
+
aria-label={t("settings.emailNotifications")}
|
|
158
|
+
checked={prefs.emailNotifications !== false}
|
|
159
|
+
disabled={prefsLoading}
|
|
160
|
+
onCheckedChange={(checked) => {
|
|
161
|
+
savePrefs({ emailNotifications: checked }).catch(
|
|
162
|
+
(err) => {
|
|
163
|
+
toast.error(
|
|
164
|
+
err instanceof Error
|
|
165
|
+
? err.message
|
|
166
|
+
: t("settings.saveFailed"),
|
|
167
|
+
);
|
|
168
|
+
},
|
|
169
|
+
);
|
|
170
|
+
}}
|
|
171
|
+
/>
|
|
172
|
+
}
|
|
173
|
+
/>
|
|
174
|
+
</SettingsGroup>
|
|
142
175
|
|
|
143
176
|
<section id="asset-generation-setup" className="scroll-mt-4">
|
|
144
177
|
<AssetsSetupCard libraryCount={data?.count ?? 0} />
|
|
@@ -243,8 +276,9 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
243
276
|
|
|
244
277
|
<CardContent className="p-0">
|
|
245
278
|
<SettingsRow
|
|
279
|
+
className="border-b border-border/70 last:border-b-0"
|
|
246
280
|
icon={<IconKey className="size-4" />}
|
|
247
|
-
|
|
281
|
+
label="Builder"
|
|
248
282
|
description={
|
|
249
283
|
builderConnected
|
|
250
284
|
? orgName
|
|
@@ -261,7 +295,7 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
261
295
|
: t("settings.optional")}
|
|
262
296
|
</StatusPill>
|
|
263
297
|
}
|
|
264
|
-
|
|
298
|
+
control={
|
|
265
299
|
builderEnabled ? (
|
|
266
300
|
<Button
|
|
267
301
|
type="button"
|
|
@@ -295,8 +329,9 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
295
329
|
{setupIssue ? <SetupIssueCallout message={setupIssue} /> : null}
|
|
296
330
|
|
|
297
331
|
<SettingsRow
|
|
332
|
+
className="border-b border-border/70 last:border-b-0"
|
|
298
333
|
icon={<IconPhoto className="size-4" />}
|
|
299
|
-
|
|
334
|
+
label={t("settings.generation")}
|
|
300
335
|
description={generationSummary(configData, builderConnected, t)}
|
|
301
336
|
status={
|
|
302
337
|
<StatusPill tone={generationReady ? "ready" : "attention"}>
|
|
@@ -305,7 +340,7 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
305
340
|
: t("settings.generationNeedsSetup")}
|
|
306
341
|
</StatusPill>
|
|
307
342
|
}
|
|
308
|
-
|
|
343
|
+
control={
|
|
309
344
|
generationStep ? (
|
|
310
345
|
<DisclosureButton
|
|
311
346
|
open={manualGenerationOpen}
|
|
@@ -326,8 +361,9 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
326
361
|
) : null}
|
|
327
362
|
|
|
328
363
|
<SettingsRow
|
|
364
|
+
className="border-b border-border/70 last:border-b-0"
|
|
329
365
|
icon={<IconCloudUpload className="size-4" />}
|
|
330
|
-
|
|
366
|
+
label={t("settings.storage")}
|
|
331
367
|
description={
|
|
332
368
|
storageReady
|
|
333
369
|
? t("settings.storageReady")
|
|
@@ -340,7 +376,7 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
340
376
|
: t("settings.generationNeedsSetup")}
|
|
341
377
|
</StatusPill>
|
|
342
378
|
}
|
|
343
|
-
|
|
379
|
+
control={
|
|
344
380
|
storageStep ? (
|
|
345
381
|
<DisclosureButton
|
|
346
382
|
open={manualStorageOpen}
|
|
@@ -361,8 +397,9 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
361
397
|
) : null}
|
|
362
398
|
|
|
363
399
|
<SettingsRow
|
|
400
|
+
className="border-b border-border/70 last:border-b-0"
|
|
364
401
|
icon={<IconLibraryPhoto className="size-4" />}
|
|
365
|
-
|
|
402
|
+
label={t("settings.brandKits")}
|
|
366
403
|
description={`${libraryCount} accessible ${
|
|
367
404
|
libraryCount === 1 ? "brand kit" : "brand kits"
|
|
368
405
|
}.`}
|
|
@@ -375,40 +412,6 @@ function AssetsSetupCard({ libraryCount }: { libraryCount: number }) {
|
|
|
375
412
|
);
|
|
376
413
|
}
|
|
377
414
|
|
|
378
|
-
function SettingsRow({
|
|
379
|
-
icon,
|
|
380
|
-
title,
|
|
381
|
-
description,
|
|
382
|
-
status,
|
|
383
|
-
action,
|
|
384
|
-
}: {
|
|
385
|
-
icon: ReactNode;
|
|
386
|
-
title: string;
|
|
387
|
-
description: string;
|
|
388
|
-
status: ReactNode;
|
|
389
|
-
action?: ReactNode;
|
|
390
|
-
}) {
|
|
391
|
-
return (
|
|
392
|
-
<div className="flex flex-col gap-3 border-b border-border/70 px-5 py-4 last:border-b-0 sm:flex-row sm:items-center sm:justify-between">
|
|
393
|
-
<div className="flex min-w-0 gap-3">
|
|
394
|
-
<div className="mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-md border border-border bg-background text-muted-foreground">
|
|
395
|
-
{icon}
|
|
396
|
-
</div>
|
|
397
|
-
<div className="min-w-0">
|
|
398
|
-
<div className="flex flex-wrap items-center gap-2">
|
|
399
|
-
<h3 className="text-sm font-medium">{title}</h3>
|
|
400
|
-
{status}
|
|
401
|
-
</div>
|
|
402
|
-
<p className="mt-1 max-w-xl text-sm leading-6 text-muted-foreground">
|
|
403
|
-
{description}
|
|
404
|
-
</p>
|
|
405
|
-
</div>
|
|
406
|
-
</div>
|
|
407
|
-
{action ? <div className="shrink-0 sm:ms-4">{action}</div> : null}
|
|
408
|
-
</div>
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
415
|
function StatusPill({
|
|
413
416
|
children,
|
|
414
417
|
tone,
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Your generation finished" notifications.
|
|
3
|
+
*
|
|
4
|
+
* Only terminal transitions that happen *out of band* call this — a polled video
|
|
5
|
+
* run landing, or a stale image run being declared interrupted. Synchronous
|
|
6
|
+
* `generate-image` hands the result straight back to the caller, so emailing
|
|
7
|
+
* there would mail a user who is already looking at the image.
|
|
8
|
+
*/
|
|
9
|
+
import { notifyWithDelivery } from "@agent-native/core/notifications";
|
|
10
|
+
import { getUserSetting } from "@agent-native/core/settings";
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
ASSETS_USER_PREFS_KEY,
|
|
14
|
+
type AssetsUserPrefs,
|
|
15
|
+
} from "../../shared/assets-user-prefs.js";
|
|
16
|
+
import type { schema } from "../db/index.js";
|
|
17
|
+
|
|
18
|
+
type GenerationRun = typeof schema.assetGenerationRuns.$inferSelect;
|
|
19
|
+
|
|
20
|
+
export type GenerationRunNotificationStatus =
|
|
21
|
+
| "no-recipient"
|
|
22
|
+
| "notified"
|
|
23
|
+
| "notification-error";
|
|
24
|
+
|
|
25
|
+
export interface GenerationRunNotificationResult {
|
|
26
|
+
status: GenerationRunNotificationStatus;
|
|
27
|
+
emailed: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function wantsEmail(email: string): Promise<boolean> {
|
|
31
|
+
const stored = await getUserSetting(email, ASSETS_USER_PREFS_KEY);
|
|
32
|
+
if (!stored || typeof stored !== "object" || Array.isArray(stored)) {
|
|
33
|
+
// No stored preference is a real state, and its meaning is "opted in".
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return (stored as AssetsUserPrefs).emailNotifications !== false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function summarize(run: GenerationRun): string {
|
|
40
|
+
const kind = run.mediaType === "video" ? "Video" : "Image";
|
|
41
|
+
const prompt = run.prompt.trim();
|
|
42
|
+
return prompt.length > 80
|
|
43
|
+
? `${kind}: ${prompt.slice(0, 77)}…`
|
|
44
|
+
: `${kind}: ${prompt}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function notifyGenerationRunFinished(
|
|
48
|
+
run: GenerationRun,
|
|
49
|
+
outcome: "completed" | "failed",
|
|
50
|
+
): Promise<GenerationRunNotificationResult> {
|
|
51
|
+
const owner = run.ownerEmail?.trim().toLowerCase();
|
|
52
|
+
if (!owner) return { status: "no-recipient", emailed: false };
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
const emailed = await wantsEmail(owner);
|
|
56
|
+
const failed = outcome === "failed";
|
|
57
|
+
const title = failed ? "Generation failed" : "Generation finished";
|
|
58
|
+
const body = failed
|
|
59
|
+
? `${summarize(run)}\n\n${run.error ?? "The run ended without a result."}`
|
|
60
|
+
: summarize(run);
|
|
61
|
+
|
|
62
|
+
await notifyWithDelivery(
|
|
63
|
+
{
|
|
64
|
+
severity: failed ? "warning" : "info",
|
|
65
|
+
title,
|
|
66
|
+
body,
|
|
67
|
+
channels: emailed ? ["inbox", "email"] : ["inbox"],
|
|
68
|
+
metadata: {
|
|
69
|
+
kind: "generation_run",
|
|
70
|
+
runId: run.id,
|
|
71
|
+
libraryId: run.libraryId,
|
|
72
|
+
outcome,
|
|
73
|
+
// The email channel is a no-op without explicit recipients.
|
|
74
|
+
...(emailed ? { emailRecipients: [owner], emailSubject: title } : {}),
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{ owner },
|
|
78
|
+
);
|
|
79
|
+
return { status: "notified", emailed };
|
|
80
|
+
} catch (err) {
|
|
81
|
+
// A generation that produced an asset must not be reported as failed just
|
|
82
|
+
// because the mail server was down.
|
|
83
|
+
console.error(
|
|
84
|
+
`[assets] Could not notify ${owner} that run ${run.id} ${outcome}:`,
|
|
85
|
+
err instanceof Error ? err.message : String(err),
|
|
86
|
+
);
|
|
87
|
+
return { status: "notification-error", emailed: false };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -2,6 +2,7 @@ import { eq } from "drizzle-orm";
|
|
|
2
2
|
|
|
3
3
|
import { getDb, schema } from "../db/index.js";
|
|
4
4
|
import { createAssetFromBuffer } from "./assets.js";
|
|
5
|
+
import { notifyGenerationRunFinished } from "./generation-run-notifications.js";
|
|
5
6
|
import { nowIso, parseJson, stringifyJson } from "./json.js";
|
|
6
7
|
import { pollGeminiVideoGeneration } from "./video-generation.js";
|
|
7
8
|
|
|
@@ -59,6 +60,7 @@ async function markRunCompletedWithAsset(
|
|
|
59
60
|
metadata: nextRun.metadata,
|
|
60
61
|
})
|
|
61
62
|
.where(eq(schema.assetGenerationRuns.id, run.id));
|
|
63
|
+
await notifyGenerationRunFinished(nextRun, "completed");
|
|
62
64
|
return nextRun;
|
|
63
65
|
}
|
|
64
66
|
|
|
@@ -217,14 +219,19 @@ export async function completeVideoGenerationRun(
|
|
|
217
219
|
} catch (err) {
|
|
218
220
|
const message =
|
|
219
221
|
err instanceof Error ? err.message : "Video generation failed.";
|
|
222
|
+
const completedAt = nowIso();
|
|
220
223
|
await getDb()
|
|
221
224
|
.update(schema.assetGenerationRuns)
|
|
222
225
|
.set({
|
|
223
226
|
status: "failed",
|
|
224
227
|
error: message,
|
|
225
|
-
completedAt
|
|
228
|
+
completedAt,
|
|
226
229
|
})
|
|
227
230
|
.where(eq(schema.assetGenerationRuns.id, run.id));
|
|
231
|
+
await notifyGenerationRunFinished(
|
|
232
|
+
{ ...run, status: "failed", error: message, completedAt },
|
|
233
|
+
"failed",
|
|
234
|
+
);
|
|
228
235
|
throw err;
|
|
229
236
|
}
|
|
230
237
|
}
|
|
@@ -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 { ASSETS_USER_PREFS_KEY } from "../../../../shared/assets-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, ASSETS_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 { ASSETS_USER_PREFS_KEY } from "../../../../shared/assets-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, ASSETS_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" && existing && !Array.isArray(existing)
|
|
27
|
+
? existing
|
|
28
|
+
: {}),
|
|
29
|
+
...(body as Record<string, unknown>),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
await putUserSetting(session.email, ASSETS_USER_PREFS_KEY, next, {
|
|
33
|
+
requestSource: getHeader(event, "x-request-source") || undefined,
|
|
34
|
+
});
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-user Assets preferences, stored under one user-setting key so Settings
|
|
3
|
+
* and the generation pipeline agree on a single source of truth.
|
|
4
|
+
*/
|
|
5
|
+
export const ASSETS_USER_PREFS_KEY = "assets-user-prefs";
|
|
6
|
+
|
|
7
|
+
export type AssetsUserPrefs = {
|
|
8
|
+
/** Email me when a generation run I started finishes or fails. */
|
|
9
|
+
emailNotifications?: boolean;
|
|
10
|
+
};
|
|
@@ -1,16 +1,20 @@
|
|
|
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
|
-
|
|
15
|
+
test: {
|
|
16
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
+
exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
);
|
|
@@ -7,6 +7,8 @@ import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
|
7
7
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
8
8
|
import {
|
|
9
9
|
AccountSettingsCard,
|
|
10
|
+
SettingsGroup,
|
|
11
|
+
SettingsRow,
|
|
10
12
|
SettingsTabsPage,
|
|
11
13
|
useAgentSettingsTabs,
|
|
12
14
|
type SettingsSearchEntry,
|
|
@@ -717,21 +719,19 @@ export default function SettingsRoute() {
|
|
|
717
719
|
</main>
|
|
718
720
|
|
|
719
721
|
<aside className="grid content-start gap-5">
|
|
720
|
-
<
|
|
721
|
-
<
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
</CardContent>
|
|
734
|
-
</Card>
|
|
722
|
+
<SettingsGroup className="scroll-mt-4">
|
|
723
|
+
<SettingsRow
|
|
724
|
+
id="language"
|
|
725
|
+
icon={<IconAdjustments className="text-primary" />}
|
|
726
|
+
label={t("settings.languageTitle")}
|
|
727
|
+
description={t("settings.languageDescription")}
|
|
728
|
+
control={
|
|
729
|
+
<div className="w-48">
|
|
730
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
731
|
+
</div>
|
|
732
|
+
}
|
|
733
|
+
/>
|
|
734
|
+
</SettingsGroup>
|
|
735
735
|
|
|
736
736
|
<Card>
|
|
737
737
|
<CardHeader>
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import baseConfig from "@agent-native/core/vitest-config";
|
|
2
|
+
import { defineConfig, mergeConfig } from "vitest/config";
|
|
2
3
|
|
|
3
|
-
export default
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
export default mergeConfig(
|
|
5
|
+
baseConfig,
|
|
6
|
+
defineConfig({
|
|
7
|
+
test: {
|
|
8
|
+
passWithNoTests: true,
|
|
9
|
+
exclude: [
|
|
10
|
+
"**/node_modules/**",
|
|
11
|
+
"**/dist/**",
|
|
12
|
+
"**/.output/**",
|
|
13
|
+
"**/.{idea,git,cache,output,temp}/**",
|
|
14
|
+
],
|
|
15
|
+
},
|
|
16
|
+
}),
|
|
17
|
+
);
|
|
@@ -4,6 +4,8 @@ import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
|
4
4
|
import { TeamPage } from "@agent-native/core/client/org";
|
|
5
5
|
import {
|
|
6
6
|
AccountSettingsCard,
|
|
7
|
+
SettingsGroup,
|
|
8
|
+
SettingsRow,
|
|
7
9
|
SettingsTabsPage,
|
|
8
10
|
useAgentSettingsTabs,
|
|
9
11
|
type SettingsSearchEntry,
|
|
@@ -209,20 +211,36 @@ export default function Settings() {
|
|
|
209
211
|
{t("settings.description")}
|
|
210
212
|
</p>
|
|
211
213
|
|
|
212
|
-
<
|
|
213
|
-
<
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
214
|
+
<SettingsGroup>
|
|
215
|
+
<SettingsRow
|
|
216
|
+
id="language"
|
|
217
|
+
label={t("settings.languageTitle")}
|
|
218
|
+
description={t("settings.languageDescription")}
|
|
219
|
+
control={
|
|
220
|
+
<div className="w-56">
|
|
221
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
222
|
+
</div>
|
|
223
|
+
}
|
|
224
|
+
/>
|
|
225
|
+
<SettingsRow
|
|
226
|
+
id="appearance"
|
|
227
|
+
label={t("settings.appearance")}
|
|
228
|
+
description={t("settings.appearanceDescription")}
|
|
229
|
+
>
|
|
230
|
+
<AppearancePicker
|
|
231
|
+
onChange={(preset: AppearancePresetId) => {
|
|
232
|
+
// Persist server-side so the choice survives reload and syncs
|
|
233
|
+
// across devices; the local UI has already updated optimistically.
|
|
234
|
+
callAction(
|
|
235
|
+
"change-appearance" as any,
|
|
236
|
+
{ preset } as any,
|
|
237
|
+
).catch(() => {
|
|
238
|
+
// Server write failed; the local DOM change still stands.
|
|
239
|
+
});
|
|
240
|
+
}}
|
|
241
|
+
/>
|
|
242
|
+
</SettingsRow>
|
|
243
|
+
</SettingsGroup>
|
|
226
244
|
|
|
227
245
|
{/* Google Calendar Connection */}
|
|
228
246
|
<Card id="google-calendar" className="scroll-mt-16">
|
|
@@ -460,32 +478,6 @@ export default function Settings() {
|
|
|
460
478
|
</div>
|
|
461
479
|
</CardContent>
|
|
462
480
|
</Card>
|
|
463
|
-
|
|
464
|
-
{/* Appearance */}
|
|
465
|
-
<Card id="appearance" className="scroll-mt-16">
|
|
466
|
-
<CardHeader>
|
|
467
|
-
<CardTitle className="text-lg">
|
|
468
|
-
{t("settings.appearance")}
|
|
469
|
-
</CardTitle>
|
|
470
|
-
<CardDescription>
|
|
471
|
-
{t("settings.appearanceDescription")}
|
|
472
|
-
</CardDescription>
|
|
473
|
-
</CardHeader>
|
|
474
|
-
<CardContent>
|
|
475
|
-
<AppearancePicker
|
|
476
|
-
onChange={(preset: AppearancePresetId) => {
|
|
477
|
-
// Persist server-side so the choice survives reload and syncs
|
|
478
|
-
// across devices; the local UI has already updated optimistically.
|
|
479
|
-
callAction(
|
|
480
|
-
"change-appearance" as any,
|
|
481
|
-
{ preset } as any,
|
|
482
|
-
).catch(() => {
|
|
483
|
-
// Server write failed; the local DOM change still stands.
|
|
484
|
-
});
|
|
485
|
-
}}
|
|
486
|
-
/>
|
|
487
|
-
</CardContent>
|
|
488
|
-
</Card>
|
|
489
481
|
</div>
|
|
490
482
|
}
|
|
491
483
|
team={
|
|
@@ -1,16 +1,20 @@
|
|
|
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
|
-
|
|
15
|
+
test: {
|
|
16
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
17
|
+
exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
);
|