camox 0.44.0 → 0.45.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 (411) 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 +1734 -0
  68. package/dist/features/canvas/CanvasBlockFrame.js +353 -0
  69. package/dist/features/canvas/CanvasBlockHeader.js +55 -0
  70. package/dist/features/canvas/CanvasLoadingScreen.js +35 -0
  71. package/dist/features/canvas/CanvasOverlays.js +254 -0
  72. package/dist/features/canvas/CanvasPageEdge.js +87 -0
  73. package/dist/features/canvas/CanvasPageFrame.js +335 -0
  74. package/dist/features/canvas/CanvasPageHeader.js +125 -0
  75. package/dist/features/canvas/CanvasPreviewPageSlot.js +103 -0
  76. package/dist/features/canvas/CanvasShelfMarker.js +255 -0
  77. package/dist/features/canvas/DerivedPagePathInput.js +238 -0
  78. package/dist/features/canvas/canvasCamera.js +229 -0
  79. package/dist/features/canvas/canvasFlight.js +104 -0
  80. package/dist/features/canvas/canvasFrameCapture.js +364 -0
  81. package/dist/features/canvas/canvasFrameDocument.js +317 -0
  82. package/dist/features/canvas/canvasFrameMode.js +53 -0
  83. package/dist/features/canvas/canvasInsertionSeams.js +44 -0
  84. package/dist/features/canvas/canvasItems.js +120 -0
  85. package/dist/features/canvas/canvasOverlayGeometry.js +240 -0
  86. package/dist/features/canvas/canvasPages.js +79 -0
  87. package/dist/features/canvas/canvasScreenSpace.js +26 -0
  88. package/dist/features/canvas/canvasSelection.js +18 -0
  89. package/dist/features/canvas/canvasStore.js +149 -0
  90. package/dist/features/canvas/canvasThumbnails.js +304 -0
  91. package/dist/features/canvas/canvasZoom.js +10 -0
  92. package/dist/features/canvas/sidebar/CanvasInspector.js +202 -0
  93. package/dist/features/canvas/sidebar/CanvasNavigator.js +226 -0
  94. package/dist/features/canvas/sidebar/CanvasSidebar.js +60 -0
  95. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +48 -0
  96. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +39 -0
  97. package/dist/features/canvas/sidebar/CatalogBlockInspector.js +189 -0
  98. package/dist/features/canvas/sidebar/CuratedPageInspector.js +69 -0
  99. package/dist/features/canvas/sidebar/DerivedPageInspector.js +37 -0
  100. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +78 -0
  101. package/dist/features/canvas/sidebar/LayoutPageOverview.js +71 -0
  102. package/dist/features/canvas/sidebar/PageInspector.js +157 -0
  103. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +90 -0
  104. package/dist/features/canvas/sidebar/PageOverview.js +27 -0
  105. package/dist/features/canvas/sidebar/SingletonPageInspector.js +31 -0
  106. package/dist/features/canvas/useCanvasCamera.js +803 -0
  107. package/dist/features/canvas/useCanvasFrame.js +149 -0
  108. package/dist/features/canvas/useCanvasFrameInput.js +97 -0
  109. package/dist/features/canvas/useCanvasNearness.js +57 -0
  110. package/dist/features/canvas/useDiscoveredPreviewPaths.js +62 -0
  111. package/dist/features/content/CamoxContent.d.ts +2 -5
  112. package/dist/features/content/CamoxContent.js +174 -271
  113. package/dist/features/content/CollectionItemSheetContext.js +106 -0
  114. package/dist/features/content/ContentAssets.js +315 -0
  115. package/dist/features/content/ContentCollection.js +663 -0
  116. package/dist/features/content/collection-form.js +58 -0
  117. package/dist/features/content/components/AssetCard.js +80 -84
  118. package/dist/features/content/components/AssetCardSkeleton.js +4 -8
  119. package/dist/features/content/components/ContentSidebar.js +129 -18
  120. package/dist/features/content/components/ContentSidebarGroup.js +37 -0
  121. package/dist/features/content/components/DeleteCollectionItemButton.js +202 -0
  122. package/dist/features/content/components/MissingFromLocale.js +282 -0
  123. package/dist/features/content/components/UploadDropZone.js +27 -31
  124. package/dist/features/content/components/UploadProgressDrawer.js +90 -98
  125. package/dist/features/navigation/navigation.d.ts +66 -20
  126. package/dist/features/navigation/navigation.js +257 -90
  127. package/dist/features/og/defaultFonts.js +8 -8
  128. package/dist/features/og/geist-variable-ttf-base64.js +1 -1
  129. package/dist/features/og/imageResponse.d.ts +8 -0
  130. package/dist/features/og/imageResponse.js +26 -0
  131. package/dist/features/page/CuratedPageContent.js +167 -0
  132. package/dist/features/page/DerivedPageContent.js +26 -30
  133. package/dist/features/page/SharedLayoutContent.js +25 -27
  134. package/dist/features/preview/CamoxPreview.d.ts +23 -61
  135. package/dist/features/preview/CamoxPreview.js +816 -537
  136. package/dist/features/preview/EditablePageContent.js +1 -1
  137. package/dist/features/preview/EditablePageExperience.js +16 -22
  138. package/dist/features/preview/components/AddBlockDialog.js +270 -0
  139. package/dist/features/preview/components/AssetFieldEditor.js +173 -154
  140. package/dist/features/preview/components/AssetLightbox.js +181 -134
  141. package/dist/features/preview/components/AssetPickerModal.js +153 -170
  142. package/dist/features/preview/components/BlockActionsPopover.js +150 -149
  143. package/dist/features/preview/components/BlockErrorBoundary.js +8 -12
  144. package/dist/features/preview/components/BlockThumbnail.js +176 -100
  145. package/dist/features/preview/components/CanvasPreview.js +243 -0
  146. package/dist/features/preview/components/CreatePageModal.js +128 -137
  147. package/dist/features/preview/components/DebouncedFieldEditor.js +29 -33
  148. package/dist/features/preview/components/DerivedLayoutDialog.js +21 -19
  149. package/dist/features/preview/components/DrillRow.js +150 -0
  150. package/dist/features/preview/components/FieldOverlayStyles.js +11 -8
  151. package/dist/features/preview/components/FieldToolbar.js +160 -110
  152. package/dist/features/preview/components/Frame.js +108 -20
  153. package/dist/features/preview/components/IconFieldEditor.js +62 -66
  154. package/dist/features/preview/components/ItemFieldsEditor.js +231 -205
  155. package/dist/features/preview/components/LinkFieldEditor.js +135 -139
  156. package/dist/features/preview/components/Metadata.js +22 -30
  157. package/dist/features/preview/components/MobilePreviewDrawer.js +89 -108
  158. package/dist/features/preview/components/MultipleAssetFieldEditor.js +334 -246
  159. package/dist/features/preview/components/OverlayTracker.js +9 -41
  160. package/dist/features/preview/components/Overlays.js +81 -69
  161. package/dist/features/preview/components/PageInfo.js +1748 -0
  162. package/dist/features/preview/components/PageInfoSkeleton.js +51 -0
  163. package/dist/features/preview/components/PageLocationFieldset.js +112 -116
  164. package/dist/features/preview/components/PageNavigatorHeader.js +24 -0
  165. package/dist/features/preview/components/PageNicknameField.js +22 -26
  166. package/dist/features/preview/components/PagePicker.js +128 -130
  167. package/dist/features/preview/components/PageTree.js +525 -532
  168. package/dist/features/preview/components/PreviewActivation.js +28 -32
  169. package/dist/features/preview/components/PreviewPanel.js +620 -319
  170. package/dist/features/preview/components/PreviewToolbar.js +105 -333
  171. package/dist/features/preview/components/RecordCard.js +80 -0
  172. package/dist/features/preview/components/RecordCombobox.js +178 -0
  173. package/dist/features/preview/components/ReferenceFieldEditor.js +149 -0
  174. package/dist/features/preview/components/ReferenceListFieldEditor.js +432 -0
  175. package/dist/features/preview/components/RemovedBlockPlaceholder.js +95 -0
  176. package/dist/features/preview/components/RepeatableItemsList.js +125 -138
  177. package/dist/features/preview/components/SelectionEditor.js +993 -0
  178. package/dist/features/preview/components/ShikiMarkdown.js +14 -18
  179. package/dist/features/preview/components/SidebarSection.js +52 -64
  180. package/dist/features/preview/components/StudioEditingFallback.js +56 -0
  181. package/dist/features/preview/components/UnlinkAssetButton.js +104 -107
  182. package/dist/features/preview/components/blockGridNavigation.js +15 -0
  183. package/dist/features/preview/components/contentFieldSchema.js +8 -0
  184. package/dist/features/preview/components/useFieldWriter.js +200 -0
  185. package/dist/features/preview/components/useRecordView.js +383 -0
  186. package/dist/features/preview/components/useRepeatableItemActions.js +35 -37
  187. package/dist/features/preview/components/useUpdateBlockPosition.js +37 -37
  188. package/dist/features/preview/editingFrame.js +197 -0
  189. package/dist/features/preview/overlayHighlights.js +17 -44
  190. package/dist/features/preview/overlayMessages.js +72 -1
  191. package/dist/features/preview/pageRecord.js +189 -0
  192. package/dist/features/preview/previewConstants.js +6 -2
  193. package/dist/features/preview/previewPageFrame.js +95 -0
  194. package/dist/features/preview/previewPreparation.js +7 -0
  195. package/dist/features/preview/previewSelection.js +32 -63
  196. package/dist/features/preview/previewStore.js +225 -123
  197. package/dist/features/preview/referencePickerFocus.js +29 -0
  198. package/dist/features/preview/repeatableItemTargets.js +56 -0
  199. package/dist/features/preview/selectionReveal.js +21 -0
  200. package/dist/features/preview/usePreviewViewportActions.js +114 -0
  201. package/dist/features/preview/viewportContinuity.js +109 -0
  202. package/dist/features/provider/AuthenticatedCamoxProvider.js +69 -44
  203. package/dist/features/provider/CamoxProvider.d.ts +3 -6
  204. package/dist/features/provider/CamoxProvider.js +38 -50
  205. package/dist/features/provider/CoreCamoxProvider.js +66 -50
  206. package/dist/features/provider/LocalhostPreviewProvider.js +78 -114
  207. package/dist/features/provider/PreviewSignInPage.js +54 -0
  208. package/dist/features/provider/components/CamoxAppContext.js +11 -11
  209. package/dist/features/provider/components/CommandPalette.js +75 -82
  210. package/dist/features/provider/useAdminShortcuts.js +7 -11
  211. package/dist/features/routes/pageRuntime.d.ts +44 -4
  212. package/dist/features/routes/pageRuntime.js +244 -137
  213. package/dist/features/runtime/RuntimeChrome.js +117 -115
  214. package/dist/features/runtime/alternates.js +64 -0
  215. package/dist/features/runtime/analytics.d.ts +7 -0
  216. package/dist/features/runtime/analytics.js +66 -0
  217. package/dist/features/runtime/artifactSources.js +87 -0
  218. package/dist/features/runtime/editingFallback.js +20 -0
  219. package/dist/features/runtime/linkPrefetch.js +97 -0
  220. package/dist/features/runtime/livePages.js +62 -0
  221. package/dist/features/runtime/llmsTxt.js +40 -0
  222. package/dist/features/runtime/loopbackFetch.js +18 -0
  223. package/dist/features/runtime/navigationAccessibility.js +51 -0
  224. package/dist/features/runtime/navigationTarget.js +23 -2
  225. package/dist/features/runtime/pageApp.js +229 -158
  226. package/dist/features/runtime/pageBlockTypes.js +20 -0
  227. package/dist/features/runtime/pageClient.d.ts +2 -4
  228. package/dist/features/runtime/pageClient.js +18 -3
  229. package/dist/features/runtime/pageNavigation.js +254 -32
  230. package/dist/features/runtime/pageServer.d.ts +2 -4
  231. package/dist/features/runtime/pageServer.js +6 -2
  232. package/dist/features/runtime/pageViewport.js +7 -0
  233. package/dist/features/runtime/runtime.d.ts +59 -24
  234. package/dist/features/runtime/runtime.js +779 -191
  235. package/dist/features/runtime/runtimeChromeLoader.js +58 -0
  236. package/dist/features/runtime/runtimeRoutes.d.ts +19 -0
  237. package/dist/features/runtime/runtimeRoutes.js +25 -0
  238. package/dist/features/runtime/scrollRestoration.js +133 -0
  239. package/dist/features/runtime/studioApp.d.ts +4 -3
  240. package/dist/features/runtime/studioApp.js +5 -9
  241. package/dist/features/runtime/studioClient.d.ts +2 -4
  242. package/dist/features/runtime/studioClient.js +12 -3
  243. package/dist/features/runtime/studioServer.d.ts +2 -4
  244. package/dist/features/runtime/studioServer.js +6 -1
  245. package/dist/features/runtime/worker.d.ts +6 -0
  246. package/dist/features/runtime/worker.js +23 -0
  247. package/dist/features/runtime/workerRequest.js +44 -0
  248. package/dist/features/studio/CamoxStudio.d.ts +2 -6
  249. package/dist/features/studio/CamoxStudio.js +34 -49
  250. package/dist/features/studio/FollowAgentProvider.js +338 -0
  251. package/dist/features/studio/components/ChatSidebar.js +356 -0
  252. package/dist/features/studio/components/DraftsControl.js +676 -0
  253. package/dist/features/studio/components/FaviconDialog.js +318 -0
  254. package/dist/features/studio/components/LocalePicker.js +785 -0
  255. package/dist/features/studio/components/Navbar.js +123 -103
  256. package/dist/features/studio/components/ProjectMenu.js +239 -260
  257. package/dist/features/studio/components/RenameDraftDialog.js +206 -0
  258. package/dist/features/studio/components/ReviewDraftSheet.js +1472 -0
  259. package/dist/features/studio/components/ThreadComposer.js +157 -0
  260. package/dist/features/studio/components/ThreadMarkdown.js +113 -0
  261. package/dist/features/studio/components/ThreadMessages.js +270 -0
  262. package/dist/features/studio/components/UserButton.js +34 -23
  263. package/dist/features/studio/draftLabel.js +33 -0
  264. package/dist/features/studio/draftNotice.js +13 -0
  265. package/dist/features/studio/followAgent.js +250 -0
  266. package/dist/features/studio/followAgentContext.js +7 -0
  267. package/dist/features/studio/localeOptions.js +118 -0
  268. package/dist/features/studio/localeSwitch.js +19 -0
  269. package/dist/features/studio/routes.js +48 -1
  270. package/dist/features/studio/studioStore.js +64 -1
  271. package/dist/features/studio/useTheme.js +24 -27
  272. package/dist/features/vite/artifactRuntimeMinification.js +36 -0
  273. package/dist/features/vite/blockBoilerplate.js +6 -5
  274. package/dist/features/vite/blockChunks.js +31 -0
  275. package/dist/features/vite/bundlerLogs.js +17 -0
  276. package/dist/features/vite/definitionsSync.js +158 -226
  277. package/dist/features/vite/devAuthentication.js +4 -16
  278. package/dist/features/vite/devSignIn.js +87 -0
  279. package/dist/features/vite/iconGeneration.js +1 -1
  280. package/dist/features/vite/layoutGeneration.js +11 -1
  281. package/dist/features/vite/publishSeededContent.js +30 -0
  282. package/dist/features/vite/routeGeneration.js +6 -7
  283. package/dist/features/vite/runtimeDev.js +80 -99
  284. package/dist/features/vite/vite.d.ts +51 -31
  285. package/dist/features/vite/vite.js +224 -127
  286. package/dist/features/vite/workerBuild.js +39 -0
  287. package/dist/hooks/use-debounced-field.js +116 -47
  288. package/dist/hooks/use-file-upload.js +114 -67
  289. package/dist/hooks/use-marquee-selection.js +32 -36
  290. package/dist/hooks/use-page-destinations.js +69 -37
  291. package/dist/lib/api-client-server.d.ts +5 -0
  292. package/dist/lib/api-client-server.js +10 -4
  293. package/dist/lib/api-client.d.ts +6 -0
  294. package/dist/lib/api-client.js +51 -16
  295. package/dist/lib/api-socket.js +17 -0
  296. package/dist/lib/auth-page-styles.js +39 -0
  297. package/dist/lib/auth.js +117 -61
  298. package/dist/lib/collection-cache.js +23 -0
  299. package/dist/lib/draft-scope.d.ts +4 -0
  300. package/dist/lib/draft-scope.js +222 -0
  301. package/dist/lib/html.js +12 -0
  302. package/dist/lib/link-pages.js +154 -0
  303. package/dist/lib/locale-path.d.ts +22 -0
  304. package/dist/lib/locale-path.js +57 -0
  305. package/dist/lib/normalized-data.js +252 -152
  306. package/dist/lib/preview-handoff.js +2 -2
  307. package/dist/lib/queries.d.ts +11 -0
  308. package/dist/lib/queries.js +70 -141
  309. package/dist/lib/studio-reads.d.ts +14 -0
  310. package/dist/lib/studio-reads.js +574 -0
  311. package/dist/lib/use-project-room.js +50 -50
  312. package/dist/lib/use-thread.js +310 -0
  313. package/dist/lib/utils.js +25 -29
  314. package/dist/lib/view-locale-context.js +22 -0
  315. package/dist/lib/view-locale.js +46 -0
  316. package/dist/package.js +5 -0
  317. package/dist/studio-overlays.css +41 -151
  318. package/dist/studio.css +2 -2
  319. package/package.json +70 -73
  320. package/skills/camox/SKILL.md +16 -11
  321. package/skills/camox/references/artifacts.md +179 -0
  322. package/skills/camox/references/block-definitions.md +75 -59
  323. package/skills/camox/references/cli-common.md +9 -11
  324. package/skills/camox/references/cli-content.md +92 -69
  325. package/skills/camox/references/cli-publishing.md +26 -0
  326. package/skills/camox/references/dom-integrations.md +27 -0
  327. package/skills/camox/references/field-styling.md +4 -4
  328. package/skills/camox/references/layout-definitions.md +16 -14
  329. package/skills/camox/references/localization.md +56 -0
  330. package/skills/camox/references/routed-layouts.md +133 -15
  331. package/skills/camox-expand/SKILL.md +69 -0
  332. package/skills/camox-expand/references/jobs.md +39 -0
  333. package/skills/camoxify/SKILL.md +29 -7
  334. package/dist/core/components/AddBlockControlBar.js +0 -78
  335. package/dist/core/hooks/useRequireDraftSource.js +0 -23
  336. package/dist/features/metadata/sitemap.d.ts +0 -8
  337. package/dist/features/metadata/sitemap.js +0 -17
  338. package/dist/features/og/imageResponse.node.d.ts +0 -12
  339. package/dist/features/og/imageResponse.node.js +0 -49
  340. package/dist/features/og/imageResponse.workerd.d.ts +0 -12
  341. package/dist/features/og/imageResponse.workerd.js +0 -40
  342. package/dist/features/page/PublishedPageContent.js +0 -205
  343. package/dist/features/page/PublishedPageExperience.js +0 -23
  344. package/dist/features/preview/DerivedPreview.js +0 -134
  345. package/dist/features/preview/commentsEnabled.js +0 -8
  346. package/dist/features/preview/components/AddBlockSidebar.js +0 -381
  347. package/dist/features/preview/components/AttachedComments.js +0 -331
  348. package/dist/features/preview/components/CommentHeader.js +0 -122
  349. package/dist/features/preview/components/CommentSidebar.js +0 -29
  350. package/dist/features/preview/components/CommentTargetQuote.js +0 -167
  351. package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +0 -5
  352. package/dist/features/preview/components/DerivedLayoutSidebar.js +0 -179
  353. package/dist/features/preview/components/DerivedPageInfoSidebar.js +0 -69
  354. package/dist/features/preview/components/LeftSidebar.js +0 -68
  355. package/dist/features/preview/components/PageEditorSidebar.js +0 -563
  356. package/dist/features/preview/components/PageInfoSidebar.js +0 -1551
  357. package/dist/features/preview/components/PageNavigatorSidebar.js +0 -78
  358. package/dist/features/preview/components/PageStatusBadge.js +0 -97
  359. package/dist/features/preview/components/PeekedBlock.js +0 -217
  360. package/dist/features/preview/components/PreviewComments.js +0 -56
  361. package/dist/features/preview/components/PreviewToolbarSpacer.js +0 -43
  362. package/dist/features/preview/components/PublicationRow.js +0 -422
  363. package/dist/features/preview/components/PublishDialog.js +0 -194
  364. package/dist/features/preview/components/RightSidebar.js +0 -59
  365. package/dist/features/preview/components/SendFeedbackDialog.js +0 -83
  366. package/dist/features/preview/previewCommentsStore.js +0 -135
  367. package/dist/features/preview/publication.js +0 -81
  368. package/dist/features/preview/usePageComments.js +0 -39
  369. package/dist/features/runtime/SharedChromeContext.js +0 -7
  370. package/dist/features/studio/components/EnvironmentMenu.js +0 -425
  371. package/dist/features/vite/appGeneration.js +0 -89
  372. package/dist/lib/view-queries.js +0 -28
  373. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +0 -114
  374. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +0 -25
  375. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +0 -1
  376. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +0 -1
  377. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +0 -20
  378. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +0 -8
  379. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +0 -1
  380. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +0 -18
  381. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +0 -161
  382. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +0 -6
  383. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +0 -54
  384. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +0 -8
  385. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +0 -32
  386. 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
  387. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +0 -1
  388. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +0 -49
  389. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +0 -1
  390. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +0 -6
  391. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +0 -343
  392. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +0 -48
  393. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +0 -695
  394. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +0 -1
  395. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +0 -1
  396. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +0 -5
  397. 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
  398. 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
  399. 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
  400. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +0 -69
  401. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +0 -1
  402. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +0 -1
  403. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +0 -1
  404. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +0 -1
  405. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +0 -10
  406. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +0 -1
  407. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +0 -1
  408. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +0 -1
  409. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +0 -28
  410. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +0 -49
  411. package/skills/camox/references/cli-environments.md +0 -37
