canopycms 0.0.68-int.98 → 0.1.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 (688) hide show
  1. package/CHANGELOG.md +2131 -0
  2. package/README.md +47 -63
  3. package/dist/ai/generate.d.ts +5 -0
  4. package/dist/ai/generate.js +244 -115
  5. package/dist/ai/index.d.ts +1 -1
  6. package/dist/ai/json-to-markdown.d.ts +21 -1
  7. package/dist/ai/json-to-markdown.js +120 -57
  8. package/dist/ai/references.d.ts +72 -0
  9. package/dist/ai/references.js +223 -0
  10. package/dist/ai/resolve-branch.js +9 -2
  11. package/dist/ai/to-plain-text.d.ts +17 -8
  12. package/dist/ai/to-plain-text.js +18 -15
  13. package/dist/ai/types.d.ts +84 -3
  14. package/dist/api/admin-branch-health.d.ts +24 -1
  15. package/dist/api/admin-branch-health.js +52 -20
  16. package/dist/api/admin.d.ts +23 -5
  17. package/dist/api/admin.js +36 -1
  18. package/dist/api/assets.js +88 -78
  19. package/dist/api/branch-create-window.d.ts +12 -0
  20. package/dist/api/branch-create-window.js +13 -0
  21. package/dist/api/branch-merge.d.ts +1 -1
  22. package/dist/api/branch-merge.js +1 -1
  23. package/dist/api/branch-review.d.ts +3 -3
  24. package/dist/api/branch-review.js +16 -7
  25. package/dist/api/branch-status.d.ts +16 -6
  26. package/dist/api/branch-status.js +57 -12
  27. package/dist/api/branch-withdraw.d.ts +2 -2
  28. package/dist/api/branch-withdraw.js +8 -3
  29. package/dist/api/branch.d.ts +25 -12
  30. package/dist/api/branch.js +164 -103
  31. package/dist/api/client.d.ts +78 -58
  32. package/dist/api/client.js +150 -117
  33. package/dist/api/comments.d.ts +12 -3
  34. package/dist/api/comments.js +118 -9
  35. package/dist/api/content.d.ts +9 -9
  36. package/dist/api/content.js +131 -22
  37. package/dist/api/entries-constants.d.ts +14 -3
  38. package/dist/api/entries-constants.js +14 -3
  39. package/dist/api/entries.d.ts +40 -2
  40. package/dist/api/entries.js +102 -6
  41. package/dist/api/github-sync.d.ts +19 -0
  42. package/dist/api/github-sync.js +50 -3
  43. package/dist/api/groups.d.ts +4 -4
  44. package/dist/api/groups.js +2 -1
  45. package/dist/api/guards.js +23 -3
  46. package/dist/api/index.d.ts +3 -1
  47. package/dist/api/index.js +1 -0
  48. package/dist/api/permissions.d.ts +21 -2
  49. package/dist/api/permissions.js +50 -3
  50. package/dist/api/request-deadline.d.ts +59 -0
  51. package/dist/api/request-deadline.js +73 -0
  52. package/dist/api/resolve-references.js +8 -7
  53. package/dist/api/route-builder.d.ts +14 -0
  54. package/dist/api/route-builder.js +14 -1
  55. package/dist/api/schema.d.ts +11 -9
  56. package/dist/api/schema.js +2 -0
  57. package/dist/api/settings-helpers.d.ts +5 -1
  58. package/dist/api/settings-helpers.js +10 -2
  59. package/dist/api/types.d.ts +18 -0
  60. package/dist/api/users-constants.d.ts +6 -0
  61. package/dist/api/users-constants.js +6 -0
  62. package/dist/assets/asset-url.d.ts +28 -16
  63. package/dist/assets/asset-url.js +51 -25
  64. package/dist/assets/finalize.js +3 -0
  65. package/dist/assets/index.d.ts +1 -1
  66. package/dist/assets/materialize.d.ts +153 -0
  67. package/dist/assets/materialize.js +402 -0
  68. package/dist/assets/store-local.d.ts +19 -5
  69. package/dist/assets/store-local.js +69 -10
  70. package/dist/assets/store-s3.d.ts +38 -7
  71. package/dist/assets/store-s3.js +128 -22
  72. package/dist/assets/transform-directives.d.ts +52 -13
  73. package/dist/assets/transform-directives.js +87 -27
  74. package/dist/assets/transform.d.ts +3 -3
  75. package/dist/assets/transform.js +13 -8
  76. package/dist/assets/types.d.ts +31 -4
  77. package/dist/auth/cache.d.ts +1 -1
  78. package/dist/auth/cache.js +1 -1
  79. package/dist/auth/caching-auth-plugin.d.ts +2 -0
  80. package/dist/auth/caching-auth-plugin.js +12 -2
  81. package/dist/auth/file-based-auth-cache.d.ts +8 -0
  82. package/dist/auth/file-based-auth-cache.js +18 -8
  83. package/dist/auth/person-name.d.ts +5 -0
  84. package/dist/auth/person-name.js +8 -0
  85. package/dist/auth/plugin.d.ts +10 -1
  86. package/dist/auth/types.d.ts +2 -0
  87. package/dist/auth/user-metadata-lookup.d.ts +21 -0
  88. package/dist/auth/user-metadata-lookup.js +116 -0
  89. package/dist/authorization/branch.d.ts +1 -1
  90. package/dist/authorization/branch.js +12 -13
  91. package/dist/authorization/groups/schema.d.ts +4 -4
  92. package/dist/authorization/helpers.d.ts +8 -0
  93. package/dist/authorization/helpers.js +8 -0
  94. package/dist/authorization/index.d.ts +1 -1
  95. package/dist/authorization/index.js +1 -1
  96. package/dist/authorization/protected-branch.d.ts +5 -4
  97. package/dist/authorization/protected-branch.js +7 -5
  98. package/dist/branch-health.d.ts +35 -8
  99. package/dist/branch-health.js +54 -18
  100. package/dist/branch-metadata-error.d.ts +27 -0
  101. package/dist/branch-metadata-error.js +23 -0
  102. package/dist/branch-metadata-file.d.ts +205 -24
  103. package/dist/branch-metadata-file.js +126 -25
  104. package/dist/branch-metadata.d.ts +45 -6
  105. package/dist/branch-metadata.js +142 -50
  106. package/dist/branch-provisioning.d.ts +167 -0
  107. package/dist/branch-provisioning.js +501 -0
  108. package/dist/branch-registry.d.ts +8 -0
  109. package/dist/branch-registry.js +61 -9
  110. package/dist/branch-schema-cache.d.ts +29 -12
  111. package/dist/branch-schema-cache.js +64 -21
  112. package/dist/branch-sparse.d.ts +23 -0
  113. package/dist/branch-sparse.js +118 -0
  114. package/dist/branch-workspace.d.ts +42 -3
  115. package/dist/branch-workspace.js +239 -100
  116. package/dist/build/asset-refs.d.ts +94 -0
  117. package/dist/build/asset-refs.js +267 -0
  118. package/dist/build/generate-ai-content.js +5 -0
  119. package/dist/build/inline-flight.d.ts +37 -0
  120. package/dist/build/inline-flight.js +142 -0
  121. package/dist/cli/asset-refs.d.ts +52 -0
  122. package/dist/cli/asset-refs.js +194 -0
  123. package/dist/cli/cli.d.ts +15 -1
  124. package/dist/cli/cli.js +8543 -3193
  125. package/dist/cli/configured-asset-store.d.ts +12 -0
  126. package/dist/cli/configured-asset-store.js +46 -0
  127. package/dist/cli/generate-ai-content.js +4244 -1072
  128. package/dist/cli/init.js +217 -126
  129. package/dist/cli/project-detect.d.ts +2 -0
  130. package/dist/cli/project-detect.js +2 -0
  131. package/dist/cli/template-files/Dockerfile.cms.template +13 -5
  132. package/dist/cli/template-files/cms-stack.ts.template +16 -13
  133. package/dist/client.d.ts +1 -2
  134. package/dist/client.js +1 -2
  135. package/dist/comment-store.d.ts +25 -0
  136. package/dist/comment-store.js +43 -8
  137. package/dist/config/flatten.js +2 -0
  138. package/dist/config/helpers.js +2 -2
  139. package/dist/config/index.d.ts +1 -1
  140. package/dist/config/schemas/config.d.ts +12 -29
  141. package/dist/config/schemas/config.js +9 -12
  142. package/dist/config/schemas/field.d.ts +3 -0
  143. package/dist/config/schemas/field.js +58 -4
  144. package/dist/config/schemas/media.d.ts +4 -13
  145. package/dist/config/schemas/media.js +5 -8
  146. package/dist/config/schemas/url.d.ts +2 -20
  147. package/dist/config/schemas/url.js +2 -25
  148. package/dist/config/types.d.ts +116 -22
  149. package/dist/config/types.js +3 -9
  150. package/dist/config/validation.d.ts +25 -4
  151. package/dist/config/validation.js +116 -3
  152. package/dist/content-id-index.js +2 -2
  153. package/dist/content-index-generation.d.ts +1 -1
  154. package/dist/content-index-generation.js +1 -1
  155. package/dist/content-listing.d.ts +10 -1
  156. package/dist/content-listing.js +22 -5
  157. package/dist/content-reader.d.ts +9 -0
  158. package/dist/content-reader.js +16 -11
  159. package/dist/content-store.d.ts +75 -12
  160. package/dist/content-store.js +249 -86
  161. package/dist/content-tree.js +2 -2
  162. package/dist/context.js +5 -2
  163. package/dist/dangling-reference-log.d.ts +17 -0
  164. package/dist/dangling-reference-log.js +29 -0
  165. package/dist/dev-content-watcher.d.ts +1 -1
  166. package/dist/dev-content-watcher.js +1 -1
  167. package/dist/editor/BranchManager.d.ts +23 -7
  168. package/dist/editor/BranchManager.js +119 -54
  169. package/dist/editor/CanopyEditor.d.ts +1 -1
  170. package/dist/editor/CanopyEditor.js +1 -2
  171. package/dist/editor/CommentsPanel.d.ts +14 -0
  172. package/dist/editor/CommentsPanel.js +68 -43
  173. package/dist/editor/Editor.d.ts +11 -5
  174. package/dist/editor/Editor.js +891 -218
  175. package/dist/editor/EditorAuthGate.d.ts +7 -1
  176. package/dist/editor/EditorAuthGate.js +41 -9
  177. package/dist/editor/EntryNavigator.d.ts +22 -0
  178. package/dist/editor/EntryNavigator.js +353 -105
  179. package/dist/editor/FormHeader.d.ts +25 -0
  180. package/dist/editor/FormHeader.js +82 -0
  181. package/dist/editor/FormRenderer.d.ts +27 -3
  182. package/dist/editor/FormRenderer.js +171 -76
  183. package/dist/editor/PreviewFrame.d.ts +40 -0
  184. package/dist/editor/PreviewFrame.js +215 -0
  185. package/dist/editor/PreviewPane.d.ts +47 -0
  186. package/dist/editor/PreviewPane.js +147 -0
  187. package/dist/editor/PreviewToolbarTools.d.ts +22 -0
  188. package/dist/editor/PreviewToolbarTools.js +73 -0
  189. package/dist/editor/admin/SystemHealthPanel.d.ts +2 -1
  190. package/dist/editor/admin/SystemHealthPanel.js +163 -33
  191. package/dist/editor/admin/useSystemHealth.d.ts +18 -0
  192. package/dist/editor/admin/useSystemHealth.js +70 -1
  193. package/dist/editor/branch-status.d.ts +17 -0
  194. package/dist/editor/branch-status.js +29 -0
  195. package/dist/editor/canopy-path.d.ts +9 -6
  196. package/dist/editor/canopy-path.js +8 -11
  197. package/dist/editor/client-reference-resolver.d.ts +43 -16
  198. package/dist/editor/client-reference-resolver.js +155 -64
  199. package/dist/editor/comments/BranchComments.d.ts +1 -1
  200. package/dist/editor/comments/BranchComments.js +2 -2
  201. package/dist/editor/comments/CloseRefusedNotice.d.ts +4 -0
  202. package/dist/editor/comments/CloseRefusedNotice.js +7 -0
  203. package/dist/editor/comments/CommentThreadsPopover.d.ts +47 -0
  204. package/dist/editor/comments/CommentThreadsPopover.js +274 -0
  205. package/dist/editor/comments/CommentWriteAlert.d.ts +11 -0
  206. package/dist/editor/comments/CommentWriteAlert.js +13 -0
  207. package/dist/editor/comments/EntryComments.d.ts +10 -4
  208. package/dist/editor/comments/EntryComments.js +14 -17
  209. package/dist/editor/comments/FieldWrapper.d.ts +18 -4
  210. package/dist/editor/comments/FieldWrapper.js +62 -28
  211. package/dist/editor/comments/InlineCommentThread.d.ts +9 -2
  212. package/dist/editor/comments/InlineCommentThread.js +11 -47
  213. package/dist/editor/comments/ThreadCarousel.d.ts +1 -1
  214. package/dist/editor/comments/ThreadCarousel.js +18 -21
  215. package/dist/editor/comments/ThreadReplyControls.d.ts +28 -0
  216. package/dist/editor/comments/ThreadReplyControls.js +92 -0
  217. package/dist/editor/comments/field-comment-context.d.ts +14 -0
  218. package/dist/editor/comments/field-comment-context.js +14 -0
  219. package/dist/editor/comments/form-comments.d.ts +48 -0
  220. package/dist/editor/comments/form-comments.js +178 -0
  221. package/dist/editor/comments/item-anchor-copy.d.ts +6 -0
  222. package/dist/editor/comments/item-anchor-copy.js +6 -0
  223. package/dist/editor/comments/move-focus-if-unmoved.d.ts +6 -0
  224. package/dist/editor/comments/move-focus-if-unmoved.js +11 -0
  225. package/dist/editor/comments/popover-placement.d.ts +18 -0
  226. package/dist/editor/comments/popover-placement.js +58 -0
  227. package/dist/editor/comments/use-tracked-writes.d.ts +16 -0
  228. package/dist/editor/comments/use-tracked-writes.js +53 -0
  229. package/dist/editor/components/BranchAccessList.d.ts +15 -0
  230. package/dist/editor/components/BranchAccessList.js +52 -0
  231. package/dist/editor/components/BranchLockBanner.d.ts +22 -0
  232. package/dist/editor/components/BranchLockBanner.js +39 -0
  233. package/dist/editor/components/BranchPill.d.ts +32 -0
  234. package/dist/editor/components/BranchPill.js +33 -0
  235. package/dist/editor/components/BranchesDrawer.d.ts +11 -0
  236. package/dist/editor/components/BranchesDrawer.js +5 -0
  237. package/dist/editor/components/ConfirmDeleteModal.d.ts +6 -1
  238. package/dist/editor/components/ConfirmDeleteModal.js +3 -2
  239. package/dist/editor/components/DestructiveMenuItem.d.ts +7 -0
  240. package/dist/editor/components/DestructiveMenuItem.js +8 -0
  241. package/dist/editor/components/EditorCrashScreen.d.ts +17 -0
  242. package/dist/editor/components/EditorCrashScreen.js +22 -0
  243. package/dist/editor/components/EditorErrorBoundary.d.ts +38 -0
  244. package/dist/editor/components/EditorErrorBoundary.js +40 -0
  245. package/dist/editor/components/EditorHeader.d.ts +56 -106
  246. package/dist/editor/components/EditorHeader.js +130 -131
  247. package/dist/editor/components/EditorRail.d.ts +49 -0
  248. package/dist/editor/components/EditorRail.js +65 -0
  249. package/dist/editor/components/EntryBreadcrumb.d.ts +33 -0
  250. package/dist/editor/components/EntryBreadcrumb.js +56 -0
  251. package/dist/editor/components/EntryCreateModal.d.ts +12 -7
  252. package/dist/editor/components/EntryCreateModal.js +51 -57
  253. package/dist/editor/components/NoEditPermissionNotice.d.ts +6 -5
  254. package/dist/editor/components/NoEditPermissionNotice.js +5 -4
  255. package/dist/editor/components/QuickOpenPalette.d.ts +22 -0
  256. package/dist/editor/components/QuickOpenPalette.js +66 -0
  257. package/dist/editor/components/ReadOnlyDraftNotice.d.ts +11 -0
  258. package/dist/editor/components/ReadOnlyDraftNotice.js +12 -0
  259. package/dist/editor/components/ReasonedMenuItem.d.ts +15 -0
  260. package/dist/editor/components/ReasonedMenuItem.js +15 -0
  261. package/dist/editor/components/ReferencedByList.d.ts +11 -0
  262. package/dist/editor/components/ReferencedByList.js +28 -0
  263. package/dist/editor/components/RelativeTime.d.ts +10 -0
  264. package/dist/editor/components/RelativeTime.js +10 -0
  265. package/dist/editor/components/RenameEntryModal.d.ts +9 -1
  266. package/dist/editor/components/RenameEntryModal.js +19 -31
  267. package/dist/editor/components/RetryToastMessage.d.ts +9 -0
  268. package/dist/editor/components/RetryToastMessage.js +6 -0
  269. package/dist/editor/components/SaveAllResult.d.ts +25 -0
  270. package/dist/editor/components/SaveAllResult.js +86 -0
  271. package/dist/editor/components/SaveSplitButton.d.ts +30 -0
  272. package/dist/editor/components/SaveSplitButton.js +108 -0
  273. package/dist/editor/components/StagedChangesDrawer.d.ts +39 -0
  274. package/dist/editor/components/StagedChangesDrawer.js +92 -0
  275. package/dist/editor/components/UnavailableEntryNotice.d.ts +6 -0
  276. package/dist/editor/components/UnavailableEntryNotice.js +9 -0
  277. package/dist/editor/components/UnavailableTypeMessage.d.ts +6 -0
  278. package/dist/editor/components/UnavailableTypeMessage.js +9 -0
  279. package/dist/editor/components/UndoToastMessage.d.ts +18 -0
  280. package/dist/editor/components/UndoToastMessage.js +10 -0
  281. package/dist/editor/components/UserBadge.d.ts +2 -5
  282. package/dist/editor/components/UserBadge.js +62 -33
  283. package/dist/editor/components/ValidationSummary.d.ts +14 -0
  284. package/dist/editor/components/ValidationSummary.js +24 -0
  285. package/dist/editor/components/index.d.ts +2 -2
  286. package/dist/editor/components/index.js +2 -2
  287. package/dist/editor/context/ApiClientContext.d.ts +8 -2
  288. package/dist/editor/context/ApiClientContext.js +19 -8
  289. package/dist/editor/context/AssetContext.d.ts +13 -35
  290. package/dist/editor/context/AssetContext.js +12 -31
  291. package/dist/editor/context/EditorStateContext.d.ts +4 -4
  292. package/dist/editor/context/EditorStateContext.js +4 -4
  293. package/dist/editor/context/SWRProvider.d.ts +3 -3
  294. package/dist/editor/context/SiteMdxAllowContext.d.ts +4 -0
  295. package/dist/editor/context/SiteMdxAllowContext.js +7 -0
  296. package/dist/editor/context/index.d.ts +2 -1
  297. package/dist/editor/context/index.js +2 -1
  298. package/dist/editor/contrast.d.ts +19 -0
  299. package/dist/editor/contrast.js +41 -0
  300. package/dist/editor/copy.d.ts +18 -0
  301. package/dist/editor/copy.js +18 -0
  302. package/dist/editor/editor-config.js +16 -0
  303. package/dist/editor/editor-utils.d.ts +34 -8
  304. package/dist/editor/editor-utils.js +42 -20
  305. package/dist/editor/entry-search.d.ts +20 -0
  306. package/dist/editor/entry-search.js +34 -0
  307. package/dist/editor/field-breadcrumb.d.ts +12 -0
  308. package/dist/editor/field-breadcrumb.js +85 -0
  309. package/dist/editor/field-props.d.ts +86 -0
  310. package/dist/editor/field-props.js +27 -0
  311. package/dist/editor/field-target.d.ts +30 -0
  312. package/dist/editor/field-target.js +77 -0
  313. package/dist/editor/fields/BlockField.d.ts +12 -0
  314. package/dist/editor/fields/BlockField.js +89 -73
  315. package/dist/editor/fields/CodeField.d.ts +2 -0
  316. package/dist/editor/fields/CodeField.js +6 -2
  317. package/dist/editor/fields/DateTimeField.d.ts +4 -29
  318. package/dist/editor/fields/DateTimeField.js +79 -41
  319. package/dist/editor/fields/ExpandAllButton.d.ts +6 -0
  320. package/dist/editor/fields/ExpandAllButton.js +4 -0
  321. package/dist/editor/fields/FieldCrashFallback.d.ts +17 -0
  322. package/dist/editor/fields/FieldCrashFallback.js +30 -0
  323. package/dist/editor/fields/FieldLabel.d.ts +37 -0
  324. package/dist/editor/fields/FieldLabel.js +19 -0
  325. package/dist/editor/fields/ImageField.d.ts +4 -0
  326. package/dist/editor/fields/ImageField.js +29 -14
  327. package/dist/editor/fields/InlineGroupField.js +4 -3
  328. package/dist/editor/fields/ItemList.d.ts +42 -0
  329. package/dist/editor/fields/ItemList.js +130 -0
  330. package/dist/editor/fields/MarkdownField.d.ts +32 -0
  331. package/dist/editor/fields/MarkdownField.js +223 -46
  332. package/dist/editor/fields/MdxImageDialog.js +1 -1
  333. package/dist/editor/fields/NumberField.d.ts +2 -0
  334. package/dist/editor/fields/NumberField.js +8 -5
  335. package/dist/editor/fields/NumberListField.d.ts +2 -0
  336. package/dist/editor/fields/NumberListField.js +19 -16
  337. package/dist/editor/fields/ObjectField.d.ts +2 -7
  338. package/dist/editor/fields/ObjectField.js +15 -5
  339. package/dist/editor/fields/ObjectListField.d.ts +29 -0
  340. package/dist/editor/fields/ObjectListField.js +57 -0
  341. package/dist/editor/fields/ReferenceField.d.ts +2 -0
  342. package/dist/editor/fields/ReferenceField.js +34 -9
  343. package/dist/editor/fields/SelectField.d.ts +2 -0
  344. package/dist/editor/fields/SelectField.js +11 -2
  345. package/dist/editor/fields/StringListField.d.ts +4 -1
  346. package/dist/editor/fields/StringListField.js +22 -8
  347. package/dist/editor/fields/TextField.d.ts +2 -0
  348. package/dist/editor/fields/TextField.js +6 -2
  349. package/dist/editor/fields/ToggleField.d.ts +2 -0
  350. package/dist/editor/fields/ToggleField.js +8 -3
  351. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +1 -1
  352. package/dist/editor/fields/entry-link/InsertEntryLink.js +1 -1
  353. package/dist/editor/fields/form-expansion.d.ts +9 -0
  354. package/dist/editor/fields/form-expansion.js +2 -0
  355. package/dist/editor/fields/item-expansion.d.ts +15 -0
  356. package/dist/editor/fields/item-expansion.js +60 -0
  357. package/dist/editor/fields/list-item-keys.d.ts +8 -0
  358. package/dist/editor/fields/list-item-keys.js +50 -0
  359. package/dist/editor/fields/list-item-title.d.ts +20 -0
  360. package/dist/editor/fields/list-item-title.js +85 -0
  361. package/dist/editor/fields/markdown-export-options.d.ts +2 -0
  362. package/dist/editor/fields/markdown-export-options.js +8 -0
  363. package/dist/editor/fields/markdown-fidelity-visitors.d.ts +11 -0
  364. package/dist/editor/fields/markdown-fidelity-visitors.js +160 -0
  365. package/dist/editor/fields/mdx-jsx-support.d.ts +5 -1
  366. package/dist/editor/fields/mdx-jsx-support.js +157 -69
  367. package/dist/editor/fields/rich-text-failures.d.ts +5 -0
  368. package/dist/editor/fields/rich-text-failures.js +26 -0
  369. package/dist/editor/fields/toolbar-wrap.d.ts +7 -0
  370. package/dist/editor/fields/toolbar-wrap.js +35 -0
  371. package/dist/editor/form-outline.d.ts +13 -0
  372. package/dist/editor/form-outline.js +70 -0
  373. package/dist/editor/group-manager/GroupCard.d.ts +4 -1
  374. package/dist/editor/group-manager/GroupCard.js +12 -3
  375. package/dist/editor/group-manager/GroupForm.js +1 -1
  376. package/dist/editor/group-manager/InternalGroupsTab.d.ts +2 -1
  377. package/dist/editor/group-manager/InternalGroupsTab.js +4 -4
  378. package/dist/editor/group-manager/MemberList.d.ts +2 -1
  379. package/dist/editor/group-manager/MemberList.js +15 -4
  380. package/dist/editor/group-manager/hooks/useGroupState.d.ts +5 -0
  381. package/dist/editor/group-manager/hooks/useGroupState.js +30 -7
  382. package/dist/editor/group-manager/index.js +34 -5
  383. package/dist/editor/group-manager/types.d.ts +5 -2
  384. package/dist/editor/hooks/create-branch-request.d.ts +20 -0
  385. package/dist/editor/hooks/create-branch-request.js +54 -0
  386. package/dist/editor/hooks/save-all.d.ts +68 -0
  387. package/dist/editor/hooks/save-all.js +61 -0
  388. package/dist/editor/hooks/useBranchActions.d.ts +11 -1
  389. package/dist/editor/hooks/useBranchActions.js +42 -19
  390. package/dist/editor/hooks/useBranchManager.d.ts +21 -0
  391. package/dist/editor/hooks/useBranchManager.js +321 -125
  392. package/dist/editor/hooks/useBranchesData.d.ts +8 -4
  393. package/dist/editor/hooks/useBranchesData.js +9 -5
  394. package/dist/editor/hooks/useCommentSystem.d.ts +14 -2
  395. package/dist/editor/hooks/useCommentSystem.js +79 -55
  396. package/dist/editor/hooks/useCommentsData.d.ts +11 -7
  397. package/dist/editor/hooks/useCommentsData.js +20 -19
  398. package/dist/editor/hooks/useDraftManager.d.ts +77 -3
  399. package/dist/editor/hooks/useDraftManager.js +887 -94
  400. package/dist/editor/hooks/useEditorLayout.d.ts +53 -7
  401. package/dist/editor/hooks/useEditorLayout.js +98 -20
  402. package/dist/editor/hooks/useEntriesData.d.ts +2 -1
  403. package/dist/editor/hooks/useEntriesData.js +18 -4
  404. package/dist/editor/hooks/useEntryManager.d.ts +41 -2
  405. package/dist/editor/hooks/useEntryManager.js +227 -41
  406. package/dist/editor/hooks/useGroupManager.js +13 -16
  407. package/dist/editor/hooks/usePermissionManager.js +14 -6
  408. package/dist/editor/hooks/usePreviewMarks.d.ts +21 -0
  409. package/dist/editor/hooks/usePreviewMarks.js +33 -0
  410. package/dist/editor/hooks/useReferenceResolution.d.ts +10 -3
  411. package/dist/editor/hooks/useReferenceResolution.js +34 -177
  412. package/dist/editor/hooks/useSchemaManager.d.ts +25 -6
  413. package/dist/editor/hooks/useSchemaManager.js +97 -39
  414. package/dist/editor/hooks/useUserMetadata.d.ts +14 -4
  415. package/dist/editor/hooks/useUserMetadata.js +76 -47
  416. package/dist/editor/hooks/user-metadata-batcher.d.ts +8 -0
  417. package/dist/editor/hooks/user-metadata-batcher.js +33 -0
  418. package/dist/editor/media/AssetCard.d.ts +6 -7
  419. package/dist/editor/media/AssetCard.js +24 -31
  420. package/dist/editor/media/AssetListRow.d.ts +16 -0
  421. package/dist/editor/media/AssetListRow.js +41 -0
  422. package/dist/editor/media/CropStep.js +6 -1
  423. package/dist/editor/media/MediaLibrary.d.ts +4 -3
  424. package/dist/editor/media/MediaLibrary.js +11 -4
  425. package/dist/editor/media/MediaLibraryBody.d.ts +3 -3
  426. package/dist/editor/media/MediaLibraryBody.js +195 -80
  427. package/dist/editor/media/MediaLibrarySkeleton.d.ts +6 -0
  428. package/dist/editor/media/MediaLibrarySkeleton.js +14 -0
  429. package/dist/editor/media/crop-math.d.ts +3 -4
  430. package/dist/editor/media/crop-math.js +11 -22
  431. package/dist/editor/media/editor-image-src.d.ts +8 -0
  432. package/dist/editor/media/editor-image-src.js +10 -0
  433. package/dist/editor/media/format-bytes.d.ts +2 -0
  434. package/dist/editor/media/format-bytes.js +23 -0
  435. package/dist/editor/media/media-library-prefs.d.ts +23 -0
  436. package/dist/editor/media/media-library-prefs.js +49 -0
  437. package/dist/editor/media/media-library-view.d.ts +34 -0
  438. package/dist/editor/media/media-library-view.js +40 -0
  439. package/dist/editor/media/useAssetLibrary.d.ts +30 -0
  440. package/dist/editor/media/useAssetLibrary.js +126 -0
  441. package/dist/editor/media/useStableAssetOrder.d.ts +11 -0
  442. package/dist/editor/media/useStableAssetOrder.js +37 -0
  443. package/dist/editor/media/useThumbnailFailure.d.ts +6 -0
  444. package/dist/editor/media/useThumbnailFailure.js +16 -0
  445. package/dist/editor/permission-manager/GroupSelector.js +2 -2
  446. package/dist/editor/permission-manager/PermissionEditor.d.ts +1 -1
  447. package/dist/editor/permission-manager/PermissionEditor.js +15 -4
  448. package/dist/editor/permission-manager/PermissionLevelBadge.js +1 -1
  449. package/dist/editor/permission-manager/PermissionTree.d.ts +1 -1
  450. package/dist/editor/permission-manager/UserSelector.d.ts +1 -1
  451. package/dist/editor/permission-manager/UserSelector.js +3 -3
  452. package/dist/editor/permission-manager/index.js +12 -3
  453. package/dist/editor/permission-manager/types.d.ts +5 -2
  454. package/dist/editor/platform.d.ts +3 -0
  455. package/dist/editor/platform.js +9 -0
  456. package/dist/editor/preview-asset-base.d.ts +9 -0
  457. package/dist/editor/preview-asset-base.js +17 -0
  458. package/dist/editor/preview-bridge.d.ts +51 -27
  459. package/dist/editor/preview-bridge.js +103 -144
  460. package/dist/editor/preview-marks.d.ts +15 -0
  461. package/dist/editor/preview-marks.js +74 -0
  462. package/dist/editor/preview-path.d.ts +12 -0
  463. package/dist/editor/preview-path.js +45 -1
  464. package/dist/editor/preview-scale.d.ts +27 -0
  465. package/dist/editor/preview-scale.js +34 -0
  466. package/dist/editor/raw-asset-base.d.ts +5 -0
  467. package/dist/editor/raw-asset-base.js +14 -0
  468. package/dist/editor/relative-time.d.ts +4 -4
  469. package/dist/editor/relative-time.js +16 -8
  470. package/dist/editor/schema-editor/CollectionEditor.d.ts +20 -3
  471. package/dist/editor/schema-editor/CollectionEditor.js +361 -62
  472. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +5 -1
  473. package/dist/editor/schema-editor/EntryTypeEditor.js +11 -6
  474. package/dist/editor/schema-editor/collection-draft.d.ts +22 -0
  475. package/dist/editor/schema-editor/collection-draft.js +40 -0
  476. package/dist/editor/schema-editor/index.d.ts +1 -1
  477. package/dist/editor/schema-label.d.ts +10 -0
  478. package/dist/editor/schema-label.js +17 -0
  479. package/dist/editor/settings-conflict.d.ts +5 -0
  480. package/dist/editor/settings-conflict.js +8 -0
  481. package/dist/editor/shell/ActivityRail.d.ts +37 -0
  482. package/dist/editor/shell/ActivityRail.js +91 -0
  483. package/dist/editor/shell/EditorShell.d.ts +17 -0
  484. package/dist/editor/shell/EditorShell.js +31 -0
  485. package/dist/editor/shell/PaneLayout.d.ts +28 -0
  486. package/dist/editor/shell/PaneLayout.js +116 -0
  487. package/dist/editor/shell/SidePanelHost.d.ts +35 -0
  488. package/dist/editor/shell/SidePanelHost.js +184 -0
  489. package/dist/editor/shell/TopBar.d.ts +12 -0
  490. package/dist/editor/shell/TopBar.js +14 -0
  491. package/dist/editor/shell/host-chrome.d.ts +16 -0
  492. package/dist/editor/shell/host-chrome.js +69 -0
  493. package/dist/editor/slug.d.ts +16 -0
  494. package/dist/editor/slug.js +43 -0
  495. package/dist/editor/theme.d.ts +2 -1
  496. package/dist/editor/theme.js +314 -13
  497. package/dist/editor/unanswered.d.ts +17 -0
  498. package/dist/editor/unanswered.js +26 -0
  499. package/dist/editor/unavailable-entry-type.d.ts +20 -0
  500. package/dist/editor/unavailable-entry-type.js +28 -0
  501. package/dist/editor/undo-removal.d.ts +57 -0
  502. package/dist/editor/undo-removal.js +163 -0
  503. package/dist/editor/user-display.d.ts +4 -0
  504. package/dist/editor/user-display.js +5 -0
  505. package/dist/editor/utils/confirm-modal.d.ts +8 -0
  506. package/dist/editor/utils/confirm-modal.js +12 -0
  507. package/dist/editor/utils/editor-errors.d.ts +19 -0
  508. package/dist/editor/utils/editor-errors.js +32 -0
  509. package/dist/editor/utils/focus-return.d.ts +56 -0
  510. package/dist/editor/utils/focus-return.js +106 -0
  511. package/dist/entry-link-resolver.d.ts +11 -1
  512. package/dist/entry-link-resolver.js +65 -5
  513. package/dist/entry-schema-registry.d.ts +3 -3
  514. package/dist/entry-schema-registry.js +7 -4
  515. package/dist/entry-schema.d.ts +49 -3
  516. package/dist/entry-schema.js +18 -0
  517. package/dist/git-manager.d.ts +172 -10
  518. package/dist/git-manager.js +449 -107
  519. package/dist/github-service.d.ts +39 -2
  520. package/dist/github-service.js +101 -7
  521. package/dist/http/handler.js +74 -9
  522. package/dist/http/types.d.ts +2 -0
  523. package/dist/http/worker-not-ready.d.ts +9 -4
  524. package/dist/http/worker-not-ready.js +59 -6
  525. package/dist/index.d.ts +2 -0
  526. package/dist/index.js +3 -0
  527. package/dist/item-keys.d.ts +46 -0
  528. package/dist/item-keys.js +235 -0
  529. package/dist/operating-mode/editor-mode-check.d.ts +15 -0
  530. package/dist/operating-mode/editor-mode-check.js +24 -0
  531. package/dist/operating-mode/mode-env.d.ts +13 -14
  532. package/dist/operating-mode/mode-env.js +13 -14
  533. package/dist/operating-mode/types.d.ts +2 -2
  534. package/dist/paths/branch.d.ts +0 -1
  535. package/dist/paths/branch.js +1 -8
  536. package/dist/paths/index.d.ts +1 -1
  537. package/dist/paths/index.js +1 -1
  538. package/dist/paths/validation.js +0 -2
  539. package/dist/preview.d.ts +8 -0
  540. package/dist/preview.js +7 -0
  541. package/dist/reference-resolver.js +1 -0
  542. package/dist/resolve-canopy-user.d.ts +1 -1
  543. package/dist/resolve-canopy-user.js +1 -1
  544. package/dist/schema/meta-loader.d.ts +18 -8
  545. package/dist/schema/meta-loader.js +42 -9
  546. package/dist/schema/registry-fingerprint.d.ts +14 -0
  547. package/dist/schema/registry-fingerprint.js +63 -0
  548. package/dist/schema/resolver.d.ts +7 -4
  549. package/dist/schema/resolver.js +7 -6
  550. package/dist/schema/schema-store.d.ts +7 -10
  551. package/dist/schema/schema-store.js +13 -11
  552. package/dist/schema/schema-unavailable-error.d.ts +11 -0
  553. package/dist/schema/schema-unavailable-error.js +15 -0
  554. package/dist/schema/types.d.ts +22 -0
  555. package/dist/schema-registry-record.d.ts +35 -0
  556. package/dist/schema-registry-record.js +134 -0
  557. package/dist/server.d.ts +79 -9
  558. package/dist/server.js +62 -8
  559. package/dist/services.d.ts +33 -5
  560. package/dist/services.js +155 -37
  561. package/dist/settings-workspace.d.ts +23 -3
  562. package/dist/settings-workspace.js +159 -45
  563. package/dist/stamp-on-publish.d.ts +36 -0
  564. package/dist/stamp-on-publish.js +71 -0
  565. package/dist/static/index.d.ts +58 -5
  566. package/dist/static/index.js +133 -3
  567. package/dist/static/seo.d.ts +5 -5
  568. package/dist/static/seo.js +5 -5
  569. package/dist/submission-attribution.d.ts +8 -0
  570. package/dist/submission-attribution.js +22 -0
  571. package/dist/system-users.d.ts +12 -0
  572. package/dist/system-users.js +12 -0
  573. package/dist/task-queue/cms-task-queue.d.ts +1 -1
  574. package/dist/task-queue/cms-task-queue.js +1 -1
  575. package/dist/task-queue/index.d.ts +1 -1
  576. package/dist/task-queue/index.js +1 -1
  577. package/dist/task-queue/task-queue.d.ts +6 -0
  578. package/dist/task-queue/task-queue.js +29 -0
  579. package/dist/task-queue/worker-status.d.ts +35 -9
  580. package/dist/task-queue/worker-status.js +84 -17
  581. package/dist/types.d.ts +90 -9
  582. package/dist/url-collision.js +3 -3
  583. package/dist/url-exclusivity-fixtures.d.ts +8 -1
  584. package/dist/url-exclusivity-fixtures.js +11 -1
  585. package/dist/user.js +2 -1
  586. package/dist/utils/atomic-write.js +2 -1
  587. package/dist/utils/base-branch.d.ts +13 -0
  588. package/dist/utils/base-branch.js +23 -0
  589. package/dist/utils/content-serialize.d.ts +15 -7
  590. package/dist/utils/content-serialize.js +353 -51
  591. package/dist/utils/content-write-lock.d.ts +6 -1
  592. package/dist/utils/content-write-lock.js +21 -6
  593. package/dist/utils/debug.d.ts +1 -1
  594. package/dist/utils/debug.js +5 -3
  595. package/dist/utils/error.js +13 -2
  596. package/dist/utils/escape-text.d.ts +7 -0
  597. package/dist/utils/escape-text.js +27 -0
  598. package/dist/utils/fs.d.ts +12 -4
  599. package/dist/utils/fs.js +18 -5
  600. package/dist/utils/git.d.ts +21 -1
  601. package/dist/utils/git.js +63 -8
  602. package/dist/utils/json-source-splice.d.ts +14 -0
  603. package/dist/utils/json-source-splice.js +120 -0
  604. package/dist/utils/markdown-body-splice.d.ts +39 -0
  605. package/dist/utils/markdown-body-splice.js +421 -0
  606. package/dist/utils/occ-json-write.js +18 -12
  607. package/dist/utils/provision-log.d.ts +25 -0
  608. package/dist/utils/provision-log.js +49 -0
  609. package/dist/utils/provisioning-lock.d.ts +32 -1
  610. package/dist/utils/provisioning-lock.js +78 -32
  611. package/dist/utils/sanitize-href.d.ts +9 -23
  612. package/dist/utils/sanitize-href.js +14 -28
  613. package/dist/utils/title-field.d.ts +10 -0
  614. package/dist/utils/title-field.js +47 -0
  615. package/dist/utils/yaml-source-splice.d.ts +58 -0
  616. package/dist/utils/yaml-source-splice.js +515 -0
  617. package/dist/validation/block-structural-keys.d.ts +1 -1
  618. package/dist/validation/block-structural-keys.js +1 -1
  619. package/dist/validation/deletion-checker.d.ts +21 -29
  620. package/dist/validation/deletion-checker.js +41 -117
  621. package/dist/validation/entry-validator.d.ts +6 -10
  622. package/dist/validation/entry-validator.js +19 -26
  623. package/dist/validation/field-traversal.d.ts +22 -0
  624. package/dist/validation/field-traversal.js +39 -8
  625. package/dist/validation/markdown-safety.d.ts +68 -0
  626. package/dist/validation/markdown-safety.js +596 -0
  627. package/dist/validation/mdx-allowlist.d.ts +55 -0
  628. package/dist/validation/mdx-allowlist.js +183 -0
  629. package/dist/validation/reference-validator.d.ts +2 -0
  630. package/dist/validation/reference-validator.js +3 -0
  631. package/dist/version.d.ts +1 -1
  632. package/dist/version.js +1 -1
  633. package/dist/worker/branch-policy.d.ts +124 -0
  634. package/dist/worker/branch-policy.js +243 -0
  635. package/dist/worker/bundle-header.d.ts +117 -0
  636. package/dist/worker/bundle-header.js +253 -0
  637. package/dist/worker/cms-worker.d.ts +236 -142
  638. package/dist/worker/cms-worker.js +772 -285
  639. package/dist/worker/gateway-egress.d.ts +43 -0
  640. package/dist/worker/gateway-egress.js +209 -0
  641. package/dist/worker/gateway-instance.d.ts +42 -0
  642. package/dist/worker/gateway-instance.js +129 -0
  643. package/dist/worker/git-process.d.ts +81 -0
  644. package/dist/worker/git-process.js +234 -0
  645. package/dist/worker/git-sync.d.ts +34 -17
  646. package/dist/worker/git-sync.js +394 -131
  647. package/dist/worker/github-auth.d.ts +9 -9
  648. package/dist/worker/github-auth.js +13 -15
  649. package/dist/worker/github-gateway-http.d.ts +62 -0
  650. package/dist/worker/github-gateway-http.js +977 -0
  651. package/dist/worker/github-gateway-wire.d.ts +590 -0
  652. package/dist/worker/github-gateway-wire.js +488 -0
  653. package/dist/worker/github-gateway.d.ts +238 -0
  654. package/dist/worker/github-gateway.js +726 -0
  655. package/dist/worker/github-mirror-upkeep.d.ts +75 -0
  656. package/dist/worker/github-mirror-upkeep.js +266 -0
  657. package/dist/worker/github-mirror.d.ts +364 -0
  658. package/dist/worker/github-mirror.js +1030 -0
  659. package/dist/worker/github-transfer.d.ts +56 -0
  660. package/dist/worker/github-transfer.js +444 -0
  661. package/dist/worker/history-rewrite.d.ts +4 -5
  662. package/dist/worker/history-rewrite.js +12 -17
  663. package/dist/worker/provisioned-workspace.d.ts +5 -5
  664. package/dist/worker/provisioned-workspace.js +5 -5
  665. package/dist/worker/rebase.d.ts +1 -1
  666. package/dist/worker/rebase.js +58 -54
  667. package/dist/worker/remote-git-maintenance.d.ts +3 -0
  668. package/dist/worker/remote-git-maintenance.js +12 -0
  669. package/dist/worker/schema-gate.d.ts +49 -0
  670. package/dist/worker/schema-gate.js +226 -0
  671. package/dist/worker/self-checks.d.ts +107 -0
  672. package/dist/worker/self-checks.js +358 -0
  673. package/dist/worker/shared-repo-git.d.ts +96 -0
  674. package/dist/worker/shared-repo-git.js +459 -0
  675. package/dist/worker/sparse-cone.d.ts +20 -0
  676. package/dist/worker/sparse-cone.js +136 -0
  677. package/dist/worker/stale-mirror.d.ts +82 -0
  678. package/dist/worker/stale-mirror.js +130 -0
  679. package/dist/worker/task-runner.d.ts +5 -3
  680. package/dist/worker/task-runner.js +287 -186
  681. package/dist/worker/worker-context.d.ts +36 -37
  682. package/package.json +35 -7
  683. package/dist/editor/EditorPanes.d.ts +0 -10
  684. package/dist/editor/EditorPanes.js +0 -98
  685. package/dist/editor/components/EditorFooter.d.ts +0 -11
  686. package/dist/editor/components/EditorFooter.js +0 -9
  687. package/dist/editor/components/EditorSidebar.d.ts +0 -67
  688. package/dist/editor/components/EditorSidebar.js +0 -22
