camox 0.44.0 → 0.46.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.
Files changed (407) hide show
  1. package/dist/components/AuthGate.js +0 -6
  2. package/dist/components/DeviceSelector.js +96 -0
  3. package/dist/components/PlatformLabel.js +20 -24
  4. package/dist/core/components/lexical/HighlightNode.js +1 -1
  5. package/dist/core/components/lexical/InlineContentEditable.js +15 -19
  6. package/dist/core/components/lexical/InlineLexicalEditor.js +54 -74
  7. package/dist/core/components/lexical/InlineStylesPlugin.js +53 -53
  8. package/dist/core/components/lexical/MaxLengthPlugin.js +59 -0
  9. package/dist/core/components/lexical/SelectionBroadcaster.js +53 -54
  10. package/dist/core/components/lexical/SidebarLexicalEditor.js +322 -229
  11. package/dist/core/components/lexical/SummaryToggleGuard.js +42 -0
  12. package/dist/core/components/lexical/TextLinkPopover.js +169 -180
  13. package/dist/core/createApp.d.ts +241 -312
  14. package/dist/core/createApp.js +123 -29
  15. package/dist/core/createBlock.d.ts +5 -5
  16. package/dist/core/createBlock.js +385 -152
  17. package/dist/core/createCollection.d.ts +55 -0
  18. package/dist/core/createCollection.js +93 -0
  19. package/dist/core/createLayout.d.ts +197 -61
  20. package/dist/core/createLayout.js +114 -56
  21. package/dist/core/defineDocument.d.ts +3 -5
  22. package/dist/core/derivedRoutes.js +49 -1
  23. package/dist/core/dom.d.ts +13 -4
  24. package/dist/core/dom.js +44 -1
  25. package/dist/core/editing/BlockEditingRuntime.d.ts +16 -0
  26. package/dist/core/editing/BlockEditingRuntime.js +6 -15
  27. package/dist/core/editing/CompleteBlockEditingRuntime.js +28 -23
  28. package/dist/core/editing/createEditableBlock.d.ts +754 -633
  29. package/dist/core/editing/createEditableBlock.js +2113 -1066
  30. package/dist/core/editing/referenceWrites.js +51 -0
  31. package/dist/core/editing/useLatestRecord.js +90 -0
  32. package/dist/core/hooks/useArtifactHost.js +139 -0
  33. package/dist/core/hooks/useFieldSelection.js +43 -18
  34. package/dist/core/hooks/useIsEditable.js +12 -10
  35. package/dist/core/hooks/useOverlayMessage.js +15 -19
  36. package/dist/core/lib/artifact.d.ts +21 -0
  37. package/dist/core/lib/artifact.js +154 -0
  38. package/dist/core/lib/artifactColors.js +123 -0
  39. package/dist/core/lib/artifactData.d.ts +1 -0
  40. package/dist/core/lib/artifactData.js +131 -0
  41. package/dist/core/lib/artifactHost.js +205 -0
  42. package/dist/core/lib/artifactRuntime.js +36 -0
  43. package/dist/core/lib/artifactTheme.js +57 -0
  44. package/dist/core/lib/contentType.d.ts +302 -106
  45. package/dist/core/lib/contentType.js +201 -173
  46. package/dist/core/lib/fieldTypes.js +3 -0
  47. package/dist/core/lib/iconTypes.d.ts +3 -3
  48. package/dist/core/lib/icons.d.ts +4 -4
  49. package/dist/core/lib/icons.js +40 -44
  50. package/dist/core/lib/imagePlaceholder.js +177 -0
  51. package/dist/core/lib/imageTransform.js +1 -1
  52. package/dist/core/lib/lexicalReact.d.ts +3 -1
  53. package/dist/core/lib/lexicalState.js +1 -1
  54. package/dist/core/lib/previewPaused.js +9 -0
  55. package/dist/core/lib/recordScope.js +316 -0
  56. package/dist/core/lib/reference.d.ts +81 -0
  57. package/dist/core/lib/reference.js +29 -0
  58. package/dist/core/lib/textLinks.js +7 -5
  59. package/dist/core/lib/textStyles.d.ts +5 -7
  60. package/dist/core/lib/textStyles.js +2 -2
  61. package/dist/core/notFound.d.ts +7 -0
  62. package/dist/core/notFound.js +11 -0
  63. package/dist/core/pageDestinations.js +6 -3
  64. package/dist/core/recordItem.js +34 -0
  65. package/dist/core/requestContext.d.ts +26 -0
  66. package/dist/core/requestContext.js +20 -0
  67. package/dist/features/canvas/CamoxCanvas.js +1401 -0
  68. package/dist/features/canvas/CanvasLoadingScreen.js +35 -0
  69. package/dist/features/canvas/CanvasOverlays.js +254 -0
  70. package/dist/features/canvas/CanvasPageEdge.js +87 -0
  71. package/dist/features/canvas/CanvasPageFrame.js +333 -0
  72. package/dist/features/canvas/CanvasPageHeader.js +125 -0
  73. package/dist/features/canvas/CanvasPreviewPageSlot.js +123 -0
  74. package/dist/features/canvas/DerivedPagePathInput.js +238 -0
  75. package/dist/features/canvas/canvasCamera.js +229 -0
  76. package/dist/features/canvas/canvasFlight.js +104 -0
  77. package/dist/features/canvas/canvasFrameCapture.js +364 -0
  78. package/dist/features/canvas/canvasFrameDocument.js +302 -0
  79. package/dist/features/canvas/canvasFrameMode.js +53 -0
  80. package/dist/features/canvas/canvasInsertionSeams.js +44 -0
  81. package/dist/features/canvas/canvasItems.js +30 -0
  82. package/dist/features/canvas/canvasOverlayGeometry.js +240 -0
  83. package/dist/features/canvas/canvasPages.js +79 -0
  84. package/dist/features/canvas/canvasScreenSpace.js +26 -0
  85. package/dist/features/canvas/canvasSelection.js +18 -0
  86. package/dist/features/canvas/canvasStore.js +60 -0
  87. package/dist/features/canvas/canvasThumbnails.js +304 -0
  88. package/dist/features/canvas/canvasZoom.js +10 -0
  89. package/dist/features/canvas/sidebar/CanvasInspector.js +202 -0
  90. package/dist/features/canvas/sidebar/CanvasNavigator.js +124 -0
  91. package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -0
  92. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +48 -0
  93. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +39 -0
  94. package/dist/features/canvas/sidebar/CuratedPageInspector.js +69 -0
  95. package/dist/features/canvas/sidebar/DerivedPageInspector.js +37 -0
  96. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +78 -0
  97. package/dist/features/canvas/sidebar/LayoutPageOverview.js +71 -0
  98. package/dist/features/canvas/sidebar/PageInspector.js +157 -0
  99. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +90 -0
  100. package/dist/features/canvas/sidebar/PageOverview.js +27 -0
  101. package/dist/features/canvas/sidebar/SingletonPageInspector.js +31 -0
  102. package/dist/features/canvas/useCanvasCamera.js +783 -0
  103. package/dist/features/canvas/useCanvasFrame.js +148 -0
  104. package/dist/features/canvas/useCanvasFrameInput.js +97 -0
  105. package/dist/features/canvas/useCanvasNearness.js +57 -0
  106. package/dist/features/canvas/useDiscoveredPreviewPaths.js +62 -0
  107. package/dist/features/content/CamoxContent.d.ts +2 -5
  108. package/dist/features/content/CamoxContent.js +174 -271
  109. package/dist/features/content/CollectionItemSheetContext.js +106 -0
  110. package/dist/features/content/ContentAssets.js +315 -0
  111. package/dist/features/content/ContentCollection.js +663 -0
  112. package/dist/features/content/collection-form.js +58 -0
  113. package/dist/features/content/components/AssetCard.js +80 -84
  114. package/dist/features/content/components/AssetCardSkeleton.js +4 -8
  115. package/dist/features/content/components/ContentSidebar.js +129 -18
  116. package/dist/features/content/components/ContentSidebarGroup.js +37 -0
  117. package/dist/features/content/components/DeleteCollectionItemButton.js +202 -0
  118. package/dist/features/content/components/MissingFromLocale.js +282 -0
  119. package/dist/features/content/components/UploadDropZone.js +27 -31
  120. package/dist/features/content/components/UploadProgressDrawer.js +90 -98
  121. package/dist/features/navigation/navigation.d.ts +66 -20
  122. package/dist/features/navigation/navigation.js +257 -90
  123. package/dist/features/og/defaultFonts.js +8 -8
  124. package/dist/features/og/geist-variable-ttf-base64.js +1 -1
  125. package/dist/features/og/imageResponse.d.ts +8 -0
  126. package/dist/features/og/imageResponse.js +26 -0
  127. package/dist/features/page/CuratedPageContent.js +167 -0
  128. package/dist/features/page/DerivedPageContent.js +26 -30
  129. package/dist/features/page/SharedLayoutContent.js +25 -27
  130. package/dist/features/preview/CamoxPreview.d.ts +23 -61
  131. package/dist/features/preview/CamoxPreview.js +816 -537
  132. package/dist/features/preview/EditablePageContent.js +1 -1
  133. package/dist/features/preview/EditablePageExperience.js +16 -22
  134. package/dist/features/preview/components/AddBlockSheet.js +273 -0
  135. package/dist/features/preview/components/AssetFieldEditor.js +173 -154
  136. package/dist/features/preview/components/AssetLightbox.js +181 -134
  137. package/dist/features/preview/components/AssetPickerModal.js +153 -170
  138. package/dist/features/preview/components/BlockActionsPopover.js +150 -149
  139. package/dist/features/preview/components/BlockErrorBoundary.js +8 -12
  140. package/dist/features/preview/components/BlockThumbnail.js +172 -98
  141. package/dist/features/preview/components/CanvasPreview.js +243 -0
  142. package/dist/features/preview/components/CreatePageModal.js +128 -137
  143. package/dist/features/preview/components/DebouncedFieldEditor.js +29 -33
  144. package/dist/features/preview/components/DerivedLayoutDialog.js +21 -19
  145. package/dist/features/preview/components/DrillRow.js +150 -0
  146. package/dist/features/preview/components/FieldOverlayStyles.js +11 -8
  147. package/dist/features/preview/components/FieldToolbar.js +160 -110
  148. package/dist/features/preview/components/Frame.js +108 -20
  149. package/dist/features/preview/components/IconFieldEditor.js +62 -66
  150. package/dist/features/preview/components/ItemFieldsEditor.js +231 -205
  151. package/dist/features/preview/components/LinkFieldEditor.js +135 -139
  152. package/dist/features/preview/components/Metadata.js +22 -30
  153. package/dist/features/preview/components/MobilePreviewDrawer.js +89 -108
  154. package/dist/features/preview/components/MultipleAssetFieldEditor.js +334 -246
  155. package/dist/features/preview/components/OverlayTracker.js +9 -41
  156. package/dist/features/preview/components/Overlays.js +81 -69
  157. package/dist/features/preview/components/PageInfo.js +1748 -0
  158. package/dist/features/preview/components/PageInfoSkeleton.js +51 -0
  159. package/dist/features/preview/components/PageLocationFieldset.js +112 -116
  160. package/dist/features/preview/components/PageNavigatorHeader.js +24 -0
  161. package/dist/features/preview/components/PageNicknameField.js +22 -26
  162. package/dist/features/preview/components/PagePicker.js +128 -130
  163. package/dist/features/preview/components/PageTree.js +525 -532
  164. package/dist/features/preview/components/PreviewActivation.js +28 -32
  165. package/dist/features/preview/components/PreviewPanel.js +620 -319
  166. package/dist/features/preview/components/PreviewToolbar.js +105 -333
  167. package/dist/features/preview/components/RecordCard.js +80 -0
  168. package/dist/features/preview/components/RecordCombobox.js +178 -0
  169. package/dist/features/preview/components/ReferenceFieldEditor.js +149 -0
  170. package/dist/features/preview/components/ReferenceListFieldEditor.js +432 -0
  171. package/dist/features/preview/components/RemovedBlockPlaceholder.js +95 -0
  172. package/dist/features/preview/components/RepeatableItemsList.js +125 -138
  173. package/dist/features/preview/components/SelectionEditor.js +993 -0
  174. package/dist/features/preview/components/ShikiMarkdown.js +14 -18
  175. package/dist/features/preview/components/SidebarSection.js +52 -64
  176. package/dist/features/preview/components/StudioEditingFallback.js +56 -0
  177. package/dist/features/preview/components/UnlinkAssetButton.js +104 -107
  178. package/dist/features/preview/components/blockGridNavigation.js +15 -0
  179. package/dist/features/preview/components/contentFieldSchema.js +8 -0
  180. package/dist/features/preview/components/useFieldWriter.js +200 -0
  181. package/dist/features/preview/components/useRecordView.js +383 -0
  182. package/dist/features/preview/components/useRepeatableItemActions.js +35 -37
  183. package/dist/features/preview/components/useUpdateBlockPosition.js +37 -37
  184. package/dist/features/preview/editingFrame.js +197 -0
  185. package/dist/features/preview/overlayHighlights.js +17 -44
  186. package/dist/features/preview/overlayMessages.js +72 -1
  187. package/dist/features/preview/pageRecord.js +189 -0
  188. package/dist/features/preview/previewConstants.js +6 -2
  189. package/dist/features/preview/previewPageFrame.js +95 -0
  190. package/dist/features/preview/previewPreparation.js +7 -0
  191. package/dist/features/preview/previewSelection.js +32 -63
  192. package/dist/features/preview/previewStore.js +225 -123
  193. package/dist/features/preview/referencePickerFocus.js +29 -0
  194. package/dist/features/preview/repeatableItemTargets.js +56 -0
  195. package/dist/features/preview/selectionReveal.js +21 -0
  196. package/dist/features/preview/usePreviewViewportActions.js +114 -0
  197. package/dist/features/preview/viewportContinuity.js +109 -0
  198. package/dist/features/provider/AuthenticatedCamoxProvider.js +69 -44
  199. package/dist/features/provider/CamoxProvider.d.ts +3 -6
  200. package/dist/features/provider/CamoxProvider.js +38 -50
  201. package/dist/features/provider/CoreCamoxProvider.js +69 -50
  202. package/dist/features/provider/LocalhostPreviewProvider.js +78 -114
  203. package/dist/features/provider/PreviewSignInPage.js +54 -0
  204. package/dist/features/provider/components/CamoxAppContext.js +11 -11
  205. package/dist/features/provider/components/CommandPalette.js +75 -82
  206. package/dist/features/provider/useAdminShortcuts.js +7 -11
  207. package/dist/features/routes/pageRuntime.d.ts +44 -4
  208. package/dist/features/routes/pageRuntime.js +244 -137
  209. package/dist/features/runtime/RuntimeChrome.js +117 -115
  210. package/dist/features/runtime/alternates.js +64 -0
  211. package/dist/features/runtime/analytics.d.ts +7 -0
  212. package/dist/features/runtime/analytics.js +66 -0
  213. package/dist/features/runtime/artifactSources.js +87 -0
  214. package/dist/features/runtime/editingFallback.js +20 -0
  215. package/dist/features/runtime/linkPrefetch.js +97 -0
  216. package/dist/features/runtime/livePages.js +62 -0
  217. package/dist/features/runtime/llmsTxt.js +40 -0
  218. package/dist/features/runtime/loopbackFetch.js +18 -0
  219. package/dist/features/runtime/navigationAccessibility.js +51 -0
  220. package/dist/features/runtime/navigationTarget.js +23 -2
  221. package/dist/features/runtime/pageApp.js +229 -158
  222. package/dist/features/runtime/pageBlockTypes.js +20 -0
  223. package/dist/features/runtime/pageClient.d.ts +2 -4
  224. package/dist/features/runtime/pageClient.js +18 -3
  225. package/dist/features/runtime/pageNavigation.js +254 -32
  226. package/dist/features/runtime/pageServer.d.ts +2 -4
  227. package/dist/features/runtime/pageServer.js +6 -2
  228. package/dist/features/runtime/pageViewport.js +7 -0
  229. package/dist/features/runtime/runtime.d.ts +54 -24
  230. package/dist/features/runtime/runtime.js +766 -191
  231. package/dist/features/runtime/runtimeChromeLoader.js +58 -0
  232. package/dist/features/runtime/runtimeRoutes.d.ts +19 -0
  233. package/dist/features/runtime/runtimeRoutes.js +25 -0
  234. package/dist/features/runtime/scrollRestoration.js +133 -0
  235. package/dist/features/runtime/studioApp.d.ts +4 -3
  236. package/dist/features/runtime/studioApp.js +5 -9
  237. package/dist/features/runtime/studioClient.d.ts +2 -4
  238. package/dist/features/runtime/studioClient.js +12 -3
  239. package/dist/features/runtime/studioServer.d.ts +2 -4
  240. package/dist/features/runtime/studioServer.js +6 -1
  241. package/dist/features/runtime/worker.d.ts +6 -0
  242. package/dist/features/runtime/worker.js +23 -0
  243. package/dist/features/runtime/workerRequest.js +44 -0
  244. package/dist/features/studio/CamoxStudio.d.ts +2 -6
  245. package/dist/features/studio/CamoxStudio.js +34 -49
  246. package/dist/features/studio/FollowAgentProvider.js +327 -0
  247. package/dist/features/studio/components/ChatSidebar.js +356 -0
  248. package/dist/features/studio/components/DraftsControl.js +676 -0
  249. package/dist/features/studio/components/FaviconDialog.js +318 -0
  250. package/dist/features/studio/components/LocalePicker.js +785 -0
  251. package/dist/features/studio/components/Navbar.js +123 -103
  252. package/dist/features/studio/components/ProjectMenu.js +239 -260
  253. package/dist/features/studio/components/RenameDraftDialog.js +206 -0
  254. package/dist/features/studio/components/ReviewDraftSheet.js +1472 -0
  255. package/dist/features/studio/components/ThreadComposer.js +157 -0
  256. package/dist/features/studio/components/ThreadMarkdown.js +113 -0
  257. package/dist/features/studio/components/ThreadMessages.js +270 -0
  258. package/dist/features/studio/components/UserButton.js +34 -23
  259. package/dist/features/studio/draftLabel.js +33 -0
  260. package/dist/features/studio/draftNotice.js +13 -0
  261. package/dist/features/studio/followAgent.js +241 -0
  262. package/dist/features/studio/followAgentContext.js +7 -0
  263. package/dist/features/studio/localeOptions.js +118 -0
  264. package/dist/features/studio/localeSwitch.js +19 -0
  265. package/dist/features/studio/routes.js +26 -1
  266. package/dist/features/studio/studioStore.js +64 -1
  267. package/dist/features/studio/useTheme.js +24 -27
  268. package/dist/features/vite/artifactRuntimeMinification.js +36 -0
  269. package/dist/features/vite/blockBoilerplate.js +6 -5
  270. package/dist/features/vite/blockChunks.js +31 -0
  271. package/dist/features/vite/bundlerLogs.js +17 -0
  272. package/dist/features/vite/definitionsSync.js +158 -226
  273. package/dist/features/vite/devAuthentication.js +4 -16
  274. package/dist/features/vite/devSignIn.js +87 -0
  275. package/dist/features/vite/iconGeneration.js +1 -1
  276. package/dist/features/vite/layoutGeneration.js +11 -1
  277. package/dist/features/vite/publishSeededContent.js +30 -0
  278. package/dist/features/vite/routeGeneration.js +6 -7
  279. package/dist/features/vite/runtimeDev.js +80 -99
  280. package/dist/features/vite/vite.d.ts +51 -31
  281. package/dist/features/vite/vite.js +224 -127
  282. package/dist/features/vite/workerBuild.js +39 -0
  283. package/dist/hooks/use-debounced-field.js +116 -47
  284. package/dist/hooks/use-file-upload.js +114 -67
  285. package/dist/hooks/use-marquee-selection.js +32 -36
  286. package/dist/hooks/use-page-destinations.js +69 -37
  287. package/dist/lib/api-client-server.d.ts +5 -0
  288. package/dist/lib/api-client-server.js +10 -4
  289. package/dist/lib/api-client.d.ts +6 -0
  290. package/dist/lib/api-client.js +51 -16
  291. package/dist/lib/api-socket.js +17 -0
  292. package/dist/lib/auth-page-styles.js +39 -0
  293. package/dist/lib/auth.js +129 -61
  294. package/dist/lib/collection-cache.js +23 -0
  295. package/dist/lib/draft-scope.d.ts +4 -0
  296. package/dist/lib/draft-scope.js +222 -0
  297. package/dist/lib/html.js +12 -0
  298. package/dist/lib/link-pages.js +154 -0
  299. package/dist/lib/locale-path.d.ts +22 -0
  300. package/dist/lib/locale-path.js +57 -0
  301. package/dist/lib/normalized-data.js +252 -152
  302. package/dist/lib/preview-handoff.js +2 -2
  303. package/dist/lib/queries.d.ts +11 -0
  304. package/dist/lib/queries.js +70 -141
  305. package/dist/lib/studio-reads.d.ts +14 -0
  306. package/dist/lib/studio-reads.js +554 -0
  307. package/dist/lib/use-project-room.js +50 -50
  308. package/dist/lib/use-thread.js +310 -0
  309. package/dist/lib/utils.js +25 -29
  310. package/dist/lib/view-locale-context.js +22 -0
  311. package/dist/lib/view-locale.js +46 -0
  312. package/dist/package.js +5 -0
  313. package/dist/studio-overlays.css +41 -151
  314. package/dist/studio.css +2 -2
  315. package/package.json +70 -73
  316. package/skills/camox/SKILL.md +16 -11
  317. package/skills/camox/references/artifacts.md +179 -0
  318. package/skills/camox/references/block-definitions.md +75 -59
  319. package/skills/camox/references/cli-common.md +9 -11
  320. package/skills/camox/references/cli-content.md +92 -69
  321. package/skills/camox/references/cli-publishing.md +26 -0
  322. package/skills/camox/references/dom-integrations.md +27 -0
  323. package/skills/camox/references/field-styling.md +4 -4
  324. package/skills/camox/references/layout-definitions.md +16 -14
  325. package/skills/camox/references/localization.md +56 -0
  326. package/skills/camox/references/routed-layouts.md +133 -15
  327. package/skills/camox-expand/SKILL.md +70 -0
  328. package/skills/camox-expand/references/jobs.md +39 -0
  329. package/skills/camoxify/SKILL.md +29 -7
  330. package/dist/core/components/AddBlockControlBar.js +0 -78
  331. package/dist/core/hooks/useRequireDraftSource.js +0 -23
  332. package/dist/features/metadata/sitemap.d.ts +0 -8
  333. package/dist/features/metadata/sitemap.js +0 -17
  334. package/dist/features/og/imageResponse.node.d.ts +0 -12
  335. package/dist/features/og/imageResponse.node.js +0 -49
  336. package/dist/features/og/imageResponse.workerd.d.ts +0 -12
  337. package/dist/features/og/imageResponse.workerd.js +0 -40
  338. package/dist/features/page/PublishedPageContent.js +0 -205
  339. package/dist/features/page/PublishedPageExperience.js +0 -23
  340. package/dist/features/preview/DerivedPreview.js +0 -134
  341. package/dist/features/preview/commentsEnabled.js +0 -8
  342. package/dist/features/preview/components/AddBlockSidebar.js +0 -381
  343. package/dist/features/preview/components/AttachedComments.js +0 -331
  344. package/dist/features/preview/components/CommentHeader.js +0 -122
  345. package/dist/features/preview/components/CommentSidebar.js +0 -29
  346. package/dist/features/preview/components/CommentTargetQuote.js +0 -167
  347. package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +0 -5
  348. package/dist/features/preview/components/DerivedLayoutSidebar.js +0 -179
  349. package/dist/features/preview/components/DerivedPageInfoSidebar.js +0 -69
  350. package/dist/features/preview/components/LeftSidebar.js +0 -68
  351. package/dist/features/preview/components/PageEditorSidebar.js +0 -563
  352. package/dist/features/preview/components/PageInfoSidebar.js +0 -1551
  353. package/dist/features/preview/components/PageNavigatorSidebar.js +0 -78
  354. package/dist/features/preview/components/PageStatusBadge.js +0 -97
  355. package/dist/features/preview/components/PeekedBlock.js +0 -217
  356. package/dist/features/preview/components/PreviewComments.js +0 -56
  357. package/dist/features/preview/components/PreviewToolbarSpacer.js +0 -43
  358. package/dist/features/preview/components/PublicationRow.js +0 -422
  359. package/dist/features/preview/components/PublishDialog.js +0 -194
  360. package/dist/features/preview/components/RightSidebar.js +0 -59
  361. package/dist/features/preview/components/SendFeedbackDialog.js +0 -83
  362. package/dist/features/preview/previewCommentsStore.js +0 -135
  363. package/dist/features/preview/publication.js +0 -81
  364. package/dist/features/preview/usePageComments.js +0 -39
  365. package/dist/features/runtime/SharedChromeContext.js +0 -7
  366. package/dist/features/studio/components/EnvironmentMenu.js +0 -425
  367. package/dist/features/vite/appGeneration.js +0 -89
  368. package/dist/lib/view-queries.js +0 -28
  369. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +0 -114
  370. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +0 -25
  371. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +0 -1
  372. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +0 -1
  373. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +0 -20
  374. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +0 -8
  375. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +0 -1
  376. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +0 -18
  377. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +0 -161
  378. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +0 -6
  379. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +0 -54
  380. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +0 -8
  381. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +0 -32
  382. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/new-process-route-tree.d.ts +0 -115
  383. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +0 -1
  384. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +0 -49
  385. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +0 -1
  386. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +0 -6
  387. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +0 -343
  388. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +0 -48
  389. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +0 -695
  390. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +0 -1
  391. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +0 -1
  392. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +0 -5
  393. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/RawStream.d.ts +0 -38
  394. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/seroval-plugins.d.ts +0 -1
  395. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/transformer.d.ts +0 -65
  396. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +0 -69
  397. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +0 -1
  398. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +0 -1
  399. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +0 -1
  400. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +0 -1
  401. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +0 -10
  402. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +0 -1
  403. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +0 -1
  404. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +0 -1
  405. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +0 -28
  406. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +0 -49
  407. package/skills/camox/references/cli-environments.md +0 -37