@@ -0,0 +1,250 @@
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
+ if (here && placement) return at({ key: here.key }, placement.id);
38
+ return elsewhere ? null : { catalog: touch.blockType };
39
+ }
40
+ function destinationOf(where, batch) {
41
+ const here = currentPage(where);
42
+ const deletedPages = new Set(batch.touches.flatMap((touch) => touch.entity === "page" && touch.kind === "deleted" && !touch.blockId ? [touch.pageId] : []));
43
+ const located = batch.touches.filter((touch) => !(touch.entity === "page" && deletedPages.has(touch.pageId))).flatMap((touch) => {
44
+ const at = locate(where, here, touch);
45
+ return at ? [at] : [];
46
+ });
47
+ const touched = /* @__PURE__ */ new Map();
48
+ const identity = (ref) => {
49
+ const page = findPage(where, ref);
50
+ return page ? `key:${page.key}` : refKey(ref);
51
+ };
52
+ for (const at of located) {
53
+ if ("catalog" in at) continue;
54
+ const key = identity(at.page);
55
+ const entry = touched.get(key) ?? {
56
+ page: at.page,
57
+ blockIds: [],
58
+ count: 0
59
+ };
60
+ entry.count += 1;
61
+ if (at.blockId && !entry.blockIds.includes(at.blockId)) entry.blockIds.push(at.blockId);
62
+ touched.set(key, entry);
63
+ }
64
+ if (touched.size === 0) {
65
+ const catalog = located.find((at) => "catalog" in at);
66
+ return catalog && "catalog" in catalog ? {
67
+ kind: "catalog",
68
+ blockType: catalog.catalog
69
+ } : null;
70
+ }
71
+ const order = (ref) => {
72
+ const page = findPage(where, ref);
73
+ return page ? where.pages.indexOf(page) : where.pages.length;
74
+ };
75
+ const entries = [...touched.values()];
76
+ 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);
77
+ return {
78
+ kind: "page",
79
+ page: chosen.page,
80
+ blockIds: chosen.blockIds
81
+ };
82
+ }
83
+ /** The topmost of the touched blocks by its order on the page; ones not shown yet come last. */
84
+ function topmostBlock(page, blockIds) {
85
+ const position = (id) => {
86
+ const index = page.blocks?.findIndex((block) => block.id === id) ?? -1;
87
+ return index === -1 ? Infinity : index;
88
+ };
89
+ return [...blockIds].sort((a, b) => position(a) - position(b))[0];
90
+ }
91
+ /**
92
+ * Following the agent on the Canvas or in the Preview: each touched batch gives at most one
93
+ * destination, which the Studio goes to through the existing selection. Pages are selected
94
+ * through the URL, replacing the history entry, and blocks through the preview store once the
95
+ * destination page's editing frame is active.
96
+ */
97
+ function createFollowAgent({ navigate, where: initial }) {
98
+ let where = initial;
99
+ let following = true;
100
+ /** When following last arrived on another page; it stays there for the minimum stay. */
101
+ let arrivedAt = -Infinity;
102
+ /** The latest destination on another page, waiting for the minimum stay or for its page. */
103
+ let pendingNavigation = null;
104
+ /** When the pending destination's page has to show by, once following could go there. */
105
+ let pendingNavigationUntil = 0;
106
+ let timer = null;
107
+ /** Blocks to select once their page's editing frame is active. */
108
+ let blocksToSelect = null;
109
+ /** The block following last selected, to move to a topmost one that shows later. */
110
+ let selected = null;
111
+ /** The block following selected last, whichever page it's on, to tell the editor's apart. */
112
+ let ownSelection = null;
113
+ /** Selects the topmost of the touched blocks on `page`, if one shows. */
114
+ const selectTopmost = (touched, page) => {
115
+ const blockId = topmostBlock(page, touched.blockIds);
116
+ if (!blockId) return;
117
+ selected = {
118
+ page: touched.page,
119
+ blockIds: touched.blockIds,
120
+ blockId
121
+ };
122
+ ownSelection = {
123
+ owner: page.owner,
124
+ blockId
125
+ };
126
+ previewStore.send({
127
+ type: "setFocusedBlock",
128
+ ...page.owner,
129
+ blockId
130
+ });
131
+ };
132
+ const selectBlocks = () => {
133
+ if (!blocksToSelect) return;
134
+ const page = findPage(where, blocksToSelect.page);
135
+ const { editingContext } = previewStore.getSnapshot().context;
136
+ if (!page || !sameEditingOwner(editingContext, page.owner)) return;
137
+ const touched = blocksToSelect;
138
+ blocksToSelect = null;
139
+ selectTopmost(touched, page);
140
+ };
141
+ /** Reselects when a touched block above the selected one shows, while the selection is ours. */
142
+ const reselectTopmost = () => {
143
+ if (!selected) return;
144
+ const page = findPage(where, selected.page);
145
+ const selection = previewStore.getSnapshot().context.editingContext?.selection;
146
+ if (!page || selection?.type !== "block" || selection.blockId !== selected.blockId) {
147
+ selected = null;
148
+ return;
149
+ }
150
+ if (topmostBlock(page, selected.blockIds) !== selected.blockId) selectTopmost(selected, page);
151
+ };
152
+ const clearTimer = () => {
153
+ if (timer !== null) clearTimeout(timer);
154
+ timer = null;
155
+ };
156
+ /** Goes to the pending destination, once the minimum stay is over and its page is known. */
157
+ const navigatePending = () => {
158
+ if (!pendingNavigation) return;
159
+ const wait = arrivedAt + FOLLOW_MINIMUM_STAY - Date.now();
160
+ if (wait > 0) {
161
+ timer ??= setTimeout(() => {
162
+ timer = null;
163
+ navigatePending();
164
+ }, wait);
165
+ return;
166
+ }
167
+ if (Date.now() >= pendingNavigationUntil) {
168
+ pendingNavigation = null;
169
+ return;
170
+ }
171
+ const destination = pendingNavigation;
172
+ const pathname = destination.kind === "catalog" ? where.blockCatalogPath(destination.blockType) : findPage(where, destination.page)?.pathname;
173
+ if (!pathname) return;
174
+ pendingNavigation = null;
175
+ arrivedAt = Date.now();
176
+ blocksToSelect = destination.kind === "page" && destination.blockIds.length ? destination : null;
177
+ selected = null;
178
+ navigate({
179
+ to: `${pathname}${where.location.search}`,
180
+ replace: true,
181
+ source: "follow"
182
+ });
183
+ };
184
+ /**
185
+ * Whether the editor selected something themselves: a selection following didn't make.
186
+ * Clearing it isn't one, as frames do when the Canvas mounts or a navigation releases them.
187
+ */
188
+ const editorSelected = () => {
189
+ const { editingContext } = previewStore.getSnapshot().context;
190
+ const selection = editingContext?.selection;
191
+ if (!selection) return false;
192
+ return !(ownSelection && selection.type === "block" && selection.blockId === ownSelection.blockId && sameEditingOwner(editingContext, ownSelection.owner));
193
+ };
194
+ let lastSelection = previewStore.getSnapshot().context.editingContext?.selection ?? null;
195
+ const subscription = previewStore.subscribe(({ context }) => {
196
+ const selection = context.editingContext?.selection ?? null;
197
+ const changed = selection !== lastSelection;
198
+ lastSelection = selection;
199
+ if (changed && editorSelected()) {
200
+ follow.takeOver();
201
+ return;
202
+ }
203
+ selectBlocks();
204
+ });
205
+ const follow = {
206
+ receive(batch) {
207
+ if (!following) return;
208
+ const destination = destinationOf(where, batch);
209
+ if (!destination) return;
210
+ const here = currentPage(where);
211
+ if (destination.kind === "page" && here && findPage(where, destination.page) === here) {
212
+ pendingNavigation = null;
213
+ clearTimer();
214
+ if (!destination.blockIds.length) return;
215
+ blocksToSelect = destination;
216
+ selectBlocks();
217
+ return;
218
+ }
219
+ pendingNavigation = destination;
220
+ pendingNavigationUntil = Math.max(Date.now(), arrivedAt + FOLLOW_MINIMUM_STAY) + FOLLOW_MINIMUM_STAY;
221
+ navigatePending();
222
+ },
223
+ update(next) {
224
+ const navigated = next.location.pathname !== where.location.pathname;
225
+ where = next;
226
+ if (navigated && next.location.source === void 0) follow.takeOver();
227
+ navigatePending();
228
+ selectBlocks();
229
+ reselectTopmost();
230
+ },
231
+ takeOver() {
232
+ following = false;
233
+ pendingNavigation = null;
234
+ blocksToSelect = null;
235
+ selected = null;
236
+ clearTimer();
237
+ },
238
+ resume() {
239
+ following = true;
240
+ },
241
+ dispose() {
242
+ clearTimer();
243
+ subscription.unsubscribe();
244
+ }
245
+ };
246
+ return follow;
247
+ }
248
+
249
+ //#endregion
250
+ 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,53 @@
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`;
30
+ const STUDIO_BLOCKS_PATH = `${STUDIO_BASE_PATH}/blocks`;
31
+ /** The Studio URL of a block of the Block Catalog. */
32
+ const blockCatalogPath = (blockId) => `${STUDIO_BLOCKS_PATH}/${encodeURIComponent(blockId)}`;
33
+ /** The id of the Block Catalog block a pathname selects, if any. */
34
+ function matchBlockCatalogPath(pathname) {
35
+ const match = /^\/camox\/blocks\/([^/]+)$/.exec(pathname);
36
+ if (!match) return null;
37
+ try {
38
+ return decodeURIComponent(match[1]) || null;
39
+ } catch {
40
+ return null;
41
+ }
42
+ }
43
+ /**
44
+ * A location that only exists on the Canvas: the Canvas with
45
+ * nothing selected, or a block of the Block Catalog.
46
+ */
47
+ function matchCanvasOnlyPath(pathname) {
48
+ if (pathname === "/camox/canvas") return {};
49
+ const blockId = matchBlockCatalogPath(pathname);
50
+ return blockId ? { blockId } : null;
51
+ }
5
52
 
6
53
  //#endregion
7
- export { STUDIO_BASE_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT };
54
+ export { STUDIO_ASSETS_PATH, STUDIO_BASE_PATH, STUDIO_BLOCKS_PATH, STUDIO_CANVAS_PATH, STUDIO_CONTENT_PATH, STUDIO_ROUTE_SEGMENT, blockCatalogPath, collectionContentPath, matchBlockCatalogPath, matchCanvasOnlyPath, 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 {