@agent-native/core 0.141.6 → 0.144.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 +9 -0
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +11 -6
- package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
- package/corpus/templates/analytics/.agents/skills/provider-api/SKILL.md +19 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/analytics/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/analytics/AGENTS.md +37 -40
- package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/ensure-native-v2-dashboards.ts +1 -1
- package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +17 -22
- package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
- package/corpus/templates/analytics/actions/navigate.ts +5 -6
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +46 -13
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
- package/corpus/templates/analytics/actions/view-screen.ts +0 -20
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
- package/corpus/templates/analytics/app/i18n-data.ts +682 -90
- package/corpus/templates/analytics/app/lib/native-mcp-exclusions.ts +6 -0
- package/corpus/templates/analytics/app/lib/sql-query.ts +33 -6
- package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
- package/corpus/templates/analytics/app/pages/DataSources.tsx +4 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
- package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
- package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/analytics/app/routes/team.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-load-reliably-during-background-data-sw.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-dashboards-remain-responsive-while-historical-data.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-analytics-query-results-now-render-as-a-table-with-csv-downl.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-connect-public-https-custom-apis-and-hand-tested-endpoints-t.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-durable-agent-worker-memory.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-live-dashboard-panels-use-the-shared-query-timeout.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-on-demand-billing-is-available-as-a-native-dashboard-with-ta.md +6 -0
- package/corpus/templates/analytics/changelog/2026-08-06-visible-dashboard-names-are-unique.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
- package/corpus/templates/analytics/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -0
- package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
- package/corpus/templates/analytics/server/db/index.ts +27 -0
- package/corpus/templates/analytics/server/db/schema.ts +10 -0
- package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
- package/corpus/templates/analytics/server/lib/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1147 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +34 -15
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +57 -4
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -4
- package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +1 -0
- package/corpus/templates/analytics/server/plugins/db.ts +52 -18
- package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +36 -8
- package/corpus/templates/assets/.agents/skills/image-generation/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
- package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/assets/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/assets/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/assets/AGENTS.md +1 -0
- package/corpus/templates/assets/actions/_helpers.ts +12 -0
- package/corpus/templates/assets/actions/generate-image.ts +9 -3
- package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
- package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
- package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/assets/app/routes/settings.tsx +5 -0
- package/corpus/templates/assets/app/routes/team.tsx +1 -1
- package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
- package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
- package/corpus/templates/assets/server/lib/generation.ts +58 -0
- package/corpus/templates/assets/shared/api.ts +12 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/brain/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/brain/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/brain/actions/list-connection-providers.ts +24 -3
- package/corpus/templates/brain/app/lib/dispatch-links.ts +44 -0
- package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/brain/app/routes/sources.tsx +15 -7
- package/corpus/templates/brain/app/routes/team.tsx +1 -1
- package/corpus/templates/brain/app/routes.ts +1 -1
- package/corpus/templates/brain/changelog/2026-08-06-brain-provider-setup-links-open-dispatch-correctly-in-standa.md +6 -0
- package/corpus/templates/brain/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +26 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/calendar/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/calendar/AGENTS.md +11 -32
- package/corpus/templates/calendar/actions/update-event.ts +107 -1
- package/corpus/templates/calendar/app/components/calendar/EventCalendarSelect.tsx +83 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +57 -0
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +59 -73
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
- package/corpus/templates/calendar/app/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/calendar/changelog/2026-08-06-existing-events-can-move-between-connected-google-account-ca.md +6 -0
- package/corpus/templates/calendar/server/lib/google-calendar.ts +101 -0
- package/corpus/templates/calendar/server/plugins/agent-chat.ts +7 -1
- package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/chat/app/root.tsx +1 -1
- package/corpus/templates/chat/app/routes/agent.tsx +7 -7
- package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/chat/app/routes/team.tsx +1 -1
- package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/clips/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/clips/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/clips/app/components/editor/editor-layout.tsx +9 -24
- package/corpus/templates/clips/app/components/editor/timeline-geometry.ts +15 -0
- package/corpus/templates/clips/app/components/editor/waveform.tsx +4 -17
- package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
- package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +28 -38
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +21 -27
- package/corpus/templates/clips/changelog/2026-08-06-clips-recovers-from-stalled-recording-setup-without-requirin.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-clips-starts-faster-after-a-deploy-or-idle-period-startup-no.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-deleting-a-recording-returns-cleanly-to-the-library-and-fit-.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-06-hide-clip-insights-from-viewers-without-analytics-access.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +48 -20
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +275 -74
- package/corpus/templates/clips/desktop/src/lib/recording-start-guard.ts +84 -0
- package/corpus/templates/clips/desktop/src/overlays/toolbar.tsx +14 -4
- package/corpus/templates/clips/server/plugins/db.ts +214 -26
- package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/content/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/content/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/content/e2e/global-setup.ts +1 -1
- package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/crm/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/crm/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/crm/changelog/2026-08-06-crm-starts-faster-after-a-deploy-or-idle-period-one-time-dat.md +6 -0
- package/corpus/templates/crm/server/plugins/db.ts +11 -8
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +36 -1
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
- package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/design/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/design/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/design/actions/import-from-url.ts +6 -5
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/design/app/routes/team.tsx +1 -1
- package/corpus/templates/design/changelog/2026-08-05-deleting-a-design-from-the-home-page-no-longer-leaves-the-ap.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-renaming-a-layer-now-focuses-its-name-field-automatically.md +6 -0
- package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
- package/corpus/templates/design/e2e/global-setup.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/dispatch/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
- package/corpus/templates/dispatch/changelog/2026-08-06-ready-workspace-apps-stay-one-click-away-in-a-compact-dispat.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-shared-vault-values-and-management-are-now-restricted-to-wor.md +6 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/factory/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/factory/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/factory/app/routes/team.tsx +1 -1
- package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/forms/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/forms/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
- package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
- package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
- package/corpus/templates/forms/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/forms/shared/navigation.ts +1 -1
- package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/macros/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/macros/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/macros/app/routes/team.tsx +1 -1
- package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/mail/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/mail/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/mail/changelog/2026-08-06-delegated-requests-continue-in-the-background.md +6 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +6 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/plan/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/plan/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
- package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/plan/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +40 -2
- package/corpus/templates/slides/.agents/skills/image-generation-via-a2a/SKILL.md +6 -0
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +15 -2
- package/corpus/templates/slides/.agents/skills/slide-images/SKILL.md +29 -24
- package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/slides/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/slides/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/slides/AGENTS.md +7 -9
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
- package/corpus/templates/slides/actions/export-pptx.ts +402 -36
- package/corpus/templates/slides/actions/import-file.ts +46 -85
- package/corpus/templates/slides/actions/import-from-url.ts +6 -6
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +85 -60
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +5 -1
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +25 -12
- package/corpus/templates/slides/app/components/editor/ExportMenu.tsx +112 -57
- package/corpus/templates/slides/app/components/editor/GoogleDriveConnectionCta.tsx +202 -0
- package/corpus/templates/slides/app/components/editor/GoogleSlidesReferenceImport.tsx +26 -14
- package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +176 -0
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +182 -141
- package/corpus/templates/slides/app/components/editor/canvas-interactions/index.ts +1 -0
- package/corpus/templates/slides/app/components/editor/canvas-interactions/slides-canvas-adapter.ts +18 -0
- package/corpus/templates/slides/app/components/editor/slide-text-targets.ts +85 -0
- package/corpus/templates/slides/app/components/layout/Layout.tsx +3 -0
- package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +13 -3
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
- package/corpus/templates/slides/app/global.css +6 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +10 -6
- package/corpus/templates/slides/app/lib/deck-preview-frame.ts +15 -0
- package/corpus/templates/slides/app/lib/deck-share-links.ts +9 -0
- package/corpus/templates/slides/app/lib/export-pptx-client.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
- package/corpus/templates/slides/app/pages/Index.tsx +107 -6
- package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
- package/corpus/templates/slides/app/routes/team.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-clicking-the-gray-canvas-around-a-slide-clears-its-selection.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deck-thumbnails-keep-a-consistent-listing-frame-across-aspec.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-deep-linked-decks-open-directly-instead-of-being-interrupted.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-google-slides-exports-now-show-clear-import-steps-when-direc.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-import-pdf-google-slides-and-powerpoint-decks-directly-from-.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-imported-powerpoint-exports-keep-text-and-images-editable-an.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-presentation-prompts-continue-adding-rendered-slides-until-t.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-public-decks-now-share-read-only-presentation-links-by-defau.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-offers-a-direct-connect-google-button-when-a-drive-co.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-slides-preserve-uploaded-pdf-layouts-accept-larger-reference.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-06-styled-words-stay-part-of-their-text-box-instead-of-becoming.md +6 -0
- package/corpus/templates/slides/server/handlers/google-docs-auth.ts +7 -20
- package/corpus/templates/slides/server/handlers/import/html-converter.ts +236 -13
- package/corpus/templates/slides/server/handlers/import/pptx-assets.ts +67 -0
- package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +2 -0
- package/corpus/templates/slides/server/handlers/uploads.ts +7 -3
- package/corpus/templates/slides/server/lib/chat-attachments.ts +6 -3
- package/corpus/templates/slides/server/lib/emails.ts +7 -2
- package/corpus/templates/slides/server/lib/google-docs-error.ts +50 -0
- package/corpus/templates/slides/server/lib/google-docs-oauth.ts +1 -0
- package/corpus/templates/slides/server/lib/import-asset-storage.ts +127 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -3
- package/corpus/templates/slides/server/routes/api/import-assets/[token].get.ts +70 -0
- package/corpus/templates/slides/shared/upload-types.ts +3 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/corpus/templates/tasks/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
- package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
- package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
- package/dist/agent/engine/ai-sdk-engine.js +49 -3
- package/dist/agent/production-agent.d.ts +18 -0
- package/dist/agent/production-agent.js +80 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/cli/agent-plugin.d.ts +112 -0
- package/dist/cli/agent-plugin.js +1081 -0
- package/dist/cli/app-skill.js +39 -1
- package/dist/cli/code-agent-executor.d.ts +3 -0
- package/dist/cli/code-agent-executor.js +51 -13
- package/dist/cli/index.js +13 -0
- package/dist/cli/templates-meta.js +1 -1
- package/dist/client/AgentPanel.d.ts +3 -1
- package/dist/client/AgentPanel.js +9 -2
- package/dist/client/AssistantChat.d.ts +8 -0
- package/dist/client/AssistantChat.js +23 -8
- package/dist/client/NewWorkspaceAppFlow.js +1 -0
- package/dist/client/agent-chat-adapter.d.ts +1 -1
- package/dist/client/agent-chat-adapter.js +153 -7
- package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
- package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/chat/run-recovery.js +5 -1
- package/dist/client/embed-auth.js +6 -2
- package/dist/client/error-format.js +12 -0
- package/dist/client/integrations/IntegrationsPanel.js +40 -6
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/OrgSwitcher.js +2 -2
- package/dist/client/org/TeamPage.js +92 -72
- package/dist/client/require-session.d.ts +1 -1
- package/dist/client/require-session.js +4 -4
- package/dist/client/resources/McpConnectionSuggestion.d.ts +1 -0
- package/dist/client/resources/McpConnectionSuggestion.js +27 -10
- package/dist/client/resources/McpIntegrationDialog.js +77 -45
- package/dist/client/resources/mcp-integration-catalog.d.ts +13 -1
- package/dist/client/resources/mcp-integration-catalog.js +255 -2
- package/dist/client/resources/mcp-integration-logos.js +18 -2
- package/dist/client/resources/use-mcp-servers.d.ts +5 -0
- package/dist/client/resources/use-mcp-servers.js +36 -0
- package/dist/client/settings/AccountSettingsCard.js +42 -36
- package/dist/client/settings/AutomationsSection.js +1 -1
- package/dist/client/settings/DemoModeSection.d.ts +3 -1
- package/dist/client/settings/DemoModeSection.js +4 -1
- package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
- package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
- package/dist/client/settings/SchedulingTimezoneField.js +9 -5
- package/dist/client/settings/SettingsPanel.d.ts +4 -1
- package/dist/client/settings/SettingsPanel.js +21 -21
- package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
- package/dist/client/settings/SettingsTabsPage.js +98 -45
- package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
- package/dist/client/settings/useSettingsPanelController.js +47 -8
- package/dist/collab/routes.d.ts +1 -1
- package/dist/db/client.d.ts +9 -0
- package/dist/db/client.js +51 -16
- package/dist/db/create-get-db.js +2 -2
- package/dist/db/ddl-guard.d.ts +11 -10
- package/dist/db/ddl-guard.js +40 -12
- package/dist/deploy/build.d.ts +2 -0
- package/dist/deploy/build.js +97 -4
- package/dist/deploy/workspace-deploy.js +0 -2
- package/dist/guards/no-env-credentials.js +9 -0
- package/dist/ingestion/index.d.ts +1 -1
- package/dist/ingestion/pptx.d.ts +68 -0
- package/dist/ingestion/pptx.js +660 -213
- package/dist/ingestion/website.d.ts +30 -0
- package/dist/integrations/plugin.js +9 -6
- package/dist/localization/default-messages.d.ts +59 -0
- package/dist/localization/default-messages.js +62 -2
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/mcp-client/oauth-routes.d.ts +2 -0
- package/dist/mcp-client/oauth-routes.js +74 -7
- package/dist/mcp-client/routes.d.ts +1 -0
- package/dist/mcp-client/routes.js +49 -0
- package/dist/navigation/index.js +16 -5
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
- package/dist/provider-api/actions/provider-api.d.ts +11 -11
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +45 -4
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat/action-filters-a2a.d.ts +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +36 -1
- package/dist/server/agent-chat-plugin.js +29 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/auth.js +55 -17
- package/dist/server/better-auth-instance.js +5 -3
- package/dist/server/core-routes-plugin.d.ts +8 -1
- package/dist/server/core-routes-plugin.js +28 -3
- package/dist/server/credential-provider.d.ts +3 -3
- package/dist/server/credential-provider.js +90 -4
- package/dist/server/identity-sso.js +2 -1
- package/dist/server/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +171 -62
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/self-dispatch.d.ts +5 -4
- package/dist/server/self-dispatch.js +25 -14
- package/dist/server/ssr-handler.d.ts +1 -1
- package/dist/server/ssr-handler.js +1 -1
- package/dist/server/workspace-provider-oauth.js +1 -1
- package/dist/setup-connections/onboarding.js +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- package/dist/shared/sign-in-journey.d.ts +5 -2
- package/dist/shared/sign-in-journey.js +10 -4
- package/dist/sharing/actions/set-resource-visibility.js +16 -4
- package/dist/sharing/registry.d.ts +14 -0
- package/dist/styles/agent-native.css +6 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/dist/templates/chat/app/root.tsx +1 -1
- package/dist/templates/chat/app/routes/agent.tsx +7 -7
- package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
- package/dist/templates/chat/app/routes/team.tsx +1 -1
- package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/dist/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/dist/templates/workspace-root/AGENTS.md +7 -0
- package/dist/user-profile/actions/change-password.js +8 -3
- package/dist/user-profile/actions/set-password.js +5 -1
- package/dist/vite/action-types-plugin.js +59 -0
- package/docs/content/authentication.mdx +4 -5
- package/docs/content/skills-guide.mdx +13 -0
- package/docs/content/template-analytics-developers.mdx +1 -1
- package/docs/content/template-calendar-developers.mdx +1 -1
- package/docs/content/template-chat-developers.mdx +2 -2
- package/docs/content/template-content-developers.mdx +1 -1
- package/docs/content/template-mail-developers.mdx +1 -1
- package/docs/content/template-plan-developers.mdx +1 -1
- package/docs/content/toolkit-command-navigation.mdx +6 -6
- package/docs/content/toolkit-org-team.mdx +1 -1
- package/docs/content/toolkit-settings.mdx +8 -8
- package/docs/content/toolkit-setup-connections.mdx +1 -1
- package/package.json +6 -2
- package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/chat/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/chat/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
- package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
- package/src/templates/chat/app/root.tsx +1 -1
- package/src/templates/chat/app/routes/agent.tsx +7 -7
- package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
- package/src/templates/chat/app/routes/settings.$.tsx +1 -0
- package/src/templates/chat/app/routes/team.tsx +1 -1
- package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/default/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/default/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/default/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/headless/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/headless/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/adding-workspace-apps/SKILL.md +6 -0
- package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
- package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +51 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +296 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-app/agents/openai.yaml +4 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/SKILL.md +112 -0
- package/src/templates/workspace-core/.agents/skills/turn-into-skill/agents/openai.yaml +4 -0
- package/src/templates/workspace-root/AGENTS.md +7 -0
- package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
- package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
- package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
- package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
- package/src/templates/default/actions/navigate.spec.ts +0 -53
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
uploadPromptFiles,
|
|
16
16
|
type UploadedFile,
|
|
17
17
|
} from "@/components/editor/PromptDialog";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
describeDeckPersistenceFailure,
|
|
20
|
+
useDecks,
|
|
21
|
+
} from "@/context/DeckContext";
|
|
19
22
|
import { useAgentGenerating } from "@/hooks/use-agent-generating";
|
|
20
23
|
import { useDesignSystems } from "@/hooks/use-design-systems";
|
|
21
24
|
import { useWorkspaceDefaults } from "@/hooks/use-workspace-defaults";
|
|
@@ -26,6 +29,8 @@ import {
|
|
|
26
29
|
type RecentReference,
|
|
27
30
|
} from "@/lib/recent-references";
|
|
28
31
|
|
|
32
|
+
import { MAX_REFERENCE_FILE_BYTES } from "../../../shared/upload-types";
|
|
33
|
+
|
|
29
34
|
type FirstDeckStep = "prompt" | "references";
|
|
30
35
|
|
|
31
36
|
export function FirstDeckOnboardingFlow({
|
|
@@ -141,12 +146,15 @@ export function FirstDeckOnboardingFlow({
|
|
|
141
146
|
onUnauthenticated: () => {
|
|
142
147
|
toast.error(t("home.signInTitle"));
|
|
143
148
|
},
|
|
144
|
-
onPersistenceFailure: (failedPrompt) => {
|
|
149
|
+
onPersistenceFailure: (failedPrompt, _failedFiles, failure) => {
|
|
145
150
|
setPromptInitialText(failedPrompt);
|
|
146
151
|
setPromptInitialTextKey(Date.now());
|
|
147
152
|
setStep("prompt");
|
|
148
153
|
toast.error(t("home.generationStartFailed"), {
|
|
149
|
-
description:
|
|
154
|
+
description: describeDeckPersistenceFailure(
|
|
155
|
+
failure,
|
|
156
|
+
t("home.generationStartFailedDescription"),
|
|
157
|
+
),
|
|
150
158
|
});
|
|
151
159
|
},
|
|
152
160
|
});
|
|
@@ -297,6 +305,8 @@ export function FirstDeckOnboardingFlow({
|
|
|
297
305
|
className="mt-8"
|
|
298
306
|
autoFocus
|
|
299
307
|
attachmentsEnabled
|
|
308
|
+
maxDocumentAttachmentBytes={MAX_REFERENCE_FILE_BYTES}
|
|
309
|
+
documentAttachmentLimitLabel="Slides reference files"
|
|
300
310
|
disabled={uploading}
|
|
301
311
|
placeholder={t("home.newDeckPlaceholder")}
|
|
302
312
|
onSubmit={handlePromptSubmit}
|
|
@@ -18,6 +18,7 @@ import type {
|
|
|
18
18
|
import type { AspectRatio } from "@/lib/aspect-ratios";
|
|
19
19
|
import {
|
|
20
20
|
findLegacyAnimationContainer,
|
|
21
|
+
getElementPath,
|
|
21
22
|
resolveSlideAnimationElement,
|
|
22
23
|
} from "@/lib/slide-animation-elements";
|
|
23
24
|
|
|
@@ -43,6 +44,31 @@ function getAnimationSteps(slide: Slide): SlideAnimation[] | null {
|
|
|
43
44
|
const doc = new DOMParser().parseFromString(slide.content, "text/html");
|
|
44
45
|
const root = doc.querySelector(".fmd-slide");
|
|
45
46
|
if (!root) return null;
|
|
47
|
+
|
|
48
|
+
const paragraphs = Array.from(
|
|
49
|
+
root.querySelectorAll(".fmd-pptx-text p[data-pptx-paragraph]"),
|
|
50
|
+
).filter((paragraph) => {
|
|
51
|
+
const textBox = paragraph.closest(".fmd-pptx-text");
|
|
52
|
+
return (
|
|
53
|
+
(textBox?.querySelectorAll("p[data-pptx-paragraph]").length ?? 0) > 1
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
if (paragraphs.length > 1) {
|
|
57
|
+
return paragraphs.flatMap((paragraph, index) => {
|
|
58
|
+
const elementPath = getElementPath(root, paragraph);
|
|
59
|
+
return elementPath
|
|
60
|
+
? [
|
|
61
|
+
{
|
|
62
|
+
id: `auto-paragraph-${index}`,
|
|
63
|
+
elementIndex: index,
|
|
64
|
+
elementPath,
|
|
65
|
+
type: "slide-up" as AnimationType,
|
|
66
|
+
},
|
|
67
|
+
]
|
|
68
|
+
: [];
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
46
72
|
const container = findLegacyAnimationContainer(root);
|
|
47
73
|
if (!container) return null;
|
|
48
74
|
return Array.from(container.children).map((_, i) => ({
|
|
@@ -103,7 +129,7 @@ function annotateStepsForPresentation(
|
|
|
103
129
|
})
|
|
104
130
|
.join("\n");
|
|
105
131
|
|
|
106
|
-
const styleTag = `<style>[data-pstep] { opacity: 0; pointer-events: none; }\n${styleLines}</style>`;
|
|
132
|
+
const styleTag = `<style>[data-pstep] { opacity: 0; pointer-events: none; visibility: visible !important; }\n${styleLines}</style>`;
|
|
107
133
|
return styleTag + doc.body.innerHTML;
|
|
108
134
|
}
|
|
109
135
|
|
|
@@ -138,6 +138,25 @@ export interface Deck {
|
|
|
138
138
|
aspectRatio?: AspectRatio;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
export type DeckPersistenceResult =
|
|
142
|
+
| { persisted: true }
|
|
143
|
+
| { persisted: false; reason: "request-failed"; error: unknown }
|
|
144
|
+
| { persisted: false; reason: "not-found" };
|
|
145
|
+
|
|
146
|
+
export function describeDeckPersistenceFailure(
|
|
147
|
+
result: DeckPersistenceResult,
|
|
148
|
+
fallback: string,
|
|
149
|
+
): string {
|
|
150
|
+
if (result.persisted || result.reason === "not-found") return fallback;
|
|
151
|
+
if (result.error instanceof Error && result.error.message.trim()) {
|
|
152
|
+
return result.error.message;
|
|
153
|
+
}
|
|
154
|
+
if (typeof result.error === "string" && result.error.trim()) {
|
|
155
|
+
return result.error;
|
|
156
|
+
}
|
|
157
|
+
return fallback;
|
|
158
|
+
}
|
|
159
|
+
|
|
141
160
|
interface DeckContextType {
|
|
142
161
|
decks: Deck[];
|
|
143
162
|
loading: boolean;
|
|
@@ -146,7 +165,7 @@ interface DeckContextType {
|
|
|
146
165
|
title?: string,
|
|
147
166
|
options?: { noDefaultSlides?: boolean; designSystemId?: string | null },
|
|
148
167
|
) => Deck;
|
|
149
|
-
ensureDeckPersisted: (id: string) => Promise<
|
|
168
|
+
ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
|
|
150
169
|
/**
|
|
151
170
|
* Optimistically duplicate a deck. Inserts a copy into local state with the
|
|
152
171
|
* supplied `newId` immediately so the UI can navigate without awaiting the
|
|
@@ -167,6 +186,7 @@ interface DeckContextType {
|
|
|
167
186
|
) => void;
|
|
168
187
|
reloadDecks: () => Promise<void>;
|
|
169
188
|
reloadDecksWithStatus: () => Promise<DeckReloadStatus>;
|
|
189
|
+
refreshOpenDeck: (deckId: string) => Promise<Deck | null>;
|
|
170
190
|
getDeck: (id: string) => Deck | undefined;
|
|
171
191
|
addSlide: (
|
|
172
192
|
deckId: string,
|
|
@@ -885,7 +905,22 @@ async function fetchDecksForCurrentRoute(): Promise<Deck[] | null> {
|
|
|
885
905
|
}
|
|
886
906
|
|
|
887
907
|
async function deleteDeckFromAPI(id: string): Promise<void> {
|
|
888
|
-
|
|
908
|
+
try {
|
|
909
|
+
await callAction("delete-deck", { id }, { method: "DELETE" });
|
|
910
|
+
} catch (error) {
|
|
911
|
+
// Deleting an optimistic deck is intentionally idempotent. A create can
|
|
912
|
+
// fail after the server committed the row, or before it created one.
|
|
913
|
+
if (
|
|
914
|
+
!(
|
|
915
|
+
error &&
|
|
916
|
+
typeof error === "object" &&
|
|
917
|
+
"status" in error &&
|
|
918
|
+
(error as { status?: unknown }).status === 404
|
|
919
|
+
)
|
|
920
|
+
) {
|
|
921
|
+
throw error;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
889
924
|
}
|
|
890
925
|
|
|
891
926
|
async function createDeckOnAPI(deck: Deck): Promise<void> {
|
|
@@ -1081,7 +1116,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1081
1116
|
const deletion = pendingCreate
|
|
1082
1117
|
? pendingCreate.then(
|
|
1083
1118
|
() => deleteDeckFromAPI(deckId),
|
|
1084
|
-
() =>
|
|
1119
|
+
() => deleteDeckFromAPI(deckId),
|
|
1085
1120
|
)
|
|
1086
1121
|
: deleteDeckFromAPI(deckId);
|
|
1087
1122
|
void deletion.catch((err) => {
|
|
@@ -1267,11 +1302,11 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1267
1302
|
// - Dirty deck / unsaved local create → additive merge only: surface
|
|
1268
1303
|
// agent-added slides without ever overwriting or dropping local slides.
|
|
1269
1304
|
const refetchOpenDeckIfChanged = useCallback(
|
|
1270
|
-
async (currentOpenId: string) => {
|
|
1305
|
+
async (currentOpenId: string): Promise<Deck | null> => {
|
|
1271
1306
|
const serverDeck = await fetchDeckFromAPI(currentOpenId);
|
|
1272
1307
|
// Null means 404 (row not created yet), a transient failure, or a
|
|
1273
1308
|
// still-pending create — nothing authoritative to reconcile.
|
|
1274
|
-
if (!serverDeck) return;
|
|
1309
|
+
if (!serverDeck) return null;
|
|
1275
1310
|
const clientDeck = decksRef.current.find((d) => d.id === currentOpenId);
|
|
1276
1311
|
|
|
1277
1312
|
const hasLocalEdits =
|
|
@@ -1281,7 +1316,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1281
1316
|
if (hasLocalEdits && clientDeck) {
|
|
1282
1317
|
// Content-preserving: only ADD server slides missing locally.
|
|
1283
1318
|
const merged = mergeServerAddedSlides(clientDeck, serverDeck);
|
|
1284
|
-
if (merged === clientDeck) return; // nothing new to surface
|
|
1319
|
+
if (merged === clientDeck) return serverDeck; // nothing new to surface
|
|
1285
1320
|
lastExternalUpdateRef.current = Date.now();
|
|
1286
1321
|
setDecks((prev) => {
|
|
1287
1322
|
const idx = prev.findIndex((d) => d.id === currentOpenId);
|
|
@@ -1290,16 +1325,17 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1290
1325
|
next[idx] = merged;
|
|
1291
1326
|
return next;
|
|
1292
1327
|
});
|
|
1293
|
-
return;
|
|
1328
|
+
return serverDeck;
|
|
1294
1329
|
}
|
|
1295
1330
|
|
|
1296
1331
|
const changed =
|
|
1297
1332
|
!clientDeck ||
|
|
1298
1333
|
clientDeck.updatedAt !== serverDeck.updatedAt ||
|
|
1299
|
-
clientDeck
|
|
1300
|
-
if (!changed) return;
|
|
1334
|
+
deckContentSignature(clientDeck) !== deckContentSignature(serverDeck);
|
|
1335
|
+
if (!changed) return serverDeck;
|
|
1301
1336
|
lastExternalUpdateRef.current = Date.now();
|
|
1302
1337
|
applyRemoteDeckUpdate(serverDeck);
|
|
1338
|
+
return serverDeck;
|
|
1303
1339
|
},
|
|
1304
1340
|
[applyRemoteDeckUpdate],
|
|
1305
1341
|
);
|
|
@@ -1728,19 +1764,33 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
1728
1764
|
[noteLocalCreate, setDecksLocal],
|
|
1729
1765
|
);
|
|
1730
1766
|
|
|
1731
|
-
const ensureDeckPersisted = useCallback(
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1767
|
+
const ensureDeckPersisted = useCallback(
|
|
1768
|
+
async (id: string): Promise<DeckPersistenceResult> => {
|
|
1769
|
+
const pendingCreate = pendingCreatePromisesRef.current.get(id);
|
|
1770
|
+
if (pendingCreate) {
|
|
1771
|
+
try {
|
|
1772
|
+
await pendingCreate;
|
|
1773
|
+
return { persisted: true };
|
|
1774
|
+
} catch (error) {
|
|
1775
|
+
return { persisted: false, reason: "request-failed", error };
|
|
1776
|
+
}
|
|
1739
1777
|
}
|
|
1740
|
-
}
|
|
1741
1778
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1779
|
+
try {
|
|
1780
|
+
const result = await callAction<unknown>(
|
|
1781
|
+
"get-deck",
|
|
1782
|
+
{ id },
|
|
1783
|
+
{ method: "GET" },
|
|
1784
|
+
);
|
|
1785
|
+
return normalizeActionDeck(result)
|
|
1786
|
+
? { persisted: true }
|
|
1787
|
+
: { persisted: false, reason: "not-found" };
|
|
1788
|
+
} catch (error) {
|
|
1789
|
+
return { persisted: false, reason: "request-failed", error };
|
|
1790
|
+
}
|
|
1791
|
+
},
|
|
1792
|
+
[],
|
|
1793
|
+
);
|
|
1744
1794
|
|
|
1745
1795
|
const duplicateDeck = useCallback(
|
|
1746
1796
|
(sourceDeckId: string, newId: string, title?: string): Deck | null => {
|
|
@@ -2150,6 +2200,7 @@ export function DeckProvider({ children }: { children: ReactNode }) {
|
|
|
2150
2200
|
updateDeck,
|
|
2151
2201
|
reloadDecks,
|
|
2152
2202
|
reloadDecksWithStatus,
|
|
2203
|
+
refreshOpenDeck: refetchOpenDeckIfChanged,
|
|
2153
2204
|
getDeck,
|
|
2154
2205
|
addSlide,
|
|
2155
2206
|
updateSlide,
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
@source "./**/*.{ts,tsx}";
|
|
16
16
|
|
|
17
|
+
/* Keep the editable agent prompt readable even if the generated text utility
|
|
18
|
+
is missing or loses a cascade tie during the hosted build. */
|
|
19
|
+
.agent-composer-root [data-agent-composer-slot="editor-input"] {
|
|
20
|
+
color: hsl(var(--foreground));
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
/* Hide the sidebar's built-in collapsed tab strip — AgentToggleButton in the
|
|
18
24
|
toolbar serves this purpose instead, so we don't want a redundant bar. */
|
|
19
25
|
button[title="Open agent sidebar"] {
|
|
@@ -684,6 +684,7 @@ const messages = {
|
|
|
684
684
|
googleSlidesReferenceConnect:
|
|
685
685
|
"Connect Google Drive to import a Slides deck.",
|
|
686
686
|
googleSlidesReferenceChoose: "Choose Google Slides deck",
|
|
687
|
+
googleSlidesReferenceUrl: "Paste a Google Slides link",
|
|
687
688
|
googleSlidesReferencePicking: "Working...",
|
|
688
689
|
googleSlidesReferenceConnected:
|
|
689
690
|
"Connected. Choose a Google Slides deck to import as a reusable reference.",
|
|
@@ -4,7 +4,7 @@ import { flushSync } from "react-dom";
|
|
|
4
4
|
|
|
5
5
|
import type { NewDeckReferenceSelection } from "@/components/editor/NewDeckReferenceStep";
|
|
6
6
|
import type { UploadedFile } from "@/components/editor/PromptDialog";
|
|
7
|
-
import type { Deck } from "@/context/DeckContext";
|
|
7
|
+
import type { Deck, DeckPersistenceResult } from "@/context/DeckContext";
|
|
8
8
|
import { createDeckAgentMessage } from "@/lib/agent-visible-message";
|
|
9
9
|
|
|
10
10
|
interface DesignSystemGenerationContextResult {
|
|
@@ -100,7 +100,7 @@ function describeUploadedFilesForAgent(
|
|
|
100
100
|
"",
|
|
101
101
|
"File handling rules:",
|
|
102
102
|
`- PPTX files: call \`import-pptx --filePath \"<path>\" --deckId ${deckId}\` before adding or editing slides.`,
|
|
103
|
-
`- PDF and DOCX files: call \`import-file --filePath \"<path>\" --format auto --deckId ${deckId}\` and use the returned extracted text as source material.
|
|
103
|
+
`- PDF and DOCX files: call \`import-file --filePath \"<path>\" --format auto --deckId ${deckId}\` and use the returned extracted text as source material. For a visual PDF whose original layout should be preserved, pass \`--importIntoDeck true\` instead of rebuilding the pages from extracted text.`,
|
|
104
104
|
"- Text-like files: use the uploaded-text-file blocks already included in the prompt; do not call import-file for them.",
|
|
105
105
|
'- Image files with an embeddable URL can be inserted directly into slide HTML as `<img src="...">` or used as visual references.',
|
|
106
106
|
"- Image files without a URL are visual/reference assets only; do not claim to have processed a PPTX/PDF/DOCX unless the relevant import action succeeds.",
|
|
@@ -150,13 +150,17 @@ export interface StartDeckGenerationOptions {
|
|
|
150
150
|
selectedReferenceDeckId?: string | null;
|
|
151
151
|
designSystems: Array<{ id: string; title: string }>;
|
|
152
152
|
createDeck: CreateDeck;
|
|
153
|
-
ensureDeckPersisted: (id: string) => Promise<
|
|
153
|
+
ensureDeckPersisted: (id: string) => Promise<DeckPersistenceResult>;
|
|
154
154
|
deleteDeck: (id: string) => void;
|
|
155
155
|
navigate: Navigate;
|
|
156
156
|
agentSubmit: SubmitAgent;
|
|
157
157
|
onPromptClosed: () => void;
|
|
158
158
|
onUnauthenticated: (prompt: string, hadFiles: boolean) => void;
|
|
159
|
-
onPersistenceFailure: (
|
|
159
|
+
onPersistenceFailure: (
|
|
160
|
+
prompt: string,
|
|
161
|
+
files: UploadedFile[],
|
|
162
|
+
failure: DeckPersistenceResult,
|
|
163
|
+
) => void;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
/** Create the optimistic deck, hydrate references, and start the agent run. */
|
|
@@ -214,8 +218,8 @@ export async function startDeckGeneration({
|
|
|
214
218
|
onPromptClosed();
|
|
215
219
|
|
|
216
220
|
const persisted = await ensureDeckPersisted(deck.id);
|
|
217
|
-
if (!persisted) {
|
|
218
|
-
onPersistenceFailure(prompt, filesForGeneration);
|
|
221
|
+
if (!persisted.persisted) {
|
|
222
|
+
onPersistenceFailure(prompt, filesForGeneration, persisted);
|
|
219
223
|
deleteDeck(deckId);
|
|
220
224
|
return "failed";
|
|
221
225
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getAspectRatioDims, type AspectRatio } from "./aspect-ratios";
|
|
2
|
+
|
|
3
|
+
const LISTING_FRAME_RATIO = 16 / 9;
|
|
4
|
+
|
|
5
|
+
export function getDeckListingPreviewFrameStyle(aspectRatio?: AspectRatio) {
|
|
6
|
+
const dimensions = getAspectRatioDims(aspectRatio);
|
|
7
|
+
const isListingRatio =
|
|
8
|
+
dimensions.width / dimensions.height >= LISTING_FRAME_RATIO;
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
aspectRatio: `${dimensions.width} / ${dimensions.height}`,
|
|
12
|
+
height: "100%",
|
|
13
|
+
width: isListingRatio ? "100%" : "auto",
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type DeckShareLinkKind = "editor" | "presentation";
|
|
2
|
+
|
|
3
|
+
export function getDeckShareLinkOrder(
|
|
4
|
+
visibility?: "private" | "org" | "public",
|
|
5
|
+
): { primary: DeckShareLinkKind; secondary: DeckShareLinkKind } {
|
|
6
|
+
return visibility === "public"
|
|
7
|
+
? { primary: "presentation", secondary: "editor" }
|
|
8
|
+
: { primary: "editor", secondary: "presentation" };
|
|
9
|
+
}
|
|
@@ -313,6 +313,94 @@ function widenNoWrapTextElements(root: HTMLElement) {
|
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
+
/**
|
|
317
|
+
* dom-to-pptx serializes CSS gradients as one malformed diagonal SVG. Imported
|
|
318
|
+
* slides use a repeated master grid, so materialize that grid as a transparent
|
|
319
|
+
* image before handing the clone to the exporter and leave the real text and
|
|
320
|
+
* image objects editable.
|
|
321
|
+
*/
|
|
322
|
+
function materializeImportedBackgroundGrid(root: HTMLElement) {
|
|
323
|
+
const slideRoot = root.matches(".fmd-imported-pptx")
|
|
324
|
+
? root
|
|
325
|
+
: root.querySelector<HTMLElement>(".fmd-imported-pptx");
|
|
326
|
+
if (!slideRoot) return;
|
|
327
|
+
const computed = window.getComputedStyle(slideRoot);
|
|
328
|
+
if (!computed.backgroundImage.includes("linear-gradient")) return;
|
|
329
|
+
|
|
330
|
+
const color = computed.backgroundImage.match(/rgb\([^)]*\)/)?.[0];
|
|
331
|
+
const size = computed.backgroundSize
|
|
332
|
+
.split(",")[0]
|
|
333
|
+
?.trim()
|
|
334
|
+
.split(/\s+/)
|
|
335
|
+
.map((value) => Number.parseFloat(value));
|
|
336
|
+
const position = computed.backgroundPosition
|
|
337
|
+
.split(",")[0]
|
|
338
|
+
?.trim()
|
|
339
|
+
.split(/\s+/)
|
|
340
|
+
.map((value) => Number.parseFloat(value));
|
|
341
|
+
const declaredLineWidth = computed.backgroundImage.match(
|
|
342
|
+
/\b0(?:px)?\s+([\d.]+)px\b/i,
|
|
343
|
+
)?.[1];
|
|
344
|
+
const lineWidth = declaredLineWidth
|
|
345
|
+
? Number.parseFloat(declaredLineWidth)
|
|
346
|
+
: Number.NaN;
|
|
347
|
+
if (
|
|
348
|
+
!color ||
|
|
349
|
+
!size ||
|
|
350
|
+
size.length < 2 ||
|
|
351
|
+
!Number.isFinite(size[0]) ||
|
|
352
|
+
!Number.isFinite(size[1]) ||
|
|
353
|
+
size[0] <= 0 ||
|
|
354
|
+
size[1] <= 0 ||
|
|
355
|
+
!position ||
|
|
356
|
+
position.length < 2 ||
|
|
357
|
+
!Number.isFinite(position[0]) ||
|
|
358
|
+
!Number.isFinite(position[1]) ||
|
|
359
|
+
!Number.isFinite(lineWidth)
|
|
360
|
+
) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const canvas = document.createElement("canvas");
|
|
365
|
+
canvas.width = Math.max(1, Math.round(slideRoot.clientWidth));
|
|
366
|
+
canvas.height = Math.max(1, Math.round(slideRoot.clientHeight));
|
|
367
|
+
const context = canvas.getContext("2d");
|
|
368
|
+
if (!context) return;
|
|
369
|
+
context.strokeStyle = color;
|
|
370
|
+
context.lineWidth = Math.max(0.5, lineWidth);
|
|
371
|
+
|
|
372
|
+
for (let x = position[0]; x < canvas.width; x += size[0]) {
|
|
373
|
+
context.beginPath();
|
|
374
|
+
context.moveTo(x + context.lineWidth / 2, 0);
|
|
375
|
+
context.lineTo(x + context.lineWidth / 2, canvas.height);
|
|
376
|
+
context.stroke();
|
|
377
|
+
}
|
|
378
|
+
for (let y = position[1]; y < canvas.height; y += size[1]) {
|
|
379
|
+
context.beginPath();
|
|
380
|
+
context.moveTo(0, y + context.lineWidth / 2);
|
|
381
|
+
context.lineTo(canvas.width, y + context.lineWidth / 2);
|
|
382
|
+
context.stroke();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const gridImage = document.createElement("img");
|
|
386
|
+
gridImage.alt = "";
|
|
387
|
+
gridImage.src = canvas.toDataURL("image/png");
|
|
388
|
+
Object.assign(gridImage.style, {
|
|
389
|
+
height: "100%",
|
|
390
|
+
left: "0",
|
|
391
|
+
pointerEvents: "none",
|
|
392
|
+
position: "absolute",
|
|
393
|
+
top: "0",
|
|
394
|
+
width: "100%",
|
|
395
|
+
zIndex: "0",
|
|
396
|
+
});
|
|
397
|
+
slideRoot.insertBefore(gridImage, slideRoot.firstChild);
|
|
398
|
+
slideRoot.style.backgroundImage = "none";
|
|
399
|
+
slideRoot.style.backgroundSize = "auto";
|
|
400
|
+
slideRoot.style.backgroundPosition = "0 0";
|
|
401
|
+
slideRoot.style.backgroundRepeat = "no-repeat";
|
|
402
|
+
}
|
|
403
|
+
|
|
316
404
|
export async function buildDeckPptxBlob(
|
|
317
405
|
deckTitle: string,
|
|
318
406
|
slides: PptxExportSlide[],
|
|
@@ -341,6 +429,7 @@ export async function buildDeckPptxBlob(
|
|
|
341
429
|
height: dims.height,
|
|
342
430
|
});
|
|
343
431
|
exportClones.push(clone);
|
|
432
|
+
materializeImportedBackgroundGrid(clone.element);
|
|
344
433
|
widenNoWrapTextElements(clone.element);
|
|
345
434
|
await replaceInlineSvgsWithImages(clone.element);
|
|
346
435
|
await preloadImagesWithCors(clone.element);
|
|
@@ -118,6 +118,9 @@ export function animationElementKey(path: number[]): string {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
export function findLegacyAnimationContainer(root: Element): Element | null {
|
|
121
|
+
const marked = root.querySelector(".fmd-animation-container");
|
|
122
|
+
if (marked && marked.children.length >= 1) return marked;
|
|
123
|
+
|
|
121
124
|
const children = Array.from(root.children);
|
|
122
125
|
for (let i = children.length - 1; i >= 0; i--) {
|
|
123
126
|
if (children[i].children.length >= 2) return children[i];
|
|
@@ -155,6 +155,7 @@ export default function DeckEditor() {
|
|
|
155
155
|
getDeck,
|
|
156
156
|
reloadDecks,
|
|
157
157
|
reloadDecksWithStatus,
|
|
158
|
+
refreshOpenDeck,
|
|
158
159
|
updateDeck,
|
|
159
160
|
updateSlide,
|
|
160
161
|
deleteSlide,
|
|
@@ -396,6 +397,22 @@ export default function DeckEditor() {
|
|
|
396
397
|
}
|
|
397
398
|
}, [refetchOrg, reloadDecks]);
|
|
398
399
|
|
|
400
|
+
// The final generation write can race the last sync event. Pull the
|
|
401
|
+
// authoritative open deck when the run settles so a stale canvas does not
|
|
402
|
+
// require a browser refresh to reveal completed slides.
|
|
403
|
+
useEffect(() => {
|
|
404
|
+
if (
|
|
405
|
+
!id ||
|
|
406
|
+
!shouldClearNewDeckGeneratingState({
|
|
407
|
+
generating,
|
|
408
|
+
generationStarted: newDeckGenerationStarted.current,
|
|
409
|
+
})
|
|
410
|
+
) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
void refreshOpenDeck(id);
|
|
414
|
+
}, [generating, id, refreshOpenDeck]);
|
|
415
|
+
|
|
399
416
|
// Clean up the generating URL param/ref when generation completes or when
|
|
400
417
|
// the first slide lands, so partial progress is visible during long decks.
|
|
401
418
|
useEffect(() => {
|