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
@@ -12,26 +12,40 @@ import { isDataOnlyFormat } from '../utils/format.js';
12
12
  import { extractEntryTypeFromFilename, extractIdFromFilename, } from '../content-id-index.js';
13
13
  import { hasTraversalSequence } from '../paths/index.js';
14
14
  import { getErrorMessage, isNodeError } from '../utils/error.js';
15
- import { entryToMarkdown } from './json-to-markdown.js';
15
+ import { buildResolvedReference } from '../entry-schema.js';
16
+ import { entryToMarkdown, frontmatterTitle } from './json-to-markdown.js';
17
+ import { createReferenceRendering, createReferenceTargetResolver, decideReferenceLinks, maskUnexportedTargets, resolveReferenceFields, } from './references.js';
16
18
  import { resolveEntryLinksInText } from '../entry-link-resolver.js';
19
+ import { computeEntryUrl } from '../utils/entry-url.js';
20
+ import { DEFAULT_SEO_FIELD_NAMES, isNoindexEntry } from '../static/seo.js';
17
21
  /**
18
22
  * Generate all AI content from the content store.
19
23
  *
20
24
  * Walks the schema tree, reads entries, converts to markdown,
21
25
  * and produces per-entry files, per-collection all.md files,
22
26
  * bundle files, and a manifest.
27
+ *
28
+ * A reference or body `entry:` link may only show a target that is itself exported, so every
29
+ * entry is read and filtered first, which settles the exported set. Only then are body links
30
+ * resolved for output, references to anything outside the set masked, entry transforms run, and markdown
31
+ * rendered, in rounds that repeat while a render fails (see the loop below).
23
32
  */
