@agent-native/core 0.85.6 → 0.86.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/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +130 -1
- package/corpus/core/README.md +0 -11
- package/corpus/core/docs/content/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/ar-SA/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/ar-SA/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
- package/corpus/core/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/de-DE/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/de-DE/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/de-DE/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/de-DE/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/es-ES/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/es-ES/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/es-ES/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/es-ES/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/fr-FR/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/fr-FR/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/hi-IN/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/hi-IN/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/ja-JP/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/ja-JP/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/ko-KR/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/ko-KR/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/pt-BR/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/pt-BR/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/zh-CN/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/zh-CN/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
- package/corpus/core/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
- package/corpus/core/docs/content/locales/zh-TW/sharing.mdx +1 -2
- package/corpus/core/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
- package/corpus/core/docs/content/locales/zh-TW/template-plan.mdx +23 -7
- package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
- package/corpus/core/docs/content/plan-plugin.mdx +12 -11
- package/corpus/core/docs/content/sharing.mdx +1 -2
- package/corpus/core/docs/content/skills-guide.mdx +4 -3
- package/corpus/core/docs/content/template-plan.mdx +37 -6
- package/corpus/core/docs/content/tracking.mdx +1 -1
- package/corpus/core/docs/content/workspace-connections.mdx +1 -1
- package/corpus/core/package.json +6 -6
- package/corpus/core/src/agent/run-store.ts +1 -1
- package/corpus/core/src/chat-threads/store.ts +73 -11
- package/corpus/core/src/checkpoints/store.ts +13 -2
- package/corpus/core/src/cli/create.ts +3 -4
- package/corpus/core/src/cli/design-connect.ts +469 -9
- package/corpus/core/src/cli/index.ts +13 -0
- package/corpus/core/src/cli/plan-local.ts +281 -24
- package/corpus/core/src/cli/skills.ts +177 -21
- package/corpus/core/src/cli/templates-meta.ts +0 -13
- package/corpus/core/src/cli/visualize-repo.ts +715 -0
- package/corpus/core/src/client/AssistantChat.tsx +126 -17
- package/corpus/core/src/client/agent-chat-adapter.ts +6 -5
- package/corpus/core/src/client/app-providers.tsx +2 -2
- package/corpus/core/src/client/collab/index.ts +31 -0
- package/corpus/core/src/client/components/LiveCursorOverlay.tsx +16 -1
- package/corpus/core/src/client/components/PresenceBar.tsx +14 -1
- package/corpus/core/src/client/components/RecentEditHighlights.tsx +219 -0
- package/corpus/core/src/client/components/RemoteSelectionRings.tsx +40 -6
- package/corpus/core/src/client/index.ts +48 -0
- package/corpus/core/src/client/org/OrgSwitcher.tsx +0 -4
- package/corpus/core/src/client/rich-markdown-editor/SharedRichEditor.tsx +49 -32
- package/corpus/core/src/client/rich-markdown-editor/index.ts +6 -0
- package/corpus/core/src/client/rich-markdown-editor/surgical-apply.ts +192 -0
- package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +59 -8
- package/corpus/core/src/client/session-replay.ts +181 -15
- package/corpus/core/src/client/sse-event-processor.ts +90 -1
- package/corpus/core/src/client/use-action.ts +123 -25
- package/corpus/core/src/client/use-agent-engine-configured.ts +7 -1
- package/corpus/core/src/client/use-chat-threads.ts +18 -7
- package/corpus/core/src/client/use-db-sync.ts +104 -19
- package/corpus/core/src/client/use-pinch-zoom.ts +76 -11
- package/corpus/core/src/client/visual-style-controls.tsx +475 -0
- package/corpus/core/src/collab/agent-presence.ts +191 -62
- package/corpus/core/src/collab/awareness.ts +83 -6
- package/corpus/core/src/collab/client.ts +89 -146
- package/corpus/core/src/collab/index.ts +34 -0
- package/corpus/core/src/collab/presence.ts +63 -3
- package/corpus/core/src/collab/recent-edits.ts +171 -0
- package/corpus/core/src/collab/undo.ts +432 -0
- package/corpus/core/src/collab/ydoc-manager.ts +68 -0
- package/corpus/core/src/connections/catalog.ts +2 -3
- package/corpus/core/src/db/create-get-db.ts +86 -1
- package/corpus/core/src/db/ensure-additive-columns.ts +430 -0
- package/corpus/core/src/db/index.ts +6 -0
- package/corpus/core/src/db/migrations.ts +236 -35
- package/corpus/core/src/jobs/scheduler.ts +17 -14
- package/corpus/core/src/observability/traces.ts +182 -1
- package/corpus/core/src/org/context.ts +79 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +10 -6
- package/corpus/core/src/server/auth-marketing.ts +0 -11
- package/corpus/core/src/server/auth.ts +11 -4
- package/corpus/core/src/server/collab-plugin.ts +56 -13
- package/corpus/core/src/server/design-token-utils.ts +1 -1
- package/corpus/core/src/server/fusion-app.ts +447 -0
- package/corpus/core/src/server/index.ts +13 -0
- package/corpus/core/src/server/onboarding-html.ts +3 -4
- package/corpus/core/src/server/poll-events.ts +14 -2
- package/corpus/core/src/server/poll.ts +219 -12
- package/corpus/core/src/server/schema-prompt.ts +28 -9
- package/corpus/core/src/settings/store.ts +33 -2
- package/corpus/core/src/sharing/actions/set-resource-visibility.ts +2 -0
- package/corpus/core/src/sharing/actions/share-resource.ts +3 -0
- package/corpus/core/src/sharing/actions/unshare-resource.ts +2 -0
- package/corpus/core/src/styles/agent-native.css +0 -5
- package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/core/src/templates/default/package.json +3 -3
- package/corpus/core/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
- package/corpus/core/src/tracking/providers.ts +22 -1
- package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +20 -5
- package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/analytics/AGENTS.md +33 -6
- package/corpus/templates/analytics/actions/navigate.ts +14 -4
- package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
- package/corpus/templates/analytics/actions/view-screen.ts +57 -0
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +23 -1
- package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +21 -0
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +7 -0
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +15 -1
- package/corpus/templates/analytics/app/i18n-data.ts +151 -10
- package/corpus/templates/analytics/app/pages/Agents.tsx +118 -0
- package/corpus/templates/analytics/app/pages/DataSources.tsx +11 -1
- package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +76 -40
- package/corpus/templates/analytics/app/pages/sessions/session-replay-devtools.ts +5 -0
- package/corpus/templates/analytics/app/routes/agents.tsx +10 -0
- package/corpus/templates/analytics/changelog/2026-07-03-agent-admin-tools-page.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-03-agent-llm-observability-dashboard.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-03-session-recordings-now-include-response-bodies-for-5xx-error.md +6 -0
- package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +34 -0
- package/corpus/templates/analytics/docs/schemas/tracked-events.md +6 -0
- package/corpus/templates/analytics/package.json +3 -3
- package/corpus/templates/analytics/seeds/dashboards/agent-observability-llm.json +173 -0
- package/corpus/templates/analytics/server/jobs/analytics-alerts.ts +23 -5
- package/corpus/templates/analytics/server/lib/analytics-alerts.ts +58 -13
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +23 -0
- package/corpus/templates/analytics/server/lib/dashboard-seeds.ts +5 -0
- package/corpus/templates/analytics/server/lib/session-replay-agent-context.ts +120 -8
- package/corpus/templates/analytics/server/lib/session-replay.ts +3 -2
- package/corpus/templates/analytics/server/plugins/db.ts +93 -2
- package/corpus/templates/analytics/server/routes/api/session-replay/agent-diagnostics.json.get.ts +45 -1
- package/corpus/templates/analytics/shared/session-replay-diagnostics.ts +10 -0
- package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/assets/package.json +3 -3
- package/corpus/templates/assets/server/plugins/db.ts +63 -2
- package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/brain/package.json +3 -3
- package/corpus/templates/brain/server/plugins/db.ts +75 -2
- package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/calendar/package.json +3 -3
- package/corpus/templates/calendar/server/plugins/db.ts +64 -2
- package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/chat/package.json +3 -3
- package/corpus/templates/clips/actions/finalize-recording.ts +50 -40
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +8 -6
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -3
- package/corpus/templates/clips/changelog/2026-07-03-mobile-recording-pages-keep-videos-in-a-16-9-player-with-act.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +245 -77
- package/corpus/templates/clips/package.json +3 -3
- package/corpus/templates/clips/server/lib/recording-upload-state.ts +56 -0
- package/corpus/templates/clips/server/plugins/db.ts +68 -1
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +27 -3
- package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/content/actions/edit-document.ts +48 -1
- package/corpus/templates/content/actions/list-documents.ts +101 -94
- package/corpus/templates/content/actions/search-documents.ts +19 -3
- package/corpus/templates/content/actions/update-document.ts +54 -1
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +127 -7
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +97 -2
- package/corpus/templates/content/changelog/2026-07-03-agent-document-edits-now-appear-as-a-live-collaborator-prese.md +6 -0
- package/corpus/templates/content/changelog/2026-07-03-document-search-and-list-views-load-faster-on-large-workspac.md +6 -0
- package/corpus/templates/content/package.json +3 -3
- package/corpus/templates/content/server/plugins/db.ts +57 -1
- package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +190 -13
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +16 -4
- package/corpus/templates/design/.agents/skills/export-handoff/SKILL.md +46 -3
- package/corpus/templates/design/.agents/skills/full-app-build/SKILL.md +140 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +20 -0
- package/corpus/templates/design/AGENTS.md +83 -13
- package/corpus/templates/design/actions/add-fusion-screens.ts +91 -0
- package/corpus/templates/design/actions/apply-a11y-fix.ts +5 -1
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +24 -69
- package/corpus/templates/design/actions/apply-fusion-edits.ts +161 -0
- package/corpus/templates/design/actions/apply-motion-edit.ts +29 -2
- package/corpus/templates/design/actions/apply-visual-edit.ts +38 -3
- package/corpus/templates/design/actions/connect-localhost.ts +25 -18
- package/corpus/templates/design/actions/create-component.ts +5 -1
- package/corpus/templates/design/actions/create-fusion-app.ts +202 -0
- package/corpus/templates/design/actions/deploy-fusion-app.ts +123 -0
- package/corpus/templates/design/actions/edit-design.ts +13 -16
- package/corpus/templates/design/actions/export-pdf.ts +8 -1
- package/corpus/templates/design/actions/export-zip.ts +10 -1
- package/corpus/templates/design/actions/get-fusion-deploy-status.ts +86 -0
- package/corpus/templates/design/actions/get-motion-timeline.ts +26 -20
- package/corpus/templates/design/actions/grant-localhost-write-consent.ts +10 -0
- package/corpus/templates/design/actions/insert-asset.ts +190 -7
- package/corpus/templates/design/actions/list-fusion-edits.ts +96 -0
- package/corpus/templates/design/actions/list-local-files.ts +133 -0
- package/corpus/templates/design/actions/open-visual-edit.ts +27 -5
- package/corpus/templates/design/actions/present-design-variants.ts +2 -2
- package/corpus/templates/design/actions/push-fusion-app.ts +62 -0
- package/corpus/templates/design/actions/queue-fusion-edit.ts +112 -0
- package/corpus/templates/design/actions/read-local-file.ts +139 -0
- package/corpus/templates/design/actions/revoke-localhost-write-consent.ts +18 -14
- package/corpus/templates/design/actions/run-design-audit.ts +7 -4
- package/corpus/templates/design/actions/send-fusion-message.ts +69 -0
- package/corpus/templates/design/actions/sync-fusion-app.ts +196 -0
- package/corpus/templates/design/actions/write-local-file.ts +162 -36
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +12 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +600 -66
- package/corpus/templates/design/app/components/design/EditPanel.tsx +793 -304
- package/corpus/templates/design/app/components/design/FusionAppBanner.tsx +328 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +671 -154
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +1 -1
- package/corpus/templates/design/app/components/design/MotionDock.tsx +234 -46
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +2070 -420
- package/corpus/templates/design/app/components/design/StatesPanel.tsx +25 -2
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +7 -98
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +640 -72
- package/corpus/templates/design/app/components/design/bridge/motion-preview.bridge.ts +605 -0
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +50 -26
- package/corpus/templates/design/app/components/design/code-workbench/ActivityBar.tsx +85 -0
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +466 -0
- package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +53 -0
- package/corpus/templates/design/app/components/design/code-workbench/commands.ts +339 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/Breadcrumbs.tsx +42 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/BufferSync.tsx +128 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/EditorTabs.tsx +363 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +268 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/StatusBar.tsx +208 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-setup.ts +61 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme-palette.ts +191 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/monaco-theme.ts +29 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/status-bar-lang.ts +21 -0
- package/corpus/templates/design/app/components/design/code-workbench/editor/tab-drag.ts +27 -0
- package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +155 -0
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +551 -0
- package/corpus/templates/design/app/components/design/code-workbench/explorer/file-icons.tsx +115 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/format-on-open.ts +65 -0
- package/corpus/templates/design/app/components/design/code-workbench/format/prettier-format.ts +182 -0
- package/corpus/templates/design/app/components/design/code-workbench/model-registry.ts +133 -0
- package/corpus/templates/design/app/components/design/code-workbench/quickinput/QuickInput.tsx +563 -0
- package/corpus/templates/design/app/components/design/code-workbench/quickinput/fuzzy.ts +170 -0
- package/corpus/templates/design/app/components/design/code-workbench/search/SearchView.tsx +508 -0
- package/corpus/templates/design/app/components/design/code-workbench/search/search-engine.ts +280 -0
- package/corpus/templates/design/app/components/design/code-workbench/store.tsx +734 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +39 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +196 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/localhost-provider.ts +177 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/tree.ts +110 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/types.ts +103 -0
- package/corpus/templates/design/app/components/design/code-workbench-theme.ts +68 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +16 -4
- package/corpus/templates/design/app/components/design/inspector/DesignColorPicker.tsx +217 -113
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +111 -5
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -2
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +79 -16
- package/corpus/templates/design/app/components/design/inspector/index.ts +9 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +67 -2
- package/corpus/templates/design/app/components/design/types.ts +16 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +80 -1
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +24 -6
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +15 -1
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +6 -16
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +77 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/design/app/i18n-data.ts +31 -0
- package/corpus/templates/design/app/lib/design-import.ts +95 -0
- package/corpus/templates/design/app/pages/DesignEditor.tsx +5586 -1112
- package/corpus/templates/design/app/pages/Index.tsx +90 -17
- package/corpus/templates/design/changelog/2026-07-03-canvas-interactions-now-match-figma-rotation-aware-resizing-.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-inspector-fixes-mixed-selections-show-mixed-instead-of-wrong.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-keyframe-timeline-works-reliably-drag-keyframes-smoothly-pic.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-layers-panel-matches-figma-top-layer-on-top-drag-with-auto-s.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-much-faster-editor-smooth-dragging-zooming-and-panel-updates.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-pen-tool-refinements-click-the-first-point-to-close-with-a-d.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-text-editing-enter-adds-a-line-break-international-ime-typin.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-the-ai-now-edits-like-a-collaborator-on-canvas-its-cursor-gl.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-the-code-panel-is-now-a-full-vs-code-style-editor-with-a-fil.md +6 -0
- package/corpus/templates/design/changelog/2026-07-03-undo-and-redo-are-dependable-across-agent-edits-screen-switc.md +6 -0
- package/corpus/templates/design/package.json +4 -3
- package/corpus/templates/design/server/db/schema.ts +31 -0
- package/corpus/templates/design/server/lib/design-export.ts +43 -1
- package/corpus/templates/design/server/lib/fusion-screens.ts +246 -0
- package/corpus/templates/design/server/plugins/db.ts +89 -2
- package/corpus/templates/design/shared/board-file.ts +25 -5
- package/corpus/templates/design/shared/canvas-math.ts +754 -9
- package/corpus/templates/design/shared/code-layer.ts +304 -26
- package/corpus/templates/design/shared/collab-selection.ts +52 -0
- package/corpus/templates/design/shared/color-utils.ts +84 -0
- package/corpus/templates/design/shared/design-source-capabilities.ts +16 -7
- package/corpus/templates/design/shared/full-app.ts +126 -0
- package/corpus/templates/design/shared/motion-compiler.ts +75 -31
- package/corpus/templates/design/shared/motion-timeline.ts +335 -0
- package/corpus/templates/design/shared/pen-path.ts +496 -23
- package/corpus/templates/dispatch/package.json +3 -3
- package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/forms/package.json +3 -3
- package/corpus/templates/forms/server/plugins/db.ts +62 -2
- package/corpus/templates/macros/package.json +3 -3
- package/corpus/templates/macros/server/plugins/db.ts +63 -2
- package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +8 -0
- package/corpus/templates/mail/package.json +3 -3
- package/corpus/templates/mail/server/lib/contact-frequency.ts +42 -15
- package/corpus/templates/mail/server/plugins/db.ts +63 -2
- package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +9 -3
- package/corpus/templates/plan/.agents/skills/visualize-repo/SKILL.md +92 -0
- package/corpus/templates/plan/actions/export-visual-plan.ts +5 -0
- package/corpus/templates/plan/actions/get-local-plan-folder.ts +4 -22
- package/corpus/templates/plan/actions/get-plan-version.ts +6 -16
- package/corpus/templates/plan/actions/list-plan-versions.ts +48 -20
- package/corpus/templates/plan/actions/patch-visual-plan-source.ts +41 -1
- package/corpus/templates/plan/actions/promote-local-plan-folder.ts +4 -22
- package/corpus/templates/plan/actions/update-local-plan-comments.ts +4 -2
- package/corpus/templates/plan/actions/update-local-plan-folder.ts +4 -22
- package/corpus/templates/plan/actions/update-visual-plan.ts +60 -1
- package/corpus/templates/plan/agent-native.app-skill.json +10 -0
- package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +138 -39
- package/corpus/templates/plan/app/components/editor/usePlanUndoStack.ts +165 -23
- package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +80 -4
- package/corpus/templates/plan/app/global.css +11 -9
- package/corpus/templates/plan/app/hooks/use-navigation-state.ts +10 -1
- package/corpus/templates/plan/app/hooks/use-plan-presence.ts +66 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +215 -63
- package/corpus/templates/plan/changelog/2026-07-03-local-visual-plans-and-recaps-can-save-comments-without-sign.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-03-plan-tabs-render-nested-text-instead-of-raw-json.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-03-plans-are-now-fully-real-time-collaborative-multiple-people-.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-03-plans-open-and-refresh-faster-especially-long-lived-plans-wi.md +6 -0
- package/corpus/templates/plan/changelog/2026-07-03-undo-now-survives-agent-edits-cmd-z-keeps-working-on-your-ow.md +6 -0
- package/corpus/templates/plan/package.json +5 -3
- package/corpus/templates/plan/server/db/schema.ts +12 -0
- package/corpus/templates/plan/server/lib/local-plan-kind.ts +25 -0
- package/corpus/templates/plan/server/lib/plan-versions.ts +83 -1
- package/corpus/templates/plan/server/lib/public-action-paths.ts +0 -2
- package/corpus/templates/plan/server/plans.ts +26 -3
- package/corpus/templates/plan/server/plugins/db.ts +105 -2
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +8 -4
- package/corpus/templates/slides/AGENTS.md +4 -0
- package/corpus/templates/slides/actions/_agent-presence.ts +48 -0
- package/corpus/templates/slides/actions/add-slide.ts +16 -18
- package/corpus/templates/slides/actions/patch-deck.ts +4 -2
- package/corpus/templates/slides/actions/update-slide.ts +114 -77
- package/corpus/templates/slides/actions/view-screen.ts +39 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +47 -3
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +32 -35
- package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +625 -199
- package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +342 -0
- package/corpus/templates/slides/app/components/editor/TweaksPanel.tsx +46 -96
- package/corpus/templates/slides/app/components/visual-editor/SaveStatusIndicator.tsx +8 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +589 -176
- package/corpus/templates/slides/app/hooks/use-deck-presence.ts +84 -42
- package/corpus/templates/slides/app/i18n/ar-SA.ts +46 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +46 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +46 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +46 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +46 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +46 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +46 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +46 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +46 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +46 -0
- package/corpus/templates/slides/app/i18n/zh-TW.ts +46 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +25 -13
- package/corpus/templates/slides/changelog/2026-07-03-figma-style-slide-editing.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-03-see-the-ai-working-with-you-when-the-agent-edits-a-slide-it-.md +6 -0
- package/corpus/templates/slides/changelog/2026-07-03-undo-redo-is-now-precise-and-safe-with-collaborators-it-only.md +6 -0
- package/corpus/templates/slides/package.json +3 -3
- package/corpus/templates/slides/server/handlers/decks.ts +31 -3
- package/corpus/templates/slides/server/plugins/db.ts +65 -2
- package/corpus/templates/videos/netlify.toml +1 -12
- package/dist/agent/run-store.js +1 -1
- package/dist/agent/run-store.js.map +1 -1
- package/dist/chat-threads/store.d.ts +9 -1
- package/dist/chat-threads/store.d.ts.map +1 -1
- package/dist/chat-threads/store.js +63 -11
- package/dist/chat-threads/store.js.map +1 -1
- package/dist/checkpoints/store.d.ts.map +1 -1
- package/dist/checkpoints/store.js +10 -2
- package/dist/checkpoints/store.js.map +1 -1
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +3 -5
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/design-connect.d.ts +49 -1
- package/dist/cli/design-connect.d.ts.map +1 -1
- package/dist/cli/design-connect.js +414 -9
- package/dist/cli/design-connect.js.map +1 -1
- package/dist/cli/index.js +12 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/plan-local.d.ts +24 -0
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +188 -20
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +173 -21
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +0 -14
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/cli/visualize-repo.d.ts +49 -0
- package/dist/cli/visualize-repo.d.ts.map +1 -0
- package/dist/cli/visualize-repo.js +561 -0
- package/dist/cli/visualize-repo.js.map +1 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +120 -15
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +6 -5
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/app-providers.d.ts +2 -2
- package/dist/client/app-providers.js.map +1 -1
- package/dist/client/collab/index.d.ts +4 -1
- package/dist/client/collab/index.d.ts.map +1 -1
- package/dist/client/collab/index.js +3 -0
- package/dist/client/collab/index.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
- package/dist/client/components/LiveCursorOverlay.js +11 -3
- package/dist/client/components/LiveCursorOverlay.js.map +1 -1
- package/dist/client/components/PresenceBar.d.ts.map +1 -1
- package/dist/client/components/PresenceBar.js +6 -1
- package/dist/client/components/PresenceBar.js.map +1 -1
- package/dist/client/components/RecentEditHighlights.d.ts +43 -0
- package/dist/client/components/RecentEditHighlights.d.ts.map +1 -0
- package/dist/client/components/RecentEditHighlights.js +146 -0
- package/dist/client/components/RecentEditHighlights.js.map +1 -0
- package/dist/client/components/RemoteSelectionRings.d.ts +9 -0
- package/dist/client/components/RemoteSelectionRings.d.ts.map +1 -1
- package/dist/client/components/RemoteSelectionRings.js +22 -8
- package/dist/client/components/RemoteSelectionRings.js.map +1 -1
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
- package/dist/client/org/OrgSwitcher.js +1 -3
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +8 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/SharedRichEditor.js +8 -2
- package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -1
- package/dist/client/rich-markdown-editor/index.d.ts +1 -0
- package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/index.js +1 -0
- package/dist/client/rich-markdown-editor/index.js.map +1 -1
- package/dist/client/rich-markdown-editor/surgical-apply.d.ts +66 -0
- package/dist/client/rich-markdown-editor/surgical-apply.d.ts.map +1 -0
- package/dist/client/rich-markdown-editor/surgical-apply.js +147 -0
- package/dist/client/rich-markdown-editor/surgical-apply.js.map +1 -0
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +18 -2
- package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -1
- package/dist/client/rich-markdown-editor/useCollabReconcile.js +39 -8
- package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -1
- package/dist/client/session-replay.d.ts +10 -1
- package/dist/client/session-replay.d.ts.map +1 -1
- package/dist/client/session-replay.js +134 -7
- package/dist/client/session-replay.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +81 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-action.d.ts +24 -0
- package/dist/client/use-action.d.ts.map +1 -1
- package/dist/client/use-action.js +109 -27
- package/dist/client/use-action.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +7 -1
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +11 -3
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-db-sync.d.ts +36 -0
- package/dist/client/use-db-sync.d.ts.map +1 -1
- package/dist/client/use-db-sync.js +68 -12
- package/dist/client/use-db-sync.js.map +1 -1
- package/dist/client/use-pinch-zoom.d.ts.map +1 -1
- package/dist/client/use-pinch-zoom.js +76 -11
- package/dist/client/use-pinch-zoom.js.map +1 -1
- package/dist/client/visual-style-controls.d.ts +79 -0
- package/dist/client/visual-style-controls.d.ts.map +1 -0
- package/dist/client/visual-style-controls.js +150 -0
- package/dist/client/visual-style-controls.js.map +1 -0
- package/dist/collab/agent-presence.d.ts +51 -5
- package/dist/collab/agent-presence.d.ts.map +1 -1
- package/dist/collab/agent-presence.js +144 -58
- package/dist/collab/agent-presence.js.map +1 -1
- package/dist/collab/awareness-store.d.ts +32 -0
- package/dist/collab/awareness-store.d.ts.map +1 -0
- package/dist/collab/awareness-store.js +0 -0
- package/dist/collab/awareness-store.js.map +1 -0
- package/dist/collab/awareness.d.ts +14 -3
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +53 -5
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client.d.ts +2 -0
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +79 -119
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/index.d.ts +3 -1
- package/dist/collab/index.d.ts.map +1 -1
- package/dist/collab/index.js +5 -1
- package/dist/collab/index.js.map +1 -1
- package/dist/collab/presence.d.ts.map +1 -1
- package/dist/collab/presence.js +54 -3
- package/dist/collab/presence.js.map +1 -1
- package/dist/collab/recent-edits.d.ts +87 -0
- package/dist/collab/recent-edits.d.ts.map +1 -0
- package/dist/collab/recent-edits.js +116 -0
- package/dist/collab/recent-edits.js.map +1 -0
- package/dist/collab/undo.d.ts +121 -0
- package/dist/collab/undo.d.ts.map +1 -0
- package/dist/collab/undo.js +244 -0
- package/dist/collab/undo.js.map +1 -0
- package/dist/collab/ydoc-manager.d.ts +10 -0
- package/dist/collab/ydoc-manager.d.ts.map +1 -1
- package/dist/collab/ydoc-manager.js +57 -0
- package/dist/collab/ydoc-manager.js.map +1 -1
- package/dist/connections/catalog.d.ts +2 -2
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +1 -1
- package/dist/connections/catalog.js.map +1 -1
- package/dist/db/create-get-db.d.ts +22 -0
- package/dist/db/create-get-db.d.ts.map +1 -1
- package/dist/db/create-get-db.js +73 -1
- package/dist/db/create-get-db.js.map +1 -1
- package/dist/db/ensure-additive-columns.d.ts +93 -0
- package/dist/db/ensure-additive-columns.d.ts.map +1 -0
- package/dist/db/ensure-additive-columns.js +355 -0
- package/dist/db/ensure-additive-columns.js.map +1 -0
- package/dist/db/index.d.ts +1 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +70 -0
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +196 -33
- package/dist/db/migrations.js.map +1 -1
- package/dist/jobs/scheduler.js +17 -10
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +5 -5
- package/dist/observability/traces.d.ts.map +1 -1
- package/dist/observability/traces.js +155 -1
- package/dist/observability/traces.js.map +1 -1
- package/dist/org/context.d.ts +7 -0
- package/dist/org/context.d.ts.map +1 -1
- package/dist/org/context.js +54 -2
- package/dist/org/context.js.map +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +10 -6
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/auth-marketing.d.ts.map +1 -1
- package/dist/server/auth-marketing.js +0 -10
- package/dist/server/auth-marketing.js.map +1 -1
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +6 -4
- package/dist/server/auth.js.map +1 -1
- package/dist/server/collab-plugin.d.ts.map +1 -1
- package/dist/server/collab-plugin.js +45 -13
- package/dist/server/collab-plugin.js.map +1 -1
- package/dist/server/design-token-utils.d.ts +1 -1
- package/dist/server/design-token-utils.js +1 -1
- package/dist/server/design-token-utils.js.map +1 -1
- package/dist/server/fusion-app.d.ts +107 -0
- package/dist/server/fusion-app.d.ts.map +1 -0
- package/dist/server/fusion-app.js +371 -0
- package/dist/server/fusion-app.js.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +3 -4
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/server/poll-events.d.ts +2 -0
- package/dist/server/poll-events.d.ts.map +1 -1
- package/dist/server/poll-events.js +7 -2
- package/dist/server/poll-events.js.map +1 -1
- package/dist/server/poll.d.ts +47 -3
- package/dist/server/poll.d.ts.map +1 -1
- package/dist/server/poll.js +176 -10
- package/dist/server/poll.js.map +1 -1
- package/dist/server/schema-prompt.d.ts.map +1 -1
- package/dist/server/schema-prompt.js +24 -7
- package/dist/server/schema-prompt.js.map +1 -1
- package/dist/settings/store.d.ts.map +1 -1
- package/dist/settings/store.js +32 -3
- package/dist/settings/store.js.map +1 -1
- package/dist/sharing/actions/set-resource-visibility.js +2 -0
- package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
- package/dist/sharing/actions/share-resource.d.ts.map +1 -1
- package/dist/sharing/actions/share-resource.js +3 -0
- package/dist/sharing/actions/share-resource.js.map +1 -1
- package/dist/sharing/actions/unshare-resource.js +2 -0
- package/dist/sharing/actions/unshare-resource.js.map +1 -1
- package/dist/styles/agent-native.css +0 -5
- package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/dist/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
- package/dist/templates/default/package.json +3 -3
- package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
- package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
- package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
- package/dist/tracking/providers.d.ts.map +1 -1
- package/dist/tracking/providers.js +17 -1
- package/dist/tracking/providers.js.map +1 -1
- package/docs/content/cloneable-saas.mdx +0 -1
- package/docs/content/locales/ar-SA/cloneable-saas.mdx +0 -1
- package/docs/content/locales/ar-SA/plan-plugin.mdx +10 -9
- package/docs/content/locales/ar-SA/sharing.mdx +1 -2
- package/docs/content/locales/ar-SA/skills-guide.mdx +2 -3
- package/docs/content/locales/ar-SA/template-plan.mdx +23 -7
- package/docs/content/locales/ar-SA/tracking.mdx +1 -1
- package/docs/content/locales/ar-SA/workspace-connections.mdx +11 -11
- package/docs/content/locales/de-DE/cloneable-saas.mdx +0 -1
- package/docs/content/locales/de-DE/plan-plugin.mdx +10 -9
- package/docs/content/locales/de-DE/sharing.mdx +1 -2
- package/docs/content/locales/de-DE/skills-guide.mdx +2 -3
- package/docs/content/locales/de-DE/template-plan.mdx +23 -7
- package/docs/content/locales/de-DE/tracking.mdx +1 -1
- package/docs/content/locales/de-DE/workspace-connections.mdx +1 -1
- package/docs/content/locales/es-ES/cloneable-saas.mdx +0 -1
- package/docs/content/locales/es-ES/plan-plugin.mdx +10 -9
- package/docs/content/locales/es-ES/sharing.mdx +1 -2
- package/docs/content/locales/es-ES/skills-guide.mdx +2 -3
- package/docs/content/locales/es-ES/template-plan.mdx +23 -7
- package/docs/content/locales/es-ES/tracking.mdx +1 -1
- package/docs/content/locales/es-ES/workspace-connections.mdx +1 -1
- package/docs/content/locales/fr-FR/cloneable-saas.mdx +0 -1
- package/docs/content/locales/fr-FR/plan-plugin.mdx +10 -9
- package/docs/content/locales/fr-FR/sharing.mdx +1 -2
- package/docs/content/locales/fr-FR/skills-guide.mdx +2 -3
- package/docs/content/locales/fr-FR/template-plan.mdx +23 -7
- package/docs/content/locales/fr-FR/tracking.mdx +1 -1
- package/docs/content/locales/fr-FR/workspace-connections.mdx +1 -1
- package/docs/content/locales/hi-IN/cloneable-saas.mdx +0 -1
- package/docs/content/locales/hi-IN/plan-plugin.mdx +10 -9
- package/docs/content/locales/hi-IN/sharing.mdx +1 -2
- package/docs/content/locales/hi-IN/skills-guide.mdx +2 -3
- package/docs/content/locales/hi-IN/template-plan.mdx +23 -7
- package/docs/content/locales/hi-IN/tracking.mdx +1 -1
- package/docs/content/locales/hi-IN/workspace-connections.mdx +1 -1
- package/docs/content/locales/ja-JP/cloneable-saas.mdx +0 -1
- package/docs/content/locales/ja-JP/plan-plugin.mdx +10 -9
- package/docs/content/locales/ja-JP/sharing.mdx +1 -2
- package/docs/content/locales/ja-JP/skills-guide.mdx +2 -3
- package/docs/content/locales/ja-JP/template-plan.mdx +23 -7
- package/docs/content/locales/ja-JP/tracking.mdx +1 -1
- package/docs/content/locales/ja-JP/workspace-connections.mdx +1 -1
- package/docs/content/locales/ko-KR/cloneable-saas.mdx +0 -1
- package/docs/content/locales/ko-KR/plan-plugin.mdx +10 -9
- package/docs/content/locales/ko-KR/sharing.mdx +1 -2
- package/docs/content/locales/ko-KR/skills-guide.mdx +2 -3
- package/docs/content/locales/ko-KR/template-plan.mdx +23 -7
- package/docs/content/locales/ko-KR/tracking.mdx +1 -1
- package/docs/content/locales/ko-KR/workspace-connections.mdx +1 -1
- package/docs/content/locales/pt-BR/cloneable-saas.mdx +0 -1
- package/docs/content/locales/pt-BR/plan-plugin.mdx +10 -9
- package/docs/content/locales/pt-BR/sharing.mdx +1 -2
- package/docs/content/locales/pt-BR/skills-guide.mdx +2 -3
- package/docs/content/locales/pt-BR/template-plan.mdx +23 -7
- package/docs/content/locales/pt-BR/tracking.mdx +1 -1
- package/docs/content/locales/pt-BR/workspace-connections.mdx +1 -1
- package/docs/content/locales/zh-CN/cloneable-saas.mdx +0 -1
- package/docs/content/locales/zh-CN/plan-plugin.mdx +10 -9
- package/docs/content/locales/zh-CN/sharing.mdx +1 -2
- package/docs/content/locales/zh-CN/skills-guide.mdx +2 -3
- package/docs/content/locales/zh-CN/template-plan.mdx +23 -7
- package/docs/content/locales/zh-CN/tracking.mdx +1 -1
- package/docs/content/locales/zh-CN/workspace-connections.mdx +1 -1
- package/docs/content/locales/zh-TW/cloneable-saas.mdx +0 -1
- package/docs/content/locales/zh-TW/plan-plugin.mdx +10 -9
- package/docs/content/locales/zh-TW/sharing.mdx +1 -2
- package/docs/content/locales/zh-TW/skills-guide.mdx +2 -3
- package/docs/content/locales/zh-TW/template-plan.mdx +23 -7
- package/docs/content/locales/zh-TW/tracking.mdx +1 -1
- package/docs/content/locales/zh-TW/workspace-connections.mdx +1 -1
- package/docs/content/plan-plugin.mdx +12 -11
- package/docs/content/sharing.mdx +1 -2
- package/docs/content/skills-guide.mdx +4 -3
- package/docs/content/template-plan.mdx +37 -6
- package/docs/content/tracking.mdx +1 -1
- package/docs/content/workspace-connections.mdx +1 -1
- package/package.json +6 -6
- package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/src/templates/default/.agents/skills/storing-data/SKILL.md +8 -0
- package/src/templates/default/package.json +3 -3
- package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +8 -0
- package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +22 -0
- package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +82 -19
- package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +15 -0
- package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +8 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +1 -0
- package/corpus/core/docs/content/locales/ar-SA/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/de-DE/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/es-ES/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/fr-FR/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/hi-IN/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/ja-JP/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/ko-KR/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/pt-BR/template-videos.mdx +0 -336
- package/corpus/core/docs/content/locales/zh-CN/template-videos.mdx +0 -334
- package/corpus/core/docs/content/locales/zh-TW/template-videos.mdx +0 -334
- package/corpus/core/docs/content/template-videos.mdx +0 -332
- package/corpus/templates/design/app/components/design/CodeWorkbenchHost.tsx +0 -697
- package/corpus/templates/slides/app/components/editor/CodeEditor.tsx +0 -49
- package/corpus/templates/videos/.agents/skills/actions/SKILL.md +0 -432
- package/corpus/templates/videos/.agents/skills/animation-tracks/SKILL.md +0 -99
- package/corpus/templates/videos/.agents/skills/capture-learnings/SKILL.md +0 -76
- package/corpus/templates/videos/.agents/skills/composition-management/SKILL.md +0 -106
- package/corpus/templates/videos/.agents/skills/create-skill/SKILL.md +0 -221
- package/corpus/templates/videos/.agents/skills/delegate-to-agent/SKILL.md +0 -263
- package/corpus/templates/videos/.agents/skills/frontend-design/SKILL.md +0 -112
- package/corpus/templates/videos/.agents/skills/security/SKILL.md +0 -263
- package/corpus/templates/videos/.agents/skills/self-modifying-code/SKILL.md +0 -88
- package/corpus/templates/videos/.agents/skills/shadcn-ui/SKILL.md +0 -95
- package/corpus/templates/videos/.builder/ANIMATED_PROPERTIES.md +0 -335
- package/corpus/templates/videos/.builder/KEYFRAME_SYNC.md +0 -166
- package/corpus/templates/videos/.builder/SEAMLESS_SYNC.md +0 -211
- package/corpus/templates/videos/.builder/rules/deploy-app.mdc +0 -22
- package/corpus/templates/videos/.builder/rules/organize-ui.mdc +0 -9
- package/corpus/templates/videos/.builder/skills/remotion/SKILL.md +0 -29
- package/corpus/templates/videos/.builder/skills/remotion/rules/animations.md +0 -27
- package/corpus/templates/videos/.builder/skills/remotion/rules/assets.md +0 -43
- package/corpus/templates/videos/.builder/skills/remotion/rules/audio.md +0 -58
- package/corpus/templates/videos/.builder/skills/remotion/rules/compositions.md +0 -129
- package/corpus/templates/videos/.builder/skills/remotion/rules/fonts.md +0 -47
- package/corpus/templates/videos/.builder/skills/remotion/rules/images.md +0 -41
- package/corpus/templates/videos/.builder/skills/remotion/rules/parameters.md +0 -59
- package/corpus/templates/videos/.builder/skills/remotion/rules/sequencing.md +0 -54
- package/corpus/templates/videos/.builder/skills/remotion/rules/tailwind.md +0 -11
- package/corpus/templates/videos/.builder/skills/remotion/rules/text-animations.md +0 -18
- package/corpus/templates/videos/.builder/skills/remotion/rules/timing.md +0 -103
- package/corpus/templates/videos/.builder/skills/remotion/rules/transparent-videos.md +0 -35
- package/corpus/templates/videos/.builder/skills/remotion/rules/trimming.md +0 -38
- package/corpus/templates/videos/.builder/skills/remotion/rules/videos.md +0 -54
- package/corpus/templates/videos/.dockerignore +0 -62
- package/corpus/templates/videos/.env.example +0 -4
- package/corpus/templates/videos/.oxfmtrc.json +0 -8
- package/corpus/templates/videos/AGENTS.md +0 -46
- package/corpus/templates/videos/CHANGELOG.md +0 -10
- package/corpus/templates/videos/DEVELOPING.md +0 -143
- package/corpus/templates/videos/README.md +0 -33
- package/corpus/templates/videos/actions/analyze-brand-assets.ts +0 -151
- package/corpus/templates/videos/actions/apply-design-system.ts +0 -35
- package/corpus/templates/videos/actions/create-design-system.ts +0 -84
- package/corpus/templates/videos/actions/create-folder.ts +0 -48
- package/corpus/templates/videos/actions/db-connect.ts +0 -45
- package/corpus/templates/videos/actions/db-health.ts +0 -24
- package/corpus/templates/videos/actions/db-status.ts +0 -28
- package/corpus/templates/videos/actions/delete-composition.ts +0 -272
- package/corpus/templates/videos/actions/delete-folder.ts +0 -27
- package/corpus/templates/videos/actions/generate-animated-component.ts +0 -470
- package/corpus/templates/videos/actions/get-composition.ts +0 -36
- package/corpus/templates/videos/actions/get-design-system.ts +0 -35
- package/corpus/templates/videos/actions/import-code.ts +0 -67
- package/corpus/templates/videos/actions/import-design-project.ts +0 -42
- package/corpus/templates/videos/actions/import-document.ts +0 -125
- package/corpus/templates/videos/actions/import-from-url.ts +0 -18
- package/corpus/templates/videos/actions/import-github.ts +0 -182
- package/corpus/templates/videos/actions/list-compositions.ts +0 -32
- package/corpus/templates/videos/actions/list-design-systems.ts +0 -66
- package/corpus/templates/videos/actions/list-folders.ts +0 -61
- package/corpus/templates/videos/actions/move-composition-to-folder.ts +0 -59
- package/corpus/templates/videos/actions/navigate.ts +0 -40
- package/corpus/templates/videos/actions/rename-folder.ts +0 -41
- package/corpus/templates/videos/actions/run.ts +0 -2
- package/corpus/templates/videos/actions/save-composition.ts +0 -114
- package/corpus/templates/videos/actions/set-default-design-system.ts +0 -40
- package/corpus/templates/videos/actions/update-composition.ts +0 -81
- package/corpus/templates/videos/actions/update-design-system.ts +0 -68
- package/corpus/templates/videos/actions/validate-compositions.ts +0 -502
- package/corpus/templates/videos/actions/view-screen.ts +0 -48
- package/corpus/templates/videos/app/components/CameraControls.tsx +0 -442
- package/corpus/templates/videos/app/components/CameraToolbar.tsx +0 -437
- package/corpus/templates/videos/app/components/CloudUpgrade.tsx +0 -287
- package/corpus/templates/videos/app/components/CollabPresenceBar.tsx +0 -81
- package/corpus/templates/videos/app/components/CompSettingsEditor.tsx +0 -107
- package/corpus/templates/videos/app/components/ComponentLibrarySidebar.tsx +0 -457
- package/corpus/templates/videos/app/components/ComponentPropsPanel.tsx +0 -227
- package/corpus/templates/videos/app/components/ComponentsSidebar.tsx +0 -70
- package/corpus/templates/videos/app/components/CompositionCard.tsx +0 -147
- package/corpus/templates/videos/app/components/CurrentElementPanel.tsx +0 -835
- package/corpus/templates/videos/app/components/CursorControls.tsx +0 -664
- package/corpus/templates/videos/app/components/CursorPositioningOverlay.tsx +0 -238
- package/corpus/templates/videos/app/components/LibraryFolderRow.tsx +0 -235
- package/corpus/templates/videos/app/components/MotionCurveSelect.tsx +0 -61
- package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +0 -192
- package/corpus/templates/videos/app/components/PropsEditor.tsx +0 -210
- package/corpus/templates/videos/app/components/QuestionFlow.tsx +0 -40
- package/corpus/templates/videos/app/components/Sidebar.tsx +0 -609
- package/corpus/templates/videos/app/components/StudioHeader.tsx +0 -109
- package/corpus/templates/videos/app/components/Timeline.tsx +0 -2067
- package/corpus/templates/videos/app/components/TrackPropertiesPanel.tsx +0 -922
- package/corpus/templates/videos/app/components/TweaksPanel.tsx +0 -277
- package/corpus/templates/videos/app/components/VideoPlayer.tsx +0 -487
- package/corpus/templates/videos/app/components/design-system/DesignSystemCard.tsx +0 -134
- package/corpus/templates/videos/app/components/design-system/DesignSystemPreview.tsx +0 -176
- package/corpus/templates/videos/app/components/design-system/DesignSystemSetup.tsx +0 -707
- package/corpus/templates/videos/app/components/keyframes/KeyframeActionButtons.tsx +0 -78
- package/corpus/templates/videos/app/components/keyframes/KeyframeNavigation.tsx +0 -59
- package/corpus/templates/videos/app/components/keyframes/PropertyNumberInput.tsx +0 -56
- package/corpus/templates/videos/app/components/layout/Header.tsx +0 -64
- package/corpus/templates/videos/app/components/layout/HeaderActions.tsx +0 -84
- package/corpus/templates/videos/app/components/layout/Layout.tsx +0 -132
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -180
- package/corpus/templates/videos/app/components/ui/accordion.tsx +0 -56
- package/corpus/templates/videos/app/components/ui/alert-dialog.tsx +0 -139
- package/corpus/templates/videos/app/components/ui/alert.tsx +0 -59
- package/corpus/templates/videos/app/components/ui/aspect-ratio.tsx +0 -5
- package/corpus/templates/videos/app/components/ui/avatar.tsx +0 -48
- package/corpus/templates/videos/app/components/ui/badge.tsx +0 -37
- package/corpus/templates/videos/app/components/ui/breadcrumb.tsx +0 -115
- package/corpus/templates/videos/app/components/ui/button.tsx +0 -57
- package/corpus/templates/videos/app/components/ui/calendar.tsx +0 -68
- package/corpus/templates/videos/app/components/ui/card.tsx +0 -86
- package/corpus/templates/videos/app/components/ui/carousel.tsx +0 -260
- package/corpus/templates/videos/app/components/ui/chart.tsx +0 -375
- package/corpus/templates/videos/app/components/ui/checkbox.tsx +0 -28
- package/corpus/templates/videos/app/components/ui/collapsible.tsx +0 -9
- package/corpus/templates/videos/app/components/ui/command.tsx +0 -154
- package/corpus/templates/videos/app/components/ui/context-menu.tsx +0 -202
- package/corpus/templates/videos/app/components/ui/dialog.tsx +0 -130
- package/corpus/templates/videos/app/components/ui/drawer.tsx +0 -116
- package/corpus/templates/videos/app/components/ui/dropdown-menu.tsx +0 -212
- package/corpus/templates/videos/app/components/ui/form.tsx +0 -177
- package/corpus/templates/videos/app/components/ui/hover-card.tsx +0 -27
- package/corpus/templates/videos/app/components/ui/input-otp.tsx +0 -69
- package/corpus/templates/videos/app/components/ui/input.tsx +0 -22
- package/corpus/templates/videos/app/components/ui/label.tsx +0 -24
- package/corpus/templates/videos/app/components/ui/menubar.tsx +0 -234
- package/corpus/templates/videos/app/components/ui/navigation-menu.tsx +0 -128
- package/corpus/templates/videos/app/components/ui/pagination.tsx +0 -121
- package/corpus/templates/videos/app/components/ui/popover.tsx +0 -44
- package/corpus/templates/videos/app/components/ui/progress.tsx +0 -26
- package/corpus/templates/videos/app/components/ui/radio-group.tsx +0 -42
- package/corpus/templates/videos/app/components/ui/resizable.tsx +0 -43
- package/corpus/templates/videos/app/components/ui/scroll-area.tsx +0 -46
- package/corpus/templates/videos/app/components/ui/select.tsx +0 -158
- package/corpus/templates/videos/app/components/ui/separator.tsx +0 -29
- package/corpus/templates/videos/app/components/ui/sheet.tsx +0 -160
- package/corpus/templates/videos/app/components/ui/sidebar.tsx +0 -782
- package/corpus/templates/videos/app/components/ui/skeleton.tsx +0 -15
- package/corpus/templates/videos/app/components/ui/slider.tsx +0 -26
- package/corpus/templates/videos/app/components/ui/sonner.tsx +0 -58
- package/corpus/templates/videos/app/components/ui/spinner.tsx +0 -17
- package/corpus/templates/videos/app/components/ui/switch.tsx +0 -27
- package/corpus/templates/videos/app/components/ui/table.tsx +0 -117
- package/corpus/templates/videos/app/components/ui/tabs.tsx +0 -53
- package/corpus/templates/videos/app/components/ui/textarea.tsx +0 -23
- package/corpus/templates/videos/app/components/ui/toast.tsx +0 -127
- package/corpus/templates/videos/app/components/ui/toaster.tsx +0 -33
- package/corpus/templates/videos/app/components/ui/toggle-group.tsx +0 -59
- package/corpus/templates/videos/app/components/ui/toggle.tsx +0 -43
- package/corpus/templates/videos/app/components/ui/tooltip.tsx +0 -30
- package/corpus/templates/videos/app/components/ui/use-toast.ts +0 -3
- package/corpus/templates/videos/app/config/constants.ts +0 -204
- package/corpus/templates/videos/app/contexts/CompositionContext.tsx +0 -437
- package/corpus/templates/videos/app/contexts/CurrentElementContext.tsx +0 -247
- package/corpus/templates/videos/app/contexts/PlaybackContext.tsx +0 -65
- package/corpus/templates/videos/app/contexts/TimelineContext.tsx +0 -433
- package/corpus/templates/videos/app/entry.client.tsx +0 -19
- package/corpus/templates/videos/app/entry.server.tsx +0 -10
- package/corpus/templates/videos/app/global.css +0 -171
- package/corpus/templates/videos/app/hooks/use-composition-collab.ts +0 -269
- package/corpus/templates/videos/app/hooks/use-composition-design-system.ts +0 -47
- package/corpus/templates/videos/app/hooks/use-database-compositions.ts +0 -144
- package/corpus/templates/videos/app/hooks/use-db-status.ts +0 -30
- package/corpus/templates/videos/app/hooks/use-design-systems.ts +0 -21
- package/corpus/templates/videos/app/hooks/use-folders.ts +0 -199
- package/corpus/templates/videos/app/hooks/use-mobile.tsx +0 -21
- package/corpus/templates/videos/app/hooks/use-navigation-state.ts +0 -52
- package/corpus/templates/videos/app/hooks/use-question-flow.ts +0 -14
- package/corpus/templates/videos/app/hooks/use-toast.ts +0 -188
- package/corpus/templates/videos/app/hooks/useUnsavedChanges.ts +0 -48
- package/corpus/templates/videos/app/i18n/ar-SA.ts +0 -446
- package/corpus/templates/videos/app/i18n/de-DE.ts +0 -470
- package/corpus/templates/videos/app/i18n/en-US.ts +0 -452
- package/corpus/templates/videos/app/i18n/es-ES.ts +0 -468
- package/corpus/templates/videos/app/i18n/fr-FR.ts +0 -469
- package/corpus/templates/videos/app/i18n/hi-IN.ts +0 -446
- package/corpus/templates/videos/app/i18n/index.ts +0 -34
- package/corpus/templates/videos/app/i18n/ja-JP.ts +0 -460
- package/corpus/templates/videos/app/i18n/ko-KR.ts +0 -453
- package/corpus/templates/videos/app/i18n/pt-BR.ts +0 -461
- package/corpus/templates/videos/app/i18n/zh-CN.ts +0 -437
- package/corpus/templates/videos/app/i18n/zh-TW.ts +0 -437
- package/corpus/templates/videos/app/lib/database-compositions.ts +0 -67
- package/corpus/templates/videos/app/lib/design-systems.ts +0 -234
- package/corpus/templates/videos/app/lib/tab-id.ts +0 -1
- package/corpus/templates/videos/app/lib/utils.ts +0 -1
- package/corpus/templates/videos/app/pages/ComponentLibrary.tsx +0 -134
- package/corpus/templates/videos/app/pages/ComponentLibraryView.tsx +0 -362
- package/corpus/templates/videos/app/pages/CompositionView.tsx +0 -715
- package/corpus/templates/videos/app/pages/DesignSystems.tsx +0 -180
- package/corpus/templates/videos/app/pages/Index.tsx +0 -258
- package/corpus/templates/videos/app/pages/NewComposition.tsx +0 -95
- package/corpus/templates/videos/app/pages/NotFound.tsx +0 -36
- package/corpus/templates/videos/app/remotion/CameraHost.tsx +0 -223
- package/corpus/templates/videos/app/remotion/animations/useElementAnimations.ts +0 -231
- package/corpus/templates/videos/app/remotion/componentRegistry.ts +0 -473
- package/corpus/templates/videos/app/remotion/components/AnimatedElement.tsx +0 -436
- package/corpus/templates/videos/app/remotion/components/InteractiveElement.tsx +0 -159
- package/corpus/templates/videos/app/remotion/components/InteractiveZoneEditor.tsx +0 -273
- package/corpus/templates/videos/app/remotion/compositions/BlankComposition.tsx +0 -204
- package/corpus/templates/videos/app/remotion/compositions/index.ts +0 -2
- package/corpus/templates/videos/app/remotion/createComponentCursorTrack.ts +0 -132
- package/corpus/templates/videos/app/remotion/docs/CURSOR_TRACKS.md +0 -285
- package/corpus/templates/videos/app/remotion/easingFunctions.ts +0 -255
- package/corpus/templates/videos/app/remotion/hooks/createInteractiveComposition.tsx +0 -283
- package/corpus/templates/videos/app/remotion/hooks/useCursorHistory.ts +0 -72
- package/corpus/templates/videos/app/remotion/hooks/useCursorTypeFromHover.ts +0 -35
- package/corpus/templates/videos/app/remotion/hooks/useEditableZones.tsx +0 -267
- package/corpus/templates/videos/app/remotion/hooks/useHoverAnimation.ts +0 -90
- package/corpus/templates/videos/app/remotion/hooks/useHoverAnimationSmooth.ts +0 -146
- package/corpus/templates/videos/app/remotion/hooks/useInteractiveComponent.ts +0 -711
- package/corpus/templates/videos/app/remotion/hooks/useRegisterInteractiveElement.ts +0 -56
- package/corpus/templates/videos/app/remotion/library-components/Button.tsx +0 -252
- package/corpus/templates/videos/app/remotion/library-components/Card.tsx +0 -241
- package/corpus/templates/videos/app/remotion/library-components/CodePanel.tsx +0 -1005
- package/corpus/templates/videos/app/remotion/library-components/FileItem.tsx +0 -196
- package/corpus/templates/videos/app/remotion/library-components/FolderItem.tsx +0 -199
- package/corpus/templates/videos/app/remotion/library-components/PrimaryButton.tsx +0 -177
- package/corpus/templates/videos/app/remotion/library-components/SecondaryButton.tsx +0 -167
- package/corpus/templates/videos/app/remotion/library-components/SectionHeader.tsx +0 -108
- package/corpus/templates/videos/app/remotion/library-components/TEMPLATE.tsx +0 -211
- package/corpus/templates/videos/app/remotion/library-components/index.ts +0 -10
- package/corpus/templates/videos/app/remotion/registry.ts +0 -91
- package/corpus/templates/videos/app/remotion/testing/animationTestUtils.ts +0 -366
- package/corpus/templates/videos/app/remotion/trackAnimation.ts +0 -179
- package/corpus/templates/videos/app/remotion/trackHelpers.ts +0 -110
- package/corpus/templates/videos/app/remotion/ui-components/Cursor.tsx +0 -182
- package/corpus/templates/videos/app/remotion/ui-components/InteractiveButton.tsx +0 -116
- package/corpus/templates/videos/app/remotion/ui-components/InteractiveCard.tsx +0 -126
- package/corpus/templates/videos/app/remotion/ui-components/index.ts +0 -16
- package/corpus/templates/videos/app/remotion/utils/animationHelpers.ts +0 -444
- package/corpus/templates/videos/app/remotion/utils/interactiveElements.ts +0 -235
- package/corpus/templates/videos/app/remotion/utils/springAnimation.ts +0 -76
- package/corpus/templates/videos/app/root.tsx +0 -165
- package/corpus/templates/videos/app/routes/$.tsx +0 -10
- package/corpus/templates/videos/app/routes/_index.tsx +0 -25
- package/corpus/templates/videos/app/routes/c.$compositionId.tsx +0 -10
- package/corpus/templates/videos/app/routes/components.tsx +0 -10
- package/corpus/templates/videos/app/routes/design-systems.tsx +0 -10
- package/corpus/templates/videos/app/routes/extensions.$id.$slug.tsx +0 -2
- package/corpus/templates/videos/app/routes/extensions.$id.tsx +0 -5
- package/corpus/templates/videos/app/routes/extensions._index.tsx +0 -5
- package/corpus/templates/videos/app/routes/extensions.tsx +0 -5
- package/corpus/templates/videos/app/routes/settings.tsx +0 -88
- package/corpus/templates/videos/app/routes/team.tsx +0 -11
- package/corpus/templates/videos/app/routes.ts +0 -4
- package/corpus/templates/videos/app/state.ts +0 -77
- package/corpus/templates/videos/app/types/elementAnimations.ts +0 -121
- package/corpus/templates/videos/app/types.ts +0 -200
- package/corpus/templates/videos/app/utils/compositionHelpers.ts +0 -445
- package/corpus/templates/videos/app/utils/debug.ts +0 -63
- package/corpus/templates/videos/app/utils/keyframeUtils.ts +0 -331
- package/corpus/templates/videos/app/utils/timelineCoordinates.ts +0 -79
- package/corpus/templates/videos/app/vite-env.d.ts +0 -6
- package/corpus/templates/videos/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
- package/corpus/templates/videos/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
- package/corpus/templates/videos/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
- package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +0 -6
- package/corpus/templates/videos/changelog/2026-06-29-video-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
- package/corpus/templates/videos/components.json +0 -20
- package/corpus/templates/videos/data/sync-config.json +0 -3
- package/corpus/templates/videos/docs/examples/create-composition.example.ts +0 -128
- package/corpus/templates/videos/drizzle.config.ts +0 -3
- package/corpus/templates/videos/learnings.defaults.md +0 -5
- package/corpus/templates/videos/package.json +0 -114
- package/corpus/templates/videos/public/agent-native-icon-dark.svg +0 -10
- package/corpus/templates/videos/public/agent-native-icon-light.svg +0 -10
- package/corpus/templates/videos/public/agent-native-logo-dark.svg +0 -21
- package/corpus/templates/videos/public/agent-native-logo-light.svg +0 -21
- package/corpus/templates/videos/public/favicon.svg +0 -1
- package/corpus/templates/videos/public/icon-180.svg +0 -1
- package/corpus/templates/videos/public/icon-192.svg +0 -1
- package/corpus/templates/videos/public/icon-512.svg +0 -1
- package/corpus/templates/videos/public/manifest.json +0 -21
- package/corpus/templates/videos/public/placeholder.svg +0 -1
- package/corpus/templates/videos/public/robots.txt +0 -14
- package/corpus/templates/videos/react-router.config.ts +0 -7
- package/corpus/templates/videos/server/db/index.ts +0 -37
- package/corpus/templates/videos/server/db/schema.ts +0 -55
- package/corpus/templates/videos/server/middleware/auth.ts +0 -15
- package/corpus/templates/videos/server/plugins/agent-chat.ts +0 -29
- package/corpus/templates/videos/server/plugins/auth.ts +0 -14
- package/corpus/templates/videos/server/plugins/collab.ts +0 -11
- package/corpus/templates/videos/server/plugins/core-routes.ts +0 -22
- package/corpus/templates/videos/server/plugins/db.ts +0 -160
- package/corpus/templates/videos/server/routes/[...page].get.ts +0 -5
- package/corpus/templates/videos/server/routes/[...page].head.ts +0 -1
- package/corpus/templates/videos/server/routes/api/save-composition-defaults.post.ts +0 -274
- package/corpus/templates/videos/shared/api.ts +0 -75
- package/corpus/templates/videos/ssr-entry.ts +0 -15
- package/corpus/templates/videos/tsconfig.json +0 -21
- package/corpus/templates/videos/vite.config.ts +0 -19
- package/corpus/templates/videos/vitest.config.ts +0 -16
- package/docs/content/locales/ar-SA/template-videos.mdx +0 -336
- package/docs/content/locales/de-DE/template-videos.mdx +0 -336
- package/docs/content/locales/es-ES/template-videos.mdx +0 -336
- package/docs/content/locales/fr-FR/template-videos.mdx +0 -336
- package/docs/content/locales/hi-IN/template-videos.mdx +0 -336
- package/docs/content/locales/ja-JP/template-videos.mdx +0 -336
- package/docs/content/locales/ko-KR/template-videos.mdx +0 -336
- package/docs/content/locales/pt-BR/template-videos.mdx +0 -336
- package/docs/content/locales/zh-CN/template-videos.mdx +0 -334
- package/docs/content/locales/zh-TW/template-videos.mdx +0 -334
- package/docs/content/template-videos.mdx +0 -332
|
@@ -30,7 +30,10 @@ import {
|
|
|
30
30
|
applyFaststart,
|
|
31
31
|
hasPlayableMp4Metadata,
|
|
32
32
|
} from "../server/lib/faststart.js";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
listRecordingChunkKeys,
|
|
35
|
+
validateRecordingChunkKeys,
|
|
36
|
+
} from "../server/lib/recording-upload-state.js";
|
|
34
37
|
import {
|
|
35
38
|
getCurrentOwnerEmail,
|
|
36
39
|
ownerEmailMatches,
|
|
@@ -89,10 +92,6 @@ function concatBytes(parts: Uint8Array[]): Uint8Array {
|
|
|
89
92
|
return out;
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
function chunkIndexFromKey(key: string): number {
|
|
93
|
-
return Number(key.split("-").pop() || 0);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
95
|
const RECORDING_TOO_LARGE_REASON =
|
|
97
96
|
"Recording is too large to process after automatic compression. Please update the app and try again, or record a shorter clip.";
|
|
98
97
|
|
|
@@ -485,39 +484,9 @@ export default defineAction({
|
|
|
485
484
|
updatedAt: new Date().toISOString(),
|
|
486
485
|
});
|
|
487
486
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
const chunkKeys = await listRecordingChunkKeys(ownerEmail, id);
|
|
492
|
-
chunkKeys.sort((a, b) => chunkIndexFromKey(a) - chunkIndexFromKey(b));
|
|
493
|
-
debugLog("[finalize] chunks found", {
|
|
494
|
-
id,
|
|
495
|
-
count: chunkKeys.length,
|
|
496
|
-
});
|
|
497
|
-
// Commit to deleting these keys in the finally below. We collect
|
|
498
|
-
// the keys NOW (not after success) because a throw in uploadFile
|
|
499
|
-
// or the drizzle update would otherwise bypass the delete and
|
|
500
|
-
// orphan the chunks.
|
|
501
|
-
chunkKeysToPurge = chunkKeys;
|
|
502
|
-
|
|
503
|
-
if (chunkKeys.length === 0) {
|
|
504
|
-
await db
|
|
505
|
-
.update(schema.recordings)
|
|
506
|
-
.set({
|
|
507
|
-
status: "failed",
|
|
508
|
-
failureReason: "No chunks found for recording",
|
|
509
|
-
updatedAt: new Date().toISOString(),
|
|
510
|
-
})
|
|
511
|
-
.where(eq(schema.recordings.id, id));
|
|
512
|
-
await writeAppState(`recording-upload-${id}`, {
|
|
513
|
-
recordingId: id,
|
|
514
|
-
status: "failed",
|
|
515
|
-
failureReason: "No chunks found for recording",
|
|
516
|
-
});
|
|
517
|
-
throw new Error(`No chunks found for recording ${id}`);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const failChunkAssembly = async (failureReason: string) => {
|
|
487
|
+
const failChunkAssembly = async (
|
|
488
|
+
failureReason: string,
|
|
489
|
+
): Promise<never> => {
|
|
521
490
|
const now = new Date().toISOString();
|
|
522
491
|
await db
|
|
523
492
|
.update(schema.recordings)
|
|
@@ -536,17 +505,58 @@ export default defineAction({
|
|
|
536
505
|
throw new Error(failureReason);
|
|
537
506
|
};
|
|
538
507
|
|
|
508
|
+
// Pull chunk keys first, then fetch values one at a time. A single
|
|
509
|
+
// SELECT key,value over many base64 chunks can exceed Neon's 8s op
|
|
510
|
+
// timeout before we even start assembling the recording.
|
|
511
|
+
const chunkKeys = await listRecordingChunkKeys(ownerEmail, id);
|
|
512
|
+
const expectedDataChunks = stateNumber(uploadState, "expectedDataChunks");
|
|
513
|
+
debugLog("[finalize] chunks found", {
|
|
514
|
+
id,
|
|
515
|
+
count: chunkKeys.length,
|
|
516
|
+
expectedDataChunks,
|
|
517
|
+
});
|
|
518
|
+
// Commit to deleting these keys in the finally below. We collect
|
|
519
|
+
// the keys NOW (not after success) because a throw in uploadFile
|
|
520
|
+
// or the drizzle update would otherwise bypass the delete and
|
|
521
|
+
// orphan the chunks.
|
|
522
|
+
chunkKeysToPurge = chunkKeys;
|
|
523
|
+
|
|
524
|
+
if (chunkKeys.length === 0) {
|
|
525
|
+
await failChunkAssembly(`No chunks found for recording ${id}`);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
let chunkSequence: ReturnType<typeof validateRecordingChunkKeys>;
|
|
529
|
+
try {
|
|
530
|
+
chunkSequence = validateRecordingChunkKeys(
|
|
531
|
+
chunkKeys,
|
|
532
|
+
expectedDataChunks,
|
|
533
|
+
);
|
|
534
|
+
} catch (err) {
|
|
535
|
+
await failChunkAssembly(
|
|
536
|
+
err instanceof Error
|
|
537
|
+
? err.message
|
|
538
|
+
: "Recording upload is incomplete. Please retry the recording.",
|
|
539
|
+
);
|
|
540
|
+
throw new Error("Unreachable chunk validation failure");
|
|
541
|
+
}
|
|
542
|
+
|
|
539
543
|
const parts: Uint8Array[] = [];
|
|
540
|
-
for (const key of
|
|
544
|
+
for (const { key, index } of chunkSequence) {
|
|
541
545
|
const entry = await readAppState(key);
|
|
542
546
|
const b64 = typeof entry?.data === "string" ? entry.data : null;
|
|
543
|
-
const index = chunkIndexFromKey(key);
|
|
544
547
|
if (!b64) {
|
|
545
548
|
await failChunkAssembly(
|
|
546
549
|
`Recording chunk ${index} is missing upload data. Please retry the recording.`,
|
|
547
550
|
);
|
|
548
551
|
}
|
|
549
552
|
|
|
553
|
+
const entryIndex = stateNumber(entry, "index");
|
|
554
|
+
if (entryIndex !== undefined && entryIndex !== index) {
|
|
555
|
+
await failChunkAssembly(
|
|
556
|
+
`Recording chunk metadata mismatch for chunk ${index}. Please retry the recording.`,
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
|
|
550
560
|
const bytes = b64ToBytes(b64!);
|
|
551
561
|
const expectedBytes = stateNumber(entry, "bytes");
|
|
552
562
|
if (
|
|
@@ -927,9 +927,9 @@ export default function RecordingPage() {
|
|
|
927
927
|
);
|
|
928
928
|
|
|
929
929
|
return (
|
|
930
|
-
<div className="flex h-screen w-full bg-background overflow-hidden">
|
|
930
|
+
<div className="flex min-h-screen w-full bg-background xl:h-screen xl:overflow-hidden">
|
|
931
931
|
{/* Main video column */}
|
|
932
|
-
<div className="flex-
|
|
932
|
+
<div className="flex w-full min-w-0 flex-col xl:flex-1">
|
|
933
933
|
<header className="flex items-center gap-3 px-4 py-3 border-b border-border shrink-0">
|
|
934
934
|
<Button
|
|
935
935
|
variant="ghost"
|
|
@@ -1128,15 +1128,17 @@ export default function RecordingPage() {
|
|
|
1128
1128
|
|
|
1129
1129
|
<div
|
|
1130
1130
|
className={cn(
|
|
1131
|
-
"flex
|
|
1132
|
-
editing && canUseNativeEditor
|
|
1131
|
+
"flex flex-col",
|
|
1132
|
+
editing && canUseNativeEditor
|
|
1133
|
+
? "min-h-0 flex-1 overflow-hidden"
|
|
1134
|
+
: "gap-4 p-4 xl:min-h-0 xl:flex-1 xl:overflow-hidden",
|
|
1133
1135
|
)}
|
|
1134
1136
|
>
|
|
1135
1137
|
{editing && canUseNativeEditor ? (
|
|
1136
1138
|
<EditorLayout recordingId={recording.id} className="flex-1" />
|
|
1137
1139
|
) : (
|
|
1138
1140
|
<>
|
|
1139
|
-
<div className="
|
|
1141
|
+
<div className="relative aspect-video w-full xl:min-h-0 xl:flex-1 xl:aspect-auto">
|
|
1140
1142
|
<VideoPlayer
|
|
1141
1143
|
ref={playerRef}
|
|
1142
1144
|
recordingId={recording.id}
|
|
@@ -1159,7 +1161,7 @@ export default function RecordingPage() {
|
|
|
1159
1161
|
cta={firstCta}
|
|
1160
1162
|
onCtaClick={() => tracking.reportCtaClick()}
|
|
1161
1163
|
onTimeUpdate={(ms) => setCurrentMs(ms)}
|
|
1162
|
-
className="h-full"
|
|
1164
|
+
className="h-full w-full"
|
|
1163
1165
|
/>
|
|
1164
1166
|
{commentOpen ? (
|
|
1165
1167
|
<TimestampedCommentBar
|
|
@@ -773,7 +773,7 @@ export default function ShareRoute() {
|
|
|
773
773
|
return (
|
|
774
774
|
<div className="flex min-h-screen flex-col bg-background text-foreground lg:h-screen lg:flex-row lg:overflow-hidden">
|
|
775
775
|
{agentDiscovery}
|
|
776
|
-
<div className="flex min-w-0 flex-
|
|
776
|
+
<div className="flex w-full min-w-0 flex-col lg:flex-1">
|
|
777
777
|
<header className="flex shrink-0 flex-wrap items-center gap-3 border-b border-border px-4 py-3 lg:flex-nowrap">
|
|
778
778
|
{session ? (
|
|
779
779
|
<Button
|
|
@@ -880,8 +880,8 @@ export default function ShareRoute() {
|
|
|
880
880
|
</div>
|
|
881
881
|
</header>
|
|
882
882
|
|
|
883
|
-
<div className="flex flex-
|
|
884
|
-
<div className="min-h-
|
|
883
|
+
<div className="flex flex-col gap-4 overflow-visible p-4 lg:min-h-0 lg:flex-1 lg:overflow-hidden">
|
|
884
|
+
<div className="aspect-video w-full lg:min-h-0 lg:flex-1 lg:aspect-auto">
|
|
885
885
|
<VideoPlayer
|
|
886
886
|
ref={playerRef}
|
|
887
887
|
recordingId={recording.id}
|
|
@@ -88,6 +88,17 @@ const DEV_SYNTHETIC_CAPTURE_FLAG = "clips:dev-synthetic-capture";
|
|
|
88
88
|
const LEGACY_DEV_REAL_CAPTURE_FLAG = "clips:dev-real-capture";
|
|
89
89
|
const LIVE_UPLOAD_CHUNK_MS = 1_000;
|
|
90
90
|
const NATIVE_FULLSCREEN_SEGMENT_MS = 5 * 60_000;
|
|
91
|
+
// GCS resumable uploads require every non-final chunk to be a multiple of
|
|
92
|
+
// 256 KiB. MediaRecorder emits arbitrary blob sizes, so on the streaming path
|
|
93
|
+
// we buffer raw blobs and only PUT aligned slices; the unaligned remainder is
|
|
94
|
+
// held and sent as the final chunk on stop.
|
|
95
|
+
const GCS_CHUNK_ALIGN_BYTES = 256 * 1024;
|
|
96
|
+
const STREAM_CHUNK_BYTES = 15 * GCS_CHUNK_ALIGN_BYTES; // 3.75 MiB
|
|
97
|
+
|
|
98
|
+
// How the client delivers recorded data to the server.
|
|
99
|
+
// - "streaming" — server has a resumable session; flush aligned chunks live.
|
|
100
|
+
// - "buffered" — per-blob chunks staged server-side, assembled on finalize.
|
|
101
|
+
type UploadMode = "streaming" | "buffered";
|
|
91
102
|
const CLOUD_CAPTURE_FRAME_RATE = 24;
|
|
92
103
|
const CLOUD_CAPTURE_MAX_WIDTH = 1920;
|
|
93
104
|
const CLOUD_CAPTURE_MAX_HEIGHT = 1080;
|
|
@@ -903,12 +914,14 @@ async function createServerRecording(
|
|
|
903
914
|
hasCamera: boolean,
|
|
904
915
|
hasAudio: boolean,
|
|
905
916
|
titleContext?: CaptureTitleResult,
|
|
917
|
+
options?: { mimeType?: string; requestStreaming?: boolean },
|
|
906
918
|
) {
|
|
907
919
|
const url = `${serverUrl.replace(/\/+$/, "")}/_agent-native/actions/create-recording`;
|
|
908
920
|
console.log("[clips-recorder] POST", url, {
|
|
909
921
|
hasCamera,
|
|
910
922
|
hasAudio,
|
|
911
923
|
title: titleContext?.title,
|
|
924
|
+
requestStreaming: options?.requestStreaming ?? false,
|
|
912
925
|
});
|
|
913
926
|
let res: Response;
|
|
914
927
|
try {
|
|
@@ -925,6 +938,9 @@ async function createServerRecording(
|
|
|
925
938
|
hasAudio,
|
|
926
939
|
spaceIds: [],
|
|
927
940
|
visibility: "public",
|
|
941
|
+
...(options?.requestStreaming
|
|
942
|
+
? { requestStreaming: true, mimeType: options.mimeType }
|
|
943
|
+
: {}),
|
|
928
944
|
...(titleContext
|
|
929
945
|
? {
|
|
930
946
|
title: titleContext.title,
|
|
@@ -947,12 +963,18 @@ async function createServerRecording(
|
|
|
947
963
|
console.error("[clips-recorder] bad response:", url, res.status, body);
|
|
948
964
|
throw new Error(`create-recording ${res.status}: ${body.slice(0, 200)}`);
|
|
949
965
|
}
|
|
950
|
-
const data = (await res.json()) as {
|
|
966
|
+
const data = (await res.json()) as {
|
|
967
|
+
result?: { id: string; uploadMode?: string };
|
|
968
|
+
id?: string;
|
|
969
|
+
uploadMode?: string;
|
|
970
|
+
};
|
|
951
971
|
const result = data.result ?? data;
|
|
952
972
|
if (!result.id) {
|
|
953
973
|
throw new Error("create-recording did not return an id");
|
|
954
974
|
}
|
|
955
|
-
|
|
975
|
+
const uploadMode: UploadMode =
|
|
976
|
+
result.uploadMode === "streaming" ? "streaming" : "buffered";
|
|
977
|
+
return { id: result.id, uploadMode };
|
|
956
978
|
}
|
|
957
979
|
|
|
958
980
|
interface ActiveWindowContext {
|
|
@@ -1234,48 +1256,95 @@ function decChunkBusy(): void {
|
|
|
1234
1256
|
}
|
|
1235
1257
|
}
|
|
1236
1258
|
|
|
1259
|
+
// Bounded retry for live chunk uploads. A brief network blip (Wi-Fi roam, DNS
|
|
1260
|
+
// hiccup, a single 5xx) should not fail the whole recording into the manual
|
|
1261
|
+
// backup-replay path when the very next attempt would land
|
|
1262
|
+
const CHUNK_UPLOAD_MAX_ATTEMPTS = 3;
|
|
1263
|
+
const CHUNK_UPLOAD_RETRY_BASE_MS = 250;
|
|
1264
|
+
|
|
1265
|
+
// Only transient server responses are worth retrying inline; a 4xx (bad
|
|
1266
|
+
// request, auth, not found) won't fix itself on the next attempt.
|
|
1267
|
+
function isRetriableChunkStatus(status: number): boolean {
|
|
1268
|
+
return status === 429 || status >= 500;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1237
1271
|
async function uploadChunk(url: string, blob: Blob): Promise<void> {
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1272
|
+
let lastError: Error | null = null;
|
|
1273
|
+
for (let attempt = 1; attempt <= CHUNK_UPLOAD_MAX_ATTEMPTS; attempt++) {
|
|
1274
|
+
// Signal to the bubble frame pump that a chunk is being uploaded, but only
|
|
1275
|
+
// around the actual network call. The pump's tick loop checks this flag and
|
|
1276
|
+
// yields its slot to the fetch for the ~150-300ms the POST takes to
|
|
1277
|
+
// serialize and land. Released before any backoff wait so the pump can
|
|
1278
|
+
// encode frames while we sit idle between attempts.
|
|
1279
|
+
incChunkBusy();
|
|
1280
|
+
let res: Response | null = null;
|
|
1281
|
+
try {
|
|
1282
|
+
res = await fetch(url, {
|
|
1283
|
+
method: "POST",
|
|
1284
|
+
headers: { "Content-Type": blob.type || "application/octet-stream" },
|
|
1285
|
+
// Tauri webview runs on localhost:1420 (dev) or tauri://localhost (prod);
|
|
1286
|
+
// the clips server is a different origin. The framework's dev CORS is
|
|
1287
|
+
// permissive for "*" but won't accept credentialed requests without
|
|
1288
|
+
// Allow-Credentials — and in dev auth is bypassed anyway, so we don't
|
|
1289
|
+
// need cookies.
|
|
1290
|
+
credentials: "include",
|
|
1291
|
+
body: blob,
|
|
1292
|
+
});
|
|
1293
|
+
} catch (err) {
|
|
1294
|
+
// Network-level failure (offline, connection reset, DNS) — transient.
|
|
1295
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
1296
|
+
} finally {
|
|
1297
|
+
decChunkBusy();
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
if (res) {
|
|
1301
|
+
if (res.ok) {
|
|
1302
|
+
// Drain the response body even on success. If we don't consume the
|
|
1303
|
+
// body, WebKit can keep the network buffer resident until GC — that's
|
|
1304
|
+
// extra retention on top of the ~1MB Blob we just uploaded. Reading
|
|
1305
|
+
// and discarding is cheap (the body is usually tiny for a chunk ack)
|
|
1306
|
+
// and makes the memory footprint predictable.
|
|
1307
|
+
try {
|
|
1308
|
+
await res.text();
|
|
1309
|
+
} catch {
|
|
1310
|
+
// ignore — body drain is best-effort
|
|
1311
|
+
}
|
|
1312
|
+
console.log(
|
|
1313
|
+
"[clips-recorder] chunk ok:",
|
|
1314
|
+
res.status,
|
|
1315
|
+
blob.size,
|
|
1316
|
+
"bytes",
|
|
1317
|
+
);
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
const body = await res.text().catch(() => "");
|
|
1321
|
+
lastError = new Error(`chunk ${res.status}: ${body.slice(0, 200)}`);
|
|
1322
|
+
if (!isRetriableChunkStatus(res.status)) {
|
|
1323
|
+
console.error(
|
|
1324
|
+
"[clips-recorder] chunk failed:",
|
|
1325
|
+
res.status,
|
|
1326
|
+
body.slice(0, 200),
|
|
1327
|
+
);
|
|
1328
|
+
throw lastError;
|
|
1329
|
+
}
|
|
1330
|
+
console.warn(
|
|
1331
|
+
"[clips-recorder] chunk retriable failure:",
|
|
1332
|
+
res.status,
|
|
1333
|
+
`attempt ${attempt}/${CHUNK_UPLOAD_MAX_ATTEMPTS}`,
|
|
1334
|
+
);
|
|
1335
|
+
} else {
|
|
1336
|
+
console.warn(
|
|
1337
|
+
"[clips-recorder] chunk network error:",
|
|
1338
|
+
lastError?.message,
|
|
1339
|
+
`attempt ${attempt}/${CHUNK_UPLOAD_MAX_ATTEMPTS}`,
|
|
1340
|
+
);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
if (attempt < CHUNK_UPLOAD_MAX_ATTEMPTS) {
|
|
1344
|
+
await wait(CHUNK_UPLOAD_RETRY_BASE_MS * 2 ** (attempt - 1));
|
|
1345
|
+
}
|
|
1277
1346
|
}
|
|
1278
|
-
|
|
1347
|
+
throw lastError ?? new Error("chunk upload failed");
|
|
1279
1348
|
}
|
|
1280
1349
|
|
|
1281
1350
|
async function abortRecordingUpload(
|
|
@@ -2804,6 +2873,17 @@ async function startRecordingInner(
|
|
|
2804
2873
|
.forEach((track) => uploadCombined.addTrack(track));
|
|
2805
2874
|
recordingAudio.tracks.forEach((track) => uploadCombined.addTrack(track));
|
|
2806
2875
|
|
|
2876
|
+
// MIME type is resolved up front so create-recording can initialize the
|
|
2877
|
+
// resumable session with the correct content type when the server supports
|
|
2878
|
+
// streaming uploads.
|
|
2879
|
+
const mimeCandidates = [
|
|
2880
|
+
"video/webm;codecs=vp9,opus",
|
|
2881
|
+
"video/webm;codecs=vp8,opus",
|
|
2882
|
+
"video/webm",
|
|
2883
|
+
];
|
|
2884
|
+
const mimeType =
|
|
2885
|
+
mimeCandidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? "";
|
|
2886
|
+
|
|
2807
2887
|
// 2+3. Countdown + create-recording happen IN PARALLEL. The countdown is
|
|
2808
2888
|
// pure visual feedback — gating it on a network round-trip makes the
|
|
2809
2889
|
// 3-2-1 feel laggy after the user picks a screen. Kick both off and
|
|
@@ -2818,6 +2898,7 @@ async function startRecordingInner(
|
|
|
2818
2898
|
wantsCamera,
|
|
2819
2899
|
wantsAudio,
|
|
2820
2900
|
captureTitle,
|
|
2901
|
+
{ mimeType: mimeType || "video/webm", requestStreaming: true },
|
|
2821
2902
|
).finally(() => {
|
|
2822
2903
|
console.timeEnd("[clips-recorder] createServerRecording duration");
|
|
2823
2904
|
});
|
|
@@ -2833,12 +2914,12 @@ async function startRecordingInner(
|
|
|
2833
2914
|
);
|
|
2834
2915
|
throw err;
|
|
2835
2916
|
}
|
|
2836
|
-
const { id } = createRes;
|
|
2917
|
+
const { id, uploadMode } = createRes;
|
|
2837
2918
|
console.log(
|
|
2838
2919
|
"[clips-recorder] countdown + createServerRecording both resolved, id=",
|
|
2839
2920
|
id,
|
|
2840
2921
|
);
|
|
2841
|
-
console.log("[clips-recorder] recording row created", { id });
|
|
2922
|
+
console.log("[clips-recorder] recording row created", { id, uploadMode });
|
|
2842
2923
|
let nativeTranscriptFailureSaved = false;
|
|
2843
2924
|
const saveTranscriptFailure = async (failureReason: string) => {
|
|
2844
2925
|
if (!wantsAudio || nativeTranscriptFailureSaved) return;
|
|
@@ -2853,17 +2934,15 @@ async function startRecordingInner(
|
|
|
2853
2934
|
|
|
2854
2935
|
// 4. Start MediaRecorder with a 2-second timeslice — each `ondataavailable`
|
|
2855
2936
|
// streams a chunk to the server, so we don't hold 5-min buffers in memory.
|
|
2856
|
-
const mimeCandidates = [
|
|
2857
|
-
"video/webm;codecs=vp9,opus",
|
|
2858
|
-
"video/webm;codecs=vp8,opus",
|
|
2859
|
-
"video/webm",
|
|
2860
|
-
];
|
|
2861
|
-
const mimeType =
|
|
2862
|
-
mimeCandidates.find((m) => MediaRecorder.isTypeSupported(m)) ?? "";
|
|
2863
2937
|
const recorder = createCloudMediaRecorder(uploadCombined, mimeType);
|
|
2864
2938
|
let chunkIndex = 0;
|
|
2865
2939
|
let failed: Error | null = null;
|
|
2866
2940
|
let backupBytes = 0;
|
|
2941
|
+
// Backup chunks are indexed by raw MediaRecorder blob (one per
|
|
2942
|
+
// `ondataavailable`), independent of `chunkIndex` — on the streaming path
|
|
2943
|
+
// `chunkIndex` counts aligned upload slices, not raw blobs.
|
|
2944
|
+
let backupChunkCount = 0;
|
|
2945
|
+
const streamMimeType = mimeType || "video/webm";
|
|
2867
2946
|
let backupMeta: BrowserRecordingBackupMeta = {
|
|
2868
2947
|
recordingId: id,
|
|
2869
2948
|
serverUrl: params.serverUrl.replace(/\/+$/, ""),
|
|
@@ -2889,6 +2968,41 @@ async function startRecordingInner(
|
|
|
2889
2968
|
persistBackupMeta().catch((err) => {
|
|
2890
2969
|
console.warn("[clips-recorder] local backup metadata failed:", err);
|
|
2891
2970
|
});
|
|
2971
|
+
|
|
2972
|
+
// Every raw MediaRecorder blob is mirrored to IndexedDB on both upload paths.
|
|
2973
|
+
// If uploads fail the recording can still be recovered locally — replayed to
|
|
2974
|
+
// the server (the retry first resets any resumable session so replay routes
|
|
2975
|
+
// through the buffered chunk path) or exported to a local file.
|
|
2976
|
+
const backupWrites = new Set<Promise<void>>();
|
|
2977
|
+
const backupChunkLocally = (blob: Blob): Promise<void> => {
|
|
2978
|
+
const backupIdx = backupChunkCount++;
|
|
2979
|
+
backupBytes += blob.size;
|
|
2980
|
+
const chunkMimeType = blob.type || streamMimeType;
|
|
2981
|
+
let w: Promise<void>;
|
|
2982
|
+
w = (async () => {
|
|
2983
|
+
try {
|
|
2984
|
+
await putBrowserRecordingBackupChunk({
|
|
2985
|
+
recordingId: id,
|
|
2986
|
+
index: backupIdx,
|
|
2987
|
+
blob,
|
|
2988
|
+
bytes: blob.size,
|
|
2989
|
+
mimeType: chunkMimeType,
|
|
2990
|
+
createdAt: new Date().toISOString(),
|
|
2991
|
+
});
|
|
2992
|
+
await persistBackupMeta({
|
|
2993
|
+
bytes: backupBytes,
|
|
2994
|
+
chunkCount: backupChunkCount,
|
|
2995
|
+
mimeType: chunkMimeType,
|
|
2996
|
+
});
|
|
2997
|
+
} catch (err) {
|
|
2998
|
+
console.warn("[clips-recorder] local chunk backup failed:", err);
|
|
2999
|
+
}
|
|
3000
|
+
})().finally(() => {
|
|
3001
|
+
backupWrites.delete(w);
|
|
3002
|
+
});
|
|
3003
|
+
backupWrites.add(w);
|
|
3004
|
+
return w;
|
|
3005
|
+
};
|
|
2892
3006
|
// In-flight chunk uploads. We use a Set (not an array) so entries can be
|
|
2893
3007
|
// removed as soon as each fetch settles — otherwise, for a 30-minute
|
|
2894
3008
|
// recording the array grows to 900 Promises, and EACH promise closes over
|
|
@@ -2898,10 +3012,62 @@ async function startRecordingInner(
|
|
|
2898
3012
|
// See `uploadChunk()` — it removes its own entry in `.finally()`.
|
|
2899
3013
|
const inflight = new Set<Promise<void>>();
|
|
2900
3014
|
|
|
3015
|
+
// Streaming-path state. When the server opened a resumable session, blobs
|
|
3016
|
+
// accumulate here until at least STREAM_CHUNK_BYTES is available, then a
|
|
3017
|
+
// 256 KiB-aligned slice is uploaded as a non-final chunk. Resumable sessions
|
|
3018
|
+
// append by byte offset server-side, so streamed chunks MUST arrive in order
|
|
3019
|
+
// — uploads are serialized through `streamQueue`. The unaligned remainder is
|
|
3020
|
+
// sent as the final chunk on stop().
|
|
3021
|
+
let pendingStreamBlobs: Blob[] = [];
|
|
3022
|
+
let pendingStreamBytes = 0;
|
|
3023
|
+
let streamQueue: Promise<void> = Promise.resolve();
|
|
3024
|
+
|
|
3025
|
+
const queueStreamChunk = (blob: Blob, idx: number) => {
|
|
3026
|
+
const url = chunkUrl(params.serverUrl, id, idx, false, {
|
|
3027
|
+
mimeType: streamMimeType,
|
|
3028
|
+
});
|
|
3029
|
+
streamQueue = streamQueue.then(async () => {
|
|
3030
|
+
if (failed) return;
|
|
3031
|
+
try {
|
|
3032
|
+
await uploadChunk(url, blob);
|
|
3033
|
+
} catch (err) {
|
|
3034
|
+
failed ??= err instanceof Error ? err : new Error(String(err));
|
|
3035
|
+
}
|
|
3036
|
+
});
|
|
3037
|
+
};
|
|
3038
|
+
|
|
3039
|
+
const flushAlignedStreamChunks = () => {
|
|
3040
|
+
while (pendingStreamBytes >= STREAM_CHUNK_BYTES) {
|
|
3041
|
+
const combined = new Blob(pendingStreamBlobs, { type: streamMimeType });
|
|
3042
|
+
const head = combined.slice(0, STREAM_CHUNK_BYTES, streamMimeType);
|
|
3043
|
+
const tail = combined.slice(
|
|
3044
|
+
STREAM_CHUNK_BYTES,
|
|
3045
|
+
combined.size,
|
|
3046
|
+
streamMimeType,
|
|
3047
|
+
);
|
|
3048
|
+
pendingStreamBlobs = tail.size > 0 ? [tail] : [];
|
|
3049
|
+
pendingStreamBytes = tail.size;
|
|
3050
|
+
queueStreamChunk(head, chunkIndex++);
|
|
3051
|
+
}
|
|
3052
|
+
};
|
|
3053
|
+
|
|
2901
3054
|
recorder.ondataavailable = (ev) => {
|
|
2902
3055
|
if (!ev.data || ev.data.size === 0) return;
|
|
3056
|
+
|
|
3057
|
+
// Always mirror the raw blob to the local backup first (disaster recovery).
|
|
3058
|
+
void backupChunkLocally(ev.data);
|
|
3059
|
+
|
|
3060
|
+
if (uploadMode === "streaming") {
|
|
3061
|
+
// Resumable session on the server: buffer and flush 256 KiB-aligned
|
|
3062
|
+
// slices, uploaded in order. The unaligned remainder is sent as the
|
|
3063
|
+
// final chunk on stop().
|
|
3064
|
+
pendingStreamBlobs.push(ev.data);
|
|
3065
|
+
pendingStreamBytes += ev.data.size;
|
|
3066
|
+
flushAlignedStreamChunks();
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
|
|
2903
3070
|
const idx = chunkIndex++;
|
|
2904
|
-
backupBytes += ev.data.size;
|
|
2905
3071
|
const chunkMimeType = ev.data.type || mimeType || "video/webm";
|
|
2906
3072
|
const url = chunkUrl(params.serverUrl, id, idx, false, {
|
|
2907
3073
|
mimeType: chunkMimeType,
|
|
@@ -2912,26 +3078,7 @@ async function startRecordingInner(
|
|
|
2912
3078
|
// constructing the promise body so `inflight.delete(p)` inside the
|
|
2913
3079
|
// `.finally` can reference the same handle we added.
|
|
2914
3080
|
let p: Promise<void>;
|
|
2915
|
-
p = (
|
|
2916
|
-
try {
|
|
2917
|
-
await putBrowserRecordingBackupChunk({
|
|
2918
|
-
recordingId: id,
|
|
2919
|
-
index: idx,
|
|
2920
|
-
blob: ev.data,
|
|
2921
|
-
bytes: ev.data.size,
|
|
2922
|
-
mimeType: chunkMimeType,
|
|
2923
|
-
createdAt: new Date().toISOString(),
|
|
2924
|
-
});
|
|
2925
|
-
await persistBackupMeta({
|
|
2926
|
-
bytes: backupBytes,
|
|
2927
|
-
chunkCount: Math.max(backupMeta.chunkCount, idx + 1),
|
|
2928
|
-
mimeType: chunkMimeType,
|
|
2929
|
-
});
|
|
2930
|
-
} catch (err) {
|
|
2931
|
-
console.warn("[clips-recorder] local chunk backup failed:", err);
|
|
2932
|
-
}
|
|
2933
|
-
await uploadChunk(url, ev.data);
|
|
2934
|
-
})()
|
|
3081
|
+
p = uploadChunk(url, ev.data)
|
|
2935
3082
|
.catch((err) => {
|
|
2936
3083
|
failed ??= err instanceof Error ? err : new Error(String(err));
|
|
2937
3084
|
})
|
|
@@ -3182,7 +3329,7 @@ async function startRecordingInner(
|
|
|
3182
3329
|
bytes: backupBytes,
|
|
3183
3330
|
hasAudio: uploadCombined.getAudioTracks().length > 0,
|
|
3184
3331
|
hasCamera: wantsCamera,
|
|
3185
|
-
chunkCount:
|
|
3332
|
+
chunkCount: backupChunkCount,
|
|
3186
3333
|
mimeType: finalMimeType,
|
|
3187
3334
|
lastError: null,
|
|
3188
3335
|
}).catch((err) => {
|
|
@@ -3235,11 +3382,19 @@ async function startRecordingInner(
|
|
|
3235
3382
|
|
|
3236
3383
|
// Wait for any in-flight chunk uploads to settle before sending the
|
|
3237
3384
|
// final chunk. Otherwise the server could finalize before the last
|
|
3238
|
-
// few bytes land.
|
|
3239
|
-
//
|
|
3385
|
+
// few bytes land. On the streaming path uploads are serialized through
|
|
3386
|
+
// `streamQueue`; on the buffered path they run concurrently and each
|
|
3387
|
+
// `.finally` has already removed settled entries from `inflight`.
|
|
3240
3388
|
const pending = Array.from(inflight);
|
|
3241
|
-
|
|
3389
|
+
if (uploadMode === "streaming") {
|
|
3390
|
+
await streamQueue;
|
|
3391
|
+
} else {
|
|
3392
|
+
await Promise.allSettled(pending);
|
|
3393
|
+
}
|
|
3242
3394
|
inflight.clear();
|
|
3395
|
+
// Ensure the local backup is fully written before we either delete it
|
|
3396
|
+
// (on success) or leave it in place for recovery (on failure).
|
|
3397
|
+
await Promise.allSettled([...backupWrites]);
|
|
3243
3398
|
if (failed) {
|
|
3244
3399
|
console.error("[clips-recorder] chunk upload failed:", failed);
|
|
3245
3400
|
await markBrowserRecordingBackupError(id, failed.message).catch(
|
|
@@ -3253,6 +3408,17 @@ async function startRecordingInner(
|
|
|
3253
3408
|
throw failed;
|
|
3254
3409
|
}
|
|
3255
3410
|
|
|
3411
|
+
// Streaming: the closing bytes are whatever remains under the 256 KiB
|
|
3412
|
+
// alignment boundary — send them as the final chunk so the resumable
|
|
3413
|
+
// session can complete. Buffered: bytes are already staged server-side,
|
|
3414
|
+
// so the final chunk is a 0-byte close sentinel.
|
|
3415
|
+
const finalBody =
|
|
3416
|
+
uploadMode === "streaming"
|
|
3417
|
+
? new Blob(pendingStreamBlobs, { type: finalMimeType })
|
|
3418
|
+
: new Blob([], { type: finalMimeType });
|
|
3419
|
+
pendingStreamBlobs = [];
|
|
3420
|
+
pendingStreamBytes = 0;
|
|
3421
|
+
|
|
3256
3422
|
const finalizeUrl = chunkUrl(params.serverUrl, id, chunkIndex, true, {
|
|
3257
3423
|
mimeType: finalMimeType,
|
|
3258
3424
|
durationMs: String(durationMs),
|
|
@@ -3264,6 +3430,8 @@ async function startRecordingInner(
|
|
|
3264
3430
|
console.log("[clips-recorder] finalize POST", finalizeUrl, {
|
|
3265
3431
|
chunksSent: chunkIndex,
|
|
3266
3432
|
inflightAtFinalize: pending.length,
|
|
3433
|
+
finalBodyBytes: finalBody.size,
|
|
3434
|
+
uploadMode,
|
|
3267
3435
|
anyFailed: !!failed,
|
|
3268
3436
|
});
|
|
3269
3437
|
try {
|
|
@@ -3271,7 +3439,7 @@ async function startRecordingInner(
|
|
|
3271
3439
|
method: "POST",
|
|
3272
3440
|
headers: { "Content-Type": "application/octet-stream" },
|
|
3273
3441
|
credentials: "include",
|
|
3274
|
-
body:
|
|
3442
|
+
body: finalBody,
|
|
3275
3443
|
});
|
|
3276
3444
|
const bodyText = await finalRes.text().catch(() => "");
|
|
3277
3445
|
console.log(
|