@agent-native/core 0.85.7 → 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 +124 -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/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/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/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/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 +50 -12
- 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 +10 -2
- package/corpus/templates/design/actions/apply-fusion-edits.ts +161 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +34 -1
- 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/get-fusion-deploy-status.ts +86 -0
- 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/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/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 +115 -14
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +12 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +379 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +149 -73
- package/corpus/templates/design/app/components/design/FusionAppBanner.tsx +328 -0
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +148 -30
- package/corpus/templates/design/app/components/design/LocalhostWriteConsentDialog.tsx +1 -1
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +567 -6
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +7 -98
- 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/DesignColorPicker.tsx +127 -10
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +52 -29
- package/corpus/templates/design/app/components/design/inspector/index.ts +9 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +56 -0
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +80 -1
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +6 -16
- package/corpus/templates/design/app/i18n/zh-TW.ts +2 -1
- package/corpus/templates/design/app/i18n-data.ts +31 -18
- package/corpus/templates/design/app/pages/DesignEditor.tsx +1474 -175
- package/corpus/templates/design/app/pages/Index.tsx +90 -17
- 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/package.json +4 -3
- package/corpus/templates/design/server/db/schema.ts +31 -0
- 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/collab-selection.ts +52 -0
- package/corpus/templates/design/shared/full-app.ts +126 -0
- package/corpus/templates/design/shared/pen-path.ts +296 -0
- 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/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 +12 -1
- 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/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/routes.d.ts +2 -2
- package/dist/collab/struct-routes.d.ts +1 -1
- 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 +2 -2
- 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/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- 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/server/transcribe-voice.d.ts +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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recent-edit attribution for collaborative documents.
|
|
3
|
+
*
|
|
4
|
+
* Every participant (human or agent) may publish a short ring of recent edits
|
|
5
|
+
* in its awareness state under the `recentEdits` key. Clients render these as
|
|
6
|
+
* lingering, fading highlights ("Google Docs / Figma collaborator just edited
|
|
7
|
+
* this") for a few seconds after the edit lands, with the editor's name and
|
|
8
|
+
* color next to the highlighted region.
|
|
9
|
+
*
|
|
10
|
+
* The descriptor is intentionally open-ended — each app publishes whatever its
|
|
11
|
+
* surfaces can resolve back to a DOM rect:
|
|
12
|
+
* - `{ kind: "text", quote }` rich-text apps resolve by text search
|
|
13
|
+
* - `{ kind: "selector", selector }` canvas/DOM apps resolve by querySelector
|
|
14
|
+
* - `{ kind: "paths", paths }` structured apps resolve JSON paths
|
|
15
|
+
* (e.g. `slides.3.content`) to their rendered element
|
|
16
|
+
* - `{ kind: "doc" }` whole-document change (no region)
|
|
17
|
+
*/
|
|
18
|
+
import type { OtherPresence } from "./presence.js";
|
|
19
|
+
export type RecentEditDescriptor = {
|
|
20
|
+
kind: "text";
|
|
21
|
+
quote: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "selector";
|
|
24
|
+
selector: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: "paths";
|
|
27
|
+
paths: string[];
|
|
28
|
+
} | {
|
|
29
|
+
kind: "doc";
|
|
30
|
+
} | {
|
|
31
|
+
kind: string;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
};
|
|
34
|
+
export interface RecentEdit {
|
|
35
|
+
descriptor: RecentEditDescriptor;
|
|
36
|
+
/** Short human-readable label, e.g. "Rewrote intro" or "Slide 3". */
|
|
37
|
+
label?: string;
|
|
38
|
+
/** Epoch ms when the edit landed. */
|
|
39
|
+
at: number;
|
|
40
|
+
}
|
|
41
|
+
/** A recent edit attributed to the participant who made it. */
|
|
42
|
+
export interface AttributedRecentEdit extends RecentEdit {
|
|
43
|
+
clientId: number;
|
|
44
|
+
user: OtherPresence["user"];
|
|
45
|
+
isAgent: boolean;
|
|
46
|
+
}
|
|
47
|
+
/** Max entries kept in a participant's recentEdits ring. */
|
|
48
|
+
export declare const RECENT_EDITS_MAX = 5;
|
|
49
|
+
/**
|
|
50
|
+
* Default time a recent-edit highlight stays visible, measured from the
|
|
51
|
+
* edit's `at` timestamp. Awareness delivery adds up to ~3s (poll cadence),
|
|
52
|
+
* and some actions do post-write work before a viewer looks, so this is
|
|
53
|
+
* deliberately generous — the fade consumes the final 40% of the window.
|
|
54
|
+
*/
|
|
55
|
+
export declare const RECENT_EDIT_TTL_MS = 10000;
|
|
56
|
+
/**
|
|
57
|
+
* Append an edit to a recentEdits ring, keeping the newest
|
|
58
|
+
* {@link RECENT_EDITS_MAX} entries. Pure — returns a new array.
|
|
59
|
+
*/
|
|
60
|
+
export declare function appendRecentEdit(existing: RecentEdit[] | undefined, edit: RecentEdit): RecentEdit[];
|
|
61
|
+
/**
|
|
62
|
+
* Flatten non-expired recent edits from remote participants, newest last.
|
|
63
|
+
* Pure — exported for tests and non-React consumers.
|
|
64
|
+
*/
|
|
65
|
+
export declare function collectRecentEdits(others: OtherPresence[], ttlMs: number, now: number): AttributedRecentEdit[];
|
|
66
|
+
export interface UseRecentEditsOptions {
|
|
67
|
+
/** How long a highlight lingers after the edit. Default 6000ms. */
|
|
68
|
+
ttlMs?: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Reactive list of remote participants' recent edits that haven't expired.
|
|
72
|
+
* Ticks internally (~500ms) while any highlight is visible so consumers can
|
|
73
|
+
* render a smooth fade-out without wiring their own timers.
|
|
74
|
+
*/
|
|
75
|
+
export declare function useRecentEdits(others: OtherPresence[], options?: UseRecentEditsOptions): AttributedRecentEdit[];
|
|
76
|
+
/**
|
|
77
|
+
* Publish a local edit into this client's awareness ring so peers render a
|
|
78
|
+
* lingering highlight for it. Call from app mutation paths (throttled by the
|
|
79
|
+
* ring size + TTL; safe to call per committed edit, not per keystroke).
|
|
80
|
+
*/
|
|
81
|
+
export declare function publishRecentEdit(awareness: {
|
|
82
|
+
getLocalState: () => Record<string, unknown> | null;
|
|
83
|
+
setLocalStateField: (field: string, value: unknown) => void;
|
|
84
|
+
}, edit: Omit<RecentEdit, "at"> & {
|
|
85
|
+
at?: number;
|
|
86
|
+
}): void;
|
|
87
|
+
//# sourceMappingURL=recent-edits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent-edits.d.ts","sourceRoot":"","sources":["../../src/collab/recent-edits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE7C,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,oBAAoB,CAAC;IACjC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,+DAA+D;AAC/D,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,UAAU,EAAE,GAAG,SAAS,EAClC,IAAI,EAAE,UAAU,GACf,UAAU,EAAE,CAOd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,oBAAoB,EAAE,CAmBxB;AAED,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,oBAAoB,EAAE,CA0BxB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE;IACT,aAAa,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACpD,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7D,EACD,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C,IAAI,CAON"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recent-edit attribution for collaborative documents.
|
|
3
|
+
*
|
|
4
|
+
* Every participant (human or agent) may publish a short ring of recent edits
|
|
5
|
+
* in its awareness state under the `recentEdits` key. Clients render these as
|
|
6
|
+
* lingering, fading highlights ("Google Docs / Figma collaborator just edited
|
|
7
|
+
* this") for a few seconds after the edit lands, with the editor's name and
|
|
8
|
+
* color next to the highlighted region.
|
|
9
|
+
*
|
|
10
|
+
* The descriptor is intentionally open-ended — each app publishes whatever its
|
|
11
|
+
* surfaces can resolve back to a DOM rect:
|
|
12
|
+
* - `{ kind: "text", quote }` rich-text apps resolve by text search
|
|
13
|
+
* - `{ kind: "selector", selector }` canvas/DOM apps resolve by querySelector
|
|
14
|
+
* - `{ kind: "paths", paths }` structured apps resolve JSON paths
|
|
15
|
+
* (e.g. `slides.3.content`) to their rendered element
|
|
16
|
+
* - `{ kind: "doc" }` whole-document change (no region)
|
|
17
|
+
*/
|
|
18
|
+
import { useEffect, useRef, useState } from "react";
|
|
19
|
+
/** Max entries kept in a participant's recentEdits ring. */
|
|
20
|
+
export const RECENT_EDITS_MAX = 5;
|
|
21
|
+
/**
|
|
22
|
+
* Default time a recent-edit highlight stays visible, measured from the
|
|
23
|
+
* edit's `at` timestamp. Awareness delivery adds up to ~3s (poll cadence),
|
|
24
|
+
* and some actions do post-write work before a viewer looks, so this is
|
|
25
|
+
* deliberately generous — the fade consumes the final 40% of the window.
|
|
26
|
+
*/
|
|
27
|
+
export const RECENT_EDIT_TTL_MS = 10_000;
|
|
28
|
+
/**
|
|
29
|
+
* Append an edit to a recentEdits ring, keeping the newest
|
|
30
|
+
* {@link RECENT_EDITS_MAX} entries. Pure — returns a new array.
|
|
31
|
+
*/
|
|
32
|
+
export function appendRecentEdit(existing, edit) {
|
|
33
|
+
const ring = Array.isArray(existing) ? existing.slice() : [];
|
|
34
|
+
ring.push(edit);
|
|
35
|
+
if (ring.length > RECENT_EDITS_MAX) {
|
|
36
|
+
ring.splice(0, ring.length - RECENT_EDITS_MAX);
|
|
37
|
+
}
|
|
38
|
+
return ring;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Flatten non-expired recent edits from remote participants, newest last.
|
|
42
|
+
* Pure — exported for tests and non-React consumers.
|
|
43
|
+
*/
|
|
44
|
+
export function collectRecentEdits(others, ttlMs, now) {
|
|
45
|
+
const result = [];
|
|
46
|
+
for (const other of others) {
|
|
47
|
+
const ring = other.presence["recentEdits"];
|
|
48
|
+
if (!Array.isArray(ring))
|
|
49
|
+
continue;
|
|
50
|
+
for (const raw of ring) {
|
|
51
|
+
const edit = raw;
|
|
52
|
+
if (!edit || typeof edit.at !== "number" || !edit.descriptor)
|
|
53
|
+
continue;
|
|
54
|
+
if (now - edit.at > ttlMs)
|
|
55
|
+
continue;
|
|
56
|
+
result.push({
|
|
57
|
+
...edit,
|
|
58
|
+
clientId: other.clientId,
|
|
59
|
+
user: other.user,
|
|
60
|
+
isAgent: other.isAgent,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
result.sort((a, b) => a.at - b.at);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Reactive list of remote participants' recent edits that haven't expired.
|
|
69
|
+
* Ticks internally (~500ms) while any highlight is visible so consumers can
|
|
70
|
+
* render a smooth fade-out without wiring their own timers.
|
|
71
|
+
*/
|
|
72
|
+
export function useRecentEdits(others, options) {
|
|
73
|
+
const ttlMs = options?.ttlMs ?? RECENT_EDIT_TTL_MS;
|
|
74
|
+
const [edits, setEdits] = useState([]);
|
|
75
|
+
const othersRef = useRef(others);
|
|
76
|
+
othersRef.current = others;
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
let timer = null;
|
|
79
|
+
function tick() {
|
|
80
|
+
const next = collectRecentEdits(othersRef.current, ttlMs, Date.now());
|
|
81
|
+
setEdits((prev) => (recentEditsEqual(prev, next) ? prev : next));
|
|
82
|
+
if (next.length > 0) {
|
|
83
|
+
timer = setTimeout(tick, 500);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
timer = null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
tick();
|
|
90
|
+
return () => {
|
|
91
|
+
if (timer)
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
};
|
|
94
|
+
}, [others, ttlMs]);
|
|
95
|
+
return edits;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Publish a local edit into this client's awareness ring so peers render a
|
|
99
|
+
* lingering highlight for it. Call from app mutation paths (throttled by the
|
|
100
|
+
* ring size + TTL; safe to call per committed edit, not per keystroke).
|
|
101
|
+
*/
|
|
102
|
+
export function publishRecentEdit(awareness, edit) {
|
|
103
|
+
const local = awareness.getLocalState();
|
|
104
|
+
const existing = local?.["recentEdits"];
|
|
105
|
+
awareness.setLocalStateField("recentEdits", appendRecentEdit(existing, { ...edit, at: edit.at ?? Date.now() }));
|
|
106
|
+
}
|
|
107
|
+
function recentEditsEqual(a, b) {
|
|
108
|
+
if (a.length !== b.length)
|
|
109
|
+
return false;
|
|
110
|
+
for (let i = 0; i < a.length; i++) {
|
|
111
|
+
if (a[i].clientId !== b[i].clientId || a[i].at !== b[i].at)
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=recent-edits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recent-edits.js","sourceRoot":"","sources":["../../src/collab/recent-edits.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Recent-edit attribution for collaborative documents.\n *\n * Every participant (human or agent) may publish a short ring of recent edits\n * in its awareness state under the `recentEdits` key. Clients render these as\n * lingering, fading highlights (\"Google Docs / Figma collaborator just edited\n * this\") for a few seconds after the edit lands, with the editor's name and\n * color next to the highlighted region.\n *\n * The descriptor is intentionally open-ended — each app publishes whatever its\n * surfaces can resolve back to a DOM rect:\n * - `{ kind: \"text\", quote }` rich-text apps resolve by text search\n * - `{ kind: \"selector\", selector }` canvas/DOM apps resolve by querySelector\n * - `{ kind: \"paths\", paths }` structured apps resolve JSON paths\n * (e.g. `slides.3.content`) to their rendered element\n * - `{ kind: \"doc\" }` whole-document change (no region)\n */\n\nimport { useEffect, useRef, useState } from \"react\";\n\nimport type { OtherPresence } from \"./presence.js\";\n\nexport type RecentEditDescriptor =\n | { kind: \"text\"; quote: string }\n | { kind: \"selector\"; selector: string }\n | { kind: \"paths\"; paths: string[] }\n | { kind: \"doc\" }\n | { kind: string; [key: string]: unknown };\n\nexport interface RecentEdit {\n descriptor: RecentEditDescriptor;\n /** Short human-readable label, e.g. \"Rewrote intro\" or \"Slide 3\". */\n label?: string;\n /** Epoch ms when the edit landed. */\n at: number;\n}\n\n/** A recent edit attributed to the participant who made it. */\nexport interface AttributedRecentEdit extends RecentEdit {\n clientId: number;\n user: OtherPresence[\"user\"];\n isAgent: boolean;\n}\n\n/** Max entries kept in a participant's recentEdits ring. */\nexport const RECENT_EDITS_MAX = 5;\n\n/**\n * Default time a recent-edit highlight stays visible, measured from the\n * edit's `at` timestamp. Awareness delivery adds up to ~3s (poll cadence),\n * and some actions do post-write work before a viewer looks, so this is\n * deliberately generous — the fade consumes the final 40% of the window.\n */\nexport const RECENT_EDIT_TTL_MS = 10_000;\n\n/**\n * Append an edit to a recentEdits ring, keeping the newest\n * {@link RECENT_EDITS_MAX} entries. Pure — returns a new array.\n */\nexport function appendRecentEdit(\n existing: RecentEdit[] | undefined,\n edit: RecentEdit,\n): RecentEdit[] {\n const ring = Array.isArray(existing) ? existing.slice() : [];\n ring.push(edit);\n if (ring.length > RECENT_EDITS_MAX) {\n ring.splice(0, ring.length - RECENT_EDITS_MAX);\n }\n return ring;\n}\n\n/**\n * Flatten non-expired recent edits from remote participants, newest last.\n * Pure — exported for tests and non-React consumers.\n */\nexport function collectRecentEdits(\n others: OtherPresence[],\n ttlMs: number,\n now: number,\n): AttributedRecentEdit[] {\n const result: AttributedRecentEdit[] = [];\n for (const other of others) {\n const ring = other.presence[\"recentEdits\"];\n if (!Array.isArray(ring)) continue;\n for (const raw of ring) {\n const edit = raw as RecentEdit;\n if (!edit || typeof edit.at !== \"number\" || !edit.descriptor) continue;\n if (now - edit.at > ttlMs) continue;\n result.push({\n ...edit,\n clientId: other.clientId,\n user: other.user,\n isAgent: other.isAgent,\n });\n }\n }\n result.sort((a, b) => a.at - b.at);\n return result;\n}\n\nexport interface UseRecentEditsOptions {\n /** How long a highlight lingers after the edit. Default 6000ms. */\n ttlMs?: number;\n}\n\n/**\n * Reactive list of remote participants' recent edits that haven't expired.\n * Ticks internally (~500ms) while any highlight is visible so consumers can\n * render a smooth fade-out without wiring their own timers.\n */\nexport function useRecentEdits(\n others: OtherPresence[],\n options?: UseRecentEditsOptions,\n): AttributedRecentEdit[] {\n const ttlMs = options?.ttlMs ?? RECENT_EDIT_TTL_MS;\n const [edits, setEdits] = useState<AttributedRecentEdit[]>([]);\n const othersRef = useRef(others);\n othersRef.current = others;\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function tick() {\n const next = collectRecentEdits(othersRef.current, ttlMs, Date.now());\n setEdits((prev) => (recentEditsEqual(prev, next) ? prev : next));\n if (next.length > 0) {\n timer = setTimeout(tick, 500);\n } else {\n timer = null;\n }\n }\n\n tick();\n return () => {\n if (timer) clearTimeout(timer);\n };\n }, [others, ttlMs]);\n\n return edits;\n}\n\n/**\n * Publish a local edit into this client's awareness ring so peers render a\n * lingering highlight for it. Call from app mutation paths (throttled by the\n * ring size + TTL; safe to call per committed edit, not per keystroke).\n */\nexport function publishRecentEdit(\n awareness: {\n getLocalState: () => Record<string, unknown> | null;\n setLocalStateField: (field: string, value: unknown) => void;\n },\n edit: Omit<RecentEdit, \"at\"> & { at?: number },\n): void {\n const local = awareness.getLocalState();\n const existing = local?.[\"recentEdits\"] as RecentEdit[] | undefined;\n awareness.setLocalStateField(\n \"recentEdits\",\n appendRecentEdit(existing, { ...edit, at: edit.at ?? Date.now() }),\n );\n}\n\nfunction recentEditsEqual(\n a: AttributedRecentEdit[],\n b: AttributedRecentEdit[],\n): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i].clientId !== b[i].clientId || a[i].at !== b[i].at) return false;\n }\n return true;\n}\n"]}
|
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
|
@@ -41,9 +41,9 @@ export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import
|
|
|
41
41
|
* Body: { text: string, fieldName?: string, requestSource?: string }
|
|
42
42
|
*/
|
|
43
43
|
export declare const postCollabText: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
44
|
-
text?: undefined;
|
|
45
44
|
ok?: undefined;
|
|
46
45
|
error: string;
|
|
46
|
+
text?: undefined;
|
|
47
47
|
} | {
|
|
48
48
|
error?: undefined;
|
|
49
49
|
ok: boolean;
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
|
|
14
14
|
*/
|
|
15
15
|
export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
16
|
-
ok?: undefined;
|
|
17
16
|
error: string;
|
|
17
|
+
ok?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
error?: undefined;
|
|
20
20
|
ok: boolean;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared per-user undo/redo for collaborative surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Two primitives, one rule: undo NEVER reverts another participant's (human
|
|
5
|
+
* or agent) work, and never restores whole-document snapshots that would
|
|
6
|
+
* clobber concurrent edits.
|
|
7
|
+
*
|
|
8
|
+
* - `useCollabUndo` — Y.UndoManager lifecycle wrapper for Yjs-backed surfaces.
|
|
9
|
+
* Tracks only transactions tagged with the local origin, coalesces rapid
|
|
10
|
+
* edits, and is recreated/destroyed when the document changes (stale
|
|
11
|
+
* managers hold Y.Doc references and grow unboundedly).
|
|
12
|
+
*
|
|
13
|
+
* - `useLocalOpUndo` / `createLocalOpUndoController` — inverse-operation undo
|
|
14
|
+
* for op-based apps (slides decks, forms). Each local mutation registers
|
|
15
|
+
* the granular ops that redo and undo it; Cmd+Z replays the inverse ops
|
|
16
|
+
* through the app's normal granular mutation path, so concurrent edits by
|
|
17
|
+
* other participants to OTHER items are never touched.
|
|
18
|
+
*/
|
|
19
|
+
import * as Y from "yjs";
|
|
20
|
+
export interface UndoKeyboardOptions {
|
|
21
|
+
/** Bind Mod+Z / Shift+Mod+Z / Mod+Y on window while mounted. */
|
|
22
|
+
enableKeyboardShortcuts?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Skip the shortcut when the event target is an input, textarea, or
|
|
25
|
+
* contentEditable (those own their own undo). Default true.
|
|
26
|
+
*/
|
|
27
|
+
ignoreInputTargets?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export type CollabUndoScope = Y.AbstractType<any> | Y.AbstractType<any>[] | ((doc: Y.Doc) => Y.AbstractType<any> | Y.AbstractType<any>[]);
|
|
30
|
+
export interface UseCollabUndoOptions extends UndoKeyboardOptions {
|
|
31
|
+
/** The collaborative document. Null/undefined while loading. */
|
|
32
|
+
ydoc: Y.Doc | null | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Shared type(s) to track, or a factory receiving the doc (evaluated when
|
|
35
|
+
* the doc changes) — e.g. `(doc) => doc.getText("content")`.
|
|
36
|
+
*/
|
|
37
|
+
scope: CollabUndoScope;
|
|
38
|
+
/**
|
|
39
|
+
* Origins captured as undoable. Defaults to the hook's own `localOrigin`.
|
|
40
|
+
* Transactions from remote peers ("remote") and the agent ("agent"/
|
|
41
|
+
* "server") are never captured.
|
|
42
|
+
*/
|
|
43
|
+
trackedOrigins?: unknown[];
|
|
44
|
+
/** Coalesce rapid edits into one undo step. Default 500ms. */
|
|
45
|
+
captureTimeout?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface UseCollabUndoResult {
|
|
48
|
+
/** Undo the local user's most recent edit. Returns true if applied. */
|
|
49
|
+
undo: () => boolean;
|
|
50
|
+
/** Redo the local user's most recently undone edit. */
|
|
51
|
+
redo: () => boolean;
|
|
52
|
+
canUndo: boolean;
|
|
53
|
+
canRedo: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Tag local transactions with this origin so they're captured:
|
|
56
|
+
* `ydoc.transact(() => { ... }, localOrigin)` — or use `transactLocal`.
|
|
57
|
+
*/
|
|
58
|
+
localOrigin: unknown;
|
|
59
|
+
/** Run a mutation in a transaction tagged with the local origin. */
|
|
60
|
+
transactLocal: <T>(fn: () => T) => T;
|
|
61
|
+
/** The underlying manager (null while the doc is loading). */
|
|
62
|
+
undoManager: Y.UndoManager | null;
|
|
63
|
+
}
|
|
64
|
+
export declare function useCollabUndo(options: UseCollabUndoOptions): UseCollabUndoResult;
|
|
65
|
+
export interface LocalOpUndoEntry<TOp> {
|
|
66
|
+
/** Granular ops that reverse the mutation. */
|
|
67
|
+
undo: TOp[];
|
|
68
|
+
/** Granular ops that re-apply the mutation. */
|
|
69
|
+
redo: TOp[];
|
|
70
|
+
/** Optional label for UI ("Delete slide 3"). */
|
|
71
|
+
label?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Coalescing key: consecutive pushes with the same non-empty key within
|
|
74
|
+
* `coalesceMs` merge into one entry (keeps the FIRST undo ops and the
|
|
75
|
+
* LATEST redo ops) — e.g. per-keystroke text patches on one field.
|
|
76
|
+
*/
|
|
77
|
+
coalesceKey?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface LocalOpUndoController<TOp> {
|
|
80
|
+
/** Record a local mutation. Clears the redo stack. */
|
|
81
|
+
push(entry: LocalOpUndoEntry<TOp>): void;
|
|
82
|
+
/** Apply the inverse ops of the most recent entry. */
|
|
83
|
+
undo(): Promise<boolean>;
|
|
84
|
+
/** Re-apply the most recently undone entry. */
|
|
85
|
+
redo(): Promise<boolean>;
|
|
86
|
+
canUndo(): boolean;
|
|
87
|
+
canRedo(): boolean;
|
|
88
|
+
clear(): void;
|
|
89
|
+
/** Peek labels for UI (undo tooltip). */
|
|
90
|
+
peekUndoLabel(): string | undefined;
|
|
91
|
+
peekRedoLabel(): string | undefined;
|
|
92
|
+
}
|
|
93
|
+
export interface CreateLocalOpUndoOptions<TOp> {
|
|
94
|
+
/**
|
|
95
|
+
* Apply granular ops through the app's normal mutation path. MUST NOT
|
|
96
|
+
* push back into this controller (re-entrant pushes are ignored).
|
|
97
|
+
*/
|
|
98
|
+
apply: (ops: TOp[], direction: "undo" | "redo", entry: LocalOpUndoEntry<TOp>) => void | Promise<void>;
|
|
99
|
+
/** Max retained entries. Default 200. */
|
|
100
|
+
maxDepth?: number;
|
|
101
|
+
/** Window for coalescing same-key pushes. Default 800ms. */
|
|
102
|
+
coalesceMs?: number;
|
|
103
|
+
/** Called after any stack change (for canUndo/canRedo UI updates). */
|
|
104
|
+
onChange?: () => void;
|
|
105
|
+
/** Clock override for tests. */
|
|
106
|
+
now?: () => number;
|
|
107
|
+
}
|
|
108
|
+
export declare function createLocalOpUndoController<TOp>(options: CreateLocalOpUndoOptions<TOp>): LocalOpUndoController<TOp>;
|
|
109
|
+
export interface UseLocalOpUndoOptions<TOp> extends Omit<CreateLocalOpUndoOptions<TOp>, "onChange">, UndoKeyboardOptions {
|
|
110
|
+
}
|
|
111
|
+
export interface UseLocalOpUndoResult<TOp> {
|
|
112
|
+
push: (entry: LocalOpUndoEntry<TOp>) => void;
|
|
113
|
+
undo: () => Promise<boolean>;
|
|
114
|
+
redo: () => Promise<boolean>;
|
|
115
|
+
canUndo: boolean;
|
|
116
|
+
canRedo: boolean;
|
|
117
|
+
clear: () => void;
|
|
118
|
+
controller: LocalOpUndoController<TOp>;
|
|
119
|
+
}
|
|
120
|
+
export declare function useLocalOpUndo<TOp>(options: UseLocalOpUndoOptions<TOp>): UseLocalOpUndoResult<TOp>;
|
|
121
|
+
//# sourceMappingURL=undo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo.d.ts","sourceRoot":"","sources":["../../src/collab/undo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared per-user undo/redo for collaborative surfaces.
|
|
3
|
+
*
|
|
4
|
+
* Two primitives, one rule: undo NEVER reverts another participant's (human
|
|
5
|
+
* or agent) work, and never restores whole-document snapshots that would
|
|
6
|
+
* clobber concurrent edits.
|
|
7
|
+
*
|
|
8
|
+
* - `useCollabUndo` — Y.UndoManager lifecycle wrapper for Yjs-backed surfaces.
|
|
9
|
+
* Tracks only transactions tagged with the local origin, coalesces rapid
|
|
10
|
+
* edits, and is recreated/destroyed when the document changes (stale
|
|
11
|
+
* managers hold Y.Doc references and grow unboundedly).
|
|
12
|
+
*
|
|
13
|
+
* - `useLocalOpUndo` / `createLocalOpUndoController` — inverse-operation undo
|
|
14
|
+
* for op-based apps (slides decks, forms). Each local mutation registers
|
|
15
|
+
* the granular ops that redo and undo it; Cmd+Z replays the inverse ops
|
|
16
|
+
* through the app's normal granular mutation path, so concurrent edits by
|
|
17
|
+
* other participants to OTHER items are never touched.
|
|
18
|
+
*/
|
|
19
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
20
|
+
import * as Y from "yjs";
|
|
21
|
+
function isEditableTarget(target) {
|
|
22
|
+
const el = target;
|
|
23
|
+
if (!el)
|
|
24
|
+
return false;
|
|
25
|
+
const tag = el.tagName;
|
|
26
|
+
return (tag === "INPUT" ||
|
|
27
|
+
tag === "TEXTAREA" ||
|
|
28
|
+
tag === "SELECT" ||
|
|
29
|
+
!!el.isContentEditable);
|
|
30
|
+
}
|
|
31
|
+
function useUndoKeyboard(undo, redo, options) {
|
|
32
|
+
const enabled = options?.enableKeyboardShortcuts ?? false;
|
|
33
|
+
const ignoreInputs = options?.ignoreInputTargets ?? true;
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!enabled || typeof window === "undefined")
|
|
36
|
+
return;
|
|
37
|
+
function onKeyDown(e) {
|
|
38
|
+
if (!(e.metaKey || e.ctrlKey))
|
|
39
|
+
return;
|
|
40
|
+
if (ignoreInputs && isEditableTarget(e.target))
|
|
41
|
+
return;
|
|
42
|
+
const key = e.key.toLowerCase();
|
|
43
|
+
if (key === "z") {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
if (e.shiftKey)
|
|
46
|
+
redo();
|
|
47
|
+
else
|
|
48
|
+
undo();
|
|
49
|
+
}
|
|
50
|
+
else if (key === "y") {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
redo();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
window.addEventListener("keydown", onKeyDown);
|
|
56
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
57
|
+
}, [enabled, ignoreInputs, undo, redo]);
|
|
58
|
+
}
|
|
59
|
+
export function useCollabUndo(options) {
|
|
60
|
+
const { ydoc, scope, trackedOrigins, captureTimeout = 500 } = options;
|
|
61
|
+
// Stable per-hook local origin (an object identity — never collides).
|
|
62
|
+
const localOrigin = useMemo(() => ({ collabUndoLocalOrigin: true }), []);
|
|
63
|
+
const managerRef = useRef(null);
|
|
64
|
+
const [canUndo, setCanUndo] = useState(false);
|
|
65
|
+
const [canRedo, setCanRedo] = useState(false);
|
|
66
|
+
// Keep latest scope/origins in refs so the effect only re-runs on doc change.
|
|
67
|
+
const scopeRef = useRef(scope);
|
|
68
|
+
scopeRef.current = scope;
|
|
69
|
+
const trackedRef = useRef(trackedOrigins);
|
|
70
|
+
trackedRef.current = trackedOrigins;
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!ydoc) {
|
|
73
|
+
managerRef.current = null;
|
|
74
|
+
setCanUndo(false);
|
|
75
|
+
setCanRedo(false);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const rawScope = scopeRef.current;
|
|
79
|
+
const resolved = typeof rawScope === "function" ? rawScope(ydoc) : rawScope;
|
|
80
|
+
const scopes = Array.isArray(resolved) ? resolved : [resolved];
|
|
81
|
+
const origins = new Set(trackedRef.current ?? [localOrigin]);
|
|
82
|
+
const manager = new Y.UndoManager(scopes, {
|
|
83
|
+
trackedOrigins: origins,
|
|
84
|
+
captureTimeout,
|
|
85
|
+
});
|
|
86
|
+
// The manager applies undo/redo transactions with itself as origin;
|
|
87
|
+
// track it so redo of an undone step is capturable.
|
|
88
|
+
origins.add(manager);
|
|
89
|
+
managerRef.current = manager;
|
|
90
|
+
function refresh() {
|
|
91
|
+
setCanUndo(manager.undoStack.length > 0);
|
|
92
|
+
setCanRedo(manager.redoStack.length > 0);
|
|
93
|
+
}
|
|
94
|
+
refresh();
|
|
95
|
+
manager.on("stack-item-added", refresh);
|
|
96
|
+
manager.on("stack-item-popped", refresh);
|
|
97
|
+
manager.on("stack-cleared", refresh);
|
|
98
|
+
return () => {
|
|
99
|
+
manager.off("stack-item-added", refresh);
|
|
100
|
+
manager.off("stack-item-popped", refresh);
|
|
101
|
+
manager.off("stack-cleared", refresh);
|
|
102
|
+
manager.destroy();
|
|
103
|
+
if (managerRef.current === manager) {
|
|
104
|
+
managerRef.current = null;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}, [ydoc, captureTimeout, localOrigin]);
|
|
108
|
+
const undo = useCallback(() => {
|
|
109
|
+
const m = managerRef.current;
|
|
110
|
+
if (!m || m.undoStack.length === 0)
|
|
111
|
+
return false;
|
|
112
|
+
m.undo();
|
|
113
|
+
return true;
|
|
114
|
+
}, []);
|
|
115
|
+
const redo = useCallback(() => {
|
|
116
|
+
const m = managerRef.current;
|
|
117
|
+
if (!m || m.redoStack.length === 0)
|
|
118
|
+
return false;
|
|
119
|
+
m.redo();
|
|
120
|
+
return true;
|
|
121
|
+
}, []);
|
|
122
|
+
const transactLocal = useCallback((fn) => {
|
|
123
|
+
if (!ydoc)
|
|
124
|
+
return fn();
|
|
125
|
+
let result;
|
|
126
|
+
ydoc.transact(() => {
|
|
127
|
+
result = fn();
|
|
128
|
+
}, localOrigin);
|
|
129
|
+
return result;
|
|
130
|
+
}, [ydoc, localOrigin]);
|
|
131
|
+
useUndoKeyboard(undo, redo, options);
|
|
132
|
+
return {
|
|
133
|
+
undo,
|
|
134
|
+
redo,
|
|
135
|
+
canUndo,
|
|
136
|
+
canRedo,
|
|
137
|
+
localOrigin,
|
|
138
|
+
transactLocal,
|
|
139
|
+
undoManager: managerRef.current,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export function createLocalOpUndoController(options) {
|
|
143
|
+
const { apply, maxDepth = 200, coalesceMs = 800, onChange, now = () => Date.now(), } = options;
|
|
144
|
+
const undoStack = [];
|
|
145
|
+
const redoStack = [];
|
|
146
|
+
let applying = false;
|
|
147
|
+
function notify() {
|
|
148
|
+
onChange?.();
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
push(entry) {
|
|
152
|
+
// Ignore pushes triggered by our own undo/redo application.
|
|
153
|
+
if (applying)
|
|
154
|
+
return;
|
|
155
|
+
const at = now();
|
|
156
|
+
const top = undoStack[undoStack.length - 1];
|
|
157
|
+
if (top &&
|
|
158
|
+
entry.coalesceKey &&
|
|
159
|
+
top.coalesceKey === entry.coalesceKey &&
|
|
160
|
+
at - top.at <= coalesceMs) {
|
|
161
|
+
// Merge: first undo wins (restores the pre-burst state), latest redo
|
|
162
|
+
// wins (re-applies the final state).
|
|
163
|
+
top.redo = entry.redo;
|
|
164
|
+
top.at = at;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
undoStack.push({ ...entry, at });
|
|
168
|
+
if (undoStack.length > maxDepth) {
|
|
169
|
+
undoStack.splice(0, undoStack.length - maxDepth);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
redoStack.length = 0;
|
|
173
|
+
notify();
|
|
174
|
+
},
|
|
175
|
+
async undo() {
|
|
176
|
+
const entry = undoStack.pop();
|
|
177
|
+
if (!entry)
|
|
178
|
+
return false;
|
|
179
|
+
redoStack.push(entry);
|
|
180
|
+
notify();
|
|
181
|
+
applying = true;
|
|
182
|
+
try {
|
|
183
|
+
await apply(entry.undo, "undo", entry);
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
applying = false;
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
},
|
|
190
|
+
async redo() {
|
|
191
|
+
const entry = redoStack.pop();
|
|
192
|
+
if (!entry)
|
|
193
|
+
return false;
|
|
194
|
+
undoStack.push(entry);
|
|
195
|
+
notify();
|
|
196
|
+
applying = true;
|
|
197
|
+
try {
|
|
198
|
+
await apply(entry.redo, "redo", entry);
|
|
199
|
+
}
|
|
200
|
+
finally {
|
|
201
|
+
applying = false;
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
},
|
|
205
|
+
canUndo: () => undoStack.length > 0,
|
|
206
|
+
canRedo: () => redoStack.length > 0,
|
|
207
|
+
clear() {
|
|
208
|
+
undoStack.length = 0;
|
|
209
|
+
redoStack.length = 0;
|
|
210
|
+
notify();
|
|
211
|
+
},
|
|
212
|
+
peekUndoLabel: () => undoStack[undoStack.length - 1]?.label,
|
|
213
|
+
peekRedoLabel: () => redoStack[redoStack.length - 1]?.label,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
export function useLocalOpUndo(options) {
|
|
217
|
+
const [, setTick] = useState(0);
|
|
218
|
+
const applyRef = useRef(options.apply);
|
|
219
|
+
applyRef.current = options.apply;
|
|
220
|
+
const controller = useMemo(() => createLocalOpUndoController({
|
|
221
|
+
apply: (ops, direction, entry) => applyRef.current(ops, direction, entry),
|
|
222
|
+
maxDepth: options.maxDepth,
|
|
223
|
+
coalesceMs: options.coalesceMs,
|
|
224
|
+
now: options.now,
|
|
225
|
+
onChange: () => setTick((n) => n + 1),
|
|
226
|
+
}),
|
|
227
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
228
|
+
[]);
|
|
229
|
+
const undo = useCallback(() => controller.undo(), [controller]);
|
|
230
|
+
const redo = useCallback(() => controller.redo(), [controller]);
|
|
231
|
+
const push = useCallback((entry) => controller.push(entry), [controller]);
|
|
232
|
+
const clear = useCallback(() => controller.clear(), [controller]);
|
|
233
|
+
useUndoKeyboard(() => void controller.undo(), () => void controller.redo(), options);
|
|
234
|
+
return {
|
|
235
|
+
push,
|
|
236
|
+
undo,
|
|
237
|
+
redo,
|
|
238
|
+
canUndo: controller.canUndo(),
|
|
239
|
+
canRedo: controller.canRedo(),
|
|
240
|
+
clear,
|
|
241
|
+
controller,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=undo.js.map
|