@agent-native/core 0.79.27 → 0.80.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 +26 -0
- package/corpus/core/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/corpus/core/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/corpus/core/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/corpus/core/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/corpus/core/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/corpus/core/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/corpus/core/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/corpus/core/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/corpus/core/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/corpus/core/docs/content/template-design.mdx +45 -0
- package/corpus/core/package.json +2 -1
- package/corpus/core/src/agent/engine/index.ts +1 -0
- package/corpus/core/src/agent/engine/registry.ts +40 -0
- package/corpus/core/src/agent/production-agent.ts +6 -2
- package/corpus/core/src/cli/design-connect.ts +490 -0
- package/corpus/core/src/cli/index.ts +16 -0
- package/corpus/core/src/cli/skills.ts +126 -3
- package/corpus/core/src/client/AssistantChat.tsx +43 -7
- package/corpus/core/src/client/agent-chat.ts +27 -3
- package/corpus/core/src/client/blocks/library/MermaidBlock.tsx +1 -1
- package/corpus/core/src/client/blocks/library/diagram.tsx +2 -2
- package/corpus/core/src/client/blocks/library/wireframe.tsx +1 -1
- package/corpus/core/src/client/chat/message-components.tsx +1 -1
- package/corpus/core/src/client/chat-model-groups.ts +1 -2
- package/corpus/core/src/client/components/LiveCursorOverlay.tsx +33 -66
- package/corpus/core/src/client/composer/TiptapComposer.tsx +99 -24
- package/corpus/core/src/client/composer/useVoiceDictation.ts +429 -260
- package/corpus/core/src/client/frame-protocol.ts +17 -2
- package/corpus/core/src/client/rich-markdown-editor/RegistryBlockNode.tsx +2 -2
- package/corpus/core/src/client/sharing/ShareButton.tsx +20 -15
- package/corpus/core/src/client/use-agent-engine-configured.ts +80 -28
- package/corpus/core/src/server/transcribe-voice.ts +57 -22
- package/corpus/core/src/shared/mcp-embed-headers.ts +23 -1
- package/corpus/core/src/styles/agent-native.css +56 -7
- package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/core/src/vite/client.ts +2 -0
- package/corpus/core/src/voice/index.ts +18 -0
- package/corpus/core/src/voice/voice-cleanup-prompt.ts +38 -0
- package/corpus/core/src/voice/voice-context.ts +217 -0
- package/corpus/core/src/voice/voice-replacements.ts +75 -0
- package/corpus/templates/analytics/AGENTS.md +4 -3
- package/corpus/templates/analytics/actions/list-session-recordings.ts +6 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +557 -400
- package/corpus/templates/analytics/app/global.css +0 -4
- package/corpus/templates/analytics/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/analytics/app/i18n-data.ts +20 -0
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +33 -8
- package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +7 -0
- package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +7 -0
- package/corpus/templates/analytics/changelog/2026-06-28-ask-tab-now-matches-the-darker-app-background.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-dashboard-email-reports-now-use-cleaner-light-mode-snapshots.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-28-sessions-now-show-only-signed-in-recordings-with-playable-re.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +3 -3
- package/corpus/templates/analytics/server/lib/dashboard-report.ts +29 -7
- package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +5 -2
- package/corpus/templates/analytics/server/lib/session-replay.ts +24 -4
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/assets/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +131 -42
- package/corpus/templates/brain/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/brain/app/i18n-data.ts +20 -0
- package/corpus/templates/brain/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +29 -1
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +417 -299
- package/corpus/templates/calendar/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/calendar/app/i18n-data.ts +20 -0
- package/corpus/templates/calendar/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +6 -19
- package/corpus/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/clips/AGENTS.md +4 -0
- package/corpus/templates/clips/actions/cleanup-transcript.ts +39 -9
- package/corpus/templates/clips/actions/finalize-meeting.ts +81 -12
- package/corpus/templates/clips/actions/lib/agents-md-context.ts +4 -1
- package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +1 -1
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +2 -2
- package/corpus/templates/clips/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/clips/desktop/src/lib/personal-vocabulary.ts +13 -8
- package/corpus/templates/clips/desktop/src/lib/voice-dictation.ts +60 -1
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +1 -1
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +1 -1
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +5 -5
- package/corpus/templates/content/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +137 -0
- package/corpus/templates/design/AGENTS.md +95 -5
- package/corpus/templates/design/DESIGN.md +82 -0
- package/corpus/templates/design/DEVELOPING.md +43 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +426 -0
- package/corpus/templates/design/actions/apply-shader.ts +277 -0
- package/corpus/templates/design/actions/apply-visual-edit.ts +303 -0
- package/corpus/templates/design/actions/connect-localhost.ts +183 -0
- package/corpus/templates/design/actions/edit-design.ts +195 -42
- package/corpus/templates/design/actions/generate-design.ts +71 -1
- package/corpus/templates/design/actions/generate-screens.ts +193 -0
- package/corpus/templates/design/actions/get-code-layer-projection.ts +191 -0
- package/corpus/templates/design/actions/get-shader.ts +119 -0
- package/corpus/templates/design/actions/list-localhost-connections.ts +95 -0
- package/corpus/templates/design/actions/navigate.ts +55 -2
- package/corpus/templates/design/actions/view-screen.ts +68 -1
- package/corpus/templates/design/agent-native.app-skill.json +10 -0
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +761 -0
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +2057 -103
- package/corpus/templates/design/app/components/design/DesignEditorSkeleton.tsx +74 -38
- package/corpus/templates/design/app/components/design/DesignExtensionsPanel.tsx +399 -0
- package/corpus/templates/design/app/components/design/EditPanel.tsx +3185 -439
- package/corpus/templates/design/app/components/design/LayersPanel.tsx +1124 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +3116 -147
- package/corpus/templates/design/app/components/design/QuestionFlow.tsx +700 -13
- package/corpus/templates/design/app/components/design/TweaksPanel.tsx +107 -63
- package/corpus/templates/design/app/components/design/index.ts +0 -5
- package/corpus/templates/design/app/components/design/inspector/AlignmentMatrix.tsx +286 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +699 -0
- package/corpus/templates/design/app/components/design/inspector/ConstraintsWidget.tsx +461 -0
- package/corpus/templates/design/app/components/design/inspector/ExportSettingsPanel.tsx +166 -0
- package/corpus/templates/design/app/components/design/inspector/FigmaColorPicker.tsx +1420 -0
- package/corpus/templates/design/app/components/design/inspector/SHADER_INTEGRATION.md +420 -0
- package/corpus/templates/design/app/components/design/inspector/ScrubInput.tsx +215 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.stories.tsx +71 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderControls.tsx +518 -0
- package/corpus/templates/design/app/components/design/inspector/ShaderEffectRow.tsx +106 -0
- package/corpus/templates/design/app/components/design/inspector/figma-icons.tsx +361 -0
- package/corpus/templates/design/app/components/design/inspector/index.ts +60 -0
- package/corpus/templates/design/app/components/design/inspector/scrub-input-utils.ts +201 -0
- package/corpus/templates/design/app/components/design/types.ts +23 -0
- package/corpus/templates/design/app/components/layout/Layout.tsx +24 -13
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +4 -4
- package/corpus/templates/design/app/components/visual-editor/CanvasCommentPins.tsx +474 -36
- package/corpus/templates/design/app/components/visual-editor/DrawOverlay.tsx +22 -5
- package/corpus/templates/design/app/components/visual-editor/SaveStatusIndicator.tsx +24 -11
- package/corpus/templates/design/app/global.css +121 -3
- package/corpus/templates/design/app/hooks/use-agent-generating.ts +4 -0
- package/corpus/templates/design/app/hooks/use-navigation-state.ts +130 -8
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +329 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +264 -0
- package/corpus/templates/design/app/i18n-data.ts +2790 -1
- package/corpus/templates/design/app/pages/DesignEditor.tsx +5108 -851
- package/corpus/templates/design/changelog/2026-06-28-annotate-mode-now-combines-drawing-and-comment-pins-in-one-c.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-design-editor-panel-borders-are-cleaner-so-the-canvas-edge-s.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-drawing-prompts-now-reliably-open-and-submit-to-the-design-a.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-editor-app-menus-now-use-an-outline-agent-native-mark-with-b.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-figma-style-code-design-mode.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selection-now-updates-chat-context-without-opening-the.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-layer-selections-now-preserve-hidden-and-locked-canvas-state.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-live-cursors-now-keep-names-beside-a-cleaner-pointer-marker.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-mode-switching-now-lives-in-a-compact-bottom-right-icon-dock.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-handles-zooming-drawing-opening-and-dele.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-now-selects-screens-on-click-and-opens-them-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-screen-overview-zooms-into-the-active-screen-with-smoother-e.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-selected-element-chips-in-chat-are-shorter-and-easier-to-sca.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-the-design-editor-toolbar-is-more-compact-and-the-app-menu-m.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-at-the-top-of-the-design-sidebar-instead-of-.md +6 -0
- package/corpus/templates/design/changelog/2026-06-28-tweaks-now-live-in-the-right-inspector-beside-the-design-tab.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-active-sidebar-rows-use-soft-highlights.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-agents-can-now-open-screen-overview-focus-screens-and-add.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-agents-now-edit-broad-copy-changes-more-reliably.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-design-editor-extensions-now-run-inline-beside-the-artboard.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-sidebars-use-darker-chrome-and-chat-warns-immediately.md +6 -0
- package/corpus/templates/design/changelog/2026-06-29-visual-edit-can-open-localhost-routes-as-url-backed-screens.md +6 -0
- package/corpus/templates/design/package.json +1 -0
- package/corpus/templates/design/server/db/schema.ts +26 -0
- package/corpus/templates/design/server/lib/design-snapshot.ts +1 -1
- package/corpus/templates/design/server/plugins/agent-chat.ts +3 -0
- package/corpus/templates/design/shared/api.ts +27 -0
- package/corpus/templates/design/shared/canvas-frames.ts +103 -0
- package/corpus/templates/design/shared/canvas-math.ts +1058 -0
- package/corpus/templates/design/shared/code-layer.ts +2212 -0
- package/corpus/templates/design/shared/color-utils.ts +180 -0
- package/corpus/templates/design/shared/generation-session.ts +61 -0
- package/corpus/templates/design/shared/shader-presets.ts +782 -0
- package/corpus/templates/design/shared/shader-safety.ts +137 -0
- package/corpus/templates/design/shared/source-mode.ts +237 -0
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +149 -6
- package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/forms/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +2 -2
- package/corpus/templates/macros/changelog/2026-06-28-left-sidebar-footer-controls-use-less-divider-chrome.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +408 -247
- package/corpus/templates/mail/app/i18n/ar-SA.ts +4 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +4 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +4 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +4 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +4 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +4 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +4 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +4 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +4 -0
- package/corpus/templates/mail/app/i18n/zh-TW.ts +4 -0
- package/corpus/templates/mail/changelog/2026-06-28-pinned-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +6 -8
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +1 -1
- package/corpus/templates/plan/app/global.css +61 -78
- package/corpus/templates/plan/app/pages/PlansPage.tsx +8 -0
- package/corpus/templates/plan/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-plans-use-the-shared-neutral-light-and-dark-theme.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-28-sending-open-feedback-from-a-plan-now-opens-the-inline-plan-.md +6 -0
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +5 -5
- package/corpus/templates/slides/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
- package/corpus/templates/videos/app/components/Sidebar.tsx +2 -2
- package/corpus/templates/videos/app/components/layout/Layout.tsx +29 -2
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +113 -30
- package/corpus/templates/videos/app/i18n/ar-SA.ts +2 -0
- package/corpus/templates/videos/app/i18n/de-DE.ts +2 -0
- package/corpus/templates/videos/app/i18n/en-US.ts +2 -0
- package/corpus/templates/videos/app/i18n/es-ES.ts +2 -0
- package/corpus/templates/videos/app/i18n/fr-FR.ts +2 -0
- package/corpus/templates/videos/app/i18n/hi-IN.ts +2 -0
- package/corpus/templates/videos/app/i18n/ja-JP.ts +2 -0
- package/corpus/templates/videos/app/i18n/ko-KR.ts +2 -0
- package/corpus/templates/videos/app/i18n/pt-BR.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-CN.ts +2 -0
- package/corpus/templates/videos/app/i18n/zh-TW.ts +2 -0
- package/corpus/templates/videos/changelog/2026-06-28-left-sidebar-collapses-into-an-animated-icon-rail.md +6 -0
- package/dist/agent/engine/index.d.ts +1 -1
- package/dist/agent/engine/index.d.ts.map +1 -1
- package/dist/agent/engine/index.js +1 -1
- package/dist/agent/engine/index.js.map +1 -1
- package/dist/agent/engine/registry.d.ts +9 -0
- package/dist/agent/engine/registry.d.ts.map +1 -1
- package/dist/agent/engine/registry.js +37 -0
- package/dist/agent/engine/registry.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +4 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/design-connect.d.ts +52 -0
- package/dist/cli/design-connect.d.ts.map +1 -0
- package/dist/cli/design-connect.js +409 -0
- package/dist/cli/design-connect.js.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +121 -3
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +38 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-chat.d.ts +6 -0
- package/dist/client/agent-chat.d.ts.map +1 -1
- package/dist/client/agent-chat.js +17 -3
- package/dist/client/agent-chat.js.map +1 -1
- package/dist/client/blocks/library/MermaidBlock.js +1 -1
- package/dist/client/blocks/library/MermaidBlock.js.map +1 -1
- package/dist/client/blocks/library/diagram.js +1 -1
- package/dist/client/blocks/library/diagram.js.map +1 -1
- package/dist/client/blocks/library/wireframe.js +1 -1
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.js +1 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +1 -2
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/components/LiveCursorOverlay.d.ts +1 -2
- package/dist/client/components/LiveCursorOverlay.d.ts.map +1 -1
- package/dist/client/components/LiveCursorOverlay.js +19 -40
- package/dist/client/components/LiveCursorOverlay.js.map +1 -1
- package/dist/client/composer/TiptapComposer.d.ts +3 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +86 -24
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/composer/useVoiceDictation.d.ts +9 -0
- package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
- package/dist/client/composer/useVoiceDictation.js +154 -32
- package/dist/client/composer/useVoiceDictation.js.map +1 -1
- package/dist/client/frame-protocol.d.ts +17 -2
- package/dist/client/frame-protocol.d.ts.map +1 -1
- package/dist/client/frame-protocol.js.map +1 -1
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js +2 -2
- package/dist/client/rich-markdown-editor/RegistryBlockNode.js.map +1 -1
- package/dist/client/sharing/ShareButton.d.ts +2 -0
- package/dist/client/sharing/ShareButton.d.ts.map +1 -1
- package/dist/client/sharing/ShareButton.js +7 -6
- package/dist/client/sharing/ShareButton.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts +5 -0
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +51 -25
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +8 -8
- package/dist/progress/routes.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts.map +1 -1
- package/dist/server/transcribe-voice.js +40 -24
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/shared/mcp-embed-headers.d.ts +1 -0
- package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
- package/dist/shared/mcp-embed-headers.js +20 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-native.css +56 -7
- package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/dist/vite/client.d.ts.map +1 -1
- package/dist/vite/client.js +2 -0
- package/dist/vite/client.js.map +1 -1
- package/dist/voice/index.d.ts +5 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +4 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/voice-cleanup-prompt.d.ts +6 -0
- package/dist/voice/voice-cleanup-prompt.d.ts.map +1 -0
- package/dist/voice/voice-cleanup-prompt.js +26 -0
- package/dist/voice/voice-cleanup-prompt.js.map +1 -0
- package/dist/voice/voice-context.d.ts +25 -0
- package/dist/voice/voice-context.d.ts.map +1 -0
- package/dist/voice/voice-context.js +156 -0
- package/dist/voice/voice-context.js.map +1 -0
- package/dist/voice/voice-replacements.d.ts +4 -0
- package/dist/voice/voice-replacements.d.ts.map +1 -0
- package/dist/voice/voice-replacements.js +52 -0
- package/dist/voice/voice-replacements.js.map +1 -0
- package/docs/content/locales/ar-SA/template-design.mdx +41 -0
- package/docs/content/locales/de-DE/template-design.mdx +51 -0
- package/docs/content/locales/es-ES/template-design.mdx +50 -0
- package/docs/content/locales/fr-FR/template-design.mdx +49 -0
- package/docs/content/locales/hi-IN/template-design.mdx +44 -0
- package/docs/content/locales/ja-JP/template-design.mdx +46 -0
- package/docs/content/locales/ko-KR/template-design.mdx +44 -0
- package/docs/content/locales/pt-BR/template-design.mdx +48 -0
- package/docs/content/locales/zh-CN/template-design.mdx +36 -0
- package/docs/content/locales/zh-TW/template-design.mdx +38 -0
- package/docs/content/template-design.mdx +45 -0
- package/package.json +2 -1
- package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +10 -0
- package/corpus/templates/design/app/components/design/DesignToolbar.tsx +0 -339
- package/corpus/templates/design/app/components/design/PresentMode.tsx +0 -68
- package/corpus/templates/design/app/components/design/ViewportTabs.tsx +0 -149
- package/corpus/templates/design/app/components/design/ZoomControls.tsx +0 -157
|
@@ -35,6 +35,8 @@ const enUS = {
|
|
|
35
35
|
recentSalesDescription: "You made 265 sales this month.",
|
|
36
36
|
},
|
|
37
37
|
sidebar: {
|
|
38
|
+
collapseSidebar: "Collapse sidebar",
|
|
39
|
+
expandSidebar: "Expand sidebar",
|
|
38
40
|
collapseDashboards: "Collapse dashboards",
|
|
39
41
|
expandDashboards: "Expand dashboards",
|
|
40
42
|
collapseAnalyses: "Collapse analyses",
|
|
@@ -3406,6 +3408,8 @@ export const messagesByLocale = {
|
|
|
3406
3408
|
created: "创建于 {{date}}",
|
|
3407
3409
|
},
|
|
3408
3410
|
sidebar: {
|
|
3411
|
+
collapseSidebar: "折叠侧边栏",
|
|
3412
|
+
expandSidebar: "展开侧边栏",
|
|
3409
3413
|
collapseDashboards: "收起仪表板",
|
|
3410
3414
|
expandDashboards: "展开仪表板",
|
|
3411
3415
|
collapseAnalyses: "收起分析",
|
|
@@ -3580,6 +3584,8 @@ export const messagesByLocale = {
|
|
|
3580
3584
|
created: "Creado el {{date}}",
|
|
3581
3585
|
},
|
|
3582
3586
|
sidebar: {
|
|
3587
|
+
collapseSidebar: "Contraer barra lateral",
|
|
3588
|
+
expandSidebar: "Expandir barra lateral",
|
|
3583
3589
|
collapseDashboards: "Contraer paneles",
|
|
3584
3590
|
expandDashboards: "Expandir paneles",
|
|
3585
3591
|
collapseAnalyses: "Contraer análisis",
|
|
@@ -3762,6 +3768,8 @@ export const messagesByLocale = {
|
|
|
3762
3768
|
created: "Créé le {{date}}",
|
|
3763
3769
|
},
|
|
3764
3770
|
sidebar: {
|
|
3771
|
+
collapseSidebar: "Réduire la barre latérale",
|
|
3772
|
+
expandSidebar: "Développer la barre latérale",
|
|
3765
3773
|
collapseDashboards: "Réduire les tableaux de bord",
|
|
3766
3774
|
expandDashboards: "Développer les tableaux de bord",
|
|
3767
3775
|
collapseAnalyses: "Réduire les analyses",
|
|
@@ -3950,6 +3958,8 @@ export const messagesByLocale = {
|
|
|
3950
3958
|
created: "Erstellt am {{date}}",
|
|
3951
3959
|
},
|
|
3952
3960
|
sidebar: {
|
|
3961
|
+
collapseSidebar: "Seitenleiste einklappen",
|
|
3962
|
+
expandSidebar: "Seitenleiste erweitern",
|
|
3953
3963
|
collapseDashboards: "Dashboards einklappen",
|
|
3954
3964
|
expandDashboards: "Dashboards ausklappen",
|
|
3955
3965
|
collapseAnalyses: "Analysen einklappen",
|
|
@@ -4138,6 +4148,8 @@ export const messagesByLocale = {
|
|
|
4138
4148
|
created: "{{date}} 作成",
|
|
4139
4149
|
},
|
|
4140
4150
|
sidebar: {
|
|
4151
|
+
collapseSidebar: "サイドバーを折りたたむ",
|
|
4152
|
+
expandSidebar: "サイドバーを展開",
|
|
4141
4153
|
collapseDashboards: "ダッシュボードを折りたたむ",
|
|
4142
4154
|
expandDashboards: "ダッシュボードを展開",
|
|
4143
4155
|
collapseAnalyses: "分析を折りたたむ",
|
|
@@ -4322,6 +4334,8 @@ export const messagesByLocale = {
|
|
|
4322
4334
|
created: "{{date}} 생성됨",
|
|
4323
4335
|
},
|
|
4324
4336
|
sidebar: {
|
|
4337
|
+
collapseSidebar: "사이드바 접기",
|
|
4338
|
+
expandSidebar: "사이드바 펼치기",
|
|
4325
4339
|
collapseDashboards: "대시보드 접기",
|
|
4326
4340
|
expandDashboards: "대시보드 펼치기",
|
|
4327
4341
|
collapseAnalyses: "분석 접기",
|
|
@@ -4505,6 +4519,8 @@ export const messagesByLocale = {
|
|
|
4505
4519
|
created: "Criado em {{date}}",
|
|
4506
4520
|
},
|
|
4507
4521
|
sidebar: {
|
|
4522
|
+
collapseSidebar: "Recolher barra lateral",
|
|
4523
|
+
expandSidebar: "Expandir barra lateral",
|
|
4508
4524
|
collapseDashboards: "Recolher dashboards",
|
|
4509
4525
|
expandDashboards: "Expandir dashboards",
|
|
4510
4526
|
collapseAnalyses: "Recolher análises",
|
|
@@ -4693,6 +4709,8 @@ export const messagesByLocale = {
|
|
|
4693
4709
|
created: "{{date}} को बनाया गया",
|
|
4694
4710
|
},
|
|
4695
4711
|
sidebar: {
|
|
4712
|
+
collapseSidebar: "साइडबार समेटें",
|
|
4713
|
+
expandSidebar: "साइडबार फैलाएं",
|
|
4696
4714
|
collapseDashboards: "डैशबोर्ड समेटें",
|
|
4697
4715
|
expandDashboards: "डैशबोर्ड फैलाएं",
|
|
4698
4716
|
collapseAnalyses: "विश्लेषण समेटें",
|
|
@@ -4874,6 +4892,8 @@ export const messagesByLocale = {
|
|
|
4874
4892
|
created: "تم الإنشاء في {{date}}",
|
|
4875
4893
|
},
|
|
4876
4894
|
sidebar: {
|
|
4895
|
+
collapseSidebar: "طي الشريط الجانبي",
|
|
4896
|
+
expandSidebar: "توسيع الشريط الجانبي",
|
|
4877
4897
|
collapseDashboards: "طي لوحات المعلومات",
|
|
4878
4898
|
expandDashboards: "توسيع لوحات المعلومات",
|
|
4879
4899
|
collapseAnalyses: "طي التحليلات",
|
|
@@ -427,6 +427,7 @@ export default function SqlDashboardPage() {
|
|
|
427
427
|
const navigate = useNavigate();
|
|
428
428
|
const dashboardId = searchParams.get("id") || routeId;
|
|
429
429
|
const reportScreenshot = searchParams.get("reportScreenshot") === "1";
|
|
430
|
+
const reportSettingsRequested = searchParams.get("reportSettings") === "1";
|
|
430
431
|
const reportPanelLimit = reportScreenshot
|
|
431
432
|
? parseReportPanelLimit(searchParams.get("reportPanelLimit"))
|
|
432
433
|
: null;
|
|
@@ -1033,6 +1034,28 @@ export default function SqlDashboardPage() {
|
|
|
1033
1034
|
return out;
|
|
1034
1035
|
}, [dashboard?.filters, searchParams]);
|
|
1035
1036
|
|
|
1037
|
+
useEffect(() => {
|
|
1038
|
+
if (!reportScreenshot && reportSettingsRequested) {
|
|
1039
|
+
setEmailReportOpen(true);
|
|
1040
|
+
}
|
|
1041
|
+
}, [reportScreenshot, reportSettingsRequested]);
|
|
1042
|
+
|
|
1043
|
+
const handleEmailReportOpenChange = useCallback(
|
|
1044
|
+
(open: boolean) => {
|
|
1045
|
+
setEmailReportOpen(open);
|
|
1046
|
+
if (open || !reportSettingsRequested) return;
|
|
1047
|
+
setSearchParams(
|
|
1048
|
+
(prev) => {
|
|
1049
|
+
const next = new URLSearchParams(prev);
|
|
1050
|
+
next.delete("reportSettings");
|
|
1051
|
+
return next;
|
|
1052
|
+
},
|
|
1053
|
+
{ replace: true },
|
|
1054
|
+
);
|
|
1055
|
+
},
|
|
1056
|
+
[reportSettingsRequested, setSearchParams],
|
|
1057
|
+
);
|
|
1058
|
+
|
|
1036
1059
|
// Distinct tab values across panels in declaration order. When this is
|
|
1037
1060
|
// non-empty the dashboard renders a tab strip and filters panels by tab.
|
|
1038
1061
|
const tabs = useMemo<string[]>(() => {
|
|
@@ -1453,7 +1476,7 @@ export default function SqlDashboardPage() {
|
|
|
1453
1476
|
{dashboardId ? (
|
|
1454
1477
|
<EmailReportDialog
|
|
1455
1478
|
open={emailReportOpen}
|
|
1456
|
-
onOpenChange={
|
|
1479
|
+
onOpenChange={handleEmailReportOpenChange}
|
|
1457
1480
|
dashboardId={dashboardId}
|
|
1458
1481
|
dashboardName={dashboard.name}
|
|
1459
1482
|
filters={currentReportFilters}
|
|
@@ -1565,7 +1588,7 @@ export default function SqlDashboardPage() {
|
|
|
1565
1588
|
placeholder={t("sqlDashboard.addDescriptionPlaceholder")}
|
|
1566
1589
|
className="text-sm resize-y"
|
|
1567
1590
|
/>
|
|
1568
|
-
) : dashboard.description ? (
|
|
1591
|
+
) : !reportScreenshot && dashboard.description ? (
|
|
1569
1592
|
<button
|
|
1570
1593
|
className={
|
|
1571
1594
|
canEdit
|
|
@@ -1637,12 +1660,14 @@ export default function SqlDashboardPage() {
|
|
|
1637
1660
|
)}
|
|
1638
1661
|
|
|
1639
1662
|
{/* Filters */}
|
|
1640
|
-
{
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1663
|
+
{!reportScreenshot &&
|
|
1664
|
+
dashboard.filters &&
|
|
1665
|
+
dashboard.filters.length > 0 && (
|
|
1666
|
+
<DashboardFilterBar
|
|
1667
|
+
filters={dashboard.filters}
|
|
1668
|
+
onSaveView={canEdit ? handleSaveView : undefined}
|
|
1669
|
+
/>
|
|
1670
|
+
)}
|
|
1646
1671
|
|
|
1647
1672
|
{/* Panels grid */}
|
|
1648
1673
|
{dashboard.panels.length === 0 ? (
|
|
@@ -1269,6 +1269,8 @@ function visitorLabel(
|
|
|
1269
1269
|
recording: SessionRecordingSummary,
|
|
1270
1270
|
t: ReturnType<typeof useT>,
|
|
1271
1271
|
): string {
|
|
1272
|
+
const email = emailLike(recording.userId) || emailLike(recording.userKey);
|
|
1273
|
+
if (email) return email;
|
|
1272
1274
|
return (
|
|
1273
1275
|
recording.userId ||
|
|
1274
1276
|
recording.userKey ||
|
|
@@ -1277,6 +1279,11 @@ function visitorLabel(
|
|
|
1277
1279
|
);
|
|
1278
1280
|
}
|
|
1279
1281
|
|
|
1282
|
+
function emailLike(value: string | null): string | null {
|
|
1283
|
+
if (!value?.includes("@")) return null;
|
|
1284
|
+
return value;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1280
1287
|
function formatDuration(ms: number | null): string {
|
|
1281
1288
|
if (!ms || !Number.isFinite(ms) || ms <= 0) return "0s";
|
|
1282
1289
|
const seconds = Math.round(ms / 1000);
|
|
@@ -374,6 +374,8 @@ function visitorLabel(
|
|
|
374
374
|
recording: SessionRecordingSummary,
|
|
375
375
|
t: ReturnType<typeof useT>,
|
|
376
376
|
): string {
|
|
377
|
+
const email = emailLike(recording.userId) || emailLike(recording.userKey);
|
|
378
|
+
if (email) return email;
|
|
377
379
|
return (
|
|
378
380
|
recording.userId ||
|
|
379
381
|
recording.userKey ||
|
|
@@ -382,6 +384,11 @@ function visitorLabel(
|
|
|
382
384
|
);
|
|
383
385
|
}
|
|
384
386
|
|
|
387
|
+
function emailLike(value: string | null): string | null {
|
|
388
|
+
if (!value?.includes("@")) return null;
|
|
389
|
+
return value;
|
|
390
|
+
}
|
|
391
|
+
|
|
385
392
|
function shortId(value: string): string {
|
|
386
393
|
return value.length > 22
|
|
387
394
|
? `${value.slice(0, 10)}...${value.slice(-8)}`
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
"chartType": "metric",
|
|
268
268
|
"source": "first-party",
|
|
269
269
|
"width": 1,
|
|
270
|
-
"sql": "SELECT COUNT(*) AS count FROM session_recordings WHERE chunk_count > 0 AND ('{{timeRange}}' IN ('', 'all') OR ('{{timeRange}}' = '7d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '7 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '30d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '30 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '90d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '90 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '180d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '180 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '365d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '365 days', 'YYYY-MM-DD'))) AND ('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(user_id, '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(user_id, '')) LIKE '%@builder.io'))",
|
|
270
|
+
"sql": "SELECT COUNT(*) AS count FROM session_recordings WHERE chunk_count > 0 AND event_count > 0 AND COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')) IS NOT NULL AND ('{{timeRange}}' IN ('', 'all') OR ('{{timeRange}}' = '7d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '7 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '30d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '30 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '90d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '90 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '180d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '180 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '365d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '365 days', 'YYYY-MM-DD'))) AND ('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) LIKE '%@builder.io'))",
|
|
271
271
|
"config": {
|
|
272
272
|
"yKey": "count",
|
|
273
273
|
"yFormatter": "number",
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
"chartType": "area",
|
|
281
281
|
"source": "first-party",
|
|
282
282
|
"width": 1,
|
|
283
|
-
"sql": "SELECT substr(started_at, 1, 10) AS date, SUM(chunk_count) AS count FROM session_recordings WHERE chunk_count > 0 AND ('{{timeRange}}' IN ('', 'all') OR ('{{timeRange}}' = '7d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '7 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '30d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '30 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '90d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '90 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '180d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '180 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '365d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '365 days', 'YYYY-MM-DD'))) AND ('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(user_id, '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(user_id, '')) LIKE '%@builder.io')) GROUP BY substr(started_at, 1, 10) ORDER BY date",
|
|
283
|
+
"sql": "SELECT substr(started_at, 1, 10) AS date, SUM(chunk_count) AS count FROM session_recordings WHERE chunk_count > 0 AND event_count > 0 AND COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')) IS NOT NULL AND ('{{timeRange}}' IN ('', 'all') OR ('{{timeRange}}' = '7d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '7 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '30d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '30 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '90d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '90 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '180d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '180 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '365d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '365 days', 'YYYY-MM-DD'))) AND ('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) LIKE '%@builder.io')) GROUP BY substr(started_at, 1, 10) ORDER BY date",
|
|
284
284
|
"config": {
|
|
285
285
|
"xKey": "date",
|
|
286
286
|
"yKey": "count",
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
"chartType": "table",
|
|
296
296
|
"source": "first-party",
|
|
297
297
|
"width": 2,
|
|
298
|
-
"sql": "SELECT id AS recording_id, session_id, COALESCE(NULLIF(app, ''), NULLIF(template, ''), 'unknown') AS app, COALESCE(NULLIF(user_id, '')
|
|
298
|
+
"sql": "SELECT id AS recording_id, session_id, COALESCE(NULLIF(app, ''), NULLIF(template, ''), 'unknown') AS app, COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')) AS visitor, chunk_count AS chunks, event_count AS events, started_at, COALESCE(ended_at, last_ingested_at, started_at) AS last_seen, '/sessions/' || id AS href FROM session_recordings WHERE chunk_count > 0 AND event_count > 0 AND COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')) IS NOT NULL AND ('{{timeRange}}' IN ('', 'all') OR ('{{timeRange}}' = '7d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '7 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '30d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '30 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '90d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '90 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '180d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '180 days', 'YYYY-MM-DD')) OR ('{{timeRange}}' = '365d' AND substr(started_at, 1, 10) >= to_char(CURRENT_DATE - INTERVAL '365 days', 'YYYY-MM-DD'))) AND ('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, '')), '')) LIKE '%@builder.io')) ORDER BY last_seen DESC LIMIT 25",
|
|
299
299
|
"config": {
|
|
300
300
|
"description": "Recent first-party session recordings. Session links open the local replay viewer.",
|
|
301
301
|
"sortable": true,
|
|
@@ -27,6 +27,7 @@ type ReportSnapshot = {
|
|
|
27
27
|
description?: string;
|
|
28
28
|
filters: Record<string, string>;
|
|
29
29
|
dashboardUrl: string;
|
|
30
|
+
reportSettingsUrl: string;
|
|
30
31
|
generatedAt: string;
|
|
31
32
|
};
|
|
32
33
|
|
|
@@ -39,6 +40,7 @@ const DEFAULT_SERVERLESS_CHROMIUM_PACK_URL =
|
|
|
39
40
|
"https://github.com/Sparticuz/chromium/releases/download/v149.0.0/chromium-v149.0.0-pack.x64.tar";
|
|
40
41
|
const DASHBOARD_REPORT_SCREENSHOT_PARAM = "reportScreenshot";
|
|
41
42
|
const DASHBOARD_REPORT_PANEL_LIMIT_PARAM = "reportPanelLimit";
|
|
43
|
+
const DASHBOARD_REPORT_SETTINGS_PARAM = "reportSettings";
|
|
42
44
|
const DASHBOARD_REPORT_CID = "dashboard-report-snapshot";
|
|
43
45
|
const COMPACT_REPORT_PANEL_LIMIT = 12;
|
|
44
46
|
const LOCAL_SCREENSHOT_TIMEOUT_MS = 90_000;
|
|
@@ -114,7 +116,11 @@ function dashboardBaseUrl(): string {
|
|
|
114
116
|
function buildDashboardPath(
|
|
115
117
|
dashboardId: string,
|
|
116
118
|
filters: Record<string, string>,
|
|
117
|
-
options?: {
|
|
119
|
+
options?: {
|
|
120
|
+
reportScreenshot?: boolean;
|
|
121
|
+
reportSettings?: boolean;
|
|
122
|
+
panelLimit?: number;
|
|
123
|
+
},
|
|
118
124
|
): string {
|
|
119
125
|
const url = new URL(
|
|
120
126
|
`/dashboards/${encodeURIComponent(dashboardId)}`,
|
|
@@ -126,6 +132,9 @@ function buildDashboardPath(
|
|
|
126
132
|
if (options?.reportScreenshot) {
|
|
127
133
|
url.searchParams.set(DASHBOARD_REPORT_SCREENSHOT_PARAM, "1");
|
|
128
134
|
}
|
|
135
|
+
if (options?.reportSettings) {
|
|
136
|
+
url.searchParams.set(DASHBOARD_REPORT_SETTINGS_PARAM, "1");
|
|
137
|
+
}
|
|
129
138
|
if (options?.panelLimit && options.panelLimit > 0) {
|
|
130
139
|
url.searchParams.set(
|
|
131
140
|
DASHBOARD_REPORT_PANEL_LIMIT_PARAM,
|
|
@@ -138,7 +147,11 @@ function buildDashboardPath(
|
|
|
138
147
|
function buildDashboardUrl(
|
|
139
148
|
dashboardId: string,
|
|
140
149
|
filters: Record<string, string>,
|
|
141
|
-
options?: {
|
|
150
|
+
options?: {
|
|
151
|
+
reportScreenshot?: boolean;
|
|
152
|
+
reportSettings?: boolean;
|
|
153
|
+
panelLimit?: number;
|
|
154
|
+
},
|
|
142
155
|
): string {
|
|
143
156
|
const path = buildDashboardPath(dashboardId, filters, options);
|
|
144
157
|
const url = new URL(path, `${dashboardBaseUrl()}/`);
|
|
@@ -178,6 +191,9 @@ async function collectReportSnapshot(
|
|
|
178
191
|
description: config.description,
|
|
179
192
|
filters,
|
|
180
193
|
dashboardUrl: buildDashboardUrl(sub.dashboardId, filters),
|
|
194
|
+
reportSettingsUrl: buildDashboardUrl(sub.dashboardId, filters, {
|
|
195
|
+
reportSettings: true,
|
|
196
|
+
}),
|
|
181
197
|
generatedAt: new Date().toISOString(),
|
|
182
198
|
};
|
|
183
199
|
}
|
|
@@ -335,7 +351,10 @@ async function captureDashboardPng(
|
|
|
335
351
|
deviceScaleFactor: 1,
|
|
336
352
|
});
|
|
337
353
|
page.setDefaultTimeout(timeout);
|
|
338
|
-
await page.emulateMedia({ media: "screen" });
|
|
354
|
+
await page.emulateMedia({ media: "screen", colorScheme: "light" });
|
|
355
|
+
await page.addInitScript(() => {
|
|
356
|
+
window.localStorage.setItem("theme", "light");
|
|
357
|
+
});
|
|
339
358
|
await page.goto(screenshotUrl.toString(), {
|
|
340
359
|
waitUntil: "domcontentloaded",
|
|
341
360
|
timeout,
|
|
@@ -423,10 +442,8 @@ function renderReportEmailHtml(
|
|
|
423
442
|
): string {
|
|
424
443
|
const title = escapeHtml(snapshot.title);
|
|
425
444
|
const dashboardUrl = escapeHtml(snapshot.dashboardUrl);
|
|
445
|
+
const reportSettingsUrl = escapeHtml(snapshot.reportSettingsUrl);
|
|
426
446
|
const date = escapeHtml(reportDate(snapshot));
|
|
427
|
-
const description = snapshot.description
|
|
428
|
-
? `<p style="margin:8px 0 18px;color:#525866;font-size:14px;line-height:1.5;">${escapeHtml(snapshot.description)}</p>`
|
|
429
|
-
: "";
|
|
430
447
|
const screenshotBlock = options.screenshotAttached
|
|
431
448
|
? `<a href="${dashboardUrl}" style="display:block;text-decoration:none;">
|
|
432
449
|
<img src="cid:${DASHBOARD_REPORT_CID}" alt="${title}" width="100%" style="display:block;width:100%;max-width:1280px;height:auto;border:1px solid #e5e7eb;border-radius:8px;" />
|
|
@@ -441,10 +458,14 @@ function renderReportEmailHtml(
|
|
|
441
458
|
<h3 style="margin:0 0 8px;font-size:18px;line-height:1.35;font-weight:600;">
|
|
442
459
|
Here's the report of <a href="${dashboardUrl}" style="color:#2563eb;text-decoration:none;">${title}</a> for ${date}.
|
|
443
460
|
</h3>
|
|
444
|
-
${description}
|
|
445
461
|
${screenshotBlock}
|
|
446
462
|
<p style="margin:18px 0 0;color:#525866;font-size:13px;line-height:1.45;">
|
|
447
463
|
<a href="${dashboardUrl}" style="color:#2563eb;text-decoration:none;">Open dashboard</a>
|
|
464
|
+
<span style="color:#9ca3af;"> · </span>
|
|
465
|
+
<a href="${reportSettingsUrl}" style="color:#2563eb;text-decoration:none;">Edit subscription settings</a>
|
|
466
|
+
</p>
|
|
467
|
+
<p style="margin:6px 0 0;color:#6b7280;font-size:12px;line-height:1.45;">
|
|
468
|
+
Change recipients, delivery time, filters, or turn this report on/off.
|
|
448
469
|
</p>
|
|
449
470
|
</body>
|
|
450
471
|
</html>`;
|
|
@@ -458,6 +479,7 @@ function renderReportText(
|
|
|
458
479
|
`Daily dashboard report: ${snapshot.title}`,
|
|
459
480
|
`Date: ${reportDate(snapshot)}`,
|
|
460
481
|
`Open dashboard: ${snapshot.dashboardUrl}`,
|
|
482
|
+
`Edit subscription settings: ${snapshot.reportSettingsUrl}`,
|
|
461
483
|
];
|
|
462
484
|
if (!options.screenshotAttached) {
|
|
463
485
|
lines.push("Dashboard image unavailable for this run.");
|
|
@@ -166,10 +166,13 @@ const REPLAY_RECORDING_DATE_SQL = "substr(started_at, 1, 10)";
|
|
|
166
166
|
const REPLAY_TIME_RANGE_FILTER = dashboardTimeRangeFilter(
|
|
167
167
|
REPLAY_RECORDING_DATE_SQL,
|
|
168
168
|
);
|
|
169
|
-
const
|
|
169
|
+
const REPLAY_VISITOR_EMAIL_SQL =
|
|
170
|
+
"COALESCE(NULLIF(CASE WHEN lower(coalesce(user_id, '')) LIKE '%@%' THEN user_id ELSE '' END, ''), NULLIF(CASE WHEN lower(coalesce(user_key, '')) LIKE '%@%' THEN user_key ELSE '' END, ''))";
|
|
171
|
+
const REPLAY_EMAIL_FILTER = `('{{emailFilter}}' IN ('', 'all') OR ('{{emailFilter}}' = 'exclude_builder' AND lower(coalesce(${REPLAY_VISITOR_EMAIL_SQL}, '')) NOT LIKE '%@builder.io') OR ('{{emailFilter}}' = 'only_builder' AND lower(coalesce(${REPLAY_VISITOR_EMAIL_SQL}, '')) LIKE '%@builder.io'))`;
|
|
172
|
+
const REPLAY_RECORDING_FILTER = `chunk_count > 0 AND event_count > 0 AND ${REPLAY_VISITOR_EMAIL_SQL} IS NOT NULL AND ${REPLAY_TIME_RANGE_FILTER} AND ${REPLAY_EMAIL_FILTER}`;
|
|
170
173
|
const REPLAY_SESSIONS_SQL = `SELECT COUNT(*) AS count FROM session_recordings WHERE ${REPLAY_RECORDING_FILTER}`;
|
|
171
174
|
const REPLAY_CHUNKS_OVER_TIME_SQL = `SELECT ${REPLAY_RECORDING_DATE_SQL} AS date, SUM(chunk_count) AS count FROM session_recordings WHERE ${REPLAY_RECORDING_FILTER} GROUP BY ${REPLAY_RECORDING_DATE_SQL} ORDER BY date`;
|
|
172
|
-
const RECENT_REPLAY_SESSIONS_SQL = `SELECT id AS recording_id, session_id, COALESCE(NULLIF(app, ''), NULLIF(template, ''), 'unknown') AS app,
|
|
175
|
+
const RECENT_REPLAY_SESSIONS_SQL = `SELECT id AS recording_id, session_id, COALESCE(NULLIF(app, ''), NULLIF(template, ''), 'unknown') AS app, ${REPLAY_VISITOR_EMAIL_SQL} AS visitor, chunk_count AS chunks, event_count AS events, started_at, COALESCE(ended_at, last_ingested_at, started_at) AS last_seen, '/sessions/' || id AS href FROM session_recordings WHERE ${REPLAY_RECORDING_FILTER} ORDER BY last_seen DESC LIMIT 25`;
|
|
173
176
|
export const FIRST_PARTY_DASHBOARD_FILTERS: FirstPartyDashboardFilter[] = [
|
|
174
177
|
{
|
|
175
178
|
id: "timeRange",
|
|
@@ -988,11 +988,18 @@ function rowToSessionRecordingSummary(
|
|
|
988
988
|
}
|
|
989
989
|
|
|
990
990
|
function hasVisibleSessionRecordingIdentity(row: any): boolean {
|
|
991
|
-
return Boolean(replayEmail(row.userId) ||
|
|
991
|
+
return Boolean(replayEmail(row.userId) || replayEmail(row.userKey));
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
function hasPlayableSessionRecordingEvents(row: any): boolean {
|
|
995
|
+
return Number(row.chunkCount ?? 0) > 0 && Number(row.eventCount ?? 0) > 0;
|
|
992
996
|
}
|
|
993
997
|
|
|
994
998
|
function isVisibleSessionRecording(row: any): boolean {
|
|
995
|
-
return
|
|
999
|
+
return (
|
|
1000
|
+
hasVisibleSessionRecordingIdentity(row) &&
|
|
1001
|
+
hasPlayableSessionRecordingEvents(row)
|
|
1002
|
+
);
|
|
996
1003
|
}
|
|
997
1004
|
|
|
998
1005
|
function mergeReplayMetadata(
|
|
@@ -1045,7 +1052,14 @@ function replayTextContains(column: unknown, query: string) {
|
|
|
1045
1052
|
function replayVisibleIdentityCondition() {
|
|
1046
1053
|
return or(
|
|
1047
1054
|
replayTextContains(schema.sessionRecordings.userId, "@"),
|
|
1048
|
-
|
|
1055
|
+
replayTextContains(schema.sessionRecordings.userKey, "@"),
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
function replayPlayableEventsCondition() {
|
|
1060
|
+
return and(
|
|
1061
|
+
gte(schema.sessionRecordings.chunkCount, 1),
|
|
1062
|
+
gte(schema.sessionRecordings.eventCount, 1),
|
|
1049
1063
|
);
|
|
1050
1064
|
}
|
|
1051
1065
|
|
|
@@ -1353,6 +1367,7 @@ export async function listSessionRecordings(
|
|
|
1353
1367
|
orgId: scope.orgId ?? undefined,
|
|
1354
1368
|
}),
|
|
1355
1369
|
replayVisibleIdentityCondition(),
|
|
1370
|
+
replayPlayableEventsCondition(),
|
|
1356
1371
|
];
|
|
1357
1372
|
if (filters.app)
|
|
1358
1373
|
conditions.push(eq(schema.sessionRecordings.app, filters.app));
|
|
@@ -1363,7 +1378,12 @@ export async function listSessionRecordings(
|
|
|
1363
1378
|
conditions.push(eq(schema.sessionRecordings.sessionId, filters.sessionId));
|
|
1364
1379
|
}
|
|
1365
1380
|
if (filters.userId) {
|
|
1366
|
-
conditions.push(
|
|
1381
|
+
conditions.push(
|
|
1382
|
+
or(
|
|
1383
|
+
eq(schema.sessionRecordings.userId, filters.userId),
|
|
1384
|
+
eq(schema.sessionRecordings.userKey, filters.userId),
|
|
1385
|
+
),
|
|
1386
|
+
);
|
|
1367
1387
|
}
|
|
1368
1388
|
if (filters.anonymousId) {
|
|
1369
1389
|
conditions.push(
|
|
@@ -425,7 +425,7 @@ export function Sidebar() {
|
|
|
425
425
|
return (
|
|
426
426
|
<aside
|
|
427
427
|
className={cn(
|
|
428
|
-
"flex h-full min-w-0 shrink-0 flex-col overflow-hidden border-e border-border bg-sidebar text-sidebar-foreground",
|
|
428
|
+
"flex h-full min-w-0 shrink-0 flex-col overflow-hidden border-e border-border bg-sidebar text-sidebar-foreground transition-[width] duration-200 ease-out",
|
|
429
429
|
collapsed ? "w-14" : "w-56",
|
|
430
430
|
)}
|
|
431
431
|
>
|
|
@@ -553,15 +553,15 @@ export function Sidebar() {
|
|
|
553
553
|
|
|
554
554
|
{!collapsed && (
|
|
555
555
|
<div className="mt-auto shrink-0">
|
|
556
|
-
<div className="
|
|
556
|
+
<div className="px-2 py-1">
|
|
557
557
|
<ExtensionsSidebarSection />
|
|
558
558
|
</div>
|
|
559
559
|
|
|
560
|
-
<div className="
|
|
560
|
+
<div className="px-3 py-2">
|
|
561
561
|
<OrgSwitcher />
|
|
562
562
|
</div>
|
|
563
563
|
|
|
564
|
-
<div className="
|
|
564
|
+
<div className="px-3 py-2">
|
|
565
565
|
<DevDatabaseLink />
|
|
566
566
|
<FeedbackButton />
|
|
567
567
|
</div>
|
|
@@ -20,11 +20,24 @@ import {
|
|
|
20
20
|
} from "@/components/ui/sheet";
|
|
21
21
|
import { TAB_ID } from "@/lib/tab-id";
|
|
22
22
|
|
|
23
|
+
const SIDEBAR_COLLAPSE_KEY = "brain.sidebar.collapsed";
|
|
24
|
+
|
|
25
|
+
function readSidebarCollapsed() {
|
|
26
|
+
if (typeof window === "undefined") return false;
|
|
27
|
+
try {
|
|
28
|
+
return window.localStorage.getItem(SIDEBAR_COLLAPSE_KEY) === "1";
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
export function Layout({ children }: { children: React.ReactNode }) {
|
|
24
35
|
const location = useLocation();
|
|
25
36
|
const navigate = useNavigate();
|
|
26
37
|
const t = useT();
|
|
27
38
|
const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
|
|
39
|
+
const [sidebarCollapsed, setSidebarCollapsed] =
|
|
40
|
+
useState(readSidebarCollapsed);
|
|
28
41
|
const isAskRoute = location.pathname === "/";
|
|
29
42
|
const chatHomeHandoffActive = useAgentChatHomeHandoff({
|
|
30
43
|
storageKey: "brain",
|
|
@@ -37,10 +50,24 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
37
50
|
setMobileSidebarOpen(false);
|
|
38
51
|
}, [location.pathname]);
|
|
39
52
|
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
try {
|
|
55
|
+
window.localStorage.setItem(
|
|
56
|
+
SIDEBAR_COLLAPSE_KEY,
|
|
57
|
+
sidebarCollapsed ? "1" : "0",
|
|
58
|
+
);
|
|
59
|
+
} catch {
|
|
60
|
+
// Ignore storage failures; the in-memory preference still works.
|
|
61
|
+
}
|
|
62
|
+
}, [sidebarCollapsed]);
|
|
63
|
+
|
|
40
64
|
const sidebarFrame = (
|
|
41
65
|
<>
|
|
42
66
|
<div className="agent-layout-left-drawer hidden md:block">
|
|
43
|
-
<Sidebar
|
|
67
|
+
<Sidebar
|
|
68
|
+
collapsed={sidebarCollapsed}
|
|
69
|
+
onCollapsedChange={setSidebarCollapsed}
|
|
70
|
+
/>
|
|
44
71
|
</div>
|
|
45
72
|
<Sheet open={mobileSidebarOpen} onOpenChange={setMobileSidebarOpen}>
|
|
46
73
|
<SheetContent side="left" className="w-[min(18rem,88vw)] p-0">
|
|
@@ -50,7 +77,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
50
77
|
<SheetDescription className="sr-only">
|
|
51
78
|
{t("navigation.brainNavigationDescription")}
|
|
52
79
|
</SheetDescription>
|
|
53
|
-
<Sidebar />
|
|
80
|
+
<Sidebar collapsed={false} collapsible={false} />
|
|
54
81
|
</SheetContent>
|
|
55
82
|
</Sheet>
|
|
56
83
|
</>
|