@agent-native/core 0.86.0 → 0.86.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +9 -0
  3. package/corpus/core/package.json +2 -1
  4. package/corpus/core/src/client/AgentPanel.tsx +10 -0
  5. package/corpus/core/src/client/AssistantChat.tsx +91 -27
  6. package/corpus/core/src/client/ErrorBoundary.tsx +67 -12
  7. package/corpus/core/src/client/ErrorReportActions.tsx +69 -0
  8. package/corpus/core/src/client/FeedbackButton.tsx +8 -4
  9. package/corpus/core/src/client/db-admin/DbAdminPage.tsx +41 -13
  10. package/corpus/core/src/client/db-admin/SqlEditor.tsx +10 -3
  11. package/corpus/core/src/client/db-admin/TableEditor.tsx +12 -5
  12. package/corpus/core/src/client/db-admin/useAgentSync.ts +10 -3
  13. package/corpus/core/src/client/db-admin/useDbAdmin.ts +65 -16
  14. package/corpus/core/src/client/error-reporting.ts +100 -0
  15. package/corpus/core/src/client/index.ts +11 -0
  16. package/corpus/core/src/client/org/RequireActiveOrg.tsx +12 -0
  17. package/corpus/core/src/client/visual-style-controls.tsx +615 -2
  18. package/corpus/core/src/db-admin/index.ts +26 -0
  19. package/corpus/core/src/db-admin/operations.ts +87 -49
  20. package/corpus/core/src/localization/default-messages.ts +4 -0
  21. package/corpus/core/src/server/builder-design-systems.ts +328 -9
  22. package/corpus/core/src/server/index.ts +15 -0
  23. package/corpus/core/src/templates/default/app/root.tsx +47 -0
  24. package/corpus/templates/analytics/AGENTS.md +6 -4
  25. package/corpus/templates/analytics/actions/delete-db-admin-connection.ts +19 -0
  26. package/corpus/templates/analytics/actions/list-db-admin-connections.ts +18 -0
  27. package/corpus/templates/analytics/actions/navigate.ts +17 -3
  28. package/corpus/templates/analytics/actions/save-db-admin-connection.ts +33 -0
  29. package/corpus/templates/analytics/actions/view-screen.ts +11 -3
  30. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +11 -2
  31. package/corpus/templates/analytics/app/i18n/zh-TW.ts +23 -2
  32. package/corpus/templates/analytics/app/i18n-data.ts +230 -20
  33. package/corpus/templates/analytics/app/pages/Agents.tsx +398 -4
  34. package/corpus/templates/analytics/changelog/2026-07-03-connect-other-app-databases-from-analytics.md +6 -0
  35. package/corpus/templates/analytics/server/db/schema.ts +27 -0
  36. package/corpus/templates/analytics/server/lib/db-admin-connections.ts +458 -0
  37. package/corpus/templates/analytics/server/plugins/db.ts +35 -0
  38. package/corpus/templates/analytics/server/routes/[base]/_agent-native/analytics-db-admin/[...path].ts +1 -0
  39. package/corpus/templates/analytics/server/routes/_agent-native/analytics-db-admin/[...path].ts +160 -0
  40. package/corpus/templates/content/app/root.tsx +9 -0
  41. package/corpus/templates/content/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  42. package/corpus/templates/design/AGENTS.md +13 -7
  43. package/corpus/templates/design/actions/get-design-system.ts +21 -0
  44. package/corpus/templates/design/actions/index-design-system-with-builder.ts +14 -37
  45. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +3 -3
  46. package/corpus/templates/design/app/components/design/code-workbench/SideBar.tsx +70 -9
  47. package/corpus/templates/design/app/components/design/code-workbench/editor/EditorTabs.tsx +11 -2
  48. package/corpus/templates/design/app/components/design/code-workbench/editor/MonacoHost.tsx +1 -1
  49. package/corpus/templates/design/app/components/design/code-workbench/editor/StatusBar.tsx +1 -1
  50. package/corpus/templates/design/app/components/design/code-workbench/explorer/ExplorerView.tsx +8 -2
  51. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +7 -3
  52. package/corpus/templates/design/app/components/design/code-workbench/store.tsx +48 -0
  53. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +6 -0
  54. package/corpus/templates/design/app/i18n/zh-TW.ts +15 -14
  55. package/corpus/templates/design/app/i18n-data.ts +154 -142
  56. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +32 -14
  57. package/corpus/templates/design/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  58. package/corpus/templates/design/changelog/2026-07-03-the-code-editor-is-easier-to-use-with-top-sidebar-tabs-clear.md +6 -0
  59. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +16 -106
  60. package/corpus/templates/mail/app/root.tsx +60 -1
  61. package/corpus/templates/mail/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  62. package/corpus/templates/plan/app/i18n/ar-SA.ts +3 -0
  63. package/corpus/templates/plan/app/i18n/de-DE.ts +4 -0
  64. package/corpus/templates/plan/app/i18n/en-US.ts +4 -0
  65. package/corpus/templates/plan/app/i18n/es-ES.ts +4 -0
  66. package/corpus/templates/plan/app/i18n/fr-FR.ts +4 -0
  67. package/corpus/templates/plan/app/i18n/hi-IN.ts +3 -0
  68. package/corpus/templates/plan/app/i18n/ja-JP.ts +4 -0
  69. package/corpus/templates/plan/app/i18n/ko-KR.ts +4 -0
  70. package/corpus/templates/plan/app/i18n/pt-BR.ts +4 -0
  71. package/corpus/templates/plan/app/i18n/zh-CN.ts +3 -0
  72. package/corpus/templates/plan/app/i18n/zh-TW.ts +3 -0
  73. package/corpus/templates/plan/app/pages/PlansPage.tsx +74 -3
  74. package/corpus/templates/plan/changelog/2026-07-03-error-screens-now-include-a-feedback-button-with-debug-info.md +6 -0
  75. package/corpus/templates/slides/AGENTS.md +7 -3
  76. package/corpus/templates/slides/actions/get-design-system.ts +21 -0
  77. package/corpus/templates/slides/actions/import-file.ts +15 -7
  78. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +14 -37
  79. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +32 -8
  80. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +2 -2
  81. package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +2 -4
  82. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +163 -154
  83. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +19 -15
  84. package/corpus/templates/slides/app/components/editor/SpeakerNotesPanel.tsx +56 -6
  85. package/corpus/templates/slides/app/components/layout/Layout.tsx +6 -1
  86. package/corpus/templates/slides/app/i18n/ar-SA.ts +8 -7
  87. package/corpus/templates/slides/app/i18n/de-DE.ts +7 -8
  88. package/corpus/templates/slides/app/i18n/en-US.ts +8 -7
  89. package/corpus/templates/slides/app/i18n/es-ES.ts +7 -8
  90. package/corpus/templates/slides/app/i18n/fr-FR.ts +7 -8
  91. package/corpus/templates/slides/app/i18n/hi-IN.ts +8 -7
  92. package/corpus/templates/slides/app/i18n/ja-JP.ts +7 -8
  93. package/corpus/templates/slides/app/i18n/ko-KR.ts +7 -7
  94. package/corpus/templates/slides/app/i18n/pt-BR.ts +7 -8
  95. package/corpus/templates/slides/app/i18n/zh-CN.ts +8 -7
  96. package/corpus/templates/slides/app/i18n/zh-TW.ts +8 -7
  97. package/corpus/templates/slides/app/lib/canvas-zoom.ts +16 -1
  98. package/corpus/templates/slides/app/pages/DeckEditor.tsx +3 -3
  99. package/corpus/templates/slides/changelog/2026-07-03-design-system-setup-now-indexes-figma-code-and-design-md-sou.md +6 -0
  100. package/corpus/templates/slides/changelog/2026-07-03-slide-editing-now-keeps-thumbnails-speaker-notes-styling-and.md +6 -0
  101. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +16 -104
  102. package/dist/client/AgentPanel.d.ts.map +1 -1
  103. package/dist/client/AgentPanel.js +2 -1
  104. package/dist/client/AgentPanel.js.map +1 -1
  105. package/dist/client/AssistantChat.d.ts.map +1 -1
  106. package/dist/client/AssistantChat.js +77 -25
  107. package/dist/client/AssistantChat.js.map +1 -1
  108. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  109. package/dist/client/ErrorBoundary.js +37 -2
  110. package/dist/client/ErrorBoundary.js.map +1 -1
  111. package/dist/client/ErrorReportActions.d.ts +13 -0
  112. package/dist/client/ErrorReportActions.d.ts.map +1 -0
  113. package/dist/client/ErrorReportActions.js +14 -0
  114. package/dist/client/ErrorReportActions.js.map +1 -0
  115. package/dist/client/FeedbackButton.d.ts +3 -1
  116. package/dist/client/FeedbackButton.d.ts.map +1 -1
  117. package/dist/client/FeedbackButton.js +6 -5
  118. package/dist/client/FeedbackButton.js.map +1 -1
  119. package/dist/client/db-admin/DbAdminPage.d.ts +9 -1
  120. package/dist/client/db-admin/DbAdminPage.d.ts.map +1 -1
  121. package/dist/client/db-admin/DbAdminPage.js +17 -13
  122. package/dist/client/db-admin/DbAdminPage.js.map +1 -1
  123. package/dist/client/db-admin/SqlEditor.d.ts +3 -1
  124. package/dist/client/db-admin/SqlEditor.d.ts.map +1 -1
  125. package/dist/client/db-admin/SqlEditor.js +3 -3
  126. package/dist/client/db-admin/SqlEditor.js.map +1 -1
  127. package/dist/client/db-admin/TableEditor.d.ts +3 -1
  128. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  129. package/dist/client/db-admin/TableEditor.js +6 -6
  130. package/dist/client/db-admin/TableEditor.js.map +1 -1
  131. package/dist/client/db-admin/useAgentSync.d.ts +3 -2
  132. package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
  133. package/dist/client/db-admin/useAgentSync.js +8 -4
  134. package/dist/client/db-admin/useAgentSync.js.map +1 -1
  135. package/dist/client/db-admin/useDbAdmin.d.ts +11 -7
  136. package/dist/client/db-admin/useDbAdmin.d.ts.map +1 -1
  137. package/dist/client/db-admin/useDbAdmin.js +45 -20
  138. package/dist/client/db-admin/useDbAdmin.js.map +1 -1
  139. package/dist/client/error-reporting.d.ts +19 -0
  140. package/dist/client/error-reporting.d.ts.map +1 -0
  141. package/dist/client/error-reporting.js +71 -0
  142. package/dist/client/error-reporting.js.map +1 -0
  143. package/dist/client/index.d.ts +3 -1
  144. package/dist/client/index.d.ts.map +1 -1
  145. package/dist/client/index.js +3 -1
  146. package/dist/client/index.js.map +1 -1
  147. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
  148. package/dist/client/org/RequireActiveOrg.js +2 -1
  149. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  150. package/dist/client/visual-style-controls.d.ts +11 -0
  151. package/dist/client/visual-style-controls.d.ts.map +1 -1
  152. package/dist/client/visual-style-controls.js +350 -1
  153. package/dist/client/visual-style-controls.js.map +1 -1
  154. package/dist/collab/routes.d.ts +1 -1
  155. package/dist/collab/struct-routes.d.ts +1 -1
  156. package/dist/db-admin/index.d.ts +3 -0
  157. package/dist/db-admin/index.d.ts.map +1 -0
  158. package/dist/db-admin/index.js +2 -0
  159. package/dist/db-admin/index.js.map +1 -0
  160. package/dist/db-admin/operations.d.ts +26 -5
  161. package/dist/db-admin/operations.d.ts.map +1 -1
  162. package/dist/db-admin/operations.js +66 -55
  163. package/dist/db-admin/operations.js.map +1 -1
  164. package/dist/localization/default-messages.d.ts +3 -0
  165. package/dist/localization/default-messages.d.ts.map +1 -1
  166. package/dist/localization/default-messages.js +3 -0
  167. package/dist/localization/default-messages.js.map +1 -1
  168. package/dist/notifications/routes.d.ts +1 -1
  169. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  170. package/dist/resources/handlers.d.ts +1 -1
  171. package/dist/secrets/routes.d.ts +9 -9
  172. package/dist/server/builder-design-systems.d.ts +61 -0
  173. package/dist/server/builder-design-systems.d.ts.map +1 -1
  174. package/dist/server/builder-design-systems.js +219 -14
  175. package/dist/server/builder-design-systems.js.map +1 -1
  176. package/dist/server/index.d.ts +1 -1
  177. package/dist/server/index.d.ts.map +1 -1
  178. package/dist/server/index.js +1 -1
  179. package/dist/server/index.js.map +1 -1
  180. package/dist/server/transcribe-voice.d.ts +1 -1
  181. package/dist/templates/default/app/root.tsx +47 -0
  182. package/package.json +2 -1
  183. package/src/templates/default/app/root.tsx +47 -0
