@agent-native/core 0.141.7 → 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/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/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 +133 -44
- 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/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/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/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 +7 -9
- package/corpus/templates/slides/_gitignore +1 -0
- 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-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/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 +4 -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 +1 -1
- 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/Index.tsx +91 -1
- 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/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/routes.d.ts +1 -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/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/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/onboarding/app-profile.js +11 -0
- 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 +9 -9
- 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/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/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
|
@@ -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.",
|
|
@@ -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.",
|
|
@@ -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];
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
import PromptPopover, {
|
|
28
28
|
uploadPromptFiles,
|
|
29
29
|
type UploadedFile,
|
|
30
|
+
type PromptImportSelection,
|
|
30
31
|
} from "@/components/editor/PromptDialog";
|
|
31
32
|
import {
|
|
32
33
|
AlertDialog,
|
|
@@ -195,7 +196,7 @@ function describeUploadedFilesForAgent(
|
|
|
195
196
|
"",
|
|
196
197
|
"File handling rules:",
|
|
197
198
|
`- PPTX files: call \`import-pptx --filePath "<path>" --deckId ${deckId}\` before adding or editing slides.`,
|
|
198
|
-
`- PDF and DOCX files: call \`import-file --filePath "<path>" --format auto --deckId ${deckId}\` and use the returned extracted text as source material.
|
|
199
|
+
`- 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.`,
|
|
199
200
|
"- Text-like files: use the uploaded-text-file blocks already included in the prompt; do not call import-file for them.",
|
|
200
201
|
'- Image files with an embeddable URL can be inserted directly into slide HTML as `<img src="...">` or used as visual references.',
|
|
201
202
|
"- 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.",
|
|
@@ -663,9 +664,11 @@ export default function Index() {
|
|
|
663
664
|
deckId +
|
|
664
665
|
'"` 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.',
|
|
665
666
|
"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.",
|
|
667
|
+
"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.",
|
|
666
668
|
"Add slides ONE AT A TIME using the `add-slide` action with --deckId=" +
|
|
667
669
|
deckId +
|
|
668
670
|
". Wait for each `add-slide` result before calling it again; do not batch or parallelize slide writes.",
|
|
671
|
+
"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.",
|
|
669
672
|
"If the user asked for a specific slide count, keep going sequentially until that count is reached unless a tool error blocks you.",
|
|
670
673
|
"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.",
|
|
671
674
|
"Each slide's --content must be full HTML. Slide HTML templates are in your AGENTS.md.",
|
|
@@ -692,6 +695,90 @@ export default function Index() {
|
|
|
692
695
|
[setNewDeckPromptOpen],
|
|
693
696
|
);
|
|
694
697
|
|
|
698
|
+
const handleDirectImport = useCallback(
|
|
699
|
+
async (selection: PromptImportSelection): Promise<boolean> => {
|
|
700
|
+
if (!session) {
|
|
701
|
+
setSignInPromptHadFiles(selection.kind !== "google-slides");
|
|
702
|
+
setShowSignInDialog(true);
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (selection.kind === "google-slides") {
|
|
707
|
+
const imported = (await callAction("import-google-slides-reference", {
|
|
708
|
+
presentationUrl: selection.url,
|
|
709
|
+
})) as { id?: unknown };
|
|
710
|
+
if (typeof imported.id !== "string" || !imported.id) {
|
|
711
|
+
throw new Error(
|
|
712
|
+
"The Google Slides presentation did not create a deck.",
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
await reloadDecks();
|
|
716
|
+
navigate(`/deck/${imported.id}`, { flushSync: true });
|
|
717
|
+
return true;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
const uploaded = await uploadPromptFiles(selection.files);
|
|
721
|
+
const file = uploaded[0];
|
|
722
|
+
if (!file) throw new Error("The selected file could not be uploaded.");
|
|
723
|
+
|
|
724
|
+
if (selection.kind === "pptx") {
|
|
725
|
+
const imported = (await callAction("import-pptx", {
|
|
726
|
+
filePath: file.path,
|
|
727
|
+
})) as { id?: unknown };
|
|
728
|
+
if (typeof imported.id !== "string" || !imported.id) {
|
|
729
|
+
throw new Error("The PowerPoint presentation did not create a deck.");
|
|
730
|
+
}
|
|
731
|
+
await reloadDecks();
|
|
732
|
+
navigate(`/deck/${imported.id}`, { flushSync: true });
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
let deck: ReturnType<typeof createDeck> | undefined;
|
|
737
|
+
flushSync(() => {
|
|
738
|
+
deck = createDeck(undefined, { noDefaultSlides: true });
|
|
739
|
+
});
|
|
740
|
+
if (!deck) throw new Error("The PDF deck could not be created.");
|
|
741
|
+
|
|
742
|
+
const persisted = await ensureDeckPersisted(deck.id);
|
|
743
|
+
if (!persisted.persisted) {
|
|
744
|
+
deleteDeck(deck.id);
|
|
745
|
+
throw new Error(
|
|
746
|
+
describeDeckPersistenceFailure(
|
|
747
|
+
persisted,
|
|
748
|
+
"The PDF deck could not be saved.",
|
|
749
|
+
),
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
try {
|
|
754
|
+
const imported = (await callAction("import-file", {
|
|
755
|
+
filePath: file.path,
|
|
756
|
+
format: "pdf",
|
|
757
|
+
deckId: deck.id,
|
|
758
|
+
importIntoDeck: true,
|
|
759
|
+
})) as { imported?: unknown; deckId?: unknown };
|
|
760
|
+
if (imported.imported !== true || imported.deckId !== deck.id) {
|
|
761
|
+
throw new Error("The PDF could not be imported into the new deck.");
|
|
762
|
+
}
|
|
763
|
+
await reloadDecks();
|
|
764
|
+
navigate(`/deck/${deck.id}`, { flushSync: true });
|
|
765
|
+
return true;
|
|
766
|
+
} catch (error) {
|
|
767
|
+
deleteDeck(deck.id);
|
|
768
|
+
throw error;
|
|
769
|
+
}
|
|
770
|
+
},
|
|
771
|
+
[
|
|
772
|
+
callAction,
|
|
773
|
+
createDeck,
|
|
774
|
+
deleteDeck,
|
|
775
|
+
ensureDeckPersisted,
|
|
776
|
+
navigate,
|
|
777
|
+
reloadDecks,
|
|
778
|
+
session,
|
|
779
|
+
],
|
|
780
|
+
);
|
|
781
|
+
|
|
695
782
|
const handleReferenceSelect = useCallback(
|
|
696
783
|
async (selection: NewDeckReferenceSelection) => {
|
|
697
784
|
const pending = pendingDeck;
|
|
@@ -1151,6 +1238,9 @@ export default function Index() {
|
|
|
1151
1238
|
onSkip={handleCreateDeckBlank}
|
|
1152
1239
|
skipLabel={t("home.skipPrompt")}
|
|
1153
1240
|
onSubmit={handlePromptSubmit}
|
|
1241
|
+
onImport={handleDirectImport}
|
|
1242
|
+
importFromLabel={t("home.importFrom")}
|
|
1243
|
+
importingLabel={t("editorToolbar.importing")}
|
|
1154
1244
|
onBeforeUpload={(prompt, files) => {
|
|
1155
1245
|
if (session) return true;
|
|
1156
1246
|
preservePromptForSignIn(prompt, { hadFiles: files.length > 0 });
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type H3Event,
|
|
17
17
|
} from "h3";
|
|
18
18
|
|
|
19
|
+
import { formatGoogleOAuthError } from "../lib/google-docs-error.js";
|
|
19
20
|
import {
|
|
20
21
|
disconnectGoogleDocs,
|
|
21
22
|
exchangeGoogleDocsCode,
|
|
@@ -25,22 +26,8 @@ import {
|
|
|
25
26
|
isGoogleDocsOAuthConfigured,
|
|
26
27
|
listGoogleDocsAccounts,
|
|
27
28
|
} from "../lib/google-docs-oauth.js";
|
|
28
|
-
|
|
29
29
|
const OAUTH_STATE_APP_ID = process.env.APP_NAME || "slides";
|
|
30
30
|
|
|
31
|
-
function permissionMessage(error: unknown): string {
|
|
32
|
-
const message =
|
|
33
|
-
error instanceof Error ? error.message : String(error || "Unknown error");
|
|
34
|
-
if (
|
|
35
|
-
message.includes("Insufficient Permission") ||
|
|
36
|
-
message.includes("insufficient_scope") ||
|
|
37
|
-
message.includes("access_denied")
|
|
38
|
-
) {
|
|
39
|
-
return "Google Docs access was denied. Connect again and approve the requested Google Drive file permission.";
|
|
40
|
-
}
|
|
41
|
-
return message;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
31
|
async function requireSessionEmail(event: H3Event): Promise<string | null> {
|
|
45
32
|
const session = await getSession(event);
|
|
46
33
|
if (!session?.email) {
|
|
@@ -105,7 +92,7 @@ export const getGoogleDocsAuthUrlHandler = defineEventHandler(
|
|
|
105
92
|
return { url };
|
|
106
93
|
} catch (error) {
|
|
107
94
|
setResponseStatus(event, 500);
|
|
108
|
-
return { error:
|
|
95
|
+
return { error: formatGoogleOAuthError(error) };
|
|
109
96
|
}
|
|
110
97
|
},
|
|
111
98
|
);
|
|
@@ -127,7 +114,7 @@ export const handleGoogleDocsCallback = defineEventHandler(
|
|
|
127
114
|
if (googleError) {
|
|
128
115
|
const errorDesc =
|
|
129
116
|
(query.error_description as string | undefined) || googleError;
|
|
130
|
-
return oauthErrorPage(
|
|
117
|
+
return oauthErrorPage(formatGoogleOAuthError(new Error(errorDesc)));
|
|
131
118
|
}
|
|
132
119
|
|
|
133
120
|
const code = query.code as string | undefined;
|
|
@@ -157,7 +144,7 @@ export const handleGoogleDocsCallback = defineEventHandler(
|
|
|
157
144
|
});
|
|
158
145
|
} catch (error) {
|
|
159
146
|
return oauthErrorPage(
|
|
160
|
-
`Google Docs connection failed: ${
|
|
147
|
+
`Google Docs connection failed: ${formatGoogleOAuthError(error)}`,
|
|
161
148
|
);
|
|
162
149
|
}
|
|
163
150
|
},
|
|
@@ -183,7 +170,7 @@ export const getGoogleDocsStatus = defineEventHandler(
|
|
|
183
170
|
};
|
|
184
171
|
} catch (error) {
|
|
185
172
|
setResponseStatus(event, 500);
|
|
186
|
-
return { error:
|
|
173
|
+
return { error: formatGoogleOAuthError(error) };
|
|
187
174
|
}
|
|
188
175
|
},
|
|
189
176
|
);
|
|
@@ -230,7 +217,7 @@ export const getGoogleDocsPickerToken = defineEventHandler(
|
|
|
230
217
|
};
|
|
231
218
|
} catch (error) {
|
|
232
219
|
setResponseStatus(event, 401);
|
|
233
|
-
return { error:
|
|
220
|
+
return { error: formatGoogleOAuthError(error) };
|
|
234
221
|
}
|
|
235
222
|
},
|
|
236
223
|
);
|
|
@@ -247,7 +234,7 @@ export const disconnectGoogleDocsHandler = defineEventHandler(
|
|
|
247
234
|
return { ok: true };
|
|
248
235
|
} catch (error) {
|
|
249
236
|
setResponseStatus(event, 500);
|
|
250
|
-
return { error:
|
|
237
|
+
return { error: formatGoogleOAuthError(error) };
|
|
251
238
|
}
|
|
252
239
|
},
|
|
253
240
|
);
|