@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
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from "@agent-native/toolkit/ui/button";
|
|
3
3
|
import { Popover, PopoverContent, PopoverTrigger, } from "@agent-native/toolkit/ui/popover";
|
|
4
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
5
|
-
import { BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
4
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
|
+
import { BETA_FORCE_QUERY_PARAM, BETA_FORCE_SESSION_STORAGE_KEY, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
6
6
|
import { trackEvent } from "./analytics.js";
|
|
7
7
|
import { injectedAgentNativeConfig } from "./app-config.js";
|
|
8
8
|
import { useSession } from "./use-session.js";
|
|
9
9
|
import { cn } from "./utils.js";
|
|
10
|
-
export { BETA_OPT_OUT_DURATION_MS, BETA_OPT_OUT_QUERY_PARAM, BETA_OPT_OUT_STORAGE_KEY, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
10
|
+
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, buildEnvironmentOptOutUrl, buildEnvironmentUrl, resolveEnvironmentTargets, } from "../shared/environment-lanes.js";
|
|
11
11
|
export function isBuilderIoEmployee(email) {
|
|
12
12
|
return email?.trim().toLowerCase().endsWith("@builder.io") ?? false;
|
|
13
13
|
}
|
|
@@ -50,6 +50,29 @@ function readBetaOptOutUntil(now = Date.now()) {
|
|
|
50
50
|
}
|
|
51
51
|
return null;
|
|
52
52
|
}
|
|
53
|
+
function rememberForcedProductionSession(sourceHref) {
|
|
54
|
+
let forcedByQuery = false;
|
|
55
|
+
try {
|
|
56
|
+
forcedByQuery =
|
|
57
|
+
new URL(sourceHref).searchParams.get(BETA_FORCE_QUERY_PARAM) === "true";
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// coercion-ok: the browser supplied an invalid location.
|
|
61
|
+
}
|
|
62
|
+
if (typeof window === "undefined")
|
|
63
|
+
return forcedByQuery;
|
|
64
|
+
try {
|
|
65
|
+
if (forcedByQuery) {
|
|
66
|
+
window.sessionStorage.setItem(BETA_FORCE_SESSION_STORAGE_KEY, "1");
|
|
67
|
+
}
|
|
68
|
+
return (forcedByQuery ||
|
|
69
|
+
window.sessionStorage.getItem(BETA_FORCE_SESSION_STORAGE_KEY) === "1");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// coercion-ok: session storage is optional; the current URL remains authoritative.
|
|
73
|
+
return forcedByQuery;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
53
76
|
function consumeBetaOptOutQueryParam(sourceHref, now = Date.now()) {
|
|
54
77
|
let target;
|
|
55
78
|
try {
|
|
@@ -81,8 +104,11 @@ function EnvironmentLink({ label, href }) {
|
|
|
81
104
|
return (_jsx(Button, { asChild: true, className: "w-full justify-center", size: "sm", variant: "outline", children: _jsx("a", { href: href, children: label }) }));
|
|
82
105
|
}
|
|
83
106
|
function EnvironmentBadgeContent({ environment, targets, }) {
|
|
107
|
+
const [isHidden, setIsHidden] = useState(false);
|
|
84
108
|
if (typeof window === "undefined")
|
|
85
109
|
return null;
|
|
110
|
+
if (isHidden)
|
|
111
|
+
return null;
|
|
86
112
|
const currentHref = window.location.href;
|
|
87
113
|
const betaHref = buildEnvironmentUrl(currentHref, targets.betaHost);
|
|
88
114
|
const productionHref = buildEnvironmentOptOutUrl(currentHref, targets.productionHost);
|
|
@@ -94,7 +120,7 @@ function EnvironmentBadgeContent({ environment, targets, }) {
|
|
|
94
120
|
: "You're on Agent Native Production";
|
|
95
121
|
return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { "aria-label": `Open ${title.toLowerCase()} switcher`, className: cn(environmentBadgePlacementClasses, environment === "beta"
|
|
96
122
|
? "border-primary/80"
|
|
97
|
-
: "border-border/80 bg-background/95 text-foreground"), size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "start", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }),
|
|
123
|
+
: "border-border/80 bg-background/95 text-foreground"), size: "sm", variant: environment === "beta" ? "default" : "outline", children: label }) }), _jsxs(PopoverContent, { align: "start", className: "w-[280px] p-5", side: "top", sideOffset: 8, children: [_jsx("div", { className: "mb-1 text-sm font-semibold leading-5", children: title }), _jsx("div", { className: "mb-4 text-sm text-muted-foreground", children: "Choose where you want to continue." }), _jsxs("div", { className: "grid gap-2", children: [environment === "beta" ? (_jsx(EnvironmentLink, { href: productionHref, label: "Switch to production" })) : (_jsx(EnvironmentLink, { href: betaHref, label: "Go to beta" })), _jsx(Button, { className: "mt-2 -mb-2 w-full justify-center text-muted-foreground", onClick: () => setIsHidden(true), size: "sm", type: "button", variant: "ghost", children: "Hide badge" })] })] })] }));
|
|
98
124
|
}
|
|
99
125
|
function LocalEnvironmentBadge() {
|
|
100
126
|
return (_jsx("div", { "aria-label": "Local development environment", className: cn(environmentBadgePlacementClasses, "inline-flex items-center justify-center border border-border/80 bg-background/95 text-foreground"), role: "status", children: "dev" }));
|
|
@@ -107,6 +133,10 @@ function ProductionEnvironmentBadge({ targets, }) {
|
|
|
107
133
|
isBuilderIoEmployee(session?.email);
|
|
108
134
|
const didAutoRedirect = useRef(false);
|
|
109
135
|
useEffect(() => {
|
|
136
|
+
if (typeof window === "undefined")
|
|
137
|
+
return;
|
|
138
|
+
if (rememberForcedProductionSession(window.location.href))
|
|
139
|
+
return;
|
|
110
140
|
if (!isEligible || didAutoRedirect.current) {
|
|
111
141
|
return;
|
|
112
142
|
}
|
|
@@ -140,11 +170,16 @@ function ProductionEnvironmentBadge({ targets, }) {
|
|
|
140
170
|
* lane for authenticated staff.
|
|
141
171
|
*/
|
|
142
172
|
export function EnvironmentBadge({ showProduction = true, } = {}) {
|
|
173
|
+
const [hydrated, setHydrated] = useState(false);
|
|
143
174
|
const config = useMemo(injectedAgentNativeConfig, []);
|
|
144
175
|
const hostname = typeof window === "undefined" ? undefined : window.location.hostname;
|
|
145
176
|
const environment = resolveEnvironmentChannel(config, hostname);
|
|
146
177
|
const targets = resolveEnvironmentTargets(hostname);
|
|
147
|
-
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
setHydrated(true);
|
|
180
|
+
}, []);
|
|
181
|
+
if (!hydrated ||
|
|
182
|
+
typeof window === "undefined" ||
|
|
148
183
|
window.parent !== window ||
|
|
149
184
|
!environment) {
|
|
150
185
|
return null;
|
|
@@ -71,4 +71,4 @@ export type MultiTabAssistantChatProps = Omit<AssistantChatProps, "tabId" | "thr
|
|
|
71
71
|
/** Cadence for hydrating agent-team sub-agent tab status. Default: 3000. */
|
|
72
72
|
agentTeamPollMs?: number;
|
|
73
73
|
};
|
|
74
|
-
export declare function MultiTabAssistantChat({ showTabBar, renderHeader, renderOverlay, contentHidden, apiUrl, storageKey, restoreActiveThread, browserTabId, threadUrlSync, scope, isolateHistoryByScope, agentTeamPollMs, ...props }: MultiTabAssistantChatProps): React.JSX.Element;
|
|
74
|
+
export declare function MultiTabAssistantChat({ showTabBar, renderHeader, renderOverlay, contentHidden, apiUrl, storageKey, restoreActiveThread, browserTabId, threadUrlSync, scope, isolateHistoryByScope, agentTeamPollMs, availableModels: hostAvailableModels, modelListLoading: hostModelListLoading, onModelChange: hostOnModelChange, ...props }: MultiTabAssistantChatProps): React.JSX.Element;
|
|
@@ -17,7 +17,7 @@ import { DEFAULT_LOCALE, useOptionalLocale, useT } from "./i18n.js";
|
|
|
17
17
|
import { RunStuckBanner } from "./RunStuckBanner.js";
|
|
18
18
|
import { callAction } from "./use-action.js";
|
|
19
19
|
import { useChangeVersion } from "./use-change-version.js";
|
|
20
|
-
import { CHAT_MODEL_SELECTION_CHANGED_EVENT } from "./use-chat-models.js";
|
|
20
|
+
import { CHAT_MODEL_SELECTION_CHANGED_EVENT, chatModelSelectionStorageKey, } from "./use-chat-models.js";
|
|
21
21
|
import { useChatThreads, } from "./use-chat-threads.js";
|
|
22
22
|
import { usePollLoop } from "./use-poll-loop.js";
|
|
23
23
|
import { cn } from "./utils.js";
|
|
@@ -43,7 +43,6 @@ function deliverPendingSend(ref, send) {
|
|
|
43
43
|
ref.sendMessage(send.message, send.images);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
const MODEL_SELECTION_STORAGE_KEY = "agent-native:chat-models:selection";
|
|
47
46
|
function readStoredModelSelection(key) {
|
|
48
47
|
if (typeof window === "undefined")
|
|
49
48
|
return undefined;
|
|
@@ -402,7 +401,7 @@ function runToAgentTeamTabInfo(run) {
|
|
|
402
401
|
status: run.status ?? "unknown",
|
|
403
402
|
};
|
|
404
403
|
}
|
|
405
|
-
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, threadUrlSync = false, scope = null, isolateHistoryByScope = false, agentTeamPollMs = DEFAULT_AGENT_TEAM_POLL_MS, ...props }) {
|
|
404
|
+
export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderOverlay, contentHidden = false, apiUrl = agentNativePath("/_agent-native/agent-chat"), storageKey, restoreActiveThread = true, browserTabId, threadUrlSync = false, scope = null, isolateHistoryByScope = false, agentTeamPollMs = DEFAULT_AGENT_TEAM_POLL_MS, availableModels: hostAvailableModels, modelListLoading: hostModelListLoading, onModelChange: hostOnModelChange, ...props }) {
|
|
406
405
|
const translate = useT();
|
|
407
406
|
const contextNamespace = scope
|
|
408
407
|
? scope.contextKey?.trim() || `scope:${scope.type}:${scope.id}`
|
|
@@ -528,7 +527,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
528
527
|
}, [switchThreadState, writeThreadUrl]);
|
|
529
528
|
// Namespace all localStorage keys by storageKey when provided (for per-app isolation in frame)
|
|
530
529
|
const keyPrefix = storageKey ? `:${storageKey}` : "";
|
|
531
|
-
const modelSelectionKey =
|
|
530
|
+
const modelSelectionKey = chatModelSelectionStorageKey(storageKey);
|
|
532
531
|
// Track which tabs have been focused at least once (lazy mount for sub-agent tabs)
|
|
533
532
|
const mountedTabsRef = useRef(new Set());
|
|
534
533
|
const activeThreadIdRef = useRef(activeThreadId);
|
|
@@ -557,8 +556,16 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
557
556
|
setPageOverlayScrolled(target.scrollTop > 1);
|
|
558
557
|
}, [renderOverlay]);
|
|
559
558
|
// ─── Model state ─────────────────────────────────────────────────────────
|
|
560
|
-
|
|
561
|
-
|
|
559
|
+
// A host that supplies its own catalog owns the whole picker: the server
|
|
560
|
+
// catalog must not be discovered or merged, or a host with no engine of its
|
|
561
|
+
// own silently gets this app's models instead.
|
|
562
|
+
const hostManagedModels = hostAvailableModels !== undefined;
|
|
563
|
+
const [discoveredModels, setDiscoveredModels] = useState([]);
|
|
564
|
+
const availableModels = hostAvailableModels ?? discoveredModels;
|
|
565
|
+
const [discoveredModelsLoading, setModelListLoading] = useState(true);
|
|
566
|
+
const modelListLoading = hostManagedModels
|
|
567
|
+
? (hostModelListLoading ?? false)
|
|
568
|
+
: discoveredModelsLoading;
|
|
562
569
|
const [defaultModel, setDefaultModel] = useState(DEFAULT_MODEL);
|
|
563
570
|
const threadModelRef = useRef(new Map());
|
|
564
571
|
const [persistedModelSelection, setPersistedModelSelection] = useState(() => readStoredModelSelection(modelSelectionKey));
|
|
@@ -666,6 +673,14 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
666
673
|
persistModelSelection,
|
|
667
674
|
props.selectedAgent,
|
|
668
675
|
]);
|
|
676
|
+
// A host that owns the model list still needs the internal selection updated:
|
|
677
|
+
// `selectedModel`/`selectedEngine` render from it and submitted turns read it,
|
|
678
|
+
// so routing a pick only to the host snaps the picker back to the previous
|
|
679
|
+
// model and sends that one.
|
|
680
|
+
const handleModelChangeWithHost = useCallback((model, engine) => {
|
|
681
|
+
handleModelChange(model, engine);
|
|
682
|
+
hostOnModelChange?.(model, engine);
|
|
683
|
+
}, [handleModelChange, hostOnModelChange]);
|
|
669
684
|
const handleEffortChange = useCallback((effort) => {
|
|
670
685
|
const threadId = activeThreadIdRef.current;
|
|
671
686
|
if (!threadId)
|
|
@@ -689,15 +704,19 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
689
704
|
resolveThreadModelSelection,
|
|
690
705
|
]);
|
|
691
706
|
useEffect(() => {
|
|
692
|
-
const preferredAgentModel = props.selectedAgent
|
|
693
|
-
? resolvePreferredAgentModel(props.selectedAgent, availableModels)
|
|
694
|
-
: undefined;
|
|
695
|
-
if (!preferredAgentModel)
|
|
696
|
-
return;
|
|
697
707
|
const threadId = activeThreadIdRef.current;
|
|
698
708
|
const current = threadId
|
|
699
709
|
? resolveThreadModelSelection(threadId)
|
|
700
710
|
: persistedModelSelection;
|
|
711
|
+
// Only correct a selection the agent cannot run. This effect re-runs on
|
|
712
|
+
// every selection change, so an unconditional rewrite pins the picker and
|
|
713
|
+
// each later user pick snaps straight back.
|
|
714
|
+
const preferredAgentModel = isClaudeCodeAgentId(props.selectedAgent) &&
|
|
715
|
+
isLunaModel(current?.model ?? "")
|
|
716
|
+
? resolvePreferredAgentModel(props.selectedAgent, availableModels)
|
|
717
|
+
: undefined;
|
|
718
|
+
if (!preferredAgentModel)
|
|
719
|
+
return;
|
|
701
720
|
if (current?.model === preferredAgentModel.model &&
|
|
702
721
|
current.engine === preferredAgentModel.engine) {
|
|
703
722
|
return;
|
|
@@ -721,6 +740,8 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
721
740
|
resolveThreadModelSelection,
|
|
722
741
|
]);
|
|
723
742
|
const refreshEngines = useCallback(() => {
|
|
743
|
+
if (hostManagedModels)
|
|
744
|
+
return;
|
|
724
745
|
setModelListLoading(true);
|
|
725
746
|
Promise.all([
|
|
726
747
|
callAction("manage-agent-engine", { action: "list" }).catch(() => null),
|
|
@@ -751,12 +772,12 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
751
772
|
currentEngineName,
|
|
752
773
|
currentModel,
|
|
753
774
|
});
|
|
754
|
-
|
|
775
|
+
setDiscoveredModels(groups);
|
|
755
776
|
setDefaultModel(currentModel ?? DEFAULT_MODEL);
|
|
756
777
|
})
|
|
757
778
|
.catch(() => { })
|
|
758
779
|
.finally(() => setModelListLoading(false));
|
|
759
|
-
}, []);
|
|
780
|
+
}, [hostManagedModels]);
|
|
760
781
|
useEffect(() => {
|
|
761
782
|
refreshEngines();
|
|
762
783
|
window.addEventListener("agent-engine:configured-changed", refreshEngines);
|
|
@@ -1976,7 +1997,7 @@ export function MultiTabAssistantChat({ showTabBar = true, renderHeader, renderO
|
|
|
1976
1997
|
? clearActiveTab
|
|
1977
1998
|
: undefined, isThreadStateLoading: isLoading, onMessageCountChange: (count) => setMessageCounts((prev) => prev[tabId] === count
|
|
1978
1999
|
? prev
|
|
1979
|
-
: { ...prev, [tabId]: count }), onSaveThread: handleSaveThread, onGenerateTitle: handleGenerateTitle, onSlashCommand: handleSlashCommand, selectedModel: modelSelection?.model, selectedEngine: modelSelection?.engine, selectedEffort: modelSelection?.effort ?? DEFAULT_REASONING_EFFORT, composerSlot: props.composerSlot, defaultModel: defaultModel, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange:
|
|
2000
|
+
: { ...prev, [tabId]: count }), onSaveThread: handleSaveThread, onGenerateTitle: handleGenerateTitle, onSlashCommand: handleSlashCommand, selectedModel: modelSelection?.model, selectedEngine: modelSelection?.engine, selectedEffort: modelSelection?.effort ?? DEFAULT_REASONING_EFFORT, composerSlot: props.composerSlot, defaultModel: defaultModel, availableModels: availableModels, modelListLoading: modelListLoading, onModelChange: handleModelChangeWithHost, onEffortChange: handleEffortChange, onForkChat: () => handleForkChat(tabId),
|
|
1980
2001
|
// Sub-agent tabs are read-only: sending a new message from the
|
|
1981
2002
|
// sub-agent tab would start a fresh run on that thread and kill
|
|
1982
2003
|
// the in-flight team chunk. Disable the composer and show a
|
|
@@ -11,7 +11,7 @@ export { buildRepositoryFromCodeAgentTranscript, type BuildRepositoryFromCodeAge
|
|
|
11
11
|
export { compareCodeAgentTranscriptEvents, getCodeAgentTranscriptSeq, isCodeAgentRunActive, mergeCodeAgentTranscriptEvents, type CodeAgentRunStateLike, type CodeAgentTranscriptOrderEvent, } from "../../code-agents/transcript-order.js";
|
|
12
12
|
export { CREDENTIAL_GAP_SIGNAL, isCredentialGapCodeAgentEvent, } from "../../code-agents/transcript-normalizer.js";
|
|
13
13
|
export { useSendToAgentChat } from "../use-send-to-agent-chat.js";
|
|
14
|
-
export { useChatModels, type UseChatModelsResult, type EngineModelGroup, } from "../use-chat-models.js";
|
|
14
|
+
export { chatModelSelectionStorageKey, useChatModels, type UseChatModelsResult, type EngineModelGroup, } from "../use-chat-models.js";
|
|
15
15
|
export { CodeRequiredDialog, type CodeRequiredDialogProps, } from "../components/CodeRequiredDialog.js";
|
|
16
16
|
export { ChatFirstAgentActivityPanel, type ChatFirstAgentActivityPanelProps, } from "../chat-first-agent-activity.js";
|
|
17
17
|
export { ChatFirstSurfacePanelToggle } from "../chat-first-surface-panel-toggle.js";
|
|
@@ -11,7 +11,7 @@ export { buildRepositoryFromCodeAgentTranscript, } from "../../agent/thread-data
|
|
|
11
11
|
export { compareCodeAgentTranscriptEvents, getCodeAgentTranscriptSeq, isCodeAgentRunActive, mergeCodeAgentTranscriptEvents, } from "../../code-agents/transcript-order.js";
|
|
12
12
|
export { CREDENTIAL_GAP_SIGNAL, isCredentialGapCodeAgentEvent, } from "../../code-agents/transcript-normalizer.js";
|
|
13
13
|
export { useSendToAgentChat } from "../use-send-to-agent-chat.js";
|
|
14
|
-
export { useChatModels, } from "../use-chat-models.js";
|
|
14
|
+
export { chatModelSelectionStorageKey, useChatModels, } from "../use-chat-models.js";
|
|
15
15
|
export { CodeRequiredDialog, } from "../components/CodeRequiredDialog.js";
|
|
16
16
|
export { ChatFirstAgentActivityPanel, } from "../chat-first-agent-activity.js";
|
|
17
17
|
export { ChatFirstSurfacePanelToggle } from "../chat-first-surface-panel-toggle.js";
|
|
@@ -57,7 +57,8 @@ export type ManageJobInput = {
|
|
|
57
57
|
};
|
|
58
58
|
export type ManageAutomationInput = ManageJobInput;
|
|
59
59
|
export interface RunAutomationNowInput {
|
|
60
|
-
name
|
|
60
|
+
name?: string;
|
|
61
|
+
path?: string;
|
|
61
62
|
scope: "personal" | "organization";
|
|
62
63
|
}
|
|
63
64
|
export interface RunAutomationNowResult {
|
|
@@ -87,12 +87,10 @@ export function useRunAutomationNow() {
|
|
|
87
87
|
return useActionMutation("run-automation-now", {
|
|
88
88
|
onSuccess: (_result, variables) => {
|
|
89
89
|
const scope = variables.scope === "organization" ? "organization" : "personal";
|
|
90
|
+
const name = variables.name ??
|
|
91
|
+
variables.path?.replace(/^jobs\//, "").replace(/\.md$/, "");
|
|
90
92
|
queryClient.invalidateQueries({
|
|
91
|
-
queryKey: [
|
|
92
|
-
"action",
|
|
93
|
-
"list-automation-runs",
|
|
94
|
-
{ scope, name: variables.name },
|
|
95
|
-
],
|
|
93
|
+
queryKey: ["action", "list-automation-runs", { scope, name }],
|
|
96
94
|
});
|
|
97
95
|
queryClient.invalidateQueries({
|
|
98
96
|
queryKey: ["action", "list-automations", { scope }],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, } from "../shared/agent-sidebar-url.js";
|
|
1
|
+
import { AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_CLOSED, AGENT_SIDEBAR_QUERY_VALUE_OPEN, } from "../shared/agent-sidebar-url.js";
|
|
2
2
|
import { hasChatThreadDeepLink } from "./chat-thread-url.js";
|
|
3
3
|
export { hasChatThreadDeepLink } from "./chat-thread-url.js";
|
|
4
4
|
export const SIDEBAR_OPEN_KEY = "agent-native-sidebar-open";
|
|
@@ -62,6 +62,8 @@ export function getAgentSidebarUrlOpenOverride() {
|
|
|
62
62
|
const value = url.searchParams.get(AGENT_SIDEBAR_QUERY_PARAM);
|
|
63
63
|
if (value === AGENT_SIDEBAR_QUERY_VALUE_CLOSED)
|
|
64
64
|
return false;
|
|
65
|
+
if (value === AGENT_SIDEBAR_QUERY_VALUE_OPEN)
|
|
66
|
+
return true;
|
|
65
67
|
}
|
|
66
68
|
catch { }
|
|
67
69
|
return null;
|
|
@@ -273,4 +273,9 @@ export const codeTabsBlock = defineBlock({
|
|
|
273
273
|
label: "Code tabs",
|
|
274
274
|
icon: IconCode,
|
|
275
275
|
description: "A vertical file tab rail of syntax-highlighted code snippets, one tab per file with an optional language and caption.",
|
|
276
|
+
// `tabs` has schema min(1), so a fresh insert needs one starter tab — same
|
|
277
|
+
// shape `addTab` mints for a second tab.
|
|
278
|
+
empty: () => ({
|
|
279
|
+
tabs: [{ id: newCodeTabId(), label: "file-1.ts", code: "" }],
|
|
280
|
+
}),
|
|
276
281
|
});
|
|
@@ -131,4 +131,5 @@ export const codeBlock = defineBlock({
|
|
|
131
131
|
label: "Code",
|
|
132
132
|
icon: IconCode,
|
|
133
133
|
description: "A single syntax-highlighted code snippet, Notion-style: one border, a hover language switcher + copy, and collapse-to-N lines. Put several in a `tabs` block for a file rail.",
|
|
134
|
+
empty: () => ({ code: "" }),
|
|
134
135
|
});
|
|
@@ -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);
|
|
@@ -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
|
+
}
|
|
@@ -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"],
|
|
@@ -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
|