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
@@ -9,15 +9,15 @@ When asked to add a section, also place an instance after dev-server discovery u
9
9
  Use one `.tsx` file per block in `src/blocks/`, a named `block` export (not default), a named function component, and Tailwind styling.
10
10
 
11
11
  ```tsx
12
- import { Type, createBlock } from "camox/createBlock";
12
+ import { createBlock } from "camox/createBlock";
13
13
 
14
14
  const myBlock = createBlock({
15
15
  id: "my-block",
16
16
  title: "My Block",
17
17
  description: "A page introduction with an editable heading.",
18
- content: {
19
- title: Type.String({ default: "Welcome" }),
20
- },
18
+ content: (field) => ({
19
+ title: field.string({ default: "Welcome" }),
20
+ }),
21
21
  component: MyBlockComponent,
22
22
  toMarkdown: (c) => [`# ${c.title}`],
23
23
  });
@@ -33,34 +33,33 @@ function MyBlockComponent() {
33
33
  export { myBlock as block };
34
34
  ```
35
35
 
36
- For DOM listeners, scrolling, scripts, or widgets, read [DOM integrations](dom-integrations.md). Preview DOM lives in an iframe; use `getElementContext` from `camox/dom`, not component-global `window` or `document`.
36
+ For DOM listeners, scrolling, scripts, widgets, or JavaScript-driven animation, read [DOM integrations](dom-integrations.md). Preview DOM lives in an iframe; use `getElementContext` from `camox/dom`, not component-global `window` or `document`.
37
37
 
38
38
  ## The `createBlock` options
39
39
 
40
- | Option | Required | Description |
41
- | ------------- | -------- | --------------------------------------------------------------------------------------------- |
42
- | `id` | yes | Unique kebab-case identifier matching the filename without extension. |
43
- | `title` | yes | CMS display name. |
44
- | `description` | yes | Agent guidance on placement, expected content, and tone. |
45
- | `content` | yes | Field names mapped to `Type.*` schemas for editable content. |
46
- | `settings` | no | Settings-panel fields; only `Type.Enum` and `Type.Boolean`. |
47
- | `layoutOnly` | no | If true, restricts placement to layouts and hides the type from the add-block picker. |
48
- | `synced` | no | Defaults to false. Shares content/settings across instances within an environment; see below. |
49
- | `component` | yes | Named React function component. |
50
- | `toMarkdown` | yes | `(c, s) => [...]` markdown builder; see below. |
40
+ | Option | Required | Description |
41
+ | ------------- | -------- | -------------------------------------------------------------------------------------------- |
42
+ | `id` | yes | Unique kebab-case identifier matching the filename without extension. |
43
+ | `title` | yes | CMS display name. |
44
+ | `description` | yes | Agent guidance on placement, expected content, and tone. |
45
+ | `content` | yes | `(field) => ({ ... })`: field names mapped to `field.*` builders for editable content. |
46
+ | `settings` | no | `(setting) => ({ ... })`: settings-panel options; only `setting.enum` and `setting.boolean`. |
47
+ | `layoutOnly` | no | If true, restricts placement to layouts and hides the type from the add-block picker. |
48
+ | `synced` | no | Defaults to false. Shares content/settings across placements; see below. |
49
+ | `component` | yes | Named React function component. |
50
+ | `toMarkdown` | yes | `(c, s) => [...]` markdown builder; see below. |
51
51
 
52
52
  ## Synced blocks (`synced`, optional)
53
53
 
54
- `synced: true` shares content and settings, including nested repeater items and their settings, across every instance of the block **type** within one environment. Dev and production remain independent. Synced blocks have purple editor highlights.
54
+ `synced: true` shares content and settings, including nested repeatable items and their settings, across every placement of the block **definition**. Like any content, the shared content is changed in a draft and reaches Live when the draft is published. Synced blocks have purple editor highlights.
55
55
 
56
56
  For shared navbar/footer data across layouts, use `layoutOnly: true, synced: true`. These flags are independent: synced blocks can also be ordinary page-content blocks.
57
57
 
58
- - Editing any instance updates the shared draft everywhere. New instances reuse existing data rather than resetting to defaults.
59
- - Position, placement, and deletion remain per instance; deleting one placement leaves the others.
60
- - Publishing a page or layout containing the block publishes shared data for all live instances. Unpublished drafts do not leak into live.
61
- - Enabling syncing on an existing type applies the oldest instance's data to all instances. Disabling it leaves independently editable copies.
58
+ - Editing any placement updates the shared content everywhere. New placements reuse existing data rather than resetting to defaults.
59
+ - Position, layout slot, and deletion remain per placement; deleting one placement leaves the others.
60
+ - Enabling syncing on an existing type applies the oldest placement's data to all placements. Disabling it leaves independently editable copies.
62
61
 
63
- ## Markdown Template (`toMarkdown`)
62
+ ## Markdown Representation (`toMarkdown`)
64
63
 
65
64
  Required on blocks and repeaters. Receives typed proxies `c` (content) and `s` (settings); returns entries joined with `\n\n` for AI summaries and SEO. Lines whose referenced fields are all empty, or whose condition is false, are omitted.
66
65
 
@@ -101,14 +100,14 @@ Only Boolean/Enum settings support these conditionals. A repeater's `s` refers t
101
100
 
102
101
  ## Content Field Types
103
102
 
104
- Import `Type` from `"camox/createBlock"`. Supply defaults for scalar fields; images/files get automatic placeholders, lists use `defaultItems`, and repeaters use their item schemas and bounds.
103
+ `content` and a repeater's `content` receive a `field` builder; `settings` receive a `setting` builder. Each builder only offers what its context accepts: `field` has no `enum` or `boolean`, and `setting` has nothing else. Supply defaults for scalar fields; images/files get automatic placeholders (empty images paint with the stylesheet's `--camox-placeholder` and `--camox-placeholder-ink`), lists use `defaultItems`, and repeaters use their item schemas and bounds.
105
104
 
106
- ### Type.String
105
+ ### field.string
107
106
 
108
107
  Inline-editable text supporting formatting and links while remaining a string. See [Field styling](field-styling.md) for formatting syntax and appearance customization.
109
108
 
110
109
  ```tsx
111
- Type.String({
110
+ field.string({
112
111
  default: "Hello world",
113
112
  title: "Heading", // Optional label
114
113
  maxLength: 280, // Optional
@@ -117,22 +116,22 @@ Type.String({
117
116
  });
118
117
  ```
119
118
 
120
- ### Type.Icon
119
+ ### field.icon
121
120
 
122
121
  Choose one Iconify collection in Vite config:
123
122
 
124
123
  ```ts
125
- camox({ projectSlug: "my-project", icons: "lucide" });
124
+ camox({ projectId: "01a15fff-627b-7fa1-938b-93ab659c1acc", icons: "lucide" });
126
125
  ```
127
126
 
128
127
  Declare a non-nullable icon with a required, prefixed default, then render inline SVG:
129
128
 
130
129
  ```tsx
131
130
  // In content:
132
- icon: Type.Icon({ default: "lucide:zap", title: "Icon" })
131
+ icon: field.icon({ default: "lucide:zap", title: "Icon" })
133
132
 
134
133
  // In the component (also supported as <item.Icon> inside repeaters):
135
- <block.Icon name="icon" className="size-6 text-primary" />
134
+ <block.Icon name="icon" className="size-6 text-brand" />
136
135
  <block.Icon name="icon" aria-label="Fast" />
137
136
  ```
138
137
 
@@ -144,25 +143,27 @@ Camox resolves selected SVGs from that same versioned snapshot and serves them t
144
143
 
145
144
  Collection licenses still apply. SVG responses retain author/license attribution. Include any copyright notices, license text, or attribution required by your chosen collection in your site's distributed notices; Iconify does not relicense the icons. Changing collections or migrating existing icon values is not supported in v1.
146
145
 
147
- ### Type.Boolean and Type.Enum
146
+ ### setting.boolean and setting.enum
148
147
 
149
- Use in `settings` for configuration or `content` for editable values. Enum defaults must match an option key.
148
+ Settings only: configuration choices are never block or repeater content. Enum defaults must match an option key.
150
149
 
151
150
  ```tsx
152
- Type.Boolean({ default: false, title: "Show background" });
153
- Type.Enum({
151
+ settings: (setting) => ({
152
+ showBackground: setting.boolean({ default: false, title: "Show background" }),
153
+ alignment: setting.enum({
154
154
  default: "left",
155
- options: { left: "Left", center: "Center", right: "Right" },
156
- title: "Alignment",
157
- });
155
+ options: { left: "Left", center: "Center", right: "Right" },
156
+ title: "Alignment",
157
+ }),
158
+ }),
158
159
  ```
159
160
 
160
- ### Type.Link
161
+ ### field.link
161
162
 
162
163
  Text, destination, and new-tab toggle. Curated page links store page IDs; singleton links store fixed URLs using the existing `type: "external"` representation, which also supports site-relative URLs: `{ type: "external", href: "/pokedex", text: "Pokédex", newTab: false }`. Both page kinds appear in Studio's destination picker. Inline `[Pokédex](/pokedex)` links stay in the current tab.
163
164
 
164
165
  ```tsx
165
- Type.Link({
166
+ field.link({
166
167
  default: { text: "Learn more", href: "/", newTab: false },
167
168
  title: "CTA",
168
169
  });
@@ -173,38 +174,50 @@ Type.Link({
173
174
  Files support MIME filtering. Render each type with its matching helper; asset lists are **not** repeaters.
174
175
 
175
176
  ```tsx
176
- Type.Image({ title: "Cover photo" });
177
- Type.ImageList({ defaultItems: 6, title: "Gallery images" });
178
- Type.File({ accept: ["application/pdf"], title: "PDF Document" });
179
- Type.FileList({ accept: ["application/pdf"], defaultItems: 0, title: "Documents" });
177
+ field.image({ title: "Cover photo" });
178
+ field.imageList({ defaultItems: 6, title: "Gallery images" });
179
+ field.file({ accept: ["application/pdf"], title: "PDF Document" });
180
+ field.fileList({ accept: ["application/pdf"], defaultItems: 0, title: "Documents" });
180
181
  ```
181
182
 
182
- ### Type.Embed
183
+ ### field.embed
183
184
 
184
185
  A URL validated against a regex. A nonmatching default throws at definition time.
185
186
 
186
187
  ```tsx
187
- Type.Embed({
188
+ field.embed({
188
189
  pattern: "https:\\/\\/(www\\.)?(youtube\\.com|youtu\\.be)\\/.+",
189
190
  default: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
190
191
  title: "YouTube URL",
191
192
  });
192
193
  ```
193
194
 
194
- ### Type.Repeater
195
+ ### field.artifact
196
+
197
+ A sandboxed web page stored as content, for bespoke visuals and widgets. Read [Artifacts](artifacts.md) before declaring one.
198
+
199
+ ```tsx
200
+ field.artifact({ size: "fill", title: "Hero visual" });
201
+ field.artifact({ size: "fill", data: ["headline", "variant"] }); // shares sibling fields and settings
202
+ ```
203
+
204
+ ### field.repeater
195
205
 
196
206
  Structured items with their own content, optional settings, and required `toMarkdown`. `minItems` must be at least 1; repeaters cannot be empty. Nest repeaters in an item's `content` when needed.
197
207
 
198
208
  ```tsx
199
- Type.Repeater({
200
- content: {
201
- name: Type.String({ default: "Feature" }),
202
- description: Type.String({ default: "Description" }),
203
- },
209
+ field.repeater({
210
+ content: (field) => ({
211
+ name: field.string({ default: "Feature" }),
212
+ description: field.string({ default: "Description" }),
213
+ }),
214
+ settings: (setting) => ({
215
+ highlighted: setting.boolean({ default: false, title: "Highlighted" }),
216
+ }),
204
217
  minItems: 1,
205
218
  maxItems: 10,
206
219
  title: "Features",
207
- toMarkdown: (c) => [`### ${c.name}`, c.description],
220
+ toMarkdown: (c, s) => [`### ${c.name}`, s.highlighted(c.description)],
208
221
  });
209
222
  ```
210
223
 
@@ -219,7 +232,7 @@ Field renderers receive `(props, data)`:
219
232
 
220
233
  ### Strings — `block.Field`
221
234
 
222
- `name` must select a `Type.String` field. `props.children` contains Camox's rendered inline markup.
235
+ `name` must select a `field.string` field. `props.children` contains Camox's rendered inline markup.
223
236
 
224
237
  ```tsx
225
238
  <myBlock.Field name="title">{(props) => <h1 {...props} />}</myBlock.Field>
@@ -233,7 +246,7 @@ For `textStyle` and `linkStyle`, read [Field styling](field-styling.md).
233
246
 
234
247
  ### Links — `block.Link`
235
248
 
236
- Use `Link` from `camox/navigation`, not `<a>`, for client-side internal navigation. `props` supplies `to`, `target`, and `rel`; raw `data` exposes `{ text, href, newTab }`.
249
+ Use `Link` from `camox/navigation`, not `<a>`, for client-side internal navigation. `props` supplies `to`, `target`, and `rel`; raw `data` exposes `{ text, href, newTab }`. Render link fields as they come; a path written in code goes through `useLocalizedHref` (see [Localization](localization.md#internal-links-stay-in-the-locale)).
237
250
 
238
251
  ```tsx
239
252
  import { Link } from "camox/navigation";
@@ -255,12 +268,15 @@ import { Link } from "camox/navigation";
255
268
 
256
269
  ### Repeaters — `block.Repeater`
257
270
 
258
- The callback receives an item-scoped API with the same `.Field`, `.Link`, `.Image`, `.File`, `.Embed`, `.ImageList`, `.FileList`, and `.Repeater` methods.
271
+ The callback signature is `(item, index) => ReactNode`:
272
+
273
+ - `item` is an item-scoped API with the same `.Field`, `.Link`, `.Image`, `.File`, `.Embed`, `.Artifact`, `.ImageList`, `.FileList`, and `.Repeater` methods.
274
+ - `index` is the item's zero-based position in the current repeater. Use it for position-based behavior such as first-item styling, numbering, or matching tabs to panels without comparing editable text. It changes when items are reordered or removed; it is not a stable item ID.
259
275
 
260
276
  ```tsx
261
277
  <myBlock.Repeater name="features">
262
- {(item) => (
263
- <div>
278
+ {(item, index) => (
279
+ <div className={index === 0 ? "featured" : undefined}>
264
280
  <item.Field name="name">{(props) => <h3 {...props} />}</item.Field>
265
281
  <item.Field name="description">{(props) => <p {...props} />}</item.Field>
266
282
  </div>
@@ -268,7 +284,7 @@ The callback receives an item-scoped API with the same `.Field`, `.Link`, `.Imag
268
284
  </myBlock.Repeater>
269
285
  ```
270
286
 
271
- Nested repeaters use the item-scoped `.Repeater`:
287
+ Nested repeaters use the item-scoped `.Repeater` with the same `(item, index)` callback signature. Each index is local to its repeater, so the inner index starts at `0` for each parent item. Omit the index parameter when it is not needed:
272
288
 
273
289
  ```tsx
274
290
  <footer.Repeater name="columns">
@@ -292,7 +308,7 @@ Use the matching helper, **not `block.Repeater`**. Its `(props, data)` callback
292
308
 
293
309
  ### Settings — `block.useSetting`
294
310
 
295
- Read settings inside the component with `myBlock.useSetting("theme")`.
311
+ Read settings inside the component with `myBlock.useSetting("name")`. For example, `myBlock.useSetting("scheme")` returns the color scheme an editor picked in the block's "Color scheme" setting.
296
312
 
297
313
  ### Detached rendering — `block.Detached`
298
314
 
@@ -301,7 +317,7 @@ Renders outside the block's DOM container for fixed/floating elements. Spread it
301
317
  ```tsx
302
318
  <myBlock.Detached>
303
319
  {(props) => (
304
- <div {...props} className="fixed top-0 left-0 right-0 z-50">
320
+ <div {...props} className="fixed top-0 right-0 left-0 z-50">
305
321
  {/* floating content */}
306
322
  </div>
307
323
  )}
@@ -1,6 +1,6 @@
1
1
  # Camox CLI common guidance
2
2
 
3
- Use the Camox CLI for CRUD operations on Pages, Block instances, Layout assignments, metadata, drafts, and published content. Use the code references instead when changing Block Definitions or Layout Definitions in `src/blocks/` or `src/layouts/`.
3
+ Use the Camox CLI for CRUD operations on Pages, Blocks, Layout assignments, and metadata. Use the code references instead when changing Block Definitions or Layout Definitions in `src/blocks/` or `src/layouts/`.
4
4
 
5
5
  If a change should be visible without a code deployment, it is usually a CLI content operation. Some requests require both code and CLI work: define the new type first, wait for the dev server to discover it, then create or assign its content through the CLI.
6
6
 
@@ -26,27 +26,25 @@ Before a write, verify the relevant subcommand's `--help` unless already checked
26
26
 
27
27
  Use root or group help only to discover unfamiliar commands. Reuse verified help within the session; recheck if the installed version changes. Installed help overrides these examples—do not guess commands or flags.
28
28
 
29
- ## Draft-first workflow
29
+ ## Dev-first workflow
30
30
 
31
- By default, reads and writes operate on the draft in the current developer's isolated dev Environment. Make content changes in draft, summarize them for review, and publish only after the user asks or approves.
31
+ Every command reads and writes the current developer's development draft, never Live. Make content changes there and summarize them for review; they reach Live only when the draft is published (see [CLI Publishing](cli-publishing.md)). Don't publish unless the user asks.
32
32
 
33
- - Omit `--live` while editing. `--live` only reads the published snapshot.
34
- - Omit `--production` unless the user explicitly asks to operate on the production Environment.
35
- - Publishing a draft and replicating an Environment are different operations. Read the Environment reference before using `env push` or `env pull`.
33
+ - If a command fails with "run the site locally first", the development draft doesn't exist yet: the dev server creates it on its first sync after `camox login`.
36
34
 
37
- ## Verify drafts in a browser
35
+ ## Verify changes in a browser
38
36
 
39
- CLI credentials and browser sessions are separate. A fresh browser shows published content until it signs in, even when CLI draft writes succeeded.
37
+ CLI credentials and browser sessions are separate. A fresh browser isn't signed in, even when CLI writes succeeded.
40
38
 
41
39
  1. Start the app's dev server and check `{{CAMOX_CMD}} preview --help`.
42
40
  2. Generate a handoff for the page you changed:
43
41
  `{{CAMOX_CMD}} preview --url http://localhost:3000/about --json`
44
42
  (Use the actual port; add `--cwd apps/site` in a monorepo.)
45
43
  3. Open the returned `url` in your verification browser, not a separate default browser.
46
- 4. Wait for `[data-camox-preview="ready"]`. Its text identifies the project and developer environment; the server has loaded authenticated draft content. `[data-camox-preview="error"]` means verification failed, not that the write failed.
47
- 5. Inspect the changed content. Do not publish merely to make it visible.
44
+ 4. Wait for `[data-camox-preview="ready"]`. Its text identifies the project and the development draft; the server has loaded authenticated content. `[data-camox-preview="error"]` means verification failed, not that the write failed.
45
+ 5. Inspect the changed content.
48
46
 
49
- The URL is a single-use sign-in credential valid for three minutes. Do not share, commit, or include it in reports. Generate a new URL if expired or consumed. Only loopback HTTP(S) destinations are supported; production preview is intentionally unsupported. The SDK must support this handoff: if the ready marker never appears, check the installed SDK version rather than assuming the page is a draft. A project/backend/environment mismatch requires correcting `--cwd` or `--url` (or restarting a dev server running under another account).
47
+ The URL is a single-use sign-in credential valid for three minutes. Do not share, commit, or include it in reports. Generate a new URL if expired or consumed. Only loopback HTTP(S) destinations are supported; previewing a deployed site is intentionally unsupported. The SDK must support this handoff: if the ready marker never appears, check the installed SDK version rather than assuming the write failed. A project or backend mismatch requires correcting `--cwd` or `--url` (or restarting a dev server running under another account).
50
48
 
51
49
  ## Write grounded content
52
50
 
@@ -1,8 +1,8 @@
1
1
  # Managing Pages and Blocks with the Camox CLI
2
2
 
3
- Read [cli-common.md](cli-common.md) first for `{{CAMOX_CMD}}`, help verification, and draft-first rules.
3
+ Read [cli-common.md](cli-common.md) first for `{{CAMOX_CMD}}`, help verification, and the dev-first workflow.
4
4
 
5
- Use these commands for Pages, metadata, Layout assignments, Block instances and their Content, draft review, and publishing. To change Block schemas or rendering, read [Block Definitions](block-definitions.md); to create or change Layout Definitions, follow the code-definition routing in [the Camox skill](../SKILL.md).
5
+ Use these commands for Pages, metadata, Layout assignments, Blocks and their Content, and review. To change Block schemas or rendering, read [Block Definitions](block-definitions.md); to create or change Layout Definitions, follow the code-definition routing in [the Camox skill](../SKILL.md).
6
6
 
7
7
  ## Pages
8
8
 
@@ -10,40 +10,33 @@ Use these commands for Pages, metadata, Layout assignments, Block instances and
10
10
 
11
11
  ```sh
12
12
  {{CAMOX_CMD}} layouts list
13
- {{CAMOX_CMD}} pages create --path-segment about --layout-id 39
13
+ {{CAMOX_CMD}} pages create --path-segment about --layout-id default
14
14
  ```
15
15
 
16
+ `--layout-id` takes a Layout's name, the `layoutId` listed by `layouts list`.
17
+
16
18
  Use `--parent-page-id <ID>` to nest the Page under another Page.
17
19
 
18
20
  ### Read and edit SEO metadata
19
21
 
20
22
  ```sh
21
23
  {{CAMOX_CMD}} pages get --path /about
22
- {{CAMOX_CMD}} pages update --path /about --meta-title "About us" --meta-description "Meet the team."
23
- {{CAMOX_CMD}} pages update --id 25 --meta-description ""
24
- {{CAMOX_CMD}} pages update --id 25 --ai-seo on
25
- {{CAMOX_CMD}} pages update --id 25 --ai-seo off
24
+ {{CAMOX_CMD}} pages set-seo --path /about --meta-title "About us" --meta-description "Meet the team."
25
+ {{CAMOX_CMD}} pages set-seo --id <PAGE_UUID> --meta-description ""
26
+ {{CAMOX_CMD}} pages set-seo --id <PAGE_UUID> --ai-seo on
27
+ {{CAMOX_CMD}} pages set-seo --id <PAGE_UUID> --ai-seo off
26
28
  ```
27
29
 
28
- Updates accept exactly one of `--id` or `--path` and require at least one update
29
- field. Omitted fields are preserved; an empty string clears a metadata field.
30
- Setting either metadata field disables automatic SEO for both fields and cannot
31
- be combined with `--ai-seo on`. Disabling AI preserves current metadata; enabling
32
- it schedules asynchronous generation, so read the Page again to inspect results.
33
-
34
- Metadata edits affect only the draft, even with `--production`. Read published
35
- metadata with `pages get --live`; publish only after user approval.
36
-
37
- ## Comments
30
+ `set-seo` accepts exactly one of `--id` or `--path` and requires at least one of
31
+ `--meta-title`, `--meta-description` or `--ai-seo`. The meta title and
32
+ description are one group: writing either field makes both manual, keeping the
33
+ current value of the other, and cannot be combined with `--ai-seo on`.
34
+ `--ai-seo off` keeps current metadata as manual; `--ai-seo on` schedules
35
+ asynchronous generation, so read the Page again to inspect results. An empty
36
+ meta title blocks publishing.
38
37
 
39
- List a Page's comments, then use a returned comment `id` to resolve one on that same Page:
40
-
41
- ```sh
42
- {{CAMOX_CMD}} comments list --page-id 25
43
- {{CAMOX_CMD}} comments resolve --page-id 25 --id <COMMENT_UUID>
44
- ```
45
-
46
- `--page-id` is the numeric Page ID (find it with `pages get --path /about`); `--id` is the comment's UUID, not a Block or Page ID. Resolution changes the comment's status, not the Page's draft or published content. Check `comments resolve --help` before writing, per [CLI common guidance](cli-common.md). Use `--json` for structured output; `--project`, `--production`, and `--cwd` select the same project, environment, and working directory as other CLI commands.
38
+ Metadata edits apply right away in the development draft. Read metadata
39
+ with `pages get`.
47
40
 
48
41
  ## Blocks
49
42
 
@@ -56,13 +49,41 @@ Look up the Page before creating or moving Blocks so you have its `id`, current
56
49
  {{CAMOX_CMD}} blocks describe --type hero
57
50
  ```
58
51
 
52
+ ### Find shared navigation and footer Blocks
53
+
54
+ `pages get` returns page-owned Blocks, not the Layout's shared shell. Inspect
55
+ the Layout to discover navigation, footer, and other layout-owned block IDs:
56
+
57
+ ```sh
58
+ {{CAMOX_CMD}} layouts list
59
+ {{CAMOX_CMD}} layouts get --layout-id default
60
+ {{CAMOX_CMD}} blocks get --id <BLOCK_UUID>
61
+ {{CAMOX_CMD}} blocks edit --id <BLOCK_UUID> --content '{"title": "Updated title"}'
62
+ ```
63
+
64
+ Pass the Layout's name, the `layoutId` from `layouts list` (also the Page's
65
+ `layoutId`), to `layouts get --layout-id`. The response
66
+ includes `blocks` with `id`, `type`, `slot`, and Content, plus
67
+ `layout.beforeBlockIds` and `layout.afterBlockIds`. Pass a Block's `id` to
68
+ `blocks get` and `blocks edit`; do not use the Layout ID or Block type.
69
+ Inspect the Block's schema and current Content before editing, and preserve
70
+ repeatable items as described below.
71
+
72
+ Keep `--project` and `--cwd` consistent across the discovery and editing
73
+ commands. Shared shell edits affect every Page using that Layout,
74
+ and synced Block types can share Content across Layouts.
75
+
59
76
  ### Create and position a Block
60
77
 
61
78
  ```sh
62
- {{CAMOX_CMD}} blocks create --page-id 25 --type hero --content '{...}' --position first
79
+ {{CAMOX_CMD}} blocks create --page-id <PAGE_UUID> --type hero --content '{...}' --position first
63
80
  ```
64
81
 
65
- Creation initializes omitted Content and Settings fields from the Block definition's defaults, including when `--content '{}'` is supplied. Explicit field values—including `""`, `null`, `false`, and `[]`—are preserved; defaults do not merge into a supplied Link object. Omitted Repeaters initialize their default item count (or minimum count) with item defaults; supplying an array uses exactly those items, and `[]` creates none. Asset placeholders are not stored. Existing synced Block data still takes precedence for synced types.
82
+ Creation initializes omitted Content and Settings fields from the Block definition's defaults, including when `--content '{}'` is supplied. Explicit values are not replaced by defaults and must satisfy the field's JSON Schema; defaults do not merge into a supplied Link object. Omitted Repeaters initialize their default item count (or minimum count) with item defaults. Supplied arrays use exactly those items and must satisfy `minItems`/`maxItems`; `[]` is accepted only when the minimum allows it. Asset placeholders are not stored. Existing synced Block data still takes precedence for synced types.
83
+
84
+ Content and Settings writes are validated server-side against the development draft's definitions before mutation. Validation errors include field paths. String fields contain Markdown strings (not rich-text JSON objects); Embed fields contain strings matching their pattern. Assets use managed `{ "_fileId": "<file UUIDv7>" }` references, with asset lists stored as arrays of references. Asset normalization drops hydrated URL metadata and converts placeholders to null.
85
+
86
+ Updates validate only submitted fields, so unrelated historical invalid values do not prevent an edit. New records validate after defaults are applied. Unknown properties follow the schema's `additionalProperties` policy (allowed when unspecified); missing definitions retain legacy permissive behavior. Saved snapshots are not retroactively migrated or revalidated when restored.
66
87
 
67
88
  Supply reference-specific copy, links, assets, and items directly as instance Content. Definition defaults should remain neutral, reusable examples—not a way to populate a reference site.
68
89
 
@@ -85,74 +106,76 @@ Content patches merge ordinary fields, so send only fields that should change:
85
106
 
86
107
  ```sh
87
108
  {{CAMOX_CMD}} pages get --path /pricing
88
- {{CAMOX_CMD}} blocks edit --id 314 --content '{"headline": "New headline"}'
109
+ {{CAMOX_CMD}} blocks edit --id <BLOCK_UUID> --content '{"headline": "New headline"}'
89
110
  ```
90
111
 
91
- ### Edit repeatable Content safely
112
+ ### Set string fields from files
92
113
 
93
- A repeatable field's array is replacement-shaped: omitting an existing item deletes it and cascades to its file references, settings, and nested items. Fetch the Block, preserve every existing item with `_itemId`, and add changes only to the intended entries:
114
+ Use `--field-file <NAME>=<PATH>` on `blocks create` and `blocks edit` to set a top-level string field to a file's raw contents, without escaping it into JSON. It suits long Markdown and [Artifact](artifacts.md) sources. Repeat the flag to set several fields. It merges with `--content`; when both set the same field, the file wins. On `blocks create`, pass `--content`, `--field-file`, or both.
94
115
 
95
116
  ```sh
96
- {{CAMOX_CMD}} blocks get --id 99
97
-
98
- {{CAMOX_CMD}} blocks edit --id 99 --content '{
99
- "items": [
100
- {"_itemId": 401},
101
- {"_itemId": 402, "answer": "Updated answer."},
102
- {"_itemId": 403}
103
- ]
104
- }'
117
+ {{CAMOX_CMD}} blocks edit --id <BLOCK_UUID> --content '{"title": "Orbit"}' --field-file source=./orbit.html
105
118
  ```
106
119
 
107
- The response's `repeatableItems` contains each item's `id`, `fieldName`, `parentItemId`, and Content. Use the same `_itemId` pattern recursively for nested repeatables. Fetch multiple Blocks together when useful:
120
+ Every file is read before anything is written, so a missing or unreadable file fails the command without changing anything.
108
121
 
109
- ```sh
110
- {{CAMOX_CMD}} blocks get-many --id 99 --id 100 --id 101
111
- ```
122
+ To build an Artifact source, loop until it renders correctly:
112
123
 
113
- `blocks get-many` returns the same bundle shape as `blocks get`, in requested-id order.
124
+ 1. Write the source to a local file, such as `./orbit.html`.
125
+ 2. Push it with `blocks edit --id <ID> --field-file <NAME>=./orbit.html` (or `blocks create` for a new Block).
126
+ 3. Check the rendered page with `{{CAMOX_CMD}} preview`, following [CLI common guidance](cli-common.md).
127
+ 4. Edit the file and push again.
114
128
 
115
- ## Review and publishing
116
-
117
- For curated page-content blocks, publish or discard changes at the Page level. Layout-owned blocks use layout publishing; curated Page publishing includes its Layout by default, as described below. Singleton and derived routes have no curated Page record: use layout publishing, not `pages publish` (see [Routed layouts](routed-layouts.md)).
129
+ ### Edit repeatable Content safely
118
130
 
119
- ### Review draft and live state
131
+ A repeatable field's array is replacement-shaped: omitting an existing item deletes it and cascades to its file references, settings, and nested items. Fetch the Block, preserve every existing item with `_itemId`, and add changes only to the intended entries:
120
132
 
121
133
  ```sh
122
- {{CAMOX_CMD}} pages get --path /pricing # draft
123
- {{CAMOX_CMD}} pages get --path /pricing --live # published snapshot
124
- {{CAMOX_CMD}} blocks get --id 314 # draft
125
- {{CAMOX_CMD}} blocks get --id 314 --live # published snapshot
126
- ```
127
-
128
- Live reads fail when the Page or Block has never been published. `--live` is not a write target and does not publish anything.
134
+ {{CAMOX_CMD}} blocks get --id <BLOCK_UUID>
129
135
 
130
- ### Publish after approval
131
-
132
- ```sh
133
- {{CAMOX_CMD}} pages publish --path /pricing
136
+ {{CAMOX_CMD}} blocks edit --id <BLOCK_UUID> --content '{
137
+ "items": [
138
+ {"_itemId": "<ITEM_UUID_1>"},
139
+ {"_itemId": "<ITEM_UUID_2>", "answer": "Updated answer."},
140
+ {"_itemId": "<ITEM_UUID_3>"}
141
+ ]
142
+ }'
134
143
  ```
135
144
 
136
- `pages publish` accepts exactly one of `--id` or `--path`. It publishes the Page's current draft and, by default, its Layout. Publishing the Layout is a no-op when it has no pending changes. Use `--no-layout` only when the user explicitly does not want pending Layout changes published with the Page:
145
+ The response's `repeatableItems` contains each item's `id`, `fieldName`, `parentItemId`, and Content. Use the same `_itemId` pattern recursively for nested repeatables. Fetch multiple Blocks together when useful:
137
146
 
138
147
  ```sh
139
- {{CAMOX_CMD}} pages publish --path /pricing --no-layout
148
+ {{CAMOX_CMD}} blocks get-many --id <BLOCK_UUID> --id <BLOCK_UUID> --id <BLOCK_UUID>
140
149
  ```
141
150
 
142
- Publish only after the user asks or approves, not automatically after editing a draft.
143
-
144
- ### Unpublish or discard drafts
151
+ `blocks get-many` returns the same bundle shape as `blocks get`, in requested-id order.
145
152
 
146
- Remove a Page from live without deleting its draft:
153
+ ## Locales
147
154
 
148
155
  ```sh
149
- {{CAMOX_CMD}} pages unpublish --path /pricing
156
+ {{CAMOX_CMD}} locales list
157
+ {{CAMOX_CMD}} locales add --tag de
158
+ {{CAMOX_CMD}} pages get --path /pricing --locale de
159
+ {{CAMOX_CMD}} blocks edit --id <BLOCK_UUID> --content '{"title":"Hallo"}' --locale de
160
+ {{CAMOX_CMD}} locales remove --tag de
150
161
  ```
151
162
 
152
- Reset a draft to its current live snapshot without changing live:
163
+ Locales are content: adding or removing one changes the development draft, and
164
+ publishing puts the change on Live. Adding a locale gives every Page, Block,
165
+ repeatable item, synced Block and collection record a copy in it, keeping its
166
+ id, which Camox translates in the background. Every later change to the default
167
+ locale is translated into every other locale of the draft; edits made with
168
+ `--locale` aren't translated anywhere. `pages`,
169
+ `blocks edit/get/create/move/delete` and `layouts get` take `--locale <TAG>` to
170
+ read or write that copy; without it they act on the default locale. Removing a locale deletes its content from Live for good once
171
+ published. `locales set-default-tag --tag en-GB` corrects the default locale's
172
+ tag, only while it's the only locale.
173
+
174
+ ## Review
153
175
 
154
176
  ```sh
155
- {{CAMOX_CMD}} pages discard-changes --path /pricing
177
+ {{CAMOX_CMD}} pages get --path /pricing
178
+ {{CAMOX_CMD}} blocks get --id <BLOCK_UUID>
156
179
  ```
157
180
 
158
- Both commands accept exactly one of `--id` or `--path`. Discarding fails if the Page has never been published.
181
+ Reads return the content of the development draft, which shows Live wherever it changes nothing. Every edit lands in the development draft right away and reaches Live only when the draft is published (see [CLI Publishing](cli-publishing.md)).
@@ -0,0 +1,26 @@
1
+ # Publishing with the Camox CLI
2
+
3
+ Read [cli-common.md](cli-common.md) first for `{{CAMOX_CMD}}`, help verification, and the dev-first workflow.
4
+
5
+ Every command works in the current developer's development draft. Its changes reach Live, the public site, only when the draft is published. Agents in parallel worktrees share their developer's development draft, so publishing or discarding it covers all of their changes.
6
+
7
+ Don't publish or discard unless the user asks you to.
8
+
9
+ ```sh
10
+ {{CAMOX_CMD}} status # whether the development draft exists, and how many changes it holds
11
+ {{CAMOX_CMD}} publish # what publishing would do, with a token
12
+ {{CAMOX_CMD}} publish --confirm TOKEN # publish the whole draft to Live
13
+ {{CAMOX_CMD}} discard --yes # empty the development draft; Live is untouched
14
+ ```
15
+
16
+ `publish` lists, in order:
17
+
18
+ - **Blockers**: problems to fix in the draft before it can be published, such as an empty required reference or a page without a meta title. Definitions that differ from Live's are blockers too: local code changed a block, layout, or collection, and only a release can ship it to Live. Don't try to fix those through content; tell the user a release is needed.
19
+ - **Conflicts**: content Live changed or deleted since the draft changed it, with who published it and when. Publishing overwrites Live's version.
20
+ - **Lost changes**: changes publishing drops because what they belong to is gone.
21
+ - **Warnings**: the same problems already on Live. They don't block.
22
+ - **Changes**: everything the draft creates, changes, or deletes.
23
+
24
+ Show the user the list, especially conflicts and lost changes, and get their confirmation before passing the token to `publish --confirm`. If Live changed since the list was printed, nothing is published: the command prints the new list with a new token and fails with `CONFLICTS_CHANGED`. Review the new list with the user before confirming again.
25
+
26
+ After publishing, the development draft stays open and empty. `discard` empties it without publishing and can't be undone; it requires `--yes` when not run in a terminal.
@@ -37,6 +37,33 @@ function Header() {
37
37
 
38
38
  Read viewport dimensions, query elements, and attach resize listeners through the same context. If the root is conditionally mounted or replaced, rerun setup for the new element (for example, store it using a callback ref and include it in the effect dependencies).
39
39
 
40
+ ## Pausing JavaScript-driven animation
41
+
42
+ The studio Canvas shows many pages at once and pauses the previews nobody is looking at. Camox pauses their CSS animations, transitions and media itself, but cannot stop JavaScript running in your block: WebGL shaders, `<canvas>` drawing, `requestAnimationFrame` loops or animation libraries. Use `usePreviewPaused` from `camox/dom` with a ref to an element the component renders, and stop that work while it returns true. It is always false outside Camox preview.
43
+
44
+ ```tsx
45
+ import { usePreviewPaused } from "camox/dom";
46
+ import { useEffect, useRef } from "react";
47
+
48
+ function Shader() {
49
+ const canvas = useRef<HTMLCanvasElement>(null);
50
+ const paused = usePreviewPaused(canvas);
51
+
52
+ useEffect(() => {
53
+ if (paused) return;
54
+ let frame = requestAnimationFrame(function draw(time) {
55
+ // Draw a frame of the shader at `time`.
56
+ frame = requestAnimationFrame(draw);
57
+ });
58
+ return () => cancelAnimationFrame(frame);
59
+ }, [paused]);
60
+
61
+ return <canvas ref={canvas} />;
62
+ }
63
+ ```
64
+
65
+ The element must render together with the component calling the hook, not conditionally later.
66
+
40
67
  ## Third-party scripts and widgets
41
68
 
42
69
  Resolve context from the widget container, create scripts with `context.document.createElement("script")`, and append them to `context.document.head`. Initialize the SDK exposed on `context.window`, not the editor global. Deduplicate script loading **per document**, not with one module-global promise: preview, thumbnails, and the ordinary page can each have their own SDK instance.