@agent-native/core 0.80.2 → 0.80.5
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 +66 -2
- package/corpus/core/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +1 -1
- package/corpus/core/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +1 -1
- package/corpus/core/docs/content/real-time-collaboration.mdx +2 -2
- package/corpus/core/docs/content/template-design.mdx +1 -1
- package/corpus/core/package.json +3 -7
- package/corpus/core/src/action.ts +32 -0
- package/corpus/core/src/agent/durable-background.ts +32 -11
- package/corpus/core/src/agent/production-agent.ts +14 -1
- package/corpus/core/src/agent/run-loop-with-resume.ts +3 -1
- package/corpus/core/src/brand-kit/fig/index.ts +17 -37
- package/corpus/core/src/cli/index.ts +1 -1
- package/corpus/core/src/cli/mcp-config-writers.ts +187 -51
- package/corpus/core/src/cli/plan-local.ts +445 -108
- package/corpus/core/src/cli/skills.ts +32 -8
- package/corpus/core/src/client/AssistantChat.tsx +11 -1
- package/corpus/core/src/client/agent-chat.ts +12 -1
- package/corpus/core/src/client/composer/PromptComposer.tsx +100 -41
- package/corpus/core/src/client/org/OrgSwitcher.tsx +1 -1
- package/corpus/core/src/client/sharing/ShareButton.tsx +3 -27
- package/corpus/core/src/collab/presence.ts +1 -1
- package/corpus/core/src/mcp/connect-route.ts +34 -5
- package/corpus/core/src/server/action-discovery.ts +4 -0
- package/corpus/core/src/server/action-routes.ts +14 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +20 -0
- package/corpus/core/src/vite/client.ts +15 -1
- package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +2 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +8 -0
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +117 -33
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +4 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +7 -0
- package/corpus/templates/analytics/changelog/2026-06-27-dashboards-can-now-nest-under-a-parent-in-the-sidebar-via-a-.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-29-analytics-pages-now-sit-closer-under-the-header-with-tighter.md +6 -0
- package/corpus/templates/assets/actions/generate-image-batch.ts +3 -0
- package/corpus/templates/assets/actions/generate-image.ts +3 -0
- package/corpus/templates/assets/changelog/2026-06-29-longer-agent-generation-window.md +6 -0
- package/corpus/templates/assets/netlify.toml +3 -3
- package/corpus/templates/assets/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/clips/app/components/capture-install-options.tsx +7 -8
- package/corpus/templates/clips/app/components/player/timestamped-comment-button.tsx +162 -0
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +1 -1
- package/corpus/templates/clips/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +4 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/clips/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +42 -18
- package/corpus/templates/content/AGENTS.md +12 -0
- package/corpus/templates/content/app/blocks/BuilderDocsBlocks.tsx +10 -0
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +1 -0
- package/corpus/templates/content/app/components/editor/ContentReferencePreview.tsx +185 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +3 -0
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +19 -0
- package/corpus/templates/content/app/components/editor/extensions/ContentReferenceNode.tsx +82 -0
- package/corpus/templates/content/app/global.css +9 -0
- package/corpus/templates/content/app/i18n/zh-TW.ts +12 -0
- package/corpus/templates/content/app/i18n-data.ts +140 -0
- package/corpus/templates/content/changelog/2026-06-29-reusable-mdx-references-now-preview-linked-local-documents-i.md +6 -0
- package/corpus/templates/content/shared/builder-docs-blocks.ts +8 -0
- package/corpus/templates/content/shared/builder-mdx.ts +141 -4
- package/corpus/templates/content/shared/nfm.ts +62 -0
- package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +10 -11
- package/corpus/templates/design/AGENTS.md +5 -0
- package/corpus/templates/design/_gitignore +7 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +22 -12
- package/corpus/templates/design/actions/create-design-system.ts +15 -4
- package/corpus/templates/design/actions/create-file.ts +20 -1
- package/corpus/templates/design/actions/delete-design-system.ts +2 -2
- package/corpus/templates/design/actions/duplicate-design.ts +35 -9
- package/corpus/templates/design/actions/generate-design.ts +146 -69
- package/corpus/templates/design/actions/generate-screens.ts +51 -19
- package/corpus/templates/design/actions/get-design-snapshot.ts +5 -1
- package/corpus/templates/design/actions/get-design.ts +2 -0
- package/corpus/templates/design/actions/import-design-project.ts +28 -9
- package/corpus/templates/design/actions/import-document.ts +22 -8
- package/corpus/templates/design/actions/index-design-system-with-builder.ts +6 -153
- package/corpus/templates/design/actions/navigate.ts +105 -54
- package/corpus/templates/design/actions/set-default-design-system.ts +17 -3
- package/corpus/templates/design/actions/show-design-questions.ts +2 -0
- package/corpus/templates/design/actions/update-design.ts +2 -1
- package/corpus/templates/design/actions/view-screen.ts +12 -6
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +4 -4
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +159 -41
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +8 -4
- package/corpus/templates/design/app/components/design/DrawOverlay.tsx +37 -42
- package/corpus/templates/design/app/components/design/EditPanel.tsx +336 -183
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +153 -34
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +135 -33
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +6 -0
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +4 -10
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +84 -43
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +4 -4
- package/corpus/templates/design/app/components/design/inspector/{FigmaColorPicker.tsx → DesignColorPicker.tsx} +89 -62
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +14 -26
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +40 -12
- package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +13 -13
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +13 -9
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +13 -4
- package/corpus/templates/design/app/components/design/inspector/ShaderFillsPanel.tsx +6 -6
- package/corpus/templates/design/app/components/design/inspector/{figma-icons.tsx → design-icons.tsx} +2 -2
- package/corpus/templates/design/app/components/design/inspector/index.ts +12 -12
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +5 -2
- package/corpus/templates/design/app/components/editor/PromptDialog.tsx +3 -3
- package/corpus/templates/design/app/components/layout/Layout.tsx +5 -2
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +167 -91
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +16 -3
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +15 -0
- package/corpus/templates/design/app/global.css +4 -0
- package/corpus/templates/design/app/hooks/use-design-system.ts +4 -1
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +38 -3
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +9 -2
- package/corpus/templates/design/app/i18n/zh-TW.ts +22 -0
- package/corpus/templates/design/app/i18n-data.ts +527 -0
- package/corpus/templates/design/app/lib/design-systems.ts +6 -4
- package/corpus/templates/design/app/lib/design-templates.ts +15 -3
- package/corpus/templates/design/app/pages/DesignEditor.tsx +641 -158
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +42 -34
- package/corpus/templates/design/app/pages/VisualEdit.tsx +100 -0
- package/corpus/templates/design/app/root.tsx +42 -9
- package/corpus/templates/design/app/routes/visual-edit.tsx +7 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +1 -1
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +1 -1
- package/corpus/templates/design/changelog/2026-06-28-visual-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-generation-prompts-now-show-connect-ai-before-sending.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-mode-top-chrome-now-groups-collaborators-preview-shar.md +1 -1
- package/corpus/templates/design/changelog/2026-06-29-fixed-design-editor-exports-and-gradient-edits-so-multi-scre.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-png-export-handles-modern-css-color-functions-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-png-export-now-ignores-duplicate-clicks-while-a-download-is-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-public-visual-edit-and-shared-design-links-now-invite-visito.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-actions-now-reject-missing-design-targets-before.md +6 -0
- package/corpus/templates/design/e2e/README.md +71 -0
- package/corpus/templates/design/e2e/global-setup.ts +157 -0
- package/corpus/templates/design/e2e/helpers.ts +148 -0
- package/corpus/templates/design/netlify.toml +3 -4
- package/corpus/templates/design/package.json +5 -1
- package/corpus/templates/design/playwright.config.ts +51 -0
- package/corpus/templates/design/server/handlers/index-design-system-with-builder.ts +121 -0
- package/corpus/templates/design/server/handlers/uploads.ts +89 -38
- package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +181 -0
- package/corpus/templates/design/server/lib/coding-handoff.ts +33 -4
- package/corpus/templates/design/server/lib/design-export.ts +35 -8
- package/corpus/templates/design/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/design/server/plugins/auth.ts +10 -1
- package/corpus/templates/design/server/routes/api/index-design-system-with-builder.post.ts +1 -0
- package/corpus/templates/design/shared/api.ts +2 -0
- package/corpus/templates/design/shared/apply-edits.ts +12 -8
- package/corpus/templates/design/shared/canvas-math.ts +19 -1
- package/corpus/templates/design/shared/code-layer.ts +87 -28
- package/corpus/templates/design/shared/generation-session.ts +1 -0
- package/corpus/templates/design/shared/resolve-tweaks.ts +4 -3
- package/corpus/templates/design/shared/shader-presets.ts +10 -0
- package/corpus/templates/design/shared/source-mode.ts +9 -0
- package/corpus/templates/design/vitest.config.ts +2 -1
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +1 -1
- package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +1 -1
- package/corpus/templates/plan/.agents/skills/visual-plan/references/local-files.md +14 -5
- package/corpus/templates/plan/.agents/skills/visual-recap/references/local-files.md +14 -5
- package/corpus/templates/plan/AGENTS.md +1 -1
- package/corpus/templates/plan/actions/create-plan-design.ts +1 -1
- package/corpus/templates/plan/actions/validate-local-plan-source.ts +110 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -0
- package/corpus/templates/plan/docs/commenting-ux-plan.md +2 -2
- package/corpus/templates/plan/server/lib/plan-connector-catalog.ts +1 -0
- package/corpus/templates/plan/server/lib/public-action-paths.ts +1 -0
- package/corpus/templates/plan/server/plan-content.ts +1 -1
- package/corpus/templates/plan/server/ui-plan-html.ts +2 -2
- package/corpus/templates/slides/actions/index-design-system-with-builder.ts +6 -153
- package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +53 -38
- package/corpus/templates/slides/app/components/design-system/{fig-import-response.ts → builder-index-response.ts} +9 -6
- package/corpus/templates/slides/app/components/visual-editor/MultiSelectChip.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-06-29-design-system-setup-now-indexes-uploaded-design-files-throug.md +6 -0
- package/corpus/templates/slides/changelog/2026-06-29-longer-hosted-agent-turns.md +6 -0
- package/corpus/templates/slides/netlify.toml +3 -6
- package/corpus/templates/slides/server/handlers/index-design-system-with-builder.ts +116 -0
- package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +179 -0
- package/corpus/templates/slides/server/plugins/agent-chat.ts +4 -1
- package/corpus/templates/slides/server/routes/api/index-design-system-with-builder.post.ts +1 -0
- package/dist/action.d.ts +23 -0
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +9 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/durable-background.d.ts +9 -7
- package/dist/agent/durable-background.d.ts.map +1 -1
- package/dist/agent/durable-background.js +27 -11
- package/dist/agent/durable-background.js.map +1 -1
- package/dist/agent/production-agent.d.ts +10 -0
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -1
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts +2 -1
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +2 -2
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/brand-kit/fig/index.d.ts +4 -4
- package/dist/brand-kit/fig/index.d.ts.map +1 -1
- package/dist/brand-kit/fig/index.js +14 -27
- package/dist/brand-kit/fig/index.js.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-config-writers.d.ts +15 -7
- package/dist/cli/mcp-config-writers.d.ts.map +1 -1
- package/dist/cli/mcp-config-writers.js +198 -45
- package/dist/cli/mcp-config-writers.js.map +1 -1
- package/dist/cli/plan-local.d.ts +30 -0
- package/dist/cli/plan-local.d.ts.map +1 -1
- package/dist/cli/plan-local.js +281 -56
- package/dist/cli/plan-local.js.map +1 -1
- package/dist/cli/skills.d.ts +2 -2
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +32 -8
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +11 -1
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +15 -2
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/composer/PromptComposer.d.ts.map +1 -1
- package/dist/client/composer/PromptComposer.js +35 -1
- package/dist/client/composer/PromptComposer.js.map +1 -1
- package/dist/client/org/OrgSwitcher.js +1 -1
- package/dist/client/org/OrgSwitcher.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +1 -1
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +2 -15
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/collab/presence.d.ts +1 -1
- package/dist/collab/presence.js +1 -1
- package/dist/collab/presence.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/mcp/connect-route.d.ts.map +1 -1
- package/dist/mcp/connect-route.js +34 -5
- package/dist/mcp/connect-route.js.map +1 -1
- package/dist/observability/routes.d.ts +2 -2
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +5 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/action-routes.d.ts.map +1 -1
- package/dist/server/action-routes.js +14 -0
- package/dist/server/action-routes.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts +6 -0
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +12 -3
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +12 -1
- package/dist/vite/client.js.map +1 -1
- package/docs/content/locales/ar-SA/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ar-SA/template-design.mdx +1 -1
- package/docs/content/locales/de-DE/real-time-collaboration.mdx +3 -3
- package/docs/content/locales/de-DE/template-design.mdx +1 -1
- package/docs/content/locales/es-ES/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/es-ES/template-design.mdx +1 -1
- package/docs/content/locales/fr-FR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/fr-FR/template-design.mdx +1 -1
- package/docs/content/locales/hi-IN/template-design.mdx +1 -1
- package/docs/content/locales/ja-JP/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ja-JP/template-design.mdx +1 -1
- package/docs/content/locales/ko-KR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/ko-KR/template-design.mdx +1 -1
- package/docs/content/locales/pt-BR/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/pt-BR/template-design.mdx +1 -1
- package/docs/content/locales/zh-CN/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/zh-CN/template-design.mdx +1 -1
- package/docs/content/locales/zh-TW/real-time-collaboration.mdx +2 -2
- package/docs/content/locales/zh-TW/template-design.mdx +1 -1
- package/docs/content/real-time-collaboration.mdx +2 -2
- package/docs/content/template-design.mdx +1 -1
- package/package.json +3 -7
- package/corpus/core/src/brand-kit/fig/decode.ts +0 -410
- package/corpus/core/src/brand-kit/fig/extract-design-system.ts +0 -947
- package/corpus/core/src/brand-kit/fig/fig-to-html.ts +0 -1906
- package/corpus/templates/design/actions/import-figma.ts +0 -55
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +0 -6
- package/corpus/templates/design/server/handlers/import-figma-system.ts +0 -86
- package/corpus/templates/design/server/routes/api/import-figma-system.post.ts +0 -1
- package/corpus/templates/slides/server/handlers/import-figma-system.ts +0 -101
- package/corpus/templates/slides/server/routes/api/import-figma-system.post.ts +0 -1
- package/dist/brand-kit/fig/decode.d.ts +0 -33
- package/dist/brand-kit/fig/decode.d.ts.map +0 -1
- package/dist/brand-kit/fig/decode.js +0 -358
- package/dist/brand-kit/fig/decode.js.map +0 -1
- package/dist/brand-kit/fig/extract-design-system.d.ts +0 -44
- package/dist/brand-kit/fig/extract-design-system.d.ts.map +0 -1
- package/dist/brand-kit/fig/extract-design-system.js +0 -752
- package/dist/brand-kit/fig/extract-design-system.js.map +0 -1
- package/dist/brand-kit/fig/fig-to-html.d.ts +0 -246
- package/dist/brand-kit/fig/fig-to-html.d.ts.map +0 -1
- package/dist/brand-kit/fig/fig-to-html.js +0 -1506
- package/dist/brand-kit/fig/fig-to-html.js.map +0 -1
|
@@ -30,7 +30,14 @@ import {
|
|
|
30
30
|
type QueryKey,
|
|
31
31
|
} from "@tanstack/react-query";
|
|
32
32
|
import { useTheme } from "next-themes";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
useState,
|
|
35
|
+
useEffect,
|
|
36
|
+
useCallback,
|
|
37
|
+
useRef,
|
|
38
|
+
useMemo,
|
|
39
|
+
Fragment,
|
|
40
|
+
} from "react";
|
|
34
41
|
import { Link, useLocation, useNavigate } from "react-router";
|
|
35
42
|
import { toast } from "sonner";
|
|
36
43
|
|
|
@@ -51,6 +58,8 @@ type SidebarDashboard = {
|
|
|
51
58
|
subviews?: DashboardSubview[];
|
|
52
59
|
source: "static" | "sql";
|
|
53
60
|
visibility?: Visibility;
|
|
61
|
+
/** Id of the dashboard this one nests under in the sidebar, if any. */
|
|
62
|
+
parentId?: string;
|
|
54
63
|
};
|
|
55
64
|
import {
|
|
56
65
|
DevDatabaseLink,
|
|
@@ -1026,6 +1035,7 @@ type SqlDashboardListItem = {
|
|
|
1026
1035
|
id: string;
|
|
1027
1036
|
name: string;
|
|
1028
1037
|
visibility?: Visibility;
|
|
1038
|
+
parentId?: string;
|
|
1029
1039
|
};
|
|
1030
1040
|
|
|
1031
1041
|
async function fetchSqlDashboards(
|
|
@@ -1045,6 +1055,10 @@ async function fetchSqlDashboards(
|
|
|
1045
1055
|
d.visibility === "org" || d.visibility === "public"
|
|
1046
1056
|
? (d.visibility as Visibility)
|
|
1047
1057
|
: ("private" as Visibility),
|
|
1058
|
+
parentId:
|
|
1059
|
+
typeof d.parentId === "string" && d.parentId.trim().length > 0
|
|
1060
|
+
? d.parentId
|
|
1061
|
+
: undefined,
|
|
1048
1062
|
}));
|
|
1049
1063
|
} catch {
|
|
1050
1064
|
return [];
|
|
@@ -1445,6 +1459,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1445
1459
|
name: d.name,
|
|
1446
1460
|
source: "sql",
|
|
1447
1461
|
visibility: d.visibility,
|
|
1462
|
+
parentId: d.parentId,
|
|
1448
1463
|
}));
|
|
1449
1464
|
const all = [...staticItems, ...sqlItems];
|
|
1450
1465
|
if (dashboardSortMode === "alphabetical") {
|
|
@@ -1482,12 +1497,54 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1482
1497
|
[visibleDashboards, dashFilter],
|
|
1483
1498
|
);
|
|
1484
1499
|
|
|
1500
|
+
// Group dashboards that declare a parentId beneath their parent. Nesting is
|
|
1501
|
+
// intentionally one level deep: a dashboard only nests when its parent is
|
|
1502
|
+
// itself top-level. Orphans (parent missing/filtered out), self-references,
|
|
1503
|
+
// cycles, and deeper descendants all fall back to top level so nothing is
|
|
1504
|
+
// ever hidden.
|
|
1505
|
+
const dashboardChildren = useMemo<Map<string, SidebarDashboard[]>>(() => {
|
|
1506
|
+
const byId = new Map(filteredDashboards.map((d) => [d.id, d]));
|
|
1507
|
+
const hasValidParent = (d: SidebarDashboard) =>
|
|
1508
|
+
!!d.parentId && d.parentId !== d.id && byId.has(d.parentId);
|
|
1509
|
+
const byParent = new Map<string, SidebarDashboard[]>();
|
|
1510
|
+
for (const d of filteredDashboards) {
|
|
1511
|
+
if (!hasValidParent(d)) continue;
|
|
1512
|
+
const parent = byId.get(d.parentId as string);
|
|
1513
|
+
if (!parent || hasValidParent(parent)) continue;
|
|
1514
|
+
const arr = byParent.get(d.parentId as string) ?? [];
|
|
1515
|
+
arr.push(d);
|
|
1516
|
+
byParent.set(d.parentId as string, arr);
|
|
1517
|
+
}
|
|
1518
|
+
return byParent;
|
|
1519
|
+
}, [filteredDashboards]);
|
|
1520
|
+
|
|
1521
|
+
const topLevelDashboards = useMemo(() => {
|
|
1522
|
+
const childIds = new Set<string>();
|
|
1523
|
+
for (const arr of dashboardChildren.values())
|
|
1524
|
+
for (const c of arr) childIds.add(c.id);
|
|
1525
|
+
return filteredDashboards.filter((d) => !childIds.has(d.id));
|
|
1526
|
+
}, [filteredDashboards, dashboardChildren]);
|
|
1527
|
+
|
|
1485
1528
|
const displayedDashboards = useMemo(
|
|
1486
1529
|
() =>
|
|
1487
1530
|
dashShowAll
|
|
1488
|
-
?
|
|
1489
|
-
:
|
|
1490
|
-
[
|
|
1531
|
+
? topLevelDashboards
|
|
1532
|
+
: topLevelDashboards.slice(0, SIDEBAR_PREVIEW_COUNT),
|
|
1533
|
+
[topLevelDashboards, dashShowAll],
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
// The flattened id order exactly as rendered (each parent immediately
|
|
1537
|
+
// followed by its nested children). Drag reordering must use this so the
|
|
1538
|
+
// arrayMove indices match what the user sees; the raw `visibleDashboards`
|
|
1539
|
+
// order interleaves children at their sorted positions and would move the
|
|
1540
|
+
// wrong rows once a dashboard is nested.
|
|
1541
|
+
const dashboardRenderOrderIds = useMemo(
|
|
1542
|
+
() =>
|
|
1543
|
+
topLevelDashboards.flatMap((d) => [
|
|
1544
|
+
d.id,
|
|
1545
|
+
...(dashboardChildren.get(d.id) ?? []).map((c) => c.id),
|
|
1546
|
+
]),
|
|
1547
|
+
[topLevelDashboards, dashboardChildren],
|
|
1491
1548
|
);
|
|
1492
1549
|
|
|
1493
1550
|
const handleDashboardDelete = useCallback(
|
|
@@ -1801,18 +1858,16 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
1801
1858
|
(event: DragEndEvent) => {
|
|
1802
1859
|
const { active, over } = event;
|
|
1803
1860
|
if (!over || active.id === over.id) return;
|
|
1861
|
+
const ids = dashboardRenderOrderIds;
|
|
1862
|
+
const oldIndex = ids.indexOf(active.id as string);
|
|
1863
|
+
const newIndex = ids.indexOf(over.id as string);
|
|
1864
|
+
if (oldIndex === -1 || newIndex === -1) return;
|
|
1804
1865
|
setDashboardSortMode("manual");
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
const newIndex = ids.indexOf(over.id as string);
|
|
1809
|
-
if (oldIndex === -1 || newIndex === -1) return prev;
|
|
1810
|
-
const newOrder = arrayMove(ids, oldIndex, newIndex);
|
|
1811
|
-
setDashboardOrder(newOrder);
|
|
1812
|
-
return newOrder;
|
|
1813
|
-
});
|
|
1866
|
+
const newOrder = arrayMove(ids, oldIndex, newIndex);
|
|
1867
|
+
setDashboardOrder(newOrder);
|
|
1868
|
+
setDashboardOrderState(newOrder);
|
|
1814
1869
|
},
|
|
1815
|
-
[setDashboardSortMode,
|
|
1870
|
+
[setDashboardSortMode, dashboardRenderOrderIds],
|
|
1816
1871
|
);
|
|
1817
1872
|
|
|
1818
1873
|
const handleAnalysisDragEnd = useCallback(
|
|
@@ -2169,27 +2224,56 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2169
2224
|
onDragEnd={handleDashboardDragEnd}
|
|
2170
2225
|
>
|
|
2171
2226
|
<SortableContext
|
|
2172
|
-
items={displayedDashboards.
|
|
2227
|
+
items={displayedDashboards.flatMap((d) => [
|
|
2228
|
+
d.id,
|
|
2229
|
+
...(dashboardChildren.get(d.id) ?? []).map((c) => c.id),
|
|
2230
|
+
])}
|
|
2173
2231
|
strategy={verticalListSortingStrategy}
|
|
2174
2232
|
>
|
|
2175
2233
|
<div className="ms-4 min-w-0 space-y-0.5">
|
|
2176
|
-
{displayedDashboards.map((d) =>
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2234
|
+
{displayedDashboards.map((d) => {
|
|
2235
|
+
const children = dashboardChildren.get(d.id) ?? [];
|
|
2236
|
+
return (
|
|
2237
|
+
<Fragment key={d.id}>
|
|
2238
|
+
<SortableDashboardItem
|
|
2239
|
+
d={d}
|
|
2240
|
+
isActive={activeDashboardId === d.id}
|
|
2241
|
+
location={location}
|
|
2242
|
+
favoriteIds={favoriteIds}
|
|
2243
|
+
onToggleFavorite={toggleFavorite}
|
|
2244
|
+
onDelete={handleDashboardDelete}
|
|
2245
|
+
onRename={handleDashboardRename}
|
|
2246
|
+
onArchive={handleDashboardArchive}
|
|
2247
|
+
onSetVisibility={handleDashboardSetVisibility}
|
|
2248
|
+
onPrefetch={prefetchDashboard}
|
|
2249
|
+
views={allViewsMap[d.id]}
|
|
2250
|
+
/>
|
|
2251
|
+
{children.length > 0 && (
|
|
2252
|
+
<div className="ms-3 space-y-0.5 border-s border-sidebar-border/60 ps-1">
|
|
2253
|
+
{children.map((child) => (
|
|
2254
|
+
<SortableDashboardItem
|
|
2255
|
+
key={child.id}
|
|
2256
|
+
d={child}
|
|
2257
|
+
isActive={activeDashboardId === child.id}
|
|
2258
|
+
location={location}
|
|
2259
|
+
favoriteIds={favoriteIds}
|
|
2260
|
+
onToggleFavorite={toggleFavorite}
|
|
2261
|
+
onDelete={handleDashboardDelete}
|
|
2262
|
+
onRename={handleDashboardRename}
|
|
2263
|
+
onArchive={handleDashboardArchive}
|
|
2264
|
+
onSetVisibility={
|
|
2265
|
+
handleDashboardSetVisibility
|
|
2266
|
+
}
|
|
2267
|
+
onPrefetch={prefetchDashboard}
|
|
2268
|
+
views={allViewsMap[child.id]}
|
|
2269
|
+
/>
|
|
2270
|
+
))}
|
|
2271
|
+
</div>
|
|
2272
|
+
)}
|
|
2273
|
+
</Fragment>
|
|
2274
|
+
);
|
|
2275
|
+
})}
|
|
2276
|
+
{topLevelDashboards.length > SIDEBAR_PREVIEW_COUNT && (
|
|
2193
2277
|
<button
|
|
2194
2278
|
onClick={() => setDashShowAll(!dashShowAll)}
|
|
2195
2279
|
className="flex items-center gap-1 px-3 py-1 text-[11px] text-muted-foreground/70 hover:text-primary"
|
|
@@ -2198,7 +2282,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2198
2282
|
? t("sidebar.showLess")
|
|
2199
2283
|
: t("sidebar.showMore", {
|
|
2200
2284
|
count:
|
|
2201
|
-
|
|
2285
|
+
topLevelDashboards.length -
|
|
2202
2286
|
SIDEBAR_PREVIEW_COUNT,
|
|
2203
2287
|
})}
|
|
2204
2288
|
</button>
|
|
@@ -379,6 +379,10 @@ async function fetchDashboard(id: string): Promise<FetchedDashboard | null> {
|
|
|
379
379
|
config: {
|
|
380
380
|
name: data.name ?? "Untitled Dashboard",
|
|
381
381
|
description: data.description,
|
|
382
|
+
parentId:
|
|
383
|
+
typeof data.parentId === "string" && data.parentId.trim().length > 0
|
|
384
|
+
? data.parentId
|
|
385
|
+
: undefined,
|
|
382
386
|
catalog: parseDashboardCatalogMetadata(data.catalog),
|
|
383
387
|
demo: parseDashboardDemoMetadata(data.demo),
|
|
384
388
|
filters: data.filters,
|
|
@@ -114,6 +114,13 @@ export interface SqlPanel {
|
|
|
114
114
|
export interface SqlDashboardConfig {
|
|
115
115
|
name: string;
|
|
116
116
|
description?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Optional id of another dashboard this one nests under. When set, the
|
|
119
|
+
* sidebar renders this dashboard indented beneath its parent instead of at
|
|
120
|
+
* the top level. Orphans (parent missing/inaccessible) fall back to the top
|
|
121
|
+
* level. Self-references and cycles are ignored by the renderer.
|
|
122
|
+
*/
|
|
123
|
+
parentId?: string;
|
|
117
124
|
catalog?: {
|
|
118
125
|
templateId?: string;
|
|
119
126
|
templateVersion?: string;
|
|
@@ -22,6 +22,8 @@ import { readImageModelDefault } from "./_image-model-default.js";
|
|
|
22
22
|
import generateImage from "./generate-image.js";
|
|
23
23
|
import { upsertVariantSlot } from "./variant-slots.js";
|
|
24
24
|
|
|
25
|
+
const IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12 * 60_000;
|
|
26
|
+
|
|
25
27
|
export default defineAction({
|
|
26
28
|
description:
|
|
27
29
|
"Generate several brand-consistent images in parallel from one brand kit/library. Use @brand-kit mentions as libraryId and @preset mentions as presetId when present. This is synchronous for images: one call waits for every slot and returns final image artifacts. Use this for slide decks, landing pages, and multi-slot design work. Do not call get-generation-run or refresh-generation-run after a normal image batch result.",
|
|
@@ -74,6 +76,7 @@ export default defineAction({
|
|
|
74
76
|
),
|
|
75
77
|
}),
|
|
76
78
|
parallelSafe: true,
|
|
79
|
+
timeoutMs: IMAGE_GENERATION_TOOL_TIMEOUT_MS,
|
|
77
80
|
run: async ({ slots, ...inputBase }, context?: ActionRunContext) => {
|
|
78
81
|
const imageModelDefault = await readImageModelDefault();
|
|
79
82
|
const libraryId = inputBase.libraryId;
|
|
@@ -46,6 +46,8 @@ import {
|
|
|
46
46
|
import { readImageModelDefault } from "./_image-model-default.js";
|
|
47
47
|
import { upsertVariantSlot, wasVariantSlotDismissed } from "./variant-slots.js";
|
|
48
48
|
|
|
49
|
+
const IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12 * 60_000;
|
|
50
|
+
|
|
49
51
|
function resolveModelForTier(
|
|
50
52
|
tier: ImageQualityTier | undefined,
|
|
51
53
|
category: ImageCategory | undefined,
|
|
@@ -125,6 +127,7 @@ export default defineAction({
|
|
|
125
127
|
),
|
|
126
128
|
}),
|
|
127
129
|
parallelSafe: true,
|
|
130
|
+
timeoutMs: IMAGE_GENERATION_TOOL_TIMEOUT_MS,
|
|
128
131
|
run: async (input, context?: ActionRunContext) => {
|
|
129
132
|
const imageModelDefault = await readImageModelDefault();
|
|
130
133
|
const libraryId = input.libraryId;
|
|
@@ -8,9 +8,9 @@ functions = "templates/assets/.netlify/functions-internal"
|
|
|
8
8
|
GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
|
|
9
9
|
NITRO_PRESET = "netlify"
|
|
10
10
|
NPM_CONFIG_PRODUCTION = "false"
|
|
11
|
+
AGENT_CHAT_DURABLE_BACKGROUND = "true"
|
|
11
12
|
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
# slides' generous timeout so multi-image runs don't get killed mid-flight.
|
|
13
|
+
# Emit the Netlify background function used by Assets' durable agent-chat opt-in.
|
|
14
|
+
# The normal server timeout still protects non-agent image/video HTTP handlers.
|
|
15
15
|
[functions."*"]
|
|
16
16
|
timeout = 300
|
|
@@ -10,6 +10,8 @@ import actionsRegistry from "../../.generated/actions-registry.js";
|
|
|
10
10
|
import { getDb, schema } from "../db/index.js";
|
|
11
11
|
import "../register-secrets.js";
|
|
12
12
|
|
|
13
|
+
const ASSETS_BACKGROUND_RUN_SOFT_TIMEOUT_MS = 13 * 60_000;
|
|
14
|
+
|
|
13
15
|
const INITIAL_TOOL_NAMES = [
|
|
14
16
|
"view-screen",
|
|
15
17
|
"list-libraries",
|
|
@@ -240,5 +242,6 @@ export default createAgentChatPlugin({
|
|
|
240
242
|
},
|
|
241
243
|
},
|
|
242
244
|
},
|
|
243
|
-
|
|
245
|
+
durableBackgroundRuns: true,
|
|
246
|
+
runSoftTimeoutMs: ASSETS_BACKGROUND_RUN_SOFT_TIMEOUT_MS,
|
|
244
247
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useT } from "@agent-native/core/client";
|
|
1
|
+
import { appPath, useT } from "@agent-native/core/client";
|
|
2
2
|
import {
|
|
3
3
|
IconBrandApple,
|
|
4
4
|
IconBrandChrome,
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
IconExternalLink,
|
|
9
9
|
} from "@tabler/icons-react";
|
|
10
10
|
import { type ReactNode } from "react";
|
|
11
|
-
import { Link } from "react-router";
|
|
12
11
|
|
|
13
12
|
import { Button, type ButtonProps } from "@/components/ui/button";
|
|
14
13
|
import {
|
|
@@ -91,8 +90,8 @@ function InstallOptionsContent({ desktopHref = "/download" }) {
|
|
|
91
90
|
</div>
|
|
92
91
|
)}
|
|
93
92
|
|
|
94
|
-
<
|
|
95
|
-
|
|
93
|
+
<a
|
|
94
|
+
href={appPath(desktopHref)}
|
|
96
95
|
className="flex items-start gap-3 rounded-md border border-border p-3 text-start transition hover:bg-accent"
|
|
97
96
|
>
|
|
98
97
|
<DesktopIcon className="mt-0.5 h-4 w-4 shrink-0 text-primary" />
|
|
@@ -104,7 +103,7 @@ function InstallOptionsContent({ desktopHref = "/download" }) {
|
|
|
104
103
|
{t("captureInstall.desktopDescription")}
|
|
105
104
|
</span>
|
|
106
105
|
</span>
|
|
107
|
-
</
|
|
106
|
+
</a>
|
|
108
107
|
</div>
|
|
109
108
|
);
|
|
110
109
|
}
|
|
@@ -120,7 +119,7 @@ export function CaptureInstallButton({
|
|
|
120
119
|
if (!clipsChromeExtensionEnabled) {
|
|
121
120
|
return (
|
|
122
121
|
<Button asChild className={className} {...buttonProps}>
|
|
123
|
-
<
|
|
122
|
+
<a href={appPath(desktopHref)}>{children}</a>
|
|
124
123
|
</Button>
|
|
125
124
|
);
|
|
126
125
|
}
|
|
@@ -149,9 +148,9 @@ export function CaptureInstallInlineLink({
|
|
|
149
148
|
}: CaptureInstallInlineLinkProps) {
|
|
150
149
|
if (!clipsChromeExtensionEnabled) {
|
|
151
150
|
return (
|
|
152
|
-
<
|
|
151
|
+
<a href={appPath(desktopHref)} className={className}>
|
|
153
152
|
{children}
|
|
154
|
-
</
|
|
153
|
+
</a>
|
|
155
154
|
);
|
|
156
155
|
}
|
|
157
156
|
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { useActionMutation, useT } from "@agent-native/core/client";
|
|
2
|
+
import { IconMessagePlus, IconAt, IconMoodSmile } from "@tabler/icons-react";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
|
|
5
|
+
import { Button } from "@/components/ui/button";
|
|
6
|
+
import { Textarea } from "@/components/ui/textarea";
|
|
7
|
+
import { cn } from "@/lib/utils";
|
|
8
|
+
|
|
9
|
+
import { msToClock } from "./scrubber";
|
|
10
|
+
|
|
11
|
+
interface TimestampedCommentButtonProps {
|
|
12
|
+
enableComments: boolean;
|
|
13
|
+
onOpen: () => void;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Trigger that opens the docked comment composer, pinned to the current time. */
|
|
18
|
+
export function TimestampedCommentButton({
|
|
19
|
+
enableComments,
|
|
20
|
+
onOpen,
|
|
21
|
+
className,
|
|
22
|
+
}: TimestampedCommentButtonProps) {
|
|
23
|
+
const t = useT();
|
|
24
|
+
if (!enableComments) return null;
|
|
25
|
+
return (
|
|
26
|
+
<Button
|
|
27
|
+
type="button"
|
|
28
|
+
variant="outline"
|
|
29
|
+
size="sm"
|
|
30
|
+
className={cn("gap-1.5", className)}
|
|
31
|
+
onClick={onOpen}
|
|
32
|
+
>
|
|
33
|
+
<IconMessagePlus className="h-4 w-4" />
|
|
34
|
+
{t("commentsPanel.commentButton")}
|
|
35
|
+
</Button>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface TimestampedCommentBarProps {
|
|
40
|
+
recordingId: string;
|
|
41
|
+
atMs: number;
|
|
42
|
+
onClose: () => void;
|
|
43
|
+
onAdded?: () => void;
|
|
44
|
+
className?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Bottom-docked comment composer. Render inside a `relative` container (the
|
|
49
|
+
* video wrapper) so it overlays the bottom of the video at the captured moment.
|
|
50
|
+
*/
|
|
51
|
+
export function TimestampedCommentBar({
|
|
52
|
+
recordingId,
|
|
53
|
+
atMs,
|
|
54
|
+
onClose,
|
|
55
|
+
onAdded,
|
|
56
|
+
className,
|
|
57
|
+
}: TimestampedCommentBarProps) {
|
|
58
|
+
const t = useT();
|
|
59
|
+
const [draft, setDraft] = useState("");
|
|
60
|
+
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
61
|
+
|
|
62
|
+
const addComment = useActionMutation("add-comment");
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
requestAnimationFrame(() => textareaRef.current?.focus());
|
|
66
|
+
}, []);
|
|
67
|
+
|
|
68
|
+
const insertAtCursor = (text: string) => {
|
|
69
|
+
const el = textareaRef.current;
|
|
70
|
+
if (!el) {
|
|
71
|
+
setDraft((d) => d + text);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const start = el.selectionStart ?? draft.length;
|
|
75
|
+
const end = el.selectionEnd ?? draft.length;
|
|
76
|
+
const next = draft.slice(0, start) + text + draft.slice(end);
|
|
77
|
+
setDraft(next);
|
|
78
|
+
requestAnimationFrame(() => {
|
|
79
|
+
el.focus();
|
|
80
|
+
const pos = start + text.length;
|
|
81
|
+
el.setSelectionRange(pos, pos);
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const submit = () => {
|
|
86
|
+
const content = draft.trim();
|
|
87
|
+
if (!content) return;
|
|
88
|
+
addComment.mutate(
|
|
89
|
+
{ recordingId, content, videoTimestampMs: atMs },
|
|
90
|
+
{
|
|
91
|
+
onSuccess: () => {
|
|
92
|
+
setDraft("");
|
|
93
|
+
onAdded?.();
|
|
94
|
+
onClose();
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div className={cn("absolute inset-x-0 bottom-0 z-30 p-3", className)}>
|
|
102
|
+
<div className="rounded-xl border border-border bg-background/95 p-3 shadow-lg backdrop-blur">
|
|
103
|
+
<Textarea
|
|
104
|
+
ref={textareaRef}
|
|
105
|
+
value={draft}
|
|
106
|
+
onChange={(e) => setDraft(e.target.value)}
|
|
107
|
+
onKeyDown={(e) => {
|
|
108
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
submit();
|
|
111
|
+
}
|
|
112
|
+
if (e.key === "Escape") {
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
onClose();
|
|
115
|
+
}
|
|
116
|
+
}}
|
|
117
|
+
placeholder={t("commentsPanel.composerPlaceholder")}
|
|
118
|
+
rows={2}
|
|
119
|
+
className="min-h-[3rem] resize-none border-0 bg-transparent px-1 text-sm shadow-none focus-visible:ring-0 focus-visible:ring-offset-0"
|
|
120
|
+
/>
|
|
121
|
+
<div className="mt-2 flex items-center justify-between">
|
|
122
|
+
<div className="flex items-center gap-1">
|
|
123
|
+
<Button
|
|
124
|
+
type="button"
|
|
125
|
+
variant="ghost"
|
|
126
|
+
size="icon"
|
|
127
|
+
className="h-8 w-8 text-muted-foreground"
|
|
128
|
+
aria-label={t("commentsPanel.mentionSomeone")}
|
|
129
|
+
onClick={() => insertAtCursor("@")}
|
|
130
|
+
>
|
|
131
|
+
<IconAt className="h-4 w-4" />
|
|
132
|
+
</Button>
|
|
133
|
+
<Button
|
|
134
|
+
type="button"
|
|
135
|
+
variant="ghost"
|
|
136
|
+
size="icon"
|
|
137
|
+
className="h-8 w-8 text-muted-foreground"
|
|
138
|
+
aria-label={t("commentsPanel.addEmoji")}
|
|
139
|
+
onClick={() => insertAtCursor("🙂")}
|
|
140
|
+
>
|
|
141
|
+
<IconMoodSmile className="h-4 w-4" />
|
|
142
|
+
</Button>
|
|
143
|
+
</div>
|
|
144
|
+
<div className="flex items-center gap-2">
|
|
145
|
+
<Button type="button" variant="ghost" size="sm" onClick={onClose}>
|
|
146
|
+
{t("common.cancel")}
|
|
147
|
+
</Button>
|
|
148
|
+
<Button
|
|
149
|
+
type="button"
|
|
150
|
+
size="sm"
|
|
151
|
+
className="rounded-full"
|
|
152
|
+
disabled={!draft.trim() || addComment.isPending}
|
|
153
|
+
onClick={submit}
|
|
154
|
+
>
|
|
155
|
+
{t("commentsPanel.commentAt")} {msToClock(atMs)}
|
|
156
|
+
</Button>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
@@ -194,7 +194,7 @@ const SCREEN_CAPTURE_MAX_HEIGHT = 1080;
|
|
|
194
194
|
// client-side (ffmpeg.wasm re-encode is disabled — see COMPRESSION_ENABLED in
|
|
195
195
|
// `@/lib/compress`) and the upload provider streams large files directly, so we
|
|
196
196
|
// capture at a crisp 1080p bitrate instead of a tight budget. 1.2 Mbps left
|
|
197
|
-
// dense UI (fine text
|
|
197
|
+
// dense UI (fine text and code) visibly fuzzy; 8 Mbps keeps it sharp.
|
|
198
198
|
// Dial down here if file sizes become a concern for a deployment.
|
|
199
199
|
const RECORDING_VIDEO_BITRATE_BPS = 8_000_000;
|
|
200
200
|
const RECORDING_AUDIO_BITRATE_BPS = 128_000;
|
|
@@ -850,6 +850,10 @@ const messages = {
|
|
|
850
850
|
replyingTo: "الرد على",
|
|
851
851
|
commentAt: "تعليق عند",
|
|
852
852
|
writeReply: "اكتب ردًا...",
|
|
853
|
+
commentButton: "تعليق",
|
|
854
|
+
composerPlaceholder: "أضف تعليقًا…",
|
|
855
|
+
mentionSomeone: "أذكر شخصًا",
|
|
856
|
+
addEmoji: "أضف رمزًا تعبيريًا",
|
|
853
857
|
},
|
|
854
858
|
shareMeeting: {
|
|
855
859
|
pageTitle: "ملاحظات الاجتماع · Clips",
|
|
@@ -878,6 +878,10 @@ Alle sichtbaren Änderungen für Clips-Nutzer werden hier dokumentiert. Du kanns
|
|
|
878
878
|
replyingTo: "Antwort an",
|
|
879
879
|
commentAt: "Kommentar bei",
|
|
880
880
|
writeReply: "Antwort schreiben...",
|
|
881
|
+
commentButton: "Kommentar",
|
|
882
|
+
composerPlaceholder: "Kommentar hinzufügen…",
|
|
883
|
+
mentionSomeone: "Jemanden erwähnen",
|
|
884
|
+
addEmoji: "Emoji hinzufügen",
|
|
881
885
|
},
|
|
882
886
|
shareMeeting: {
|
|
883
887
|
pageTitle: "Meeting-Notizen · Clips",
|
|
@@ -849,6 +849,10 @@ All notable user-facing changes to Clips are documented here. Open it any time f
|
|
|
849
849
|
replyingTo: "Replying to",
|
|
850
850
|
commentAt: "Comment at",
|
|
851
851
|
writeReply: "Write a reply...",
|
|
852
|
+
commentButton: "Comment",
|
|
853
|
+
composerPlaceholder: "Add a comment…",
|
|
854
|
+
mentionSomeone: "Mention someone",
|
|
855
|
+
addEmoji: "Add emoji",
|
|
852
856
|
},
|
|
853
857
|
shareMeeting: {
|
|
854
858
|
pageTitle: "Meeting notes · Clips",
|
|
@@ -870,6 +870,10 @@ Todos los cambios visibles para los usuarios de Clips se documentan aquí. Puede
|
|
|
870
870
|
replyingTo: "Respondiendo a",
|
|
871
871
|
commentAt: "Comentar en",
|
|
872
872
|
writeReply: "Escribe una respuesta...",
|
|
873
|
+
commentButton: "Comentar",
|
|
874
|
+
composerPlaceholder: "Añadir un comentario…",
|
|
875
|
+
mentionSomeone: "Mencionar a alguien",
|
|
876
|
+
addEmoji: "Añadir emoji",
|
|
873
877
|
},
|
|
874
878
|
shareMeeting: {
|
|
875
879
|
pageTitle: "Notas de reunión · Clips",
|
|
@@ -872,6 +872,10 @@ Tous les changements visibles par les utilisateurs de Clips sont documentés ici
|
|
|
872
872
|
replyingTo: "Réponse à",
|
|
873
873
|
commentAt: "Commentaire à",
|
|
874
874
|
writeReply: "Écrire une réponse...",
|
|
875
|
+
commentButton: "Commenter",
|
|
876
|
+
composerPlaceholder: "Ajouter un commentaire…",
|
|
877
|
+
mentionSomeone: "Mentionner quelqu'un",
|
|
878
|
+
addEmoji: "Ajouter un emoji",
|
|
875
879
|
},
|
|
876
880
|
shareMeeting: {
|
|
877
881
|
pageTitle: "Notes de réunion · Clips",
|
|
@@ -844,6 +844,10 @@ Clips में उपयोगकर्ताओं को दिखने व
|
|
|
844
844
|
replyingTo: "जवाब दे रहे हैं",
|
|
845
845
|
commentAt: "टिप्पणी करें",
|
|
846
846
|
writeReply: "जवाब लिखें...",
|
|
847
|
+
commentButton: "टिप्पणी",
|
|
848
|
+
composerPlaceholder: "टिप्पणी जोड़ें…",
|
|
849
|
+
mentionSomeone: "किसी का उल्लेख करें",
|
|
850
|
+
addEmoji: "इमोजी जोड़ें",
|
|
847
851
|
},
|
|
848
852
|
shareMeeting: {
|
|
849
853
|
pageTitle: "मीटिंग नोट्स · Clips",
|
|
@@ -860,6 +860,10 @@ Clips のユーザー向けの主な変更はここに記録されます。コ
|
|
|
860
860
|
replyingTo: "返信先",
|
|
861
861
|
commentAt: "コメント位置",
|
|
862
862
|
writeReply: "返信を書く...",
|
|
863
|
+
commentButton: "コメント",
|
|
864
|
+
composerPlaceholder: "コメントを追加…",
|
|
865
|
+
mentionSomeone: "メンバーをメンション",
|
|
866
|
+
addEmoji: "絵文字を追加",
|
|
863
867
|
},
|
|
864
868
|
shareMeeting: {
|
|
865
869
|
pageTitle: "会議メモ · Clips",
|
|
@@ -851,6 +851,10 @@ Clips의 모든 사용자 대상 변경 사항은 여기에 기록됩니다. 명
|
|
|
851
851
|
replyingTo: "답글 대상",
|
|
852
852
|
commentAt: "댓글 위치",
|
|
853
853
|
writeReply: "답글 쓰기...",
|
|
854
|
+
commentButton: "댓글",
|
|
855
|
+
composerPlaceholder: "댓글 추가…",
|
|
856
|
+
mentionSomeone: "멘션하기",
|
|
857
|
+
addEmoji: "이모지 추가",
|
|
854
858
|
},
|
|
855
859
|
shareMeeting: {
|
|
856
860
|
pageTitle: "회의 노트 · Clips",
|