@agent-native/core 0.176.1 → 0.176.2-nightly-20260831184159
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 +1 -1
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/analytics/AGENTS.md +13 -2
- package/corpus/templates/analytics/CHANGELOG.md +8 -0
- package/corpus/templates/analytics/actions/certify-dashboard.ts +39 -0
- package/corpus/templates/analytics/actions/get-sql-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/list-analysis-revisions.ts +4 -2
- package/corpus/templates/analytics/actions/list-dashboard-revisions.ts +4 -2
- package/corpus/templates/analytics/actions/search-analytics-query-catalog.ts +1 -0
- package/corpus/templates/analytics/actions/search-dashboard-references.ts +2 -1
- package/corpus/templates/analytics/actions/set-workspace-feature-flag.ts +2 -2
- package/corpus/templates/analytics/app/components/agents/FeatureFlagsFleetPanel.tsx +16 -1
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +58 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +7 -19
- package/corpus/templates/analytics/app/global.css +0 -7
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +42 -0
- package/corpus/templates/analytics/app/lib/track-metric.ts +15 -0
- package/corpus/templates/analytics/app/pages/NotFound.tsx +1 -1
- package/corpus/templates/analytics/app/pages/Placeholder.tsx +1 -1
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +115 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +8 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +23 -25
- package/corpus/templates/analytics/app/root.tsx +5 -5
- package/corpus/templates/analytics/app/routes/_index.tsx +18 -20
- package/corpus/templates/analytics/app/routes/dashboard.tsx +1 -1
- package/corpus/templates/analytics/app/routes/home.tsx +39 -0
- package/corpus/templates/analytics/changelog/2026-08-27-show-analytics-s-own-registered-flags-in-fleet-feature-flag-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-28-analytics-loading-placeholders-now-use-a-smooth-whole-surfac.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-28-analytics-loading-states-use-a-softer-whole-surfac.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-28-analytics-sidebar-horizontal-spacing-is-tighter.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-28-sidebar-branding-matches-the-app-text-color-with-a-tighter-m.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-28-sidebar-branding-uses-a-monochrome-agent-native-mark.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-29-analytics-loading-shine-is-more-subtle.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-29-chat-edits-can-be-reverted-to-saved-checkpoints.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-29-dashboard-certification-lives-in-the-overflow-menu.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-29-public-marketing-home.md +6 -0
- package/corpus/templates/analytics/package.json +2 -0
- package/corpus/templates/analytics/public/manifest.json +1 -1
- package/corpus/templates/analytics/server/db/schema.ts +4 -0
- package/corpus/templates/analytics/server/handlers/events.ts +10 -1
- package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +9 -1
- package/corpus/templates/analytics/server/handlers/session-replay.ts +10 -1
- package/corpus/templates/analytics/server/lib/agent-readable-resource-context.ts +22 -2
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +82 -7
- package/corpus/templates/analytics/server/lib/dashboard-certification.ts +58 -0
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +1 -0
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +429 -46
- package/corpus/templates/analytics/server/lib/workspace-feature-flags.ts +204 -32
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +139 -0
- package/corpus/templates/analytics/server/plugins/auth.ts +1 -0
- package/corpus/templates/analytics/server/plugins/core-routes.ts +3 -2
- package/corpus/templates/analytics/server/plugins/db.ts +11 -0
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/assets/app/components/layout/Header.tsx +2 -2
- package/corpus/templates/assets/app/components/layout/Layout.tsx +4 -3
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +14 -27
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -2
- package/corpus/templates/assets/app/root.tsx +29 -9
- package/corpus/templates/assets/app/routes/_index.tsx +15 -116
- package/corpus/templates/assets/app/routes/chat.$threadId.tsx +1 -1
- package/corpus/templates/assets/app/routes/home.tsx +137 -0
- package/corpus/templates/assets/app/routes/library.tsx +5 -1
- package/corpus/templates/assets/app/routes/settings.tsx +28 -25
- package/corpus/templates/assets/changelog/2026-08-26-templates-across-brand-kits.md +1 -0
- package/corpus/templates/assets/public/manifest.json +1 -1
- package/corpus/templates/assets/server/plugins/auth.ts +1 -0
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +3 -3
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +10 -23
- package/corpus/templates/brain/app/lib/brain.ts +2 -2
- package/corpus/templates/brain/app/root.tsx +13 -3
- package/corpus/templates/brain/app/routes/_index.tsx +15 -55
- package/corpus/templates/brain/app/routes/home.tsx +76 -0
- package/corpus/templates/brain/app/routes.ts +1 -0
- package/corpus/templates/brain/public/manifest.json +1 -1
- package/corpus/templates/brain/server/lib/brain-health.ts +2 -2
- package/corpus/templates/brain/server/plugins/auth.ts +1 -1
- package/corpus/templates/brain/server/plugins/core-routes.ts +2 -1
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/calendar/CHANGELOG.md +12 -0
- package/corpus/templates/calendar/actions/event-action-helpers.ts +2 -1
- package/corpus/templates/calendar/actions/manage-event-draft.ts +1 -1
- package/corpus/templates/calendar/actions/update-event.ts +8 -1
- package/corpus/templates/calendar/amplify.yml +15 -0
- package/corpus/templates/calendar/app/components/calendar/ApolloPanel.tsx +2 -2
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +102 -109
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +23 -10
- package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +2 -11
- package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +150 -141
- package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +3 -1
- package/corpus/templates/calendar/app/components/calendar/EventDescription.tsx +2 -2
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +359 -222
- package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +13 -5
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +21 -9
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +21 -32
- package/corpus/templates/calendar/app/global.css +11 -0
- package/corpus/templates/calendar/app/hooks/use-meeting-start-notifications.ts +10 -0
- package/corpus/templates/calendar/app/hooks/use-navigation-state.ts +3 -3
- package/corpus/templates/calendar/app/i18n-data.ts +110 -0
- package/corpus/templates/calendar/app/lib/calendar-timezone.ts +12 -3
- package/corpus/templates/calendar/app/lib/event-popover-style.ts +43 -0
- package/corpus/templates/calendar/app/lib/mcp-embed.ts +8 -2
- package/corpus/templates/calendar/app/lib/utils.ts +3 -1
- package/corpus/templates/calendar/app/pages/BookingPage.tsx +2 -8
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +9 -11
- package/corpus/templates/calendar/app/pages/ManageBookingPage.tsx +2 -6
- package/corpus/templates/calendar/app/pages/NotFound.tsx +1 -1
- package/corpus/templates/calendar/app/pages/Settings.tsx +54 -0
- package/corpus/templates/calendar/app/root.tsx +9 -1
- package/corpus/templates/calendar/app/routes/{_app._index.tsx → _app.home.tsx} +1 -1
- package/corpus/templates/calendar/app/routes/_index.tsx +34 -0
- package/corpus/templates/calendar/app/routes/event.tsx +2 -6
- package/corpus/templates/calendar/changelog/2026-08-28-all-day-events-stay-in-the-compact-top-bar-in-day-and-week-v.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-calendar-organizer-note-emails-now-link-back-to-agent-native.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-calendar-shows-google-profile-photos-in-the-desktop-app.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-event-creators-can-choose-whether-a-meeting-shows-as-free-or.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-event-popovers-match-notion-calendar-s-density-a-284px-blurr.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-fixed-calendar-navigation-scheduling-permissions-and-action-.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-google-calendar-connections-use-the-registered-callback-on-m.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-sidebar-branding-matches-the-app-text-color-with-a-tighter-m.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-sidebar-branding-uses-a-monochrome-agent-native-mark.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-the-calendar-sidebar-keeps-the-settings-link-compact.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-28-the-calendar-sidebar-keeps-the-workspace-picker-compact.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-29-public-marketing-home.md +6 -0
- package/corpus/templates/calendar/public/manifest.json +1 -1
- package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
- package/corpus/templates/calendar/server/lib/emails.ts +2 -1
- package/corpus/templates/calendar/server/lib/event-guest-notifications.ts +31 -5
- package/corpus/templates/calendar/server/lib/google-calendar.ts +4 -2
- package/corpus/templates/calendar/server/plugins/auth.ts +1 -0
- package/corpus/templates/calendar/server/plugins/core-routes.ts +5 -3
- package/corpus/templates/calendar/shared/event-permissions.ts +12 -0
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/chat/AGENTS.md +5 -4
- package/corpus/templates/chat/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/chat/app/components/layout/Layout.tsx +5 -4
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +16 -25
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +5 -5
- package/corpus/templates/chat/app/root.tsx +16 -3
- package/corpus/templates/chat/app/routes/_index.tsx +17 -74
- package/corpus/templates/chat/app/routes/chat.$threadId.tsx +1 -1
- package/corpus/templates/chat/app/routes/home.tsx +94 -0
- package/corpus/templates/chat/netlify.toml +2 -1
- package/corpus/templates/chat/public/manifest.json +1 -1
- package/corpus/templates/chat/server/plugins/auth.ts +1 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/clips/actions/add-comment.ts +18 -1
- package/corpus/templates/clips/actions/get-recording-player-data.ts +2 -0
- package/corpus/templates/clips/actions/list-comments.ts +2 -0
- package/corpus/templates/clips/actions/list-notifications.ts +60 -28
- package/corpus/templates/clips/actions/list-recording-mention-members.ts +64 -0
- package/corpus/templates/clips/actions/list-recordings.ts +1 -1
- package/corpus/templates/clips/actions/reply-to-comment.ts +17 -1
- package/corpus/templates/clips/actions/update-comment.ts +36 -2
- package/corpus/templates/clips/app/components/library/empty-state.tsx +1 -3
- package/corpus/templates/clips/app/components/library/library-grid.tsx +18 -6
- package/corpus/templates/clips/app/components/library/library-layout.tsx +6 -58
- package/corpus/templates/clips/app/components/library/recording-card.tsx +101 -3
- package/corpus/templates/clips/app/components/library/sort-menu.tsx +2 -2
- package/corpus/templates/clips/app/components/player/comment-composer.tsx +284 -0
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +162 -46
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +38 -133
- package/corpus/templates/clips/app/components/player/video-player.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +99 -20
- package/corpus/templates/clips/app/components/recorder/recording-toolbar.tsx +110 -116
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +83 -60
- package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +17 -11
- package/corpus/templates/clips/app/components/settings/types.ts +5 -1
- package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +21 -12
- package/corpus/templates/clips/app/global.css +0 -27
- package/corpus/templates/clips/app/hooks/use-desktop-promo.ts +3 -17
- package/corpus/templates/clips/app/hooks/use-mention-members.ts +24 -0
- package/corpus/templates/clips/app/hooks/use-navigation-state.ts +2 -2
- package/corpus/templates/clips/app/i18n/en-US.ts +15 -0
- package/corpus/templates/clips/app/lib/recording-backup.ts +245 -0
- package/corpus/templates/clips/app/lib/recording-retry.ts +189 -0
- package/corpus/templates/clips/app/lib/recording-status.ts +32 -0
- package/corpus/templates/clips/app/root.tsx +11 -2
- package/corpus/templates/clips/app/routes/_app.home.tsx +62 -0
- package/corpus/templates/clips/app/routes/_app.notifications.tsx +45 -12
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +2 -0
- package/corpus/templates/clips/app/routes/_index.tsx +11 -40
- package/corpus/templates/clips/app/routes/download.tsx +148 -15
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +4 -3
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +6 -11
- package/corpus/templates/clips/app/routes/record.tsx +72 -13
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +40 -24
- package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +2 -7
- package/corpus/templates/clips/changelog/2026-08-28-chrome-extension-download-help.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-28-clips-loading-skeletons-use-a-softer-whole-surface.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-28-comment-composer-no-longer-has-an-outer-border.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-29-clips-loading-shine-is-more-subtle.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +377 -476
- package/corpus/templates/clips/desktop/src/components/ui/skeleton.tsx +1 -1
- package/corpus/templates/clips/desktop/src/components/ui/spinner.tsx +1 -17
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +4 -0
- package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +0 -8
- package/corpus/templates/clips/desktop/src/overlays/record-pill.tsx +221 -460
- package/corpus/templates/clips/desktop/src/styles.css +0 -40
- package/corpus/templates/clips/desktop/src/tailwind.css +28 -14
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +15 -11
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +9 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +192 -57
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +9 -3
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +97 -3
- package/corpus/templates/clips/public/manifest.json +1 -1
- package/corpus/templates/clips/server/db/schema.ts +1 -0
- package/corpus/templates/clips/server/lib/activity-notifications.ts +30 -5
- package/corpus/templates/clips/server/lib/comment-mentions.ts +23 -0
- package/corpus/templates/clips/server/lib/emails.ts +2 -2
- package/corpus/templates/clips/server/lib/recording-page-access.ts +16 -0
- package/corpus/templates/clips/server/lib/transactional-email-templates.ts +14 -7
- package/corpus/templates/clips/server/plugins/auth.ts +1 -0
- package/corpus/templates/clips/server/plugins/core-routes.ts +5 -0
- package/corpus/templates/clips/server/plugins/db.ts +5 -0
- package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +4 -2
- package/corpus/templates/clips/server/routes/api/clips-latest.json.get.ts +77 -22
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +11 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +4 -4
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/resume.get.ts +1 -1
- package/corpus/templates/clips/shared/comment-mentions.ts +71 -0
- package/corpus/templates/clips/shared/prerendered-public-paths.ts +1 -1
- package/corpus/templates/clips/shared/recording-core.ts +5 -0
- package/corpus/templates/clips/shared/recording-playhead.css +207 -0
- package/corpus/templates/clips/shared/recording-playhead.tsx +616 -0
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/content/CHANGELOG.md +6 -0
- package/corpus/templates/content/actions/_property-utils.ts +45 -9
- package/corpus/templates/content/actions/edit-document.ts +17 -0
- package/corpus/templates/content/actions/get-document.ts +31 -11
- package/corpus/templates/content/actions/list-document-properties.ts +30 -2
- package/corpus/templates/content/actions/list-document-versions.ts +49 -17
- package/corpus/templates/content/actions/list-documents.ts +13 -2
- package/corpus/templates/content/actions/restore-document-version.ts +8 -1
- package/corpus/templates/content/actions/update-document.ts +8 -0
- package/corpus/templates/content/app/components/QueryErrorState.tsx +1 -0
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +28 -8
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +94 -61
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +24 -10
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +16 -13
- package/corpus/templates/content/app/components/editor/database/settings.tsx +16 -13
- package/corpus/templates/content/app/components/layout/Layout.tsx +35 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -18
- package/corpus/templates/content/app/hooks/use-document-properties.ts +5 -3
- package/corpus/templates/content/app/hooks/use-documents.ts +3 -1
- package/corpus/templates/content/app/hooks/use-navigation-state.ts +3 -3
- package/corpus/templates/content/app/root.tsx +9 -4
- package/corpus/templates/content/app/routes/{_app._index.tsx → _app.home.tsx} +12 -4
- package/corpus/templates/content/app/routes/_index.tsx +33 -0
- package/corpus/templates/content/changelog/2026-08-26-shared-page-load-failures-now-stay-visible-and-safe.md +6 -0
- package/corpus/templates/content/docs/product/capabilities/content.workspace.session-restore.md +2 -2
- package/corpus/templates/content/e2e/playwright.config.ts +1 -1
- package/corpus/templates/content/package.json +2 -0
- package/corpus/templates/content/parity/matrix.md +1 -1
- package/corpus/templates/content/parity/matrix.ts +1 -1
- package/corpus/templates/content/public/manifest.json +1 -1
- package/corpus/templates/content/server/db/schema.ts +1 -0
- package/corpus/templates/content/server/lib/document-version-context.ts +67 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +155 -0
- package/corpus/templates/content/server/plugins/auth.ts +1 -0
- package/corpus/templates/content/server/plugins/core-routes.ts +3 -2
- package/corpus/templates/content/server/plugins/db.ts +5 -0
- package/corpus/templates/content/shared/api.ts +6 -4
- package/corpus/templates/crm/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +1 -1
- package/corpus/templates/crm/agent-native.app-skill.json +1 -1
- package/corpus/templates/crm/app/components/layout/CrmCommandMenu.tsx +1 -1
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +36 -1
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +3 -3
- package/corpus/templates/crm/app/root.tsx +28 -7
- package/corpus/templates/crm/app/routes/_index.tsx +28 -18
- package/corpus/templates/crm/app/routes/home.tsx +27 -0
- package/corpus/templates/crm/app/routes/setup.tsx +2 -2
- package/corpus/templates/crm/app/routes.ts +1 -0
- package/corpus/templates/crm/public/manifest.json +1 -1
- package/corpus/templates/crm/server/plugins/agent-chat.ts +81 -0
- package/corpus/templates/crm/server/plugins/auth.ts +1 -0
- package/corpus/templates/crm/server/plugins/core-routes.ts +2 -1
- package/corpus/templates/crm/server/plugins/db.ts +7 -1
- package/corpus/templates/crm/shared/crm-navigation.ts +3 -2
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +13 -0
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +22 -10
- package/corpus/templates/design/AGENTS.md +1 -1
- package/corpus/templates/design/actions/add-breakpoint.ts +3 -1
- package/corpus/templates/design/actions/add-fusion-screens.ts +2 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +16 -11
- package/corpus/templates/design/actions/apply-a11y-fix.ts +6 -8
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +3 -1
- package/corpus/templates/design/actions/apply-design-token-edit.ts +3 -1
- package/corpus/templates/design/actions/apply-motion-edit.ts +18 -13
- package/corpus/templates/design/actions/apply-shader-fill.ts +3 -1
- package/corpus/templates/design/actions/apply-source-edit.ts +6 -1
- package/corpus/templates/design/actions/apply-tweaks.ts +3 -1
- package/corpus/templates/design/actions/apply-visual-edit.ts +14 -9
- package/corpus/templates/design/actions/clone-creative-context-design.ts +6 -1
- package/corpus/templates/design/actions/create-component.ts +3 -1
- package/corpus/templates/design/actions/create-file.ts +3 -1
- package/corpus/templates/design/actions/delete-file.ts +3 -1
- package/corpus/templates/design/actions/detach-component-instance.ts +3 -1
- package/corpus/templates/design/actions/edit-design.ts +16 -11
- package/corpus/templates/design/actions/generate-design.ts +19 -14
- package/corpus/templates/design/actions/get-design-branch-diff.ts +26 -31
- package/corpus/templates/design/actions/get-design-review.ts +25 -31
- package/corpus/templates/design/actions/get-design-system-index-status.ts +55 -0
- package/corpus/templates/design/actions/get-design-system.ts +1 -1
- package/corpus/templates/design/actions/hydrate-figma-paste-images.ts +3 -1
- package/corpus/templates/design/actions/import-design-source.ts +16 -9
- package/corpus/templates/design/actions/import-design-tokens.ts +3 -1
- package/corpus/templates/design/actions/import-figma-clipboard.ts +28 -16
- package/corpus/templates/design/actions/import-figma-frame.ts +3 -1
- package/corpus/templates/design/actions/insert-asset.ts +3 -1
- package/corpus/templates/design/actions/insert-design-native-asset.ts +3 -1
- package/corpus/templates/design/actions/insert-figma-library-asset.ts +3 -1
- package/corpus/templates/design/actions/list-design-versions.ts +23 -0
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +3 -1
- package/corpus/templates/design/actions/open-visual-edit.ts +23 -20
- package/corpus/templates/design/actions/present-design-variants.ts +7 -2
- package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +66 -10
- package/corpus/templates/design/actions/remove-breakpoint.ts +3 -1
- package/corpus/templates/design/actions/remove-motion-timeline.ts +3 -1
- package/corpus/templates/design/actions/restore-design-version.ts +16 -0
- package/corpus/templates/design/actions/set-layout-grid.ts +94 -0
- package/corpus/templates/design/actions/swap-component-instance.ts +6 -1
- package/corpus/templates/design/actions/update-design.ts +16 -11
- package/corpus/templates/design/actions/update-file.ts +2 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +25 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +36 -8
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +6 -6
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +185 -29
- package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +4 -4
- package/corpus/templates/design/app/components/design/ReviewPanel.tsx +1 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +35 -10
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +16 -9
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +51 -21
- package/corpus/templates/design/app/components/design/edit-panel/effects-properties.tsx +18 -17
- package/corpus/templates/design/app/components/design/edit-panel/field-primitives.tsx +6 -1
- package/corpus/templates/design/app/components/design/edit-panel/frame-presets-panel.tsx +3 -3
- package/corpus/templates/design/app/components/design/edit-panel/layout-grid-properties.tsx +88 -0
- package/corpus/templates/design/app/components/design/edit-panel/panel-primitives.tsx +5 -2
- package/corpus/templates/design/app/components/design/edit-panel/position-layout-properties.tsx +8 -4
- package/corpus/templates/design/app/components/design/edit-panel/typography-helpers.ts +8 -103
- package/corpus/templates/design/app/components/design/edit-panel/typography-properties.tsx +68 -83
- package/corpus/templates/design/app/components/design/editor/MakeRealDialog.tsx +35 -10
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +29 -24
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +6 -0
- package/corpus/templates/design/app/components/design/inspector/GlslShaderPanel.tsx +72 -71
- package/corpus/templates/design/app/components/design/inspector/InspectorControlPopover.tsx +1 -1
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +9 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +8 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +32 -0
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +8 -21
- package/corpus/templates/design/app/global.css +72 -1
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +32 -1
- package/corpus/templates/design/app/i18n-data.ts +116 -12
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +3 -1
- package/corpus/templates/design/app/lib/design-system-data.ts +36 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +170 -34
- package/corpus/templates/design/app/pages/DesignSystems.tsx +126 -11
- package/corpus/templates/design/app/pages/Index.tsx +15 -7
- package/corpus/templates/design/app/pages/NotFound.tsx +1 -1
- package/corpus/templates/design/app/pages/Templates.tsx +18 -3
- package/corpus/templates/design/app/pages/VisualEdit.tsx +1 -1
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +3 -3
- package/corpus/templates/design/app/pages/design-editor/commands/README.md +1 -0
- package/corpus/templates/design/app/pages/design-editor/commands/geometry-commit.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/commands/set-layout-grid.ts +66 -0
- package/corpus/templates/design/app/pages/design-editor/design-data-geometry-utils.ts +5 -0
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +9 -1
- package/corpus/templates/design/app/pages/design-editor/effects/resume-pending-generation.ts +39 -9
- package/corpus/templates/design/app/pages/design-editor/generation-prompt-directives.ts +31 -2
- package/corpus/templates/design/app/pages/design-editor/geometry-persistence.ts +26 -0
- package/corpus/templates/design/app/pages/design-editor/intake-question-topics.ts +335 -0
- package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +8 -1
- package/corpus/templates/design/app/root.tsx +12 -2
- package/corpus/templates/design/app/routes/_index.tsx +14 -1
- package/corpus/templates/design/app/routes/home.tsx +21 -0
- package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +1 -1
- package/corpus/templates/design/changelog/2026-08-28-frames-can-carry-an-8px-layout-grid-that-positions-snap-to.md +6 -0
- package/corpus/templates/design/changelog/2026-08-28-x-and-y-are-always-whole-numbers.md +6 -0
- package/corpus/templates/design/public/manifest.json +1 -1
- package/corpus/templates/design/server/db/schema.ts +2 -0
- package/corpus/templates/design/server/handlers/design-system-builder-link.ts +84 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +9 -1
- package/corpus/templates/design/server/lib/design-versions.ts +1017 -0
- package/corpus/templates/design/server/plugins/agent-chat.ts +144 -0
- package/corpus/templates/design/server/plugins/auth.ts +1 -1
- package/corpus/templates/design/server/plugins/core-routes.ts +3 -2
- package/corpus/templates/design/server/plugins/db.ts +7 -0
- package/corpus/templates/design/server/routes/api/design-system-builder-link.get.ts +1 -0
- package/corpus/templates/design/shared/canvas-math.ts +106 -14
- package/corpus/templates/design/shared/layout-grid.ts +80 -0
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/dispatch/AGENTS.md +11 -13
- package/corpus/templates/dispatch/actions/list-workspace-connections.ts +10 -5
- package/corpus/templates/dispatch/app/i18n-data.ts +120 -0
- package/corpus/templates/dispatch/app/root.tsx +11 -1
- package/corpus/templates/dispatch/app/routes/_index.tsx +34 -7
- package/corpus/templates/dispatch/app/routes/home.tsx +7 -0
- package/corpus/templates/dispatch/package.json +1 -0
- package/corpus/templates/dispatch/public/manifest.json +1 -1
- package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +11 -2
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/factory/.env.example +2 -14
- package/corpus/templates/factory/AGENTS.md +12 -11
- package/corpus/templates/factory/README.md +15 -17
- package/corpus/templates/factory/actions/{babysit-agent-native-pull-request.ts → babysit-factory-pull-request.ts} +125 -88
- package/corpus/templates/factory/actions/create-factory-automation.ts +161 -0
- package/corpus/templates/factory/actions/create-factory.ts +4 -124
- package/corpus/templates/factory/actions/delete-factory.ts +11 -23
- package/corpus/templates/factory/actions/{start-builder-for-item.ts → dispatch-factory-item.ts} +169 -57
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +30 -10
- package/corpus/templates/factory/actions/get-triage-config.ts +22 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +49 -2
- package/corpus/templates/factory/actions/{govern-agent-native-pull-request.ts → govern-factory-pull-request.ts} +95 -112
- package/corpus/templates/factory/actions/ingest-github-observation.ts +9 -2
- package/corpus/templates/factory/actions/list-factory-audit.ts +85 -12
- package/corpus/templates/factory/actions/list-factory-automation-templates.ts +56 -0
- package/corpus/templates/factory/actions/list-factory-automations.ts +36 -3
- package/corpus/templates/factory/actions/list-factory-graph-versions.ts +37 -10
- package/corpus/templates/factory/actions/list-triage-items.ts +120 -15
- package/corpus/templates/factory/actions/poll-github-sources.ts +102 -58
- package/corpus/templates/factory/actions/poll-sentry-errors.ts +73 -36
- package/corpus/templates/factory/actions/poll-slack-channel.ts +112 -28
- package/corpus/templates/factory/actions/{babysit-pull-request.ts → propose-pr-babysit-status.ts} +9 -47
- package/corpus/templates/factory/actions/reconcile-triage-run.ts +1 -1
- package/corpus/templates/factory/actions/save-factory-automation.ts +131 -33
- package/corpus/templates/factory/actions/save-factory-graph.ts +31 -8
- package/corpus/templates/factory/actions/save-triage-config.ts +7 -27
- package/corpus/templates/factory/actions/save-triage-rule.ts +1 -1
- package/corpus/templates/factory/app/components/factory/CreateFactoryAutomationView.tsx +258 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +349 -106
- package/corpus/templates/factory/app/components/factory/FactoryAutomationFields.tsx +614 -0
- package/corpus/templates/factory/app/components/factory/FactoryInboxView.tsx +1136 -0
- package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +7 -14
- package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +4 -223
- package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +10 -205
- package/corpus/templates/factory/app/components/factory/SlackMrkdwn.tsx +100 -0
- package/corpus/templates/factory/app/components/factory/audit-filters.ts +30 -0
- package/corpus/templates/factory/app/components/factory/factory-automation-form.ts +120 -0
- package/corpus/templates/factory/app/components/factory/inbox-filters.ts +84 -0
- package/corpus/templates/factory/app/components/factory/inbox-source-url.ts +23 -0
- package/corpus/templates/factory/app/components/factory/slack-emoji.ts +165 -0
- package/corpus/templates/factory/app/components/factory/slack-mrkdwn.ts +128 -0
- package/corpus/templates/factory/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/factory/app/components/layout/Layout.tsx +63 -6
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +13 -26
- package/corpus/templates/factory/app/components/triage/triage-status-pill.tsx +63 -14
- package/corpus/templates/factory/app/global.css +106 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +16 -10
- package/corpus/templates/factory/app/i18n/en-US.ts +154 -7
- package/corpus/templates/factory/app/lib/factory-tab-params.ts +59 -0
- package/corpus/templates/factory/app/lib/safe-http-url.ts +8 -0
- package/corpus/templates/factory/app/root.tsx +16 -3
- package/corpus/templates/factory/app/routes/_index.tsx +27 -5
- package/corpus/templates/factory/app/routes/factory.tsx +325 -733
- package/corpus/templates/factory/app/routes/home.tsx +13 -0
- package/corpus/templates/factory/app/routes/new-factory.tsx +3 -5
- package/corpus/templates/factory/changelog/2026-08-26-inbox-full-screen-thread.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-26-inbox-thread-and-audit-labels.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-audit-run-list-stacks.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-audit-run-names-wrap.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-factory-opens-on-inbox.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-github-repository-url.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-inbox-filters.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-polling-does-not-enable-automations.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-27-pr-babysit-can-poll-github.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-factory-automations-use-workspace-connections.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-inbox-approve-and-start-removed.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-pr-babysit-audit-shows-decisions.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-pr-babysit-reviews-next-github-prs.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-pr-babysit-sticky-out-of-scope.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-28-pr-babysit-uses-github-evidence.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-29-audit-filters-pagination-scroll.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-29-create-factory-automations.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-29-dispatch-reaction-argument.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-29-factory-action-names-match-behavior.md +6 -0
- package/corpus/templates/factory/public/manifest.json +1 -1
- package/corpus/templates/factory/server/connectors/slack.ts +8 -6
- package/corpus/templates/factory/server/db/schema.ts +23 -0
- package/corpus/templates/factory/server/lib/audit-cursor.ts +44 -0
- package/corpus/templates/factory/server/lib/factory-action-names.ts +15 -0
- package/corpus/templates/factory/server/lib/factory-audit-report.ts +29 -9
- package/corpus/templates/factory/server/lib/factory-automation-caller.ts +38 -0
- package/corpus/templates/factory/server/lib/factory-automation-config.ts +543 -0
- package/corpus/templates/factory/server/lib/factory-automation-plan.ts +0 -48
- package/corpus/templates/factory/server/lib/factory-automation-repair.ts +2 -18
- package/corpus/templates/factory/server/lib/factory-poll-cursors.ts +98 -0
- package/corpus/templates/factory/server/lib/factory-scope.ts +8 -0
- package/corpus/templates/factory/server/lib/github-repository.ts +104 -0
- package/corpus/templates/factory/server/lib/inbox-cursor.ts +34 -0
- package/corpus/templates/factory/server/lib/pr-babysit-prompt.ts +33 -0
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +58 -17
- package/corpus/templates/factory/server/lib/safe-http-url.ts +8 -0
- package/corpus/templates/factory/server/lib/slack-feedback-prompt.ts +19 -10
- package/corpus/templates/factory/server/lib/source-reaction.ts +37 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +18 -22
- package/corpus/templates/factory/server/plugins/auth.ts +1 -0
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +26 -0
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +277 -164
- package/corpus/templates/factory/server/plugins/integrations.ts +5 -7
- package/corpus/templates/factory/server/triage/github-client.ts +274 -3
- package/corpus/templates/factory/server/triage/github-ingestion.ts +3 -1
- package/corpus/templates/factory/server/triage/metadata.ts +12 -0
- package/corpus/templates/factory/server/triage/pr-babysit.ts +22 -21
- package/corpus/templates/factory/server/triage/review-skill-alignment.ts +11 -11
- package/corpus/templates/factory/server/triage/review-state.ts +39 -0
- package/corpus/templates/factory/server/triage/slack-client.ts +14 -6
- package/corpus/templates/factory/server/triage/slack-poller.ts +34 -65
- package/corpus/templates/factory/server/triage/slack-user-labels.ts +126 -0
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/forms/AGENTS.md +4 -3
- package/corpus/templates/forms/actions/response-insights.ts +4 -4
- package/corpus/templates/forms/actions/retry-response-deliveries.ts +26 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +8 -33
- package/corpus/templates/forms/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/forms/app/lib/route-prewarm.ts +1 -1
- package/corpus/templates/forms/app/root.tsx +3 -2
- package/corpus/templates/forms/app/routes/_app.home.tsx +47 -0
- package/corpus/templates/forms/app/routes/_app.tsx +2 -1
- package/corpus/templates/forms/app/routes/_index.tsx +10 -23
- package/corpus/templates/forms/public/manifest.json +1 -1
- package/corpus/templates/forms/server/db/schema.ts +64 -17
- package/corpus/templates/forms/server/handlers/submissions.ts +1022 -94
- package/corpus/templates/forms/server/lib/integrations.ts +100 -33
- package/corpus/templates/forms/server/middleware/00-public-cors.ts +1 -1
- package/corpus/templates/forms/server/plugins/auth.ts +1 -0
- package/corpus/templates/forms/server/plugins/core-routes.ts +1 -0
- package/corpus/templates/forms/server/plugins/db.ts +40 -0
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/macros/actions/view-screen.ts +1 -1
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +9 -21
- package/corpus/templates/macros/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/macros/app/root.tsx +22 -8
- package/corpus/templates/macros/app/routes/_index.tsx +16 -291
- package/corpus/templates/macros/app/routes/home.tsx +312 -0
- package/corpus/templates/macros/server/plugins/auth.ts +9 -7
- package/corpus/templates/macros/server/plugins/core-routes.ts +1 -0
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/mail/.agents/skills/inbox-automations/SKILL.md +13 -2
- package/corpus/templates/mail/.agents/skills/inbox-reads-and-triage/SKILL.md +1 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/mail/AGENTS.md +5 -2
- package/corpus/templates/mail/actions/apply-ai-filter.ts +294 -0
- package/corpus/templates/mail/actions/create-automation.ts +1 -0
- package/corpus/templates/mail/actions/get-ai-filter.ts +19 -0
- package/corpus/templates/mail/actions/manage-automations.ts +162 -157
- package/corpus/templates/mail/actions/manage-email-rules.ts +3 -0
- package/corpus/templates/mail/actions/navigate.ts +1 -1
- package/corpus/templates/mail/actions/update-automation.ts +1 -0
- package/corpus/templates/mail/actions/update-mail-preferences.ts +1 -0
- package/corpus/templates/mail/app/components/email/AiFilterDialog.tsx +127 -0
- package/corpus/templates/mail/app/components/email/EmailList.tsx +63 -0
- package/corpus/templates/mail/app/components/email/EmailThread.tsx +95 -0
- package/corpus/templates/mail/app/components/email/MobileActionBar.tsx +35 -3
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +17 -22
- package/corpus/templates/mail/app/components/settings/AiFilterSection.tsx +401 -0
- package/corpus/templates/mail/app/hooks/use-ai-filter.ts +48 -0
- package/corpus/templates/mail/app/hooks/use-automations.ts +1 -0
- package/corpus/templates/mail/app/hooks/use-emails.ts +11 -3
- package/corpus/templates/mail/app/i18n/en-US.ts +55 -0
- package/corpus/templates/mail/app/lib/automation-visibility.ts +17 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +5 -2
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +16 -8
- package/corpus/templates/mail/app/pages/inbox-zero.ts +1 -2
- package/corpus/templates/mail/app/root.tsx +20 -8
- package/corpus/templates/mail/app/routes/_index.tsx +16 -55
- package/corpus/templates/mail/app/routes/home.tsx +71 -0
- package/corpus/templates/mail/changelog/2026-08-28-mail-settings-show-chat-created-automations.md +6 -0
- package/corpus/templates/mail/public/manifest.json +1 -1
- package/corpus/templates/mail/server/db/schema.ts +3 -0
- package/corpus/templates/mail/server/handlers/emails.ts +34 -11
- package/corpus/templates/mail/server/handlers/google-auth.ts +1 -1
- package/corpus/templates/mail/server/lib/ai-filter.ts +103 -0
- package/corpus/templates/mail/server/lib/automation-actions.ts +14 -9
- package/corpus/templates/mail/server/lib/automation-engine.ts +142 -18
- package/corpus/templates/mail/server/lib/automations.ts +9 -0
- package/corpus/templates/mail/server/lib/email-state.ts +7 -2
- package/corpus/templates/mail/server/lib/gmail-query.ts +10 -0
- package/corpus/templates/mail/server/lib/google-auth.ts +5 -8
- package/corpus/templates/mail/server/lib/jobs.ts +1 -5
- package/corpus/templates/mail/server/onboarding.ts +2 -2
- package/corpus/templates/mail/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/mail/server/plugins/auth.ts +1 -0
- package/corpus/templates/mail/server/plugins/core-routes.ts +4 -1
- package/corpus/templates/mail/server/plugins/db.ts +6 -0
- package/corpus/templates/mail/server/routes/api/attachments.get.ts +1 -5
- package/corpus/templates/mail/shared/ai-filter.ts +74 -0
- package/corpus/templates/mail/shared/types.ts +2 -0
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/plan/actions/list-plan-versions.ts +20 -5
- package/corpus/templates/plan/agent-native.json +1 -4
- package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +5 -2
- package/corpus/templates/plan/app/components/layout/Layout.tsx +41 -1
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -16
- package/corpus/templates/plan/app/components/plan/PlanMarkdownEditor.tsx +7 -4
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +15 -0
- package/corpus/templates/plan/app/components/plan/wireframe/kit/plan-wireframe-tokens.css +0 -15
- package/corpus/templates/plan/app/components/plan/wireframe/kit/primitives.tsx +2 -2
- package/corpus/templates/plan/app/hooks/use-plan-presence.ts +20 -10
- package/corpus/templates/plan/app/pages/PlansPage.tsx +2 -2
- package/corpus/templates/plan/app/root.tsx +13 -7
- package/corpus/templates/plan/app/routes/_index.tsx +31 -6
- package/corpus/templates/plan/app/routes/chat.tsx +3 -6
- package/corpus/templates/plan/app/routes/home.tsx +11 -0
- package/corpus/templates/plan/app/routes/local-plans.$slug.tsx +2 -6
- package/corpus/templates/plan/app/routes/plans.$id.tsx +3 -6
- package/corpus/templates/plan/app/routes/plans.tsx +3 -6
- package/corpus/templates/plan/app/routes/recaps.$id.tsx +3 -6
- package/corpus/templates/plan/app/routes/recaps.tsx +3 -6
- package/corpus/templates/plan/changelog/2026-08-28-plan-loading-skeletons-use-a-softer-whole-surface.md +6 -0
- package/corpus/templates/plan/changelog/2026-08-29-plan-loading-shine-is-more-subtle.md +6 -0
- package/corpus/templates/plan/public/manifest.json +1 -1
- package/corpus/templates/plan/server/db/schema.ts +1 -0
- package/corpus/templates/plan/server/lib/plan-versions.ts +57 -0
- package/corpus/templates/plan/server/plugins/agent-chat.ts +83 -0
- package/corpus/templates/plan/server/plugins/core-routes.ts +1 -0
- package/corpus/templates/plan/server/plugins/db.ts +10 -0
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/slides/CHANGELOG.md +9 -0
- package/corpus/templates/slides/actions/_deck-write.ts +65 -0
- package/corpus/templates/slides/actions/add-slide.ts +44 -24
- package/corpus/templates/slides/actions/clone-context-slide.ts +22 -12
- package/corpus/templates/slides/actions/create-deck.ts +36 -21
- package/corpus/templates/slides/actions/delete-design-system.ts +10 -3
- package/corpus/templates/slides/actions/import-file.ts +9 -3
- package/corpus/templates/slides/actions/import-pptx.ts +11 -4
- package/corpus/templates/slides/actions/list-deck-versions.ts +20 -8
- package/corpus/templates/slides/actions/patch-deck.ts +29 -3
- package/corpus/templates/slides/actions/restore-deck-version.ts +37 -22
- package/corpus/templates/slides/actions/save-deck.ts +35 -22
- package/corpus/templates/slides/actions/update-deck-aspect-ratio.ts +31 -16
- package/corpus/templates/slides/actions/update-slide.ts +250 -37
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +10 -4
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +2 -2
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +7 -8
- package/corpus/templates/slides/app/components/editor/ImageOverlay.tsx +78 -12
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +42 -4
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +381 -53
- package/corpus/templates/slides/app/components/editor/SlidesLayersPanel.tsx +20 -34
- package/corpus/templates/slides/app/components/editor/slide-style.ts +5 -0
- package/corpus/templates/slides/app/components/editor/style-clipboard.ts +2 -0
- package/corpus/templates/slides/app/components/layout/AgentWorkIndicator.tsx +18 -2
- package/corpus/templates/slides/app/components/layout/Header.tsx +1 -1
- package/corpus/templates/slides/app/components/layout/Layout.tsx +39 -10
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +7 -20
- package/corpus/templates/slides/app/components/presentation/PresenterView.tsx +35 -15
- package/corpus/templates/slides/app/components/presentation/present-channel.ts +12 -0
- package/corpus/templates/slides/app/global.css +45 -13
- package/corpus/templates/slides/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +11 -0
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +133 -5
- package/corpus/templates/slides/app/lib/slide-image-replacement.ts +741 -17
- package/corpus/templates/slides/app/lib/validate-native-slide-html.ts +1 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +288 -95
- package/corpus/templates/slides/app/pages/DesignSystems.tsx +5 -5
- package/corpus/templates/slides/app/pages/Index.tsx +7 -7
- package/corpus/templates/slides/app/pages/NotFound.tsx +1 -1
- package/corpus/templates/slides/app/pages/SharedPresentation.tsx +1 -1
- package/corpus/templates/slides/app/root.tsx +4 -23
- package/corpus/templates/slides/app/routes/_index.tsx +18 -7
- package/corpus/templates/slides/app/routes/home.tsx +26 -0
- package/corpus/templates/slides/changelog/2026-08-27-image-fit-controls-apply-cover-crops-and-position.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-28-image-edits-persist-while-dropped-images-finish-uploading.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-28-shared-slides-with-a-style-block-render-again.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-28-slides-loading-skeletons-use-a-softer-whole-surface.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-28-standard-empty-home-layout.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-29-chat-imports-attached-decks-on-request.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-29-slides-loading-shine-is-more-subtle.md +6 -0
- package/corpus/templates/slides/package.json +3 -0
- package/corpus/templates/slides/public/manifest.json +1 -1
- package/corpus/templates/slides/server/db/schema.ts +1 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +1 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +102 -7
- package/corpus/templates/slides/server/lib/deck-versions.ts +77 -2
- package/corpus/templates/slides/server/plugins/agent-chat.ts +95 -1
- package/corpus/templates/slides/server/plugins/auth.ts +1 -0
- package/corpus/templates/slides/server/plugins/core-routes.ts +8 -1
- package/corpus/templates/slides/server/plugins/db.ts +5 -0
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +4 -0
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +47 -0
- package/corpus/templates/tasks/AGENTS.md +2 -1
- package/corpus/templates/tasks/README.md +3 -1
- package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -18
- package/corpus/templates/tasks/app/root.tsx +19 -3
- package/corpus/templates/tasks/app/routes/_index.tsx +28 -14
- package/corpus/templates/tasks/app/routes/home.tsx +24 -0
- package/corpus/templates/tasks/public/manifest.json +1 -1
- package/corpus/templates/tasks/server/plugins/auth.ts +1 -0
- package/dist/a2a/client.d.ts +4 -0
- package/dist/a2a/client.js +15 -2
- package/dist/action.d.ts +3 -1
- package/dist/agent/engine/ai-sdk-engine.js +13 -9
- package/dist/agent/engine/anthropic-engine.js +2 -1
- package/dist/agent/engine/builder-engine.js +23 -5
- package/dist/agent/engine/limit-provider-tools.d.ts +3 -0
- package/dist/agent/engine/limit-provider-tools.js +23 -0
- package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
- package/dist/agent/engine/openai-compatible-endpoint.js +4 -0
- package/dist/agent/engine/output-tokens.d.ts +12 -6
- package/dist/agent/engine/output-tokens.js +42 -16
- package/dist/agent/engine/registry.d.ts +1 -1
- package/dist/agent/engine/registry.js +69 -16
- package/dist/agent/production-agent.js +107 -13
- package/dist/agent/run-manager.d.ts +9 -0
- package/dist/agent/run-manager.js +35 -6
- package/dist/agent/thread-data-builder.d.ts +6 -1
- package/dist/agent/thread-data-builder.js +20 -5
- package/dist/agent/types.d.ts +2 -0
- package/dist/app-config/agent.d.ts +4 -0
- package/dist/app-config/agent.js +44 -0
- package/dist/app-config/integrations.d.ts +1 -0
- package/dist/app-config/integrations.js +8 -0
- package/dist/app-config/migration.d.ts +1 -0
- package/dist/app-config/migration.js +4 -0
- package/dist/app-config/observability.d.ts +4 -1
- package/dist/app-config/observability.js +25 -1
- package/dist/app-config/schema.d.ts +9 -0
- package/dist/app-config/store.js +1 -0
- package/dist/client/AgentAskPopover.d.ts +2 -1
- package/dist/client/AgentAskPopover.js +2 -2
- package/dist/client/AgentPanel.d.ts +35 -10
- package/dist/client/AgentPanel.js +136 -119
- package/dist/client/AssistantChat.d.ts +9 -2
- package/dist/client/AssistantChat.js +161 -36
- package/dist/client/ConnectBuilderCard.js +3 -1
- package/dist/client/DefaultSpinner.d.ts +13 -1
- package/dist/client/DefaultSpinner.js +52 -46
- package/dist/client/FeedbackButton.d.ts +12 -0
- package/dist/client/FeedbackButton.js +62 -28
- package/dist/client/MultiTabAssistantChat.js +30 -11
- package/dist/client/NewWorkspaceAppFlow.js +5 -3
- package/dist/client/agent-chat/index.d.ts +1 -0
- package/dist/client/agent-chat/index.js +1 -0
- package/dist/client/agent-chat-adapter.js +16 -1
- package/dist/client/agent-chat.d.ts +9 -0
- package/dist/client/agent-chat.js +6 -3
- package/dist/client/agent-page/AgentJobsTab.d.ts +2 -1
- package/dist/client/agent-page/AgentJobsTab.js +8 -5
- package/dist/client/agent-page/AgentTabsPage.js +2 -2
- package/dist/client/analytics.d.ts +2 -0
- package/dist/client/analytics.js +86 -15
- package/dist/client/app-providers.js +13 -1
- package/dist/client/auth/AuthPage.d.ts +87 -0
- package/dist/client/auth/AuthPage.js +1847 -0
- package/dist/client/auth/ResetPasswordPage.d.ts +9 -0
- package/dist/client/auth/ResetPasswordPage.js +119 -0
- package/dist/client/auth/entry.d.ts +1 -0
- package/dist/client/auth/entry.js +15 -0
- package/dist/client/chat/message-components.d.ts +53 -0
- package/dist/client/chat/message-components.js +181 -11
- package/dist/client/chat/run-recovery.d.ts +4 -1
- package/dist/client/chat/run-recovery.js +30 -12
- package/dist/client/chat/tool-call-display.d.ts +4 -2
- package/dist/client/chat/tool-call-display.js +16 -11
- package/dist/client/chat-first.js +8 -2
- package/dist/client/chat-model-groups.js +11 -1
- package/dist/client/collab/index.d.ts +1 -1
- package/dist/client/components/CodeRequiredDialog.js +22 -35
- package/dist/client/components/icons/AgentNativeIcon.d.ts +3 -3
- package/dist/client/components/icons/AgentNativeIcon.js +4 -4
- package/dist/client/components/ui/message-scroller.js +1 -1
- package/dist/client/composer/runtime-adapters.js +2 -0
- package/dist/client/feedback-context.d.ts +1 -0
- package/dist/client/feedback-context.js +3 -2
- package/dist/client/host-bridge.d.ts +1 -0
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +1 -1
- package/dist/client/integrations/IntegrationsPanel.d.ts +2 -1
- package/dist/client/integrations/IntegrationsPanel.js +3 -3
- package/dist/client/observability/ThumbsFeedback.js +73 -10
- package/dist/client/onboarding/FirstRunOnboarding.js +24 -15
- package/dist/client/onboarding/OnboardingPanel.js +5 -3
- package/dist/client/onboarding/first-run-startup-gate.js +7 -1
- package/dist/client/resources/McpIntegrationDialog.d.ts +2 -1
- package/dist/client/resources/McpIntegrationDialog.js +10 -2
- package/dist/client/session-replay.js +10 -0
- package/dist/client/settings/BuilderConnectPopover.d.ts +25 -0
- package/dist/client/settings/BuilderConnectPopover.js +55 -0
- package/dist/client/settings/SettingsPanel.js +21 -7
- package/dist/client/settings/SettingsTabsPage.d.ts +1 -1
- package/dist/client/settings/SettingsTabsPage.js +42 -25
- package/dist/client/settings/VoiceTranscriptionSection.js +16 -22
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.js +1 -0
- package/dist/client/settings/useBuilderStatus.d.ts +7 -0
- package/dist/client/settings/useBuilderStatus.js +77 -21
- package/dist/client/setup-connections/BuilderConnectCard.js +2 -1
- package/dist/client/setup-connections/useBuilderConnectCardController.d.ts +3 -1
- package/dist/client/setup-connections/useBuilderConnectCardController.js +4 -2
- package/dist/client/sse-event-processor.js +8 -0
- package/dist/client/terminal/AgentTerminal.js +6 -7
- package/dist/client/transcription/BuilderTranscriptionCta.js +17 -69
- package/dist/client/ui/index.d.ts +1 -0
- package/dist/client/ui/index.js +1 -0
- package/dist/client/use-chat-models.js +5 -4
- package/dist/client/webmcp.d.ts +4 -0
- package/dist/client/webmcp.js +51 -4
- package/dist/collab/client.d.ts +13 -0
- package/dist/collab/client.js +96 -21
- package/dist/dashboard-storage/index.d.ts +1 -1
- package/dist/dashboard-storage/schema.d.ts +19 -0
- package/dist/dashboard-storage/schema.js +1 -0
- package/dist/dashboard-storage/store.d.ts +9 -0
- package/dist/dashboard-storage/store.js +93 -3
- package/dist/deploy/build.d.ts +19 -3
- package/dist/deploy/build.js +262 -10
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/ingestion/media.js +7 -2
- package/dist/integrations/config-store.js +2 -4
- package/dist/integrations/google-docs-poller.d.ts +1 -1
- package/dist/integrations/google-docs-poller.js +100 -24
- package/dist/integrations/plugin.js +45 -15
- package/dist/integrations/webhook-handler.js +2 -1
- package/dist/jobs/background-automation-runner.js +17 -1
- package/dist/localization/core-messages/ar-SA.js +19 -0
- package/dist/localization/core-messages/de-DE.js +19 -0
- package/dist/localization/core-messages/en-US.d.ts +19 -0
- package/dist/localization/core-messages/en-US.js +19 -0
- package/dist/localization/core-messages/es-ES.js +19 -0
- package/dist/localization/core-messages/fr-FR.js +19 -0
- package/dist/localization/core-messages/hi-IN.js +19 -0
- package/dist/localization/core-messages/ja-JP.js +19 -0
- package/dist/localization/core-messages/ko-KR.js +19 -0
- package/dist/localization/core-messages/pt-BR.js +19 -0
- package/dist/localization/core-messages/zh-CN.js +19 -0
- package/dist/localization/core-messages/zh-TW.js +19 -0
- package/dist/localization/core-messages.d.ts +19 -0
- package/dist/localization/default-messages.d.ts +11 -0
- package/dist/localization/default-messages.js +11 -0
- package/dist/mcp/analytics.d.ts +103 -0
- package/dist/mcp/analytics.js +204 -0
- package/dist/mcp/build-server.d.ts +7 -0
- package/dist/mcp/build-server.js +132 -35
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp/server.js +37 -8
- package/dist/mcp/stdio.js +1 -0
- package/dist/mcp-client/errors.js +30 -10
- package/dist/mcp-client/oauth-routes.d.ts +7 -2
- package/dist/mcp-client/oauth-routes.js +12 -3
- package/dist/mcp-client/routes.js +2 -1
- package/dist/oauth-tokens/store.js +6 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/routes.js +8 -2
- package/dist/observability/store.d.ts +1 -1
- package/dist/observability/store.js +18 -3
- package/dist/observability/types.d.ts +1 -0
- package/dist/onboarding/plugin.js +16 -4
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +16 -16
- package/dist/provider-api/actions/provider-api.d.ts +12 -12
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/action-routes.d.ts +1 -6
- package/dist/server/action-routes.js +61 -18
- package/dist/server/agent-chat/plugin-options.d.ts +8 -1
- package/dist/server/agent-chat-plugin.d.ts +3 -0
- package/dist/server/agent-chat-plugin.js +49 -4
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-run-context.d.ts +1 -0
- package/dist/server/agent-run-context.js +6 -0
- package/dist/server/analytics.d.ts +3 -2
- package/dist/server/analytics.js +18 -7
- package/dist/server/app-url.d.ts +5 -2
- package/dist/server/app-url.js +4 -3
- package/dist/server/auth.d.ts +25 -0
- package/dist/server/auth.js +168 -21
- package/dist/server/better-auth-instance.js +18 -4
- package/dist/server/better-auth-migrations.d.ts +14 -0
- package/dist/server/better-auth-migrations.js +5 -1
- package/dist/server/builder-api-auth.js +30 -6
- package/dist/server/builder-browser.d.ts +10 -0
- package/dist/server/builder-browser.js +22 -5
- package/dist/server/builder-design-systems.d.ts +11 -0
- package/dist/server/builder-design-systems.js +52 -3
- package/dist/server/builder-oauth.d.ts +13 -6
- package/dist/server/builder-oauth.js +121 -63
- package/dist/server/capture-error.js +3 -0
- package/dist/server/cookie-namespace.d.ts +1 -0
- package/dist/server/cookie-namespace.js +3 -0
- package/dist/server/core-routes-plugin.d.ts +25 -9
- package/dist/server/core-routes-plugin.js +180 -76
- package/dist/server/credential-provider.js +22 -12
- package/dist/server/email.d.ts +4 -0
- package/dist/server/email.js +13 -5
- package/dist/server/framework-request-handler.js +6 -3
- package/dist/server/google-credential-check.d.ts +7 -3
- package/dist/server/google-credential-check.js +71 -0
- package/dist/server/google-oauth-credentials.d.ts +4 -3
- package/dist/server/google-oauth-credentials.js +7 -8
- package/dist/server/google-oauth.d.ts +9 -4
- package/dist/server/google-oauth.js +14 -93
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/jwks-secret-rotation.d.ts +29 -0
- package/dist/server/jwks-secret-rotation.js +150 -0
- package/dist/server/onboarding-html.d.ts +2 -14
- package/dist/server/onboarding-html.js +254 -2519
- package/dist/server/origin-allowlist.d.ts +15 -0
- package/dist/server/origin-allowlist.js +93 -0
- package/dist/server/release-migrations.js +48 -0
- package/dist/server/request-context.d.ts +2 -0
- package/dist/server/request-context.js +7 -2
- package/dist/server/self-dispatch.js +5 -0
- package/dist/server/sentry.js +5 -0
- package/dist/server/ssr-handler.js +5 -0
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +9 -0
- package/dist/server/workspace-provider-oauth.js +96 -31
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/index.js +2 -0
- package/dist/shared/loading-labels.d.ts +1 -0
- package/dist/shared/loading-labels.js +55 -0
- package/dist/shared/qa-test-email.d.ts +1 -0
- package/dist/shared/qa-test-email.js +42 -0
- package/dist/shared/route-warmup-config.js +2 -2
- package/dist/shared/sign-in-journey.js +1 -1
- package/dist/shared/ssr-auth-redirect.d.ts +8 -0
- package/dist/shared/ssr-auth-redirect.js +56 -0
- package/dist/shared/test-traffic.d.ts +8 -0
- package/dist/shared/test-traffic.js +11 -0
- package/dist/styles/agent-native.css +50 -14
- package/dist/styles/blocks.css +0 -6
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +47 -0
- package/dist/templates/chat/AGENTS.md +5 -4
- package/dist/templates/chat/app/components/layout/Header.tsx +1 -1
- package/dist/templates/chat/app/components/layout/Layout.tsx +5 -4
- package/dist/templates/chat/app/components/layout/Sidebar.tsx +16 -25
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +5 -5
- package/dist/templates/chat/app/root.tsx +16 -3
- package/dist/templates/chat/app/routes/_index.tsx +17 -74
- package/dist/templates/chat/app/routes/chat.$threadId.tsx +1 -1
- package/dist/templates/chat/app/routes/home.tsx +94 -0
- package/dist/templates/chat/netlify.toml +2 -1
- package/dist/templates/chat/public/manifest.json +1 -1
- package/dist/templates/chat/server/plugins/auth.ts +1 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +4 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +47 -0
- package/dist/templates/default/AGENTS.md +10 -6
- package/dist/templates/default/DEVELOPING.md +8 -1
- package/dist/templates/default/app/hooks/use-navigation-state.ts +1 -1
- package/dist/templates/default/app/root.tsx +10 -3
- package/dist/templates/default/app/routes/_index.tsx +10 -86
- package/dist/templates/default/app/routes/home.tsx +94 -0
- package/dist/templates/default/app/routes/settings.tsx +1 -1
- package/dist/templates/default/public/manifest.json +1 -1
- package/dist/templates/default/server/plugins/auth.ts +5 -0
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +47 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -0
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +47 -0
- package/dist/templates/workspace-root/.env.example +3 -2
- package/dist/terminal/pty-server.d.ts +2 -0
- package/dist/terminal/pty-server.js +22 -5
- package/dist/tracking/registry.d.ts +1 -0
- package/dist/tracking/registry.js +12 -0
- package/dist/usage/store.d.ts +1 -0
- package/dist/usage/store.js +16 -7
- package/dist/vite/client.d.ts +1 -1
- package/dist/vite/client.js +59 -0
- package/dist/workspace-connections/index.d.ts +1 -1
- package/dist/workspace-connections/index.js +1 -1
- package/dist/workspace-connections/store.d.ts +1 -0
- package/dist/workspace-connections/store.js +4 -0
- package/docs/content/aws-amplify.mdx +179 -0
- package/docs/content/client-agent-chat.mdx +1 -1
- package/docs/content/deploy-an-app.mdx +2 -1
- package/docs/content/deployment.mdx +14 -3
- package/docs/content/environment-variables.mdx +1 -0
- package/docs/content/template-forms-agent.mdx +65 -0
- package/docs/content/template-forms-developers.mdx +220 -65
- package/docs/content/template-forms-features.mdx +154 -0
- package/docs/content/template-forms-integrations.mdx +40 -0
- package/docs/content/template-forms.mdx +49 -36
- package/docs/content/template-mail-developers.mdx +3 -3
- package/docs/content/toolkit-settings.mdx +3 -3
- package/docs/content/webmcp.mdx +31 -12
- package/package.json +3 -3
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +47 -0
- package/src/templates/chat/AGENTS.md +5 -4
- package/src/templates/chat/app/components/layout/Header.tsx +1 -1
- package/src/templates/chat/app/components/layout/Layout.tsx +5 -4
- package/src/templates/chat/app/components/layout/Sidebar.tsx +16 -25
- package/src/templates/chat/app/hooks/use-navigation-state.ts +5 -5
- package/src/templates/chat/app/root.tsx +16 -3
- package/src/templates/chat/app/routes/_index.tsx +17 -74
- package/src/templates/chat/app/routes/chat.$threadId.tsx +1 -1
- package/src/templates/chat/app/routes/home.tsx +94 -0
- package/src/templates/chat/netlify.toml +2 -1
- package/src/templates/chat/public/manifest.json +1 -1
- package/src/templates/chat/server/plugins/auth.ts +1 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +4 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +47 -0
- package/src/templates/default/AGENTS.md +10 -6
- package/src/templates/default/DEVELOPING.md +8 -1
- package/src/templates/default/app/hooks/use-navigation-state.ts +1 -1
- package/src/templates/default/app/root.tsx +10 -3
- package/src/templates/default/app/routes/_index.tsx +10 -86
- package/src/templates/default/app/routes/home.tsx +94 -0
- package/src/templates/default/app/routes/settings.tsx +1 -1
- package/src/templates/default/public/manifest.json +1 -1
- package/src/templates/default/server/plugins/auth.ts +5 -0
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +47 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +4 -0
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +47 -0
- package/src/templates/workspace-root/.env.example +3 -2
- package/corpus/templates/factory/actions/approve-factory-item.ts +0 -244
- package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +0 -33
- package/corpus/templates/factory/server/routes/_agent-native/factory/builder-callback.post.ts +0 -116
- package/corpus/templates/factory/server/triage/ai-services-git.ts +0 -205
- package/corpus/templates/factory/server/triage/builder-executor.ts +0 -123
- package/docs/content/template-forms-building-publishing.mdx +0 -135
- package/docs/content/template-forms-responses.mdx +0 -120
- /package/corpus/templates/clips/{server/lib → shared}/upload-interruption.ts +0 -0
|
@@ -43,8 +43,8 @@ import { readAnalyticsClientPlatformHeader, readBrowserSessionIdHeader, } from "
|
|
|
43
43
|
import { getConfiguredAppBasePath, stripAppBasePath } from "./app-base-path.js";
|
|
44
44
|
import { getSession } from "./auth.js";
|
|
45
45
|
import { getBetterAuthInternalAdapter, getBetterAuthSync, } from "./better-auth-instance.js";
|
|
46
|
-
import { BUILDER_CONNECT_PARAM, BUILDER_CONNECT_MODE_PARAM, BUILDER_AGENT_NATIVE_PROVISION_MODE, BUILDER_PROVISIONING_TOKEN_PARAM, BUILDER_CONNECT_STATE_COOKIE, BUILDER_ENV_KEYS, BUILDER_OPENER_PARAM, BUILDER_RELAY_FLOW_HEADER, BUILDER_RELAY_SIGNATURE_HEADER, BUILDER_RELAY_STATE_PARAM, BUILDER_RELAY_TIMESTAMP_HEADER, appendBuilderConnectToken, appendBuilderConnectStateCookie, builderConnectTrackingProperties, createBuilderConnectState, createBuilderBrowserCallbackErrorPage, createBuilderBrowserCallbackPage, createBuilderRelayRequest, getBuilderConnectTrackingParams, getBuilderBrowserOriginForEvent, getBuilderBrowserStatusForEvent, isBuilderAccountProvisioningEnabled, isBuilderConnectCallbackUrlAllowed, isSignedBuilderConnectState, normalizeBuilderAgentContext, provisionBuilderAccount, resolveBuilderBranchProjectId, resolveBuilderConnectCallbackUrl, resolveBuilderConnectCallbackState, resolveBuilderPreviewRelayParentOrigin, removeBuilderConnectStateCookie, runBuilderAgent, verifyBuilderRelayRequest, verifyBuilderPreviewRelayStateForCallback, verifyBuilderConnectTokenAndGetOwner, signBuilderProvisioningToken, verifyBuilderProvisioningToken, } from "./builder-browser.js";
|
|
47
|
-
import { BUILDER_ASSETS_WRITE_SCOPE, BUILDER_OAUTH_SCOPE, deleteBuilderOAuthSession, exchangeBuilderOAuthAuthorization, hasBuilderOAuthSession, resolveBuilderOAuthRequestAccess, saveBuilderOAuthCredentials, startBuilderOAuthAuthorization, } from "./builder-oauth.js";
|
|
46
|
+
import { BUILDER_CONNECT_PARAM, BUILDER_CONNECT_MODE_PARAM, BUILDER_AGENT_NATIVE_PROVISION_MODE, BUILDER_PROVISIONING_TOKEN_PARAM, BUILDER_CONNECT_ATTEMPT_PARAM, BUILDER_CONNECT_STATE_COOKIE, BUILDER_ENV_KEYS, BUILDER_OPENER_PARAM, BUILDER_RELAY_FLOW_HEADER, BUILDER_RELAY_SIGNATURE_HEADER, BUILDER_RELAY_STATE_PARAM, BUILDER_RELAY_TIMESTAMP_HEADER, appendBuilderConnectToken, appendBuilderConnectStateCookie, builderConnectTrackingProperties, createBuilderConnectState, createBuilderBrowserCallbackErrorPage, createBuilderBrowserCallbackPage, createBuilderRelayRequest, getBuilderConnectTrackingParams, getBuilderBrowserOriginForEvent, getBuilderBrowserStatusForEvent, isBuilderAccountAlreadyExistsError, isBuilderAccountProvisioningEnabled, isBuilderConnectCallbackUrlAllowed, isSignedBuilderConnectState, normalizeBuilderAgentContext, provisionBuilderAccount, resolveBuilderBranchProjectId, resolveBuilderConnectCallbackUrl, resolveBuilderConnectCallbackState, resolveBuilderPreviewRelayParentOrigin, removeBuilderConnectStateCookie, runBuilderAgent, verifyBuilderRelayRequest, verifyBuilderPreviewRelayStateForCallback, verifyBuilderConnectTokenAndGetOwner, signBuilderProvisioningToken, verifyBuilderProvisioningToken, } from "./builder-browser.js";
|
|
47
|
+
import { BUILDER_ASSETS_WRITE_SCOPE, BUILDER_OAUTH_SCOPE, deleteBuilderOAuthSession, exchangeBuilderOAuthAuthorization, getBuilderOAuthStoredScope, hasBuilderOAuthSession, resolveBuilderOAuthRequestAccess, saveBuilderOAuthCredentials, startBuilderOAuthAuthorization, } from "./builder-oauth.js";
|
|
48
48
|
import { captureError, registerErrorCaptureProvider } from "./capture-error.js";
|
|
49
49
|
import { resolveCoreRoutesMcpOptions, } from "./core-routes/mcp-connect-options.js";
|
|
50
50
|
import { getAllowedCorsOrigin, readCorsAllowedOrigins, } from "./cors-origins.js";
|
|
@@ -55,7 +55,7 @@ import { createEmbedStartRouteHandler } from "./embed-route.js";
|
|
|
55
55
|
import { shouldReportError } from "./error-noise-filter.js";
|
|
56
56
|
import { FRAMEWORK_AUTH_EARLY_PATHS, getH3App, awaitBootstrap, markDefaultPluginProvided, markFrameworkRoutesReadyBeforeBootstrap, trackPluginInit, } from "./framework-request-handler.js";
|
|
57
57
|
import { createGatewayAccessCheckHandler } from "./gateway-access-check.js";
|
|
58
|
-
import { checkGoogleSignInCredential } from "./google-credential-check.js";
|
|
58
|
+
import { checkGoogleManagedCredential, checkGoogleSignInCredential, } from "./google-credential-check.js";
|
|
59
59
|
import { getAppBasePath, getOrigin } from "./google-oauth.js";
|
|
60
60
|
import { createGoogleRealtimeSessionHandler } from "./google-realtime-session.js";
|
|
61
61
|
import { readBody, DEFAULT_UPLOAD_MAX_FILE_BYTES, isAllowedUploadMimeType, } from "./h3-helpers.js";
|
|
@@ -111,16 +111,19 @@ export async function resolveAgentEngineStatus(deps) {
|
|
|
111
111
|
const configuredEngine = getAppConfig().agent.engine;
|
|
112
112
|
const envEntry = configuredEngine ? lookupEntry(configuredEngine) : undefined;
|
|
113
113
|
if (envEntry) {
|
|
114
|
-
if (
|
|
114
|
+
if (await deps.isStoredEngineUsable({ engine: envEntry.name }, envEntry)) {
|
|
115
|
+
return {
|
|
116
|
+
configured: true,
|
|
117
|
+
engine: envEntry.name,
|
|
118
|
+
model: envEntry.defaultModel ?? DEFAULT_MODEL,
|
|
119
|
+
source: "env",
|
|
120
|
+
envVar: "AGENT_ENGINE",
|
|
121
|
+
openAiBaseUrlConfigured,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
if (getRequestContext()?.isSyntheticTraffic !== true) {
|
|
115
125
|
return { configured: false, openAiBaseUrlConfigured };
|
|
116
|
-
|
|
117
|
-
configured: true,
|
|
118
|
-
engine: envEntry.name,
|
|
119
|
-
model: envEntry.defaultModel ?? DEFAULT_MODEL,
|
|
120
|
-
source: "env",
|
|
121
|
-
envVar: "AGENT_ENGINE",
|
|
122
|
-
openAiBaseUrlConfigured,
|
|
123
|
-
};
|
|
126
|
+
}
|
|
124
127
|
}
|
|
125
128
|
// Stored provider selections win over an existing Builder connection, so
|
|
126
129
|
// this is checked before the app_secrets sweep — and the sweep is skipped
|
|
@@ -164,29 +167,6 @@ export async function resolveAgentEngineStatus(deps) {
|
|
|
164
167
|
}
|
|
165
168
|
return { configured: false, openAiBaseUrlConfigured };
|
|
166
169
|
}
|
|
167
|
-
const _agentEngineStatusInFlight = new Map();
|
|
168
|
-
/**
|
|
169
|
-
* Share one in-flight status resolution between concurrent probes of the same
|
|
170
|
-
* identity. Several client surfaces probe this route on mount and the client
|
|
171
|
-
* retries after its own timeout; without this each probe re-ran the whole
|
|
172
|
-
* credential sweep. The entry is dropped as soon as the lookup settles, so a
|
|
173
|
-
* joiner never sees an answer older than one lookup — no TTL, nothing to
|
|
174
|
-
* invalidate when a provider is added or removed. The key carries the identity
|
|
175
|
-
* that decides the answer, so no tenant can read another's result.
|
|
176
|
-
*/
|
|
177
|
-
export function shareAgentEngineStatusLookup(identityKey, compute) {
|
|
178
|
-
const existing = _agentEngineStatusInFlight.get(identityKey);
|
|
179
|
-
if (existing)
|
|
180
|
-
return existing;
|
|
181
|
-
const started = compute().finally(() => {
|
|
182
|
-
_agentEngineStatusInFlight.delete(identityKey);
|
|
183
|
-
});
|
|
184
|
-
_agentEngineStatusInFlight.set(identityKey, started);
|
|
185
|
-
return started;
|
|
186
|
-
}
|
|
187
|
-
export function agentEngineStatusIdentityKey(userEmail, orgId) {
|
|
188
|
-
return `${userEmail ?? ""}\u0000${orgId ?? ""}`;
|
|
189
|
-
}
|
|
190
170
|
function requestAgentEngineStatusDeps() {
|
|
191
171
|
return {
|
|
192
172
|
readStoredEngine: async () => (await getSetting("agent-engine")),
|
|
@@ -225,14 +205,12 @@ async function resolveAgentEngineStatusIdentity(event) {
|
|
|
225
205
|
}
|
|
226
206
|
}
|
|
227
207
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
* authorized, not one re-resolved after the OAuth round trip. Fails closed: an
|
|
233
|
-
* unreadable owner/admin role is denied.
|
|
208
|
+
* Shared Builder grants stay org-scoped, but connect initiation can come from
|
|
209
|
+
* any authenticated member. Revocation still needs owner/admin authority.
|
|
210
|
+
* Capture the org id at connect start so the grant is stored under the org
|
|
211
|
+
* that was authorized, not one re-resolved after the OAuth round trip.
|
|
234
212
|
*/
|
|
235
|
-
async function resolveBuilderOrgMutation(event) {
|
|
213
|
+
export async function resolveBuilderOrgMutation(event, options = {}) {
|
|
236
214
|
let orgId = null;
|
|
237
215
|
let role = null;
|
|
238
216
|
try {
|
|
@@ -243,13 +221,23 @@ async function resolveBuilderOrgMutation(event) {
|
|
|
243
221
|
catch {
|
|
244
222
|
// coercion-ok: org is missing, it will fail closed
|
|
245
223
|
}
|
|
224
|
+
if (options.allowMemberInitiation) {
|
|
225
|
+
if (orgId)
|
|
226
|
+
return { orgId, role, deny: null };
|
|
227
|
+
return {
|
|
228
|
+
orgId,
|
|
229
|
+
role,
|
|
230
|
+
deny: "Only signed-in organization members can connect Builder.",
|
|
231
|
+
};
|
|
232
|
+
}
|
|
246
233
|
if (role !== "owner" && role !== "admin") {
|
|
247
234
|
return {
|
|
248
235
|
orgId,
|
|
236
|
+
role,
|
|
249
237
|
deny: "Only an organization owner or admin can change the shared Builder connection.",
|
|
250
238
|
};
|
|
251
239
|
}
|
|
252
|
-
return { orgId, deny: null };
|
|
240
|
+
return { orgId, role, deny: null };
|
|
253
241
|
}
|
|
254
242
|
export function getFrameworkEnvKeys() {
|
|
255
243
|
return [
|
|
@@ -857,6 +845,16 @@ function redactValues(text, values) {
|
|
|
857
845
|
}
|
|
858
846
|
return out;
|
|
859
847
|
}
|
|
848
|
+
const DEFAULT_GOOGLE_OAUTH_CALLBACK_PATH = "/_agent-native/google/callback";
|
|
849
|
+
const GOOGLE_OAUTH_CALLBACK_PATH_PATTERN = /^\/_agent-native\/[A-Za-z0-9._/-]+\/callback$/;
|
|
850
|
+
function normalizeGoogleOAuthCallbackPaths(paths) {
|
|
851
|
+
const values = [...new Set(paths ?? [DEFAULT_GOOGLE_OAUTH_CALLBACK_PATH])];
|
|
852
|
+
if (values.length === 0 ||
|
|
853
|
+
values.some((value) => !GOOGLE_OAUTH_CALLBACK_PATH_PATTERN.test(value))) {
|
|
854
|
+
throw new Error("googleOAuthCallbackPaths must contain /_agent-native/*/callback paths.");
|
|
855
|
+
}
|
|
856
|
+
return values;
|
|
857
|
+
}
|
|
860
858
|
export async function readLegacyCoreRouteInitSettings(readSetting = getSetting) {
|
|
861
859
|
const readOrNull = async (key) => {
|
|
862
860
|
try {
|
|
@@ -994,6 +992,9 @@ export async function resolveOAuthCustodyBuilderKeyStatus(dependencies = {
|
|
|
994
992
|
}
|
|
995
993
|
}
|
|
996
994
|
export function createCoreRoutesPlugin(options = {}) {
|
|
995
|
+
const googleOAuthCallbackPaths = normalizeGoogleOAuthCallbackPaths(options.googleOAuthCallbackPaths);
|
|
996
|
+
const googleOAuthCredentialMode = options.googleOAuthCredentialMode ?? "managed";
|
|
997
|
+
const googleOAuthManagedConnection = options.googleOAuthManagedConnection ?? "unknown";
|
|
997
998
|
return async (nitroApp) => {
|
|
998
999
|
markDefaultPluginProvided(nitroApp, "core-routes");
|
|
999
1000
|
// No-op when called from inside the bootstrap (auto-mount path).
|
|
@@ -1073,12 +1074,37 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1073
1074
|
// health handler would otherwise swallow this path.
|
|
1074
1075
|
getH3App(nitroApp).use(`${P}/health/google`, defineEventHandler(async (event) => {
|
|
1075
1076
|
setResponseHeader(event, "cache-control", "no-store");
|
|
1076
|
-
const result =
|
|
1077
|
+
const result = event.url?.searchParams.get("client") === "managed"
|
|
1078
|
+
? googleOAuthManagedConnection === "not_applicable"
|
|
1079
|
+
? {
|
|
1080
|
+
status: "unconfigured",
|
|
1081
|
+
clientId: null,
|
|
1082
|
+
mismatchedPairs: false,
|
|
1083
|
+
credentialSource: "none",
|
|
1084
|
+
reason: "this app does not expose deployment-level Google OAuth",
|
|
1085
|
+
checkedAt: Date.now(),
|
|
1086
|
+
}
|
|
1087
|
+
: googleOAuthCredentialMode === "user"
|
|
1088
|
+
? {
|
|
1089
|
+
status: "unconfigured",
|
|
1090
|
+
clientId: null,
|
|
1091
|
+
mismatchedPairs: false,
|
|
1092
|
+
credentialSource: "user",
|
|
1093
|
+
reason: "user-scoped OAuth credentials are checked after authentication",
|
|
1094
|
+
checkedAt: Date.now(),
|
|
1095
|
+
}
|
|
1096
|
+
: await checkGoogleManagedCredential()
|
|
1097
|
+
: await checkGoogleSignInCredential();
|
|
1077
1098
|
// `invalid` is the fleet-wide outage shape: the deploy is up and
|
|
1078
1099
|
// healthy while nobody can sign in. Page on it.
|
|
1079
1100
|
if (result.status === "invalid")
|
|
1080
1101
|
setResponseStatus(event, 503);
|
|
1081
|
-
return
|
|
1102
|
+
return {
|
|
1103
|
+
...result,
|
|
1104
|
+
callbackPaths: googleOAuthCallbackPaths,
|
|
1105
|
+
credentialMode: googleOAuthCredentialMode,
|
|
1106
|
+
managedConnection: googleOAuthManagedConnection,
|
|
1107
|
+
};
|
|
1082
1108
|
}));
|
|
1083
1109
|
getH3App(nitroApp).use(`${P}/health`, defineEventHandler(async (event) => {
|
|
1084
1110
|
setResponseHeader(event, "cache-control", "no-store");
|
|
@@ -1567,6 +1593,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1567
1593
|
}
|
|
1568
1594
|
}
|
|
1569
1595
|
return runWithRequestContext({ userEmail, orgId: orgId ?? undefined }, async () => {
|
|
1596
|
+
const requestUrl = getFrameworkRouteRequestUrl(event);
|
|
1597
|
+
const connectAttemptId = requestUrl.searchParams.get(BUILDER_CONNECT_ATTEMPT_PARAM);
|
|
1570
1598
|
const projectId = await resolveBuilderBranchProjectId();
|
|
1571
1599
|
const requestStatus = {
|
|
1572
1600
|
...envStatus,
|
|
@@ -1582,8 +1610,16 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1582
1610
|
if (userEmail) {
|
|
1583
1611
|
const errKey = `builder-connect-error:${userEmail}`;
|
|
1584
1612
|
const errRow = await getSetting(errKey);
|
|
1585
|
-
|
|
1586
|
-
|
|
1613
|
+
const isCorrelatedProvisioningError = errRow?.code === "account_exists" &&
|
|
1614
|
+
typeof connectAttemptId === "string" &&
|
|
1615
|
+
errRow.attemptId === connectAttemptId;
|
|
1616
|
+
const isLegacyConnectError = errRow?.code !== "account_exists";
|
|
1617
|
+
if (errRow &&
|
|
1618
|
+
typeof errRow.message === "string" &&
|
|
1619
|
+
(isCorrelatedProvisioningError || isLegacyConnectError)) {
|
|
1620
|
+
if (isLegacyConnectError) {
|
|
1621
|
+
await deleteSetting(errKey).catch(() => { });
|
|
1622
|
+
}
|
|
1587
1623
|
return withConnectToken({
|
|
1588
1624
|
...requestStatus,
|
|
1589
1625
|
configured: false,
|
|
@@ -1602,6 +1638,9 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1602
1638
|
at: typeof errRow.at === "number"
|
|
1603
1639
|
? errRow.at
|
|
1604
1640
|
: Date.now(),
|
|
1641
|
+
...(typeof errRow.code === "string"
|
|
1642
|
+
? { code: errRow.code }
|
|
1643
|
+
: {}),
|
|
1605
1644
|
},
|
|
1606
1645
|
});
|
|
1607
1646
|
}
|
|
@@ -1614,7 +1653,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1614
1653
|
let oauthAccess = null;
|
|
1615
1654
|
let hasOAuthCustody = false;
|
|
1616
1655
|
try {
|
|
1617
|
-
hasOAuthCustody = await hasBuilderOAuthSession(userEmail);
|
|
1656
|
+
hasOAuthCustody = await hasBuilderOAuthSession(userEmail, orgId);
|
|
1618
1657
|
}
|
|
1619
1658
|
catch {
|
|
1620
1659
|
return withConnectToken({
|
|
@@ -1634,6 +1673,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1634
1673
|
oauthAccess = await resolveBuilderOAuthRequestAccess({
|
|
1635
1674
|
ownerEmail: userEmail,
|
|
1636
1675
|
requiredScope: BUILDER_OAUTH_SCOPE,
|
|
1676
|
+
orgId,
|
|
1637
1677
|
});
|
|
1638
1678
|
}
|
|
1639
1679
|
catch {
|
|
@@ -1852,6 +1892,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1852
1892
|
// the cookie. The callback still requires the matching session,
|
|
1853
1893
|
// pending row, and a successful PKCE exchange before persistence.
|
|
1854
1894
|
getH3App(nitroApp).use(`${P}/builder/connect`, defineEventHandler(async (event) => {
|
|
1895
|
+
const requestUrl = getFrameworkRouteRequestUrl(event);
|
|
1896
|
+
const connectAttemptId = requestUrl.searchParams.get(BUILDER_CONNECT_ATTEMPT_PARAM);
|
|
1855
1897
|
const ownerContext = await resolveBuilderOwnerContext(event, "connect");
|
|
1856
1898
|
const ownerEmail = ownerContext.email;
|
|
1857
1899
|
if (!ownerEmail) {
|
|
@@ -1866,9 +1908,9 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1866
1908
|
title: "Sign in required",
|
|
1867
1909
|
body: "Builder OAuth is tied to a signed-in account. Sign in, then try Connect Builder again.",
|
|
1868
1910
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
1911
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1869
1912
|
});
|
|
1870
1913
|
}
|
|
1871
|
-
const requestUrl = getFrameworkRouteRequestUrl(event);
|
|
1872
1914
|
const connectToken = requestUrl.searchParams.get(BUILDER_CONNECT_PARAM);
|
|
1873
1915
|
const connectTokenOwner = verifyBuilderConnectTokenAndGetOwner(connectToken);
|
|
1874
1916
|
const connectTracking = getBuilderConnectTrackingParams(requestUrl.searchParams);
|
|
@@ -1896,6 +1938,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1896
1938
|
await putSetting(`builder-connect-error:${ownerEmail}`, {
|
|
1897
1939
|
message: crossOriginMessage,
|
|
1898
1940
|
at: Date.now(),
|
|
1941
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1899
1942
|
}).catch(() => { });
|
|
1900
1943
|
console.warn("[builder-connect] rejected cross-origin connect", {
|
|
1901
1944
|
hasConnectToken: Boolean(connectToken),
|
|
@@ -1910,15 +1953,18 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1910
1953
|
body: "The connect popup did not include a valid signed link for this app.",
|
|
1911
1954
|
closeHint: "Close this popup, refresh the app, and try Connect account again.",
|
|
1912
1955
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
1956
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1913
1957
|
});
|
|
1914
1958
|
}
|
|
1915
1959
|
const shouldProvisionAgentNativeAccount = requestUrl.searchParams.get(BUILDER_CONNECT_MODE_PARAM) ===
|
|
1916
1960
|
BUILDER_AGENT_NATIVE_PROVISION_MODE;
|
|
1917
1961
|
if (shouldProvisionAgentNativeAccount) {
|
|
1918
|
-
const failProvisioning = async (status, message, reason) => {
|
|
1962
|
+
const failProvisioning = async (status, message, reason, code) => {
|
|
1919
1963
|
await putSetting(`builder-connect-error:${ownerEmail}`, {
|
|
1920
1964
|
message,
|
|
1921
1965
|
at: Date.now(),
|
|
1966
|
+
...(code ? { code } : {}),
|
|
1967
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1922
1968
|
}).catch(() => { });
|
|
1923
1969
|
await trackBuilderLifecycle(event, "builder connect failed", ownerEmail, {
|
|
1924
1970
|
...builderConnectTrackingProperties(connectTracking),
|
|
@@ -1929,6 +1975,8 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1929
1975
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
1930
1976
|
return createBuilderBrowserCallbackErrorPage(message, {
|
|
1931
1977
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
1978
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1979
|
+
...(code ? { code } : {}),
|
|
1932
1980
|
});
|
|
1933
1981
|
};
|
|
1934
1982
|
if (!isBuilderAccountProvisioningEnabled()) {
|
|
@@ -1961,10 +2009,16 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1961
2009
|
const parentOrigin = getBuilderBrowserOriginForEvent(event);
|
|
1962
2010
|
setResponseHeader(event, "Cache-Control", "no-store");
|
|
1963
2011
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
1964
|
-
return createBuilderBrowserCallbackPage(`${parentOrigin}${getAppBasePath() || "/"}`, {
|
|
2012
|
+
return createBuilderBrowserCallbackPage(`${parentOrigin}${getAppBasePath() || "/"}`, {
|
|
2013
|
+
parentOrigin,
|
|
2014
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
2015
|
+
});
|
|
1965
2016
|
}
|
|
1966
2017
|
catch (error) {
|
|
1967
2018
|
console.error("[builder] Agent-Native account provisioning failed:", error instanceof Error ? error.message : error);
|
|
2019
|
+
if (isBuilderAccountAlreadyExistsError(error)) {
|
|
2020
|
+
return failProvisioning(409, "A Builder account already exists for this email. Log in to connect it.", "account_exists", "account_exists");
|
|
2021
|
+
}
|
|
1968
2022
|
return failProvisioning(502, "Couldn't create your Builder account. Try again or connect an existing account.", "provision_failed");
|
|
1969
2023
|
}
|
|
1970
2024
|
}
|
|
@@ -1988,9 +2042,12 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
1988
2042
|
title: "Builder connection is unavailable here",
|
|
1989
2043
|
body: "Open this app on its public HTTPS URL, then try again.",
|
|
1990
2044
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
2045
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
1991
2046
|
});
|
|
1992
2047
|
}
|
|
1993
|
-
const { orgId: connectOrgId, deny: orgConnectDenied } = await resolveBuilderOrgMutation(event
|
|
2048
|
+
const { orgId: connectOrgId, role: connectRole, deny: orgConnectDenied, } = await resolveBuilderOrgMutation(event, {
|
|
2049
|
+
allowMemberInitiation: true,
|
|
2050
|
+
});
|
|
1994
2051
|
if (orgConnectDenied) {
|
|
1995
2052
|
await trackBuilderLifecycle(event, "builder connect failed", ownerEmail, {
|
|
1996
2053
|
...builderConnectTrackingProperties(connectTracking),
|
|
@@ -2001,8 +2058,9 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2001
2058
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2002
2059
|
return createBuilderBrowserCallbackErrorPage(orgConnectDenied, {
|
|
2003
2060
|
title: "Not allowed to connect Builder for this organization",
|
|
2004
|
-
body:
|
|
2061
|
+
body: orgConnectDenied,
|
|
2005
2062
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
2063
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
2006
2064
|
});
|
|
2007
2065
|
}
|
|
2008
2066
|
// The standard OAuth client discovers Builder's protected-resource
|
|
@@ -2021,11 +2079,12 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2021
2079
|
await putSetting(`builder-connect-pending:${state}`, {
|
|
2022
2080
|
ownerEmail,
|
|
2023
2081
|
orgId: connectOrgId,
|
|
2024
|
-
role:
|
|
2082
|
+
role: connectRole,
|
|
2025
2083
|
encryptedOAuthFlow: encryptSecretValue(JSON.stringify(oauthFlow)),
|
|
2026
2084
|
redirectUri: callbackUrl,
|
|
2027
2085
|
expiresAt: Date.now() + BUILDER_CONNECT_PENDING_TTL_MS,
|
|
2028
2086
|
tracking: connectTracking,
|
|
2087
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
2029
2088
|
});
|
|
2030
2089
|
await purgeExpiredBuilderConnectPendingStates().catch(() => 0); // coercion-ok: connect already persisted the new pending row; purge of abandoned rows must not fail OAuth start
|
|
2031
2090
|
setCookie(event, BUILDER_CONNECT_STATE_COOKIE, appendBuilderConnectStateCookie(getCookie(event, BUILDER_CONNECT_STATE_COOKIE), state), {
|
|
@@ -2049,11 +2108,13 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2049
2108
|
await putSetting(`builder-connect-error:${ownerEmail}`, {
|
|
2050
2109
|
message: msg,
|
|
2051
2110
|
at: Date.now(),
|
|
2111
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
2052
2112
|
}).catch(() => { });
|
|
2053
2113
|
setResponseStatus(event, 503);
|
|
2054
2114
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2055
2115
|
return createBuilderBrowserCallbackErrorPage(msg, {
|
|
2056
2116
|
parentOrigin: getBuilderBrowserOriginForEvent(event),
|
|
2117
|
+
...(connectAttemptId ? { attemptId: connectAttemptId } : {}),
|
|
2057
2118
|
});
|
|
2058
2119
|
}
|
|
2059
2120
|
await trackBuilderLifecycle(event, "builder connect started", ownerEmail, {
|
|
@@ -2248,6 +2309,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2248
2309
|
setResponseHeader(event, "Pragma", "no-cache");
|
|
2249
2310
|
setResponseHeader(event, "Referrer-Policy", "no-referrer");
|
|
2250
2311
|
const requestUrl = getFrameworkRouteRequestUrl(event);
|
|
2312
|
+
const requestConnectAttemptId = requestUrl.searchParams.get(BUILDER_CONNECT_ATTEMPT_PARAM);
|
|
2251
2313
|
const relayStateRaw = requestUrl.searchParams.get(BUILDER_RELAY_STATE_PARAM);
|
|
2252
2314
|
if (relayStateRaw) {
|
|
2253
2315
|
let relayPayload = null;
|
|
@@ -2262,7 +2324,9 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2262
2324
|
if (!relayPayload) {
|
|
2263
2325
|
setResponseStatus(event, 403);
|
|
2264
2326
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2265
|
-
return createBuilderBrowserCallbackErrorPage("Builder preview relay state is invalid or expired."
|
|
2327
|
+
return createBuilderBrowserCallbackErrorPage("Builder preview relay state is invalid or expired.", requestConnectAttemptId
|
|
2328
|
+
? { attemptId: requestConnectAttemptId }
|
|
2329
|
+
: undefined);
|
|
2266
2330
|
}
|
|
2267
2331
|
const relayOpenerOrigin = requestUrl.searchParams.get(BUILDER_OPENER_PARAM);
|
|
2268
2332
|
const relayParentOrigin = resolveBuilderPreviewRelayParentOrigin({
|
|
@@ -2274,7 +2338,12 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2274
2338
|
if (!privateKey || !publicKey) {
|
|
2275
2339
|
setResponseStatus(event, 400);
|
|
2276
2340
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2277
|
-
return createBuilderBrowserCallbackErrorPage("Builder didn't return credentials. Restart the connect flow from settings.", {
|
|
2341
|
+
return createBuilderBrowserCallbackErrorPage("Builder didn't return credentials. Restart the connect flow from settings.", {
|
|
2342
|
+
parentOrigin: relayParentOrigin,
|
|
2343
|
+
...(requestConnectAttemptId
|
|
2344
|
+
? { attemptId: requestConnectAttemptId }
|
|
2345
|
+
: {}),
|
|
2346
|
+
});
|
|
2278
2347
|
}
|
|
2279
2348
|
const credentials = {
|
|
2280
2349
|
privateKey,
|
|
@@ -2309,10 +2378,18 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2309
2378
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2310
2379
|
return createBuilderBrowserCallbackErrorPage(message, {
|
|
2311
2380
|
parentOrigin: relayParentOrigin,
|
|
2381
|
+
...(requestConnectAttemptId
|
|
2382
|
+
? { attemptId: requestConnectAttemptId }
|
|
2383
|
+
: {}),
|
|
2312
2384
|
});
|
|
2313
2385
|
}
|
|
2314
2386
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2315
|
-
return createBuilderBrowserCallbackPage(`${relayParentOrigin}${relayPayload.basePath || "/"}`, {
|
|
2387
|
+
return createBuilderBrowserCallbackPage(`${relayParentOrigin}${relayPayload.basePath || "/"}`, {
|
|
2388
|
+
parentOrigin: relayParentOrigin,
|
|
2389
|
+
...(requestConnectAttemptId
|
|
2390
|
+
? { attemptId: requestConnectAttemptId }
|
|
2391
|
+
: {}),
|
|
2392
|
+
});
|
|
2316
2393
|
}
|
|
2317
2394
|
// Builder sometimes drops the top-level OAuth state. Recover it
|
|
2318
2395
|
// from the host-only cookie set by /builder/connect; the pending row
|
|
@@ -2320,11 +2397,13 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2320
2397
|
const queryState = requestUrl.searchParams.get("state");
|
|
2321
2398
|
const state = resolveBuilderConnectCallbackState(queryState, getCookie(event, BUILDER_CONNECT_STATE_COOKIE));
|
|
2322
2399
|
const parentOrigin = getBuilderBrowserOriginForEvent(event);
|
|
2400
|
+
let callbackAttemptId = requestConnectAttemptId;
|
|
2323
2401
|
const fail = async (status, message, ownerEmail, reason, tracking = {}) => {
|
|
2324
2402
|
if (ownerEmail) {
|
|
2325
2403
|
await putSetting(`builder-connect-error:${ownerEmail}`, {
|
|
2326
2404
|
message,
|
|
2327
2405
|
at: Date.now(),
|
|
2406
|
+
...(callbackAttemptId ? { attemptId: callbackAttemptId } : {}),
|
|
2328
2407
|
}).catch(() => { });
|
|
2329
2408
|
await trackBuilderLifecycle(event, "builder connect failed", ownerEmail, {
|
|
2330
2409
|
...builderConnectTrackingProperties(tracking),
|
|
@@ -2336,6 +2415,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2336
2415
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2337
2416
|
return createBuilderBrowserCallbackErrorPage(message, {
|
|
2338
2417
|
parentOrigin,
|
|
2418
|
+
...(callbackAttemptId ? { attemptId: callbackAttemptId } : {}),
|
|
2339
2419
|
});
|
|
2340
2420
|
};
|
|
2341
2421
|
if (!state || !isSignedBuilderConnectState(state)) {
|
|
@@ -2345,6 +2425,10 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2345
2425
|
if (!pending) {
|
|
2346
2426
|
return fail(403, "No active Builder connect flow found. Restart the connection from Settings.");
|
|
2347
2427
|
}
|
|
2428
|
+
callbackAttemptId =
|
|
2429
|
+
typeof pending.attemptId === "string"
|
|
2430
|
+
? pending.attemptId
|
|
2431
|
+
: callbackAttemptId;
|
|
2348
2432
|
const ownerEmail = typeof pending.ownerEmail === "string" ? pending.ownerEmail : null;
|
|
2349
2433
|
const tracking = pending.tracking && typeof pending.tracking === "object"
|
|
2350
2434
|
? pending.tracking
|
|
@@ -2395,10 +2479,24 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2395
2479
|
// PKCE proves the callback belongs to this flow before its pending
|
|
2396
2480
|
// row is consumed. Persist first so a transient credential-store
|
|
2397
2481
|
// failure does not strand an otherwise valid pending flow.
|
|
2482
|
+
let callbackRole = null;
|
|
2483
|
+
if (pending.role === "owner" || pending.role === "admin") {
|
|
2484
|
+
// Re-check authority after the external OAuth round trip. A role
|
|
2485
|
+
// captured at connect start must not authorize a later org write.
|
|
2486
|
+
const currentOrg = await resolveBuilderOrgMutation(event, {
|
|
2487
|
+
allowMemberInitiation: true,
|
|
2488
|
+
});
|
|
2489
|
+
if (currentOrg.orgId === pending.orgId &&
|
|
2490
|
+
(currentOrg.role === "owner" || currentOrg.role === "admin")) {
|
|
2491
|
+
callbackRole = currentOrg.role;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
let credentialScope = "user";
|
|
2398
2495
|
try {
|
|
2399
|
-
await saveBuilderOAuthCredentials({
|
|
2496
|
+
credentialScope = await saveBuilderOAuthCredentials({
|
|
2400
2497
|
ownerEmail,
|
|
2401
2498
|
orgId: typeof pending.orgId === "string" ? pending.orgId : undefined,
|
|
2499
|
+
role: callbackRole,
|
|
2402
2500
|
credentials,
|
|
2403
2501
|
});
|
|
2404
2502
|
}
|
|
@@ -2434,10 +2532,13 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2434
2532
|
await trackBuilderLifecycle(event, "builder connect succeeded", ownerEmail, {
|
|
2435
2533
|
...builderConnectTrackingProperties(tracking),
|
|
2436
2534
|
stage: "callback",
|
|
2437
|
-
credential_scope:
|
|
2535
|
+
credential_scope: credentialScope,
|
|
2438
2536
|
});
|
|
2439
2537
|
setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
|
|
2440
|
-
return createBuilderBrowserCallbackPage(`${parentOrigin}${getAppBasePath() || "/"}`, {
|
|
2538
|
+
return createBuilderBrowserCallbackPage(`${parentOrigin}${getAppBasePath() || "/"}`, {
|
|
2539
|
+
parentOrigin,
|
|
2540
|
+
...(callbackAttemptId ? { attemptId: callbackAttemptId } : {}),
|
|
2541
|
+
});
|
|
2441
2542
|
}));
|
|
2442
2543
|
// POST /_agent-native/builder/disconnect — remove this user's OAuth
|
|
2443
2544
|
// custody. Legacy BUILDER_* secrets are cleared at user scope when OAuth
|
|
@@ -2454,19 +2555,6 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2454
2555
|
return { error: "unauthorized" };
|
|
2455
2556
|
}
|
|
2456
2557
|
try {
|
|
2457
|
-
const hadOAuth = await hasBuilderOAuthSession(session.email);
|
|
2458
|
-
// Revoking an org-scoped grant takes the connection offline for
|
|
2459
|
-
// every member, so require org owner/admin before doing so.
|
|
2460
|
-
if (hadOAuth) {
|
|
2461
|
-
const { deny } = await resolveBuilderOrgMutation(event);
|
|
2462
|
-
if (deny) {
|
|
2463
|
-
setResponseStatus(event, 403);
|
|
2464
|
-
return { error: deny };
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
const oauthResult = hadOAuth
|
|
2468
|
-
? await deleteBuilderOAuthSession(session.email)
|
|
2469
|
-
: { localDeleted: false, remoteRevoked: false };
|
|
2470
2558
|
const { deleteBuilderCredentials } = await import("./credential-provider.js");
|
|
2471
2559
|
let orgId = null;
|
|
2472
2560
|
let role = null;
|
|
@@ -2479,7 +2567,21 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2479
2567
|
catch {
|
|
2480
2568
|
// coercion-ok: org module is optional; disconnect still clears user-scoped custody.
|
|
2481
2569
|
}
|
|
2482
|
-
await
|
|
2570
|
+
const oauthScope = await getBuilderOAuthStoredScope(session.email, orgId);
|
|
2571
|
+
const hadOAuth = oauthScope !== null;
|
|
2572
|
+
// Revoking an org-scoped grant takes the connection offline for
|
|
2573
|
+
// every member, so require org owner/admin before doing so.
|
|
2574
|
+
if (oauthScope === "org") {
|
|
2575
|
+
const { deny } = await resolveBuilderOrgMutation(event);
|
|
2576
|
+
if (deny) {
|
|
2577
|
+
setResponseStatus(event, 403);
|
|
2578
|
+
return { error: deny };
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
const oauthResult = oauthScope
|
|
2582
|
+
? await deleteBuilderOAuthSession(session.email, oauthScope, orgId)
|
|
2583
|
+
: { localDeleted: false, remoteRevoked: false };
|
|
2584
|
+
await deleteBuilderCredentials(session.email, oauthScope ? undefined : { orgId, role });
|
|
2483
2585
|
await trackBuilderLifecycle(event, "builder disconnect succeeded", session.email, {
|
|
2484
2586
|
oauth_present: hadOAuth,
|
|
2485
2587
|
remote_revoked: hadOAuth
|
|
@@ -2636,7 +2738,7 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
2636
2738
|
getH3App(nitroApp).use(`${P}/agent-engine/status`, defineEventHandler(async (event) => {
|
|
2637
2739
|
try {
|
|
2638
2740
|
const { userEmail, orgId } = await resolveAgentEngineStatusIdentity(event);
|
|
2639
|
-
return await
|
|
2741
|
+
return await runWithRequestContext({ userEmail, orgId }, () => resolveAgentEngineStatus(requestAgentEngineStatusDeps()));
|
|
2640
2742
|
}
|
|
2641
2743
|
catch (err) {
|
|
2642
2744
|
// NOT `{ configured: false }`. A 200 saying "not configured" is an
|
|
@@ -3376,4 +3478,6 @@ export function createCoreRoutesPlugin(options = {}) {
|
|
|
3376
3478
|
* export { defaultCoreRoutesPlugin as default } from "@agent-native/core/server";
|
|
3377
3479
|
* ```
|
|
3378
3480
|
*/
|
|
3379
|
-
export const defaultCoreRoutesPlugin = createCoreRoutesPlugin(
|
|
3481
|
+
export const defaultCoreRoutesPlugin = createCoreRoutesPlugin({
|
|
3482
|
+
googleOAuthManagedConnection: "not_applicable",
|
|
3483
|
+
});
|
|
@@ -23,7 +23,7 @@ import { getAppConfig } from "../app-config/index.js";
|
|
|
23
23
|
import { getDbExec, isLocalDatabase, isTransientDatabaseError, } from "../db/client.js";
|
|
24
24
|
import { getOrgSetting } from "../settings/org-settings.js";
|
|
25
25
|
import { isTruthyRuntimeValue } from "../shared/runtime-config.js";
|
|
26
|
-
import { getRequestUserEmail, getRequestOrgId } from "./request-context.js";
|
|
26
|
+
import { getRequestContext, getRequestUserEmail, getRequestOrgId, } from "./request-context.js";
|
|
27
27
|
const DISPATCH_VAULT_ACCESS_SETTINGS_KEY = "dispatch-vault-access-settings";
|
|
28
28
|
/**
|
|
29
29
|
* The designated vault fallback is an all-apps compatibility path. Manual
|
|
@@ -179,6 +179,11 @@ export function isDeployCredentialFallbackAllowed() {
|
|
|
179
179
|
return isLocalDatabase();
|
|
180
180
|
}
|
|
181
181
|
export function canUseDeployCredentialFallbackForRequest(key) {
|
|
182
|
+
// Synthetic checks must never fall through to a deploy-wide provider key.
|
|
183
|
+
// If the dedicated test credential is rejected, using the site's shared key
|
|
184
|
+
// would make a green retry both misleading and billable to real traffic.
|
|
185
|
+
if (getRequestContext()?.isSyntheticTraffic === true)
|
|
186
|
+
return false;
|
|
182
187
|
const email = getRequestUserEmail();
|
|
183
188
|
if (!email)
|
|
184
189
|
return true;
|
|
@@ -1245,17 +1250,17 @@ export async function prefetchSecrets(keys) {
|
|
|
1245
1250
|
if (!email || keys.length === 0)
|
|
1246
1251
|
return;
|
|
1247
1252
|
const { readAppSecrets } = await import("../secrets/storage.js");
|
|
1248
|
-
const
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
{ scope: "workspace", scopeId: `solo:${email}` }
|
|
1258
|
-
|
|
1253
|
+
const syntheticTraffic = getRequestContext()?.isSyntheticTraffic === true;
|
|
1254
|
+
const orgId = syntheticTraffic
|
|
1255
|
+
? undefined
|
|
1256
|
+
: getRequestOrgId() || (await resolveOrgIdForRequestEmail(email)).orgId;
|
|
1257
|
+
const scopes = [{ scope: "user", scopeId: email }];
|
|
1258
|
+
if (orgId && !syntheticTraffic) {
|
|
1259
|
+
scopes.push({ scope: "org", scopeId: orgId }, { scope: "workspace", scopeId: orgId });
|
|
1260
|
+
}
|
|
1261
|
+
if (!syntheticTraffic) {
|
|
1262
|
+
scopes.push({ scope: "workspace", scopeId: `solo:${email}` });
|
|
1263
|
+
}
|
|
1259
1264
|
await Promise.all(scopes.map((s) => readAppSecrets({ keys, ...s }).catch(() => undefined)));
|
|
1260
1265
|
}
|
|
1261
1266
|
/**
|
|
@@ -1411,6 +1416,7 @@ export async function resolveSecretPair(keys, options) {
|
|
|
1411
1416
|
export async function resolveSecretDetailed(key) {
|
|
1412
1417
|
const traceLookup = shouldTraceCredentialResolve();
|
|
1413
1418
|
const email = getRequestUserEmail();
|
|
1419
|
+
const syntheticTraffic = getRequestContext()?.isSyntheticTraffic === true;
|
|
1414
1420
|
let lookupFailed = false;
|
|
1415
1421
|
let cause;
|
|
1416
1422
|
if (email) {
|
|
@@ -1428,6 +1434,10 @@ export async function resolveSecretDetailed(key) {
|
|
|
1428
1434
|
}
|
|
1429
1435
|
return { value: userSecret.value, lookupFailed: false };
|
|
1430
1436
|
}
|
|
1437
|
+
// The beta suite writes one user-scoped credential and must never turn a
|
|
1438
|
+
// rejected or missing test key into a charge against a shared scope.
|
|
1439
|
+
if (syntheticTraffic)
|
|
1440
|
+
return NOT_FOUND;
|
|
1431
1441
|
// Mirrors resolveScopedBuilderCredential: a transient org_members read
|
|
1432
1442
|
// failure makes getOrgContext report no org, which would otherwise hide
|
|
1433
1443
|
// an org-scoped vault row behind an intermittent "not configured" error.
|
package/dist/server/email.d.ts
CHANGED
|
@@ -32,6 +32,10 @@ export interface SendEmailArgs {
|
|
|
32
32
|
subject: string;
|
|
33
33
|
html: string;
|
|
34
34
|
text?: string;
|
|
35
|
+
/** Keep security-sensitive links out of provider click-tracking redirects. */
|
|
36
|
+
disableClickTracking?: boolean;
|
|
37
|
+
/** Use deployment credentials for process-owned sends, not request-scoped overrides. */
|
|
38
|
+
useDeploymentCredentials?: boolean;
|
|
35
39
|
from?: string;
|
|
36
40
|
/**
|
|
37
41
|
* Display-name-only override. Keeps the configured (domain-verified) sending
|