@@ -1,9 +1,14 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Avatar, Badge, Tooltip, Group, Text, Skeleton, ActionIcon } from '@mantine/core';
3
- import { IconUserOff, IconX } from '@tabler/icons-react';
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Avatar, Badge, Tooltip, Group, Text, Skeleton, ActionIcon, VisuallyHidden, } from '@mantine/core';
4
+ import { IconRobot, IconUserOff, IconX } from '@tabler/icons-react';
4
5
  import { useUserMetadata } from '../hooks/useUserMetadata.js';
5
- export const UserBadge = ({ userId, getUserMetadata, variant = 'avatar-name', showEmailTooltip = true, onRemove, color, size = 'sm', badgeVariant = 'filled', showBadge = false, loading: loadingOverride, cachedUser, }) => {
6
+ import { isSystemUserId } from '../../system-users.js';
7
+ import { personName } from '../../auth/person-name.js';
8
+ export const UserBadge = ({ userId, getUserMetadata, variant = 'avatar-name', showEmailTooltip = true, onRemove, color, size = 'sm', badgeVariant = 'filled', showBadge = false, loading: loadingOverride, cachedUser, revealIdOnFallback = false, }) => {
6
9
  const { userMetadata, isLoading, error } = useUserMetadata(userId, getUserMetadata, cachedUser);
10
+ // The badge's tooltip stays shut while the pointer or focus is on the X and its own tooltip.
11
+ const [onRemoveButton, setOnRemoveButton] = useState(false);
7
12
  const loading = loadingOverride ?? isLoading;
8
13
  const avatarSize = {
9
14
  xs: 16,
@@ -20,9 +25,35 @@ export const UserBadge = ({ userId, getUserMetadata, variant = 'avatar-name', sh
20
25
  if (loading) {
21
26
  return (_jsxs(Group, { gap: 4, children: [_jsx(Skeleton, { circle: true, height: avatarSize, width: avatarSize }), variant !== 'avatar-only' && _jsx(Skeleton, { height: 12, width: 60 })] }));
22
27
  }
23
- if (error || !userMetadata) {
24
- const content = (_jsxs(Group, { gap: 4, children: [_jsx(Avatar, { size: avatarSize, color: "gray" }), variant !== 'avatar-only' && (_jsx(Text, { size: textSize, c: "dimmed", children: userId }))] }));
25
- return showEmailTooltip ? (_jsx(Tooltip, { label: error ? 'Error loading user' : 'User not found', children: content })) : (content);
28
+ const inBadge = !!onRemove || showBadge;
29
+ // A light or outline badge tints its label with the badge colour, too faint for a name.
30
+ const nameColor = inBadge && badgeVariant !== 'filled' ? 'var(--mantine-color-text)' : undefined;
31
+ const wrap = (content, tooltip, personLabel) => {
32
+ const wrapped = inBadge ? (_jsx(Badge, { variant: badgeVariant, color: color, pr: onRemove ? 3 : 8, pl: 4, rightSection: onRemove ? (_jsx(Tooltip, { label: `Remove ${personLabel}`, position: "bottom", children: _jsx(ActionIcon, { size: "xs", radius: "xl", variant: "transparent", onClick: () => onRemove(userId), onMouseEnter: () => setOnRemoveButton(true), onMouseLeave: () => setOnRemoveButton(false), onFocus: () => setOnRemoveButton(true), onBlur: () => setOnRemoveButton(false), "aria-label": `Remove ${personLabel}`, style: { color: nameColor ?? 'var(--mantine-color-white)' }, children: _jsx(IconX, { size: 12, stroke: 2.5 }) }) })) : undefined, styles: {
33
+ label: {
34
+ display: 'flex',
35
+ alignItems: 'center',
36
+ gap: '4px',
37
+ },
38
+ }, children: content })) : (content);
39
+ return showEmailTooltip ? (_jsx(Tooltip, { label: tooltip, disabled: !tooltip || onRemoveButton, children: wrapped })) : (wrapped);
40
+ };
41
+ const record = error ? null : userMetadata;
42
+ const displayName = record ? personName(userId, record.name) : undefined;
43
+ if (!record || displayName === undefined) {
44
+ // The id shows only where `revealIdOnFallback` is set (admin surfaces); the People rule treats
45
+ // an id as an internal name. A record with no usable name still offers its avatar and email.
46
+ const unavailable = error ? "Couldn't load this name" : 'Name unavailable';
47
+ const described = revealIdOnFallback ? `${unavailable} · ${userId}` : unavailable;
48
+ const emailDetail = showEmailTooltip && variant !== 'full' ? (record?.email ?? '') : '';
49
+ const describedWithEmail = emailDetail ? `${described}, ${emailDetail}` : described;
50
+ // A filled badge keeps its white text; dimmed would not contrast with its fill.
51
+ const fallbackColor = inBadge && badgeVariant === 'filled' ? undefined : 'dimmed';
52
+ const unavailableText = (_jsx(Text, { size: textSize, c: fallbackColor, fs: "italic", children: unavailable }));
53
+ const hiddenDetail = `${revealIdOnFallback ? ` · ${userId}` : ''}${emailDetail ? `, ${emailDetail}` : ''}`;
54
+ return wrap(_jsxs(Group, { gap: 4, children: [_jsx(Avatar, { src: record?.avatarUrl, alt: "", size: avatarSize, color: "gray", "aria-hidden": true }), variant === 'avatar-only' ? (_jsx(VisuallyHidden, { component: "span", children: describedWithEmail })) : (_jsxs(_Fragment, { children: [variant === 'full' && record?.email ? (_jsxs("div", { children: [unavailableText, _jsx(Text, { size: "xs", c: "dimmed", children: record.email })] })) : (unavailableText), hiddenDetail && _jsx(VisuallyHidden, { component: "span", children: hiddenDetail })] }))] }), variant === 'avatar-only'
55
+ ? describedWithEmail
56
+ : [revealIdOnFallback ? described : '', emailDetail].filter(Boolean).join(', '), described);
26
57
  }
27
58
  const getInitials = (name) => {
28
59
  const parts = name.trim().split(/\s+/);
@@ -32,51 +63,49 @@ export const UserBadge = ({ userId, getUserMetadata, variant = 'avatar-name', sh
32
63
  };
33
64
  const renderAvatar = () => {
34
65
  if (userId === 'anonymous') {
35
- return (_jsx(Avatar, { size: avatarSize, color: "orange", children: _jsx(IconUserOff, { size: avatarSize * 0.6 }) }));
66
+ return (_jsx(Avatar, { size: avatarSize, color: "orange", "aria-hidden": true, children: _jsx(IconUserOff, { size: avatarSize * 0.6 }) }));
67
+ }
68
+ if (isSystemUserId(userId)) {
69
+ return (_jsx(Avatar, { size: avatarSize, color: "gray", "aria-hidden": true, children: _jsx(IconRobot, { size: avatarSize * 0.6 }) }));
36
70
  }
37
- // When inside Badge wrapper with filled/light variant, use white background for visibility
38
- // For outline badges or no badge, use the passed color
39
71
  let avatarColor = color || 'blue';
40
72
  let avatarStyles = {};
41
- if (onRemove || showBadge) {
73
+ if (inBadge) {
42
74
  if (badgeVariant === 'filled') {
43
- // Filled badges: white background with dark text for maximum contrast
44
75
  avatarStyles = {
45
- backgroundColor: 'white',
46
- color: 'var(--mantine-color-dark-6)',
76
+ backgroundColor: 'var(--mantine-color-body)',
77
+ color: 'var(--mantine-color-text)',
47
78
  };
48
79
  }
49
80
  else if (badgeVariant === 'light') {
50
- // Light badges: use dark avatar for contrast
51
81
  avatarColor = 'dark';
52
82
  }
53
- // outline badges: keep the passed color
54
83
  }
55
- return (_jsx(Avatar, { src: userMetadata.avatarUrl, size: avatarSize, color: avatarColor, style: avatarStyles, children: !userMetadata.avatarUrl && getInitials(userMetadata.name) }));
84
+ return (_jsx(Avatar, { src: record.avatarUrl,
85
+ // The name is text beside it (hidden when alone), so initials stay out of the tree.
86
+ alt: "", "aria-hidden": true, size: avatarSize, color: avatarColor, style: avatarStyles, children: !record.avatarUrl && getInitials(displayName) }));
56
87
  };
88
+ // The tooltip's email, read after the name by a screen reader, with no tab stop.
89
+ const detail = showEmailTooltip && variant !== 'full' && userId !== 'anonymous' ? record.email : '';
90
+ const detailText = detail ? (_jsx(VisuallyHidden, { component: "span", children: `, ${detail}` })) : null;
91
+ const personLabel = userId === 'anonymous' ? 'Anonymous (Public)' : displayName;
57
92
  const renderContent = () => {
58
93
  const avatar = renderAvatar();
59
94
  switch (variant) {
60
95
  case 'avatar-only':
61
- return avatar;
96
+ return (_jsxs(Group, { gap: 0, children: [avatar, _jsx(VisuallyHidden, { component: "span", children: personLabel }), detailText] }));
62
97
  case 'full':
63
- return (_jsxs(Group, { gap: 4, children: [avatar, _jsxs("div", { children: [_jsx(Text, { size: textSize, fw: 500, children: userMetadata.name }), _jsx(Text, { size: "xs", c: "dimmed", children: userMetadata.email })] })] }));
98
+ return (_jsxs(Group, { gap: 4, children: [avatar, _jsxs("div", { children: [_jsx(Text, { size: textSize, fw: 500, children: displayName }), _jsx(Text, { size: "xs", c: "dimmed", children: record.email })] })] }));
64
99
  case 'avatar-name':
65
100
  default:
66
- return (_jsxs(Group, { gap: 4, children: [avatar, _jsx(Text, { size: textSize, fw: 500, children: userId === 'anonymous' ? 'Anonymous (Public)' : userMetadata.name })] }));
101
+ return (_jsxs(Group, { gap: 4, children: [avatar, _jsx(Text, { size: textSize, fw: 500, c: nameColor, children: personLabel }), detailText] }));
67
102
  }
68
103
  };
69
- const content = renderContent();
70
- if (onRemove || showBadge) {
71
- const badgeContent = (_jsx(Badge, { variant: badgeVariant, color: color, pr: onRemove ? 3 : 8, pl: 4, rightSection: onRemove ? (_jsx(ActionIcon, { size: "xs", radius: "xl", variant: "transparent", onClick: () => onRemove(userId), "aria-label": "Remove user", style: { color: 'white' }, children: _jsx(IconX, { size: 12, stroke: 2.5 }) })) : undefined, styles: {
72
- label: {
73
- textTransform: 'none',
74
- display: 'flex',
75
- alignItems: 'center',
76
- gap: '4px',
77
- },
78
- }, children: content }));
79
- return showEmailTooltip && variant !== 'full' ? (_jsx(Tooltip, { label: userMetadata.email, children: badgeContent })) : (badgeContent);
80
- }
81
- return showEmailTooltip && variant !== 'full' ? (_jsx(Tooltip, { label: userMetadata.email, children: content })) : (content);
104
+ // Alone, the avatar shows no name, so its tooltip gives it before the email.
105
+ const tooltip = variant === 'full'
106
+ ? ''
107
+ : variant === 'avatar-only'
108
+ ? [personLabel, detail].filter(Boolean).join(', ')
109
+ : record.email;
110
+ return wrap(renderContent(), tooltip, personLabel);
82
111
  };
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { FieldConfig } from '../../config/index.js';
3
+ export interface ValidationSummaryProps {
4
+ fields: readonly FieldConfig[];
5
+ /** The form's value, which names list items and blocks in the breadcrumbs. */
6
+ value: unknown;
7
+ /** Messages keyed by canonical canopy path. */
8
+ errors: Record<string, string>;
9
+ }
10
+ /**
11
+ * The form's errors as labelled breadcrumbs ("Page sections › Hero › Heading"), each a button
12
+ * that scrolls to its field in the enclosing form and focuses it.
13
+ */
14
+ export declare const ValidationSummary: React.FC<ValidationSummaryProps>;
@@ -0,0 +1,24 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Alert, Anchor, List, Text } from '@mantine/core';
4
+ import { IconAlertCircle } from '@tabler/icons-react';
5
+ import { fieldBreadcrumb } from '../field-breadcrumb.js';
6
+ import { findFieldTarget, focusFieldTarget } from '../field-target.js';
7
+ /**
8
+ * The form's errors as labelled breadcrumbs ("Page sections › Hero › Heading"), each a button
9
+ * that scrolls to its field in the enclosing form and focuses it.
10
+ */
11
+ export const ValidationSummary = ({ fields, value, errors }) => {
12
+ const entries = Object.entries(errors);
13
+ if (entries.length === 0)
14
+ return null;
15
+ return (_jsx(Alert, { icon: _jsx(IconAlertCircle, { size: 16 }), color: "red", variant: "light", title: "Fix these issues before saving", "data-testid": "validation-alert", children: _jsx(List, { size: "sm", spacing: 2, children: entries.map(([path, message]) => {
16
+ const crumb = fieldBreadcrumb(fields, value, path).join(' › ');
17
+ return (_jsxs(List.Item, { children: [_jsx(Anchor, { component: "button", type: "button", size: "sm", c: "inherit", underline: "always", ta: "left", "data-testid": `validation-item-${path}`, onClick: (event) => {
18
+ const form = event.currentTarget.closest('[data-form-renderer]') ?? document;
19
+ const target = findFieldTarget(path, form);
20
+ if (target)
21
+ focusFieldTarget(target.element);
22
+ }, children: crumb }), _jsxs(Text, { span: true, size: "sm", children: [": ", message] })] }, path));
23
+ }) }) }));
24
+ };
@@ -1,3 +1,3 @@
1
- export * from './EditorFooter.js';
1
+ export * from './BranchLockBanner.js';
2
2
  export * from './EditorHeader.js';
3
- export * from './EditorSidebar.js';
3
+ export * from './EditorRail.js';
@@ -1,3 +1,3 @@
1
- export * from './EditorFooter.js';
1
+ export * from './BranchLockBanner.js';
2
2
  export * from './EditorHeader.js';
3
- export * from './EditorSidebar.js';
3
+ export * from './EditorRail.js';
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import React from 'react';
7
7
  import { createApiClient } from '../../api/index.js';
8
+ import type { OperatingMode } from '../../operating-mode/types.js';
8
9
  export type ApiClient = ReturnType<typeof createApiClient>;
9
10
  export interface ApiClientProviderProps {
10
11
  children: React.ReactNode;
@@ -17,17 +18,22 @@ export interface ApiClientProviderProps {
17
18
  * when `client` is supplied directly. Unset/empty is a no-op (same as today).
18
19
  */
19
20
  basePath?: string;
21
+ /** The mode this bundle was built for (`CanopyClientConfig.mode`); see `ApiClientOptions.editorMode`. */
22
+ editorMode?: OperatingMode;
20
23
  }
21
24
  /**
22
25
  * Provider that creates and provides the API client.
23
26
  * Use the client prop to inject a mock client for testing.
24
27
  */
25
- export declare function ApiClientProvider({ children, client, basePath }: ApiClientProviderProps): import("react/jsx-runtime").JSX.Element;
28
+ export declare function ApiClientProvider({ children, client, basePath, editorMode, }: ApiClientProviderProps): import("react/jsx-runtime").JSX.Element;
26
29
  /**
27
- * Subscribe to every 401 the provider's client receives, from any request. `listener` should be
30
+ * Subscribe to every unauthenticated response (`ApiClientOptions.onUnauthorized`) the provider's
31
+ * client receives, from any request. `listener` should be
28
32
  * stable (e.g. from `useCallback`): a new function re-subscribes. No-op outside a provider.
29
33
  */
30
34
  export declare function useOnUnauthorized(listener: () => void): void;
35
+ /** As {@link useOnUnauthorized}, for responses refusing the editor's mode (`EDITOR_MODE_MISMATCH`). */
36
+ export declare function useOnEditorModeMismatch(listener: () => void): void;
31
37
  /**
32
38
  * Hook to access the API client.
33
39
  * Must be used within an ApiClientProvider.
@@ -9,7 +9,7 @@ import { createContext, useContext, useEffect, useMemo, useState } from 'react';
9
9
  import { createApiClient } from '../../api/index.js';
10
10
  import { joinUrlPrefix } from '../../utils/url-prefix.js';
11
11
  const ApiClientContext = createContext(null);
12
- function createUnauthorizedSignal() {
12
+ function createClientSignal() {
13
13
  const listeners = new Set();
14
14
  return {
15
15
  emit: () => {
@@ -25,36 +25,47 @@ function createUnauthorizedSignal() {
25
25
  };
26
26
  }
27
27
  const UnauthorizedSignalContext = createContext(null);
28
+ const EditorModeMismatchSignalContext = createContext(null);
28
29
  /**
29
30
  * Provider that creates and provides the API client.
30
31
  * Use the client prop to inject a mock client for testing.
31
32
  */
32
- export function ApiClientProvider({ children, client, basePath }) {
33
- const [unauthorized] = useState(createUnauthorizedSignal);
33
+ export function ApiClientProvider({ children, client, basePath, editorMode, }) {
34
+ const [unauthorized] = useState(createClientSignal);
35
+ const [modeMismatch] = useState(createClientSignal);
34
36
  // Memoized on identity, not just for cost: several consumers now list the client in their
35
37
  // effect deps (useUserContext, useReferenceResolution, ReferenceField), so a fresh client each
36
38
  // render would turn those one-shot fetches into a loop. A caller injecting an inline
37
39
  // `client={createApiClient()}` would reintroduce exactly that.
38
40
  //
39
- // Only a client built HERE reports 401s to `useOnUnauthorized`; an injected `client` is used
40
- // as-is, so its 401s reach the auth gate only through the gate's own whoami result.
41
+ // Only a client built HERE reports to `useOnUnauthorized` and `useOnEditorModeMismatch`; an
42
+ // injected `client` is used as-is, so its 401s and mode mismatches reach the auth gate only
43
+ // through the gate's own whoami result.
41
44
  const apiClient = useMemo(() => {
42
45
  return (client ??
43
46
  createApiClient({
44
47
  baseUrl: joinUrlPrefix(basePath, '/api/canopycms'),
45
48
  onUnauthorized: unauthorized.emit,
49
+ editorMode,
50
+ onEditorModeMismatch: modeMismatch.emit,
46
51
  }));
47
- }, [client, basePath, unauthorized]);
48
- return (_jsx(UnauthorizedSignalContext.Provider, { value: unauthorized, children: _jsx(ApiClientContext.Provider, { value: apiClient, children: children }) }));
52
+ }, [client, basePath, editorMode, unauthorized, modeMismatch]);
53
+ return (_jsx(UnauthorizedSignalContext.Provider, { value: unauthorized, children: _jsx(EditorModeMismatchSignalContext.Provider, { value: modeMismatch, children: _jsx(ApiClientContext.Provider, { value: apiClient, children: children }) }) }));
49
54
  }
50
55
  /**
51
- * Subscribe to every 401 the provider's client receives, from any request. `listener` should be
56
+ * Subscribe to every unauthenticated response (`ApiClientOptions.onUnauthorized`) the provider's
57
+ * client receives, from any request. `listener` should be
52
58
  * stable (e.g. from `useCallback`): a new function re-subscribes. No-op outside a provider.
53
59
  */
54
60
  export function useOnUnauthorized(listener) {
55
61
  const signal = useContext(UnauthorizedSignalContext);
56
62
  useEffect(() => signal?.subscribe(listener), [signal, listener]);
57
63
  }
64
+ /** As {@link useOnUnauthorized}, for responses refusing the editor's mode (`EDITOR_MODE_MISMATCH`). */
65
+ export function useOnEditorModeMismatch(listener) {
66
+ const signal = useContext(EditorModeMismatchSignalContext);
67
+ useEffect(() => signal?.subscribe(listener), [signal, listener]);
68
+ }
58
69
  /**
59
70
  * Hook to access the API client.
60
71
  * Must be used within an ApiClientProvider.
@@ -1,44 +1,22 @@
1
1
  /**
2
- * Carries `media.publicBaseUrl` (see CanopyClientConfig.assetBaseUrl) down to
3
- * every asset-URL-building component - MediaLibrary, ImageField, and the MDX
4
- * image dialog. A context (rather than a prop) because the MDX dialog is
5
- * rendered deep inside MDXEditor's lazy-loaded internals via `imagePlugin`'s
6
- * `ImageDialog` param, with no prop channel of its own (the same reason
7
- * `EntryLinkContext` exists for the entry-link toolbar button). Unlike
8
- * `ApiClientContext`, reading this without a provider is safe and intentional:
9
- * no provider means root-relative URLs, which is the correct default for the
10
- * common case (editor and site share an origin).
2
+ * Carries the prefix every editor-built asset URL is put behind - MediaLibrary thumbnails,
3
+ * ImageField's preview and crop source, and the MDX editor's image previews. A context (rather
4
+ * than a prop) because the MDX dialog is rendered deep inside MDXEditor's lazy-loaded internals
5
+ * via `imagePlugin`'s `ImageDialog` param, with no prop channel of its own (the same reason
6
+ * `EntryLinkContext` exists for the entry-link toolbar button).
11
7
  */
12
8
  import React from 'react';
9
+ import { authenticatedAssetBase } from '../raw-asset-base.js';
10
+ export { authenticatedAssetBase };
13
11
  export interface AssetContextValue {
14
- /** Prefixed onto every asset URL the editor builds. `undefined` (no provider, or no `media.publicBaseUrl` configured) means root-relative - same-origin dev/prod-today behavior. */
15
- baseUrl?: string;
12
+ /** The `baseUrl` to pass to `assetUrl` for every asset URL the editor renders. */
13
+ baseUrl: string;
16
14
  }
17
- export interface AssetContextProviderProps extends AssetContextValue {
15
+ export interface AssetContextProviderProps {
18
16
  children: React.ReactNode;
19
- /**
20
- * `CanopyClientConfig.basePath` - the deployment prefix the host app is served under. Used only
21
- * when `baseUrl` is unset.
22
- */
17
+ /** `CanopyClientConfig.basePath` - the deployment prefix the host app is served under. */
23
18
  basePath?: string;
24
19
  }
25
- /**
26
- * `baseUrl` (`media.publicBaseUrl`) wins; `basePath` is the fallback.
27
- *
28
- * They are ALTERNATIVES, never composed: whichever is used names where `/assets` is mounted, in
29
- * full, and a deployment `basePath` cannot apply on top of it. Where the two differ is topology,
30
- * not precedence - see the asset-mount table in the README.
31
- *
32
- * The fallback is kept only so that existing basePath deployments do not break on upgrade,
33
- * which makes removing it a deliberate decision rather than a cleanup - it is option 1 of
34
- * `.claude/future-tasks/editor-asset-mount-topology.md`, still open.
35
- *
36
- * KNOWN LIMITATION: on a CloudFront/CDK deployment, a basePath does NOT move the asset
37
- * space (behaviors are anchored at the distribution root), so this fallback prefixes
38
- * wrongly — requests still resolve, via `withCanopy`'s auto-prefixed `/assets/:path*`
39
- * rewrite, but bypass the CDN cache and the dedicated transform Lambda. Workaround: set
40
- * `media.publicBaseUrl` to the distribution origin instead, which takes precedence here.
41
- */
42
- export declare function AssetContextProvider({ baseUrl, basePath, children }: AssetContextProviderProps): import("react/jsx-runtime").JSX.Element;
43
- /** Safe to call outside a provider - returns `{ baseUrl: undefined }` (root-relative URLs). */
20
+ export declare function AssetContextProvider({ basePath, children }: AssetContextProviderProps): import("react/jsx-runtime").JSX.Element;
21
+ /** Safe to call outside a provider - see the context's default. */
44
22
  export declare function useAssetContext(): AssetContextValue;
@@ -1,41 +1,22 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  /**
4
- * Carries `media.publicBaseUrl` (see CanopyClientConfig.assetBaseUrl) down to
5
- * every asset-URL-building component - MediaLibrary, ImageField, and the MDX
6
- * image dialog. A context (rather than a prop) because the MDX dialog is
7
- * rendered deep inside MDXEditor's lazy-loaded internals via `imagePlugin`'s
8
- * `ImageDialog` param, with no prop channel of its own (the same reason
9
- * `EntryLinkContext` exists for the entry-link toolbar button). Unlike
10
- * `ApiClientContext`, reading this without a provider is safe and intentional:
11
- * no provider means root-relative URLs, which is the correct default for the
12
- * common case (editor and site share an origin).
4
+ * Carries the prefix every editor-built asset URL is put behind - MediaLibrary thumbnails,
5
+ * ImageField's preview and crop source, and the MDX editor's image previews. A context (rather
6
+ * than a prop) because the MDX dialog is rendered deep inside MDXEditor's lazy-loaded internals
7
+ * via `imagePlugin`'s `ImageDialog` param, with no prop channel of its own (the same reason
8
+ * `EntryLinkContext` exists for the entry-link toolbar button).
13
9
  */
14
10
  import { createContext, useContext, useMemo } from 'react';
15
- const AssetContext = createContext({});
16
- /**
17
- * `baseUrl` (`media.publicBaseUrl`) wins; `basePath` is the fallback.
18
- *
19
- * They are ALTERNATIVES, never composed: whichever is used names where `/assets` is mounted, in
20
- * full, and a deployment `basePath` cannot apply on top of it. Where the two differ is topology,
21
- * not precedence - see the asset-mount table in the README.
22
- *
23
- * The fallback is kept only so that existing basePath deployments do not break on upgrade,
24
- * which makes removing it a deliberate decision rather than a cleanup - it is option 1 of
25
- * `.claude/future-tasks/editor-asset-mount-topology.md`, still open.
26
- *
27
- * KNOWN LIMITATION: on a CloudFront/CDK deployment, a basePath does NOT move the asset
28
- * space (behaviors are anchored at the distribution root), so this fallback prefixes
29
- * wrongly — requests still resolve, via `withCanopy`'s auto-prefixed `/assets/:path*`
30
- * rewrite, but bypass the CDN cache and the dedicated transform Lambda. Workaround: set
31
- * `media.publicBaseUrl` to the distribution origin instead, which takes precedence here.
32
- */
33
- export function AssetContextProvider({ baseUrl, basePath, children }) {
34
- const resolved = baseUrl ?? basePath;
35
- const value = useMemo(() => ({ baseUrl: resolved }), [resolved]);
11
+ import { authenticatedAssetBase } from '../raw-asset-base.js';
12
+ export { authenticatedAssetBase };
13
+ /** No provider means no `basePath`: the API is mounted at the origin root. */
14
+ const AssetContext = createContext({ baseUrl: authenticatedAssetBase() });
15
+ export function AssetContextProvider({ basePath, children }) {
16
+ const value = useMemo(() => ({ baseUrl: authenticatedAssetBase(basePath) }), [basePath]);
36
17
  return _jsx(AssetContext.Provider, { value: value, children: children });
37
18
  }
38
- /** Safe to call outside a provider - returns `{ baseUrl: undefined }` (root-relative URLs). */
19
+ /** Safe to call outside a provider - see the context's default. */
39
20
  export function useAssetContext() {
40
21
  return useContext(AssetContext);
41
22
  }
@@ -21,11 +21,11 @@ interface EditorStateProviderProps {
21
21
  /** Initial modal states (useful for deep linking) */
22
22
  initialModals?: Partial<ModalState>;
23
23
  }
24
- /** @internal No importer; deletion candidate in editor-state-context-migration.md. */
24
+ /** @internal No importer; deletion candidate in safeinsights/canopycms#678. */
25
25
  export declare function EditorStateProvider({ children, initialModals }: EditorStateProviderProps): import("react/jsx-runtime").JSX.Element;
26
26
  /**
27
27
  * Convenience hook for loading states only.
28
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
28
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
29
29
  */
30
30
  export declare function useEditorLoading(): {
31
31
  busy: boolean;
@@ -36,7 +36,7 @@ export declare function useEditorLoading(): {
36
36
  };
37
37
  /**
38
38
  * Convenience hook for modal states only.
39
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
39
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
40
40
  */
41
41
  export declare function useEditorModals(): {
42
42
  openModal: (key: keyof ModalState) => void;
@@ -50,7 +50,7 @@ export declare function useEditorModals(): {
50
50
  };
51
51
  /**
52
52
  * Convenience hook for preview state only.
53
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
53
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
54
54
  */
55
55
  export declare function useEditorPreview(): {
56
56
  data: FormValue;
@@ -6,7 +6,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
6
6
  */
7
7
  import { createContext, useContext, useCallback, useState, useMemo } from 'react';
8
8
  const EditorStateContext = createContext(null);
9
- /** @internal No importer; deletion candidate in editor-state-context-migration.md. */
9
+ /** @internal No importer; deletion candidate in safeinsights/canopycms#678. */
10
10
  export function EditorStateProvider({ children, initialModals }) {
11
11
  const [loading, setLoadingState] = useState({
12
12
  branches: false,
@@ -88,7 +88,7 @@ function useEditorState() {
88
88
  }
89
89
  /**
90
90
  * Convenience hook for loading states only.
91
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
91
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
92
92
  */
93
93
  export function useEditorLoading() {
94
94
  const { state, actions } = useEditorState();
@@ -100,7 +100,7 @@ export function useEditorLoading() {
100
100
  }
101
101
  /**
102
102
  * Convenience hook for modal states only.
103
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
103
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
104
104
  */
105
105
  export function useEditorModals() {
106
106
  const { state, actions } = useEditorState();
@@ -113,7 +113,7 @@ export function useEditorModals() {
113
113
  }
114
114
  /**
115
115
  * Convenience hook for preview state only.
116
- * @internal No importer; deletion candidate in editor-state-context-migration.md.
116
+ * @internal No importer; deletion candidate in safeinsights/canopycms#678.
117
117
  */
118
118
  export function useEditorPreview() {
119
119
  const { state, actions } = useEditorState();
@@ -7,9 +7,9 @@
7
7
  * to snap back to fresh data whenever the tab regains focus; a few
8
8
  * seconds of staleness is harmless, and refetching on every alt-tab is
9
9
  * just extra load against the branch clone.
10
- * - shouldRetryOnError: false -- matches the hooks' pre-SWR behavior, which
11
- * surfaced a single failure (notification + console.error) rather than
12
- * silently retrying in the background.
10
+ * - shouldRetryOnError: false -- a failure, an ApiTimeoutError included,
11
+ * stays an error until something revalidates the key (a Retry, a branch
12
+ * switch, a re-sign-in), so a stalled API never drives a retry loop.
13
13
  * - provider: () => new Map() -- gives the editor its own cache instead of
14
14
  * SWR's module-global one, so editor keys ("canopy:entries:main", ...) can
15
15
  * never collide with an SWR cache the host app is running for its own data.
@@ -0,0 +1,4 @@
1
+ import type { MdxAllowlist } from '../../config/index.js';
2
+ /** The config's `mdxAllow`, which each field checked as MDX narrows by its own. */
3
+ export declare const SiteMdxAllowContext: import("react").Context<MdxAllowlist | undefined>;
4
+ export declare function useSiteMdxAllow(): MdxAllowlist | undefined;
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ import { createContext, useContext } from 'react';
3
+ /** The config's `mdxAllow`, which each field checked as MDX narrows by its own. */
4
+ export const SiteMdxAllowContext = createContext(undefined);
5
+ export function useSiteMdxAllow() {
6
+ return useContext(SiteMdxAllowContext);
7
+ }
@@ -1,4 +1,5 @@
1
1
  export { ApiClientProvider, useApiClient, useOptionalApiClient, type ApiClient, type ApiClientProviderProps, } from './ApiClientContext.js';
2
- export { AssetContextProvider, useAssetContext, type AssetContextValue, type AssetContextProviderProps, } from './AssetContext.js';
2
+ export { AssetContextProvider, authenticatedAssetBase, useAssetContext, type AssetContextValue, type AssetContextProviderProps, } from './AssetContext.js';
3
3
  export { SWRProvider, type SWRProviderProps } from './SWRProvider.js';
4
4
  export { useEditorLoading, useEditorModals, useEditorPreview } from './EditorStateContext.js';
5
+ export { SiteMdxAllowContext, useSiteMdxAllow } from './SiteMdxAllowContext.js';
@@ -1,4 +1,5 @@
1
1
  export { ApiClientProvider, useApiClient, useOptionalApiClient, } from './ApiClientContext.js';
2
- export { AssetContextProvider, useAssetContext, } from './AssetContext.js';
2
+ export { AssetContextProvider, authenticatedAssetBase, useAssetContext, } from './AssetContext.js';
3
3
  export { SWRProvider } from './SWRProvider.js';
4
4
  export { useEditorLoading, useEditorModals, useEditorPreview } from './EditorStateContext.js';
5
+ export { SiteMdxAllowContext, useSiteMdxAllow } from './SiteMdxAllowContext.js';
@@ -0,0 +1,19 @@
1
+ /** Whether Mantine's `toRgba` parses `colour`; it misreads anything else, `oklch()` as black. */
2
+ export declare const isMeasurable: (colour: string) => boolean;
3
+ /** The WCAG 2 contrast ratio of two opaque colours. */
4
+ export declare const contrastRatio: (a: string, b: string) => number;
5
+ /** `color` at `opacity` over the opaque `background`, as one opaque colour. */
6
+ export declare const composite: (color: string, opacity: number, background: string) => string;
7
+ /**
8
+ * The first step from `from` toward the scale's dark or light end reaching `minimum` on
9
+ * `background`, else the end shade darkened or lightened until it does (`shade` unset).
10
+ */
11
+ export declare const readableOnScale: (scale: readonly string[], options: {
12
+ from: number;
13
+ toward: "darker" | "lighter";
14
+ background: string;
15
+ minimum?: number;
16
+ }) => {
17
+ shade?: number;
18
+ value: string;
19
+ };
@@ -0,0 +1,41 @@
1
+ import { darken, lighten, luminance, toRgba } from '@mantine/core';
2
+ const MEASURABLE = [
3
+ /^#([0-9a-f]{3}){1,2}([0-9a-f]{2})?$/i,
4
+ /^rgba?\(\s*[\d.]+\s*,\s*[\d.]+\s*,\s*[\d.]+\s*(,\s*[\d.]+\s*)?\)$/i,
5
+ /^hsla?\(\s*\d+\s*,\s*\d+%\s*,\s*\d+%\s*(,\s*[\d.]+\s*)?\)$/i,
6
+ ];
7
+ /** Whether Mantine's `toRgba` parses `colour`; it misreads anything else, `oklch()` as black. */
8
+ export const isMeasurable = (colour) => MEASURABLE.some((pattern) => pattern.test(colour.trim()));
9
+ /** WCAG 2's minimum for body text. */
10
+ const TEXT_CONTRAST = 4.5;
11
+ /** The WCAG 2 contrast ratio of two opaque colours. */
12
+ export const contrastRatio = (a, b) => {
13
+ const [light, dark] = [luminance(a), luminance(b)].sort((x, y) => y - x);
14
+ return (light + 0.05) / (dark + 0.05);
15
+ };
16
+ /** `color` at `opacity` over the opaque `background`, as one opaque colour. */
17
+ export const composite = (color, opacity, background) => {
18
+ const fg = toRgba(color);
19
+ const bg = toRgba(background);
20
+ const mix = (f, b) => Math.round(f * opacity + b * (1 - opacity));
21
+ return `rgb(${mix(fg.r, bg.r)}, ${mix(fg.g, bg.g)}, ${mix(fg.b, bg.b)})`;
22
+ };
23
+ /**
24
+ * The first step from `from` toward the scale's dark or light end reaching `minimum` on
25
+ * `background`, else the end shade darkened or lightened until it does (`shade` unset).
26
+ */
27
+ export const readableOnScale = (scale, options) => {
28
+ const { from, toward, background, minimum = TEXT_CONTRAST } = options;
29
+ const step = toward === 'darker' ? 1 : -1;
30
+ const end = toward === 'darker' ? scale.length - 1 : 0;
31
+ for (let shade = from; step > 0 ? shade <= end : shade >= end; shade += step) {
32
+ if (contrastRatio(scale[shade], background) >= minimum)
33
+ return { shade, value: scale[shade] };
34
+ }
35
+ for (let amount = 0.05; amount < 1; amount += 0.05) {
36
+ const value = toward === 'darker' ? darken(scale[end], amount) : lighten(scale[end], amount);
37
+ if (contrastRatio(value, background) >= minimum)
38
+ return { value };
39
+ }
40
+ return { value: toward === 'darker' ? '#000000' : '#ffffff' };
41
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The editor's fixed action verbs, sentence case and verb first. "…" is appended only where
3
+ * the command asks for more before it acts ("Switch branch…"); see docs/ux-guidelines.md.
4
+ * New UI uses these instead of writing the strings inline.
5
+ */
6
+ export declare const EDITOR_ACTIONS: {
7
+ readonly save: "Save";
8
+ readonly saveAll: "Save all";
9
+ readonly refreshFromServer: "Refresh from server";
10
+ readonly submitForReview: "Submit for review";
11
+ readonly withdrawFromReview: "Withdraw from review";
12
+ readonly requestChanges: "Request changes";
13
+ readonly switchBranch: "Switch branch";
14
+ readonly newBranch: "New branch";
15
+ readonly remove: "Remove";
16
+ readonly clear: "Clear";
17
+ readonly openEntry: "Open entry";
18
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The editor's fixed action verbs, sentence case and verb first. "…" is appended only where
3
+ * the command asks for more before it acts ("Switch branch…"); see docs/ux-guidelines.md.
4
+ * New UI uses these instead of writing the strings inline.
5
+ */
6
+ export const EDITOR_ACTIONS = {
7
+ save: 'Save',
8
+ saveAll: 'Save all',
9
+ refreshFromServer: 'Refresh from server',
10
+ submitForReview: 'Submit for review',
11
+ withdrawFromReview: 'Withdraw from review',
12
+ requestChanges: 'Request changes',
13
+ switchBranch: 'Switch branch',
14
+ newBranch: 'New branch',
15
+ remove: 'Remove',
16
+ clear: 'Clear',
17
+ openEntry: 'Open entry',
18
+ };