@agent-native/core 0.169.1 → 0.171.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +4 -1
- package/bin/agent-native.js +23 -5
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/routes/$.tsx +10 -0
- package/corpus/templates/analytics/app/routes.ts +3 -1
- package/corpus/templates/analytics/changelog/2026-08-22-fixed-the-agent-native-templates-first-party-dashboard-panel.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-org-admin-panels-no-longer-report-a-database-error-as-a-per.md +9 -0
- package/corpus/templates/analytics/changelog/2026-08-22-slack-requests-report-invalid-inputs.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-22-unknown-analytics-links-now-return-a-real-not-found-status.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +2 -1
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +2 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +29 -7
- package/corpus/templates/analytics/server/handlers/slack.ts +59 -5
- package/corpus/templates/analytics/server/lib/db-admin-connections.ts +11 -6
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +132 -2
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/vitest.config.ts +6 -1
- package/corpus/templates/assets/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/assets/app/routes/library.tsx +5 -3
- package/corpus/templates/assets/app/routes.ts +3 -1
- package/corpus/templates/assets/changelog/2026-08-22-library-page-loads-again-instead-of-crashing-on-open.md +6 -0
- package/corpus/templates/assets/vitest.config.ts +6 -1
- package/corpus/templates/brain/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/brain/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/brain/app/routes/sources.tsx +8 -3
- package/corpus/templates/brain/changelog/2026-08-22-tuning-or-adding-a-source-no-longer-leaves-the-sources-page.md +6 -0
- package/corpus/templates/brain/vitest.config.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/calendar/actions/list-booking-links.ts +83 -4
- package/corpus/templates/calendar/actions/update-booking-link.ts +4 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +11 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +1 -1
- package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +103 -44
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +28 -24
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +9 -2
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +47 -58
- package/corpus/templates/calendar/app/hooks/use-booking-links.ts +5 -1
- package/corpus/templates/calendar/app/lib/event-layout.ts +52 -26
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +126 -98
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +1 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +88 -81
- package/corpus/templates/calendar/app/routes.ts +3 -1
- package/corpus/templates/calendar/changelog/2026-08-22-booking-link-visibility-respects-shared-access.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-clicking-an-out-of-office-event-s-marker-no-longer-creates-a.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-event-detail-views-now-show-your-calendar-timezone.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-google-calendar-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-overlapping-events-now-show-each-others-boundaries.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-22-public-booking-pages-now-offer-time-slots-from-the-host-s-we.md +6 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +5 -7
- package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -2
- package/corpus/templates/calendar/server/lib/google-calendar.ts +139 -14
- package/corpus/templates/calendar/server/onboarding.ts +85 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/calendar/shared/api.ts +9 -1
- package/corpus/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/chat/app/routes.ts +3 -1
- package/corpus/templates/chat/vitest.config.ts +8 -0
- package/corpus/templates/clips/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/clips/actions/get-meeting.ts +9 -4
- package/corpus/templates/clips/actions/list-recordings.ts +16 -3
- package/corpus/templates/clips/actions/search-meetings.ts +1 -0
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/meetings/meeting-history-row.tsx +32 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +29 -1
- package/corpus/templates/clips/app/i18n/en-US.ts +5 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +33 -4
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +1 -0
- package/corpus/templates/clips/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +17 -7
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +17 -7
- package/corpus/templates/clips/changelog/2026-08-21-camera-bubble-black-circle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-screen-recordings-respect-the-microphone-toggle.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-22-the-recordings-library-no-longer-fails-right-after-server-start.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-23-the-agent-can-see-your-library-right-after-server-start.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +1 -2
- package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +39 -7
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +21 -25
- package/corpus/templates/clips/desktop/src/app.tsx +53 -24
- package/corpus/templates/clips/desktop/src/lib/bubble-playback.ts +68 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +3 -0
- package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +72 -14
- package/corpus/templates/clips/desktop/src/lib/updater.ts +8 -3
- package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +162 -20
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +43 -6
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +150 -13
- package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +12 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +28 -3
- package/corpus/templates/clips/server/lib/emails.ts +17 -33
- package/corpus/templates/content/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +140 -15
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +12 -14
- package/corpus/templates/content/app/components/ui/pointer-lock.ts +1 -0
- package/corpus/templates/content/app/hooks/use-content-database.ts +18 -2
- package/corpus/templates/content/app/hooks/use-local-storage.ts +38 -22
- package/corpus/templates/content/app/i18n-data.ts +25 -0
- package/corpus/templates/content/app/routes.ts +3 -1
- package/corpus/templates/content/changelog/2026-08-22-code-blocks-inserted-from-the-slash-menu-no-longer-get-stuck.md +6 -0
- package/corpus/templates/content/changelog/2026-08-22-the-sidebar-page-tree-no-longer-flashes-empty-after-creating-a-page.md +6 -0
- package/corpus/templates/content/docs/solutions/2026-08-21-content-mermaid-rendering-shape.md +233 -0
- package/corpus/templates/content/server/plugins/agent-chat.ts +9 -2
- package/corpus/templates/content/vitest.config.ts +7 -1
- package/corpus/templates/crm/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +1383 -88
- package/corpus/templates/design/actions/generate-design.ts +98 -47
- package/corpus/templates/design/actions/get-design-system.ts +6 -1
- package/corpus/templates/design/actions/refresh-design-system-with-builder.ts +146 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +70 -26
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2057 -141
- package/corpus/templates/design/app/components/design/editor/DesignBottomToolbar.tsx +6 -2
- package/corpus/templates/design/app/components/design/editor/DesignWorkspaceRail.tsx +4 -4
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +10 -1
- package/corpus/templates/design/app/components/design/multi-screen/alt-hover-measurement.ts +19 -2
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +9 -2
- package/corpus/templates/design/app/components/layout/Header.tsx +15 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +7 -2
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +11 -4
- package/corpus/templates/design/app/i18n-data.ts +1 -0
- package/corpus/templates/design/app/i18n-keyboard-shortcuts.ts +12 -0
- package/corpus/templates/design/app/lib/design-system-data.ts +68 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +77 -35
- package/corpus/templates/design/app/pages/DesignSystems.tsx +136 -42
- package/corpus/templates/design/app/pages/Index.tsx +2 -0
- package/corpus/templates/design/app/pages/Templates.tsx +0 -10
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +10 -0
- package/corpus/templates/design/app/pages/design-editor/collab-sync.ts +50 -0
- package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +10 -8
- package/corpus/templates/design/app/pages/design-editor/commands/apply-local-content-update.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/commands/apply-pending-visual-styles-with-agent.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/commit-visual-styles.ts +18 -7
- package/corpus/templates/design/app/pages/design-editor/commands/escape-hotkey.ts +4 -90
- package/corpus/templates/design/app/pages/design-editor/commands/layer-marquee-selection-change.ts +2 -1
- package/corpus/templates/design/app/pages/design-editor/commands/layer-selection-change.ts +4 -3
- package/corpus/templates/design/app/pages/design-editor/commands/screen-element-select.ts +12 -2
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-style-change.ts +9 -2
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-move-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/send-runtime-layer-state-semantic-handoff.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/commands/start-sidebar-resize.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +11 -1
- package/corpus/templates/design/app/pages/design-editor/effects/adopt-db-file-content.ts +11 -19
- package/corpus/templates/design/app/pages/design-editor/effects/observe-collab-text.ts +6 -6
- package/corpus/templates/design/app/pages/design-editor/effects/publish-agent-selection-context.ts +1 -1
- package/corpus/templates/design/app/pages/design-editor/effects/seed-collab-content.ts +12 -15
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +5 -59
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/types.ts +3 -3
- package/corpus/templates/design/app/routes.ts +3 -1
- package/corpus/templates/design/changelog/2026-08-20-canvas-edits-patch-the-frame-instead-of-rebuilding-it.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-builder-design-system-imports-reconcile-after-indexing.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-draw-mode-needs-shift-y.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-eyedropper-shortcut.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-figma-style-alignment-guides-and-snapping.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-group-transforms-keep-the-selection.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-inspector-fields-keep-focus-on-enter.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-alt-keeps-the-incoming-handle.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-pen-on-the-board-creates-one-vector.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-a-multi-selection-from-the-group-handles.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-scale-resizes-text-with-the-object.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-selecting-another-object-keeps-the-scale-tool-armed.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-the-shape-tool-remembers-the-shape-you-picked.md +6 -0
- package/corpus/templates/design/changelog/2026-08-21-vectors-drawn-in-a-frame-land-where-you-drew-them.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-multi-screen-generation-no-longer-loses-a-saved-screens-layo.md +6 -0
- package/corpus/templates/design/changelog/2026-08-22-rename-and-search-fields-are-labeled-for-screen-readers.md +6 -0
- package/corpus/templates/design/package.json +2 -0
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +311 -0
- package/corpus/templates/design/shared/canvas-math.ts +612 -206
- package/corpus/templates/design/shared/pen-path.ts +37 -0
- package/corpus/templates/design/vitest.config.ts +7 -1
- package/corpus/templates/dispatch/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/dispatch/actions/list-workspace-connections.ts +34 -3
- package/corpus/templates/dispatch/app/routes/integrations.tsx +55 -21
- package/corpus/templates/dispatch/app/routes.ts +3 -1
- package/corpus/templates/factory/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/factory/.env.example +2 -7
- package/corpus/templates/factory/AGENTS.md +3 -0
- package/corpus/templates/factory/README.md +5 -3
- package/corpus/templates/factory/actions/create-factory.ts +16 -3
- package/corpus/templates/factory/actions/get-slack-feedback-context.ts +2 -0
- package/corpus/templates/factory/actions/get-triage-item.ts +2 -0
- package/corpus/templates/factory/actions/list-factory-audit.ts +116 -36
- package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
- package/corpus/templates/factory/actions/list-triage-items.ts +22 -19
- package/corpus/templates/factory/actions/run-factory-automation.ts +7 -3
- package/corpus/templates/factory/actions/save-factory-automation.ts +5 -2
- package/corpus/templates/factory/actions/save-triage-config.ts +2 -8
- package/corpus/templates/factory/actions/start-builder-for-item.ts +21 -0
- package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +229 -297
- package/corpus/templates/factory/app/components/factory/FactorySettingsView.tsx +397 -247
- package/corpus/templates/factory/app/components/factory/FactorySourceSettingsGroup.tsx +33 -0
- package/corpus/templates/factory/app/components/factory/NewFactoryForm.tsx +202 -162
- package/corpus/templates/factory/app/i18n/en-US.ts +32 -4
- package/corpus/templates/factory/app/routes/factory.tsx +84 -11
- package/corpus/templates/factory/app/routes.ts +3 -1
- package/corpus/templates/factory/changelog/2026-08-21-activity-runs-use-automation-display-names.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-create-and-settings-source-cards.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-keep-automations-visible-while-running.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-nested-factory-automations-can-poll.md +6 -0
- package/corpus/templates/factory/changelog/2026-08-21-settings-sticky-unsaved-bar.md +6 -0
- package/corpus/templates/factory/server/connectors/credentials.ts +10 -5
- package/corpus/templates/factory/server/lib/factory-audit-report.ts +412 -0
- package/corpus/templates/factory/server/lib/factory-config-reconcile.ts +321 -0
- package/corpus/templates/factory/server/lib/factory-scope.ts +25 -2
- package/corpus/templates/factory/server/lib/require-factory-automation.ts +13 -4
- package/corpus/templates/factory/server/plugins/factory-migrations.ts +148 -4
- package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +4 -6
- package/corpus/templates/factory/vitest.config.ts +17 -2
- package/corpus/templates/forms/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/forms/app/routes/_app.settings.tsx +4 -1
- package/corpus/templates/forms/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/forms/server/lib/public-form-ssr.ts +11 -1
- package/corpus/templates/forms/vitest.config.ts +1 -0
- package/corpus/templates/macros/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/macros/app/routes.ts +3 -1
- package/corpus/templates/macros/vitest.config.ts +6 -1
- package/corpus/templates/mail/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/mail/actions/manage-gmail-filters.ts +10 -2
- package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -37
- package/corpus/templates/mail/app/components/email/IntegrationsSidebar.tsx +14 -2
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +66 -36
- package/corpus/templates/mail/app/hooks/use-google-auth.ts +2 -0
- package/corpus/templates/mail/app/lib/google-oauth-setup.ts +17 -0
- package/corpus/templates/mail/app/pages/InboxPage.tsx +69 -9
- package/corpus/templates/mail/app/routes/$.tsx +9 -0
- package/corpus/templates/mail/app/routes/$view.$threadId.tsx +23 -1
- package/corpus/templates/mail/app/routes/$view.tsx +47 -1
- package/corpus/templates/mail/app/routes.ts +3 -1
- package/corpus/templates/mail/changelog/2026-08-22-gmail-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-gmail-filters-now-shows-the-real-error.md +6 -0
- package/corpus/templates/mail/changelog/2026-08-22-unknown-mail-urls-now-show-the-404-page.md +6 -0
- package/corpus/templates/mail/server/handlers/google-auth.ts +11 -2
- package/corpus/templates/mail/server/lib/google-auth.ts +92 -12
- package/corpus/templates/mail/server/onboarding.ts +66 -18
- package/corpus/templates/mail/vitest.config.ts +6 -1
- package/corpus/templates/plan/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/plan/app/routes/settings.tsx +4 -1
- package/corpus/templates/plan/app/routes.ts +3 -1
- package/corpus/templates/plan/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/plan/netlify.toml +1 -1
- package/corpus/templates/slides/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/slides/actions/patch-deck.ts +79 -10
- package/corpus/templates/slides/actions/update-slide.ts +11 -1
- package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +14 -4
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +10 -52
- package/corpus/templates/slides/app/components/editor/GoogleDocImportHint.tsx +8 -53
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +9 -75
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +8 -60
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +10 -2
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +19 -7
- package/corpus/templates/slides/app/lib/sanitize-slide-html.ts +49 -36
- package/corpus/templates/slides/app/routes/access-request.approve.tsx +16 -9
- package/corpus/templates/slides/app/routes.ts +3 -1
- package/corpus/templates/slides/changelog/2026-08-22-already-uploaded-chat-images-are-no-longer-dropped.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-google-drive-and-slides-can-now-connect-with-the-shared-google-oauth.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-multi-slide-repairs-now-report-slides-that-still-overflow.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-22-update-slide-now-reports-which-batched-edit-was-skipped.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +52 -1
- package/corpus/templates/slides/server/lib/chat-attachments.ts +29 -3
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +66 -16
- package/corpus/templates/slides/server/lib/slide-content-patch.ts +13 -2
- package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -2
- package/corpus/templates/slides/tsconfig.json +5 -0
- package/corpus/templates/slides/vitest.config.ts +6 -1
- package/corpus/templates/tasks/.agents/skills/secrets/SKILL.md +11 -4
- package/corpus/templates/tasks/app/routes/settings.tsx +4 -1
- package/corpus/templates/tasks/app/routes.ts +3 -1
- package/corpus/templates/tasks/changelog/2026-08-22-the-extensions-link-now-opens-the-extensions-tab-instead-o.md +6 -0
- package/corpus/templates/tasks/vitest.config.ts +7 -1
- package/dist/action.d.ts +91 -0
- package/dist/action.js +50 -0
- package/dist/agent/abort-reasons.d.ts +38 -0
- package/dist/agent/abort-reasons.js +49 -0
- package/dist/agent/engine/ai-sdk-engine.js +8 -5
- package/dist/agent/engine/anthropic-engine.js +7 -5
- package/dist/agent/engine/first-event-timeout.d.ts +42 -17
- package/dist/agent/engine/first-event-timeout.js +67 -25
- package/dist/agent/production-agent.d.ts +23 -0
- package/dist/agent/production-agent.js +107 -102
- package/dist/agent/run-loop-with-resume.d.ts +2 -28
- package/dist/agent/run-loop-with-resume.js +25 -40
- package/dist/agent/run-manager.js +5 -4
- package/dist/agent/run-store.d.ts +55 -0
- package/dist/agent/run-store.js +124 -1
- package/dist/agent/tool-search.js +2 -1
- package/dist/agent/types.d.ts +9 -4
- package/dist/app-config/auth.d.ts +1 -0
- package/dist/app-config/auth.js +7 -0
- package/dist/app-config/configuration-error.d.ts +11 -0
- package/dist/app-config/configuration-error.js +14 -0
- package/dist/app-config/index.d.ts +1 -0
- package/dist/app-config/index.js +1 -0
- package/dist/app-config/integrations.d.ts +1 -0
- package/dist/app-config/integrations.js +10 -0
- package/dist/app-config/plugins.d.ts +34 -0
- package/dist/app-config/plugins.js +39 -0
- package/dist/app-config/run-lifecycle-invariants.d.ts +18 -9
- package/dist/app-config/run-lifecycle-invariants.js +18 -25
- package/dist/app-config/schema.d.ts +17 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/chat-threads/schema-migrations.js +20 -0
- package/dist/chat-threads/store.js +21 -4
- package/dist/cli/native-dependencies.d.ts +4 -0
- package/dist/cli/native-dependencies.js +15 -0
- package/dist/client/EnvironmentBadge.d.ts +1 -1
- package/dist/client/EnvironmentBadge.js +40 -5
- package/dist/client/MultiTabAssistantChat.d.ts +1 -1
- package/dist/client/MultiTabAssistantChat.js +35 -14
- package/dist/client/agent-chat/index.d.ts +1 -1
- package/dist/client/agent-chat/index.js +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +2 -1
- package/dist/client/agent-page/use-jobs.js +3 -5
- package/dist/client/agent-sidebar-state.js +3 -1
- package/dist/client/blocks/library/code-tabs.js +5 -0
- package/dist/client/blocks/library/code.js +1 -0
- package/dist/client/chat-first/apps-rail.js +2 -2
- package/dist/client/chat-model-groups.d.ts +12 -0
- package/dist/client/chat-model-groups.js +3 -2
- package/dist/client/integrations/GoogleProductLogo.d.ts +5 -0
- package/dist/client/integrations/GoogleProductLogo.js +45 -0
- package/dist/client/integrations/index.d.ts +2 -0
- package/dist/client/integrations/index.js +2 -0
- package/dist/client/integrations/workspace-provider-oauth.d.ts +8 -0
- package/dist/client/integrations/workspace-provider-oauth.js +13 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/settings/SettingsTabsPage.js +10 -6
- package/dist/client/sharing/ShareButton.js +11 -2
- package/dist/client/use-chat-models.d.ts +6 -0
- package/dist/client/use-chat-models.js +10 -0
- package/dist/client/use-db-sync.js +27 -9
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +111 -9
- package/dist/connections/catalog.js +86 -30
- package/dist/db/create-get-db.js +18 -0
- package/dist/db/ddl-guard.d.ts +0 -4
- package/dist/db/ddl-guard.js +46 -0
- package/dist/deploy/build.d.ts +19 -0
- package/dist/deploy/build.js +190 -16
- package/dist/deploy/function-bundle.d.ts +45 -0
- package/dist/deploy/function-bundle.js +337 -0
- package/dist/deploy/workspace-deploy.js +19 -1
- package/dist/eject/workspace-connections.js +4 -0
- package/dist/email-catalog/registry.d.ts +4 -0
- package/dist/email-catalog/registry.js +79 -14
- package/dist/extensions/content-patch.js +14 -2
- package/dist/integrations/plugin.d.ts +10 -0
- package/dist/integrations/plugin.js +40 -6
- package/dist/jobs/actions/run-automation-now.d.ts +2 -1
- package/dist/jobs/actions/run-automation-now.js +11 -5
- package/dist/jobs/frontmatter.js +53 -2
- package/dist/jobs/run-now.d.ts +11 -1
- package/dist/jobs/run-now.js +42 -7
- package/dist/jobs/scheduler.d.ts +1 -0
- package/dist/jobs/scheduler.js +2 -1
- package/dist/localization/core-messages/ar-SA.js +3 -0
- package/dist/localization/core-messages/de-DE.js +3 -0
- package/dist/localization/core-messages/en-US.d.ts +3 -0
- package/dist/localization/core-messages/en-US.js +3 -0
- package/dist/localization/core-messages/es-ES.js +3 -0
- package/dist/localization/core-messages/fr-FR.js +3 -0
- package/dist/localization/core-messages/hi-IN.js +3 -0
- package/dist/localization/core-messages/ja-JP.js +3 -0
- package/dist/localization/core-messages/ko-KR.js +3 -0
- package/dist/localization/core-messages/pt-BR.js +3 -0
- package/dist/localization/core-messages/zh-CN.js +3 -0
- package/dist/localization/core-messages/zh-TW.js +3 -0
- package/dist/localization/core-messages.d.ts +3 -0
- package/dist/localization/default-messages.d.ts +2 -5
- package/dist/localization/default-messages.js +2 -5
- package/dist/mcp/build-server.d.ts +9 -0
- package/dist/mcp/build-server.js +37 -8
- package/dist/mcp-client/oauth-client.d.ts +7 -0
- package/dist/mcp-client/oauth-client.js +12 -1
- package/dist/oauth-tokens/index.d.ts +1 -1
- package/dist/oauth-tokens/index.js +1 -1
- package/dist/oauth-tokens/lifecycle.d.ts +11 -0
- package/dist/oauth-tokens/lifecycle.js +17 -0
- package/dist/oauth-tokens/store.js +7 -0
- package/dist/observability/posthog-ai.d.ts +15 -1
- package/dist/observability/posthog-ai.js +24 -12
- package/dist/observability/traces.js +158 -28
- package/dist/onboarding/app-profile.js +2 -2
- package/dist/onboarding/plugin.js +10 -2
- package/dist/onboarding/types.d.ts +2 -0
- package/dist/provider-api/actions/custom-provider-registration.d.ts +1 -1
- package/dist/provider-api/actions/provider-api.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts +27 -3
- package/dist/server/agent-chat/action-filters-a2a.js +48 -9
- package/dist/server/agent-chat-plugin.js +36 -9
- package/dist/server/agent-discovery.js +43 -20
- package/dist/server/auth.js +18 -16
- package/dist/server/beta-opt-out-html.js +45 -4
- package/dist/server/better-auth-instance.d.ts +2 -1
- package/dist/server/better-auth-instance.js +37 -7
- package/dist/server/builder-design-systems.d.ts +4 -1
- package/dist/server/builder-design-systems.js +87 -6
- package/dist/server/builder-oauth.d.ts +1 -7
- package/dist/server/builder-oauth.js +80 -163
- package/dist/server/core-routes-plugin.d.ts +29 -0
- package/dist/server/core-routes-plugin.js +100 -20
- package/dist/server/default-plugins.d.ts +18 -0
- package/dist/server/default-plugins.js +22 -0
- package/dist/server/edge.d.ts +1 -0
- package/dist/server/edge.js +1 -0
- package/dist/server/framework-request-handler.js +31 -3
- package/dist/server/google-oauth.d.ts +3 -0
- package/dist/server/google-oauth.js +3 -0
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +3 -3
- package/dist/server/onboarding-html.js +37 -3
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.js +72 -20
- package/dist/shared/agent-sidebar-url.d.ts +1 -0
- package/dist/shared/agent-sidebar-url.js +1 -0
- package/dist/shared/environment-lanes.d.ts +2 -0
- package/dist/shared/environment-lanes.js +3 -1
- package/dist/shared/index.d.ts +3 -1
- package/dist/shared/index.js +3 -1
- package/dist/shared/surface-visibility.d.ts +31 -0
- package/dist/shared/surface-visibility.js +57 -0
- package/dist/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/chat/app/routes.ts +3 -1
- package/dist/templates/chat/vitest.config.ts +8 -0
- package/dist/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/default/app/routes.ts +3 -1
- package/dist/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
- package/dist/tracking/registry.d.ts +11 -0
- package/dist/tracking/registry.js +5 -2
- package/dist/triggers/actions.js +10 -3
- package/dist/usage/store.js +23 -3
- package/dist/user-profile/actions/get-auth-methods.js +18 -5
- package/dist/vite/client.js +33 -7
- package/docs/content/actions-access-control.mdx +43 -4
- package/docs/content/actions-defining.mdx +16 -0
- package/docs/content/authentication.mdx +40 -21
- package/docs/content/environment-variables.mdx +1 -0
- package/docs/content/template-clips-capture-everywhere.mdx +29 -30
- package/docs/content/template-clips-developers.mdx +4 -4
- package/docs/content/template-clips.mdx +3 -1
- package/package.json +2 -2
- package/src/eject/workspace-connections.ts +4 -0
- package/src/templates/chat/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/chat/app/routes.ts +3 -1
- package/src/templates/chat/vitest.config.ts +8 -0
- package/src/templates/default/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/default/app/routes.ts +3 -1
- package/src/templates/headless/.agents/skills/secrets/SKILL.md +11 -4
- package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +11 -4
|
@@ -97,6 +97,8 @@ export interface OAuthStatePayload {
|
|
|
97
97
|
mobile?: boolean;
|
|
98
98
|
addAccount?: boolean;
|
|
99
99
|
app?: string;
|
|
100
|
+
/** Optional signed scope for provider-specific OAuth flows. */
|
|
101
|
+
scope?: string;
|
|
100
102
|
/**
|
|
101
103
|
* Same-origin path to redirect to after a successful web-flow sign-in.
|
|
102
104
|
* Threaded through the (HMAC-signed) state so it survives the round trip
|
|
@@ -129,6 +131,7 @@ export interface EncodeOAuthStateOptions {
|
|
|
129
131
|
mobile?: boolean;
|
|
130
132
|
addAccount?: boolean;
|
|
131
133
|
app?: string;
|
|
134
|
+
scope?: string;
|
|
132
135
|
returnUrl?: string;
|
|
133
136
|
flowId?: string;
|
|
134
137
|
desktopVerifierHash?: string;
|
|
@@ -459,6 +459,8 @@ export function encodeOAuthState(redirectUriOrOpts, owner, desktop, addAccount,
|
|
|
459
459
|
payload.a = true;
|
|
460
460
|
if (opts.app)
|
|
461
461
|
payload.app = opts.app;
|
|
462
|
+
if (opts.scope)
|
|
463
|
+
payload.s = opts.scope;
|
|
462
464
|
if (opts.returnUrl)
|
|
463
465
|
payload.r2 = opts.returnUrl;
|
|
464
466
|
if (opts.flowId)
|
|
@@ -511,6 +513,7 @@ export function decodeOAuthState(stateParam, fallbackUri) {
|
|
|
511
513
|
mobile: !!parsed.m,
|
|
512
514
|
addAccount: !!parsed.a,
|
|
513
515
|
app: typeof parsed.app === "string" ? parsed.app : undefined,
|
|
516
|
+
scope: typeof parsed.s === "string" ? parsed.s : undefined,
|
|
514
517
|
// Pass returnUrl through as-is — same-origin validation runs at the
|
|
515
518
|
// consumer (oauthCallbackResponse → safeReturnPath). The state is
|
|
516
519
|
// HMAC-signed, but we still validate at consumption as defence in
|
package/dist/server/index.d.ts
CHANGED
|
@@ -69,13 +69,13 @@ export { createOnboardingPlugin, defaultOnboardingPlugin, } from "../onboarding/
|
|
|
69
69
|
export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, uploadFile, builderFileUploadProvider, type FileUploadInput, type FileUploadProvider, type FileUploadResult, } from "../file-upload/index.js";
|
|
70
70
|
export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteCommand, slackAdapter, telegramAdapter, whatsappAdapter, discordAdapter, microsoftTeamsAdapter, emailAdapter, assertPlatformCapability, type PlatformAdapter, type IncomingMessage, type OutgoingMessage, type PlatformAdapterCapabilities, type ImmediateWebhookResponse, type IntegrationStatus, type IntegrationsPluginOptions, type IntegrationExecutionContext, BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, type BuiltInChannelId, type ChannelCapabilities, type IntegrationAvailability, type IntegrationCatalogEntry, type IntegrationCategory, type IntegrationCredentialRequirement, type IntegrationIconKey, type IntegrationSupportMaturity, } from "../integrations/index.js";
|
|
71
71
|
export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, type OAuthStatePayload, type OAuthOwnerResult, type OAuthSessionResult, } from "./google-oauth.js";
|
|
72
|
-
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
|
|
73
|
-
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderGatewayCredentials, resolveBuilderGatewayCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
|
|
74
|
-
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemGitHubFile, type BuilderDesignSystemGitHubFileCollection, type BuilderDesignSystemGitHubSource, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
|
|
72
|
+
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, hasWorkspaceProviderOAuthCredentials, isGoogleWorkspaceOAuthProvider, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, type GenericWorkspaceOAuthProvider, type WorkspaceProviderOAuthFlow, } from "./workspace-provider-oauth.js";
|
|
73
|
+
export { CredentialStoreUnavailableError, FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed, resolveBuilderGatewayCredentials, resolveBuilderGatewayCredentialsDetailed, resolveBuilderCredentialSource, resolveBuilderCredential, readDeployCredentialEnv, writeBuilderCredentials, deleteBuilderCredentials, resolveSecret, type BuilderCredentialsDetailed, } from "./credential-provider.js";
|
|
74
|
+
export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSystemIndexFiles, collectBuilderDesignSystemGitHubFiles, createBuilderDesignSystemProxyFields, fetchBuilderDesignSystemDecodeJobStatus, fetchBuilderDesignSystemDocs, getBuilderDesignSystemsBaseUrl, hydrateBuilderDesignSystemReference, indexBuilderDesignSystem, localBuilderDesignSystemId, mimeTypeForBuilderDesignSystemFilename, parseBuilderDesignSystemProxyReference, startBuilderDesignSystemIndex, startBuilderDesignSystemUpload, type BuildBuilderDesignSystemIndexFilesOptions, type BuilderDesignSystemCodeFileInput, type BuilderDesignSystemDecodeJobStatus, type BuilderDesignSystemDocsOptions, type BuilderDesignSystemDocument, type BuilderDesignSystemHydratedReference, type BuilderDesignSystemIndexFile, type BuilderDesignSystemIndexFromSourcesOptions, type BuilderDesignSystemIndexOptions, type BuilderDesignSystemIndexResult, type BuilderDesignSystemStatus, type BuilderDesignSystemGitHubFile, type BuilderDesignSystemGitHubFileCollection, type BuilderDesignSystemGitHubSource, type BuilderDesignSystemUploadAttachment, type BuilderDesignSystemUploadSlot, type BuilderDesignSystemProxyFields, type BuilderDesignSystemProxyFieldsOptions, type BuilderDesignSystemProxyReference, type BuilderDesignSystemSourceKind, } from "./builder-design-systems.js";
|
|
75
75
|
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, type BuilderProjectResult, type RunBuilderAgentResult, } from "./builder-browser.js";
|
|
76
76
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, type FusionBranchRef, type EnsureFusionContainerResult, type SendFusionMessageResult, } from "./fusion-app.js";
|
|
77
77
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, type EmailAttachment, type EmailReadiness, type EmailProvider, type SendEmailArgs, } from "./email.js";
|
|
78
|
-
export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, type TransactionalEmailDefinition, type RegisteredTransactionalEmail, } from "../email-catalog/registry.js";
|
|
78
|
+
export { defineTransactionalEmail, defineTransactionalEmails, replaceTransactionalEmails, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, type TransactionalEmailDefinition, type RegisteredTransactionalEmail, } from "../email-catalog/registry.js";
|
|
79
79
|
export { notifyActivity, runActivityNotification, resolveActivityRecipients, type ActivityDeliveryFailure, type ActivityNotificationResult, type ActivityNotificationStatus, type NotifyActivityInput, type ResolveActivityRecipientsInput, } from "./activity-notifications.js";
|
|
80
80
|
export { renderEmail, emailStrong, emailLink, type RenderEmailArgs, type RenderedEmail, type EmailCta, } from "./email-template.js";
|
|
81
81
|
export { getAppProductionUrl, getFirstPartyProdUrl } from "./app-url.js";
|
package/dist/server/index.js
CHANGED
|
@@ -74,8 +74,8 @@ export { createOnboardingPlugin, defaultOnboardingPlugin, } from "../onboarding/
|
|
|
74
74
|
export { registerFileUploadProvider, unregisterFileUploadProvider, listFileUploadProviders, getActiveFileUploadProvider, getActiveFileUploadProviderForRequest, uploadFile, builderFileUploadProvider, } from "../file-upload/index.js";
|
|
75
75
|
export { createIntegrationsPlugin, defaultIntegrationsPlugin, enqueueRemoteCommand, slackAdapter, telegramAdapter, whatsappAdapter, discordAdapter, microsoftTeamsAdapter, emailAdapter, assertPlatformCapability, BUILT_IN_INTEGRATION_CATALOG, INTEGRATION_CATEGORIES, getIntegrationCatalogEntry, listBuiltInChannelIntegrations, listIntegrationCatalog, } from "../integrations/index.js";
|
|
76
76
|
export { isElectron, isMobile, getOrigin, getAppBasePath, getAppUrl, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, encodeOAuthState, decodeOAuthState, resolveOAuthOwner, createOAuthSession, oauthCallbackResponse, oauthErrorPage, oauthDesktopExchangePage, } from "./google-oauth.js";
|
|
77
|
-
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
|
|
78
|
-
export { FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed,
|
|
77
|
+
export { buildWorkspaceProviderAuthorizationUrl, createWorkspaceProviderOAuthHandler, exchangeWorkspaceProviderOAuthCode, handleWorkspaceProviderOAuthCallback, handleWorkspaceProviderOAuthStart, hasWorkspaceProviderOAuthCredentials, isGoogleWorkspaceOAuthProvider, isWorkspaceProviderOAuthFlowValid, mergeWorkspaceOAuthValues, resolveWorkspaceProviderIdentity, workspaceProviderOAuthPath, } from "./workspace-provider-oauth.js";
|
|
78
|
+
export { CredentialStoreUnavailableError, FeatureNotConfiguredError, hasBuilderPrivateKey, isBuilderEnvManaged, getBuilderProxyOrigin, getBuilderImageGenerationBaseUrl, getBuilderWebSearchBaseUrl, getBuilderAuthHeader, resolveBuilderPrivateKey, resolveBuilderAuthHeader, resolveHasBuilderPrivateKey, resolveHasCompleteBuilderConnection, resolveBuilderCredentials, resolveBuilderCredentialsDetailed,
|
|
79
79
|
// Gateway lane, for the metered surfaces a deployed site can call without an
|
|
80
80
|
// identity — image and video generation, realtime transcription. Falls
|
|
81
81
|
// through to the identity credential first, so a consumer moves lane by
|
|
@@ -85,7 +85,7 @@ export { builderDesignSystemUrl, builderProjectBranchUrl, buildBuilderDesignSyst
|
|
|
85
85
|
export { createBuilderProject, ensureBuilderProject, findBuilderProjectForRepo, getBuilderBranchProjectId, isBuilderBranchingEnabled, requestBuilderBrowserConnection, resolveBuilderBranchProjectId, resolveIsBuilderBranchingEnabled, runBuilderAgent, } from "./builder-browser.js";
|
|
86
86
|
export { ensureFusionContainer, sendFusionBranchMessage, pushFusionBranch, reserveFusionHostingSlug, deployFusionProject, getFusionDeploys, getFusionBranchEditorUrl, getFusionHostingUrl, } from "./fusion-app.js";
|
|
87
87
|
export { sendEmail, isEmailConfigured, getEmailReadiness, getEmailProvider, } from "./email.js";
|
|
88
|
-
export { defineTransactionalEmail, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, } from "../email-catalog/registry.js";
|
|
88
|
+
export { defineTransactionalEmail, defineTransactionalEmails, replaceTransactionalEmails, listTransactionalEmails, getTransactionalEmail, renderTransactionalEmailPreview, } from "../email-catalog/registry.js";
|
|
89
89
|
export { notifyActivity, runActivityNotification, resolveActivityRecipients, } from "./activity-notifications.js";
|
|
90
90
|
export { renderEmail, emailStrong, emailLink, } from "./email-template.js";
|
|
91
91
|
export { getAppProductionUrl, getFirstPartyProdUrl } from "./app-url.js";
|
|
@@ -11,7 +11,7 @@ import { getLocaleInitScript } from "../localization/server.js";
|
|
|
11
11
|
import { DEFAULT_LOCALE, LOCALE_METADATA, LOCALE_STORAGE_KEY, SUPPORTED_LOCALES, localeDisplayName, } from "../localization/shared.js";
|
|
12
12
|
import { NATIVE_AUTH_COPY } from "../shared/auth-copy.js";
|
|
13
13
|
import { docsUrl } from "../shared/docs-url.js";
|
|
14
|
-
import { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, } from "../shared/environment-lanes.js";
|
|
14
|
+
import { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, } from "../shared/environment-lanes.js";
|
|
15
15
|
import { PASSWORD_MAX_LENGTH, PASSWORD_MIN_LENGTH, } from "../shared/password-policy.js";
|
|
16
16
|
import { signInJourneyInlineScript } from "../shared/sign-in-journey.js";
|
|
17
17
|
import { AGENT_NATIVE_SOCIAL_IMAGE_ALT, AGENT_NATIVE_SOCIAL_IMAGE_HEIGHT, AGENT_NATIVE_SOCIAL_IMAGE_PATH, AGENT_NATIVE_SOCIAL_IMAGE_TYPE, AGENT_NATIVE_SOCIAL_IMAGE_WIDTH, withAgentNativeSocialImageCacheBuster, } from "../shared/social-meta.js";
|
|
@@ -1035,6 +1035,7 @@ ${localeMenuItemsHtml}
|
|
|
1035
1035
|
<div class="environment-popover-title" id="environment-popover-title">You're on Agent Native Beta</div>
|
|
1036
1036
|
<div class="environment-popover-copy">Choose where you want to continue.</div>
|
|
1037
1037
|
<a class="environment-production-link" id="environment-production-link" href="">Switch to production</a>
|
|
1038
|
+
<button type="button" class="environment-hide-badge" id="environment-hide-badge">Hide badge</button>
|
|
1038
1039
|
</div>
|
|
1039
1040
|
</div>`;
|
|
1040
1041
|
const hostedSignupLegalNotice = opts.signupLegalNotice === undefined &&
|
|
@@ -1430,9 +1431,19 @@ ${marketing.description ? ` <p class="app-desc" data-marketing-field="descr
|
|
|
1430
1431
|
var button = document.getElementById('environment-badge');
|
|
1431
1432
|
var popover = document.getElementById('environment-popover');
|
|
1432
1433
|
var productionLink = document.getElementById('environment-production-link');
|
|
1433
|
-
|
|
1434
|
+
var hideButton = document.getElementById('environment-hide-badge');
|
|
1435
|
+
if (!switcher || !button || !popover || !productionLink || !hideButton) return;
|
|
1434
1436
|
if (window.parent !== window) return;
|
|
1435
1437
|
|
|
1438
|
+
try {
|
|
1439
|
+
var forceUrl = new URL(window.location.href);
|
|
1440
|
+
if (forceUrl.searchParams.get(${JSON.stringify(BETA_FORCE_QUERY_PARAM)}) === 'true') {
|
|
1441
|
+
window.sessionStorage.setItem(${JSON.stringify(BETA_FORCE_SESSION_STORAGE_KEY)}, '1');
|
|
1442
|
+
}
|
|
1443
|
+
} catch (error) {
|
|
1444
|
+
void error;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1436
1447
|
// Persist the beta opt-out before authentication replaces this cached shell.
|
|
1437
1448
|
try {
|
|
1438
1449
|
var optOutUrl = new URL(window.location.href);
|
|
@@ -1496,6 +1507,10 @@ ${marketing.description ? ` <p class="app-desc" data-marketing-field="descr
|
|
|
1496
1507
|
document.addEventListener('keydown', function(event) {
|
|
1497
1508
|
if (event.key === 'Escape') setOpen(false);
|
|
1498
1509
|
});
|
|
1510
|
+
hideButton.addEventListener('click', function() {
|
|
1511
|
+
setOpen(false);
|
|
1512
|
+
switcher.hidden = true;
|
|
1513
|
+
});
|
|
1499
1514
|
})();`;
|
|
1500
1515
|
return `<!DOCTYPE html>
|
|
1501
1516
|
<html lang="${DEFAULT_LOCALE}" dir="ltr">
|
|
@@ -1668,7 +1683,8 @@ ${hasMarketing
|
|
|
1668
1683
|
.environment-badge:hover,
|
|
1669
1684
|
.environment-badge[aria-expanded="true"] { background: #4a4a4a; }
|
|
1670
1685
|
.environment-badge:focus-visible,
|
|
1671
|
-
.environment-production-link:focus-visible
|
|
1686
|
+
.environment-production-link:focus-visible,
|
|
1687
|
+
.environment-hide-badge:focus-visible {
|
|
1672
1688
|
outline: 2px solid #33c4ff;
|
|
1673
1689
|
outline-offset: 2px;
|
|
1674
1690
|
}
|
|
@@ -1700,6 +1716,24 @@ ${hasMarketing
|
|
|
1700
1716
|
text-decoration: none;
|
|
1701
1717
|
}
|
|
1702
1718
|
.environment-production-link:hover { background: #242424; }
|
|
1719
|
+
.environment-hide-badge {
|
|
1720
|
+
display: flex;
|
|
1721
|
+
align-items: center;
|
|
1722
|
+
justify-content: center;
|
|
1723
|
+
width: 100%;
|
|
1724
|
+
min-height: 2rem;
|
|
1725
|
+
margin-top: 0.5rem;
|
|
1726
|
+
margin-bottom: -0.5rem;
|
|
1727
|
+
padding: 0.375rem 0.75rem;
|
|
1728
|
+
color: inherit;
|
|
1729
|
+
opacity: 0.65;
|
|
1730
|
+
border: 0;
|
|
1731
|
+
background: transparent;
|
|
1732
|
+
font: inherit;
|
|
1733
|
+
font-size: 0.8125rem;
|
|
1734
|
+
cursor: pointer;
|
|
1735
|
+
}
|
|
1736
|
+
.environment-hide-badge:hover { opacity: 1; }
|
|
1703
1737
|
.card {
|
|
1704
1738
|
width: 100%;
|
|
1705
1739
|
max-width: 400px;
|
|
@@ -26,8 +26,8 @@ export declare function createRealtimeTokenHandler(): import("h3").EventHandlerW
|
|
|
26
26
|
expiresAt?: undefined;
|
|
27
27
|
ttlSeconds?: undefined;
|
|
28
28
|
} | {
|
|
29
|
-
error?: undefined;
|
|
30
29
|
token: string;
|
|
31
30
|
expiresAt: string;
|
|
32
31
|
ttlSeconds: number;
|
|
32
|
+
error?: undefined;
|
|
33
33
|
}>>;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { type H3Event } from "h3";
|
|
2
2
|
import { type WorkspaceConnectionProvider } from "../connections/catalog.js";
|
|
3
3
|
import { type OAuthStatePayload } from "./google-oauth.js";
|
|
4
|
-
export type GenericWorkspaceOAuthProvider = "figma" | "google_drive" | "github" | "hubspot" | "salesforce" | "jira" | "sentry" | "notion";
|
|
4
|
+
export type GenericWorkspaceOAuthProvider = "figma" | "gmail" | "google_calendar" | "google_docs" | "google_drive" | "google_sheets" | "google_slides" | "github" | "hubspot" | "salesforce" | "jira" | "sentry" | "notion";
|
|
5
|
+
export type WorkspaceProviderOAuthScope = "user" | "organization" | "app";
|
|
6
|
+
export declare function isWorkspaceProviderOAuthScope(value: unknown): value is WorkspaceProviderOAuthScope;
|
|
7
|
+
export declare function isGoogleWorkspaceOAuthProvider(provider: string): boolean;
|
|
8
|
+
export declare function hasWorkspaceProviderOAuthCredentials(provider: GenericWorkspaceOAuthProvider): Promise<boolean>;
|
|
5
9
|
export interface WorkspaceProviderOAuthFlow {
|
|
6
10
|
provider: GenericWorkspaceOAuthProvider;
|
|
7
11
|
flowId: string;
|
|
@@ -10,6 +14,7 @@ export interface WorkspaceProviderOAuthFlow {
|
|
|
10
14
|
owner: string;
|
|
11
15
|
orgId?: string;
|
|
12
16
|
appId: string;
|
|
17
|
+
scope: WorkspaceProviderOAuthScope;
|
|
13
18
|
salesforceLoginUrl?: string;
|
|
14
19
|
expiresAt: number;
|
|
15
20
|
}
|
|
@@ -13,7 +13,12 @@ import { decodeOAuthState, encodeOAuthState, getAppUrl, resolveOAuthRedirectUri,
|
|
|
13
13
|
import { runWithRequestContext } from "./request-context.js";
|
|
14
14
|
const SUPPORTED_PROVIDERS = new Set([
|
|
15
15
|
"figma",
|
|
16
|
+
"gmail",
|
|
17
|
+
"google_calendar",
|
|
18
|
+
"google_docs",
|
|
16
19
|
"google_drive",
|
|
20
|
+
"google_sheets",
|
|
21
|
+
"google_slides",
|
|
17
22
|
"github",
|
|
18
23
|
"hubspot",
|
|
19
24
|
"salesforce",
|
|
@@ -26,7 +31,22 @@ const PROVIDER_REQUEST_TIMEOUT_MS = 10_000;
|
|
|
26
31
|
const PROVIDER_RESPONSE_MAX_BYTES = 256 * 1024;
|
|
27
32
|
const SALESFORCE_PRODUCTION_LOGIN_URL = "https://login.salesforce.com";
|
|
28
33
|
const SALESFORCE_SANDBOX_LOGIN_URL = "https://test.salesforce.com";
|
|
29
|
-
const WORKSPACE_OAUTH_ADMIN_ERROR = "
|
|
34
|
+
const WORKSPACE_OAUTH_ADMIN_ERROR = "This shared connection requires organization or app-admin access. Personal connections can be connected by any workspace member.";
|
|
35
|
+
export function isWorkspaceProviderOAuthScope(value) {
|
|
36
|
+
return value === "user" || value === "organization" || value === "app";
|
|
37
|
+
}
|
|
38
|
+
export function isGoogleWorkspaceOAuthProvider(provider) {
|
|
39
|
+
return (provider === "gmail" ||
|
|
40
|
+
provider === "google_calendar" ||
|
|
41
|
+
provider === "google_docs" ||
|
|
42
|
+
provider === "google_drive" ||
|
|
43
|
+
provider === "google_sheets" ||
|
|
44
|
+
provider === "google_slides");
|
|
45
|
+
}
|
|
46
|
+
export async function hasWorkspaceProviderOAuthCredentials(provider) {
|
|
47
|
+
const [clientId, clientSecret] = await resolveProviderClientCredentials(provider);
|
|
48
|
+
return Boolean(clientId && clientSecret);
|
|
49
|
+
}
|
|
30
50
|
export function workspaceProviderOAuthPath(provider, phase) {
|
|
31
51
|
return `/_agent-native/connections/oauth/${provider}/${phase}`;
|
|
32
52
|
}
|
|
@@ -46,7 +66,14 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
46
66
|
return unauthorized(event);
|
|
47
67
|
const query = getQuery(event);
|
|
48
68
|
const appId = normalizeAppId(text(query.appId) ?? getAppConfig().app.workspaceId ?? "creative-context");
|
|
49
|
-
const
|
|
69
|
+
const requestedScope = parseWorkspaceProviderOAuthScope(text(query.scope));
|
|
70
|
+
if (!requestedScope) {
|
|
71
|
+
setResponseStatus(event, 400);
|
|
72
|
+
return {
|
|
73
|
+
error: "OAuth connection scope must be user, organization, or app.",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const orgContext = await requireWorkspaceProviderOAuthAccess(event, appId, requestedScope);
|
|
50
77
|
if (!orgContext) {
|
|
51
78
|
return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
|
|
52
79
|
}
|
|
@@ -91,6 +118,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
91
118
|
owner: session.email,
|
|
92
119
|
orgId,
|
|
93
120
|
app: appId,
|
|
121
|
+
scope: orgContext.oauthScope,
|
|
94
122
|
returnUrl,
|
|
95
123
|
flowId,
|
|
96
124
|
});
|
|
@@ -102,6 +130,7 @@ export async function handleWorkspaceProviderOAuthStart(event, providerId) {
|
|
|
102
130
|
owner: session.email,
|
|
103
131
|
orgId,
|
|
104
132
|
appId,
|
|
133
|
+
scope: orgContext.oauthScope,
|
|
105
134
|
...(salesforceLoginUrl ? { salesforceLoginUrl } : {}),
|
|
106
135
|
expiresAt: Date.now() + FLOW_TTL_SECONDS * 1_000,
|
|
107
136
|
};
|
|
@@ -134,7 +163,11 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
134
163
|
if (!session?.email)
|
|
135
164
|
return unauthorized(event);
|
|
136
165
|
const flow = readStoredFlow(event, providerId);
|
|
137
|
-
|
|
166
|
+
if (!flow || !isWorkspaceProviderOAuthScope(flow.scope)) {
|
|
167
|
+
setResponseStatus(event, 400);
|
|
168
|
+
return { error: "OAuth state is invalid or expired." };
|
|
169
|
+
}
|
|
170
|
+
const orgContext = await requireWorkspaceProviderOAuthAccess(event, flow.appId, flow.scope);
|
|
138
171
|
if (!orgContext) {
|
|
139
172
|
return { error: WORKSPACE_OAUTH_ADMIN_ERROR };
|
|
140
173
|
}
|
|
@@ -204,8 +237,12 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
204
237
|
await saveOAuthTokens(provider.oauth.provider, accountId, tokens, session.email);
|
|
205
238
|
await setOAuthDisplayName(provider.oauth.provider, accountId, identity.label);
|
|
206
239
|
const existing = existingConnections.find((connection) => connection.accountId === accountId &&
|
|
207
|
-
(
|
|
208
|
-
connection.
|
|
240
|
+
(flow.scope === "user"
|
|
241
|
+
? connection.allowedUsers.some((allowedUser) => allowedUser.toLowerCase() === session.email.toLowerCase())
|
|
242
|
+
: flow.scope === "organization"
|
|
243
|
+
? connection.allowedUsers.length === 0 &&
|
|
244
|
+
(connection.allowedUserGroups?.length ?? 0) === 0
|
|
245
|
+
: connection.allowedApps.some((allowedApp) => allowedApp.toLowerCase() === flow.appId.toLowerCase())));
|
|
209
246
|
const scopes = mergeWorkspaceOAuthValues(existing?.scopes ?? [], identity.scopes ?? tokenScopes(tokens, provider.oauth.scopes));
|
|
210
247
|
const connectionConfig = {
|
|
211
248
|
credentialMode: "oauth",
|
|
@@ -229,8 +266,10 @@ export async function handleWorkspaceProviderOAuthCallback(event, providerId) {
|
|
|
229
266
|
accountLabel: identity.label,
|
|
230
267
|
status: "connected",
|
|
231
268
|
scopes,
|
|
232
|
-
allowedApps: existing?.allowedApps ??
|
|
233
|
-
|
|
269
|
+
allowedApps: existing?.allowedApps ?? (flow.scope === "app" ? [flow.appId] : []),
|
|
270
|
+
allowedUsers: flow.scope === "user"
|
|
271
|
+
? [session.email]
|
|
272
|
+
: (existing?.allowedUsers ?? []),
|
|
234
273
|
config: connectionConfig,
|
|
235
274
|
lastCheckedAt: new Date(),
|
|
236
275
|
lastError: null,
|
|
@@ -267,7 +306,7 @@ export function buildWorkspaceProviderAuthorizationUrl(input) {
|
|
|
267
306
|
url.searchParams.set("audience", "api.atlassian.com");
|
|
268
307
|
url.searchParams.set("prompt", "consent");
|
|
269
308
|
}
|
|
270
|
-
if (input.provider.id
|
|
309
|
+
if (isGoogleWorkspaceOAuthProvider(input.provider.id)) {
|
|
271
310
|
url.searchParams.set("access_type", "offline");
|
|
272
311
|
url.searchParams.set("include_granted_scopes", "true");
|
|
273
312
|
url.searchParams.set("prompt", "consent");
|
|
@@ -393,7 +432,7 @@ export async function exchangeWorkspaceProviderOAuthCode(input) {
|
|
|
393
432
|
...(input.providerId === "sentry"
|
|
394
433
|
? { client_id: input.clientId, client_secret: input.clientSecret }
|
|
395
434
|
: {}),
|
|
396
|
-
...(input.providerId
|
|
435
|
+
...(isGoogleWorkspaceOAuthProvider(input.providerId)
|
|
397
436
|
? { client_id: input.clientId, client_secret: input.clientSecret }
|
|
398
437
|
: {}),
|
|
399
438
|
};
|
|
@@ -566,19 +605,16 @@ async function resolveWorkspaceProviderIdentitySingle(providerId, tokens) {
|
|
|
566
605
|
label: text(user?.email) ?? text(user?.name) ?? "Sentry account",
|
|
567
606
|
};
|
|
568
607
|
}
|
|
569
|
-
if (providerId
|
|
608
|
+
if (isGoogleWorkspaceOAuthProvider(providerId)) {
|
|
570
609
|
const accessToken = text(tokens.access_token);
|
|
571
|
-
const { response, body } = await fetchBoundedProviderJson("https://
|
|
572
|
-
const
|
|
573
|
-
const accountId = text(user?.permissionId) ?? text(user?.emailAddress);
|
|
610
|
+
const { response, body } = await fetchBoundedProviderJson("https://openidconnect.googleapis.com/v1/userinfo", { headers: { Authorization: `Bearer ${accessToken}` } }, "Google Workspace");
|
|
611
|
+
const accountId = text(body.email) ?? text(body.sub);
|
|
574
612
|
if (!response.ok || !accountId) {
|
|
575
|
-
throw new Error("Google
|
|
613
|
+
throw new Error("Google OAuth response did not identify the connected account.");
|
|
576
614
|
}
|
|
577
615
|
return {
|
|
578
616
|
accountId,
|
|
579
|
-
label: text(
|
|
580
|
-
text(user?.displayName) ??
|
|
581
|
-
"Google Drive account",
|
|
617
|
+
label: text(body.email) ?? text(body.name) ?? "Google account",
|
|
582
618
|
};
|
|
583
619
|
}
|
|
584
620
|
const accessToken = text(tokens.access_token);
|
|
@@ -615,6 +651,7 @@ export function isWorkspaceProviderOAuthFlowValid(input) {
|
|
|
615
651
|
input.state.flowId === input.flow.flowId &&
|
|
616
652
|
input.state.redirectUri === input.flow.redirectUri &&
|
|
617
653
|
input.state.owner === input.flow.owner &&
|
|
654
|
+
input.state.scope === input.flow.scope &&
|
|
618
655
|
input.sessionEmail === input.flow.owner &&
|
|
619
656
|
input.state.orgId === input.flow.orgId &&
|
|
620
657
|
input.sessionOrgId === input.flow.orgId &&
|
|
@@ -697,7 +734,9 @@ export function mergeWorkspaceOAuthValues(existing, incoming) {
|
|
|
697
734
|
return [...new Set([...existing, ...incoming])];
|
|
698
735
|
}
|
|
699
736
|
function clientCredentialKeys(provider, field) {
|
|
700
|
-
const prefix = provider
|
|
737
|
+
const prefix = isGoogleWorkspaceOAuthProvider(provider)
|
|
738
|
+
? "GOOGLE"
|
|
739
|
+
: provider.toUpperCase();
|
|
701
740
|
const suffix = field === "id" ? "ID" : "SECRET";
|
|
702
741
|
if (provider === "github") {
|
|
703
742
|
const integrationPrefix = `GITHUB_INTEGRATION_CLIENT_${suffix}`;
|
|
@@ -799,6 +838,11 @@ function normalizeAppId(value) {
|
|
|
799
838
|
function text(value) {
|
|
800
839
|
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
801
840
|
}
|
|
841
|
+
function parseWorkspaceProviderOAuthScope(value) {
|
|
842
|
+
if (value === undefined)
|
|
843
|
+
return "organization";
|
|
844
|
+
return isWorkspaceProviderOAuthScope(value) ? value : null;
|
|
845
|
+
}
|
|
802
846
|
function scalarText(value) {
|
|
803
847
|
if (typeof value === "number" && Number.isFinite(value))
|
|
804
848
|
return String(value);
|
|
@@ -817,15 +861,23 @@ function unauthorized(event) {
|
|
|
817
861
|
setResponseStatus(event, 401);
|
|
818
862
|
return { error: "Authentication required" };
|
|
819
863
|
}
|
|
820
|
-
async function
|
|
864
|
+
async function requireWorkspaceProviderOAuthAccess(event, appId, requestedScope = "organization") {
|
|
821
865
|
const context = await getOrgContext(event).catch(() => null);
|
|
822
866
|
if (!context || !context.orgId) {
|
|
823
867
|
setResponseStatus(event, 403);
|
|
824
868
|
return null;
|
|
825
869
|
}
|
|
826
|
-
if (
|
|
870
|
+
if (requestedScope === "user") {
|
|
871
|
+
return { ...context, oauthScope: "user" };
|
|
872
|
+
}
|
|
873
|
+
if (requestedScope === "organization" &&
|
|
874
|
+
canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
|
|
827
875
|
return { ...context, oauthScope: "organization" };
|
|
828
876
|
}
|
|
877
|
+
if (requestedScope === "app" &&
|
|
878
|
+
canConnectWorkspaceProviderOAuth(context.orgId, context.role)) {
|
|
879
|
+
return { ...context, oauthScope: "app" };
|
|
880
|
+
}
|
|
829
881
|
if (appId) {
|
|
830
882
|
const descriptor = getRegisteredAppRoles(appId);
|
|
831
883
|
if (descriptor?.roles.some((role) => role === "admin")) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export declare const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
|
|
2
2
|
export declare const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
|
|
3
3
|
export declare const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
|
|
4
|
+
export declare const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
|
|
4
5
|
export declare function isAgentNativeOpenDeepLink(urlOrPath: string): boolean;
|
|
5
6
|
export declare function withCollapsedAgentSidebarParam(urlOrPath: string): string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const AGENT_NATIVE_OPEN_PATH = "/_agent-native/open";
|
|
2
2
|
export const AGENT_SIDEBAR_QUERY_PARAM = "agentSidebar";
|
|
3
3
|
export const AGENT_SIDEBAR_QUERY_VALUE_CLOSED = "closed";
|
|
4
|
+
export const AGENT_SIDEBAR_QUERY_VALUE_OPEN = "open";
|
|
4
5
|
const RELATIVE_URL_BASE = "http://agent-native.invalid";
|
|
5
6
|
function hasUrlScheme(urlOrPath) {
|
|
6
7
|
return /^[a-z][a-z0-9+.-]*:/i.test(urlOrPath);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
|
|
2
2
|
export declare const BETA_OPT_OUT_DURATION_MS: number;
|
|
3
3
|
export declare const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
|
|
4
|
+
export declare const BETA_FORCE_QUERY_PARAM = "force";
|
|
5
|
+
export declare const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
|
|
4
6
|
export declare const ENVIRONMENT_BETA_HOSTS: {
|
|
5
7
|
readonly "agent-workspace.builder.io": "beta.agent-workspace.builder.io";
|
|
6
8
|
readonly "analytics.agent-native.com": "beta.analytics.agent-native.com";
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export const BETA_OPT_OUT_QUERY_PARAM = "agentNativeBetaOptOut";
|
|
2
|
-
export const BETA_OPT_OUT_DURATION_MS =
|
|
2
|
+
export const BETA_OPT_OUT_DURATION_MS = 8 * 60 * 60 * 1000;
|
|
3
3
|
export const BETA_OPT_OUT_STORAGE_KEY = "agent-native:beta-opt-out-until";
|
|
4
|
+
export const BETA_FORCE_QUERY_PARAM = "force";
|
|
5
|
+
export const BETA_FORCE_SESSION_STORAGE_KEY = "agent-native:force-production";
|
|
4
6
|
export const ENVIRONMENT_BETA_HOSTS = {
|
|
5
7
|
"agent-workspace.builder.io": "beta.agent-workspace.builder.io",
|
|
6
8
|
"analytics.agent-native.com": "beta.analytics.agent-native.com",
|
package/dist/shared/index.d.ts
CHANGED
|
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
|
|
|
6
6
|
export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
|
|
7
7
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
8
8
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
9
|
+
export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, type EnvironmentBadgeTargets, } from "./environment-lanes.js";
|
|
9
10
|
export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, type SsrHtmlContentTypeOptions, withSsrHtmlContentType, } from "./cache-control.js";
|
|
11
|
+
export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
|
|
10
12
|
export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, type DocsUrlOptions, } from "./docs-url.js";
|
|
11
13
|
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, type RuntimeConfigEnvironment, type RuntimeConfigIssue, type RuntimeConfigIssueCode, type RuntimeConfigIssueSeverity, type RuntimeConfigPhase, type RuntimeConfigReport, type RuntimeConfigRequirements, } from "./runtime-config.js";
|
|
12
14
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, type LlmConnectionStatus, } from "./llm-connection.js";
|
|
13
15
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
|
|
14
16
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, type WorkspaceAppRouteAccess, type WorkspaceAppRouteAccessFromConfig, type WorkspaceAppAudience, } from "./workspace-app-audience.js";
|
|
15
|
-
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
17
|
+
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
16
18
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, type ChatFirstAppCreationPromptInput, type ChatFirstAppCreationResource, type ChatFirstAppCreationVaultAccessMode, } from "./chat-first-app-creation.js";
|
|
17
19
|
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, type NativeAuthCopy, } from "./auth-copy.js";
|
|
18
20
|
export { createPollEngine, type PollEngineOptions, type PollEngineHandle, } from "./poll-engine.js";
|
package/dist/shared/index.js
CHANGED
|
@@ -6,13 +6,15 @@ export { truncate } from "./truncate.js";
|
|
|
6
6
|
export { isHumanReadableDocumentTitle, normalizeDocumentTitle, } from "./document-title.js";
|
|
7
7
|
export { injectDocumentMarkup } from "./html-document.js";
|
|
8
8
|
export { withBuilderUtmTrackingParams } from "./builder-link-tracking.js";
|
|
9
|
+
export { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, ENVIRONMENT_BETA_HOSTS, resolveEnvironmentTargets, } from "./environment-lanes.js";
|
|
9
10
|
export { SSR_HTML_CONTENT_TYPE, SSR_QUERY_CACHE_KEY_HEADER, withSsrHtmlContentType, } from "./cache-control.js";
|
|
11
|
+
export { SURFACE_HIDDEN_FLAG, SURFACE_VISIBILITY_EVENT, addSurfaceVisibilityListener, buildSurfaceVisibilityScript, isHostSurfaceHidden, isSurfaceHidden, } from "./surface-visibility.js";
|
|
10
12
|
export { AGENT_NATIVE_DOCS_ORIGIN, docsUrl, } from "./docs-url.js";
|
|
11
13
|
export { buildRuntimeConfigPrompt, formatRuntimeConfigReport, getRuntimeConfigReport, parseRuntimeConfigReport, runtimeConfigRequirementsFromSearchParams, } from "./runtime-config.js";
|
|
12
14
|
export { llmConnectionTrackingProperties, normalizeLlmConnection, } from "./llm-connection.js";
|
|
13
15
|
export { DISPATCH_WORKSPACE_ROOT_REDIRECTS, RESERVED_WORKSPACE_APP_IDS, assertValidWorkspaceAppId, getWorkspaceAppIdValidationError, isValidWorkspaceAppIdFormat, normalizeWorkspaceAppId, } from "./workspace-app-id.js";
|
|
14
16
|
export { DEFAULT_WORKSPACE_APP_AUDIENCE, WORKSPACE_APP_AUDIENCES, normalizeWorkspaceAppAudience, normalizeWorkspaceAppPathList, workspaceAppAudienceFromEnv, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromEnv, workspaceAppRouteAccessFromPackageJson, } from "./workspace-app-audience.js";
|
|
15
|
-
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
17
|
+
export { AGENT_NATIVE_OPEN_PATH, AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "./agent-sidebar-url.js";
|
|
16
18
|
export { buildChatFirstAppCreationPrompt, titleFromChatFirstAppPrompt, } from "./chat-first-app-creation.js";
|
|
17
19
|
export { NATIVE_AUTH_COPY, resolveNativeAuthCopy, } from "./auth-copy.js";
|
|
18
20
|
export { createPollEngine, } from "./poll-engine.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-declared surface visibility.
|
|
3
|
+
*
|
|
4
|
+
* An Electron `<webview>` guest never reports itself hidden: hiding the element
|
|
5
|
+
* or any ancestor leaves `document.visibilityState === "visible"` and never
|
|
6
|
+
* fires `visibilitychange`, so every visibility-based pause in this package is
|
|
7
|
+
* inert inside the desktop shell. A backgrounded app tab there keeps polling at
|
|
8
|
+
* its full foreground cadence and holds its event stream open for as long as
|
|
9
|
+
* the shell is running. The host therefore has to say so explicitly, and this
|
|
10
|
+
* flag is what background work must consult instead of the document alone.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
|
|
13
|
+
/** Dispatched on `window` whenever the host flips the flag. */
|
|
14
|
+
export declare const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
|
|
15
|
+
/** Whether an embedding host has declared this surface off screen. */
|
|
16
|
+
export declare function isHostSurfaceHidden(): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Whether this surface is off screen by either signal. A host that has stashed
|
|
19
|
+
* the surface entirely is a stronger statement than a backgrounded browser tab,
|
|
20
|
+
* so callers that keep working while merely backgrounded should still stop on
|
|
21
|
+
* `isHostSurfaceHidden()`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isSurfaceHidden(): boolean;
|
|
24
|
+
/** Subscribe to both visibility signals. Returns an unsubscribe function. */
|
|
25
|
+
export declare function addSurfaceVisibilityListener(handler: () => void): () => void;
|
|
26
|
+
/**
|
|
27
|
+
* Script a host embedder evaluates inside the guest to declare whether the
|
|
28
|
+
* surface it is hosting is on screen. Kept here so the flag name, the event
|
|
29
|
+
* name, and the write that sets them cannot drift apart across packages.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildSurfaceVisibilityScript(hidden: boolean): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-declared surface visibility.
|
|
3
|
+
*
|
|
4
|
+
* An Electron `<webview>` guest never reports itself hidden: hiding the element
|
|
5
|
+
* or any ancestor leaves `document.visibilityState === "visible"` and never
|
|
6
|
+
* fires `visibilitychange`, so every visibility-based pause in this package is
|
|
7
|
+
* inert inside the desktop shell. A backgrounded app tab there keeps polling at
|
|
8
|
+
* its full foreground cadence and holds its event stream open for as long as
|
|
9
|
+
* the shell is running. The host therefore has to say so explicitly, and this
|
|
10
|
+
* flag is what background work must consult instead of the document alone.
|
|
11
|
+
*/
|
|
12
|
+
export const SURFACE_HIDDEN_FLAG = "__agentNativeSurfaceHidden";
|
|
13
|
+
/** Dispatched on `window` whenever the host flips the flag. */
|
|
14
|
+
export const SURFACE_VISIBILITY_EVENT = "agentnative:surfacevisibilitychange";
|
|
15
|
+
/** Whether an embedding host has declared this surface off screen. */
|
|
16
|
+
export function isHostSurfaceHidden() {
|
|
17
|
+
if (typeof window === "undefined")
|
|
18
|
+
return false;
|
|
19
|
+
return (window[SURFACE_HIDDEN_FLAG] === true);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Whether this surface is off screen by either signal. A host that has stashed
|
|
23
|
+
* the surface entirely is a stronger statement than a backgrounded browser tab,
|
|
24
|
+
* so callers that keep working while merely backgrounded should still stop on
|
|
25
|
+
* `isHostSurfaceHidden()`.
|
|
26
|
+
*/
|
|
27
|
+
export function isSurfaceHidden() {
|
|
28
|
+
if (isHostSurfaceHidden())
|
|
29
|
+
return true;
|
|
30
|
+
return (typeof document !== "undefined" && document.visibilityState === "hidden");
|
|
31
|
+
}
|
|
32
|
+
/** Subscribe to both visibility signals. Returns an unsubscribe function. */
|
|
33
|
+
export function addSurfaceVisibilityListener(handler) {
|
|
34
|
+
if (typeof document === "undefined" || typeof window === "undefined") {
|
|
35
|
+
return () => { };
|
|
36
|
+
}
|
|
37
|
+
document.addEventListener("visibilitychange", handler);
|
|
38
|
+
window.addEventListener(SURFACE_VISIBILITY_EVENT, handler);
|
|
39
|
+
return () => {
|
|
40
|
+
document.removeEventListener("visibilitychange", handler);
|
|
41
|
+
window.removeEventListener(SURFACE_VISIBILITY_EVENT, handler);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Script a host embedder evaluates inside the guest to declare whether the
|
|
46
|
+
* surface it is hosting is on screen. Kept here so the flag name, the event
|
|
47
|
+
* name, and the write that sets them cannot drift apart across packages.
|
|
48
|
+
*/
|
|
49
|
+
export function buildSurfaceVisibilityScript(hidden) {
|
|
50
|
+
return `(() => {
|
|
51
|
+
const next = ${hidden ? "true" : "false"};
|
|
52
|
+
if (window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] === next) return next;
|
|
53
|
+
window[${JSON.stringify(SURFACE_HIDDEN_FLAG)}] = next;
|
|
54
|
+
window.dispatchEvent(new Event(${JSON.stringify(SURFACE_VISIBILITY_EVENT)}));
|
|
55
|
+
return next;
|
|
56
|
+
})()`;
|
|
57
|
+
}
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type RouteConfig } from "@react-router/dev/routes";
|
|
2
2
|
import { flatRoutes } from "@react-router/fs-routes";
|
|
3
3
|
|
|
4
|
-
export default flatRoutes(
|
|
4
|
+
export default flatRoutes({
|
|
5
|
+
ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
6
|
+
}) satisfies RouteConfig;
|