@@ -0,0 +1,241 @@
1
+ import { previewStore, sameEditingOwner } from "../preview/previewStore.js";
2
+
3
+ //#region src/features/studio/followAgent.ts
4
+ /**
5
+ * How long following stays on a page it went to before it leaves for another one, in
6
+ * milliseconds. A product tuning value: long enough to see each destination, short enough to
7
+ * keep up with the agent.
8
+ */
9
+ const FOLLOW_MINIMUM_STAY = 2e3;
10
+ const pageRowId = (page) => page.owner.kind === "page" ? page.owner.pageId : null;
11
+ function findPage(where, ref) {
12
+ return where.pages.find((page) => "key" in ref ? page.key === ref.key : pageRowId(page) === ref.pageId);
13
+ }
14
+ /** The Page the editor is on, if any. */
15
+ const currentPage = (where) => where.pageKey ? where.pages.find((page) => page.key === where.pageKey) : void 0;
16
+ const refKey = (ref) => "key" in ref ? `key:${ref.key}` : `page:${ref.pageId}`;
17
+ function locate(where, here, touch) {
18
+ const elsewhere = !!touch.locale && touch.locale !== where.locale;
19
+ const keptBlock = (id) => id && !elsewhere && touch.kind !== "deleted" && touch.kind !== "settings" ? id : void 0;
20
+ const at = (page, blockId) => {
21
+ const id = keptBlock(blockId);
22
+ return {
23
+ page,
24
+ ...id ? { blockId: id } : {}
25
+ };
26
+ };
27
+ if (touch.entity === "page") {
28
+ const shown = where.pages.some((page) => pageRowId(page) === touch.pageId);
29
+ if (elsewhere && !shown) return null;
30
+ return at({ pageId: touch.pageId }, touch.blockId);
31
+ }
32
+ if (touch.entity === "layout") {
33
+ const page = here?.layoutId === touch.layoutId ? here : where.pages.find((candidate) => candidate.layoutId === touch.layoutId && candidate.pathname);
34
+ return page ? at({ key: page.key }, touch.blockId) : null;
35
+ }
36
+ const placement = here?.blocks?.find((block) => block.type === touch.blockType);
37
+ return here && placement ? at({ key: here.key }, placement.id) : null;
38
+ }
39
+ function destinationOf(where, batch) {
40
+ const here = currentPage(where);
41
+ const deletedPages = new Set(batch.touches.flatMap((touch) => touch.entity === "page" && touch.kind === "deleted" && !touch.blockId ? [touch.pageId] : []));
42
+ const located = batch.touches.filter((touch) => !(touch.entity === "page" && deletedPages.has(touch.pageId))).flatMap((touch) => {
43
+ const at = locate(where, here, touch);
44
+ return at ? [at] : [];
45
+ });
46
+ const touched = /* @__PURE__ */ new Map();
47
+ const identity = (ref) => {
48
+ const page = findPage(where, ref);
49
+ return page ? `key:${page.key}` : refKey(ref);
50
+ };
51
+ for (const at of located) {
52
+ const key = identity(at.page);
53
+ const entry = touched.get(key) ?? {
54
+ page: at.page,
55
+ blockIds: [],
56
+ count: 0
57
+ };
58
+ entry.count += 1;
59
+ if (at.blockId && !entry.blockIds.includes(at.blockId)) entry.blockIds.push(at.blockId);
60
+ touched.set(key, entry);
61
+ }
62
+ if (touched.size === 0) return null;
63
+ const order = (ref) => {
64
+ const page = findPage(where, ref);
65
+ return page ? where.pages.indexOf(page) : where.pages.length;
66
+ };
67
+ const entries = [...touched.values()];
68
+ const chosen = (here && touched.get(`key:${here.key}`)) ?? entries.reduce((best, entry) => entry.count > best.count || entry.count === best.count && order(entry.page) < order(best.page) ? entry : best);
69
+ return {
70
+ page: chosen.page,
71
+ blockIds: chosen.blockIds
72
+ };
73
+ }
74
+ /** The topmost of the touched blocks by its order on the page; ones not shown yet come last. */
75
+ function topmostBlock(page, blockIds) {
76
+ const position = (id) => {
77
+ const index = page.blocks?.findIndex((block) => block.id === id) ?? -1;
78
+ return index === -1 ? Infinity : index;
79
+ };
80
+ return [...blockIds].sort((a, b) => position(a) - position(b))[0];
81
+ }
82
+ /**
83
+ * Following the agent on the Canvas or in the Preview: each touched batch gives at most one
84
+ * destination, which the Studio goes to through the existing selection. Pages are selected
85
+ * through the URL, replacing the history entry, and blocks through the preview store once the
86
+ * destination page's editing frame is active.
87
+ */
88
+ function createFollowAgent({ navigate, where: initial }) {
89
+ let where = initial;
90
+ let following = true;
91
+ /** When following last arrived on another page; it stays there for the minimum stay. */
92
+ let arrivedAt = -Infinity;
93
+ /** The latest destination on another page, waiting for the minimum stay or for its page. */
94
+ let pendingNavigation = null;
95
+ /** When the pending destination's page has to show by, once following could go there. */
96
+ let pendingNavigationUntil = 0;
97
+ let timer = null;
98
+ /** Blocks to select once their page's editing frame is active. */
99
+ let blocksToSelect = null;
100
+ /** The block following last selected, to move to a topmost one that shows later. */
101
+ let selected = null;
102
+ /** The block following selected last, whichever page it's on, to tell the editor's apart. */
103
+ let ownSelection = null;
104
+ /** Selects the topmost of the touched blocks on `page`, if one shows. */
105
+ const selectTopmost = (touched, page) => {
106
+ const blockId = topmostBlock(page, touched.blockIds);
107
+ if (!blockId) return;
108
+ selected = {
109
+ page: touched.page,
110
+ blockIds: touched.blockIds,
111
+ blockId
112
+ };
113
+ ownSelection = {
114
+ owner: page.owner,
115
+ blockId
116
+ };
117
+ previewStore.send({
118
+ type: "setFocusedBlock",
119
+ ...page.owner,
120
+ blockId
121
+ });
122
+ };
123
+ const selectBlocks = () => {
124
+ if (!blocksToSelect) return;
125
+ const page = findPage(where, blocksToSelect.page);
126
+ const { editingContext } = previewStore.getSnapshot().context;
127
+ if (!page || !sameEditingOwner(editingContext, page.owner)) return;
128
+ const touched = blocksToSelect;
129
+ blocksToSelect = null;
130
+ selectTopmost(touched, page);
131
+ };
132
+ /** Reselects when a touched block above the selected one shows, while the selection is ours. */
133
+ const reselectTopmost = () => {
134
+ if (!selected) return;
135
+ const page = findPage(where, selected.page);
136
+ const selection = previewStore.getSnapshot().context.editingContext?.selection;
137
+ if (!page || selection?.type !== "block" || selection.blockId !== selected.blockId) {
138
+ selected = null;
139
+ return;
140
+ }
141
+ if (topmostBlock(page, selected.blockIds) !== selected.blockId) selectTopmost(selected, page);
142
+ };
143
+ const clearTimer = () => {
144
+ if (timer !== null) clearTimeout(timer);
145
+ timer = null;
146
+ };
147
+ /** Goes to the pending destination, once the minimum stay is over and its page is known. */
148
+ const navigatePending = () => {
149
+ if (!pendingNavigation) return;
150
+ const wait = arrivedAt + FOLLOW_MINIMUM_STAY - Date.now();
151
+ if (wait > 0) {
152
+ timer ??= setTimeout(() => {
153
+ timer = null;
154
+ navigatePending();
155
+ }, wait);
156
+ return;
157
+ }
158
+ if (Date.now() >= pendingNavigationUntil) {
159
+ pendingNavigation = null;
160
+ return;
161
+ }
162
+ const destination = pendingNavigation;
163
+ const pathname = findPage(where, destination.page)?.pathname;
164
+ if (!pathname) return;
165
+ pendingNavigation = null;
166
+ arrivedAt = Date.now();
167
+ blocksToSelect = destination.blockIds.length ? destination : null;
168
+ selected = null;
169
+ navigate({
170
+ to: `${pathname}${where.location.search}`,
171
+ replace: true,
172
+ source: "follow"
173
+ });
174
+ };
175
+ /**
176
+ * Whether the editor selected something themselves: a selection following didn't make.
177
+ * Clearing it isn't one, as frames do when the Canvas mounts or a navigation releases them.
178
+ */
179
+ const editorSelected = () => {
180
+ const { editingContext } = previewStore.getSnapshot().context;
181
+ const selection = editingContext?.selection;
182
+ if (!selection) return false;
183
+ return !(ownSelection && selection.type === "block" && selection.blockId === ownSelection.blockId && sameEditingOwner(editingContext, ownSelection.owner));
184
+ };
185
+ let lastSelection = previewStore.getSnapshot().context.editingContext?.selection ?? null;
186
+ const subscription = previewStore.subscribe(({ context }) => {
187
+ const selection = context.editingContext?.selection ?? null;
188
+ const changed = selection !== lastSelection;
189
+ lastSelection = selection;
190
+ if (changed && editorSelected()) {
191
+ follow.takeOver();
192
+ return;
193
+ }
194
+ selectBlocks();
195
+ });
196
+ const follow = {
197
+ receive(batch) {
198
+ if (!following) return;
199
+ const destination = destinationOf(where, batch);
200
+ if (!destination) return;
201
+ const here = currentPage(where);
202
+ if (here && findPage(where, destination.page) === here) {
203
+ pendingNavigation = null;
204
+ clearTimer();
205
+ if (!destination.blockIds.length) return;
206
+ blocksToSelect = destination;
207
+ selectBlocks();
208
+ return;
209
+ }
210
+ pendingNavigation = destination;
211
+ pendingNavigationUntil = Math.max(Date.now(), arrivedAt + FOLLOW_MINIMUM_STAY) + FOLLOW_MINIMUM_STAY;
212
+ navigatePending();
213
+ },
214
+ update(next) {
215
+ const navigated = next.location.pathname !== where.location.pathname;
216
+ where = next;
217
+ if (navigated && next.location.source === void 0) follow.takeOver();
218
+ navigatePending();
219
+ selectBlocks();
220
+ reselectTopmost();
221
+ },
222
+ takeOver() {
223
+ following = false;
224
+ pendingNavigation = null;
225
+ blocksToSelect = null;
226
+ selected = null;
227
+ clearTimer();
228
+ },
229
+ resume() {
230
+ following = true;
231
+ },
232
+ dispose() {
233
+ clearTimer();
234
+ subscription.unsubscribe();
235
+ }
236
+ };
237
+ return follow;
238
+ }
239
+
240
+ //#endregion
241
+ export { FOLLOW_MINIMUM_STAY, createFollowAgent };
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+
3
+ //#region src/features/studio/followAgentContext.ts
4
+ const FollowAgentContext = React.createContext(null);
5
+
6
+ //#endregion
7
+ export { FollowAgentContext };
@@ -0,0 +1,118 @@
1
+ //#region src/features/studio/localeOptions.ts
2
+ const localeNames = new Intl.DisplayNames(["en"], { type: "language" });
3
+ /** A locale's name as the studio shows it, "German (de)", or its tag alone when unnamed. */
4
+ function localeLabel(tag) {
5
+ try {
6
+ const name = localeNames.of(tag);
7
+ return name && name !== tag ? `${name} (${tag})` : tag;
8
+ } catch {
9
+ return tag;
10
+ }
11
+ }
12
+ /** The BCP 47 tags the studio offers to add: widely used languages and their main regions. */
13
+ const OFFERED_TAGS = [
14
+ "af",
15
+ "am",
16
+ "ar",
17
+ "az",
18
+ "be",
19
+ "bg",
20
+ "bn",
21
+ "bs",
22
+ "ca",
23
+ "cs",
24
+ "cy",
25
+ "da",
26
+ "de",
27
+ "de-AT",
28
+ "de-CH",
29
+ "el",
30
+ "en",
31
+ "en-AU",
32
+ "en-CA",
33
+ "en-GB",
34
+ "en-IE",
35
+ "en-IN",
36
+ "en-NZ",
37
+ "en-US",
38
+ "es",
39
+ "es-419",
40
+ "es-ES",
41
+ "es-MX",
42
+ "et",
43
+ "eu",
44
+ "fa",
45
+ "fi",
46
+ "fil",
47
+ "fr",
48
+ "fr-BE",
49
+ "fr-CA",
50
+ "fr-CH",
51
+ "ga",
52
+ "gl",
53
+ "gu",
54
+ "he",
55
+ "hi",
56
+ "hr",
57
+ "hu",
58
+ "hy",
59
+ "id",
60
+ "is",
61
+ "it",
62
+ "ja",
63
+ "ka",
64
+ "kk",
65
+ "km",
66
+ "kn",
67
+ "ko",
68
+ "lo",
69
+ "lt",
70
+ "lv",
71
+ "mk",
72
+ "ml",
73
+ "mn",
74
+ "mr",
75
+ "ms",
76
+ "mt",
77
+ "my",
78
+ "nb",
79
+ "ne",
80
+ "nl",
81
+ "nl-BE",
82
+ "pa",
83
+ "pl",
84
+ "pt",
85
+ "pt-BR",
86
+ "pt-PT",
87
+ "ro",
88
+ "ru",
89
+ "si",
90
+ "sk",
91
+ "sl",
92
+ "sq",
93
+ "sr",
94
+ "sv",
95
+ "sw",
96
+ "ta",
97
+ "te",
98
+ "th",
99
+ "tr",
100
+ "uk",
101
+ "ur",
102
+ "uz",
103
+ "vi",
104
+ "zh-Hans",
105
+ "zh-Hant",
106
+ "zu"
107
+ ];
108
+ /** The locales a project can add, by name: the offered tags it doesn't have yet. */
109
+ function localeOptions(existing) {
110
+ const taken = new Set(existing.map((locale) => locale.tag.toLowerCase()));
111
+ return OFFERED_TAGS.filter((tag) => !taken.has(tag.toLowerCase())).map((tag) => ({
112
+ tag,
113
+ label: localeLabel(tag)
114
+ })).sort((a, b) => a.label.localeCompare(b.label));
115
+ }
116
+
117
+ //#endregion
118
+ export { localeLabel, localeOptions };
@@ -0,0 +1,19 @@
1
+ import { STUDIO_BASE_PATH } from "./routes.js";
2
+
3
+ //#region src/features/studio/localeSwitch.ts
4
+ /**
5
+ * The locale-relative path switching to another locale goes to from `path`. A curated page keeps
6
+ * its localization's path there, found by its id (ADR 0015). Studio routes and singleton pages
7
+ * keep their code-owned path. A derived layout's record page goes to the record's page there, as
8
+ * that locale's route discovery finds it. Anything else, such as a page missing from the other
9
+ * locale, goes to that locale's home.
10
+ */
11
+ function pathInLocale(path, { shown, target, singleton, recordPath }) {
12
+ if (path === "/camox" || path.startsWith(`${"/camox"}/`) || singleton(path)) return path;
13
+ const page = shown.find((candidate) => candidate.fullPath === path);
14
+ if (page) return target.find((candidate) => candidate.id === page.id)?.fullPath ?? "/";
15
+ return recordPath ?? "/";
16
+ }
17
+
18
+ //#endregion
19
+ export { pathInLocale };
@@ -2,6 +2,31 @@
2
2
  const STUDIO_ROUTE_SEGMENT = "camox";
