@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
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -23,7 +23,10 @@ export function meta() {
|
|
|
23
23
|
|
|
24
24
|
export default function SettingsRoute() {
|
|
25
25
|
const t = useT();
|
|
26
|
-
|
|
26
|
+
// /extensions redirects here and navigation.view supports "extensions"
|
|
27
|
+
// (see use-navigation-state.ts), so the settings tab must exist too —
|
|
28
|
+
// otherwise /settings/extensions silently falls back to General.
|
|
29
|
+
const agentSettingsTabs = useAgentSettingsTabs({ extensionTools: true });
|
|
27
30
|
useSetPageTitle(t("settings.title"));
|
|
28
31
|
|
|
29
32
|
const generalSearchEntries = useMemo<SettingsSearchEntry[]>(
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type RouteConfig } from "@react-router/dev/routes";
|
|
2
2
|
import { flatRoutes } from "@react-router/fs-routes";
|
|
3
3
|
|
|
4
|
-
export default flatRoutes(
|
|
4
|
+
export default flatRoutes({
|
|
5
|
+
ignoredRouteFiles: ["**/*.test.{ts,tsx}", "**/*.spec.{ts,tsx}"],
|
|
6
|
+
}) satisfies RouteConfig;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[build]
|
|
2
2
|
ignore = "node ./scripts/netlify-ignore-build.mjs plan"
|
|
3
|
-
command = "export DATABASE_URL=${NETLIFY_DATABASE_URL:-$DATABASE_URL} && pnpm install && NITRO_PRESET=netlify pnpm --filter plan build && if [ \"${CONTEXT:-}\" = \"production\" ] || [ \"${AGENT_NATIVE_RUN_RELEASE_MIGRATIONS:-}\" = \"1\" ]; then pnpm --filter plan migrate:production; fi"
|
|
3
|
+
command = "if [ \"${agentNativePrebuiltBuild:-}\" = \"true\" ]; then export DATABASE_URL=\"${agentNativePrebuiltDatabaseUrl:?}\" BETTER_AUTH_SECRET=\"${agentNativePrebuiltAuthSecret:?}\"; else export DATABASE_URL=${NETLIFY_DATABASE_URL:-$DATABASE_URL}; fi && pnpm install && NITRO_PRESET=netlify pnpm --filter plan build && if { [ \"${CONTEXT:-}\" = \"production\" ] || [ \"${AGENT_NATIVE_RUN_RELEASE_MIGRATIONS:-}\" = \"1\" ]; } && [ \"${agentNativePrebuiltBuild:-}\" != \"true\" ]; then pnpm --filter plan migrate:production; fi"
|
|
4
4
|
publish = "templates/plan/dist"
|
|
5
5
|
functions = "templates/plan/.netlify/functions-internal"
|
|
6
6
|
|
|
@@ -19,10 +19,17 @@ data, and generated extension/app content may mention credential **names** such
|
|
|
19
19
|
as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
|
|
20
20
|
signing secrets, OAuth refresh tokens, or private Builder/customer data.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
`${keys.NAME}` substitution.
|
|
25
|
-
|
|
22
|
+
Provider secret values are supplied at runtime through the encrypted
|
|
23
|
+
`app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
|
|
24
|
+
`${keys.NAME}` substitution. Deployment configuration is reserved for
|
|
25
|
+
deploy-level secrets and non-provider configuration. Examples must use obvious
|
|
26
|
+
placeholders such as `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not
|
|
27
|
+
real-looking copied values.
|
|
28
|
+
|
|
29
|
+
Provider credentials and provider account identifiers are workspace data. Use
|
|
30
|
+
standard workspace connections and org/workspace vault scopes; never put them
|
|
31
|
+
in `.env` or deployment environment variables, and never add a provider-specific
|
|
32
|
+
action or startup bootstrap just to write a credential for one organization.
|
|
26
33
|
|
|
27
34
|
## Credential Modeling Preflight
|
|
28
35
|
|
|
@@ -37,6 +37,12 @@ import {
|
|
|
37
37
|
assertHumanReadableDeckTitle,
|
|
38
38
|
repairGeneratedDeckTitle,
|
|
39
39
|
} from "../shared/deck-title.js";
|
|
40
|
+
import { hashSlideContent } from "../shared/slide-fit.js";
|
|
41
|
+
import {
|
|
42
|
+
awaitLayoutFitCheck,
|
|
43
|
+
formatOverflowForTool,
|
|
44
|
+
type SlideFitResult,
|
|
45
|
+
} from "./_await-fit-check.js";
|
|
40
46
|
|
|
41
47
|
// ---------------------------------------------------------------------------
|
|
42
48
|
// Per-deck write lock — same pattern as add-slide.ts so all client and agent
|
|
@@ -850,21 +856,84 @@ export default defineAction({
|
|
|
850
856
|
}
|
|
851
857
|
});
|
|
852
858
|
|
|
859
|
+
// Start the freshness window right after the SQL write and before
|
|
860
|
+
// notifying editors — same ordering as add-slide/update-slide — so a
|
|
861
|
+
// fast render landing before this line isn't discarded as stale.
|
|
862
|
+
const fitSince = Date.now();
|
|
863
|
+
|
|
853
864
|
notifyClients(deckId);
|
|
854
865
|
|
|
855
|
-
|
|
866
|
+
const updatedSlideIds = [
|
|
867
|
+
...new Set(
|
|
868
|
+
operations.flatMap((operation) =>
|
|
869
|
+
operation.op === "patch-slide" || operation.op === "add-slide"
|
|
870
|
+
? [operation.slideId]
|
|
871
|
+
: [],
|
|
872
|
+
),
|
|
873
|
+
),
|
|
874
|
+
];
|
|
875
|
+
|
|
876
|
+
// Only slides whose HTML actually changed can newly overflow — an
|
|
877
|
+
// add-slide always sets content; a patch-slide only when this batch's
|
|
878
|
+
// operation included `fields.content`. Re-check every one of them in
|
|
879
|
+
// parallel: a deck-wide restyle can touch dozens of slides, and polling
|
|
880
|
+
// them one at a time would serialize N fit-check timeouts.
|
|
881
|
+
const contentChangedSlideIds = [
|
|
882
|
+
...new Set(
|
|
883
|
+
operations.flatMap((operation) =>
|
|
884
|
+
operation.op === "add-slide" ||
|
|
885
|
+
(operation.op === "patch-slide" &&
|
|
886
|
+
operation.fields.content !== undefined)
|
|
887
|
+
? [operation.slideId]
|
|
888
|
+
: [],
|
|
889
|
+
),
|
|
890
|
+
),
|
|
891
|
+
];
|
|
892
|
+
const finalSlides: Array<{ id?: unknown; content?: unknown }> =
|
|
893
|
+
Array.isArray(deck.slides) ? deck.slides : [];
|
|
894
|
+
const fitResults: SlideFitResult[] = await Promise.all(
|
|
895
|
+
contentChangedSlideIds.map((slideId) => {
|
|
896
|
+
const slide = finalSlides.find((s) => s.id === slideId);
|
|
897
|
+
return awaitLayoutFitCheck(
|
|
898
|
+
slideId,
|
|
899
|
+
fitSince,
|
|
900
|
+
5000,
|
|
901
|
+
hashSlideContent(
|
|
902
|
+
typeof slide?.content === "string" ? slide.content : "",
|
|
903
|
+
),
|
|
904
|
+
);
|
|
905
|
+
}),
|
|
906
|
+
);
|
|
907
|
+
const overflows = fitResults.filter(
|
|
908
|
+
(fit): fit is Extract<SlideFitResult, { status: "overflows" }> =>
|
|
909
|
+
fit.status === "overflows",
|
|
910
|
+
);
|
|
911
|
+
|
|
912
|
+
const base = {
|
|
856
913
|
ok: true,
|
|
857
914
|
deckId,
|
|
858
915
|
updatedAt: now,
|
|
859
|
-
updatedSlideIds
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
916
|
+
updatedSlideIds,
|
|
917
|
+
};
|
|
918
|
+
|
|
919
|
+
if (overflows.length === 0) return base;
|
|
920
|
+
|
|
921
|
+
return {
|
|
922
|
+
...base,
|
|
923
|
+
layoutOverflow: {
|
|
924
|
+
overflows: overflows.map(({ measurement }) => ({
|
|
925
|
+
slideId: measurement.slideId,
|
|
926
|
+
verticalOverflow: measurement.verticalOverflow,
|
|
927
|
+
horizontalOverflow: measurement.horizontalOverflow ?? 0,
|
|
928
|
+
contentWidth: measurement.contentWidth,
|
|
929
|
+
contentHeight: measurement.contentHeight,
|
|
930
|
+
viewportWidth: measurement.viewportWidth,
|
|
931
|
+
viewportHeight: measurement.viewportHeight,
|
|
932
|
+
})),
|
|
933
|
+
},
|
|
934
|
+
message: overflows
|
|
935
|
+
.map(({ measurement }) => formatOverflowForTool(deckId, measurement))
|
|
936
|
+
.join("\n\n"),
|
|
868
937
|
};
|
|
869
938
|
});
|
|
870
939
|
},
|
|
@@ -297,6 +297,11 @@ export default defineAction({
|
|
|
297
297
|
// structure renders and merges with concurrent typing via the Yjs CRDT.
|
|
298
298
|
let applied = false;
|
|
299
299
|
let notFound = false;
|
|
300
|
+
// Per-edit outcomes for the `edits` batch (e.g. "insert-after:0" means
|
|
301
|
+
// that edit's marker matched nothing and it silently no-opped). Stays
|
|
302
|
+
// undefined for the legacy fullContent/find paths, which have no
|
|
303
|
+
// per-edit breakdown to report.
|
|
304
|
+
let editResults: string[] | undefined;
|
|
300
305
|
const previousContent = String(slide.content ?? "");
|
|
301
306
|
|
|
302
307
|
if (fullContent !== undefined) {
|
|
@@ -327,6 +332,7 @@ export default defineAction({
|
|
|
327
332
|
});
|
|
328
333
|
slide.content = nextContent;
|
|
329
334
|
applied = patched.changed;
|
|
335
|
+
editResults = patched.applied;
|
|
330
336
|
if (!applied) slide.content = previousContent;
|
|
331
337
|
} else if (find !== undefined) {
|
|
332
338
|
const idx = previousContent.indexOf(find);
|
|
@@ -461,6 +467,7 @@ export default defineAction({
|
|
|
461
467
|
return {
|
|
462
468
|
applied,
|
|
463
469
|
notFound,
|
|
470
|
+
editResults,
|
|
464
471
|
slide,
|
|
465
472
|
slideIndex,
|
|
466
473
|
contentHash: hashSlideContent(String(slide.content ?? "")),
|
|
@@ -473,6 +480,7 @@ export default defineAction({
|
|
|
473
480
|
return {
|
|
474
481
|
applied,
|
|
475
482
|
notFound,
|
|
483
|
+
editResults,
|
|
476
484
|
slide,
|
|
477
485
|
slideIndex,
|
|
478
486
|
contentHash: hashSlideContent(String(slide.content ?? "")),
|
|
@@ -486,13 +494,14 @@ export default defineAction({
|
|
|
486
494
|
};
|
|
487
495
|
}
|
|
488
496
|
|
|
489
|
-
const { applied } = rmw;
|
|
497
|
+
const { applied, editResults } = rmw;
|
|
490
498
|
if (!applied) {
|
|
491
499
|
return {
|
|
492
500
|
ok: true,
|
|
493
501
|
deckId,
|
|
494
502
|
slideId,
|
|
495
503
|
applied: false,
|
|
504
|
+
editResults,
|
|
496
505
|
contentHash: rmw.contentHash,
|
|
497
506
|
deepLink: deckDeepLink(deckId),
|
|
498
507
|
};
|
|
@@ -537,6 +546,7 @@ export default defineAction({
|
|
|
537
546
|
deckId,
|
|
538
547
|
slideId,
|
|
539
548
|
applied,
|
|
549
|
+
editResults,
|
|
540
550
|
contentHash: rmw.contentHash,
|
|
541
551
|
deepLink: deckDeepLink(deckId),
|
|
542
552
|
...(rmw.contextMode
|
|
@@ -862,12 +862,22 @@ function MermaidHtmlContent({
|
|
|
862
862
|
html: string;
|
|
863
863
|
mermaidBlocks: string[];
|
|
864
864
|
}) {
|
|
865
|
-
// Split on mermaid placeholders and interleave HTML + MermaidRenderer
|
|
866
|
-
|
|
865
|
+
// Split on mermaid placeholders and interleave HTML + MermaidRenderer. The
|
|
866
|
+
// per-fragment `{ __html }` objects are memoized for the same reason as
|
|
867
|
+
// BlankSlideContent's `dangerousHtml` above: a fresh literal each render
|
|
868
|
+
// re-assigns `innerHTML` and wipes the live contentEditable block.
|
|
869
|
+
const fragments = useMemo(
|
|
870
|
+
() =>
|
|
871
|
+
html
|
|
872
|
+
.split(/(<div data-mermaid-index="\d+"><\/div>)/)
|
|
873
|
+
.map((part) => ({ __html: part })),
|
|
874
|
+
[html],
|
|
875
|
+
);
|
|
867
876
|
|
|
868
877
|
return (
|
|
869
878
|
<>
|
|
870
|
-
{
|
|
879
|
+
{fragments.map((fragment, i) => {
|
|
880
|
+
const part = fragment.__html;
|
|
871
881
|
const match = part.match(/data-mermaid-index="(\d+)"/);
|
|
872
882
|
if (match) {
|
|
873
883
|
const idx = parseInt(match[1], 10);
|
|
@@ -881,7 +891,7 @@ function MermaidHtmlContent({
|
|
|
881
891
|
);
|
|
882
892
|
}
|
|
883
893
|
if (!part.trim()) return null;
|
|
884
|
-
return <div key={i} dangerouslySetInnerHTML={
|
|
894
|
+
return <div key={i} dangerouslySetInnerHTML={fragment} />;
|
|
885
895
|
})}
|
|
886
896
|
</>
|
|
887
897
|
);
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
agentNativePath,
|
|
3
|
-
appBasePath,
|
|
4
|
-
} from "@agent-native/core/client/api-path";
|
|
1
|
+
import { appBasePath } from "@agent-native/core/client/api-path";
|
|
5
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
|
|
6
4
|
import {
|
|
7
5
|
IconDownload,
|
|
8
6
|
IconUpload,
|
|
@@ -193,53 +191,12 @@ export const ExportMenu = forwardRef<ExportMenuHandle, ExportMenuProps>(
|
|
|
193
191
|
}
|
|
194
192
|
};
|
|
195
193
|
|
|
196
|
-
const handleConnectGoogle =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
window.location.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
"return",
|
|
203
|
-
window.location.pathname + window.location.search,
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
const popup =
|
|
207
|
-
target ??
|
|
208
|
-
window.open("", "google-docs-oauth", "popup,width=520,height=720");
|
|
209
|
-
if (!popup) {
|
|
210
|
-
toast.error(t("editorExport.exportFailed"), {
|
|
211
|
-
description: t("editorExport.exportGoogleSlidesError"),
|
|
212
|
-
});
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
const response = await fetch(authUrl.toString(), {
|
|
218
|
-
credentials: "same-origin",
|
|
219
|
-
});
|
|
220
|
-
if (!response.ok) {
|
|
221
|
-
throw new Error(
|
|
222
|
-
await readErrorMessage(
|
|
223
|
-
response,
|
|
224
|
-
t("editorExport.exportGoogleSlidesError"),
|
|
225
|
-
),
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
const data = (await response.json()) as { url?: unknown };
|
|
229
|
-
if (typeof data.url !== "string") {
|
|
230
|
-
throw new Error(t("editorExport.exportGoogleSlidesError"));
|
|
231
|
-
}
|
|
232
|
-
popup.location.href = data.url;
|
|
233
|
-
} catch (err) {
|
|
234
|
-
popup?.close();
|
|
235
|
-
console.error("Google connection failed:", err);
|
|
236
|
-
toast.error(t("editorExport.exportFailed"), {
|
|
237
|
-
description:
|
|
238
|
-
err instanceof Error
|
|
239
|
-
? err.message
|
|
240
|
-
: t("editorExport.exportGoogleSlidesError"),
|
|
241
|
-
});
|
|
242
|
-
}
|
|
194
|
+
const handleConnectGoogle = () => {
|
|
195
|
+
startWorkspaceProviderOAuth("google_drive", {
|
|
196
|
+
appId: "slides",
|
|
197
|
+
returnPath: `${window.location.pathname}${window.location.search}`,
|
|
198
|
+
scope: "user",
|
|
199
|
+
});
|
|
243
200
|
};
|
|
244
201
|
|
|
245
202
|
const handleExportGoogleSlides = async () => {
|
|
@@ -253,7 +210,8 @@ export const ExportMenu = forwardRef<ExportMenuHandle, ExportMenuProps>(
|
|
|
253
210
|
const result = await onExportGoogleSlides();
|
|
254
211
|
if ("requiresConnection" in result && result.requiresConnection) {
|
|
255
212
|
googleSlidesImportTarget.current = null;
|
|
256
|
-
|
|
213
|
+
target?.close();
|
|
214
|
+
handleConnectGoogle();
|
|
257
215
|
return;
|
|
258
216
|
}
|
|
259
217
|
if (result.url !== null) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
2
|
-
import { oauthRedirectUri } from "@agent-native/core/client/host";
|
|
3
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
|
|
4
4
|
import { extractGoogleDocUrls } from "@shared/google-docs";
|
|
5
5
|
import {
|
|
6
6
|
IconAlertCircle,
|
|
@@ -228,60 +228,15 @@ export function GoogleDocImportHint({
|
|
|
228
228
|
return () => onSourceContextChange("");
|
|
229
229
|
}, [onSourceContextChange]);
|
|
230
230
|
|
|
231
|
-
const connect = useCallback(
|
|
231
|
+
const connect = useCallback(() => {
|
|
232
232
|
setConnecting(true);
|
|
233
233
|
setError(null);
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
"
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
const callbackUrl = oauthRedirectUri(
|
|
241
|
-
"/_agent-native/google-docs/callback",
|
|
242
|
-
);
|
|
243
|
-
const authUrl = new URL(endpoint("/_agent-native/google-docs/auth-url"));
|
|
244
|
-
authUrl.searchParams.set("redirect_uri", callbackUrl);
|
|
245
|
-
authUrl.searchParams.set(
|
|
246
|
-
"return",
|
|
247
|
-
window.location.pathname + window.location.search,
|
|
248
|
-
);
|
|
249
|
-
const response = await fetch(authUrl.toString(), {
|
|
250
|
-
credentials: "same-origin",
|
|
251
|
-
});
|
|
252
|
-
const data = await readJson<{
|
|
253
|
-
url?: string;
|
|
254
|
-
error?: string;
|
|
255
|
-
message?: string;
|
|
256
|
-
}>(response);
|
|
257
|
-
if (!response.ok || !data.url) {
|
|
258
|
-
throw new Error(
|
|
259
|
-
errorFromResponse(response, data, "Could not start Google OAuth"),
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
if (!popup) {
|
|
263
|
-
window.location.href = data.url;
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
popup.location.href = data.url;
|
|
267
|
-
|
|
268
|
-
const deadline = Date.now() + 90_000;
|
|
269
|
-
while (Date.now() < deadline && !popup.closed) {
|
|
270
|
-
await new Promise((resolve) => window.setTimeout(resolve, 1200));
|
|
271
|
-
const next = await refreshStatus();
|
|
272
|
-
if (next?.connected) {
|
|
273
|
-
popup.close();
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
await refreshStatus();
|
|
278
|
-
} catch (caught) {
|
|
279
|
-
popup?.close();
|
|
280
|
-
setError(caught instanceof Error ? caught.message : String(caught));
|
|
281
|
-
} finally {
|
|
282
|
-
setConnecting(false);
|
|
283
|
-
}
|
|
284
|
-
}, [refreshStatus]);
|
|
234
|
+
startWorkspaceProviderOAuth("google_drive", {
|
|
235
|
+
appId: "slides",
|
|
236
|
+
returnPath: `${window.location.pathname}${window.location.search}`,
|
|
237
|
+
scope: "user",
|
|
238
|
+
});
|
|
239
|
+
}, []);
|
|
285
240
|
|
|
286
241
|
const chooseDocument = useCallback(async () => {
|
|
287
242
|
setChoosing(true);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
2
|
-
import { oauthRedirectUri } from "@agent-native/core/client/host";
|
|
3
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
+
import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
|
|
4
4
|
import {
|
|
5
5
|
IconBrandGoogleDrive,
|
|
6
6
|
IconLoader2,
|
|
@@ -19,12 +19,6 @@ interface GoogleDocsStatus {
|
|
|
19
19
|
message?: string;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
interface GoogleDocsAuthResponse {
|
|
23
|
-
url?: string;
|
|
24
|
-
error?: string;
|
|
25
|
-
message?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
22
|
type JsonReadResult<T> = { ok: true; data: T } | { ok: false; error: Error };
|
|
29
23
|
|
|
30
24
|
function endpoint(path: string): string {
|
|
@@ -54,13 +48,7 @@ function responseError(
|
|
|
54
48
|
);
|
|
55
49
|
}
|
|
56
50
|
|
|
57
|
-
export
|
|
58
|
-
onConnected?: () => void;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function GoogleDriveConnectionCta({
|
|
62
|
-
onConnected,
|
|
63
|
-
}: GoogleDriveConnectionCtaProps) {
|
|
51
|
+
export function GoogleDriveConnectionCta() {
|
|
64
52
|
const t = useT();
|
|
65
53
|
const [status, setStatus] = useState<GoogleDocsStatus | null>(null);
|
|
66
54
|
const [loading, setLoading] = useState(true);
|
|
@@ -102,70 +90,16 @@ export function GoogleDriveConnectionCta({
|
|
|
102
90
|
|
|
103
91
|
const needsReconnect =
|
|
104
92
|
status?.connected === true && status.googleSlidesUrlImportReady === false;
|
|
105
|
-
const
|
|
106
|
-
status?.connected === true ||
|
|
107
|
-
status?.googleSlidesUrlImportReady !== undefined;
|
|
108
|
-
|
|
109
|
-
const connect = useCallback(async () => {
|
|
93
|
+
const connect = useCallback(() => {
|
|
110
94
|
if (connecting) return;
|
|
111
95
|
setConnecting(true);
|
|
112
96
|
setError(null);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
const authUrl = new URL(endpoint("/_agent-native/google-docs/auth-url"));
|
|
120
|
-
authUrl.searchParams.set(
|
|
121
|
-
"redirect_uri",
|
|
122
|
-
oauthRedirectUri("/_agent-native/google-docs/callback"),
|
|
123
|
-
);
|
|
124
|
-
authUrl.searchParams.set(
|
|
125
|
-
"return",
|
|
126
|
-
window.location.pathname + window.location.search,
|
|
127
|
-
);
|
|
128
|
-
const response = await fetch(authUrl.toString(), {
|
|
129
|
-
credentials: "same-origin",
|
|
130
|
-
});
|
|
131
|
-
const result = await readJson<GoogleDocsAuthResponse>(response);
|
|
132
|
-
if (!result.ok) throw result.error;
|
|
133
|
-
if (!response.ok || !result.data.url) {
|
|
134
|
-
throw responseError(
|
|
135
|
-
response,
|
|
136
|
-
result.data,
|
|
137
|
-
"Could not start Google OAuth",
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
if (!popup) {
|
|
141
|
-
window.location.href = result.data.url;
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
popup.location.href = result.data.url;
|
|
145
|
-
|
|
146
|
-
const deadline = Date.now() + 90_000;
|
|
147
|
-
while (Date.now() < deadline && !popup.closed) {
|
|
148
|
-
await new Promise((resolve) => window.setTimeout(resolve, 1_200));
|
|
149
|
-
const next = await refreshStatus();
|
|
150
|
-
const nextHasUrlImportAccess =
|
|
151
|
-
next?.googleSlidesUrlImportReady ?? !requiresUrlImportAccess;
|
|
152
|
-
if (next?.connected && nextHasUrlImportAccess) {
|
|
153
|
-
popup.close();
|
|
154
|
-
onConnected?.();
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const next = await refreshStatus();
|
|
159
|
-
const nextHasUrlImportAccess =
|
|
160
|
-
next?.googleSlidesUrlImportReady ?? !requiresUrlImportAccess;
|
|
161
|
-
if (next?.connected && nextHasUrlImportAccess) onConnected?.();
|
|
162
|
-
} catch (caught) {
|
|
163
|
-
popup?.close();
|
|
164
|
-
setError(caught instanceof Error ? caught.message : String(caught));
|
|
165
|
-
} finally {
|
|
166
|
-
setConnecting(false);
|
|
167
|
-
}
|
|
168
|
-
}, [connecting, onConnected, refreshStatus, requiresUrlImportAccess]);
|
|
97
|
+
startWorkspaceProviderOAuth("google_drive", {
|
|
98
|
+
appId: "slides",
|
|
99
|
+
returnPath: `${window.location.pathname}${window.location.search}`,
|
|
100
|
+
scope: "user",
|
|
101
|
+
});
|
|
102
|
+
}, [connecting]);
|
|
169
103
|
|
|
170
104
|
if (dismissed || loading || (status?.connected && !needsReconnect)) {
|
|
171
105
|
return null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { agentNativePath } from "@agent-native/core/client/api-path";
|
|
2
2
|
import { useActionMutation } from "@agent-native/core/client/hooks";
|
|
3
|
-
import { oauthRedirectUri } from "@agent-native/core/client/host";
|
|
4
3
|
import { useT } from "@agent-native/core/client/i18n";
|
|
4
|
+
import { startWorkspaceProviderOAuth } from "@agent-native/core/client/integrations";
|
|
5
5
|
import {
|
|
6
6
|
IconBrandGoogleDrive,
|
|
7
7
|
IconFolderOpen,
|
|
@@ -163,68 +163,16 @@ export function GoogleSlidesReferenceImport({
|
|
|
163
163
|
[onBusyChange],
|
|
164
164
|
);
|
|
165
165
|
|
|
166
|
-
const connect = useCallback(
|
|
166
|
+
const connect = useCallback(() => {
|
|
167
167
|
setConnecting(true);
|
|
168
168
|
reportBusy(true);
|
|
169
169
|
setError(null);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
"
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const callbackUrl = oauthRedirectUri(
|
|
177
|
-
"/_agent-native/google-docs/callback",
|
|
178
|
-
);
|
|
179
|
-
const authUrl = new URL(endpoint("/_agent-native/google-docs/auth-url"));
|
|
180
|
-
authUrl.searchParams.set("redirect_uri", callbackUrl);
|
|
181
|
-
authUrl.searchParams.set(
|
|
182
|
-
"return",
|
|
183
|
-
window.location.pathname + window.location.search,
|
|
184
|
-
);
|
|
185
|
-
const response = await fetch(authUrl.toString(), {
|
|
186
|
-
credentials: "same-origin",
|
|
187
|
-
});
|
|
188
|
-
const result = await readJson<{
|
|
189
|
-
url?: string;
|
|
190
|
-
error?: string;
|
|
191
|
-
message?: string;
|
|
192
|
-
}>(response);
|
|
193
|
-
if (!result.ok) throw result.error;
|
|
194
|
-
const data = result.data;
|
|
195
|
-
if (!response.ok || !data?.url) {
|
|
196
|
-
throw new Error(
|
|
197
|
-
errorFromResponse(
|
|
198
|
-
response,
|
|
199
|
-
data ?? {},
|
|
200
|
-
"Could not start Google OAuth",
|
|
201
|
-
),
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
if (!popup) {
|
|
205
|
-
window.location.href = data.url;
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
popup.location.href = data.url;
|
|
209
|
-
|
|
210
|
-
const deadline = Date.now() + 90_000;
|
|
211
|
-
while (Date.now() < deadline && !popup.closed) {
|
|
212
|
-
await new Promise((resolve) => window.setTimeout(resolve, 1200));
|
|
213
|
-
const next = await refreshStatus();
|
|
214
|
-
if (next?.connected) {
|
|
215
|
-
popup.close();
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
await refreshStatus();
|
|
220
|
-
} catch (caught) {
|
|
221
|
-
popup?.close();
|
|
222
|
-
setError(caught instanceof Error ? caught.message : String(caught));
|
|
223
|
-
} finally {
|
|
224
|
-
setConnecting(false);
|
|
225
|
-
reportBusy(false);
|
|
226
|
-
}
|
|
227
|
-
}, [refreshStatus, reportBusy]);
|
|
170
|
+
startWorkspaceProviderOAuth("google_drive", {
|
|
171
|
+
appId: "slides",
|
|
172
|
+
returnPath: `${window.location.pathname}${window.location.search}`,
|
|
173
|
+
scope: "user",
|
|
174
|
+
});
|
|
175
|
+
}, [reportBusy]);
|
|
228
176
|
|
|
229
177
|
const chooseDocument = useCallback(async () => {
|
|
230
178
|
setChoosing(true);
|
|
@@ -386,7 +386,11 @@ export function SlideContextToolbar({
|
|
|
386
386
|
</TooltipTrigger>
|
|
387
387
|
<TooltipContent>{t("styleInspector.weight")}</TooltipContent>
|
|
388
388
|
</Tooltip>
|
|
389
|
-
<DropdownMenuContent
|
|
389
|
+
<DropdownMenuContent
|
|
390
|
+
align="start"
|
|
391
|
+
className="w-36"
|
|
392
|
+
{...inlineEditSurfaceProps}
|
|
393
|
+
>
|
|
390
394
|
{fontWeightOptions(t).map((option) => (
|
|
391
395
|
<DropdownMenuItem
|
|
392
396
|
key={option.value}
|
|
@@ -481,7 +485,11 @@ export function SlideContextToolbar({
|
|
|
481
485
|
</TooltipTrigger>
|
|
482
486
|
<TooltipContent>{t("styleInspector.align")}</TooltipContent>
|
|
483
487
|
</Tooltip>
|
|
484
|
-
<DropdownMenuContent
|
|
488
|
+
<DropdownMenuContent
|
|
489
|
+
align="start"
|
|
490
|
+
className="w-36"
|
|
491
|
+
{...inlineEditSurfaceProps}
|
|
492
|
+
>
|
|
485
493
|
{textAlignOptions(t).map((option) => (
|
|
486
494
|
<DropdownMenuItem
|
|
487
495
|
key={option.value}
|