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,123 @@
1
+ //#region src/core/lib/artifactColors.ts
2
+ const unit = (part, percentOf) => {
3
+ if (part === "none") return 0;
4
+ const value = parseFloat(part);
5
+ return part.endsWith("%") ? value / 100 * percentOf : value;
6
+ };
7
+ const hue = (part) => {
8
+ if (part === "none") return 0;
9
+ const value = parseFloat(part);
10
+ if (part.endsWith("grad")) return value * .9;
11
+ if (part.endsWith("rad")) return value * 180 / Math.PI;
12
+ if (part.endsWith("turn")) return value * 360;
13
+ return value;
14
+ };
15
+ const encode = (linear) => {
16
+ const x = Math.min(1, Math.max(0, linear));
17
+ return x <= .0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - .055;
18
+ };
19
+ const fromOklab = (L, a, b) => {
20
+ const l = Math.pow(L + .3963377774 * a + .2158037573 * b, 3);
21
+ const m = Math.pow(L - .1055613458 * a - .0638541728 * b, 3);
22
+ const s = Math.pow(L - .0894841775 * a - 1.291485548 * b, 3);
23
+ return [
24
+ encode(4.0767416621 * l - 3.3077115913 * m + .2309699292 * s),
25
+ encode(-1.2684380046 * l + 2.6097574011 * m - .3413193965 * s),
26
+ encode(-.0041960863 * l - .7034186147 * m + 1.707614701 * s)
27
+ ];
28
+ };
29
+ const fromHsl = (h, s, l) => {
30
+ const k = (n) => (n + h / 30) % 12;
31
+ const a = s * Math.min(l, 1 - l);
32
+ const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, 9 - k(n), 1));
33
+ return [
34
+ f(0),
35
+ f(8),
36
+ f(4)
37
+ ];
38
+ };
39
+ /** Hex, `rgb()`, `hsl()`, `oklab()` and `oklch()` colors, as channels from 0 to 1. */
40
+ function parse(value) {
41
+ const text = value.trim().toLowerCase();
42
+ if (text.startsWith("#")) {
43
+ let hex = text.slice(1);
44
+ if (!/^[0-9a-f]+$/.test(hex) || ![
45
+ 3,
46
+ 4,
47
+ 6,
48
+ 8
49
+ ].includes(hex.length)) return null;
50
+ if (hex.length < 6) hex = hex.replace(/./g, "$&$&");
51
+ const [r, g, b] = [
52
+ 0,
53
+ 2,
54
+ 4
55
+ ].map((start) => parseInt(hex.slice(start, start + 2), 16) / 255);
56
+ return [
57
+ r,
58
+ g,
59
+ b
60
+ ];
61
+ }
62
+ const open = text.indexOf("(");
63
+ if (open < 0 || !text.endsWith(")")) return null;
64
+ const parts = text.slice(open + 1, -1).split(/[^0-9a-z.%+-]+/).filter(Boolean);
65
+ if (parts.length < 3) return null;
66
+ if (parts.slice(0, 3).some((part) => part !== "none" && !Number.isFinite(parseFloat(part)))) return null;
67
+ const [x, y, z] = parts;
68
+ switch (text.slice(0, open)) {
69
+ case "rgb":
70
+ case "rgba": return [
71
+ unit(x, 255) / 255,
72
+ unit(y, 255) / 255,
73
+ unit(z, 255) / 255
74
+ ];
75
+ case "hsl":
76
+ case "hsla": return fromHsl(hue(x), parseFloat(y) / 100 || 0, parseFloat(z) / 100 || 0);
77
+ case "oklab": return fromOklab(unit(x, 1), unit(y, .4), unit(z, .4));
78
+ case "oklch": {
79
+ const chroma = unit(y, .4);
80
+ const angle = hue(z) * Math.PI / 180;
81
+ return fromOklab(unit(x, 1), chroma * Math.cos(angle), chroma * Math.sin(angle));
82
+ }
83
+ default: return null;
84
+ }
85
+ }
86
+ /**
87
+ * The sRGB colors of a page's theme tokens, so artifacts get them ready to use and never parse
88
+ * CSS themselves. Common color syntaxes are converted directly; any other color the page's
89
+ * browser understands (named colors, `lab()`, `color-mix()`…) goes through a 1×1 canvas of the
90
+ * page's own document. Tokens that aren't colors are left out.
91
+ */
92
+ function artifactThemeColors(tokens, page) {
93
+ let canvas;
94
+ const paint = (value) => {
95
+ if (!page.CSS?.supports("color", value)) return null;
96
+ canvas ??= page.document.createElement("canvas").getContext("2d", { willReadFrequently: true });
97
+ if (!canvas) return null;
98
+ canvas.clearRect(0, 0, 1, 1);
99
+ canvas.fillStyle = value;
100
+ canvas.fillRect(0, 0, 1, 1);
101
+ const [r, g, b] = canvas.getImageData(0, 0, 1, 1).data;
102
+ return [
103
+ r / 255,
104
+ g / 255,
105
+ b / 255
106
+ ];
107
+ };
108
+ const colors = {};
109
+ for (const [name, value] of Object.entries(tokens)) {
110
+ const channels = parse(value) ?? paint(value);
111
+ if (!channels) continue;
112
+ const [r, g, b] = channels.map((channel) => Math.round(Math.min(1, Math.max(0, channel)) * 255));
113
+ colors[name] = {
114
+ r,
115
+ g,
116
+ b
117
+ };
118
+ }
119
+ return colors;
120
+ }
121
+
122
+ //#endregion
123
+ export { artifactThemeColors };
@@ -0,0 +1 @@
1
+ import { TSchema } from "@sinclair/typebox";
@@ -0,0 +1,131 @@
1
+ //#region src/core/lib/artifactData.ts
2
+ const DATA_SOURCES = Symbol("camox.artifactDataSources");
3
+ /** Content fields that can't be Artifact Data. */
4
+ const unsharedFieldTypes = /* @__PURE__ */ new Set([
5
+ "Artifact",
6
+ "Repeater",
7
+ "Reference",
8
+ "ReferenceList"
9
+ ]);
10
+ const text = { type: "string" };
11
+ function objectSchema(properties, title) {
12
+ return {
13
+ type: "object",
14
+ ...title === void 0 ? {} : { title },
15
+ properties,
16
+ required: Object.keys(properties),
17
+ additionalProperties: false
18
+ };
19
+ }
20
+ const assetProperties = {
21
+ Image: {
22
+ url: text,
23
+ alt: text
24
+ },
25
+ File: {
26
+ url: text,
27
+ filename: text
28
+ }
29
+ };
30
+ /** The JSON Schema of one normalized Artifact Data value. */
31
+ function valueSchema(schema) {
32
+ const title = schema.title;
33
+ const titled = title === void 0 ? {} : { title };
34
+ switch (schema.fieldType) {
35
+ case "Link": return objectSchema({
36
+ text,
37
+ href: text,
38
+ newTab: { type: "boolean" }
39
+ }, title);
40
+ case "Image":
41
+ case "File": return objectSchema(assetProperties[schema.fieldType], title);
42
+ case "ImageList":
43
+ case "FileList": {
44
+ const single = schema.fieldType === "ImageList" ? "Image" : "File";
45
+ return {
46
+ type: "array",
47
+ ...titled,
48
+ items: objectSchema(assetProperties[single])
49
+ };
50
+ }
51
+ case "Boolean": return {
52
+ type: "boolean",
53
+ ...titled
54
+ };
55
+ case "Enum": return {
56
+ type: "string",
57
+ ...titled,
58
+ enum: schema.enum
59
+ };
60
+ default: return {
61
+ type: "string",
62
+ ...titled
63
+ };
64
+ }
65
+ }
66
+ /**
67
+ * Resolves each artifact's `data` against its siblings: the content fields and settings of a
68
+ * block, or of a repeatable item. Adds the Artifact Data's JSON Schema to the artifact's
69
+ * definition, so `blocks describe` shows agents the exact shape of `camox.data`.
70
+ */
71
+ function attachArtifactData(content, settings, owner) {
72
+ for (const [key, field] of Object.entries(content)) {
73
+ if (field.fieldType !== "Artifact") continue;
74
+ const names = field.data ?? [];
75
+ if (names.length === 0) continue;
76
+ const sources = {};
77
+ for (const name of names) {
78
+ const source = Object.hasOwn(content, name) ? {
79
+ scope: "content",
80
+ schema: content[name]
81
+ } : settings && Object.hasOwn(settings, name) ? {
82
+ scope: "settings",
83
+ schema: settings[name]
84
+ } : null;
85
+ if (!source) throw new Error(`${owner} artifact "${key}": data "${name}" is not a field or setting`);
86
+ if (unsharedFieldTypes.has(source.schema.fieldType)) throw new Error(`${owner} artifact "${key}": ${String(source.schema.fieldType)} "${name}" can't be Artifact Data`);
87
+ sources[name] = source;
88
+ }
89
+ field.dataSchema = objectSchema(Object.fromEntries(Object.entries(sources).map(([name, s]) => [name, valueSchema(s.schema)])));
90
+ Reflect.set(field, DATA_SOURCES, sources);
91
+ }
92
+ }
93
+ function normalizeAsset(fieldType, file) {
94
+ if (!file) return null;
95
+ return fieldType === "Image" || fieldType === "ImageList" ? {
96
+ url: file.url,
97
+ alt: file.alt ?? ""
98
+ } : {
99
+ url: file.url,
100
+ filename: file.filename ?? ""
101
+ };
102
+ }
103
+ function normalizeValue(schema, value, resolve) {
104
+ switch (schema.fieldType) {
105
+ case "Link": {
106
+ const link = value ?? {};
107
+ return {
108
+ text: typeof link.text === "string" ? link.text : "",
109
+ href: resolve.linkHref(link),
110
+ newTab: link.newTab === true
111
+ };
112
+ }
113
+ case "Image":
114
+ case "File": return normalizeAsset(schema.fieldType, resolve.asset(value) ?? schema.default);
115
+ case "ImageList":
116
+ case "FileList": return (Array.isArray(value) ? value : []).map((item) => normalizeAsset(schema.fieldType, resolve.asset(item))).filter(Boolean);
117
+ default: return value ?? schema.default;
118
+ }
119
+ }
120
+ /**
121
+ * The Artifact Data of an artifact field, from its owner's content and settings: links resolved
122
+ * to hrefs and assets to URLs. Artifacts without `data` receive an empty object.
123
+ */
124
+ function artifactData(field, owner, resolve) {
125
+ const sources = field && Reflect.get(field, DATA_SOURCES);
126
+ if (!sources) return {};
127
+ return Object.fromEntries(Object.entries(sources).map(([name, { scope, schema }]) => [name, normalizeValue(schema, owner[scope][name], resolve)]));
128
+ }
129
+
130
+ //#endregion
131
+ export { artifactData, attachArtifactData };
@@ -0,0 +1,205 @@
1
+ import { artifactThemeColors } from "./artifactColors.js";
2
+ import { observeArtifactTheme, readArtifactTheme } from "./artifactTheme.js";
3
+
4
+ //#region src/core/lib/artifactHost.ts
5
+ function isRuntimeMessage(data) {
6
+ return typeof data === "object" && data !== null && typeof data.camox === "string";
7
+ }
8
+ function sameStudio(a, b) {
9
+ if (!a || !b) return a === b;
10
+ return a.editing === b.editing && a.canvas === b.canvas;
11
+ }
12
+ /**
13
+ * Where an artifact's `camox.navigate(href)` leads: an internal path for the client router, an
14
+ * external URL for a new tab, or nowhere for anything but web URLs (such as `javascript:`).
15
+ */
16
+ function navigationTarget(href, page) {
17
+ if (href.startsWith("/") && !href.startsWith("//")) return { internal: href };
18
+ let url;
19
+ try {
20
+ url = new URL(href, page.location.href);
21
+ } catch {
22
+ return null;
23
+ }
24
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null;
25
+ if (url.origin === page.location.origin) return { internal: `${url.pathname}${url.search}${url.hash}` };
26
+ return { external: url.href };
27
+ }
28
+ /**
29
+ * Follows an artifact's navigation, only right after a real click: a click inside the frame
30
+ * gives the page transient user activation too, so an artifact can't redirect visitors itself.
31
+ */
32
+ function navigateFromArtifact(href, page, options) {
33
+ if (page.navigator.userActivation?.isActive !== true) return;
34
+ const target = navigationTarget(href, page);
35
+ if (!target) return;
36
+ if ("internal" in target) {
37
+ options.navigate?.(target.internal);
38
+ return;
39
+ }
40
+ page.open(target.external, "_blank", "noopener,noreferrer");
41
+ }
42
+ const clamp = (value) => Math.min(1, Math.max(0, value));
43
+ /**
44
+ * Where a frame sits in its page's viewport: `progress` goes from 0 when its top enters at the
45
+ * bottom of the viewport to 1 when its bottom leaves at the top; `visibleRatio` is the share of
46
+ * the frame inside the viewport.
47
+ */
48
+ function viewportOf(frame, viewportHeight) {
49
+ const { top, bottom, height } = frame.getBoundingClientRect();
50
+ const travel = viewportHeight + height;
51
+ const visible = Math.max(0, Math.min(bottom, viewportHeight) - Math.max(top, 0));
52
+ return {
53
+ progress: travel > 0 ? clamp((viewportHeight - top) / travel) : 0,
54
+ visibleRatio: height > 0 ? clamp(visible / height) : 0
55
+ };
56
+ }
57
+ /** How far beyond the viewport a frame counts as near it, so it starts measuring ahead of time. */
58
+ const NEAR_VIEWPORT = "25% 0px";
59
+ /**
60
+ * Follows the frame's place in the page's viewport, measuring at most once per animation frame
61
+ * after a scroll or resize anywhere on the page, and reporting only changes. An
62
+ * IntersectionObserver limits this to while the frame is near the viewport: far frames aren't
63
+ * measured on scroll, and are measured once more as they leave, so they report where they went.
64
+ */
65
+ function trackViewport(frame, page, report) {
66
+ let pending = 0;
67
+ let last = null;
68
+ const measure = () => {
69
+ pending = 0;
70
+ const next = viewportOf(frame, page.innerHeight);
71
+ if (last && last.progress === next.progress && last.visibleRatio === next.visibleRatio) return;
72
+ last = next;
73
+ report(next);
74
+ };
75
+ const schedule = () => {
76
+ if (pending) return;
77
+ pending = page.requestAnimationFrame(measure);
78
+ };
79
+ const listener = {
80
+ capture: true,
81
+ passive: true
82
+ };
83
+ let following = false;
84
+ const follow = (near) => {
85
+ if (near === following) return;
86
+ following = near;
87
+ if (near) {
88
+ page.addEventListener("scroll", schedule, listener);
89
+ page.addEventListener("resize", schedule, listener);
90
+ return;
91
+ }
92
+ page.removeEventListener("scroll", schedule, listener);
93
+ page.removeEventListener("resize", schedule, listener);
94
+ };
95
+ const intersection = "IntersectionObserver" in page ? new page.IntersectionObserver((entries) => {
96
+ const entry = entries.at(-1);
97
+ if (!entry) return;
98
+ follow(entry.isIntersecting);
99
+ schedule();
100
+ }, { rootMargin: NEAR_VIEWPORT }) : null;
101
+ if (intersection) intersection.observe(frame);
102
+ else follow(true);
103
+ schedule();
104
+ return {
105
+ schedule,
106
+ stop() {
107
+ intersection?.disconnect();
108
+ follow(false);
109
+ if (pending) page.cancelAnimationFrame(pending);
110
+ }
111
+ };
112
+ }
113
+ /**
114
+ * Connects an artifact frame to the `camox` runtime inside it, and owns the frame's message
115
+ * channel (see `artifactRuntime.ts` for the protocol).
116
+ *
117
+ * The block's code may run in another realm than the frame's parent (the studio renders its
118
+ * preview that way), so this only goes through the frame element's own document: never the
119
+ * global `window`, and never `event.source`, whose identity differs across realms.
120
+ */
121
+ function connectArtifactHost(frame, initialState, options = {}) {
122
+ const page = frame.ownerDocument.defaultView;
123
+ if (!page) return {
124
+ update() {},
125
+ disconnect() {}
126
+ };
127
+ const channel = crypto.randomUUID();
128
+ let state = initialState;
129
+ let ready = false;
130
+ const post = (type, payload = {}) => {
131
+ frame.contentWindow?.postMessage({
132
+ ...payload,
133
+ camox: type,
134
+ channel
135
+ }, "*");
136
+ };
137
+ const sendStudio = () => post("studio", { studio: state.studio });
138
+ const sendData = () => post("data", { data: state.data ?? {} });
139
+ let sentTheme = null;
140
+ const sendTheme = (force) => {
141
+ const tokens = readArtifactTheme(frame);
142
+ const serialized = JSON.stringify(tokens);
143
+ if (!force && serialized === sentTheme) return;
144
+ sentTheme = serialized;
145
+ post("theme", {
146
+ tokens,
147
+ colors: artifactThemeColors(tokens, page)
148
+ });
149
+ };
150
+ let viewport = null;
151
+ const observeViewport = (observe) => {
152
+ viewport?.stop();
153
+ viewport = observe ? trackViewport(frame, page, (next) => post("viewport", next)) : null;
154
+ };
155
+ const onMessage = (event) => {
156
+ const message = event.data;
157
+ if (!isRuntimeMessage(message)) return;
158
+ if (message.camox === "hello") {
159
+ post("connect");
160
+ return;
161
+ }
162
+ if (message.channel !== channel) return;
163
+ if (message.camox === "ready") {
164
+ ready = true;
165
+ observeViewport(false);
166
+ sendStudio();
167
+ sendData();
168
+ sendTheme(true);
169
+ if (options.size === "content") post("measure");
170
+ return;
171
+ }
172
+ if (message.camox === "height") {
173
+ const { height } = message;
174
+ if (options.size !== "content" || typeof height !== "number") return;
175
+ if (!Number.isFinite(height) || height < 0) return;
176
+ options.onHeight?.(height);
177
+ viewport?.schedule();
178
+ return;
179
+ }
180
+ if (message.camox === "observe-viewport") observeViewport(message.observe === true);
181
+ if (message.camox === "navigate" && typeof message.href === "string") navigateFromArtifact(message.href, page, options);
182
+ };
183
+ page.addEventListener("message", onMessage);
184
+ const stopObservingTheme = observeArtifactTheme(frame, () => {
185
+ if (ready) sendTheme(false);
186
+ });
187
+ post("connect");
188
+ return {
189
+ update(next) {
190
+ const previous = state;
191
+ state = next;
192
+ if (!ready) return;
193
+ if (!sameStudio(previous.studio, next.studio)) sendStudio();
194
+ if (JSON.stringify(previous.data) !== JSON.stringify(next.data)) sendData();
195
+ },
196
+ disconnect() {
197
+ page.removeEventListener("message", onMessage);
198
+ observeViewport(false);
199
+ stopObservingTheme();
200
+ }
201
+ };
202
+ }
203
+
204
+ //#endregion
205
+ export { connectArtifactHost };
@@ -0,0 +1,36 @@
1
+ //#region src/core/lib/artifactRuntime.ts
2
+ /**
3
+ * The `camox` runtime, injected at the top of every artifact's `srcDoc` so `window.camox` always
4
+ * exists before the artifact source runs.
5
+ *
6
+ * Protocol (every message is `{ camox: <type>, channel?, ...payload }`, posted with `"*"`):
7
+ * - runtime → page: `hello` when the runtime starts, so the page's hosts (re)connect their frames.
8
+ * - host → frame: `connect` with the host's private `channel`. The runtime adopts it and answers.
9
+ * - runtime → page: `ready` on that channel. Only the host that owns the channel listens to it,
10
+ * so hosts never need `event.source`, which can't be compared across realms.
11
+ * - host → frame: state messages on the channel, such as `studio`, and `theme` with the page's
12
+ * tokens at the frame's position and their sRGB `colors`, sent once ready and again when they
13
+ * change. The host converts the colors, so the runtime that every frame inlines stays small.
14
+ * - host → frame: `data` with the latest Artifact Data. The initial data is inlined in the
15
+ * `srcDoc` as a `<script type="application/json" data-camox-data>` after the runtime and the
16
+ * font links, so it is read lazily, on first access.
17
+ * - runtime → page: `observe-viewport` with `observe`, when the artifact's first `onViewport`
18
+ * subscription starts or its last one ends. While observed, the host sends `viewport` with
19
+ * `progress` and `visibleRatio` whenever they change.
20
+ * - host → frame: `measure`, for frames sized to their content. The runtime then reports the
21
+ * document's `height` whenever it changes.
22
+ * - runtime → page: `navigate` with an `href`. The host acts only with transient user activation.
23
+ *
24
+ * The theme part applies the tokens to the artifact's `:root` and keeps the body hidden until the
25
+ * first theme arrives, so the artifact never paints in the wrong colors, or until a short fallback
26
+ * timeout, so a page that never sends one can't hide it forever.
27
+ *
28
+ * Kept as plain JavaScript in a string: it runs in the artifact's document, not in the SDK's
29
+ * bundle, so it can't share code or build helpers with it. The SDK's build minifies it (see
30
+ * `plugins/minifyArtifactRuntime.ts`), so it must stay one template literal without
31
+ * interpolations or backslashes.
32
+ */
33
+ const ARTIFACT_RUNTIME = "(()=>{\"use strict\";let e=window.parent,t=null,n=null,r,i,a=new Set,o=()=>{if(i!==void 0)return r;let e=document.querySelector(`script[data-camox-data]`);try{r=e?JSON.parse(e.textContent):{}}catch{r={}}return i=JSON.stringify(r),r},s=(()=>{let e=new Set,t=[],n=Object.freeze({tokens:Object.freeze({}),colors:Object.freeze({})}),r=document.createElement(`style`);r.textContent=`body { visibility: hidden !important; }`,document.head.append(r);let i=()=>r.remove();setTimeout(i,300);let a=e=>Number.isFinite(e)?Math.min(255,Math.max(0,Math.round(e))):0;return{get current(){return n},receive(r){let o={},s={},c=r.colors||{};for(let[e,t]of Object.entries(r.tokens||{})){if(!e.startsWith(`--`)||typeof t!=`string`)continue;o[e]=t;let n=Object.hasOwn(c,e)?c[e]:null;n&&typeof n==`object`&&(s[e]=Object.freeze({r:a(n.r),g:a(n.g),b:a(n.b)}))}let l=document.documentElement.style;for(let e of t)Object.hasOwn(o,e)||l.removeProperty(e);for(let[e,t]of Object.entries(o))l.setProperty(e,t);t=Object.keys(o),i(),n=Object.freeze({tokens:Object.freeze(o),colors:Object.freeze(s)});for(let t of[...e])t(n)},subscribe(t){return e.add(t),()=>{e.delete(t)}}}})(),c=new Set,l=null,u=null,d=null,f=()=>{let e=Math.ceil(document.documentElement.getBoundingClientRect().height);e!==d&&(d=e,p(`height`,{height:d}))},p=(n,r)=>{t&&e.postMessage({...r,camox:n,channel:t},`*`)},m=()=>p(`observe-viewport`,{observe:c.size>0}),h={studio(e){let t=e.studio;n=t?Object.freeze({editing:!!t.editing,canvas:!!t.canvas}):null},data(e){o();let t=JSON.stringify(e.data??{});if(t!==i){r=JSON.parse(t),i=t;for(let e of[...a])e(r)}},theme:s.receive,measure(){d=null,u||(u=new ResizeObserver(f),u.observe(document.documentElement)),f()},viewport(e){let{progress:t,visibleRatio:n}=e;if(typeof t==`number`&&typeof n==`number`){l=Object.freeze({progress:t,visibleRatio:n}),document.documentElement.style.setProperty(`--camox-progress`,String(t));for(let e of c)e(l)}}};window.addEventListener(`message`,e=>{let n=e.data;if(n&&typeof n.camox==`string`){if(n.camox===`connect`){if(typeof n.channel!=`string`||n.channel===t)return;t=n.channel,p(`ready`),c.size>0&&m()}else t&&n.channel===t&&Object.hasOwn(h,n.camox)&&h[n.camox](n)}});let g=Object.freeze({get studio(){return n},get data(){return o()},onData(e){return a.add(e),()=>{a.delete(e)}},get theme(){return s.current},onTheme:s.subscribe,navigate(e){p(`navigate`,{href:String(e)})},onViewport(e){if(typeof e!=`function`)throw TypeError(`camox.onViewport needs a callback`);let t=t=>e(t);return c.add(t),c.size===1?m():l&&queueMicrotask(()=>c.has(t)&&e(l)),()=>{c.delete(t)&&c.size===0&&m()}}});Object.defineProperty(window,\"camox\",{value:g,enumerable:!0}),e!==window&&e.postMessage({camox:`hello`},`*`)})();";
34
+
35
+ //#endregion
36
+ export { ARTIFACT_RUNTIME };
@@ -0,0 +1,57 @@
1
+ //#region src/core/lib/artifactTheme.ts
2
+ function addCustomProperties(style, names) {
3
+ if (!style) return;
4
+ for (let index = 0; index < style.length; index++) {
5
+ const name = style.item(index);
6
+ if (name.startsWith("--")) names.add(name);
7
+ }
8
+ }
9
+ function addRuleCustomProperties(container, names) {
10
+ for (const rule of Array.from(container.cssRules)) {
11
+ addCustomProperties(rule.style, names);
12
+ if (rule.cssRules) addRuleCustomProperties(rule, names);
13
+ }
14
+ }
15
+ /** The custom properties declared in the page's stylesheets and on the frame or its ancestors. */
16
+ function declaredCustomProperties(frame) {
17
+ const names = /* @__PURE__ */ new Set();
18
+ for (const sheet of Array.from(frame.ownerDocument.styleSheets)) try {
19
+ addRuleCustomProperties(sheet, names);
20
+ } catch {}
21
+ for (let element = frame; element; element = element.parentElement) addCustomProperties(element.style, names);
22
+ return names;
23
+ }
24
+ /**
25
+ * The theme tokens as resolved at the frame's position, so a `.dark` section, a `data-theme`
26
+ * attribute or a media query on the page all apply.
27
+ */
28
+ function readArtifactTheme(frame) {
29
+ const page = frame.ownerDocument.defaultView;
30
+ if (!page) return {};
31
+ const style = page.getComputedStyle(frame);
32
+ const tokens = {};
33
+ for (const name of [...declaredCustomProperties(frame)].sort()) {
34
+ const value = style.getPropertyValue(name).trim();
35
+ if (value) tokens[name] = value;
36
+ }
37
+ return tokens;
38
+ }
39
+ function isThemeAttribute(name) {
40
+ return name === "class" || name === "style" || !!name?.startsWith("data-");
41
+ }
42
+ /**
43
+ * Calls `onChange` when the `class`, `style` or `data-*` attributes of the frame or one of its
44
+ * ancestors change, as these may change the tokens at its position. Returns a disconnect.
45
+ */
46
+ function observeArtifactTheme(frame, onChange) {
47
+ const page = frame.ownerDocument.defaultView;
48
+ if (!page) return () => {};
49
+ const observer = new page.MutationObserver((records) => {
50
+ if (records.some((record) => isThemeAttribute(record.attributeName))) onChange();
51
+ });
52
+ for (let element = frame; element; element = element.parentElement) observer.observe(element, { attributes: true });
53
+ return () => observer.disconnect();
54
+ }
55
+
56
+ //#endregion
57
+ export { observeArtifactTheme, readArtifactTheme };