3
3
  const STUDIO_BASE_PATH = `/${STUDIO_ROUTE_SEGMENT}`;
4
4
  const STUDIO_CONTENT_PATH = `${STUDIO_BASE_PATH}/content`;
5
+ const STUDIO_ASSETS_PATH = `${STUDIO_CONTENT_PATH}/assets`;
6
+ const collectionContentPath = (collectionId) => `${STUDIO_CONTENT_PATH}/collections/${encodeURIComponent(collectionId)}`;
7
+ function matchCollectionContentPath(pathname) {
8
+ const match = /^\/camox\/content\/collections\/([^/]+)(?:(\/new)|\/([^/]+)\/edit)?$/.exec(pathname);
9
+ if (!match) return null;
10
+ try {
11
+ const collectionId = decodeURIComponent(match[1]);
12
+ if (!collectionId || collectionId.includes("/")) return null;
13
+ if (!match[3]) return {
14
+ collectionId,
15
+ isNew: !!match[2]
16
+ };
17
+ const itemId = decodeURIComponent(match[3]);
18
+ if (!itemId || itemId.includes("/")) return null;
19
+ return {
20
+ collectionId,
21
+ isNew: false,
22
+ itemId
23
+ };
24
+ } catch {
25
+ return null;
26
+ }
27
+ }
28
+ /** The Studio URL of the Canvas with nothing selected. */
29
+ const STUDIO_CANVAS_PATH = `${STUDIO_BASE_PATH}/canvas`;
5
30
 
