@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
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export const RECORDING_START_TIMEOUT_MS = 90_000;
|
|
2
|
+
|
|
3
|
+
export class RecordingStartTimeoutError extends Error {
|
|
4
|
+
constructor(timeoutMs: number) {
|
|
5
|
+
super(
|
|
6
|
+
`Recording setup timed out after ${Math.ceil(timeoutMs / 1000)} seconds.`,
|
|
7
|
+
);
|
|
8
|
+
this.name = "TimeoutError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class RecordingStartCancelledError extends Error {
|
|
13
|
+
constructor() {
|
|
14
|
+
super("Recording setup was cancelled.");
|
|
15
|
+
this.name = "AbortError";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function guardRecordingStart<T>(
|
|
20
|
+
operation: Promise<T>,
|
|
21
|
+
options: {
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
onCancel?: () => void;
|
|
25
|
+
onLateResolve?: (value: T) => void;
|
|
26
|
+
} = {},
|
|
27
|
+
): Promise<T> {
|
|
28
|
+
const timeoutMs = options.timeoutMs ?? RECORDING_START_TIMEOUT_MS;
|
|
29
|
+
|
|
30
|
+
return new Promise<T>((resolve, reject) => {
|
|
31
|
+
let settled = false;
|
|
32
|
+
let cancellationNotified = false;
|
|
33
|
+
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
34
|
+
|
|
35
|
+
const notifyCancellation = () => {
|
|
36
|
+
if (cancellationNotified) return;
|
|
37
|
+
cancellationNotified = true;
|
|
38
|
+
options.onCancel?.();
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const cleanup = () => {
|
|
42
|
+
if (timer) {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
timer = null;
|
|
45
|
+
}
|
|
46
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const finish = (callback: () => void) => {
|
|
50
|
+
if (settled) return;
|
|
51
|
+
settled = true;
|
|
52
|
+
cleanup();
|
|
53
|
+
callback();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const onAbort = () => {
|
|
57
|
+
notifyCancellation();
|
|
58
|
+
finish(() => reject(new RecordingStartCancelledError()));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (options.signal?.aborted) {
|
|
62
|
+
onAbort();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
66
|
+
|
|
67
|
+
operation.then(
|
|
68
|
+
(value) => {
|
|
69
|
+
if (settled) {
|
|
70
|
+
options.onLateResolve?.(value);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
finish(() => resolve(value));
|
|
74
|
+
},
|
|
75
|
+
(error) => {
|
|
76
|
+
finish(() => reject(error));
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
timer = setTimeout(() => {
|
|
80
|
+
notifyCancellation();
|
|
81
|
+
finish(() => reject(new RecordingStartTimeoutError(timeoutMs)));
|
|
82
|
+
}, timeoutMs);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -81,12 +81,14 @@ export function Toolbar() {
|
|
|
81
81
|
|
|
82
82
|
useEffect(() => {
|
|
83
83
|
const unlistens: Array<() => void> = [];
|
|
84
|
+
const listenerPromises: Array<Promise<() => void>> = [];
|
|
84
85
|
let stopped = false;
|
|
85
86
|
// Same race-safe listen tracker as elsewhere: if this effect
|
|
86
87
|
// cleans up before `listen()` resolves, the unlisten is called
|
|
87
88
|
// immediately — otherwise the listener lingers for the life of
|
|
88
89
|
// the webview, holding the setState closures captive.
|
|
89
90
|
const trackListen = (p: Promise<() => void>) => {
|
|
91
|
+
listenerPromises.push(p);
|
|
90
92
|
p.then((u) => {
|
|
91
93
|
if (stopped) {
|
|
92
94
|
try {
|
|
@@ -133,6 +135,11 @@ export function Toolbar() {
|
|
|
133
135
|
}
|
|
134
136
|
}),
|
|
135
137
|
);
|
|
138
|
+
trackListen(
|
|
139
|
+
listen("clips:toolbar-sync", () => {
|
|
140
|
+
emit("clips:toolbar-ready", {}).catch(() => {});
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
136
143
|
trackListen(
|
|
137
144
|
listen<boolean>("clips:toolbar-preparing", (ev) => {
|
|
138
145
|
setPreparing(!!ev.payload);
|
|
@@ -160,6 +167,9 @@ export function Toolbar() {
|
|
|
160
167
|
setDiskSpaceLevel("ok");
|
|
161
168
|
}),
|
|
162
169
|
);
|
|
170
|
+
void Promise.allSettled(listenerPromises).then(() => {
|
|
171
|
+
if (!stopped) emit("clips:toolbar-ready", {}).catch(() => {});
|
|
172
|
+
});
|
|
163
173
|
return () => {
|
|
164
174
|
stopped = true;
|
|
165
175
|
unlistens.forEach((u) => {
|
|
@@ -262,7 +272,7 @@ export function Toolbar() {
|
|
|
262
272
|
});
|
|
263
273
|
}
|
|
264
274
|
function cancel() {
|
|
265
|
-
if (pendingAction
|
|
275
|
+
if (pendingAction) return;
|
|
266
276
|
setPendingAction("cancel");
|
|
267
277
|
console.log(
|
|
268
278
|
"[clips-toolbar] cancel clicked — emitting clips:recorder-cancel",
|
|
@@ -418,14 +428,14 @@ export function Toolbar() {
|
|
|
418
428
|
<button
|
|
419
429
|
className="toolbar-v-action toolbar-v-action-danger"
|
|
420
430
|
onClick={cancel}
|
|
421
|
-
disabled={
|
|
422
|
-
aria-label="Cancel recording"
|
|
431
|
+
disabled={!!pendingAction}
|
|
432
|
+
aria-label={enabled ? "Cancel recording" : "Cancel recording setup"}
|
|
423
433
|
title={
|
|
424
434
|
pendingAction === "cancel"
|
|
425
435
|
? pendingActionLabel
|
|
426
436
|
: enabled
|
|
427
437
|
? "Cancel"
|
|
428
|
-
: "
|
|
438
|
+
: "Cancel recording setup"
|
|
429
439
|
}
|
|
430
440
|
data-no-drag
|
|
431
441
|
>
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
|
|
1
3
|
import {
|
|
2
4
|
runMigrations,
|
|
5
|
+
deferMigration,
|
|
3
6
|
getDbExec,
|
|
4
7
|
isPostgres,
|
|
5
8
|
ensureAdditiveColumns,
|
|
9
|
+
type MigrationRunResult,
|
|
6
10
|
} from "@agent-native/core/db";
|
|
7
11
|
import { registerEvent } from "@agent-native/core/event-bus";
|
|
8
12
|
import { z } from "zod";
|
|
@@ -67,14 +71,52 @@ async function retypeBooleanColumnsOnPostgres(): Promise<void> {
|
|
|
67
71
|
["meeting_participants", "is_organizer", false],
|
|
68
72
|
["clips_meetings", "share_transcript", false],
|
|
69
73
|
];
|
|
74
|
+
// One probe for all of them, not one per column. This runs on every cold
|
|
75
|
+
// start, and eleven serialized information_schema round-trips before the
|
|
76
|
+
// process can serve is exactly the startup cost that made these apps slow —
|
|
77
|
+
// the same reason `ensureAdditiveColumns` batches its own introspection.
|
|
78
|
+
// After the first deploy every column already matches and the loop below
|
|
79
|
+
// does nothing, so the probes were the entire remaining cost.
|
|
80
|
+
const typesByColumn = new Map<string, string>();
|
|
81
|
+
try {
|
|
82
|
+
const probe = await exec.execute({
|
|
83
|
+
// `information_schema` columns are the `name` type; the explicit
|
|
84
|
+
// ::text[] casts are what make the comparison legal.
|
|
85
|
+
sql: `SELECT table_name, column_name, data_type
|
|
86
|
+
FROM information_schema.columns
|
|
87
|
+
WHERE table_name = ANY($1::text[]) AND column_name = ANY($2::text[])`,
|
|
88
|
+
args: [
|
|
89
|
+
`{${[...new Set(alters.map(([t]) => t))].join(",")}}`,
|
|
90
|
+
`{${[...new Set(alters.map(([, c]) => c))].join(",")}}`,
|
|
91
|
+
],
|
|
92
|
+
});
|
|
93
|
+
for (const row of probe.rows as Array<{
|
|
94
|
+
table_name?: string;
|
|
95
|
+
column_name?: string;
|
|
96
|
+
data_type?: string;
|
|
97
|
+
}>) {
|
|
98
|
+
if (row.table_name && row.column_name && row.data_type) {
|
|
99
|
+
typesByColumn.set(
|
|
100
|
+
`${row.table_name}.${row.column_name}`,
|
|
101
|
+
row.data_type,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
} catch (err) {
|
|
106
|
+
// Probing is the optimization; a failure here must not skip the retype and
|
|
107
|
+
// silently leave int columns behind. Fall through with an empty map so each
|
|
108
|
+
// column is attempted individually below, as it was before batching.
|
|
109
|
+
console.warn(
|
|
110
|
+
"[db] batched boolean-column probe failed; retrying per column:",
|
|
111
|
+
(err as Error)?.message ?? err,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
70
115
|
for (const [table, column, defaultTrue] of alters) {
|
|
71
116
|
try {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
76
|
-
const row = (probe.rows as Array<{ data_type?: string }>)[0];
|
|
77
|
-
if (!row || row.data_type === "boolean") continue;
|
|
117
|
+
const known = typesByColumn.get(`${table}.${column}`);
|
|
118
|
+
if (known === "boolean") continue;
|
|
119
|
+
if (!known && typesByColumn.size > 0) continue; // absent column, nothing to retype
|
|
78
120
|
const def = defaultTrue ? "TRUE" : "FALSE";
|
|
79
121
|
await exec.execute(
|
|
80
122
|
`ALTER TABLE ${table} ALTER COLUMN ${column} DROP DEFAULT, ALTER COLUMN ${column} TYPE BOOLEAN USING (${column} <> 0), ALTER COLUMN ${column} SET DEFAULT ${def}`,
|
|
@@ -89,6 +131,107 @@ async function retypeBooleanColumnsOnPostgres(): Promise<void> {
|
|
|
89
131
|
}
|
|
90
132
|
}
|
|
91
133
|
|
|
134
|
+
const RECORDING_ORG_ID_BACKFILL_BATCH_SIZE = 250;
|
|
135
|
+
const RECORDING_ORG_ID_BACKFILL_LEASE_MS = 30_000;
|
|
136
|
+
const RECORDING_ORG_ID_BACKFILL_DELAY_MS = 100;
|
|
137
|
+
const RECORDING_ORG_ID_BACKFILL_LEASE_KEY = "recording-org-id";
|
|
138
|
+
const recordingOrgIdBackfillHolder = randomUUID();
|
|
139
|
+
|
|
140
|
+
async function acquireRecordingOrgIdBackfillLease(): Promise<boolean> {
|
|
141
|
+
const exec = getDbExec();
|
|
142
|
+
const now = Date.now();
|
|
143
|
+
const expiresAt = now + RECORDING_ORG_ID_BACKFILL_LEASE_MS;
|
|
144
|
+
await exec.execute({
|
|
145
|
+
sql: `INSERT INTO clips_backfill_leases (lease_key, holder, expires_at)
|
|
146
|
+
VALUES (?, ?, ?)
|
|
147
|
+
ON CONFLICT (lease_key) DO UPDATE SET
|
|
148
|
+
holder = excluded.holder,
|
|
149
|
+
expires_at = excluded.expires_at
|
|
150
|
+
WHERE clips_backfill_leases.expires_at <= ?`,
|
|
151
|
+
args: [
|
|
152
|
+
RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
|
|
153
|
+
recordingOrgIdBackfillHolder,
|
|
154
|
+
expiresAt,
|
|
155
|
+
now,
|
|
156
|
+
],
|
|
157
|
+
});
|
|
158
|
+
const result = await exec.execute({
|
|
159
|
+
sql: `SELECT holder FROM clips_backfill_leases
|
|
160
|
+
WHERE lease_key = ? AND holder = ? AND expires_at > ?`,
|
|
161
|
+
args: [
|
|
162
|
+
RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
|
|
163
|
+
recordingOrgIdBackfillHolder,
|
|
164
|
+
now,
|
|
165
|
+
],
|
|
166
|
+
});
|
|
167
|
+
return result.rows.length > 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async function renewRecordingOrgIdBackfillLease(): Promise<boolean> {
|
|
171
|
+
const result = await getDbExec().execute({
|
|
172
|
+
sql: `UPDATE clips_backfill_leases
|
|
173
|
+
SET expires_at = ?
|
|
174
|
+
WHERE lease_key = ? AND holder = ? AND expires_at > ?`,
|
|
175
|
+
args: [
|
|
176
|
+
Date.now() + RECORDING_ORG_ID_BACKFILL_LEASE_MS,
|
|
177
|
+
RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
|
|
178
|
+
recordingOrgIdBackfillHolder,
|
|
179
|
+
Date.now(),
|
|
180
|
+
],
|
|
181
|
+
});
|
|
182
|
+
return result.rowsAffected > 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function backfillRecordingOrgIdsInBatches(): Promise<void> {
|
|
186
|
+
if (!(await acquireRecordingOrgIdBackfillLease())) return;
|
|
187
|
+
const exec = getDbExec();
|
|
188
|
+
try {
|
|
189
|
+
for (;;) {
|
|
190
|
+
if (!(await renewRecordingOrgIdBackfillLease())) return;
|
|
191
|
+
// guard:allow-unscoped — this is a leased, bounded one-time repair over
|
|
192
|
+
// historical recordings whose org id was never populated.
|
|
193
|
+
const result = await exec.execute({
|
|
194
|
+
sql: `UPDATE recordings
|
|
195
|
+
SET org_id = workspace_id
|
|
196
|
+
WHERE id IN (
|
|
197
|
+
SELECT id FROM recordings
|
|
198
|
+
WHERE org_id IS NULL AND workspace_id IS NOT NULL
|
|
199
|
+
ORDER BY id
|
|
200
|
+
LIMIT ?
|
|
201
|
+
)`,
|
|
202
|
+
args: [RECORDING_ORG_ID_BACKFILL_BATCH_SIZE],
|
|
203
|
+
});
|
|
204
|
+
if (result.rowsAffected === 0) return;
|
|
205
|
+
await new Promise<void>((resolve) =>
|
|
206
|
+
setTimeout(resolve, RECORDING_ORG_ID_BACKFILL_DELAY_MS),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
} catch (err) {
|
|
210
|
+
console.warn(
|
|
211
|
+
"[db] recording org-id backfill failed; it will retry in a later process:",
|
|
212
|
+
(err as Error)?.message ?? err,
|
|
213
|
+
);
|
|
214
|
+
} finally {
|
|
215
|
+
await exec
|
|
216
|
+
.execute({
|
|
217
|
+
sql: `DELETE FROM clips_backfill_leases
|
|
218
|
+
WHERE lease_key = ? AND holder = ?`,
|
|
219
|
+
args: [
|
|
220
|
+
RECORDING_ORG_ID_BACKFILL_LEASE_KEY,
|
|
221
|
+
recordingOrgIdBackfillHolder,
|
|
222
|
+
],
|
|
223
|
+
})
|
|
224
|
+
.catch(() => undefined);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function scheduleRecordingOrgIdBackfill(): void {
|
|
229
|
+
const timer = setTimeout(() => {
|
|
230
|
+
void backfillRecordingOrgIdsInBatches();
|
|
231
|
+
}, 1_000);
|
|
232
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
233
|
+
}
|
|
234
|
+
|
|
92
235
|
// Convention: every new migration below MUST set a unique `name:` slug (see
|
|
93
236
|
// packages/core/src/db/migrations.ts for the full rationale). Version numbers
|
|
94
237
|
// alone are not a safe identity across parallel branches that each extend
|
|
@@ -946,6 +1089,63 @@ const migrations = runMigrations(
|
|
|
946
1089
|
CREATE UNIQUE INDEX IF NOT EXISTS recording_playback_positions_recording_viewer_key_unique_idx
|
|
947
1090
|
ON recording_playback_positions (recording_id, viewer_key)`,
|
|
948
1091
|
},
|
|
1092
|
+
{
|
|
1093
|
+
version: 59,
|
|
1094
|
+
name: "backfill-recording-org-id",
|
|
1095
|
+
// Keep the repair's lease in schema migrations, but run the historical
|
|
1096
|
+
// data update below in bounded background batches after boot.
|
|
1097
|
+
sql: `CREATE TABLE IF NOT EXISTS clips_backfill_leases (
|
|
1098
|
+
lease_key TEXT PRIMARY KEY,
|
|
1099
|
+
holder TEXT NOT NULL,
|
|
1100
|
+
expires_at INTEGER NOT NULL
|
|
1101
|
+
)`,
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
version: 60,
|
|
1105
|
+
name: "backfill-legacy-clips-tables",
|
|
1106
|
+
// Run-only: this copies legacy rows forward in a way SQL alone cannot
|
|
1107
|
+
// express. It used to sit in the plugin body and re-ran on every cold
|
|
1108
|
+
// start; nothing writes the legacy tables any more, so it is a one-time
|
|
1109
|
+
// historical migration and belongs here. A throw leaves it unrecorded
|
|
1110
|
+
// and it retries on the next boot.
|
|
1111
|
+
sql: {},
|
|
1112
|
+
run: backfillLegacyClipsTables,
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
version: 61,
|
|
1116
|
+
name: "sync-workspaces-to-organizations",
|
|
1117
|
+
// Run-only, and ordered after the legacy backfill exactly as the plugin
|
|
1118
|
+
// body ran them. Nothing inserts into `workspaces` anywhere in the app
|
|
1119
|
+
// any more, so this is a one-time backfill of historical rows rather
|
|
1120
|
+
// than an ongoing reconciliation — there is nothing new to sync. It
|
|
1121
|
+
// returns `deferMigration()` while the framework's org tables are still
|
|
1122
|
+
// missing, so a first-boot race leaves it pending instead of applied.
|
|
1123
|
+
sql: {},
|
|
1124
|
+
run: syncWorkspacesToOrganizations,
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
version: 62,
|
|
1128
|
+
name: "retype-boolean-columns-postgres",
|
|
1129
|
+
// Run-only: the retype is driven by a fixed historical list of columns
|
|
1130
|
+
// that predate BOOLEAN, and it probes information_schema to decide. Once
|
|
1131
|
+
// applied it can never have anything left to do, so recording it removes
|
|
1132
|
+
// the probe from the boot path entirely instead of paying it forever.
|
|
1133
|
+
// No-ops on SQLite, which never had the wrong type.
|
|
1134
|
+
sql: {},
|
|
1135
|
+
run: retypeBooleanColumnsOnPostgres,
|
|
1136
|
+
},
|
|
1137
|
+
{
|
|
1138
|
+
version: 63,
|
|
1139
|
+
name: "recording-org-id-backfill-lease-table",
|
|
1140
|
+
// v59 was already applied on some deployments before the data repair was
|
|
1141
|
+
// moved off startup. This additive no-op makes the lease table available
|
|
1142
|
+
// there as well, without re-running or blocking on the old UPDATE.
|
|
1143
|
+
sql: `CREATE TABLE IF NOT EXISTS clips_backfill_leases (
|
|
1144
|
+
lease_key TEXT PRIMARY KEY,
|
|
1145
|
+
holder TEXT NOT NULL,
|
|
1146
|
+
expires_at INTEGER NOT NULL
|
|
1147
|
+
)`,
|
|
1148
|
+
},
|
|
949
1149
|
],
|
|
950
1150
|
{ table: "clips_migrations" },
|
|
951
1151
|
);
|
|
@@ -966,7 +1166,7 @@ const migrations = runMigrations(
|
|
|
966
1166
|
* inserts are guarded with WHERE-NOT-EXISTS so it only writes rows that
|
|
967
1167
|
* aren't there yet.
|
|
968
1168
|
*/
|
|
969
|
-
async function syncWorkspacesToOrganizations(): Promise<
|
|
1169
|
+
async function syncWorkspacesToOrganizations(): Promise<MigrationRunResult> {
|
|
970
1170
|
const exec = getDbExec();
|
|
971
1171
|
const pg = isPostgres();
|
|
972
1172
|
|
|
@@ -1000,7 +1200,12 @@ async function syncWorkspacesToOrganizations(): Promise<void> {
|
|
|
1000
1200
|
!(await hasTable("org_members")) ||
|
|
1001
1201
|
!(await hasTable("organization_settings"))
|
|
1002
1202
|
) {
|
|
1003
|
-
|
|
1203
|
+
// As a tracked migration this must NOT be recorded as applied when the
|
|
1204
|
+
// framework's org tables simply have not been created yet — recording it
|
|
1205
|
+
// would mean the sync never runs and historical workspaces never become
|
|
1206
|
+
// organizations. Deferring leaves the entry pending so the next boot
|
|
1207
|
+
// retries it, without logging a startup failure.
|
|
1208
|
+
return deferMigration();
|
|
1004
1209
|
}
|
|
1005
1210
|
|
|
1006
1211
|
// 1) Copy workspaces → organizations. Use the workspace id as the org id
|
|
@@ -1230,20 +1435,6 @@ async function syncWorkspacesToOrganizations(): Promise<void> {
|
|
|
1230
1435
|
}
|
|
1231
1436
|
}
|
|
1232
1437
|
|
|
1233
|
-
async function backfillRecordingOrgId(): Promise<void> {
|
|
1234
|
-
const exec = getDbExec();
|
|
1235
|
-
try {
|
|
1236
|
-
await exec.execute(
|
|
1237
|
-
`UPDATE recordings SET org_id = workspace_id WHERE org_id IS NULL AND workspace_id IS NOT NULL`,
|
|
1238
|
-
);
|
|
1239
|
-
} catch (err) {
|
|
1240
|
-
console.warn(
|
|
1241
|
-
"[db] backfill recording org_id failed:",
|
|
1242
|
-
(err as Error)?.message ?? err,
|
|
1243
|
-
);
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
1438
|
function assertSafeIdentifier(name: string): string {
|
|
1248
1439
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
|
|
1249
1440
|
throw new Error(`Unsafe SQL identifier: ${name}`);
|
|
@@ -1483,10 +1674,6 @@ async function backfillLegacyClipsTables(): Promise<void> {
|
|
|
1483
1674
|
*/
|
|
1484
1675
|
export default async (nitroApp: any): Promise<void> => {
|
|
1485
1676
|
await migrations(nitroApp);
|
|
1486
|
-
await retypeBooleanColumnsOnPostgres();
|
|
1487
|
-
await backfillLegacyClipsTables();
|
|
1488
|
-
await syncWorkspacesToOrganizations();
|
|
1489
|
-
await backfillRecordingOrgId();
|
|
1490
1677
|
try {
|
|
1491
1678
|
const summary = await ensureAdditiveColumns({
|
|
1492
1679
|
db: getDbExec(),
|
|
@@ -1506,6 +1693,7 @@ export default async (nitroApp: any): Promise<void> => {
|
|
|
1506
1693
|
err instanceof Error ? err.message : err,
|
|
1507
1694
|
);
|
|
1508
1695
|
}
|
|
1696
|
+
scheduleRecordingOrgIdBackfill();
|
|
1509
1697
|
|
|
1510
1698
|
// ---------------------------------------------------------------------------
|
|
1511
1699
|
// Register Clips template events for the automations system.
|