@agent-native/core 0.141.7 → 0.144.1
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/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 +35 -38
- 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 +1 -1
- package/corpus/templates/analytics/actions/navigate.ts +4 -5
- package/corpus/templates/analytics/actions/provider-api-register.ts +50 -0
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +44 -11
- package/corpus/templates/analytics/actions/test-custom-api-connection.ts +106 -0
- package/corpus/templates/analytics/app/components/CustomApiCard.tsx +430 -0
- package/corpus/templates/analytics/app/i18n-data.ts +680 -0
- 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/DataSources.tsx +4 -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/netlify.toml +7 -0
- package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +4 -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/dashboards-store.ts +227 -60
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +156 -45
- package/corpus/templates/analytics/server/lib/native-v2-dashboards.ts +227 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +5 -0
- 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 +28 -2
- package/corpus/templates/assets/.agents/skills/image-generation/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/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/sources.tsx +15 -7
- 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/hooks/use-events.ts +4 -1
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- 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/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/player/delete-recording-menu.tsx +14 -3
- package/corpus/templates/clips/app/components/player/player-controls.tsx +0 -3
- package/corpus/templates/clips/app/components/player/scrubber.tsx +2 -33
- package/corpus/templates/clips/app/components/player/video-player.tsx +58 -11
- 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/changelog/2026-08-06-trimmed-clips-play-on-a-clean-timeline-without-cut-markers.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/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/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/import-from-url.ts +1 -1
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +27 -18
- package/corpus/templates/design/app/pages/Index.tsx +6 -2
- 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/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/AGENTS.md +8 -1
- package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -0
- package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +30 -15
- package/corpus/templates/dispatch/app/i18n-data.ts +131 -0
- package/corpus/templates/dispatch/app/routes/admin._index.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.agents.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.approvals.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.$appId.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.apps.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.audit.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.automations.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.destinations.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.dreams.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.identities.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.integrations.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.messaging.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.metrics.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.new-app.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.operations.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.thread-debug.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.transactional-email.$appId.$id.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.transactional-email.tsx +4 -0
- package/corpus/templates/dispatch/app/routes/admin.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.vault.tsx +1 -0
- package/corpus/templates/dispatch/app/routes/admin.workspace.tsx +1 -0
- package/corpus/templates/dispatch/changelog/2026-08-06-dispatch-keeps-everyday-navigation-focused-while-management-.md +6 -0
- 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/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/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/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/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/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/slides/.agents/skills/create-deck/SKILL.md +48 -5
- package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +37 -1
- 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 +17 -21
- package/corpus/templates/slides/_gitignore +1 -0
- package/corpus/templates/slides/actions/export-pptx.ts +470 -36
- package/corpus/templates/slides/actions/get-deck.ts +12 -0
- package/corpus/templates/slides/actions/import-file.ts +175 -139
- package/corpus/templates/slides/actions/import-google-slides-reference.ts +271 -12
- package/corpus/templates/slides/actions/import-pptx.ts +193 -68
- package/corpus/templates/slides/actions/patch-deck.ts +51 -0
- package/corpus/templates/slides/actions/update-slide.ts +29 -3
- package/corpus/templates/slides/app/components/deck/DeckCard.tsx +10 -13
- 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 +173 -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 +15 -0
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +27 -1
- package/corpus/templates/slides/app/i18n/en-US.ts +1 -0
- package/corpus/templates/slides/app/lib/create-deck-generation.ts +72 -11
- 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/import-uploaded-deck.ts +89 -0
- package/corpus/templates/slides/app/lib/slide-animation-elements.ts +3 -0
- package/corpus/templates/slides/app/pages/Index.tsx +172 -15
- 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/changelog/2026-08-06-uploaded-decks-keep-their-slides-and-visuals-when-you-improv.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 +247 -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 +7 -4
- 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/lib/source-import.ts +167 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +12 -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/dist/agent/production-agent.d.ts +17 -0
- package/dist/agent/production-agent.js +72 -1
- 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.js +123 -4
- package/dist/client/assistant-ui-recovery.d.ts +2 -1
- package/dist/client/assistant-ui-recovery.js +7 -3
- package/dist/client/onboarding/FirstRunOnboarding.js +11 -4
- package/dist/client/org/TeamPage.js +1 -1
- package/dist/client/require-session.js +1 -1
- 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/settings/AccountSettingsCard.js +2 -1
- package/dist/collab/struct-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/file-upload/actions/upload-image.d.ts +1 -1
- 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/integrations/plugin.js +9 -6
- package/dist/jobs/scheduler.js +79 -23
- package/dist/localization/default-messages.d.ts +54 -0
- package/dist/localization/default-messages.js +57 -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 +73 -6
- package/dist/observability/routes.d.ts +5 -5
- package/dist/onboarding/app-profile.js +11 -0
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/resources/store.js +15 -1
- package/dist/scripts/call-agent.js +34 -4
- package/dist/secrets/routes.d.ts +3 -3
- 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 +47 -11
- 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/onboarding-html.d.ts +2 -0
- package/dist/server/onboarding-html.js +115 -29
- 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/transcribe-voice.d.ts +1 -1
- package/dist/shared/cache-control.d.ts +26 -2
- package/dist/shared/cache-control.js +43 -2
- package/dist/shared/password-policy.d.ts +3 -0
- package/dist/shared/password-policy.js +3 -0
- 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/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/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/creating-templates.mdx +1 -1
- package/docs/content/getting-started-actions.mdx +38 -189
- package/docs/content/getting-started-database.mdx +80 -164
- package/docs/content/getting-started-pages.mdx +44 -155
- package/docs/content/getting-started.mdx +26 -106
- package/docs/content/skills-guide.mdx +13 -0
- 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/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/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
|
@@ -29,6 +29,8 @@ import {
|
|
|
29
29
|
type RecentReference,
|
|
30
30
|
} from "@/lib/recent-references";
|
|
31
31
|
|
|
32
|
+
import { MAX_REFERENCE_FILE_BYTES } from "../../../shared/upload-types";
|
|
33
|
+
|
|
32
34
|
type FirstDeckStep = "prompt" | "references";
|
|
33
35
|
|
|
34
36
|
export function FirstDeckOnboardingFlow({
|
|
@@ -155,6 +157,17 @@ export function FirstDeckOnboardingFlow({
|
|
|
155
157
|
),
|
|
156
158
|
});
|
|
157
159
|
},
|
|
160
|
+
onSetupFailure: (failedPrompt, _failedFiles, failure) => {
|
|
161
|
+
setPromptInitialText(failedPrompt);
|
|
162
|
+
setPromptInitialTextKey(Date.now());
|
|
163
|
+
setStep("prompt");
|
|
164
|
+
toast.error(t("home.generationStartFailed"), {
|
|
165
|
+
description:
|
|
166
|
+
failure instanceof Error
|
|
167
|
+
? failure.message
|
|
168
|
+
: t("home.generationStartFailedDescription"),
|
|
169
|
+
});
|
|
170
|
+
},
|
|
158
171
|
});
|
|
159
172
|
if (result === "started") onComplete();
|
|
160
173
|
},
|
|
@@ -303,6 +316,8 @@ export function FirstDeckOnboardingFlow({
|
|
|
303
316
|
className="mt-8"
|
|
304
317
|
autoFocus
|
|
305
318
|
attachmentsEnabled
|
|
319
|
+
maxDocumentAttachmentBytes={MAX_REFERENCE_FILE_BYTES}
|
|
320
|
+
documentAttachmentLimitLabel="Slides reference files"
|
|
306
321
|
disabled={uploading}
|
|
307
322
|
placeholder={t("home.newDeckPlaceholder")}
|
|
308
323
|
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
|
|
|
@@ -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.",
|
|
@@ -6,6 +6,10 @@ import type { NewDeckReferenceSelection } from "@/components/editor/NewDeckRefer
|
|
|
6
6
|
import type { UploadedFile } from "@/components/editor/PromptDialog";
|
|
7
7
|
import type { Deck, DeckPersistenceResult } from "@/context/DeckContext";
|
|
8
8
|
import { createDeckAgentMessage } from "@/lib/agent-visible-message";
|
|
9
|
+
import {
|
|
10
|
+
importUploadedDeckIntoDeck,
|
|
11
|
+
type ImportedSourceDeck,
|
|
12
|
+
} from "@/lib/import-uploaded-deck";
|
|
9
13
|
|
|
10
14
|
interface DesignSystemGenerationContextResult {
|
|
11
15
|
agentContext?: string;
|
|
@@ -85,6 +89,7 @@ async function loadReferenceDeckGenerationContext(
|
|
|
85
89
|
function describeUploadedFilesForAgent(
|
|
86
90
|
files: UploadedFile[],
|
|
87
91
|
deckId: string,
|
|
92
|
+
importedSourceDeck?: ImportedSourceDeck | null,
|
|
88
93
|
): string {
|
|
89
94
|
if (files.length === 0) return "";
|
|
90
95
|
const fileList = files
|
|
@@ -93,14 +98,21 @@ function describeUploadedFilesForAgent(
|
|
|
93
98
|
`- ${file.originalName} (${file.type}, ${(file.size / 1024).toFixed(1)}KB) at path: ${file.path}${file.url ? `; embeddable URL: ${file.url}` : ""}`,
|
|
94
99
|
)
|
|
95
100
|
.join("\n");
|
|
101
|
+
const sourceFile = importedSourceDeck?.file;
|
|
96
102
|
return [
|
|
97
103
|
"",
|
|
98
|
-
|
|
104
|
+
importedSourceDeck
|
|
105
|
+
? `The user uploaded ${files.length} file(s). The ${sourceFile?.originalName ?? importedSourceDeck.format.toUpperCase()} source deck has already been imported into target deck ${deckId} with ${importedSourceDeck.slideCount} source slide(s); do not import it again.`
|
|
106
|
+
: `The user uploaded ${files.length} file(s). These paths are real uploaded files; process them with import actions before using their contents:`,
|
|
99
107
|
fileList,
|
|
100
108
|
"",
|
|
101
109
|
"File handling rules:",
|
|
102
|
-
|
|
103
|
-
|
|
110
|
+
importedSourceDeck
|
|
111
|
+
? "- The imported source deck is the canonical source. Preserve its slide count, order, IDs, factual copy, notes, imagery, charts, tables, diagrams, and freeform objects while improving styling. Use update-slide on existing slide IDs; do not rebuild it with add-slide."
|
|
112
|
+
: `- PPTX files: call \`import-pptx --filePath \"<path>\" --deckId ${deckId}\` before adding or editing slides.`,
|
|
113
|
+
importedSourceDeck
|
|
114
|
+
? "- For a PDF source, keep the original full-page image in every slide and add restrained design-system chrome around it without obscuring source content. Never OCR-reconstruct a source-faithful page from extracted text."
|
|
115
|
+
: `- 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
116
|
"- Text-like files: use the uploaded-text-file blocks already included in the prompt; do not call import-file for them.",
|
|
105
117
|
'- Image files with an embeddable URL can be inserted directly into slide HTML as `<img src="...">` or used as visual references.',
|
|
106
118
|
"- 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.",
|
|
@@ -161,6 +173,11 @@ export interface StartDeckGenerationOptions {
|
|
|
161
173
|
files: UploadedFile[],
|
|
162
174
|
failure: DeckPersistenceResult,
|
|
163
175
|
) => void;
|
|
176
|
+
onSetupFailure: (
|
|
177
|
+
prompt: string,
|
|
178
|
+
files: UploadedFile[],
|
|
179
|
+
failure: unknown,
|
|
180
|
+
) => void;
|
|
164
181
|
}
|
|
165
182
|
|
|
166
183
|
/** Create the optimistic deck, hydrate references, and start the agent run. */
|
|
@@ -181,6 +198,7 @@ export async function startDeckGeneration({
|
|
|
181
198
|
onPromptClosed,
|
|
182
199
|
onUnauthenticated,
|
|
183
200
|
onPersistenceFailure,
|
|
201
|
+
onSetupFailure,
|
|
184
202
|
}: StartDeckGenerationOptions): Promise<
|
|
185
203
|
"started" | "failed" | "unauthenticated"
|
|
186
204
|
> {
|
|
@@ -215,7 +233,6 @@ export async function startDeckGeneration({
|
|
|
215
233
|
});
|
|
216
234
|
if (!deck) return "failed";
|
|
217
235
|
const deckId = deck.id;
|
|
218
|
-
onPromptClosed();
|
|
219
236
|
|
|
220
237
|
const persisted = await ensureDeckPersisted(deck.id);
|
|
221
238
|
if (!persisted.persisted) {
|
|
@@ -224,6 +241,20 @@ export async function startDeckGeneration({
|
|
|
224
241
|
return "failed";
|
|
225
242
|
}
|
|
226
243
|
|
|
244
|
+
let importedSourceDeck: ImportedSourceDeck | null = null;
|
|
245
|
+
try {
|
|
246
|
+
importedSourceDeck = await importUploadedDeckIntoDeck(
|
|
247
|
+
filesForGeneration,
|
|
248
|
+
deckId,
|
|
249
|
+
);
|
|
250
|
+
} catch (error) {
|
|
251
|
+
deleteDeck(deckId);
|
|
252
|
+
onSetupFailure(prompt, filesForGeneration, error);
|
|
253
|
+
return "failed";
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
onPromptClosed();
|
|
257
|
+
|
|
227
258
|
navigate(`/deck/${deck.id}`, { flushSync: true });
|
|
228
259
|
|
|
229
260
|
const trimmedPrompt = prompt.trim();
|
|
@@ -231,7 +262,11 @@ export async function startDeckGeneration({
|
|
|
231
262
|
const googleDocUrls = hasImportedGoogleDocContext
|
|
232
263
|
? []
|
|
233
264
|
: extractGoogleDocUrls(trimmedPrompt);
|
|
234
|
-
const fileContext = describeUploadedFilesForAgent(
|
|
265
|
+
const fileContext = describeUploadedFilesForAgent(
|
|
266
|
+
filesForGeneration,
|
|
267
|
+
deckId,
|
|
268
|
+
importedSourceDeck,
|
|
269
|
+
);
|
|
235
270
|
const googleDocContext =
|
|
236
271
|
googleDocUrls.length > 0
|
|
237
272
|
? [
|
|
@@ -260,7 +295,9 @@ export async function startDeckGeneration({
|
|
|
260
295
|
: [
|
|
261
296
|
"",
|
|
262
297
|
"Design system selection:",
|
|
263
|
-
"-
|
|
298
|
+
"- No design system was selected in the picker.",
|
|
299
|
+
"- Before generating a bare or on-brand deck, call `get-workspace-defaults`. If it returns a usable design system, patch this deck with that designSystemId, call `get-design-system`, and follow its exact tokens, assets, and custom instructions.",
|
|
300
|
+
"- If no workspace default exists, use the product's configured design-system action and report the missing configuration instead of inventing a generic Builder-like palette.",
|
|
264
301
|
].join("\n");
|
|
265
302
|
const referenceSource = referenceSelection.referenceSource;
|
|
266
303
|
const referenceSourceContext = referenceSource
|
|
@@ -275,21 +312,45 @@ export async function startDeckGeneration({
|
|
|
275
312
|
: "Use the Figma source as the design reference. If Builder or Figma access is required, report the exact connection step instead of guessing.",
|
|
276
313
|
].join("\n")
|
|
277
314
|
: "";
|
|
315
|
+
const sourceDeckContext = importedSourceDeck
|
|
316
|
+
? [
|
|
317
|
+
"",
|
|
318
|
+
"Source-preserving improvement mode:",
|
|
319
|
+
`- The target deck already contains ${importedSourceDeck.slideCount} imported source slides. Treat those slides as the user's complete source, not as inspiration for a new deck.`,
|
|
320
|
+
"- Keep the exact source slide count, order, IDs, factual meaning, notes, images, charts, tables, diagrams, and freeform objects unless the user explicitly asks to change one of them.",
|
|
321
|
+
"- Read `get-deck` before editing, load the linked design system with `get-design-system`, then use one `update-slide` call per existing slide ID for bounded visual improvements. Keep every original `<img>` source and enough original factual copy for each slide; for PDF slides, use restrained design-system chrome around the page without obscuring it.",
|
|
322
|
+
"- Do not call `add-slide`, delete slides, reorder slides, or replace source images with generic cards. Do not claim success until `get-deck` verifies the same slide IDs and count after the edits.",
|
|
323
|
+
"- If `get-deck` reports partial source fidelity or skipped images, stop and report the exact warning instead of claiming a reliable restyle.",
|
|
324
|
+
].join("\n")
|
|
325
|
+
: "";
|
|
326
|
+
const sourceModeInstructions = importedSourceDeck
|
|
327
|
+
? [
|
|
328
|
+
"The request is an in-place visual improvement of an imported source deck. Make a coherent style pass across every existing slide while preserving all source content and media.",
|
|
329
|
+
"Do not use the new-deck add-slide workflow for this source-preserving request.",
|
|
330
|
+
]
|
|
331
|
+
: [
|
|
332
|
+
"Start a `manage-progress` run so progress appears in the app header. Add the first slide as soon as it is ready, then continue one slide at a time so the editor visibly fills in.",
|
|
333
|
+
`After reading any requested or imported source material, but before adding the first slide, choose a concise, specific deck title from the user's request and source material. Call \`patch-deck\` with \`deckId: \"${deckId}\"\` and \`operations: [{ \"op\": \"patch-deck-fields\", \"fields\": { \"title\": \"<generated title>\" } }]\`. Include only \`title\` in \`fields\`; omit all other optional fields. Never leave a generated deck named \"Untitled Deck\" or another placeholder.`,
|
|
334
|
+
"If the user asks for a standalone visual, diagram, hero, one-pager, poster, or a couple of visuals, create only the requested one/few polished visual slides. Do not pad the result into a full presentation.",
|
|
335
|
+
"If the request is for a presentation or deck and does not explicitly ask for one slide, infer a coherent multi-slide outline from the scope and keep adding slides until that outline is complete. Do not stop after the first slide just because the prompt has few explicit instructions.",
|
|
336
|
+
`Add slides ONE AT A TIME using the \`add-slide\` action with --deckId=${deckId}. Wait for each \`add-slide\` result before calling it again; do not batch or parallelize slide writes.`,
|
|
337
|
+
"Use create-deck and add-slide for this already-created deck. Do not call the legacy generate-slides-ai action: it returns Markdown drafts rather than persisted rendered slide HTML. Treat each successful add-slide result as confirmation to continue with the next planned slide.",
|
|
338
|
+
].join("\n");
|
|
278
339
|
|
|
279
340
|
const context = [
|
|
280
|
-
|
|
341
|
+
importedSourceDeck
|
|
342
|
+
? `The user uploaded a source presentation into target deck (id: "${deckId}") and wants a reliable visual improvement.`
|
|
343
|
+
: `The user just created a new empty deck (id: "${deckId}") and wants to create a presentation or standalone visual.`,
|
|
281
344
|
"The visible user message above contains the user's request and/or pasted source material for the deck. Treat pasted memo content as source material even if the user did not explicitly say they are pasting it.",
|
|
282
345
|
googleDocContext,
|
|
283
346
|
fileContext,
|
|
284
347
|
referenceDeckContext,
|
|
285
348
|
designSystemContext,
|
|
286
349
|
referenceSourceContext,
|
|
350
|
+
sourceDeckContext,
|
|
287
351
|
"",
|
|
288
352
|
"Before generating, if the request or selected references leave a meaningful choice unresolved, use the `ask-question` tool to ask one concise, prompt-specific question in the inline guided-question flow. Generate the question wording and 2 to 4 options from the user's request and selected references, like Claude's design-question flow; do not use a fixed generic questionnaire. Ask only a choice that materially affects the deck, such as audience, tone, structure, or length. If the prompt already makes the choice clear, do not ask it again. Wait for the user's answer or skip before adding slides.",
|
|
289
|
-
|
|
290
|
-
`After reading any requested or imported source material, but before adding the first slide, choose a concise, specific deck title from the user's request and source material. Call \`patch-deck\` with \`deckId: \"${deckId}\"\` and \`operations: [{ \"op\": \"patch-deck-fields\", \"fields\": { \"title\": \"<generated title>\" } }]\`. Include only \`title\` in \`fields\`; omit all other optional fields. Never leave a generated deck named \"Untitled Deck\" or another placeholder.`,
|
|
291
|
-
"If the user asks for a standalone visual, diagram, hero, one-pager, poster, or a couple of visuals, create only the requested one/few polished visual slides. Do not pad the result into a full presentation.",
|
|
292
|
-
`Add slides ONE AT A TIME using the \`add-slide\` action with --deckId=${deckId}. Wait for each \`add-slide\` result before calling it again; do not batch or parallelize slide writes.`,
|
|
353
|
+
sourceModeInstructions,
|
|
293
354
|
"If the user asked for a specific slide count, keep going sequentially until that count is reached unless a tool error blocks you.",
|
|
294
355
|
"Every slide is rendered into a fixed native canvas (default 16:9 is 960x540 CSS pixels, with 740x380px available inside standard 80px 110px padding). Keep the main content within that fit budget; split dense source material across more slides instead of packing it tightly. Never use zoom, transform: scale(), clipping, or scroll overflow to hide content overflow, and keep body text at least 16px.",
|
|
295
356
|
"Each slide's --content must be full HTML. Slide HTML templates are in your AGENTS.md.",
|
|
@@ -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);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { callAction } from "@agent-native/core/client/hooks";
|
|
2
|
+
|
|
3
|
+
import type { UploadedFile } from "@/components/editor/PromptDialog";
|
|
4
|
+
|
|
5
|
+
export type ImportedSourceDeck = {
|
|
6
|
+
file: UploadedFile;
|
|
7
|
+
format: "pdf" | "pptx";
|
|
8
|
+
slideCount: number;
|
|
9
|
+
imagesSkipped: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function sourceFormat(file: UploadedFile): "pdf" | "pptx" | null {
|
|
13
|
+
const name = file.originalName.toLowerCase();
|
|
14
|
+
if (name.endsWith(".pptx")) return "pptx";
|
|
15
|
+
if (name.endsWith(".pdf")) return "pdf";
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function actionResultRecord(value: unknown): Record<string, unknown> {
|
|
20
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
21
|
+
throw new Error("The uploaded presentation import returned no result.");
|
|
22
|
+
}
|
|
23
|
+
return value as Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Imports the user's source deck into the already-persisted target deck before
|
|
28
|
+
* the agent run starts. This keeps the agent on the source slide IDs and
|
|
29
|
+
* preserves source-native images instead of asking it to reconstruct a deck
|
|
30
|
+
* from extracted text.
|
|
31
|
+
*/
|
|
32
|
+
export async function importUploadedDeckIntoDeck(
|
|
33
|
+
files: UploadedFile[],
|
|
34
|
+
deckId: string,
|
|
35
|
+
): Promise<ImportedSourceDeck | null> {
|
|
36
|
+
const deckFiles = files.filter((file) => sourceFormat(file));
|
|
37
|
+
if (deckFiles.length === 0) return null;
|
|
38
|
+
if (deckFiles.length > 1) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
"Upload one presentation at a time when asking Slides to improve it. Multiple source decks cannot be merged safely without losing slide order or content.",
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const file = deckFiles[0];
|
|
45
|
+
if (!file) return null;
|
|
46
|
+
const format = sourceFormat(file);
|
|
47
|
+
if (!format) return null;
|
|
48
|
+
|
|
49
|
+
const result = actionResultRecord(
|
|
50
|
+
await callAction(
|
|
51
|
+
format === "pptx" ? "import-pptx" : "import-file",
|
|
52
|
+
format === "pptx"
|
|
53
|
+
? { filePath: file.path, deckId }
|
|
54
|
+
: {
|
|
55
|
+
filePath: file.path,
|
|
56
|
+
format: "pdf",
|
|
57
|
+
deckId,
|
|
58
|
+
importIntoDeck: true,
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
);
|
|
62
|
+
if (result.imported !== true || result.deckId !== deckId) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`The ${format.toUpperCase()} source deck was not imported into the target deck, so no source-preserving improvement was started.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const slideCount = result.slideCount;
|
|
69
|
+
if (typeof slideCount !== "number" || !Number.isInteger(slideCount)) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`The ${format.toUpperCase()} import did not report a reliable slide count, so no source-preserving improvement was started.`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (slideCount < 1) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`The ${format.toUpperCase()} source deck contained no importable slides.`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const imagesSkipped =
|
|
81
|
+
typeof result.imagesSkipped === "number" ? result.imagesSkipped : 0;
|
|
82
|
+
if (imagesSkipped > 0) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`The ${format.toUpperCase()} source deck could not preserve ${imagesSkipped} image(s), so Slides stopped before restyling it. Re-export the deck with browser-renderable images, or upload a PDF for source-faithful page preservation.`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return { file, format, slideCount, imagesSkipped };
|
|
89
|
+
}
|
|
@@ -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];
|