6
31
  //#endregion
7
- export { STUDIO_BASE_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT };
32
+ export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, collectionContentPath, matchCollectionContentPath };
@@ -4,7 +4,14 @@ import { createStore } from "@xstate/store-react";
4
4
  const studioStore = createStore({
5
5
  context: {
6
6
  isCommandPaletteOpen: false,
7
- commandPalettePages: []
7
+ commandPalettePages: [],
8
+ reviewDraftSheet: {
9
+ open: false,
10
+ startRenaming: false
11
+ },
12
+ isDiscardDraftDialogOpen: false,
13
+ localeDialog: null,
14
+ websiteLocation: null
8
15
  },
9
16
  on: {
10
17
  openCommandPalette: (context) => {
@@ -38,6 +45,62 @@ const studioStore = createStore({
38
45
  ...context,
39
46
  commandPalettePages: context.commandPalettePages.slice(0, -1)
40
47
  };
48
+ },
49
+ openReviewDraftSheet: (context, event) => {
50
+ return {
51
+ ...context,
52
+ reviewDraftSheet: {
53
+ open: true,
54
+ startRenaming: event.startRenaming ?? false
55
+ }
56
+ };
57
+ },
58
+ closeReviewDraftSheet: (context) => {
59
+ return {
60
+ ...context,
61
+ reviewDraftSheet: {
62
+ open: false,
63
+ startRenaming: false
64
+ }
65
+ };
66
+ },
67
+ openDiscardDraftDialog: (context) => {
68
+ return {
69
+ ...context,
70
+ isDiscardDraftDialogOpen: true
71
+ };
72
+ },
73
+ closeDiscardDraftDialog: (context) => {
74
+ return {
75
+ ...context,
76
+ isDiscardDraftDialogOpen: false
77
+ };
78
+ },
79
+ openLocaleDialog: (context, event) => {
80
+ return {
81
+ ...context,
82
+ localeDialog: event.dialog
83
+ };
84
+ },
85
+ closeLocaleDialog: (context) => {
86
+ return {
87
+ ...context,
88
+ localeDialog: null
89
+ };
90
+ },
91
+ rememberWebsiteLocation: (context, event) => {
92
+ const previous = context.websiteLocation;
93
+ const { locale, path, search, hash } = event.location;
94
+ if (previous?.locale === locale && previous.path === path && previous.search === search && previous.hash === hash) return context;
95
+ return {
96
+ ...context,
97
+ websiteLocation: {
98
+ locale,
99
+ path,
100
+ search,
101
+ hash
102
+ }
103
+ };
41
104
  }
42
105
  }
43
106
  });
@@ -35,31 +35,32 @@ function setTheme(theme) {
35
35
  applyTheme(theme);
36
36
  notify();
37
37
  }
38
+ /**
39
+ * Owns the studio theme: writes the active class onto `<html>` and persists
40
+ * changes to localStorage. Should only be mounted from the studio chrome —
41
+ * never from contexts that share `<html>` with the user's site.
42
+ */
38
43
  function useApplyTheme() {
39
- const $ = c(5);
40
- if ($[0] !== "5860ae8e48f7dc27e488236def482df22f144de61ae2d86bfde82aeeea4f9874") {
41
- for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
42
- $[0] = "5860ae8e48f7dc27e488236def482df22f144de61ae2d86bfde82aeeea4f9874";
43
- }
44
+ const $ = c(4);
44
45
  const theme = React.useSyncExternalStore(subscribe, readStoredTheme, _temp2);
45
46
  const resolvedTheme = React.useSyncExternalStore(subscribe, _temp3, _temp4);
46
47
  let t0;
47
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
48
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
48
49
  t0 = [];
49
- $[1] = t0;
50
- } else t0 = $[1];
50
+ $[0] = t0;
51
+ } else t0 = $[0];
51
52
  React.useEffect(_temp7, t0);