@@ -796,10 +796,16 @@ export default function SlideEditor({
796
796
  const horizontalPadding =
797
797
  (parseFloat(trackStyle?.paddingLeft ?? "0") || 0) +
798
798
  (parseFloat(trackStyle?.paddingRight ?? "0") || 0);
799
+ const verticalPadding =
800
+ (parseFloat(trackStyle?.paddingTop ?? "0") || 0) +
801
+ (parseFloat(trackStyle?.paddingBottom ?? "0") || 0);
799
802
  const nextFitZoom = computeCanvasFitZoom({
800
803
  viewportWidth: scrollContainer.clientWidth,
804
+ viewportHeight: scrollContainer.clientHeight,
801
805
  canvasWidth: dims.width,
806
+ canvasHeight: dims.height,
802
807
  horizontalPadding,
808
+ verticalPadding,
803
809
  });
804
810
 
805
811
  setFitCanvasZoom(nextFitZoom);
@@ -1791,162 +1797,179 @@ export default function SlideEditor({
1791
1797
 
1792
1798
  return (
1793
1799
  <div
1794
- className="relative flex-1 flex flex-col h-full overflow-hidden"
1800
+ className="relative flex h-full min-h-0 flex-1 flex-col overflow-hidden"
1795
1801
  data-slide-element-selected={slideElementSelected ? "true" : undefined}
1796
1802
  >
1797
- <div className="flex-1 overflow-hidden">
1798
- {slide.excalidrawData ? (
1799
- <div className="h-full bg-background">
1800
- <ExcalidrawSlide
1801
- initialData={slide.excalidrawData}
1802
- onChange={(data) => onUpdateSlide({ excalidrawData: data })}
1803
- />
1804
- </div>
1805
- ) : (
1806
- <div className="relative h-full bg-background">
1807
- <div className="absolute right-3 top-3 z-20 flex h-8 items-center gap-0.5 rounded-md border border-border bg-popover/95 px-1 shadow-lg backdrop-blur">
1808
- <Tooltip>
1809
- <TooltipTrigger asChild>
1810
- <Button
1811
- variant="ghost"
1812
- size="icon"
1813
- className="h-6 w-6 cursor-pointer"
1814
- onClick={canvasZoomOut}
1815
- disabled={canvasZoom <= MIN_CANVAS_ZOOM}
1816
- aria-label={t("raw.zoomOut")}
1817
- >
1818
- <IconZoomOut className="h-3.5 w-3.5" />
1819
- </Button>
1820
- </TooltipTrigger>
1821
- <TooltipContent>{t("raw.zoomOut")}</TooltipContent>
1822
- </Tooltip>
1823
- <span className="w-11 text-center text-xs tabular-nums text-muted-foreground">
1824
- {canvasZoom}%
1825
- </span>
1826
- <Tooltip>
1827
- <TooltipTrigger asChild>
1828
- <Button
1829
- variant="ghost"
1830
- size="icon"
1831
- className="h-6 w-6 cursor-pointer"
1832
- onClick={canvasZoomIn}
1833
- disabled={
1834
- canvasZoom >=
1835
- CANVAS_ZOOM_PRESETS[CANVAS_ZOOM_PRESETS.length - 1]
1836
- }
1837
- aria-label={t("raw.zoomIn")}
1838
- >
1839
- <IconZoomIn className="h-3.5 w-3.5" />
1840
- </Button>
1841
- </TooltipTrigger>
1842
- <TooltipContent>{t("raw.zoomIn")}</TooltipContent>
1843
- </Tooltip>
1844
- <div className="mx-0.5 h-4 w-px bg-border" />
1845
- <Tooltip>
1846
- <TooltipTrigger asChild>
1847
- <Button
1848
- variant="ghost"
1849
- size="icon"
1850
- className="h-6 w-6 cursor-pointer"
1851
- onClick={fitCanvasToScreen}
1852
- aria-label={t("raw.fitSlideToScreen")}
1853
- >
1854
- <IconMaximize className="h-3.5 w-3.5" />
1855
- </Button>
1856
- </TooltipTrigger>
1857
- <TooltipContent>{t("raw.fitToScreen")}</TooltipContent>
1858
- </Tooltip>
1803
+ <div className="flex min-h-0 flex-1 overflow-hidden">
1804
+ <div className="min-w-0 flex-1 overflow-hidden">
1805
+ {slide.excalidrawData ? (
1806
+ <div className="h-full bg-background">
1807
+ <ExcalidrawSlide
1808
+ initialData={slide.excalidrawData}
1809
+ onChange={(data) => onUpdateSlide({ excalidrawData: data })}
1810
+ />
1859
1811
  </div>
1860
- <div
1861
- ref={scrollContainerRef}
1862
- className={`h-full overflow-auto ${
1863
- drawMode ? "pb-24 sm:pb-28" : ""
1864
- }`}
1865
- >
1812
+ ) : (
1813
+ <div className="relative h-full bg-background">
1814
+ <div className="absolute right-3 top-3 z-20 flex h-8 items-center gap-0.5 rounded-md border border-border bg-popover/95 px-1 shadow-lg backdrop-blur">
1815
+ <Tooltip>
1816
+ <TooltipTrigger asChild>
1817
+ <Button
1818
+ variant="ghost"
1819
+ size="icon"
1820
+ className="h-6 w-6 cursor-pointer"
1821
+ onClick={canvasZoomOut}
1822
+ disabled={canvasZoom <= MIN_CANVAS_ZOOM}
1823
+ aria-label={t("raw.zoomOut")}
1824
+ >
1825
+ <IconZoomOut className="h-3.5 w-3.5" />
1826
+ </Button>
1827
+ </TooltipTrigger>
1828
+ <TooltipContent>{t("raw.zoomOut")}</TooltipContent>
1829
+ </Tooltip>
1830
+ <span className="w-11 text-center text-xs tabular-nums text-muted-foreground">
1831
+ {canvasZoom}%
1832
+ </span>
1833
+ <Tooltip>
1834
+ <TooltipTrigger asChild>
1835
+ <Button
1836
+ variant="ghost"
1837
+ size="icon"
1838
+ className="h-6 w-6 cursor-pointer"
1839
+ onClick={canvasZoomIn}
1840
+ disabled={
1841
+ canvasZoom >=
1842
+ CANVAS_ZOOM_PRESETS[CANVAS_ZOOM_PRESETS.length - 1]
1843
+ }
1844
+ aria-label={t("raw.zoomIn")}
1845
+ >
1846
+ <IconZoomIn className="h-3.5 w-3.5" />
1847
+ </Button>
1848
+ </TooltipTrigger>
1849
+ <TooltipContent>{t("raw.zoomIn")}</TooltipContent>
1850
+ </Tooltip>
1851
+ <div className="mx-0.5 h-4 w-px bg-border" />
1852
+ <Tooltip>
1853
+ <TooltipTrigger asChild>
1854
+ <Button
1855
+ variant="ghost"
1856
+ size="icon"
1857
+ className="h-6 w-6 cursor-pointer"
1858
+ onClick={fitCanvasToScreen}
1859
+ aria-label={t("raw.fitSlideToScreen")}
1860
+ >
1861
+ <IconMaximize className="h-3.5 w-3.5" />
1862
+ </Button>
1863
+ </TooltipTrigger>
1864
+ <TooltipContent>{t("raw.fitToScreen")}</TooltipContent>
1865
+ </Tooltip>
1866
+ </div>
1866
1867
  <div
1867
- ref={canvasTrackRef}
1868
- className="flex min-h-full w-max min-w-full items-center justify-center p-2 pt-14 sm:p-4 sm:pt-14 md:p-8 md:pt-16"
1868
+ ref={scrollContainerRef}
1869
+ className={`h-full overflow-auto ${
1870
+ drawMode ? "pb-24 sm:pb-28" : ""
1871
+ }`}
1869
1872
  >
1870
1873
  <div
1871
- ref={containerRef}
1872
- data-main-slide-canvas="true"
1873
- className="shrink-0"
1874
- style={{ width: canvasWidth, maxWidth: canvasWidth }}
1874
+ ref={canvasTrackRef}
1875
+ className="flex min-h-full w-max min-w-full items-center justify-center p-2 pt-14 sm:p-4 sm:pt-14 md:p-8 md:pt-16"
1875
1876
  >
1876
1877
  <div
1877
- ref={slideCanvasRef}
1878
- className="slide-image-clickable relative"
1879
- data-editable={!readOnly ? "true" : undefined}
1880
- onClick={handleSlideClick}
1881
- onContextMenu={handleSlideContextMenu}
1882
- onDoubleClick={handleSlideDoubleClick}
1883
- onPointerDown={handleSlidePointerDown}
1884
- onDragOver={handleSlideDragOver}
1885
- onDrop={handleSlideDrop}
1886
- onMouseEnter={() => setIsHoveringText(true)}
1887
- onMouseLeave={() => setIsHoveringText(false)}
1878
+ ref={containerRef}
1879
+ data-main-slide-canvas="true"
1880
+ className="shrink-0"
1881
+ style={{ width: canvasWidth, maxWidth: canvasWidth }}
1888
1882
  >
1889
- <SlideRenderer
1890
- slide={slide}
1891
- className={`shadow-2xl shadow-black/40 ${isHoveringText ? "ring-2 ring-[#609FF8]/60" : ""}`}
1892
- designSystem={designSystem}
1893
- aspectRatio={aspectRatio}
1894
- onOverflowChange={handleOverflowChange}
1895
- />
1896
- {/* Fading "AI edited" ring around the canvas when the
1897
- agent just edited THIS slide (component handles fade). */}
1898
- {activeSlideEdits.length > 0 && (
1899
- <RecentEditHighlights
1900
- edits={activeSlideEdits}
1901
- resolveRect={resolveCanvasRect}
1902
- containerRef={slideCanvasRef}
1883
+ <div
1884
+ ref={slideCanvasRef}
1885
+ className="slide-image-clickable relative"
1886
+ data-editable={!readOnly ? "true" : undefined}
1887
+ onClick={handleSlideClick}
1888
+ onContextMenu={handleSlideContextMenu}
1889
+ onDoubleClick={handleSlideDoubleClick}
1890
+ onPointerDown={handleSlidePointerDown}
1891
+ onDragOver={handleSlideDragOver}
1892
+ onDrop={handleSlideDrop}
1893
+ onMouseEnter={() => setIsHoveringText(true)}
1894
+ onMouseLeave={() => setIsHoveringText(false)}
1895
+ >
1896
+ <SlideRenderer
1897
+ slide={slide}
1898
+ className={`shadow-2xl shadow-black/40 ${isHoveringText ? "ring-2 ring-[#609FF8]/60" : ""}`}
1899
+ designSystem={designSystem}
1900
+ aspectRatio={aspectRatio}
1901
+ onOverflowChange={handleOverflowChange}
1903
1902
  />
1904
- )}
1905
- {/* Double-click hint only shown for HTML slides that support inline editing */}
1906
- {isHoveringText && !editingEl && isHtmlSlide && (
1907
- <div className="absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/60 px-2 py-0.5 text-xs text-white/40 pointer-events-none select-none">
1908
- {t("raw.doubleClickEdit")}
1909
- </div>
1910
- )}
1911
- {agentActive && (
1912
- <div className="absolute top-2 right-2 z-10 pointer-events-none">
1913
- <AgentPresenceChip active={agentActive} />
1914
- </div>
1915
- )}
1916
- {presentUsers.length > 0 && (
1917
- <div
1918
- className={`absolute right-2 z-10 ${
1919
- agentActive ? "top-11" : "top-2"
1920
- }`}
1921
- >
1922
- <SameSlidePresenceIndicator users={presentUsers} />
1923
- </div>
1924
- )}
1925
- {overflowInfo && !readOnly && !agentActive && (
1926
- <div className="absolute top-3 left-3 z-20 flex items-center gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 backdrop-blur px-2.5 py-1.5 text-xs text-amber-100 shadow-lg">
1927
- <IconAlertTriangle
1928
- className="h-3.5 w-3.5 flex-shrink-0"
1929
- stroke={2}
1903
+ {/* Fading "AI edited" ring around the canvas when the
1904
+ agent just edited THIS slide (component handles fade). */}
1905
+ {activeSlideEdits.length > 0 && (
1906
+ <RecentEditHighlights
1907
+ edits={activeSlideEdits}
1908
+ resolveRect={resolveCanvasRect}
1909
+ containerRef={slideCanvasRef}
1930
1910
  />
1931
- <span className="leading-tight">
1932
- Layout overflows by {overflowInfo.verticalOverflow}
1933
- px
1934
- </span>
1935
- <Button
1936
- size="sm"
1937
- variant="ghost"
1938
- className="ml-1 h-6 cursor-pointer px-2 text-[11px] font-medium text-amber-100 hover:bg-amber-500/20 hover:text-white"
1939
- onClick={handleAskAgentToFixLayout}
1940
- disabled={isAskingAgentToFix}
1911
+ )}
1912
+ {/* Double-click hint — only shown for HTML slides that support inline editing */}
1913
+ {isHoveringText && !editingEl && isHtmlSlide && (
1914
+ <div className="absolute bottom-2 left-1/2 -translate-x-1/2 rounded bg-black/60 px-2 py-0.5 text-xs text-white/40 pointer-events-none select-none">
1915
+ {t("raw.doubleClickEdit")}
1916
+ </div>
1917
+ )}
1918
+ {agentActive && (
1919
+ <div className="absolute top-2 right-2 z-10 pointer-events-none">
1920
+ <AgentPresenceChip active={agentActive} />
1921
+ </div>
1922
+ )}
1923
+ {presentUsers.length > 0 && (
1924
+ <div
1925
+ className={`absolute right-2 z-10 ${
1926
+ agentActive ? "top-11" : "top-2"
1927
+ }`}
1941
1928
  >
1942
- {isAskingAgentToFix ? "Asking…" : "Fix with AI"}
1943
- </Button>
1944
- </div>
1945
- )}
1929
+ <SameSlidePresenceIndicator users={presentUsers} />
1930
+ </div>
1931
+ )}
1932
+ {overflowInfo && !readOnly && !agentActive && (
1933
+ <div className="absolute top-3 left-3 z-20 flex items-center gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 backdrop-blur px-2.5 py-1.5 text-xs text-amber-100 shadow-lg">
1934
+ <IconAlertTriangle
1935
+ className="h-3.5 w-3.5 flex-shrink-0"
1936
+ stroke={2}
1937
+ />
1938
+ <span className="leading-tight">
1939
+ Layout overflows by {overflowInfo.verticalOverflow}
1940
+ px
1941
+ </span>
1942
+ <Button
1943
+ size="sm"
1944
+ variant="ghost"
1945
+ className="ml-1 h-6 cursor-pointer px-2 text-[11px] font-medium text-amber-100 hover:bg-amber-500/20 hover:text-white"
1946
+ onClick={handleAskAgentToFixLayout}
1947
+ disabled={isAskingAgentToFix}
1948
+ >
1949
+ {isAskingAgentToFix ? "Asking…" : "Fix with AI"}
1950
+ </Button>
1951
+ </div>
1952
+ )}
1953
+ </div>
1946
1954
  </div>
1947
1955
  </div>
1948
1956
  </div>
1949
1957
  </div>
1958
+ )}
1959
+ </div>
1960
+
1961
+ {selectedStyleSnapshot && !readOnly && (
1962
+ <div className="hidden h-full w-[17rem] shrink-0 border-l border-border/70 bg-background/95 lg:block">
1963
+ <SlideStyleInspector
1964
+ snapshot={selectedStyleSnapshot}
1965
+ designSystem={designSystem}
1966
+ className="h-full w-full rounded-none border-0 bg-transparent shadow-none"
1967
+ onChange={applySelectedStylePatch}
1968
+ onClose={() => {
1969
+ clearSelectedElement();
1970
+ syncSelectionToAppState(null);
1971
+ }}
1972
+ />
1950
1973
  </div>
1951
1974
  )}
1952
1975
  </div>
@@ -1963,20 +1986,6 @@ export default function SlideEditor({
1963
1986
  <ElementSelectionOutline rect={selectedElementRect} />
1964
1987
  )}
1965
1988
 
1966
- {selectedStyleSnapshot && !readOnly && (
1967
- <div className="pointer-events-none absolute right-3 top-14 z-[80] hidden md:block">
1968
- <SlideStyleInspector
1969
- snapshot={selectedStyleSnapshot}
1970
- designSystem={designSystem}
1971
- onChange={applySelectedStylePatch}
1972
- onClose={() => {
1973
- clearSelectedElement();
1974
- syncSelectionToAppState(null);
1975
- }}
1976
- />
1977
- </div>
1978
- )}
1979
-
1980
1989
  {/* Multi-select outlines */}
1981
1990
  {Array.from(multiSelectionRects.entries()).map(([id, v]) => (
1982
1991
  <MultiSelectOutline key={id} rect={v.rect} />
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  useT,
3
+ VisualColorPicker,
3
4
  VisualControlRow,
4
5
  VisualInspectorPanel,
5
6
  VisualInspectorSection,
6
7
  VisualScrubInput,
7
8
  VisualSegmentedControl,
8
- VisualSwatchControl,
9
9
  } from "@agent-native/core/client";
10
10
  import type { DesignSystemData } from "@shared/api";
11
11
  import {
@@ -125,16 +125,19 @@ function tokenPalette(
125
125
  export function SlideStyleInspector({
126
126
  snapshot,
127
127
  designSystem,
128
+ className,
128
129
  onChange,
129
130
  onClose,
130
131
  }: {
131
132
  snapshot: SlideStyleSnapshot;
132
133
  designSystem?: DesignSystemData;
134
+ className?: string;
133
135
  onChange: (patch: SlideStylePatch) => void;
134
136
  onClose: () => void;
135
137
  }) {
136
138
  const t = useT();
137
139
  const palette = tokenPalette(designSystem, t);
140
+ const documentColors = palette.map((option) => option.value);
138
141
  const targetLabel =
139
142
  snapshot.textPreview || snapshot.label || snapshot.tagName.toUpperCase();
140
143
 
@@ -142,7 +145,7 @@ export function SlideStyleInspector({
142
145
  <VisualInspectorPanel
143
146
  title={t("styleInspector.title")}
144
147
  subtitle={targetLabel}
145
- className="pointer-events-auto"
148
+ className={className}
146
149
  headerAction={
147
150
  <Button
148
151
  type="button"
@@ -166,9 +169,10 @@ export function SlideStyleInspector({
166
169
  }
167
170
  >
168
171
  <VisualControlRow label={t("styleInspector.color")}>
169
- <VisualSwatchControl
170
- options={palette}
172
+ <VisualColorPicker
173
+ label={t("styleInspector.color")}
171
174
  value={snapshot.color}
175
+ documentColors={documentColors}
172
176
  onChange={(value) => onChange({ color: value })}
173
177
  />
174
178
  </VisualControlRow>
@@ -235,16 +239,15 @@ export function SlideStyleInspector({
235
239
  : t("styleInspector.fill")
236
240
  }
237
241
  >
238
- <VisualSwatchControl
239
- options={[
240
- {
241
- label: t("styleInspector.transparent"),
242
- value: "transparent",
243
- color: "transparent",
244
- },
245
- ...palette,
246
- ]}
242
+ <VisualColorPicker
243
+ label={
244
+ snapshot.isImage
245
+ ? t("styleInspector.tint")
246
+ : t("styleInspector.fill")
247
+ }
247
248
  value={snapshot.backgroundColor}
249
+ documentColors={documentColors}
250
+ allowTransparent
248
251
  onChange={(value) => onChange({ backgroundColor: value })}
249
252
  />
250
253
  </VisualControlRow>
@@ -288,9 +291,10 @@ export function SlideStyleInspector({
288
291
  />
289
292
  </div>
290
293
  <VisualControlRow label={t("styleInspector.strokeColor")}>
291
- <VisualSwatchControl
292
- options={palette}
294
+ <VisualColorPicker
295
+ label={t("styleInspector.strokeColor")}
293
296
  value={snapshot.borderColor}
297
+ documentColors={documentColors}
294
298
  onChange={(value) => onChange({ borderColor: value })}
295
299
  />
296
300
  </VisualControlRow>
@@ -1,6 +1,6 @@
1
1
  import { useT } from "@agent-native/core/client";
2
- import { IconChevronUp, IconChevronDown } from "@tabler/icons-react";
3
- import { useState } from "react";
2
+ import { IconChevronDown, IconChevronUp } from "@tabler/icons-react";
3
+ import { useState, type PointerEvent as ReactPointerEvent } from "react";
4
4
 
5
5
  interface SpeakerNotesPanelProps {
6
6
  notes: string;
@@ -9,6 +9,14 @@ interface SpeakerNotesPanelProps {
9
9
  slideCount: number;
10
10
  }
11
11
 
12
+ const MIN_NOTES_HEIGHT = 72;
13
+ const MAX_NOTES_HEIGHT = 260;
14
+ const DEFAULT_NOTES_HEIGHT = 112;
15
+
16
+ function clampNotesHeight(value: number) {
17
+ return Math.min(MAX_NOTES_HEIGHT, Math.max(MIN_NOTES_HEIGHT, value));
18
+ }
19
+
12
20
  export function SpeakerNotesPanel({
13
21
  notes,
14
22
  onChange,
@@ -23,6 +31,16 @@ export function SpeakerNotesPanel({
23
31
  return true;
24
32
  }
25
33
  });
34
+ const [height, setHeight] = useState(() => {
35
+ try {
36
+ const stored = Number(localStorage.getItem("speaker-notes-height"));
37
+ return Number.isFinite(stored)
38
+ ? clampNotesHeight(stored)
39
+ : DEFAULT_NOTES_HEIGHT;
40
+ } catch {
41
+ return DEFAULT_NOTES_HEIGHT;
42
+ }
43
+ });
26
44
 
27
45
  const toggle = () => {
28
46
  const next = !expanded;
@@ -32,11 +50,43 @@ export function SpeakerNotesPanel({
32
50
  } catch {}
33
51
  };
34
52
 
53
+ const startResize = (event: ReactPointerEvent<HTMLDivElement>) => {
54
+ if (!expanded) return;
55
+ event.preventDefault();
56
+ const startY = event.clientY;
57
+ const startHeight = height;
58
+ let latestHeight = startHeight;
59
+ const onMove = (moveEvent: PointerEvent) => {
60
+ latestHeight = clampNotesHeight(startHeight + startY - moveEvent.clientY);
61
+ setHeight(latestHeight);
62
+ };
63
+ const onUp = () => {
64
+ window.removeEventListener("pointermove", onMove);
65
+ window.removeEventListener("pointerup", onUp);
66
+ try {
67
+ localStorage.setItem("speaker-notes-height", String(latestHeight));
68
+ } catch {}
69
+ };
70
+ window.addEventListener("pointermove", onMove);
71
+ window.addEventListener("pointerup", onUp, { once: true });
72
+ };
73
+
35
74
  return (
36
- <div className="border-t border-border bg-background flex-shrink-0">
75
+ <div className="flex-shrink-0 border-t border-border bg-background">
76
+ {expanded && (
77
+ <div
78
+ role="separator"
79
+ aria-orientation="horizontal"
80
+ aria-label={t("raw.speakerNotes")}
81
+ className="group flex h-2 cursor-row-resize items-center justify-center"
82
+ onPointerDown={startResize}
83
+ >
84
+ <div className="h-px w-10 rounded-full bg-border transition-colors group-hover:bg-muted-foreground/70" />
85
+ </div>
86
+ )}
37
87
  <button
38
88
  onClick={toggle}
39
- className="w-full flex items-center justify-between px-4 py-1.5 cursor-pointer"
89
+ className="flex w-full cursor-pointer items-center justify-between px-4 py-1.5"
40
90
  >
41
91
  <span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">
42
92
  {t("raw.speakerNotesForSlide", {
@@ -51,12 +101,12 @@ export function SpeakerNotesPanel({
51
101
  )}
52
102
  </button>
53
103
  {expanded && (
54
- <div className="px-4 pb-3">
104
+ <div className="px-4 pb-3" style={{ height }}>
55
105
  <textarea
56
106
  value={notes || ""}
57
107
  onChange={(e) => onChange(e.target.value)}
58
108
  placeholder={t("raw.addSpeakerNotes")}
59
- className="w-full h-20 bg-transparent text-muted-foreground text-xs font-mono placeholder:text-muted-foreground/70 resize-none outline-none"
109
+ className="h-full w-full resize-none bg-transparent font-mono text-xs text-muted-foreground outline-none placeholder:text-muted-foreground/70"
60
110
  />
61
111
  </div>
62
112
  )}
@@ -121,7 +121,12 @@ export function Layout({ children }: LayoutProps) {
121
121
  )}
122
122
  {!ownToolbar && <Header />}
123
123
  <InvitationBanner />
124
- <main className="agent-native-app-main min-h-0 flex-1 overflow-y-auto">
124
+ <main
125
+ className={cn(
126
+ "agent-native-app-main min-h-0 flex-1",
127
+ ownToolbar ? "overflow-hidden" : "overflow-y-auto",
128
+ )}
129
+ >
125
130
  {children}
126
131
  </main>
127
132
  </div>
@@ -516,12 +516,12 @@ const messages = {
516
516
  newTitle: "نظام تصميم جديد",
517
517
  editDescription: "حدّث هوية علامتك التجارية.",
518
518
  newDescription:
519
- "قدّم أي مزيج من المصادر؛ كلما زاد السياق كانت النتيجة أفضل.",
519
+ "اربط Figma والكود وإرشادات design.md الاختيارية عبر Builder DSI.",
520
520
  companyBrand: "الشركة / العلامة",
521
521
  companyBrandPlaceholder: "Acme Inc. — نبني أدوات للمطورين...",
522
- figmaFile: "ملف Figma",
523
- parsingFigmaFile: "جارٍ بدء فهرسة Builder...",
524
- uploadFigDescription: "حمّل نسخة .fig محلية لفهرستها باستخدام Builder",
522
+ figmaFile: "ربط Figma",
523
+ parsingFigmaFile: "جارٍ بدء فهرسة Builder DSI...",
524
+ uploadFigDescription: "حمّل نسخة .fig محلية إلى Builder DSI",
525
525
  builderIndexingStarted: "بدأت فهرسة Builder",
526
526
  builderIndexingDescription:
527
527
  "Builder is indexing {{title}} into a reusable design system.",
@@ -531,9 +531,10 @@ const messages = {
531
531
  websiteUrl: "رابط الموقع",
532
532
  websitePlaceholder: "example.com أو Nike",
533
533
  add: "إضافة",
534
- githubRepository: "مستودع GitHub",
535
- codeFiles: "ملفات الكود",
536
- codeFilesDrop: "CSS، إعدادات Tailwind، ملفات السمة — اسحبها أو انقر",
534
+ githubRepository: "ربط الكود: مستودع GitHub",
535
+ codeFiles: "ربط ملفات الكود",
536
+ codeFilesDrop:
537
+ "CSS، إعدادات Tailwind، ملفات السمة، design.md — اسحبها أو انقر",
537
538
  documents: "المستندات والعروض",
538
539
  documentsDrop:
539
540
  "PPTX وDOCX وPDF وMarkdown وTXT — أدلة العلامة ومستندات التصميم",
@@ -509,14 +509,13 @@ const messages = {
509
509
  newTitle: "Neues Designsystem",
510
510
  editDescription: "Aktualisiere deine Markenidentität.",
511
511
  newDescription:
512
- "Gib eine beliebige Kombination von Quellen an; je mehr Kontext, desto besser das Ergebnis.",
512
+ "Verbinde Figma, Code und optionale design.md-Anweisungen über Builder DSI.",
513
513
  companyBrand: "Unternehmen / Marke",
514
514
  companyBrandPlaceholder:
515
515
  "Acme Inc. — Wir entwickeln Tools für Entwickler...",
516
- figmaFile: "Figma-Datei",
517
- parsingFigmaFile: "Builder-Indizierung wird gestartet...",
518
- uploadFigDescription:
519
- "Lade eine lokale .fig-Kopie hoch, um sie mit Builder zu indizieren",
516
+ figmaFile: "Figma verbinden",
517
+ parsingFigmaFile: "Builder-DSI-Indizierung wird gestartet...",
518
+ uploadFigDescription: "Lade eine lokale .fig-Kopie für Builder DSI hoch",
520
519
  builderIndexingStarted: "Builder-Indizierung gestartet",
521
520
  builderIndexingDescription:
522
521
  "Builder is indexing {{title}} into a reusable design system.",
@@ -526,10 +525,10 @@ const messages = {
526
525
  websiteUrl: "Website-URL",
527
526
  websitePlaceholder: "example.com oder Nike",
528
527
  add: "Hinzufügen",
529
- githubRepository: "GitHub-Repository",
530
- codeFiles: "Code-Dateien",
528
+ githubRepository: "Code verbinden: GitHub-Repository",
529
+ codeFiles: "Code-Dateien verbinden",
531
530
  codeFilesDrop:
532
- "CSS, Tailwind-Konfiguration, Theme-Dateien — ablegen oder klicken",
531
+ "CSS, Tailwind-Konfiguration, Theme-Dateien, design.md — ablegen oder klicken",
533
532
  documents: "Dokumente und Präsentationen",
534
533
  documentsDrop:
535
534
  "PPTX, DOCX, PDF, Markdown, TXT — Markenleitfäden, Designdokumente",