camox 0.44.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/dist/components/AuthGate.js +0 -6
  2. package/dist/components/DeviceSelector.js +96 -0
  3. package/dist/components/PlatformLabel.js +20 -24
  4. package/dist/core/components/lexical/HighlightNode.js +1 -1
  5. package/dist/core/components/lexical/InlineContentEditable.js +15 -19
  6. package/dist/core/components/lexical/InlineLexicalEditor.js +54 -74
  7. package/dist/core/components/lexical/InlineStylesPlugin.js +53 -53
  8. package/dist/core/components/lexical/MaxLengthPlugin.js +59 -0
  9. package/dist/core/components/lexical/SelectionBroadcaster.js +53 -54
  10. package/dist/core/components/lexical/SidebarLexicalEditor.js +322 -229
  11. package/dist/core/components/lexical/SummaryToggleGuard.js +42 -0
  12. package/dist/core/components/lexical/TextLinkPopover.js +169 -180
  13. package/dist/core/createApp.d.ts +241 -312
  14. package/dist/core/createApp.js +123 -29
  15. package/dist/core/createBlock.d.ts +5 -5
  16. package/dist/core/createBlock.js +385 -152
  17. package/dist/core/createCollection.d.ts +55 -0
  18. package/dist/core/createCollection.js +93 -0
  19. package/dist/core/createLayout.d.ts +197 -61
  20. package/dist/core/createLayout.js +114 -56
  21. package/dist/core/defineDocument.d.ts +3 -5
  22. package/dist/core/derivedRoutes.js +49 -1
  23. package/dist/core/dom.d.ts +13 -4
  24. package/dist/core/dom.js +44 -1
  25. package/dist/core/editing/BlockEditingRuntime.d.ts +16 -0
  26. package/dist/core/editing/BlockEditingRuntime.js +6 -15
  27. package/dist/core/editing/CompleteBlockEditingRuntime.js +28 -23
  28. package/dist/core/editing/createEditableBlock.d.ts +754 -633
  29. package/dist/core/editing/createEditableBlock.js +2113 -1066
  30. package/dist/core/editing/referenceWrites.js +51 -0
  31. package/dist/core/editing/useLatestRecord.js +90 -0
  32. package/dist/core/hooks/useArtifactHost.js +139 -0
  33. package/dist/core/hooks/useFieldSelection.js +43 -18
  34. package/dist/core/hooks/useIsEditable.js +12 -10
  35. package/dist/core/hooks/useOverlayMessage.js +15 -19
  36. package/dist/core/lib/artifact.d.ts +21 -0
  37. package/dist/core/lib/artifact.js +154 -0
  38. package/dist/core/lib/artifactColors.js +123 -0
  39. package/dist/core/lib/artifactData.d.ts +1 -0
  40. package/dist/core/lib/artifactData.js +131 -0
  41. package/dist/core/lib/artifactHost.js +205 -0
  42. package/dist/core/lib/artifactRuntime.js +36 -0
  43. package/dist/core/lib/artifactTheme.js +57 -0
  44. package/dist/core/lib/contentType.d.ts +302 -106
  45. package/dist/core/lib/contentType.js +201 -173
  46. package/dist/core/lib/fieldTypes.js +3 -0
  47. package/dist/core/lib/iconTypes.d.ts +3 -3
  48. package/dist/core/lib/icons.d.ts +4 -4
  49. package/dist/core/lib/icons.js +40 -44
  50. package/dist/core/lib/imagePlaceholder.js +177 -0
  51. package/dist/core/lib/imageTransform.js +1 -1
  52. package/dist/core/lib/lexicalReact.d.ts +3 -1
  53. package/dist/core/lib/lexicalState.js +1 -1
  54. package/dist/core/lib/previewPaused.js +9 -0
  55. package/dist/core/lib/recordScope.js +316 -0
  56. package/dist/core/lib/reference.d.ts +81 -0
  57. package/dist/core/lib/reference.js +29 -0
  58. package/dist/core/lib/textLinks.js +7 -5
  59. package/dist/core/lib/textStyles.d.ts +5 -7
  60. package/dist/core/lib/textStyles.js +2 -2
  61. package/dist/core/notFound.d.ts +7 -0
  62. package/dist/core/notFound.js +11 -0
  63. package/dist/core/pageDestinations.js +6 -3
  64. package/dist/core/recordItem.js +34 -0
  65. package/dist/core/requestContext.d.ts +26 -0
  66. package/dist/core/requestContext.js +20 -0
  67. package/dist/features/canvas/CamoxCanvas.js +1401 -0
  68. package/dist/features/canvas/CanvasLoadingScreen.js +35 -0
  69. package/dist/features/canvas/CanvasOverlays.js +254 -0
  70. package/dist/features/canvas/CanvasPageEdge.js +87 -0
  71. package/dist/features/canvas/CanvasPageFrame.js +333 -0
  72. package/dist/features/canvas/CanvasPageHeader.js +125 -0
  73. package/dist/features/canvas/CanvasPreviewPageSlot.js +123 -0
  74. package/dist/features/canvas/DerivedPagePathInput.js +238 -0
  75. package/dist/features/canvas/canvasCamera.js +229 -0
  76. package/dist/features/canvas/canvasFlight.js +104 -0
  77. package/dist/features/canvas/canvasFrameCapture.js +364 -0
  78. package/dist/features/canvas/canvasFrameDocument.js +302 -0
  79. package/dist/features/canvas/canvasFrameMode.js +53 -0
  80. package/dist/features/canvas/canvasInsertionSeams.js +44 -0
  81. package/dist/features/canvas/canvasItems.js +30 -0
  82. package/dist/features/canvas/canvasOverlayGeometry.js +240 -0
  83. package/dist/features/canvas/canvasPages.js +79 -0
  84. package/dist/features/canvas/canvasScreenSpace.js +26 -0
  85. package/dist/features/canvas/canvasSelection.js +18 -0
  86. package/dist/features/canvas/canvasStore.js +60 -0
  87. package/dist/features/canvas/canvasThumbnails.js +304 -0
  88. package/dist/features/canvas/canvasZoom.js +10 -0
  89. package/dist/features/canvas/sidebar/CanvasInspector.js +202 -0
  90. package/dist/features/canvas/sidebar/CanvasNavigator.js +124 -0
  91. package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -0
  92. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +48 -0
  93. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +39 -0
  94. package/dist/features/canvas/sidebar/CuratedPageInspector.js +69 -0
  95. package/dist/features/canvas/sidebar/DerivedPageInspector.js +37 -0
  96. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +78 -0
  97. package/dist/features/canvas/sidebar/LayoutPageOverview.js +71 -0
  98. package/dist/features/canvas/sidebar/PageInspector.js +157 -0
  99. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +90 -0
  100. package/dist/features/canvas/sidebar/PageOverview.js +27 -0
  101. package/dist/features/canvas/sidebar/SingletonPageInspector.js +31 -0
  102. package/dist/features/canvas/useCanvasCamera.js +783 -0
  103. package/dist/features/canvas/useCanvasFrame.js +148 -0
  104. package/dist/features/canvas/useCanvasFrameInput.js +97 -0
  105. package/dist/features/canvas/useCanvasNearness.js +57 -0
  106. package/dist/features/canvas/useDiscoveredPreviewPaths.js +62 -0
  107. package/dist/features/content/CamoxContent.d.ts +2 -5
  108. package/dist/features/content/CamoxContent.js +174 -271
  109. package/dist/features/content/CollectionItemSheetContext.js +106 -0
  110. package/dist/features/content/ContentAssets.js +315 -0
  111. package/dist/features/content/ContentCollection.js +663 -0
  112. package/dist/features/content/collection-form.js +58 -0
  113. package/dist/features/content/components/AssetCard.js +80 -84
  114. package/dist/features/content/components/AssetCardSkeleton.js +4 -8
  115. package/dist/features/content/components/ContentSidebar.js +129 -18
  116. package/dist/features/content/components/ContentSidebarGroup.js +37 -0
  117. package/dist/features/content/components/DeleteCollectionItemButton.js +202 -0
  118. package/dist/features/content/components/MissingFromLocale.js +282 -0
  119. package/dist/features/content/components/UploadDropZone.js +27 -31
  120. package/dist/features/content/components/UploadProgressDrawer.js +90 -98
  121. package/dist/features/navigation/navigation.d.ts +66 -20
  122. package/dist/features/navigation/navigation.js +257 -90
  123. package/dist/features/og/defaultFonts.js +8 -8
  124. package/dist/features/og/geist-variable-ttf-base64.js +1 -1
  125. package/dist/features/og/imageResponse.d.ts +8 -0
  126. package/dist/features/og/imageResponse.js +26 -0
  127. package/dist/features/page/CuratedPageContent.js +167 -0
  128. package/dist/features/page/DerivedPageContent.js +26 -30
  129. package/dist/features/page/SharedLayoutContent.js +25 -27
  130. package/dist/features/preview/CamoxPreview.d.ts +23 -61
  131. package/dist/features/preview/CamoxPreview.js +816 -537
  132. package/dist/features/preview/EditablePageContent.js +1 -1
  133. package/dist/features/preview/EditablePageExperience.js +16 -22
  134. package/dist/features/preview/components/AddBlockSheet.js +273 -0
  135. package/dist/features/preview/components/AssetFieldEditor.js +173 -154
  136. package/dist/features/preview/components/AssetLightbox.js +181 -134
  137. package/dist/features/preview/components/AssetPickerModal.js +153 -170
  138. package/dist/features/preview/components/BlockActionsPopover.js +150 -149
  139. package/dist/features/preview/components/BlockErrorBoundary.js +8 -12
  140. package/dist/features/preview/components/BlockThumbnail.js +172 -98
  141. package/dist/features/preview/components/CanvasPreview.js +243 -0
  142. package/dist/features/preview/components/CreatePageModal.js +128 -137
  143. package/dist/features/preview/components/DebouncedFieldEditor.js +29 -33
  144. package/dist/features/preview/components/DerivedLayoutDialog.js +21 -19
  145. package/dist/features/preview/components/DrillRow.js +150 -0
  146. package/dist/features/preview/components/FieldOverlayStyles.js +11 -8
  147. package/dist/features/preview/components/FieldToolbar.js +160 -110
  148. package/dist/features/preview/components/Frame.js +108 -20
  149. package/dist/features/preview/components/IconFieldEditor.js +62 -66
  150. package/dist/features/preview/components/ItemFieldsEditor.js +231 -205
  151. package/dist/features/preview/components/LinkFieldEditor.js +135 -139
  152. package/dist/features/preview/components/Metadata.js +22 -30
  153. package/dist/features/preview/components/MobilePreviewDrawer.js +89 -108
  154. package/dist/features/preview/components/MultipleAssetFieldEditor.js +334 -246
  155. package/dist/features/preview/components/OverlayTracker.js +9 -41
  156. package/dist/features/preview/components/Overlays.js +81 -69
  157. package/dist/features/preview/components/PageInfo.js +1748 -0
  158. package/dist/features/preview/components/PageInfoSkeleton.js +51 -0
  159. package/dist/features/preview/components/PageLocationFieldset.js +112 -116
  160. package/dist/features/preview/components/PageNavigatorHeader.js +24 -0
  161. package/dist/features/preview/components/PageNicknameField.js +22 -26
  162. package/dist/features/preview/components/PagePicker.js +128 -130
  163. package/dist/features/preview/components/PageTree.js +525 -532
  164. package/dist/features/preview/components/PreviewActivation.js +28 -32
  165. package/dist/features/preview/components/PreviewPanel.js +620 -319
  166. package/dist/features/preview/components/PreviewToolbar.js +105 -333
  167. package/dist/features/preview/components/RecordCard.js +80 -0
  168. package/dist/features/preview/components/RecordCombobox.js +178 -0
  169. package/dist/features/preview/components/ReferenceFieldEditor.js +149 -0
  170. package/dist/features/preview/components/ReferenceListFieldEditor.js +432 -0
  171. package/dist/features/preview/components/RemovedBlockPlaceholder.js +95 -0
  172. package/dist/features/preview/components/RepeatableItemsList.js +125 -138
  173. package/dist/features/preview/components/SelectionEditor.js +993 -0
  174. package/dist/features/preview/components/ShikiMarkdown.js +14 -18
  175. package/dist/features/preview/components/SidebarSection.js +52 -64
  176. package/dist/features/preview/components/StudioEditingFallback.js +56 -0
  177. package/dist/features/preview/components/UnlinkAssetButton.js +104 -107
  178. package/dist/features/preview/components/blockGridNavigation.js +15 -0
  179. package/dist/features/preview/components/contentFieldSchema.js +8 -0
  180. package/dist/features/preview/components/useFieldWriter.js +200 -0
  181. package/dist/features/preview/components/useRecordView.js +383 -0
  182. package/dist/features/preview/components/useRepeatableItemActions.js +35 -37
  183. package/dist/features/preview/components/useUpdateBlockPosition.js +37 -37
  184. package/dist/features/preview/editingFrame.js +197 -0
  185. package/dist/features/preview/overlayHighlights.js +17 -44
  186. package/dist/features/preview/overlayMessages.js +72 -1
  187. package/dist/features/preview/pageRecord.js +189 -0
  188. package/dist/features/preview/previewConstants.js +6 -2
  189. package/dist/features/preview/previewPageFrame.js +95 -0
  190. package/dist/features/preview/previewPreparation.js +7 -0
  191. package/dist/features/preview/previewSelection.js +32 -63
  192. package/dist/features/preview/previewStore.js +225 -123
  193. package/dist/features/preview/referencePickerFocus.js +29 -0
  194. package/dist/features/preview/repeatableItemTargets.js +56 -0
  195. package/dist/features/preview/selectionReveal.js +21 -0
  196. package/dist/features/preview/usePreviewViewportActions.js +114 -0
  197. package/dist/features/preview/viewportContinuity.js +109 -0
  198. package/dist/features/provider/AuthenticatedCamoxProvider.js +69 -44
  199. package/dist/features/provider/CamoxProvider.d.ts +3 -6
  200. package/dist/features/provider/CamoxProvider.js +38 -50
  201. package/dist/features/provider/CoreCamoxProvider.js +69 -50
  202. package/dist/features/provider/LocalhostPreviewProvider.js +78 -114
  203. package/dist/features/provider/PreviewSignInPage.js +54 -0
  204. package/dist/features/provider/components/CamoxAppContext.js +11 -11
  205. package/dist/features/provider/components/CommandPalette.js +75 -82
  206. package/dist/features/provider/useAdminShortcuts.js +7 -11
  207. package/dist/features/routes/pageRuntime.d.ts +44 -4
  208. package/dist/features/routes/pageRuntime.js +244 -137
  209. package/dist/features/runtime/RuntimeChrome.js +117 -115
  210. package/dist/features/runtime/alternates.js +64 -0
  211. package/dist/features/runtime/analytics.d.ts +7 -0
  212. package/dist/features/runtime/analytics.js +66 -0
  213. package/dist/features/runtime/artifactSources.js +87 -0
  214. package/dist/features/runtime/editingFallback.js +20 -0
  215. package/dist/features/runtime/linkPrefetch.js +97 -0
  216. package/dist/features/runtime/livePages.js +62 -0
  217. package/dist/features/runtime/llmsTxt.js +40 -0
  218. package/dist/features/runtime/loopbackFetch.js +18 -0
  219. package/dist/features/runtime/navigationAccessibility.js +51 -0
  220. package/dist/features/runtime/navigationTarget.js +23 -2
  221. package/dist/features/runtime/pageApp.js +229 -158
  222. package/dist/features/runtime/pageBlockTypes.js +20 -0
  223. package/dist/features/runtime/pageClient.d.ts +2 -4
  224. package/dist/features/runtime/pageClient.js +18 -3
  225. package/dist/features/runtime/pageNavigation.js +254 -32
  226. package/dist/features/runtime/pageServer.d.ts +2 -4
  227. package/dist/features/runtime/pageServer.js +6 -2
  228. package/dist/features/runtime/pageViewport.js +7 -0
  229. package/dist/features/runtime/runtime.d.ts +54 -24
  230. package/dist/features/runtime/runtime.js +766 -191
  231. package/dist/features/runtime/runtimeChromeLoader.js +58 -0
  232. package/dist/features/runtime/runtimeRoutes.d.ts +19 -0
  233. package/dist/features/runtime/runtimeRoutes.js +25 -0
  234. package/dist/features/runtime/scrollRestoration.js +133 -0
  235. package/dist/features/runtime/studioApp.d.ts +4 -3
  236. package/dist/features/runtime/studioApp.js +5 -9
  237. package/dist/features/runtime/studioClient.d.ts +2 -4
  238. package/dist/features/runtime/studioClient.js +12 -3
  239. package/dist/features/runtime/studioServer.d.ts +2 -4
  240. package/dist/features/runtime/studioServer.js +6 -1
  241. package/dist/features/runtime/worker.d.ts +6 -0
  242. package/dist/features/runtime/worker.js +23 -0
  243. package/dist/features/runtime/workerRequest.js +44 -0
  244. package/dist/features/studio/CamoxStudio.d.ts +2 -6
  245. package/dist/features/studio/CamoxStudio.js +34 -49
  246. package/dist/features/studio/FollowAgentProvider.js +327 -0
  247. package/dist/features/studio/components/ChatSidebar.js +356 -0
  248. package/dist/features/studio/components/DraftsControl.js +676 -0
  249. package/dist/features/studio/components/FaviconDialog.js +318 -0
  250. package/dist/features/studio/components/LocalePicker.js +785 -0
  251. package/dist/features/studio/components/Navbar.js +123 -103
  252. package/dist/features/studio/components/ProjectMenu.js +239 -260
  253. package/dist/features/studio/components/RenameDraftDialog.js +206 -0
  254. package/dist/features/studio/components/ReviewDraftSheet.js +1472 -0
  255. package/dist/features/studio/components/ThreadComposer.js +157 -0
  256. package/dist/features/studio/components/ThreadMarkdown.js +113 -0
  257. package/dist/features/studio/components/ThreadMessages.js +270 -0
  258. package/dist/features/studio/components/UserButton.js +34 -23
  259. package/dist/features/studio/draftLabel.js +33 -0
  260. package/dist/features/studio/draftNotice.js +13 -0
  261. package/dist/features/studio/followAgent.js +241 -0
  262. package/dist/features/studio/followAgentContext.js +7 -0
  263. package/dist/features/studio/localeOptions.js +118 -0
  264. package/dist/features/studio/localeSwitch.js +19 -0
  265. package/dist/features/studio/routes.js +26 -1
  266. package/dist/features/studio/studioStore.js +64 -1
  267. package/dist/features/studio/useTheme.js +24 -27
  268. package/dist/features/vite/artifactRuntimeMinification.js +36 -0
  269. package/dist/features/vite/blockBoilerplate.js +6 -5
  270. package/dist/features/vite/blockChunks.js +31 -0
  271. package/dist/features/vite/bundlerLogs.js +17 -0
  272. package/dist/features/vite/definitionsSync.js +158 -226
  273. package/dist/features/vite/devAuthentication.js +4 -16
  274. package/dist/features/vite/devSignIn.js +87 -0
  275. package/dist/features/vite/iconGeneration.js +1 -1
  276. package/dist/features/vite/layoutGeneration.js +11 -1
  277. package/dist/features/vite/publishSeededContent.js +30 -0
  278. package/dist/features/vite/routeGeneration.js +6 -7
  279. package/dist/features/vite/runtimeDev.js +80 -99
  280. package/dist/features/vite/vite.d.ts +51 -31
  281. package/dist/features/vite/vite.js +224 -127
  282. package/dist/features/vite/workerBuild.js +39 -0
  283. package/dist/hooks/use-debounced-field.js +116 -47
  284. package/dist/hooks/use-file-upload.js +114 -67
  285. package/dist/hooks/use-marquee-selection.js +32 -36
  286. package/dist/hooks/use-page-destinations.js +69 -37
  287. package/dist/lib/api-client-server.d.ts +5 -0
  288. package/dist/lib/api-client-server.js +10 -4
  289. package/dist/lib/api-client.d.ts +6 -0
  290. package/dist/lib/api-client.js +51 -16
  291. package/dist/lib/api-socket.js +17 -0
  292. package/dist/lib/auth-page-styles.js +39 -0
  293. package/dist/lib/auth.js +129 -61
  294. package/dist/lib/collection-cache.js +23 -0
  295. package/dist/lib/draft-scope.d.ts +4 -0
  296. package/dist/lib/draft-scope.js +222 -0
  297. package/dist/lib/html.js +12 -0
  298. package/dist/lib/link-pages.js +154 -0
  299. package/dist/lib/locale-path.d.ts +22 -0
  300. package/dist/lib/locale-path.js +57 -0
  301. package/dist/lib/normalized-data.js +252 -152
  302. package/dist/lib/preview-handoff.js +2 -2
  303. package/dist/lib/queries.d.ts +11 -0
  304. package/dist/lib/queries.js +70 -141
  305. package/dist/lib/studio-reads.d.ts +14 -0
  306. package/dist/lib/studio-reads.js +554 -0
  307. package/dist/lib/use-project-room.js +50 -50
  308. package/dist/lib/use-thread.js +310 -0
  309. package/dist/lib/utils.js +25 -29
  310. package/dist/lib/view-locale-context.js +22 -0
  311. package/dist/lib/view-locale.js +46 -0
  312. package/dist/package.js +5 -0
  313. package/dist/studio-overlays.css +41 -151
  314. package/dist/studio.css +2 -2
  315. package/package.json +70 -73
  316. package/skills/camox/SKILL.md +16 -11
  317. package/skills/camox/references/artifacts.md +179 -0
  318. package/skills/camox/references/block-definitions.md +75 -59
  319. package/skills/camox/references/cli-common.md +9 -11
  320. package/skills/camox/references/cli-content.md +92 -69
  321. package/skills/camox/references/cli-publishing.md +26 -0
  322. package/skills/camox/references/dom-integrations.md +27 -0
  323. package/skills/camox/references/field-styling.md +4 -4
  324. package/skills/camox/references/layout-definitions.md +16 -14
  325. package/skills/camox/references/localization.md +56 -0
  326. package/skills/camox/references/routed-layouts.md +133 -15
  327. package/skills/camox-expand/SKILL.md +70 -0
  328. package/skills/camox-expand/references/jobs.md +39 -0
  329. package/skills/camoxify/SKILL.md +29 -7
  330. package/dist/core/components/AddBlockControlBar.js +0 -78
  331. package/dist/core/hooks/useRequireDraftSource.js +0 -23
  332. package/dist/features/metadata/sitemap.d.ts +0 -8
  333. package/dist/features/metadata/sitemap.js +0 -17
  334. package/dist/features/og/imageResponse.node.d.ts +0 -12
  335. package/dist/features/og/imageResponse.node.js +0 -49
  336. package/dist/features/og/imageResponse.workerd.d.ts +0 -12
  337. package/dist/features/og/imageResponse.workerd.js +0 -40
  338. package/dist/features/page/PublishedPageContent.js +0 -205
  339. package/dist/features/page/PublishedPageExperience.js +0 -23
  340. package/dist/features/preview/DerivedPreview.js +0 -134
  341. package/dist/features/preview/commentsEnabled.js +0 -8
  342. package/dist/features/preview/components/AddBlockSidebar.js +0 -381
  343. package/dist/features/preview/components/AttachedComments.js +0 -331
  344. package/dist/features/preview/components/CommentHeader.js +0 -122
  345. package/dist/features/preview/components/CommentSidebar.js +0 -29
  346. package/dist/features/preview/components/CommentTargetQuote.js +0 -167
  347. package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +0 -5
  348. package/dist/features/preview/components/DerivedLayoutSidebar.js +0 -179
  349. package/dist/features/preview/components/DerivedPageInfoSidebar.js +0 -69
  350. package/dist/features/preview/components/LeftSidebar.js +0 -68
  351. package/dist/features/preview/components/PageEditorSidebar.js +0 -563
  352. package/dist/features/preview/components/PageInfoSidebar.js +0 -1551
  353. package/dist/features/preview/components/PageNavigatorSidebar.js +0 -78
  354. package/dist/features/preview/components/PageStatusBadge.js +0 -97
  355. package/dist/features/preview/components/PeekedBlock.js +0 -217
  356. package/dist/features/preview/components/PreviewComments.js +0 -56
  357. package/dist/features/preview/components/PreviewToolbarSpacer.js +0 -43
  358. package/dist/features/preview/components/PublicationRow.js +0 -422
  359. package/dist/features/preview/components/PublishDialog.js +0 -194
  360. package/dist/features/preview/components/RightSidebar.js +0 -59
  361. package/dist/features/preview/components/SendFeedbackDialog.js +0 -83
  362. package/dist/features/preview/previewCommentsStore.js +0 -135
  363. package/dist/features/preview/publication.js +0 -81
  364. package/dist/features/preview/usePageComments.js +0 -39
  365. package/dist/features/runtime/SharedChromeContext.js +0 -7
  366. package/dist/features/studio/components/EnvironmentMenu.js +0 -425
  367. package/dist/features/vite/appGeneration.js +0 -89
  368. package/dist/lib/view-queries.js +0 -28
  369. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +0 -114
  370. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +0 -25
  371. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +0 -1
  372. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +0 -1
  373. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +0 -20
  374. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +0 -8
  375. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +0 -1
  376. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +0 -18
  377. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +0 -161
  378. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +0 -6
  379. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +0 -54
  380. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +0 -8
  381. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +0 -32
  382. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/new-process-route-tree.d.ts +0 -115
  383. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +0 -1
  384. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +0 -49
  385. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +0 -1
  386. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +0 -6
  387. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +0 -343
  388. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +0 -48
  389. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +0 -695
  390. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +0 -1
  391. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +0 -1
  392. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +0 -5
  393. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/RawStream.d.ts +0 -38
  394. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/seroval-plugins.d.ts +0 -1
  395. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/transformer.d.ts +0 -65
  396. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +0 -69
  397. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +0 -1
  398. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +0 -1
  399. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +0 -1
  400. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +0 -1
  401. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +0 -10
  402. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +0 -1
  403. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +0 -1
  404. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +0 -1
  405. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +0 -28
  406. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +0 -49
  407. package/skills/camox/references/cli-environments.md +0 -37
@@ -0,0 +1,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 };