52
53
  let t1;
53
- if ($[2] !== resolvedTheme || $[3] !== theme) {
54
+ if ($[1] !== resolvedTheme || $[2] !== theme) {
54
55
  t1 = {
55
56
  theme,
56
57
  resolvedTheme,
57
58
  setTheme
58
59
  };
59
- $[2] = resolvedTheme;
60
- $[3] = theme;
61
- $[4] = t1;
62
- } else t1 = $[4];
60
+ $[1] = resolvedTheme;
61
+ $[2] = theme;
62
+ $[3] = t1;
63
+ } else t1 = $[3];
63
64
  return t1;
64
65
  }
65
66
  function _temp7() {
@@ -103,15 +104,11 @@ function _temp2() {
103
104
  return "system";
104
105
  }
105
106
  function useThemeActions() {
106
- const $ = c(5);
107
- if ($[0] !== "5860ae8e48f7dc27e488236def482df22f144de61ae2d86bfde82aeeea4f9874") {
108
- for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
109
- $[0] = "5860ae8e48f7dc27e488236def482df22f144de61ae2d86bfde82aeeea4f9874";
110
- }
107
+ const $ = c(4);
111
108
  const { theme, setTheme } = useApplyTheme();
112
109
  let t0;
113
110
  let t1;
114
- if ($[1] !== setTheme || $[2] !== theme) {
111
+ if ($[0] !== setTheme || $[1] !== theme) {
115
112
  t0 = () => {
116
113
  const actions = [
117
114
  {
@@ -162,22 +159,22 @@ function useThemeActions() {
162
159
  return () => {
163
160
  actionsStore.send({
164
161
  type: "unregisterManyActions",
165
- ids: actions.map(_temp0)
162
+ ids: actions.map(_temp10)
166
163
  });
167
164
  };
168
165
  };
169
166
  t1 = [theme, setTheme];
170
- $[1] = setTheme;
171
- $[2] = theme;
172
- $[3] = t0;
173
- $[4] = t1;
167
+ $[0] = setTheme;
168
+ $[1] = theme;
169
+ $[2] = t0;
170
+ $[3] = t1;
174
171
  } else {
175
- t0 = $[3];
176
- t1 = $[4];
172
+ t0 = $[2];
173
+ t1 = $[3];
177
174
  }
178
175
  React.useEffect(t0, t1);
179
176
  }
180
- function _temp0(a) {
177
+ function _temp10(a) {
181
178
  return a.id;
182
179
  }
183
180
  function _temp9() {}
@@ -0,0 +1,36 @@
1
+ import { minifySync } from "vite-plus";
2
+
3
+ //#region src/features/vite/artifactRuntimeMinification.ts
4
+ /** The runtime's source module, also with the query Vite's dev server may add to it. */
5
+ const RUNTIME_MODULE = /[\\/]src[\\/]core[\\/]lib[\\/]artifactRuntime\.ts(\?.*)?$/;
6
+ const RUNTIME_EXPORT = /export const ARTIFACT_RUNTIME = `([^`]*)`;/;
7
+ /**
8
+ * Minifies the `camox` runtime in the source of `artifactRuntime.ts`. Every artifact frame inlines
9
+ * the runtime in its `srcDoc`, so the website's HTML carries one copy per artifact, and the SDK's
10
+ * bundle is otherwise left unminified. Throws when the module no longer holds the runtime as one
11
+ * plain template literal, rather than shipping it unminified.
12
+ */
13
+ function minifyArtifactRuntimeModule(code) {
14
+ const match = RUNTIME_EXPORT.exec(code);
15
+ if (!match) throw new Error("artifactRuntime.ts no longer exports ARTIFACT_RUNTIME as `…`.");
16
+ const runtime = match[1];
17
+ if (runtime.includes("\\") || runtime.includes("${")) throw new Error("The artifact runtime must have no backslashes or interpolations.");
18
+ const { code: minified, errors } = minifySync("artifactRuntime.js", runtime);
19
+ if (errors.length > 0) throw new Error(`The artifact runtime failed to minify: ${errors[0].message}`);
20
+ return code.replace(match[0], () => `export const ARTIFACT_RUNTIME = ${JSON.stringify(minified.trim())};`);
21
+ }
22
+ /**
23
+ * A build `transform` that minifies the runtime's source module and leaves every other module
24
+ * alone. The SDK's own build applies it, and so does the `camox` Vite plugin, for apps that
25
+ * compile the SDK from source.
26
+ */
27
+ function transformArtifactRuntime(code, id) {
28
+ if (!RUNTIME_MODULE.test(id)) return null;
29
+ return {
30
+ code: minifyArtifactRuntimeModule(code),
31
+ map: { mappings: "" }
32
+ };
33
+ }
34
+
35
+ //#endregion
36
+ export { minifyArtifactRuntimeModule, transformArtifactRuntime };
@@ -17,15 +17,15 @@ function getBlockBoilerplate(filename) {
17
17
  const name = filename.replace(/\.tsx?$/, "");
18
18
  const camelName = kebabToCamel(name);
19
19
  const pascalName = kebabToPascal(name);
20
- return `import { Type, createBlock } from "camox/createBlock";
20
+ return `import { createBlock } from "camox/createBlock";
21
21
 
22
22
  const ${camelName} = createBlock({
23
23
  id: "${name}",
24
24
  title: "${kebabToTitle(name)}",
25
25
  description: "Describe when the AI should use this block.",
26
- content: {
27
- title: Type.String({ default: "Title" }),
28
- },
26
+ content: (field) => ({
27
+ title: field.string({ default: "Title" }),
28
+ }),
29
29
  component: ${pascalName}Component,
30
30
  toMarkdown: (c) => [c.title]
31
31
  });
@@ -49,7 +49,8 @@ function watchNewBlockFiles(server) {
49
49
  if (filePath.startsWith(blocksDir) && /\.tsx?$/.test(filePath) && !filePath.includes("index.")) try {
50
50
  if (readFileSync(filePath, "utf-8").trim().length < MAX_EMPTY_BLOCK_CHARACTER_COUNT) {
51
51
  const filename = basename(filePath);
52
- writeFileSync(filePath, getBlockBoilerplate(filename));
52
+ const boilerplate = getBlockBoilerplate(filename);
53
+ writeFileSync(filePath, boilerplate);
53
54
  server.config.logger.info(`[camox] Auto-filled block boilerplate: ${filename}`, { timestamp: true });
54
55
  }
55
56
  } catch {
@@ -0,0 +1,31 @@
1
+ import { relative } from "node:path";
2
+
3
+ //#region src/features/vite/blockChunks.ts
4
+ const BLOCK_MODULE = /^src\/(camox\/)?blocks\/[^/]+\.tsx?$/;
5
+ /**
6
+ * The chunks the browser must load to render each block, by the block's module path (as the
7
+ * app's globs name it). Chunks every entry already loads are left out: they need no preload.
8
+ */
9
+ function collectBlockChunks(bundle, root) {
10
+ const chunks = /* @__PURE__ */ new Map();
11
+ for (const output of Object.values(bundle)) if (output.type === "chunk") chunks.set(output.fileName, output);
12
+ const withImports = (fileName, into = /* @__PURE__ */ new Set()) => {
13
+ if (into.has(fileName)) return into;
14
+ into.add(fileName);
15
+ for (const imported of chunks.get(fileName)?.imports ?? []) withImports(imported, into);
16
+ return into;
17
+ };
18
+ const loadedByEntries = /* @__PURE__ */ new Set();
19
+ for (const chunk of chunks.values()) if (chunk.isEntry) withImports(chunk.fileName, loadedByEntries);
20
+ const blockChunks = {};
21
+ for (const chunk of chunks.values()) {
22
+ if (!chunk.isDynamicEntry || !chunk.facadeModuleId) continue;
23
+ const modulePath = relative(root, chunk.facadeModuleId).replaceAll("\\", "/");
24
+ if (!BLOCK_MODULE.test(modulePath)) continue;
25
+ blockChunks[`/${modulePath}`] = [...withImports(chunk.fileName)].filter((fileName) => !loadedByEntries.has(fileName));
26
+ }
27
+ return blockChunks;
28
+ }
29
+
30
+ //#endregion
31
+ export { collectBlockChunks };