@agent-native/core 0.134.0 → 0.135.0
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/docs/content/template-content-developers.mdx +1 -1
- 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/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-29-meeting-notes-no-longer-transcribe-the-other-side-twice-when.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/hooks/useMeetingTranscription.ts +37 -48
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +331 -36
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +7 -5
- package/corpus/templates/clips/desktop/src/lib/transcription-engine.ts +182 -106
- package/corpus/templates/clips/desktop/src/lib/upload-recovery.ts +129 -0
- package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +43 -14
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +3 -3
- package/corpus/templates/clips/desktop/src-tauri/src/echo_guard.rs +443 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -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/src-tauri/src/whisper_speech.rs +125 -16
- 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/.agents/skills/document-editing/references/databases.md +6 -4
- package/corpus/templates/content/actions/_database-membership-lock.ts +25 -0
- package/corpus/templates/content/actions/_database-row-batch.ts +6 -2
- package/corpus/templates/content/actions/_database-source-utils.ts +289 -129
- package/corpus/templates/content/actions/_database-utils.ts +12 -3
- package/corpus/templates/content/actions/add-comment.ts +15 -1
- package/corpus/templates/content/actions/add-content-database-source-field-property.ts +39 -21
- package/corpus/templates/content/actions/attach-content-database-source.ts +4 -1
- package/corpus/templates/content/actions/change-content-database-source-role.ts +3 -5
- package/corpus/templates/content/actions/duplicate-document-property.ts +59 -46
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +77 -71
- package/corpus/templates/content/actions/list-documents.ts +1 -0
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +7 -0
- package/corpus/templates/content/actions/remove-database-items.ts +183 -0
- package/corpus/templates/content/actions/set-document-property.ts +57 -39
- package/corpus/templates/content/actions/sync-local-folder-source.ts +7 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +5 -2
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +50 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +471 -329
- package/corpus/templates/content/app/components/editor/database/row-access.ts +45 -0
- package/corpus/templates/content/app/components/editor/database/shared.tsx +141 -38
- package/corpus/templates/content/app/components/ui/switch.tsx +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +2 -2
- package/corpus/templates/content/app/hooks/use-content-prefs.ts +55 -0
- package/corpus/templates/content/app/i18n-data.ts +170 -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-07-30-database-rows-can-now-be-removed-without-deleting-their-page.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/parity/eval-scenarios.ts +2 -2
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +4 -5
- package/corpus/templates/content/server/lib/comment-notifications.ts +146 -0
- 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 +4 -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/.generated/bridge/editor-chrome.generated.ts +26 -11
- package/corpus/templates/design/actions/take-design-screenshot.ts +7 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +11 -3
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +4 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +54 -17
- package/corpus/templates/design/app/components/design/design-canvas/local-runtime.ts +126 -0
- package/corpus/templates/design/app/components/templates/TemplatePreview.tsx +2 -0
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- package/corpus/templates/design/app/pages/Present.tsx +2 -1
- package/corpus/templates/design/app/routes/settings.tsx +14 -22
- package/corpus/templates/design/changelog/2026-07-30-a-broken-inline-script-in-a-generated-screen-is-now-caught-o.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-design-html-is-now-validated-with-a-spec-grade-html-parser-i.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-now-load-their-tailwind-and-alpine-runtimes-from-the.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-designs-with-a-broken-alpine-expression-are-now-caught-on-sa.md +6 -0
- package/corpus/templates/design/changelog/2026-07-30-editing-a-design-no-longer-strips-its-styling-the-canvas-kep.md +6 -0
- 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/package.json +4 -0
- package/corpus/templates/design/shared/html-integrity.ts +802 -556
- 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/collab/struct-routes.d.ts +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 +2 -2
- package/dist/observability/routes.d.ts +1 -1
- 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/provider-api/actions/custom-provider-registration.d.ts +10 -10
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- 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/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/docs/content/template-content-developers.mdx +1 -1
- 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/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
- package/corpus/templates/content/actions/delete-database-items.ts +0 -89
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email notifications for document comments, replies, and mentions.
|
|
3
|
+
*
|
|
4
|
+
* Recipient resolution, preference filtering, and delivery reporting come from
|
|
5
|
+
* `@agent-native/core/server`; this module owns only the Documents rows and the
|
|
6
|
+
* email copy. Share invites are not routed through the `emailNotifications`
|
|
7
|
+
* preference — they have their own delivery path.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
emailStrong,
|
|
12
|
+
getAppProductionUrl,
|
|
13
|
+
notifyActivity,
|
|
14
|
+
renderEmail,
|
|
15
|
+
runActivityNotification,
|
|
16
|
+
sendEmail,
|
|
17
|
+
type ActivityNotificationResult,
|
|
18
|
+
} from "@agent-native/core/server";
|
|
19
|
+
import { filterRecipientsByResourceAccess } from "@agent-native/core/sharing";
|
|
20
|
+
import { and, eq } from "drizzle-orm";
|
|
21
|
+
|
|
22
|
+
import { CONTENT_USER_PREFS_KEY } from "../../shared/content-user-prefs.js";
|
|
23
|
+
import { getDb, schema } from "../db/index.js";
|
|
24
|
+
|
|
25
|
+
export type DocumentCommentNotificationResult = ActivityNotificationResult;
|
|
26
|
+
|
|
27
|
+
const LOG_LABEL = "[content] comment notification";
|
|
28
|
+
const EXCERPT_LIMIT = 240;
|
|
29
|
+
|
|
30
|
+
function excerpt(content: string): string {
|
|
31
|
+
const collapsed = content.replace(/\s+/g, " ").trim();
|
|
32
|
+
return collapsed.length > EXCERPT_LIMIT
|
|
33
|
+
? `${collapsed.slice(0, EXCERPT_LIMIT - 1)}…`
|
|
34
|
+
: collapsed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function documentUrl(documentId: string): string {
|
|
38
|
+
const base = getAppProductionUrl().replace(/\/+$/, "");
|
|
39
|
+
return `${base}/page/${encodeURIComponent(documentId)}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function threadParticipants(
|
|
43
|
+
documentId: string,
|
|
44
|
+
threadId: string,
|
|
45
|
+
): Promise<string[]> {
|
|
46
|
+
const rows = await getDb()
|
|
47
|
+
.select({ authorEmail: schema.documentComments.authorEmail })
|
|
48
|
+
.from(schema.documentComments)
|
|
49
|
+
.where(
|
|
50
|
+
and(
|
|
51
|
+
eq(schema.documentComments.documentId, documentId),
|
|
52
|
+
eq(schema.documentComments.threadId, threadId),
|
|
53
|
+
),
|
|
54
|
+
);
|
|
55
|
+
return rows.map((row) => row.authorEmail);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DocumentCommentNotificationInput {
|
|
59
|
+
documentId: string;
|
|
60
|
+
/** Read from the access-checked resource by the caller, never re-queried. */
|
|
61
|
+
documentTitle: string;
|
|
62
|
+
/** The document's org, so `org` visibility resolves for its members. */
|
|
63
|
+
orgId?: string | null;
|
|
64
|
+
threadId: string;
|
|
65
|
+
ownerEmail: string;
|
|
66
|
+
authorEmail: string;
|
|
67
|
+
authorName?: string | null;
|
|
68
|
+
content: string;
|
|
69
|
+
mentions: { email: string; name: string }[];
|
|
70
|
+
isReply: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function notifyDocumentComment(
|
|
74
|
+
input: DocumentCommentNotificationInput,
|
|
75
|
+
): Promise<DocumentCommentNotificationResult> {
|
|
76
|
+
return runActivityNotification(LOG_LABEL, () =>
|
|
77
|
+
deliverDocumentCommentEmails(input),
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function deliverDocumentCommentEmails(
|
|
82
|
+
input: DocumentCommentNotificationInput,
|
|
83
|
+
): Promise<DocumentCommentNotificationResult> {
|
|
84
|
+
const title = input.documentTitle.trim() || "Untitled";
|
|
85
|
+
const mentioned = new Set(
|
|
86
|
+
input.mentions.map((mention) => mention.email.trim().toLowerCase()),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const candidates = [input.ownerEmail, ...mentioned];
|
|
90
|
+
if (input.isReply) {
|
|
91
|
+
candidates.push(
|
|
92
|
+
...(await threadParticipants(input.documentId, input.threadId)),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Mentions are caller-supplied and thread rows are historical; re-check both
|
|
97
|
+
// against the document's live ACL before mailing anyone its contents.
|
|
98
|
+
const allowed = await filterRecipientsByResourceAccess({
|
|
99
|
+
resourceType: "document",
|
|
100
|
+
resourceId: input.documentId,
|
|
101
|
+
emails: candidates,
|
|
102
|
+
orgId: input.orgId,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const actor = input.authorName?.trim() || input.authorEmail;
|
|
106
|
+
const url = documentUrl(input.documentId);
|
|
107
|
+
|
|
108
|
+
return notifyActivity({
|
|
109
|
+
candidates: allowed,
|
|
110
|
+
actorEmail: input.authorEmail,
|
|
111
|
+
preferenceKey: CONTENT_USER_PREFS_KEY,
|
|
112
|
+
logLabel: LOG_LABEL,
|
|
113
|
+
send: async (to) => {
|
|
114
|
+
const wasMentioned = mentioned.has(to);
|
|
115
|
+
const lead = wasMentioned
|
|
116
|
+
? `${emailStrong(actor)} mentioned you in a comment on ${emailStrong(title)}.`
|
|
117
|
+
: input.isReply
|
|
118
|
+
? `${emailStrong(actor)} replied in a comment thread on ${emailStrong(title)}.`
|
|
119
|
+
: `${emailStrong(actor)} commented on ${emailStrong(title)}.`;
|
|
120
|
+
|
|
121
|
+
const { html, text } = renderEmail({
|
|
122
|
+
preheader: `${actor} commented on ${title}.`,
|
|
123
|
+
heading: wasMentioned
|
|
124
|
+
? "You were mentioned"
|
|
125
|
+
: input.isReply
|
|
126
|
+
? "New reply on your document"
|
|
127
|
+
: "New comment",
|
|
128
|
+
paragraphs: [lead, `"${excerpt(input.content)}"`],
|
|
129
|
+
cta: { label: "Open document", url },
|
|
130
|
+
footer:
|
|
131
|
+
"You received this because you own, were mentioned in, or participated in this thread. Turn these off in Documents settings.",
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
await sendEmail({
|
|
135
|
+
to,
|
|
136
|
+
subject: wasMentioned
|
|
137
|
+
? `${actor} mentioned you on "${title}"`
|
|
138
|
+
: input.isReply
|
|
139
|
+
? `${actor} replied to a comment on "${title}"`
|
|
140
|
+
: `${actor} commented on "${title}"`,
|
|
141
|
+
html,
|
|
142
|
+
text,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getSession } from "@agent-native/core/server";
|
|
2
|
+
import { getUserSetting } from "@agent-native/core/settings";
|
|
3
|
+
import { defineEventHandler, setResponseStatus } from "h3";
|
|
4
|
+
|
|
5
|
+
import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
|
|
6
|
+
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const session = await getSession(event);
|
|
9
|
+
if (!session?.email) {
|
|
10
|
+
setResponseStatus(event, 401);
|
|
11
|
+
return { error: "unauthorized" };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
|
|
15
|
+
// coercion-ok: a null read means this user has no preferences yet, which is a real state.
|
|
16
|
+
return stored ?? {};
|
|
17
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getSession } from "@agent-native/core/server";
|
|
2
|
+
import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
|
|
3
|
+
import { defineEventHandler, getHeader, readBody, setResponseStatus } from "h3";
|
|
4
|
+
|
|
5
|
+
import { CONTENT_USER_PREFS_KEY } from "../../../../shared/content-user-prefs.js";
|
|
6
|
+
|
|
7
|
+
export default defineEventHandler(async (event) => {
|
|
8
|
+
const session = await getSession(event);
|
|
9
|
+
if (!session?.email) {
|
|
10
|
+
setResponseStatus(event, 401);
|
|
11
|
+
return { error: "unauthorized" };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// coercion-ok: an unparsable body is rejected with 400 immediately below.
|
|
15
|
+
const body = await readBody(event).catch(() => null);
|
|
16
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
17
|
+
setResponseStatus(event, 400);
|
|
18
|
+
return { error: "Invalid settings payload" };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Merge so a partial save never wipes preferences written elsewhere.
|
|
22
|
+
const stored = await getUserSetting(session.email, CONTENT_USER_PREFS_KEY);
|
|
23
|
+
// coercion-ok: a null read means this user has no preferences yet, which is a real state.
|
|
24
|
+
const existing = stored ?? {};
|
|
25
|
+
const next = {
|
|
26
|
+
...(typeof existing === "object" && !Array.isArray(existing)
|
|
27
|
+
? existing
|
|
28
|
+
: {}),
|
|
29
|
+
...(body as Record<string, unknown>),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
await putUserSetting(session.email, CONTENT_USER_PREFS_KEY, next, {
|
|
33
|
+
requestSource: getHeader(event, "x-request-source") || undefined,
|
|
34
|
+
});
|
|
35
|
+
return next;
|
|
36
|
+
});
|
|
@@ -29,6 +29,7 @@ export interface Document {
|
|
|
29
29
|
notionPageUrl?: string | null;
|
|
30
30
|
visibility?: "private" | "org" | "public";
|
|
31
31
|
accessRole?: DocumentAccessRole;
|
|
32
|
+
canView?: boolean;
|
|
32
33
|
canEdit?: boolean;
|
|
33
34
|
canManage?: boolean;
|
|
34
35
|
source?: DocumentSourceInfo;
|
|
@@ -795,6 +796,9 @@ export interface ContentDatabaseResponse {
|
|
|
795
796
|
duplicatedDocumentIds?: string[];
|
|
796
797
|
deletedItemIds?: string[];
|
|
797
798
|
deletedDocumentIds?: string[];
|
|
799
|
+
removedItemIds?: string[];
|
|
800
|
+
removedDocumentIds?: string[];
|
|
801
|
+
removedCount?: number;
|
|
798
802
|
timings?: BuilderActionTiming[];
|
|
799
803
|
tableQueryMode?: "server" | "client-required";
|
|
800
804
|
/** Client-only optimistic state while real provider rows are being attached. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-user Documents preferences, stored under one user-setting key so
|
|
3
|
+
* Settings and the notification senders read and write the same object.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const CONTENT_USER_PREFS_KEY = "content-user-prefs";
|
|
7
|
+
|
|
8
|
+
export type ContentUserPrefs = {
|
|
9
|
+
/** Comment, reply, and mention emails only — never share invites. */
|
|
10
|
+
emailNotifications?: boolean;
|
|
11
|
+
};
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
|
|
3
|
+
import baseConfig from "@agent-native/core/vitest-config";
|
|
3
4
|
import react from "@vitejs/plugin-react-swc";
|
|
4
|
-
import { defineConfig } from "vitest/config";
|
|
5
|
+
import { defineConfig, mergeConfig } from "vitest/config";
|
|
5
6
|
|
|
6
|
-
export default
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
export default mergeConfig(
|
|
8
|
+
baseConfig,
|
|
9
|
+
defineConfig({
|
|
10
|
+
plugins: [react()],
|
|
11
|
+
resolve: {
|
|
12
|
+
alias: {
|
|
13
|
+
"@": path.resolve(__dirname, "./app"),
|
|
14
|
+
"@shared": path.resolve(__dirname, "./shared"),
|
|
15
|
+
},
|
|
12
16
|
},
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
|
|
17
|
+
test: {
|
|
18
|
+
include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
|
|
19
|
+
exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/e2e/**"],
|
|
20
|
+
hookTimeout: 60_000,
|
|
21
|
+
testTimeout: 60_000,
|
|
22
|
+
maxWorkers: "50%",
|
|
23
|
+
},
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { ChangelogSettingsCard } from "@agent-native/core/client/changelog";
|
|
2
2
|
import { LanguagePicker, useT } from "@agent-native/core/client/i18n";
|
|
3
3
|
import {
|
|
4
|
+
SettingsGroup,
|
|
5
|
+
SettingsRow,
|
|
4
6
|
SettingsTabsPage,
|
|
5
7
|
useAgentSettingsTabs,
|
|
6
8
|
type SettingsTabItem,
|
|
@@ -20,14 +22,6 @@ import { AdvancedSettings } from "@/components/crm/settings/AdvancedSettings";
|
|
|
20
22
|
import { ConnectionSettings } from "@/components/crm/settings/ConnectionSettings";
|
|
21
23
|
import { FieldsSettings } from "@/components/crm/settings/FieldsSettings";
|
|
22
24
|
import { ListsSettings } from "@/components/crm/settings/ListsSettings";
|
|
23
|
-
import {
|
|
24
|
-
Card,
|
|
25
|
-
CardContent,
|
|
26
|
-
CardDescription,
|
|
27
|
-
CardHeader,
|
|
28
|
-
CardTitle,
|
|
29
|
-
} from "@/components/ui/card";
|
|
30
|
-
import { Label } from "@/components/ui/label";
|
|
31
25
|
|
|
32
26
|
import changelog from "../../CHANGELOG.md?raw";
|
|
33
27
|
|
|
@@ -117,20 +111,18 @@ export default function SettingsRoute() {
|
|
|
117
111
|
</p>
|
|
118
112
|
</div>
|
|
119
113
|
|
|
120
|
-
<
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
</CardContent>
|
|
133
|
-
</Card>
|
|
114
|
+
<SettingsGroup>
|
|
115
|
+
<SettingsRow
|
|
116
|
+
id="language"
|
|
117
|
+
label={t("settings.languageTitle")}
|
|
118
|
+
description={t("settings.languageDescription")}
|
|
119
|
+
control={
|
|
120
|
+
<div className="w-56">
|
|
121
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
122
|
+
</div>
|
|
123
|
+
}
|
|
124
|
+
/>
|
|
125
|
+
</SettingsGroup>
|
|
134
126
|
</div>
|
|
135
127
|
}
|
|
136
128
|
whatsNew={
|
|
@@ -1,5 +1,9 @@
|
|
|
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
|
-
|
|
4
|
+
export default mergeConfig(
|
|
5
|
+
baseConfig,
|
|
6
|
+
defineConfig({
|
|
7
|
+
test: { include: ["**/*.test.ts"], environment: "node" },
|
|
8
|
+
}),
|
|
9
|
+
);
|
|
@@ -560,17 +560,28 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
560
560
|
}
|
|
561
561
|
renderRuntimeInteractionStatePreviews();
|
|
562
562
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
563
|
+
var lastSourceHeadHtml = null;
|
|
564
|
+
function replaceSourceHeadNodes(previousSourceHtml, nextSourceHtml) {
|
|
565
|
+
if (!document.head) return;
|
|
566
|
+
var stale = document.createElement("head");
|
|
567
|
+
stale.innerHTML = previousSourceHtml || "";
|
|
568
|
+
var staleCounts = {};
|
|
569
|
+
Array.prototype.forEach.call(stale.children, function(node) {
|
|
570
|
+
var key = node.outerHTML;
|
|
571
|
+
staleCounts[key] = (staleCounts[key] || 0) + 1;
|
|
572
|
+
});
|
|
573
|
+
Array.prototype.slice.call(document.head.children).forEach(function(node) {
|
|
574
|
+
var key = node.outerHTML;
|
|
575
|
+
if (!staleCounts[key]) return;
|
|
576
|
+
staleCounts[key] -= 1;
|
|
571
577
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
572
578
|
});
|
|
573
|
-
|
|
579
|
+
var next = document.createElement("head");
|
|
580
|
+
next.innerHTML = nextSourceHtml || "";
|
|
581
|
+
var anchor = document.head.firstChild;
|
|
582
|
+
Array.prototype.slice.call(next.children).forEach(function(node) {
|
|
583
|
+
document.head.insertBefore(document.importNode(node, true), anchor);
|
|
584
|
+
});
|
|
574
585
|
}
|
|
575
586
|
function chromeScaleX() {
|
|
576
587
|
return 1 / Math.max(0.05, editorChromeScaleX);
|
|
@@ -2536,7 +2547,10 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2536
2547
|
}
|
|
2537
2548
|
var nextHeadHtml = nextDoc.head ? nextDoc.head.innerHTML : "";
|
|
2538
2549
|
ensureEditorChromeStyle();
|
|
2539
|
-
|
|
2550
|
+
if (lastSourceHeadHtml === null) {
|
|
2551
|
+
lastSourceHeadHtml = nextHeadHtml;
|
|
2552
|
+
}
|
|
2553
|
+
var currentHeadHtml = lastSourceHeadHtml;
|
|
2540
2554
|
if (nextHeadHtml === currentHeadHtml && activeCandidates.length > 0) {
|
|
2541
2555
|
var currentMatch = null;
|
|
2542
2556
|
var nextMatch = null;
|
|
@@ -2598,8 +2612,9 @@ export const editorChromeBridgeScript: string = `"use strict";
|
|
|
2598
2612
|
}
|
|
2599
2613
|
}
|
|
2600
2614
|
if (currentHeadHtml !== nextHeadHtml) {
|
|
2601
|
-
|
|
2615
|
+
replaceSourceHeadNodes(currentHeadHtml, nextHeadHtml);
|
|
2602
2616
|
ensureEditorChromeStyle();
|
|
2617
|
+
lastSourceHeadHtml = nextHeadHtml;
|
|
2603
2618
|
}
|
|
2604
2619
|
Array.prototype.slice.call(document.body.attributes).forEach(function(attribute) {
|
|
2605
2620
|
document.body.removeAttribute(attribute.name);
|
|
@@ -588,8 +588,15 @@ export default defineAction({
|
|
|
588
588
|
const consoleErrors: string[] = [];
|
|
589
589
|
const fontLoadFailures: string[] = [];
|
|
590
590
|
page.on("console", (msg) => {
|
|
591
|
+
// Alpine reports failed expressions at warn level, and that warning
|
|
592
|
+
// is the only place the expression and element appear — its paired
|
|
593
|
+
// `pageerror` is a bare "Invalid or unexpected token".
|
|
591
594
|
if (msg.type() === "error") {
|
|
592
595
|
consoleErrors.push(msg.text().slice(0, 300));
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (msg.type() === "warning" && /Alpine/.test(msg.text())) {
|
|
599
|
+
consoleErrors.push(msg.text().slice(0, 300));
|
|
593
600
|
}
|
|
594
601
|
});
|
|
595
602
|
page.on("pageerror", (err) => {
|
|
@@ -106,6 +106,7 @@ import {
|
|
|
106
106
|
forwardEmbeddedCanvasPanMessage,
|
|
107
107
|
type EmbeddedCanvasPanSession,
|
|
108
108
|
} from "./design-canvas/iframe-pan";
|
|
109
|
+
import { withLocalRuntimes } from "./design-canvas/local-runtime";
|
|
109
110
|
import type { MotionTrackWire } from "./design-canvas/motion-types";
|
|
110
111
|
import {
|
|
111
112
|
PENDING_TEXT_EDIT_TIMEOUT_MS,
|
|
@@ -1018,7 +1019,14 @@ function runtimeDocumentNeedsReload(
|
|
|
1018
1019
|
Array.from(html.matchAll(SCRIPT_ELEMENT_RE), (match) => match[0]).join(
|
|
1019
1020
|
"\n",
|
|
1020
1021
|
);
|
|
1021
|
-
|
|
1022
|
+
// A changed <head> is replaced wholesale, which drops whatever the page's own
|
|
1023
|
+
// runtime injected there and cannot re-run the scripts that produced it.
|
|
1024
|
+
const headSignature = (html: string) =>
|
|
1025
|
+
/<head\b[^>]*>([\s\S]*?)<\/head\s*>/i.exec(html)?.[1] ?? "";
|
|
1026
|
+
return (
|
|
1027
|
+
scriptSignature(previousContent) !== scriptSignature(nextContent) ||
|
|
1028
|
+
headSignature(previousContent) !== headSignature(nextContent)
|
|
1029
|
+
);
|
|
1022
1030
|
}
|
|
1023
1031
|
|
|
1024
1032
|
/**
|
|
@@ -2261,7 +2269,7 @@ export function DesignCanvas({
|
|
|
2261
2269
|
editorChromeBridge +
|
|
2262
2270
|
imageDiagBridge;
|
|
2263
2271
|
const frameContent = getEmbeddedFrameDocumentContent({
|
|
2264
|
-
content: iframeRenderContent,
|
|
2272
|
+
content: withLocalRuntimes(iframeRenderContent),
|
|
2265
2273
|
embeddedFrameBackground,
|
|
2266
2274
|
transparentBackground,
|
|
2267
2275
|
contentOffsetX: embeddedFrame?.contentOffsetX ?? 0,
|
|
@@ -2282,7 +2290,7 @@ export function DesignCanvas({
|
|
|
2282
2290
|
embeddedFrame?.contentOffsetY ?? 0,
|
|
2283
2291
|
),
|
|
2284
2292
|
].join("");
|
|
2285
|
-
frameDocument = `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">${frameStyle}</head><body>${iframeRenderContent}${bridgeToInject}</body></html>`;
|
|
2293
|
+
frameDocument = `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">${frameStyle}</head><body>${withLocalRuntimes(iframeRenderContent)}${bridgeToInject}</body></html>`;
|
|
2286
2294
|
}
|
|
2287
2295
|
// Overview frames report their own content height so the canvas can
|
|
2288
2296
|
// content-fit them (Framer-style). Embedded (overview) frames only — a
|
|
@@ -88,6 +88,7 @@ import {
|
|
|
88
88
|
type ContentSizeSample,
|
|
89
89
|
} from "./design-canvas/content-size-report";
|
|
90
90
|
import { appendHitTestResponder } from "./design-canvas/hit-test";
|
|
91
|
+
import { withLocalRuntimes } from "./design-canvas/local-runtime";
|
|
91
92
|
import { DesignCanvas } from "./DesignCanvas";
|
|
92
93
|
import { dndHostLog } from "./dnd-debug";
|
|
93
94
|
import {
|
|
@@ -9499,7 +9500,9 @@ const Screen = memo(function Screen({
|
|
|
9499
9500
|
// editable DesignCanvas is supplied) still report their own height and
|
|
9500
9501
|
// content-fit. The editable DesignCanvas path injects its own reporter.
|
|
9501
9502
|
return injectSessionReplayIframeBootstrap(
|
|
9502
|
-
appendContentSizeReporter(
|
|
9503
|
+
appendContentSizeReporter(
|
|
9504
|
+
appendHitTestResponder(withLocalRuntimes(screen.content)),
|
|
9505
|
+
),
|
|
9503
9506
|
);
|
|
9504
9507
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
9505
9508
|
}, [screen.content]);
|
|
@@ -315,19 +315,49 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
|
|
|
315
315
|
renderRuntimeInteractionStatePreviews();
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
318
|
+
/**
|
|
319
|
+
* The last source <head> this bridge applied. Compared against instead of the
|
|
320
|
+
* live head, which also carries nodes the page's own runtime injected —
|
|
321
|
+
* @tailwindcss/browser's compiled sheet above all. Against the live head the
|
|
322
|
+
* comparison always differs, the head gets wiped, the compiled CSS goes with
|
|
323
|
+
* it, and the re-inserted `<script src>` cannot rebuild it because innerHTML
|
|
324
|
+
* never executes scripts. The screen then renders unstyled for good.
|
|
325
|
+
*/
|
|
326
|
+
var lastSourceHeadHtml: string | null = null;
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Swaps only the nodes the previous source head contributed. Assigning
|
|
330
|
+
* `document.head.innerHTML` instead destroys whatever the page's own runtime
|
|
331
|
+
* injected — @tailwindcss/browser's compiled sheet above all — and the
|
|
332
|
+
* `<script src>` re-inserted in its place can never rebuild it, because
|
|
333
|
+
* innerHTML does not execute scripts.
|
|
334
|
+
*/
|
|
335
|
+
function replaceSourceHeadNodes(
|
|
336
|
+
previousSourceHtml: string | null,
|
|
337
|
+
nextSourceHtml: string,
|
|
338
|
+
): void {
|
|
339
|
+
if (!document.head) return;
|
|
340
|
+
var stale = document.createElement("head");
|
|
341
|
+
stale.innerHTML = previousSourceHtml || "";
|
|
342
|
+
var staleCounts: Record<string, number> = {};
|
|
343
|
+
Array.prototype.forEach.call(stale.children, function (node: Element) {
|
|
344
|
+
var key = node.outerHTML;
|
|
345
|
+
staleCounts[key] = (staleCounts[key] || 0) + 1;
|
|
346
|
+
});
|
|
347
|
+
Array.prototype.slice.call(document.head.children).forEach(function (
|
|
348
|
+
node: Element,
|
|
349
|
+
) {
|
|
350
|
+
var key = node.outerHTML;
|
|
351
|
+
if (!staleCounts[key]) return;
|
|
352
|
+
staleCounts[key] -= 1;
|
|
353
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
354
|
+
});
|
|
355
|
+
var next = document.createElement("head");
|
|
356
|
+
next.innerHTML = nextSourceHtml || "";
|
|
357
|
+
var anchor = document.head.firstChild;
|
|
358
|
+
Array.prototype.slice.call(next.children).forEach(function (node: Element) {
|
|
359
|
+
document.head.insertBefore(document.importNode(node, true), anchor);
|
|
360
|
+
});
|
|
331
361
|
}
|
|
332
362
|
|
|
333
363
|
function chromeScaleX(): number {
|
|
@@ -3123,8 +3153,8 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
|
|
|
3123
3153
|
// Both layer states are painted here, from the one `layer-states` message,
|
|
3124
3154
|
// so every call site that re-runs after a runtime document swap restores
|
|
3125
3155
|
// hide AND lock together. Locked paints an attribute only; the hairline
|
|
3126
|
-
// treatment lives in the editor chrome stylesheet
|
|
3127
|
-
//
|
|
3156
|
+
// treatment lives in the editor chrome stylesheet, which is never part of
|
|
3157
|
+
// the source head and so never reaches source or export.
|
|
3128
3158
|
function applyLayerStateSelectors(): void {
|
|
3129
3159
|
document
|
|
3130
3160
|
.querySelectorAll("[data-agent-native-runtime-hidden]")
|
|
@@ -3248,7 +3278,13 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
|
|
|
3248
3278
|
|
|
3249
3279
|
var nextHeadHtml = nextDoc.head ? nextDoc.head.innerHTML : "";
|
|
3250
3280
|
ensureEditorChromeStyle();
|
|
3251
|
-
|
|
3281
|
+
if (lastSourceHeadHtml === null) {
|
|
3282
|
+
// First patch after a srcdoc build, so the document already carries this
|
|
3283
|
+
// source head. Forced replacements adopt too: treating the live head as
|
|
3284
|
+
// the baseline is what wipes the runtime's own nodes.
|
|
3285
|
+
lastSourceHeadHtml = nextHeadHtml;
|
|
3286
|
+
}
|
|
3287
|
+
var currentHeadHtml = lastSourceHeadHtml;
|
|
3252
3288
|
if (nextHeadHtml === currentHeadHtml && activeCandidates.length > 0) {
|
|
3253
3289
|
var currentMatch = null;
|
|
3254
3290
|
var nextMatch = null;
|
|
@@ -3326,8 +3362,9 @@ declare var __SELECTED_LAYER_DRAG_PRIORITY__: boolean;
|
|
|
3326
3362
|
}
|
|
3327
3363
|
}
|
|
3328
3364
|
if (currentHeadHtml !== nextHeadHtml) {
|
|
3329
|
-
|
|
3365
|
+
replaceSourceHeadNodes(currentHeadHtml, nextHeadHtml);
|
|
3330
3366
|
ensureEditorChromeStyle();
|
|
3367
|
+
lastSourceHeadHtml = nextHeadHtml;
|
|
3331
3368
|
}
|
|
3332
3369
|
Array.prototype.slice.call(document.body.attributes).forEach(function (
|
|
3333
3370
|
attribute: Attr,
|