@agent-native/core 0.169.0 → 0.170.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/bigquery-table-info.ts +3 -2
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/search-bigquery-schema.ts +130 -4
- package/corpus/templates/analytics/agent-native.config.ts +1 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +36 -23
- package/corpus/templates/analytics/app/i18n-data.ts +28 -0
- package/corpus/templates/analytics/app/lib/dashboard-visibility.ts +41 -0
- package/corpus/templates/analytics/app/pages/Agents.tsx +25 -1
- package/corpus/templates/analytics/app/pages/DashboardOverview.tsx +34 -9
- 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-21-dashboard-filters-keep-other-users-dashboards-out-of-mine.md +6 -0
- 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/real-data-actions.ts +14 -3
- package/corpus/templates/analytics/server/lib/slack.ts +4 -2
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +33 -3
- 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/server/lib/brain.ts +27 -2
- 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/stop-meeting-recording.ts +87 -6
- package/corpus/templates/clips/actions/view-screen.ts +8 -1
- package/corpus/templates/clips/app/components/library/search-bar.tsx +1 -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 +1386 -92
- 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/EditPanel.tsx +15 -47
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +284 -136
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +2060 -144
- 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 -8
- 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 +13 -8
- package/corpus/templates/design/app/i18n-data.ts +11 -10
- 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 +99 -57
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +39 -8
- package/corpus/templates/design/app/pages/DesignSystems.tsx +137 -43
- package/corpus/templates/design/app/pages/Index.tsx +3 -1
- 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/preview-navigation.ts +25 -0
- 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-emails.ts +13 -3
- 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/credential-errors.d.ts +1 -1
- package/dist/agent/engine/credential-errors.js +2 -2
- 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/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 +16 -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/AssistantChat.js +47 -15
- package/dist/client/ConnectBuilderCard.d.ts +3 -1
- package/dist/client/ConnectBuilderCard.js +6 -3
- 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/message-components.d.ts +7 -0
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/run-recovery.js +5 -2
- package/dist/client/chat/tool-call-display.js +9 -3
- 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/error-format.js +12 -0
- 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/navigation/index.d.ts +1 -0
- package/dist/client/navigation/index.js +1 -0
- package/dist/client/resources/mcp-integration-catalog.js +0 -29
- package/dist/client/route-state.js +6 -0
- 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/client/workspace-app-navigation.d.ts +10 -0
- package/dist/client/workspace-app-navigation.js +38 -0
- 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 +32 -0
- package/dist/deploy/build.js +241 -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/file-upload/actions/upload-image.d.ts +1 -1
- 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 +4 -1
- package/dist/localization/core-messages/de-DE.js +4 -1
- package/dist/localization/core-messages/en-US.d.ts +4 -1
- package/dist/localization/core-messages/en-US.js +4 -1
- package/dist/localization/core-messages/es-ES.js +4 -1
- package/dist/localization/core-messages/fr-FR.js +4 -1
- package/dist/localization/core-messages/hi-IN.js +4 -1
- package/dist/localization/core-messages/ja-JP.js +4 -1
- package/dist/localization/core-messages/ko-KR.js +4 -1
- package/dist/localization/core-messages/pt-BR.js +4 -1
- package/dist/localization/core-messages/zh-CN.js +4 -1
- package/dist/localization/core-messages/zh-TW.js +4 -1
- package/dist/localization/core-messages.d.ts +4 -1
- 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/notifications/routes.d.ts +1 -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 +12 -12
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/provider-api/index.js +2 -0
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +13 -4
- package/dist/scripts/agent-engines/list-agent-engines.js +29 -3
- package/dist/scripts/db/check-scoping.js +9 -6
- package/dist/secrets/register-framework-secrets.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- 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 +23 -7
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.js +23 -1
- 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 +113 -21
- 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/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 +24 -5
- package/docs/content/actions-access-control.mdx +43 -4
- package/docs/content/actions-defining.mdx +16 -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 +3 -3
- 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
- /package/corpus/templates/dispatch/app/routes/{apps.$appId.tsx → apps.$appId.$.tsx} +0 -0
|
@@ -44,7 +44,7 @@ function AppRows({ apps, defaultAppIds, activeAppId, layout, onDragStart, onDrop
|
|
|
44
44
|
const pinned = layout.pinnedIds.includes(app.id);
|
|
45
45
|
const index = orderedApps.indexOf(app);
|
|
46
46
|
return (_jsxs(ContextMenu, { children: [_jsx(ContextMenuTrigger, { asChild: true, children: _jsxs("li", { draggable: true, "data-chat-first-app": true, "data-app-id": app.id, className: cn("group flex h-8 w-full min-w-0 items-center gap-1 rounded-md px-0 text-sm", active
|
|
47
|
-
? "font-medium text-sidebar-foreground"
|
|
47
|
+
? "bg-sidebar-accent font-medium text-sidebar-accent-foreground"
|
|
48
48
|
: "text-sidebar-foreground/75 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"), onDragStart: (event) => {
|
|
49
49
|
event.dataTransfer.effectAllowed = "move";
|
|
50
50
|
onDragStart(app.id);
|
|
@@ -136,7 +136,7 @@ export const ChatFirstAppsRail = memo(function ChatFirstAppsRail({ apps, default
|
|
|
136
136
|
return (_jsx(TooltipProvider, { children: _jsxs("section", { "data-chat-first-apps-rail": true, className: "flex flex-col items-center gap-1 px-1.5 pt-2", "aria-label": copy("workspaceApps"), children: [loading && apps.length === 0
|
|
137
137
|
? [0, 1, 2].map((index) => (_jsx(Skeleton, { className: "size-9 rounded-md" }, index)))
|
|
138
138
|
: visibleApps.map((app) => (_jsxs(Tooltip, { delayDuration: 0, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-chat-first-app": true, "data-app-id": app.id, className: cn("flex size-9 items-center justify-center rounded-md", activeAppId === app.id
|
|
139
|
-
? "text-sidebar-foreground"
|
|
139
|
+
? "bg-sidebar-accent text-sidebar-accent-foreground"
|
|
140
140
|
: "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"), onClick: () => onOpenApp(app), "aria-label": copy("openApp", { name: app.name }), children: _jsx(ChatFirstRailAppIcon, { app: app, activeAppId: activeAppId, renderIcon: renderIcon }) }) }), _jsx(TooltipContent, { side: "right", children: app.name })] }, app.id))), onOpenAllApps ? (_jsxs(Tooltip, { delayDuration: 0, children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", "data-chat-first-all-apps": true, className: "flex size-9 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", onClick: onOpenAllApps, "aria-label": copy("allApps"), children: _jsx(IconApps, { size: 16, "aria-hidden": "true" }) }) }), _jsx(TooltipContent, { side: "right", children: copy("allApps") })] })) : null, error ? (_jsx("span", { className: "size-1.5 rounded-full bg-destructive", title: error, "aria-label": error })) : null] }) }));
|
|
141
141
|
}
|
|
142
142
|
return (_jsxs("section", { "data-chat-first-apps-rail": true, className: "mt-3 px-2 pb-2 pt-2", "aria-label": copy("workspaceApps"), children: [_jsxs("div", { className: "mb-1 flex items-center gap-1.5 px-2 text-[11px] font-medium text-sidebar-foreground/50", children: [_jsx("span", { children: copy("workspaceApps") }), _jsx("span", { className: "ml-auto", children: createTrigger })] }), loading && apps.length === 0 ? (_jsx("div", { className: "space-y-0.5 px-2", children: [0, 1, 2].map((index) => (_jsx(Skeleton, { className: "h-8 w-full rounded-md" }, index))) })) : apps.length === 0 ? (_jsxs("div", { className: "px-2", children: [_jsx("p", { className: "text-xs text-sidebar-foreground/55", children: copy("noWorkspaceApps") }), createAppTrigger ? (createTrigger) : onCreateApp ? (_jsxs("button", { type: "button", className: "mt-1 inline-flex h-6 items-center gap-1.5 rounded-md border border-sidebar-border px-2 text-xs text-sidebar-foreground/75 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onCreateApp, children: [_jsx(IconPlus, { size: 13, "aria-hidden": "true" }), copy("createApp")] })) : (createTrigger)] })) : (_jsx(AppRows, { apps: visibleApps, defaultAppIds: defaultAppIds, activeAppId: activeAppId, layout: layout, onDragStart: setDraggedAppId, onDrop: reorderApps, onDragEnd: () => setDraggedAppId(null), onOpenApp: onOpenApp, onRemoveApp: onRemoveApp, onTogglePinned: togglePinned, onMove: moveApp, renderIcon: renderIcon, copy: copy })), hasMoreApps || showAllApps ? (_jsxs("button", { type: "button", className: "mt-0.5 flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/50 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: () => setShowAllApps((value) => !value), children: [showAllApps ? (_jsx(IconChevronUp, { size: 14, "aria-hidden": "true" })) : (_jsx(IconChevronDown, { size: 14, "aria-hidden": "true" })), showAllApps ? copy("showLess") : copy("showMore")] })) : null, onOpenAllApps ? (_jsx("div", { className: "mt-1 border-t border-sidebar-border/60 pt-1", children: _jsxs("button", { type: "button", "data-chat-first-all-apps": true, className: "flex h-8 w-full items-center gap-2 rounded-md px-2 text-xs text-sidebar-foreground/55 hover:bg-sidebar-accent hover:text-sidebar-foreground", onClick: onOpenAllApps, children: [_jsx(IconApps, { size: 14, "aria-hidden": "true" }), _jsx("span", { children: copy("allApps") })] }) })) : null, error ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "mt-1 flex items-center gap-1 px-2 text-[10px] text-destructive/80", onClick: onRetry, "aria-label": error, children: [_jsx("span", { className: "size-1.5 rounded-full bg-destructive" }), onRetry ? copy("retry") : copy("appsLoadError")] }) }), _jsx(TooltipContent, { side: "right", children: error })] })) : null] }));
|
|
@@ -10,6 +10,18 @@ export interface ChatModelEngineEntry {
|
|
|
10
10
|
supportedModels?: readonly string[];
|
|
11
11
|
requiredEnvVars?: readonly string[];
|
|
12
12
|
packageInstalled?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Server-resolved readiness. The env-key fallback below cannot see
|
|
15
|
+
* vault-stored credentials or the deploy-injected Builder gateway lane, so
|
|
16
|
+
* an engine running on either is reported unconfigured without this.
|
|
17
|
+
*
|
|
18
|
+
* Undefined means the server could not resolve it — including a credential
|
|
19
|
+
* read that threw, reported in `configuredError`. That deliberately falls
|
|
20
|
+
* through to the env heuristic rather than reading as "needs an API key".
|
|
21
|
+
*/
|
|
22
|
+
configured?: boolean;
|
|
23
|
+
/** Why readiness is unknown, when the server's lookup failed. */
|
|
24
|
+
configuredError?: string;
|
|
13
25
|
}
|
|
14
26
|
export interface BuildChatModelGroupsOptions {
|
|
15
27
|
engines: readonly ChatModelEngineEntry[];
|
|
@@ -143,8 +143,9 @@ export function buildChatModelGroups({ engines, configuredKeys, builderConnected
|
|
|
143
143
|
engine: engine.name,
|
|
144
144
|
label: engine.label,
|
|
145
145
|
models: sortModelsByCost(addCurrentModel(engine.supportedModels ?? [], engine.name, currentEngineName, currentModel)),
|
|
146
|
-
configured:
|
|
147
|
-
requiredEnvVars.
|
|
146
|
+
configured: engine.configured ??
|
|
147
|
+
(requiredEnvVars.length === 0 ||
|
|
148
|
+
requiredEnvVars.some((key) => configured.has(key))),
|
|
148
149
|
};
|
|
149
150
|
})
|
|
150
151
|
.filter((group) => group.models.length > 0);
|
|
@@ -80,6 +80,18 @@ const KNOWN_CHAT_ERROR_KEYS = new Map([
|
|
|
80
80
|
"No LLM provider is connected. Open this app's Manage agent > LLM, then connect Builder.io or add a provider key.",
|
|
81
81
|
"agentChat.errorMessages.noProviderConnected",
|
|
82
82
|
],
|
|
83
|
+
[
|
|
84
|
+
"No LLM provider is connected. Open this app's Manage agent > LLM, then connect Builder.io (free tier available) or add a provider key.",
|
|
85
|
+
"agentChat.errorMessages.noProviderConnected",
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
"No LLM provider is connected. Open Settings > Agent > AI providers, then connect Builder.io or add a provider key.",
|
|
89
|
+
"agentChat.errorMessages.noProviderConnected",
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"No LLM provider is connected. Open Settings > Agent > AI providers, then connect Builder.io (free tier available) or add a provider key.",
|
|
93
|
+
"agentChat.errorMessages.noProviderConnected",
|
|
94
|
+
],
|
|
83
95
|
[
|
|
84
96
|
"The provider behind this model rejected the request. Pick a different model, then retry.",
|
|
85
97
|
"agentChat.errorMessages.builderModelUnauthorized",
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
export type GoogleProduct = "calendar" | "docs" | "drive" | "gmail" | "sheets" | "slides";
|
|
3
|
+
export declare function GoogleProductLogo({ product, className, ...props }: {
|
|
4
|
+
product: GoogleProduct;
|
|
5
|
+
} & Omit<SVGProps<SVGSVGElement>, "children">): import("react").JSX.Element;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const GOOGLE_MARK_COLORS = {
|
|
3
|
+
// guard:allow-raw-color - official Google product mark color
|
|
4
|
+
blue: "#4285F4",
|
|
5
|
+
// guard:allow-raw-color - official Google product mark color
|
|
6
|
+
blueDark: "#1A73E8",
|
|
7
|
+
// guard:allow-raw-color - official Google product mark color
|
|
8
|
+
blueLight: "#8AB4F8",
|
|
9
|
+
// guard:allow-raw-color - official Google product mark color
|
|
10
|
+
border: "#DADCE0",
|
|
11
|
+
// guard:allow-raw-color - official Google product mark color
|
|
12
|
+
green: "#34A853",
|
|
13
|
+
// guard:allow-raw-color - official Google product mark color
|
|
14
|
+
greenDark: "#188038",
|
|
15
|
+
// guard:allow-raw-color - official Google product mark color
|
|
16
|
+
red: "#EA4335",
|
|
17
|
+
// guard:allow-raw-color - official Google product mark color
|
|
18
|
+
yellow: "#FBBC04",
|
|
19
|
+
// guard:allow-raw-color - official Google product mark color
|
|
20
|
+
yellowDark: "#F9AB00",
|
|
21
|
+
};
|
|
22
|
+
const commonProps = {
|
|
23
|
+
viewBox: "0 0 24 24",
|
|
24
|
+
fill: "none",
|
|
25
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
26
|
+
"aria-hidden": true,
|
|
27
|
+
focusable: false,
|
|
28
|
+
};
|
|
29
|
+
export function GoogleProductLogo({ product, className, ...props }) {
|
|
30
|
+
const svgProps = { ...commonProps, className, ...props };
|
|
31
|
+
switch (product) {
|
|
32
|
+
case "gmail":
|
|
33
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("path", { d: "M3.5 5.25h17A1.5 1.5 0 0 1 22 6.75v10.5a1.5 1.5 0 0 1-1.5 1.5h-17A1.5 1.5 0 0 1 2 17.25V6.75a1.5 1.5 0 0 1 1.5-1.5Z", fill: "white", stroke: GOOGLE_MARK_COLORS.border }), _jsx("path", { d: "m3 7 9 6.75L21 7", stroke: GOOGLE_MARK_COLORS.red, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M3 17.75V7m18 10.75V7", stroke: GOOGLE_MARK_COLORS.blue, strokeWidth: "2", strokeLinecap: "round" }), _jsx("path", { d: "m3 7 4.25 3.2", stroke: GOOGLE_MARK_COLORS.yellow, strokeWidth: "2", strokeLinecap: "round" }), _jsx("path", { d: "m21 7-4.25 3.2", stroke: GOOGLE_MARK_COLORS.green, strokeWidth: "2", strokeLinecap: "round" })] }));
|
|
34
|
+
case "calendar":
|
|
35
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("rect", { x: "3", y: "4", width: "18", height: "17", rx: "2.5", fill: GOOGLE_MARK_COLORS.blue }), _jsx("path", { d: "M3 9h18", stroke: "white", strokeWidth: "2" }), _jsx("path", { d: "M7 3v3M17 3v3", stroke: GOOGLE_MARK_COLORS.blueDark, strokeWidth: "2", strokeLinecap: "round" }), _jsx("text", { x: "12", y: "17", textAnchor: "middle", fill: "white", fontFamily: "Arial, sans-serif", fontSize: "8", fontWeight: "700", children: "31" })] }));
|
|
36
|
+
case "drive":
|
|
37
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("path", { d: "M8.1 3.5h4.65l8.45 14.65h-4.65L8.1 3.5Z", fill: GOOGLE_MARK_COLORS.yellow }), _jsx("path", { d: "M8.1 3.5 3.2 12l4.65 8.05 4.9-8.5L8.1 3.5Z", fill: GOOGLE_MARK_COLORS.green }), _jsx("path", { d: "M3.2 12h9.55l3.8 6.15H6.75L3.2 12Z", fill: GOOGLE_MARK_COLORS.blue })] }));
|
|
38
|
+
case "docs":
|
|
39
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("path", { d: "M6 2.5h8l4 4v15H6a2 2 0 0 1-2-2v-15a2 2 0 0 1 2-2Z", fill: GOOGLE_MARK_COLORS.blue }), _jsx("path", { d: "M14 2.5v4h4", fill: GOOGLE_MARK_COLORS.blueLight }), _jsx("path", { d: "M8 11h8M8 14.5h8M8 18h5", stroke: "white", strokeWidth: "1.4", strokeLinecap: "round" })] }));
|
|
40
|
+
case "sheets":
|
|
41
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("path", { d: "M6 2.5h8l4 4v15H6a2 2 0 0 1-2-2v-15a2 2 0 0 1 2-2Z", fill: GOOGLE_MARK_COLORS.green }), _jsx("path", { d: "M14 2.5v4h4", fill: GOOGLE_MARK_COLORS.greenDark }), _jsx("path", { d: "M8 10h8v8H8v-8Zm0 2.7h8M8 15.3h8M10.7 10v8", stroke: "white", strokeWidth: "1.2" })] }));
|
|
42
|
+
case "slides":
|
|
43
|
+
return (_jsxs("svg", { ...svgProps, children: [_jsx("path", { d: "M6 2.5h8l4 4v15H6a2 2 0 0 1-2-2v-15a2 2 0 0 1 2-2Z", fill: GOOGLE_MARK_COLORS.yellowDark }), _jsx("path", { d: "M14 2.5v4h4", fill: GOOGLE_MARK_COLORS.yellow }), _jsx("path", { d: "M8 17V11m3 6v-3m3 3v-7", stroke: "white", strokeWidth: "1.7", strokeLinecap: "round" })] }));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { IntegrationsPanel, McpIntegrationsLanding, McpIntegrationsSection, type McpIntegrationsLandingProps, type McpIntegrationsSectionProps, } from "./IntegrationsPanel.js";
|
|
2
2
|
export { IntegrationGrid, type IntegrationGridItem, type IntegrationGridProps, } from "./IntegrationGrid.js";
|
|
3
3
|
export { IntegrationConnectionChoice, type IntegrationConnectionChoiceProps, } from "./IntegrationConnectionChoice.js";
|
|
4
|
+
export { GoogleProductLogo, type GoogleProduct } from "./GoogleProductLogo.js";
|
|
5
|
+
export { startWorkspaceProviderOAuth, workspaceProviderOAuthUrl, type WorkspaceProviderOAuthOptions, type WorkspaceProviderOAuthScope, } from "./workspace-provider-oauth.js";
|
|
4
6
|
export { useIntegrationStatus } from "./useIntegrationStatus.js";
|
|
5
7
|
export type { IntegrationStatus } from "./useIntegrationStatus.js";
|
|
6
8
|
export { listIntegrationEnvStatuses, listIntegrationStatuses, saveIntegrationEnvVars, setIntegrationEnabled, setupIntegration, disconnectManagedIntegrationInstallation, listManagedIntegrationInstallations, managedIntegrationOAuthUrl, managedSlackAgentManifestUrl, listManagedIntegrationScopes, saveManagedIntegrationScope, listManagedIntegrationBudgets, listManagedIntegrationMemory, forgetManagedIntegrationMemory, saveManagedIntegrationBudget, testManagedIntegrationInstallation, IntegrationClientError, type ClientIntegrationInstallation, type ClientIntegrationScope, type ClientIntegrationUsageBudget, type ClientIntegrationMemory, type ClientIntegrationStatus, type IntegrationEnvStatus, type SavedEnvVarsResult, } from "./api.js";
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { IntegrationsPanel, McpIntegrationsLanding, McpIntegrationsSection, } from "./IntegrationsPanel.js";
|
|
2
2
|
export { IntegrationGrid, } from "./IntegrationGrid.js";
|
|
3
3
|
export { IntegrationConnectionChoice, } from "./IntegrationConnectionChoice.js";
|
|
4
|
+
export { GoogleProductLogo } from "./GoogleProductLogo.js";
|
|
5
|
+
export { startWorkspaceProviderOAuth, workspaceProviderOAuthUrl, } from "./workspace-provider-oauth.js";
|
|
4
6
|
export { useIntegrationStatus } from "./useIntegrationStatus.js";
|
|
5
7
|
export { listIntegrationEnvStatuses, listIntegrationStatuses, saveIntegrationEnvVars, setIntegrationEnabled, setupIntegration, disconnectManagedIntegrationInstallation, listManagedIntegrationInstallations, managedIntegrationOAuthUrl, managedSlackAgentManifestUrl, listManagedIntegrationScopes, saveManagedIntegrationScope, listManagedIntegrationBudgets, listManagedIntegrationMemory, forgetManagedIntegrationMemory, saveManagedIntegrationBudget, testManagedIntegrationInstallation, IntegrationClientError, } from "./api.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type WorkspaceProviderOAuthScope = "user" | "organization" | "app";
|
|
2
|
+
export interface WorkspaceProviderOAuthOptions {
|
|
3
|
+
appId: string;
|
|
4
|
+
returnPath?: string;
|
|
5
|
+
scope?: WorkspaceProviderOAuthScope;
|
|
6
|
+
}
|
|
7
|
+
export declare function workspaceProviderOAuthUrl(provider: string, options: WorkspaceProviderOAuthOptions): string;
|
|
8
|
+
export declare function startWorkspaceProviderOAuth(provider: string, options: WorkspaceProviderOAuthOptions): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { agentNativePath } from "../api-path.js";
|
|
2
|
+
export function workspaceProviderOAuthUrl(provider, options) {
|
|
3
|
+
const params = new URLSearchParams({
|
|
4
|
+
appId: options.appId,
|
|
5
|
+
scope: options.scope ?? "user",
|
|
6
|
+
});
|
|
7
|
+
if (options.returnPath)
|
|
8
|
+
params.set("return", options.returnPath);
|
|
9
|
+
return agentNativePath(`/_agent-native/connections/oauth/${provider}/start?${params.toString()}`);
|
|
10
|
+
}
|
|
11
|
+
export function startWorkspaceProviderOAuth(provider, options) {
|
|
12
|
+
window.location.assign(workspaceProviderOAuthUrl(provider, options));
|
|
13
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { agentNativePath, appApiPath, appBasePath, appPath, } from "../api-path.js";
|
|
2
2
|
export { useAgentRouteState, useSemanticNavigationState, type AgentRouteLocation, type SemanticNavigationCommandEnvelope, type UseAgentRouteStateOptions, type UseAgentRouteStateResult, type UseSemanticNavigationStateOptions, type UseSemanticNavigationStateResult, } from "../route-state.js";
|
|
3
|
+
export { AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE, postAgentNativeWorkspaceAppRoute, type AgentNativeWorkspaceAppRouteMessage, } from "../workspace-app-navigation.js";
|
|
3
4
|
export { COMMAND_MENU_OPEN_EVENT, CommandMenu, openAgentSidebar, openAgentSettings, openCommandMenu, submitToAgent, useCommandMenuShortcut, type CommandMenuProps, type CommandMenuDoc, type CommandDocsGroupProps, type CommandGroupProps, type CommandItemProps, type CommandShortcutProps, } from "../CommandMenu.js";
|
|
4
5
|
export { buildOpenRouteLink, buildOpenRoutePath, buildLegacyAgentSettingsRoute, buildResourceRoute, buildSettingsRoute, buildStandardAppRoute, buildTeamRoute, createStandardOpenPathResolver, STANDARD_APP_ROUTES, STANDARD_SETTINGS_TABS, type BuildResourceRouteOptions, type BuildStandardAppRouteOptions, type NavigationLink, type NavigationTarget, type StandardAppRouteId, type StandardOpenPathResolverOptions, type StandardOpenPathRoute, type StandardSettingsTabId, } from "../../navigation/index.js";
|
|
5
6
|
export { postNavigate, isInAgentEmbed, AGENT_NAVIGATE_MESSAGE_TYPE, type AgentNavigateMessage, } from "../embed.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { agentNativePath, appApiPath, appBasePath, appPath, } from "../api-path.js";
|
|
2
2
|
export { useAgentRouteState, useSemanticNavigationState, } from "../route-state.js";
|
|
3
|
+
export { AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE, postAgentNativeWorkspaceAppRoute, } from "../workspace-app-navigation.js";
|
|
3
4
|
export { COMMAND_MENU_OPEN_EVENT, CommandMenu, openAgentSidebar, openAgentSettings, openCommandMenu, submitToAgent, useCommandMenuShortcut, } from "../CommandMenu.js";
|
|
4
5
|
export { buildOpenRouteLink, buildOpenRoutePath, buildLegacyAgentSettingsRoute, buildResourceRoute, buildSettingsRoute, buildStandardAppRoute, buildTeamRoute, createStandardOpenPathResolver, STANDARD_APP_ROUTES, STANDARD_SETTINGS_TABS, } from "../../navigation/index.js";
|
|
5
6
|
export { postNavigate, isInAgentEmbed, AGENT_NAVIGATE_MESSAGE_TYPE, } from "../embed.js";
|
|
@@ -383,34 +383,6 @@ export const DEFAULT_MCP_INTEGRATIONS = [
|
|
|
383
383
|
"Grafana Cloud",
|
|
384
384
|
],
|
|
385
385
|
},
|
|
386
|
-
{
|
|
387
|
-
id: "google-workspace",
|
|
388
|
-
name: "Google Workspace",
|
|
389
|
-
provider: "google-workspace",
|
|
390
|
-
description: "Search Google Workspace data through its remote MCP server.",
|
|
391
|
-
descriptionKey: "mcpIntegrations.catalog.googleWorkspace.description",
|
|
392
|
-
useCase: "Workspace search across Gmail, Drive, Calendar, Chat, Docs, Sheets, Slides",
|
|
393
|
-
useCaseKey: "mcpIntegrations.catalog.googleWorkspace.useCase",
|
|
394
|
-
url: "https://workspacemcp.googleapis.com/mcp/v1",
|
|
395
|
-
authMode: "oauth",
|
|
396
|
-
connectionMode: "manual",
|
|
397
|
-
availability: "beta",
|
|
398
|
-
verification: "restricted",
|
|
399
|
-
logoUrl: mcpIntegrationLogo("google-workspace"),
|
|
400
|
-
docsUrl: "https://developers.google.com/workspace/guides/configure-mcp-servers",
|
|
401
|
-
setupNoteKey: "mcpIntegrations.catalog.googleWorkspace.setupNote",
|
|
402
|
-
brandAliases: ["Google", "Gmail", "Google Drive", "Google Calendar"],
|
|
403
|
-
keywords: [
|
|
404
|
-
"email",
|
|
405
|
-
"gmail",
|
|
406
|
-
"drive",
|
|
407
|
-
"calendar",
|
|
408
|
-
"chat",
|
|
409
|
-
"docs",
|
|
410
|
-
"sheets",
|
|
411
|
-
"slides",
|
|
412
|
-
],
|
|
413
|
-
},
|
|
414
386
|
{
|
|
415
387
|
id: "gitlab",
|
|
416
388
|
name: "GitLab",
|
|
@@ -900,7 +872,6 @@ const MCP_LINK_HOSTS = {
|
|
|
900
872
|
sentry: ["sentry.io", "sentry.dev"],
|
|
901
873
|
gong: ["gong.io"],
|
|
902
874
|
grafana: ["grafana.com", "grafana.net"],
|
|
903
|
-
"google-workspace": ["google.com", "googleapis.com"],
|
|
904
875
|
"builder-cms": ["builder.io"],
|
|
905
876
|
notion: ["notion.so", "notion.site"],
|
|
906
877
|
granola: ["granola.ai"],
|
|
@@ -4,6 +4,7 @@ import { useLocation, useNavigate, } from "react-router";
|
|
|
4
4
|
import { isWorkspaceAppPath } from "./api-path.js";
|
|
5
5
|
import { deleteClientAppState, readClientAppState, setClientAppState, } from "./application-state.js";
|
|
6
6
|
import { navigateWithAgentChatViewTransition, } from "./chat-view-transition.js";
|
|
7
|
+
import { postAgentNativeWorkspaceAppRoute } from "./workspace-app-navigation.js";
|
|
7
8
|
const SAFE_BROWSER_TAB_ID_RE = /^[A-Za-z0-9_-]{1,96}$/;
|
|
8
9
|
function normalizeBrowserTabId(browserTabId) {
|
|
9
10
|
if (typeof browserTabId !== "string")
|
|
@@ -195,6 +196,11 @@ export function useAgentRouteState(options) {
|
|
|
195
196
|
const location = useLocation();
|
|
196
197
|
const navigate = useNavigate();
|
|
197
198
|
const browserTabId = useMemo(() => normalizeBrowserTabId(options.browserTabId), [options.browserTabId]);
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
if (options.enabled === false)
|
|
201
|
+
return;
|
|
202
|
+
postAgentNativeWorkspaceAppRoute(`${location.pathname}${location.search}${location.hash}`);
|
|
203
|
+
}, [location.hash, location.pathname, location.search, options.enabled]);
|
|
198
204
|
const navigationKeys = useMemo(() => {
|
|
199
205
|
const scopedKey = appStateKeyForBrowserTab(navigationKey, browserTabId);
|
|
200
206
|
const keys = [scopedKey];
|
|
@@ -200,18 +200,22 @@ export function SettingsTabsPage({ general, account, team, whatsNew, extraTabs =
|
|
|
200
200
|
? defaultTab
|
|
201
201
|
: (tabs[0]?.id ?? "general");
|
|
202
202
|
const tabGroups = useMemo(() => {
|
|
203
|
-
|
|
203
|
+
// Keyed by group id so tabs sharing a group merge into one section even
|
|
204
|
+
// when another group's tabs sit between them in `tabs` — adjacency-only
|
|
205
|
+
// merging left same-id groups duplicated (and rendered with duplicate
|
|
206
|
+
// React keys) whenever the tab list interleaved groups.
|
|
207
|
+
const groupsById = new Map();
|
|
204
208
|
for (const tab of tabs) {
|
|
205
209
|
const groupId = tab.group ?? "app";
|
|
206
|
-
const
|
|
207
|
-
if (
|
|
208
|
-
|
|
210
|
+
const group = groupsById.get(groupId);
|
|
211
|
+
if (group) {
|
|
212
|
+
group.tabs.push(tab);
|
|
209
213
|
}
|
|
210
214
|
else {
|
|
211
|
-
|
|
215
|
+
groupsById.set(groupId, { id: groupId, tabs: [tab] });
|
|
212
216
|
}
|
|
213
217
|
}
|
|
214
|
-
return
|
|
218
|
+
return Array.from(groupsById.values());
|
|
215
219
|
}, [tabs]);
|
|
216
220
|
const tabGroupLabels = {
|
|
217
221
|
app: "Personal",
|
|
@@ -133,7 +133,14 @@ function SharePanel(props) {
|
|
|
133
133
|
const { controller } = props;
|
|
134
134
|
const { inviteEmail, setInviteEmail: onInviteEmailChange, activeShareTab, handleShareTabChange, data, policy, visibility, canManage, role, setRole, notifyPeople, setNotifyPeople, shareMessage, setShareMessage, messageOpen, setMessageOpen, shareError, setShareError, suggestionsOpen, setSuggestionsOpen, inFlight, memberSearch, memberSuggestions, groupSuggestions, selectGroup, knownMembers, shares, handleVisibility, handleHideInSearch, handleAdd, handleChangeRole, handleRemove, } = controller;
|
|
135
135
|
const hasInviteEmail = inviteEmail.trim().length > 0;
|
|
136
|
-
|
|
136
|
+
// `data` stays undefined after a failed read, so a stuck skeleton is
|
|
137
|
+
// indistinguishable from loading unless the error comes off the query itself.
|
|
138
|
+
// `isError` alone is not that signal: it is also true when a refetch fails
|
|
139
|
+
// while React Query still holds usable data, and this panel refetches on open
|
|
140
|
+
// and after every mutation — blocking on that would swap a working panel for
|
|
141
|
+
// a retry screen on one transient failure.
|
|
142
|
+
const loadFailed = controller.sharesQuery.isError && data === undefined;
|
|
143
|
+
const isLoading = !loadFailed && data === undefined;
|
|
137
144
|
const meta = visibilityMeta(visibility, t, props.visibilityCopy);
|
|
138
145
|
const peopleAccessLabel = props.peopleAccessLabel ??
|
|
139
146
|
t("agentChat.share.peopleWithAccess", {
|
|
@@ -151,7 +158,9 @@ function SharePanel(props) {
|
|
|
151
158
|
const hasTabs = extraTabs.length > 0;
|
|
152
159
|
const shareTabLabel = props.shareTabs?.shareLabel ??
|
|
153
160
|
t("agentChat.share.shareLink", { defaultValue: "Share link" });
|
|
154
|
-
const sharePanel =
|
|
161
|
+
const sharePanel = loadFailed ? (_jsxs("div", { children: [showShareLinks && shareUrlPlacement === "top" ? shareLinks : null, _jsxs("div", { role: "alert", className: "flex items-center justify-between gap-2 rounded-md border border-border bg-muted/30 px-3 py-2", children: [_jsx("span", { className: "text-xs text-muted-foreground", children: t("agentChat.share.loadFailed", {
|
|
162
|
+
defaultValue: "Couldn't load sharing settings.",
|
|
163
|
+
}) }), _jsx("button", { type: "button", onClick: () => controller.sharesQuery.refetch(), disabled: controller.sharesQuery.isFetching, className: cn(BUTTON_BASE, "h-7 px-2 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground"), children: t("agentChat.common.retry") })] }), showShareLinks && shareUrlPlacement === "bottom" ? shareLinks : null] })) : isLoading ? (_jsxs("div", { children: [showShareLinks ? (_jsx("div", { className: "mb-4 h-9 rounded-md bg-muted animate-pulse" })) : null, _jsx("div", { className: "mb-2 text-sm font-semibold", children: generalAccessLabel }), _jsx("div", { className: "mb-4 h-9 rounded-md bg-muted animate-pulse" }), _jsx("div", { className: "mb-2 text-sm font-semibold", children: peopleAccessLabel }), _jsx("div", { className: "mb-4 h-7 rounded-md bg-muted animate-pulse" })] })) : (_jsxs("div", { children: [showShareLinks && shareUrlPlacement === "top" ? shareLinks : null, _jsxs("div", { className: "mb-4", children: [_jsx("div", { className: "mb-2 text-sm font-semibold", children: generalAccessLabel }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { "aria-hidden": true, className: "inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-muted text-muted-foreground", children: _jsx(meta.Icon, { size: 16, strokeWidth: 1.75 }) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(VisibilitySelect, { value: visibility, onChange: handleVisibility, disabled: !canManage, visibilityCopy: props.visibilityCopy, allowPublic: policy.allowPublic }), _jsxs("div", { className: "mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground", children: [_jsx("span", { className: "sr-only", children: meta.description }), visibility === "org" && props.hideInSearchControl ? (_jsx(AdvancedAccessPopover, { control: props.hideInSearchControl, canManage: canManage, onToggle: handleHideInSearch })) : null] })] })] })] }), _jsxs("div", { className: "mb-4 space-y-4", children: [_jsx("div", { className: "text-sm font-semibold", children: peopleAccessLabel }), canManage ? (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-stretch gap-2", children: [_jsx(MemberAutocomplete, { value: inviteEmail, open: suggestionsOpen, onOpenChange: setSuggestionsOpen, onValueChange: (next) => {
|
|
155
164
|
onInviteEmailChange(next);
|
|
156
165
|
if (shareError)
|
|
157
166
|
setShareError(null);
|
|
@@ -24,6 +24,12 @@ interface Options {
|
|
|
24
24
|
*/
|
|
25
25
|
enabled?: boolean;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* `useChatModels` takes the raw localStorage key while `MultiTabAssistantChat`
|
|
29
|
+
* takes only the namespace suffix — a surface that hand-writes either one stops
|
|
30
|
+
* sharing the selection with the chat it sits next to.
|
|
31
|
+
*/
|
|
32
|
+
export declare function chatModelSelectionStorageKey(namespace?: string | null): string;
|
|
27
33
|
export declare const CHAT_MODEL_SELECTION_CHANGED_EVENT = "agent-native:chat-model-selection-changed";
|
|
28
34
|
/**
|
|
29
35
|
* Fetches available engines/models from the agent server and exposes the same
|
|
@@ -5,6 +5,16 @@ import { buildChatModelGroups, } from "./chat-model-groups.js";
|
|
|
5
5
|
import { fetchBuilderStatus, fetchEnvironmentStatus, } from "./client-status-requests.js";
|
|
6
6
|
import { callAction } from "./use-action.js";
|
|
7
7
|
const DEFAULT_STORAGE_KEY = "agent-native:chat-models:selection";
|
|
8
|
+
/**
|
|
9
|
+
* `useChatModels` takes the raw localStorage key while `MultiTabAssistantChat`
|
|
10
|
+
* takes only the namespace suffix — a surface that hand-writes either one stops
|
|
11
|
+
* sharing the selection with the chat it sits next to.
|
|
12
|
+
*/
|
|
13
|
+
export function chatModelSelectionStorageKey(namespace) {
|
|
14
|
+
return namespace
|
|
15
|
+
? `${DEFAULT_STORAGE_KEY}:${namespace}`
|
|
16
|
+
: DEFAULT_STORAGE_KEY;
|
|
17
|
+
}
|
|
8
18
|
export const CHAT_MODEL_SELECTION_CHANGED_EVENT = "agent-native:chat-model-selection-changed";
|
|
9
19
|
const MODEL_DISCOVERY_RETRY_DELAYS_MS = [250, 1_000];
|
|
10
20
|
async function fetchEngineCatalog() {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { ensureDemoModeFetchInterceptor } from "../demo/fetch-interceptor.js";
|
|
3
3
|
import { parseHandshakeFrame, parseTokenFrame, REALTIME_PROTOCOL_VERSION, REALTIME_SSE_HANDSHAKE_EVENT, REALTIME_SSE_TOKEN_EVENT, } from "../realtime-protocol.js";
|
|
4
|
+
import { addSurfaceVisibilityListener, isHostSurfaceHidden, isSurfaceHidden, } from "../shared/surface-visibility.js";
|
|
4
5
|
import { agentNativePath } from "./api-path.js";
|
|
5
6
|
import { getBrowserTabId } from "./browser-tab-id.js";
|
|
6
7
|
import { ensureEmbedAuthFetchInterceptor, isEmbedAuthActive, } from "./embed-auth.js";
|
|
@@ -103,7 +104,7 @@ function getPollAbortMs(interval) {
|
|
|
103
104
|
return Math.max(POLL_ABORT_MIN_MS, interval * 4);
|
|
104
105
|
}
|
|
105
106
|
function isDocumentHidden() {
|
|
106
|
-
return (
|
|
107
|
+
return isSurfaceHidden();
|
|
107
108
|
}
|
|
108
109
|
function resolveSseUrl(sseUrl) {
|
|
109
110
|
if (sseUrl === false)
|
|
@@ -269,6 +270,7 @@ class SyncTransport {
|
|
|
269
270
|
subscribers = new Map();
|
|
270
271
|
cursorRef = { ...INITIAL_SYNC_CURSOR };
|
|
271
272
|
timer = null;
|
|
273
|
+
removeVisibilityListener;
|
|
272
274
|
stopped = false;
|
|
273
275
|
inFlight = false;
|
|
274
276
|
eventSource = null;
|
|
@@ -470,6 +472,17 @@ class SyncTransport {
|
|
|
470
472
|
// -------------------------------------------------------------------------
|
|
471
473
|
// Derived settings (aggregate over active subscribers)
|
|
472
474
|
// -------------------------------------------------------------------------
|
|
475
|
+
/**
|
|
476
|
+
* Whether this transport must do nothing at all right now. A host that has
|
|
477
|
+
* stashed the surface off screen is a stronger statement than a backgrounded
|
|
478
|
+
* browser tab, so it pauses regardless of `pauseWhenHidden` — an embedder
|
|
479
|
+
* only sets it for a surface the user genuinely cannot see.
|
|
480
|
+
*/
|
|
481
|
+
shouldStayIdle() {
|
|
482
|
+
if (isHostSurfaceHidden())
|
|
483
|
+
return true;
|
|
484
|
+
return this.effectivePauseWhenHidden && isDocumentHidden();
|
|
485
|
+
}
|
|
473
486
|
get effectivePauseWhenHidden() {
|
|
474
487
|
// Pause only if every subscriber has opted in.
|
|
475
488
|
for (const sub of this.subscribers.values()) {
|
|
@@ -550,7 +563,7 @@ class SyncTransport {
|
|
|
550
563
|
schedulePoll() {
|
|
551
564
|
if (this.stopped)
|
|
552
565
|
return;
|
|
553
|
-
if (this.
|
|
566
|
+
if (this.shouldStayIdle())
|
|
554
567
|
return;
|
|
555
568
|
if (this.timer)
|
|
556
569
|
clearTimeout(this.timer);
|
|
@@ -743,7 +756,7 @@ class SyncTransport {
|
|
|
743
756
|
if (this.stopped ||
|
|
744
757
|
this.eventSource ||
|
|
745
758
|
typeof EventSource === "undefined" ||
|
|
746
|
-
|
|
759
|
+
this.shouldStayIdle()) {
|
|
747
760
|
return;
|
|
748
761
|
}
|
|
749
762
|
// One tab per origin holds the stream; the rest follow it over
|
|
@@ -896,6 +909,10 @@ class SyncTransport {
|
|
|
896
909
|
async poll() {
|
|
897
910
|
if (this.stopped || this.inFlight)
|
|
898
911
|
return;
|
|
912
|
+
// Re-checked here, not only at the schedule sites: whatever path
|
|
913
|
+
// reached poll(), a host-hidden surface must not issue a request.
|
|
914
|
+
if (this.shouldStayIdle())
|
|
915
|
+
return;
|
|
899
916
|
this.inFlight = true;
|
|
900
917
|
try {
|
|
901
918
|
if (this.mode === "hosted" && this.gateway && !this.token) {
|
|
@@ -947,7 +964,7 @@ class SyncTransport {
|
|
|
947
964
|
}
|
|
948
965
|
}
|
|
949
966
|
pollNow() {
|
|
950
|
-
if (this.
|
|
967
|
+
if (this.shouldStayIdle())
|
|
951
968
|
return;
|
|
952
969
|
if (this.authFailureDelayMs() > 0) {
|
|
953
970
|
this.schedulePoll();
|
|
@@ -961,11 +978,11 @@ class SyncTransport {
|
|
|
961
978
|
void this.poll();
|
|
962
979
|
}
|
|
963
980
|
handleVisibilityChange = () => {
|
|
964
|
-
if (
|
|
981
|
+
if (!isSurfaceHidden()) {
|
|
965
982
|
this.connectEvents();
|
|
966
983
|
this.pollNow();
|
|
967
984
|
}
|
|
968
|
-
else if (this.
|
|
985
|
+
else if (this.shouldStayIdle()) {
|
|
969
986
|
this.closeEvents();
|
|
970
987
|
// A hidden leader stops streaming, so it must not keep holding the
|
|
971
988
|
// origin's stream slot — that would leave every visible tab following a
|
|
@@ -1030,13 +1047,13 @@ class SyncTransport {
|
|
|
1030
1047
|
// already mounts useDbSync, so this needs zero per-template wiring.
|
|
1031
1048
|
ensureEmbedAuthFetchInterceptor();
|
|
1032
1049
|
ensureDemoModeFetchInterceptor();
|
|
1033
|
-
if (!this.
|
|
1050
|
+
if (!this.shouldStayIdle()) {
|
|
1034
1051
|
this.connectEvents();
|
|
1035
1052
|
void this.poll();
|
|
1036
1053
|
}
|
|
1037
1054
|
window.addEventListener("focus", this.handleFocus);
|
|
1038
1055
|
window.addEventListener("agentNative.chatRunning", this.handleChatRunning);
|
|
1039
|
-
|
|
1056
|
+
this.removeVisibilityListener = addSurfaceVisibilityListener(this.handleVisibilityChange);
|
|
1040
1057
|
}
|
|
1041
1058
|
teardown() {
|
|
1042
1059
|
this.stopped = true;
|
|
@@ -1060,7 +1077,8 @@ class SyncTransport {
|
|
|
1060
1077
|
}
|
|
1061
1078
|
window.removeEventListener("focus", this.handleFocus);
|
|
1062
1079
|
window.removeEventListener("agentNative.chatRunning", this.handleChatRunning);
|
|
1063
|
-
|
|
1080
|
+
this.removeVisibilityListener?.();
|
|
1081
|
+
this.removeVisibilityListener = undefined;
|
|
1064
1082
|
}
|
|
1065
1083
|
}
|
|
1066
1084
|
/**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE: "agent-native:workspace-app-route";
|
|
2
|
+
export interface AgentNativeWorkspaceAppRouteMessage {
|
|
3
|
+
type: typeof AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE;
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Report an app-local route to its immediate embedding host. The host checks
|
|
8
|
+
* the iframe source and origin before applying the route to its own URL.
|
|
9
|
+
*/
|
|
10
|
+
export declare function postAgentNativeWorkspaceAppRoute(path: string): boolean;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE = "agent-native:workspace-app-route";
|
|
2
|
+
function normalizeWorkspaceAppRoute(path) {
|
|
3
|
+
if (typeof path !== "string" ||
|
|
4
|
+
!path.startsWith("/") ||
|
|
5
|
+
path.startsWith("//")) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
if (/[\u0000-\u001f\u007f]/.test(path))
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(path, "http://agent-native.invalid");
|
|
12
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// coercion-ok: malformed route input is not reported to the host.
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Report an app-local route to its immediate embedding host. The host checks
|
|
21
|
+
* the iframe source and origin before applying the route to its own URL.
|
|
22
|
+
*/
|
|
23
|
+
export function postAgentNativeWorkspaceAppRoute(path) {
|
|
24
|
+
if (typeof window === "undefined")
|
|
25
|
+
return false;
|
|
26
|
+
const parentWindow = window.parent;
|
|
27
|
+
if (!parentWindow || parentWindow === window)
|
|
28
|
+
return false;
|
|
29
|
+
const normalizedPath = normalizeWorkspaceAppRoute(path);
|
|
30
|
+
if (!normalizedPath)
|
|
31
|
+
return false;
|
|
32
|
+
const message = {
|
|
33
|
+
type: AGENT_NATIVE_WORKSPACE_APP_ROUTE_MESSAGE_TYPE,
|
|
34
|
+
path: normalizedPath,
|
|
35
|
+
};
|
|
36
|
+
parentWindow.postMessage(message, "*");
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
|
|
14
14
|
*/
|
|
15
15
|
export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
ok?: undefined;
|
|
17
16
|
error: string;
|
|
17
|
+
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|