24
33
  export async function generateAIContent(options) {
25
34
  const { store, flatSchema, contentRoot, config, entryLinkUrl, generatedAt, buildId } = options;
35
+ assertValidNoindexConfig(config);
36
+ assertValidReferenceLink(config);
26
37
  const files = new Map();
27
38
  const idIndex = await store.idIndex();
39
+ const read = {
40
+ store,
41
+ contentRoot,
42
+ config,
43
+ idIndex,
44
+ entryLinkUrl,
45
+ resolveTarget: createReferenceTargetResolver(store),
46
+ };
28
47
  const collections = flatSchema.filter((item) => item.type === 'collection');
29
- // Track all entries for bundle filtering
30
- const allEntries = [];
31
- // Track manifest collections (tree structure)
32
- const manifestCollections = [];
33
- // Track root-level entries (entries in the content root, not in a subcollection)
34
- const rootEntries = [];
48
+ const collectionNodes = [];
35
49
  for (const collection of collections) {
36
50
  // Skip the content root itself — we process its children
37
51
  if (collection.logicalPath === contentRoot)
@@ -42,23 +56,97 @@ export async function generateAIContent(options) {
42
56
  // (subcollections are handled recursively via their parent)
43
57
  if (collection.parentPath && collection.parentPath !== contentRoot)
44
58
  continue;
45
- const collectionResult = await processCollection(store, collection, flatSchema, contentRoot, config, idIndex, entryLinkUrl);
46
- allEntries.push(...collectionResult.entries);
47
- for (const [filePath, content] of collectionResult.files) {
48
- files.set(filePath, content);
49
- }
50
- manifestCollections.push(collectionResult.manifestCollection);
59
+ collectionNodes.push(await collectCollection(read, collection, flatSchema));
51
60
  }
52
- // Process root-level entries (entries in content root, not in any subcollection)
61
+ // Root-level entries (entries in content root, not in any subcollection)
53
62
  const rootCollection = collections.find((c) => c.logicalPath === contentRoot);
54
- if (rootCollection?.entries) {
55
- const rootResult = await processRootEntries(store, rootCollection, contentRoot, config, idIndex, entryLinkUrl);
56
- allEntries.push(...rootResult.entries);
57
- for (const [filePath, content] of rootResult.files) {
58
- files.set(filePath, content);
63
+ const rootEntries = rootCollection?.entries ? await collectEntries(read, rootCollection, '') : [];
64
+ // Collection entries first, then root entries: the order bundles list them in
65
+ const allPending = [...collectionNodes.flatMap(subtreeEntries), ...rootEntries];
66
+ // Content id -> output file of every exported entry: the export set, and where each
67
+ // reference's markdown copy lives
68
+ const exported = new Map();
69
+ for (const pending of allPending) {
70
+ if (pending.contentId !== null)
71
+ exported.set(pending.contentId, pending.filePath);
72
+ }
73
+ const pendingById = new Map();
74
+ for (const pending of allPending) {
75
+ if (pending.contentId !== null)
76
+ pendingById.set(pending.contentId, pending);
77
+ }
78
+ // The target as `resolveReferenceTarget` would give it, built from this export's own read, so
79
+ // an entry outside the export set is never offered and a target cannot change mid-run
80
+ const subjectOf = (id) => {
81
+ const pending = pendingById.get(id);
82
+ if (!pending || !exported.has(id))
83
+ return undefined;
84
+ const { slug } = pending.entry;
85
+ const target = buildResolvedReference(structuredClone(pending.storedData), {
86
+ id,
87
+ slug,
88
+ collection: pending.collectionPath,
89
+ urlPath: computeEntryUrl(pending.collectionPath, slug, contentRoot),
90
+ });
91
+ return { target, body: pending.body };
92
+ };
93
+ const linkFor = config?.referenceLink
94
+ ? await decideReferenceLinks(config.referenceLink, allPending, subjectOf, entryLinkUrl)
95
+ : undefined;
96
+ // A body `entry:` link takes the same page URL a reference to its target renders with
97
+ const bodyLinkUrl = linkFor
98
+ ? (location) => {
99
+ const decided = linkFor(location.id);
100
+ if (typeof decided === 'string')
101
+ return decided;
102
+ return entryLinkUrl
103
+ ? entryLinkUrl(location)
104
+ : computeEntryUrl(location.collection, location.slug, contentRoot);
59
105
  }
60
- rootEntries.push(...rootResult.manifestEntries);
106
+ : entryLinkUrl;
107
+ const references = createReferenceRendering(idIndex, flatSchema, entryLinkUrl, { mountPath: config?.mountPath ?? '/ai', files: exported }, linkFor);
108
+ // An entry whose render throws is not in the export after all, so references and body links to
109
+ // it are withheld like any other left-out target, and the entries that changed run their
110
+ // transforms and render again. That can fail another entry, so this repeats until a round fails
111
+ // none; each round removes at least one entry, so it ends.
112
+ let round = allPending;
113
+ for (;;) {
114
+ for (const pending of round) {
115
+ if (pending.body !== undefined) {
116
+ const linked = new Set();
117
+ pending.entry.body = resolveEntryLinksInText(pending.body, idIndex, contentRoot, bodyLinkUrl, {
118
+ isLinkable: (id) => {
119
+ linked.add(id);
120
+ return exported.has(id) && linkFor?.(id) !== false;
121
+ },
122
+ });
123
+ pending.linkedIds = [...linked];
124
+ }
125
+ maskUnexportedTargets(pending.entry, exported);
126
+ // Fold in adopter-supplied markdown (e.g. a colocated sibling artifact), on data as masked
127
+ pending.entry.appendedSections = undefined;
128
+ await runEntryTransform(pending.entry, pending.absolutePath, pending.contentId, config);
129
+ }
130
+ const failed = renderAll(round, config, references);
131
+ if (failed.length === 0)
132
+ break;
133
+ const failedIds = new Set();
134
+ for (const pending of failed) {
135
+ if (pending.contentId === null)
136
+ continue;
137
+ exported.delete(pending.contentId);
138
+ failedIds.add(pending.contentId);
139
+ }
140
+ round = allPending.filter((pending) => {
141
+ if (!isRendered(pending))
142
+ return false;
143
+ const masked = maskUnexportedTargets(pending.entry, exported);
144
+ return masked || pending.linkedIds.some((id) => failedIds.has(id));
145
+ });
61
146
  }
147
+ const manifestCollections = collectionNodes.map((node) => emitCollection(node, files));
148
+ const manifestRootEntries = emitEntries(rootEntries, files);
149
+ const allEntries = allPending.filter(isRendered);
62
150
  const manifestBundles = [];
63
151
  if (config?.bundles) {
64
152
  for (const bundle of config.bundles) {
@@ -66,11 +154,9 @@ export async function generateAIContent(options) {
66
154
  if (/[/\\]|\.\./.test(bundle.name)) {
67
155
  throw new Error(`Invalid bundle name "${bundle.name}": must not contain slashes or ".."`);
68
156
  }
69
- const matchingEntries = allEntries.filter((entry) => matchesBundleFilter(entry, bundle.filter, contentRoot));
157
+ const matchingEntries = allEntries.filter((pending) => matchesBundleFilter(pending.entry, bundle.filter, contentRoot));
70
158
  if (matchingEntries.length > 0) {
71
- const bundleContent = matchingEntries
72
- .map((e) => entryToMarkdown(e, config))
73
- .join('\n---\n\n');
159
+ const bundleContent = matchingEntries.map((p) => p.markdown).join('\n---\n\n');
74
160
  const bundlePath = `bundles/${bundle.name}.md`;
75
161
  files.set(bundlePath, bundleContent);
76
162
  manifestBundles.push({
@@ -89,18 +175,53 @@ export async function generateAIContent(options) {
89
175
  const manifest = {
90
176
  ...(buildId ? { buildId } : {}),
91
177
  ...(generatedAt || !buildId ? { generated: generatedAt || new Date().toISOString() } : {}),
92
- entries: rootEntries,
178
+ entries: manifestRootEntries,
93
179
  collections: manifestCollections,
94
180
  bundles: manifestBundles,
95
181
  };
96
182
  files.set('manifest.json', JSON.stringify(manifest, null, 2));
97
183
  return { manifest, files };
98
184
  }
99
- async function processCollection(store, collection, flatSchema, contentRoot, config, idIndex, entryLinkUrl) {
100
- const files = new Map();
101
- const entries = [];
102
- const cleanPath = stripContentRoot(collection.logicalPath, contentRoot);
103
- const manifestEntries = [];
185
+ /** Render each entry's markdown, returning those whose render threw (left without markdown). */
186
+ function renderAll(entries, config, references) {
187
+ const failed = [];
188
+ for (const pending of entries) {
189
+ try {
190
+ pending.markdown = entryToMarkdown(pending.entry, config, references);
191
+ }
192
+ catch (err) {
193
+ pending.markdown = undefined;
194
+ failed.push(pending);
195
+ console.warn(`AI content: skipping entry "${pending.entry.slug}" in ${pending.collectionPath}:`, getErrorMessage(err));
196
+ }
197
+ }
198
+ return failed;
199
+ }
200
+ function isRendered(pending) {
201
+ return pending.markdown !== undefined;
202
+ }
203
+ /** A collection's direct entries, then each subcollection's, in the order all.md lists them. */
204
+ function subtreeEntries(node) {
205
+ return [...node.entries, ...node.subcollections.flatMap(subtreeEntries)];
206
+ }
207
+ async function collectCollection(read, collection, flatSchema) {
208
+ const cleanPath = stripContentRoot(collection.logicalPath, read.contentRoot);
209
+ const entries = await collectEntries(read, collection, cleanPath);
210
+ const subcollections = [];
211
+ for (const sub of flatSchema) {
212
+ if (sub.type !== 'collection' || sub.parentPath !== collection.logicalPath)
213
+ continue;
214
+ if (isCollectionExcluded(sub.logicalPath, read.contentRoot, read.config))
215
+ continue;
216
+ subcollections.push(await collectCollection(read, sub, flatSchema));
217
+ }
218
+ return { collection, cleanPath, entries, subcollections };
219
+ }
220
+ /** Read, resolve and filter the entries directly in `collection` (not its subcollections). */
221
+ async function collectEntries(read, collection, cleanPath) {
222
+ const { store, contentRoot, config, idIndex, entryLinkUrl, resolveTarget } = read;
223
+ const skipNoindex = config?.exclude?.noindex !== false;
224
+ const pending = [];
104
225
  const listed = await store.getCollectionEntryPaths(collection.logicalPath);
105
226
  // Filter to only entries in this exact collection (not subcollections)
106
227
  const directEntries = listed.filter((e) => e.collection === collection.logicalPath);
@@ -111,109 +232,116 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
111
232
  if (config?.exclude?.entryTypes?.includes(entryTypeName))
112
233
  continue;
113
234
  const entryTypeConfig = findEntryType(collection, entryTypeName);
114
- if (!entryTypeConfig)
235
+ if (!entryTypeConfig || entryTypeConfig.unavailable)
115
236
  continue;
116
237
  try {
117
238
  const doc = await store.read(listEntry.collection, listEntry.slug, {
118
239
  resolveReferences: false,
119
240
  });
241
+ // AI content advertises an entry, so `noindex` leaves it out here as it does the sitemap.
242
+ if (skipNoindex && isNoindexEntry(doc.data, config?.seo))
243
+ continue;
244
+ const storedData = doc.data;
245
+ doc.data = await resolveReferenceFields(doc.data, entryTypeConfig.schema, resolveTarget);
120
246
  const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, cleanPath);
121
- if (aiEntry.body && idIndex) {
122
- aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
123
- }
247
+ const body = aiEntry.body;
248
+ // `where` sees every link resolved; the export's own rendering re-resolves from `body`
249
+ if (body)
250
+ aiEntry.body = resolveEntryLinksInText(body, idIndex, contentRoot, entryLinkUrl);
124
251
  if (config?.exclude?.where?.(aiEntry))
125
252
  continue;
126
- // Fold in adopter-supplied markdown (e.g. a colocated sibling artifact), once per entry
127
- await runEntryTransform(aiEntry, doc.absolutePath, extractIdFromFilename(path.basename(listEntry.relativePath)), config);
128
- entries.push(aiEntry);
129
- const entryFilePath = `${cleanPath}/${listEntry.slug}.md`;
130
- const entryMarkdown = entryToMarkdown(aiEntry, config);
131
- files.set(entryFilePath, entryMarkdown);
132
- manifestEntries.push({
133
- slug: listEntry.slug,
134
- title: aiEntry.data.title ? String(aiEntry.data.title) : undefined,
135
- file: entryFilePath,
253
+ pending.push({
254
+ entry: aiEntry,
255
+ body,
256
+ storedData,
257
+ linkedIds: [],
258
+ contentId: extractIdFromFilename(path.basename(listEntry.relativePath)),
259
+ absolutePath: doc.absolutePath,
260
+ collectionPath: collection.logicalPath,
261
+ filePath: cleanPath ? `${cleanPath}/${listEntry.slug}.md` : `${listEntry.slug}.md`,
136
262
  });
137
263
  }
138
264
  catch (err) {
139
265
  console.warn(`AI content: skipping entry "${listEntry.slug}" in ${collection.logicalPath}:`, getErrorMessage(err));
140
- continue;
141
- }
142
- }
143
- const subcollections = flatSchema.filter((item) => item.type === 'collection' && item.parentPath === collection.logicalPath);
144
- const manifestSubcollections = [];
145
- for (const sub of subcollections) {
146
- if (isCollectionExcluded(sub.logicalPath, contentRoot, config))
147
- continue;
148
- const subResult = await processCollection(store, sub, flatSchema, contentRoot, config, idIndex, entryLinkUrl);
149
- entries.push(...subResult.entries);
150
- for (const [filePath, content] of subResult.files) {
151
- files.set(filePath, content);
152
266
  }
153
- manifestSubcollections.push(subResult.manifestCollection);
154
267
  }
155
- // Write all.md for this collection (includes direct entries + subcollection entries)
156
- if (entries.length > 0) {
157
- const allContent = entries.map((e) => entryToMarkdown(e, config)).join('\n---\n\n');
158
- const allPath = `${cleanPath}/all.md`;
159
- files.set(allPath, allContent);
268
+ return pending;
269
+ }
270
+ /** Write each rendered entry's file and return its manifest rows. */
271
+ function emitEntries(entries, files) {
272
+ return entries.filter(isRendered).map((pending) => {
273
+ files.set(pending.filePath, pending.markdown);
274
+ return {
275
+ slug: pending.entry.slug,
276
+ title: frontmatterTitle(pending.entry.data),
277
+ file: pending.filePath,
278
+ };
279
+ });
280
+ }
281
+ /** Write a collection's entry files and all.md, recursively, and return its manifest node. */
282
+ function emitCollection(node, files) {
283
+ const manifestEntries = emitEntries(node.entries, files);
284
+ const manifestSubcollections = node.subcollections.map((sub) => emitCollection(sub, files));
285
+ // all.md covers direct entries + subcollection entries
286
+ const rendered = subtreeEntries(node).filter(isRendered);
287
+ const allPath = `${node.cleanPath}/all.md`;
288
+ if (rendered.length > 0) {
289
+ files.set(allPath, rendered.map((p) => p.markdown).join('\n---\n\n'));
160
290
  }
161
- const manifestCollection = {
162
- name: collection.name,
163
- label: collection.label,
164
- description: collection.description,
165
- path: cleanPath,
166
- allFile: entries.length > 0 ? `${cleanPath}/all.md` : undefined,
167
- entryCount: entries.length,
291
+ return {
292
+ name: node.collection.name,
293
+ label: node.collection.label,
294
+ description: node.collection.description,
295
+ path: node.cleanPath,
296
+ allFile: rendered.length > 0 ? allPath : undefined,
297
+ entryCount: rendered.length,
168
298
  entries: manifestEntries,
169
299
  subcollections: manifestSubcollections.length > 0 ? manifestSubcollections : undefined,
170
300
  };
171
- return { entries, files, manifestCollection };
172
301
  }
173
- async function processRootEntries(store, rootCollection, contentRoot, config, idIndex, entryLinkUrl) {
174
- const files = new Map();
175
- const entries = [];
176
- const manifestEntries = [];
177
- const listed = await store.getCollectionEntryPaths(rootCollection.logicalPath);
178
- // Only direct entries in root (not in subcollections)
179
- const directEntries = listed.filter((e) => e.collection === rootCollection.logicalPath);
180
- for (const listEntry of directEntries) {
181
- const entryTypeName = extractEntryTypeFromFilename(path.basename(listEntry.relativePath));
182
- if (!entryTypeName)
183
- continue;
184
- if (config?.exclude?.entryTypes?.includes(entryTypeName))
185
- continue;
186
- const entryTypeConfig = findEntryType(rootCollection, entryTypeName);
187
- if (!entryTypeConfig)
188
- continue;
189
- try {
190
- const doc = await store.read(listEntry.collection, listEntry.slug, {
191
- resolveReferences: false,
192
- });
193
- const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, '');
194
- if (aiEntry.body && idIndex) {
195
- aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
196
- }
197
- if (config?.exclude?.where?.(aiEntry))
198
- continue;
199
- // Fold in adopter-supplied markdown (e.g. a colocated sibling artifact), once per entry
200
- await runEntryTransform(aiEntry, doc.absolutePath, extractIdFromFilename(path.basename(listEntry.relativePath)), config);
201
- entries.push(aiEntry);
202
- const entryFilePath = `${listEntry.slug}.md`;
203
- const entryMarkdown = entryToMarkdown(aiEntry, config);
204
- files.set(entryFilePath, entryMarkdown);
205
- manifestEntries.push({
206
- slug: listEntry.slug,
207
- title: aiEntry.data.title ? String(aiEntry.data.title) : undefined,
208
- file: entryFilePath,
209
- });
210
- }
211
- catch (err) {
212
- console.warn(`AI content: skipping root entry "${listEntry.slug}":`, getErrorMessage(err));
213
- continue;
214
- }
302
+ /**
303
+ * Refuse a `referenceLink` that is not a function, which would otherwise fail every call and
304
+ * withhold every link it governs, one warning per target.
305
+ */
306
+ function assertValidReferenceLink(config) {
307
+ const referenceLink = config?.referenceLink;
308
+ if (referenceLink !== undefined && typeof referenceLink !== 'function') {
309
+ throw new Error(`AI content config: referenceLink must be a function, got ${typeof referenceLink}`);
310
+ }
311
+ }
312
+ /**
313
+ * Refuse an `exclude.noindex` or `seo` the noindex gate would misread. A non-boolean
314
+ * `noindex: 'false'` would leave the gate on while the adopter believes it is off, and a
315
+ * misshapen `seo` reads the flag from a field no entry sets, so every noindex entry ships.
316
+ */
317
+ function assertValidNoindexConfig(config) {
318
+ const noindex = config?.exclude?.noindex;
319
+ if (noindex !== undefined && typeof noindex !== 'boolean') {
320
+ throw new Error(`AI content config: exclude.noindex must be a boolean, got ${typeof noindex}`);
321
+ }
322
+ const seo = config?.seo;
323
+ if (seo === undefined)
324
+ return;
325
+ if (typeof seo !== 'object' || seo === null || Array.isArray(seo)) {
326
+ throw new Error('AI content config: seo must be an object of { group?, fields? }');
327
+ }
328
+ const { group, fields } = seo;
329
+ if (group !== undefined && typeof group !== 'string') {
330
+ throw new Error('AI content config: seo.group must be a string');
331
+ }
332
+ if (fields === undefined)
333
+ return;
334
+ if (typeof fields !== 'object' ||
335
+ fields === null ||
336
+ Array.isArray(fields) ||
337
+ Object.values(fields).some((name) => typeof name !== 'string')) {
338
+ throw new Error('AI content config: seo.fields must map SEO fields to field-name strings');
339
+ }
340
+ // An unknown key (`noIndex`) would leave the gate reading the default field name
341
+ const unknown = Object.keys(fields).filter((key) => !(key in DEFAULT_SEO_FIELD_NAMES));
342
+ if (unknown.length > 0) {
343
+ throw new Error(`AI content config: unknown seo.fields key(s): ${unknown.join(', ')}`);
215
344
  }
216
- return { entries, files, manifestEntries };
217
345
  }
218
346
  function stripContentRoot(logicalPath, contentRoot) {
219
347
  if (logicalPath.startsWith(contentRoot + '/')) {
@@ -282,8 +410,9 @@ function makeReadSibling(dir) {
282
410
  /**
283
411
  * Run the configured entry transform (if any), caching its returned markdown on
284
412
  * `entry.appendedSections`. The transform receives the entry's content ID and a directory-bound
285
- * `readSibling`. Runs once per entry; the cached result is reused across the per-entry file, the
286
- * collection `all.md`, and any bundle that includes this entry. A throwing transform is logged and
413
+ * `readSibling`. Runs for every entry in the first round, then again in any later round whose
414
+ * masking changed the entry, always on the data as masked; the cached result is reused across the per-entry file, the collection `all.md`, and any bundle that
415
+ * includes this entry. A throwing transform is logged and
287
416
  * skipped — the entry still renders without the appended section (distinct from an unreadable
288
417
  * entry, which is skipped entirely upstream).
289
418
  */
@@ -9,6 +9,6 @@ export { createAIContentHandler } from './handler.js';
9
9
  export { generateAIContent } from './generate.js';
10
10
  /** See `to-plain-text.ts`'s module doc for the pipeline and why it differs from the AI-content path above. */
11
11
  export { toPlainText } from './to-plain-text.js';
12
- export type { AIContentConfig, ExcludeConfig, BundleConfig, BundleFilter, FieldTransformFn, FieldTransforms, ComponentProps, ComponentTransformFn, ComponentTransforms, BodyTransformFn, BodyTransforms, EntryTransformFn, EntryTransforms, EntryTransformContext, AIManifest, AIManifestCollection, AIManifestEntry, AIManifestBundle, AIEntry, AIEntryMeta, } from './types.js';
12
+ export type { AIContentConfig, ExcludeConfig, BundleConfig, BundleFilter, FieldTransformFn, FieldTransforms, ComponentProps, ComponentTransformFn, ComponentTransforms, BodyTransformFn, BodyTransforms, EntryTransformFn, EntryTransforms, EntryTransformContext, AIManifest, AIManifestCollection, AIManifestEntry, AIManifestBundle, AIEntry, AIEntryMeta, AIExcludedReference, AIReferenceLinkContext, AIReferenceLinkFn, AIReferenceValue, AIResolvedReference, AIUnavailableReference, } from './types.js';
13
13
  export type { AIContentHandlerOptions } from './handler.js';
14
14
  export type { GenerateOptions, GenerateResult } from './generate.js';
@@ -5,10 +5,30 @@
5
5
  * Handles all CanopyCMS field types including nested objects and blocks.
6
6
  */
7
7
  import type { AIEntry, AIContentConfig } from './types.js';
8
+ /**
9
+ * How a resolved reference becomes link text and a link target. generate.ts supplies one that
10
+ * knows every target's schema and the adopter's `entryLinkUrl`; the default needs neither.
11
+ */
12
+ export interface ReferenceRendering {
13
+ /** Display title of a resolved target, used unless the field's `displayField` holds text. */
14
+ title(target: Record<string, unknown>): string;
15
+ /**
16
+ * Where the page link points: undefined renders the title as plain text, and `false` also
17
+ * drops the markdown copy, for a target the site says has no page.
18
+ */
19
+ url(target: Record<string, unknown>): string | false | undefined;
20
+ /** URL of the target's own file in this export, linked after the page as its markdown copy. */
21
+ markdownUrl?(target: Record<string, unknown>): string | undefined;
22
+ }
23
+ /**
24
+ * The entry's `title` as frontmatter carries it. Only a scalar qualifies: a `reference` field
25
+ * named `title` holds an object and renders as a field instead.
26
+ */
27
+ export declare function frontmatterTitle(data: Record<string, unknown>): string | undefined;
8
28
  /**
9
29
  * Convert an entry to clean markdown suitable for AI consumption.
10
30
  *
11
31
  * For MD/MDX entries: renders frontmatter fields as metadata, appends body verbatim.
12
32
  * For JSON entries: full schema-driven conversion of all fields.
13
33
  */
14
- export declare function entryToMarkdown(entry: AIEntry, config?: AIContentConfig): string;
34
+ export declare function entryToMarkdown(entry: AIEntry, config?: AIContentConfig, references?: ReferenceRendering): string;