canopycms 0.0.67-int.90 → 0.0.67

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 (539) hide show
  1. package/README.md +30 -3
  2. package/dist/ai/generate.js +1 -27
  3. package/dist/ai/handler.d.ts +0 -4
  4. package/dist/ai/handler.js +0 -11
  5. package/dist/ai/index.d.ts +1 -8
  6. package/dist/ai/index.js +1 -8
  7. package/dist/ai/json-to-markdown.js +15 -58
  8. package/dist/ai/resolve-branch.d.ts +2 -7
  9. package/dist/ai/resolve-branch.js +2 -8
  10. package/dist/ai/strip-mdx.d.ts +5 -13
  11. package/dist/ai/strip-mdx.js +5 -17
  12. package/dist/ai/to-plain-text.d.ts +10 -28
  13. package/dist/ai/to-plain-text.js +10 -28
  14. package/dist/ai/transform-components.d.ts +2 -4
  15. package/dist/ai/transform-components.js +8 -19
  16. package/dist/ai/types.d.ts +5 -10
  17. package/dist/api/admin-branch-health.d.ts +4 -12
  18. package/dist/api/admin-branch-health.js +26 -66
  19. package/dist/api/admin.d.ts +4 -12
  20. package/dist/api/admin.js +10 -26
  21. package/dist/api/assets.d.ts +0 -25
  22. package/dist/api/assets.js +50 -91
  23. package/dist/api/branch-merge.d.ts +1 -1
  24. package/dist/api/branch-merge.js +0 -2
  25. package/dist/api/branch-review.d.ts +0 -8
  26. package/dist/api/branch-review.js +0 -13
  27. package/dist/api/branch-status.d.ts +0 -3
  28. package/dist/api/branch-status.js +8 -33
  29. package/dist/api/branch-withdraw.d.ts +0 -1
  30. package/dist/api/branch-withdraw.js +6 -9
  31. package/dist/api/branch.d.ts +7 -12
  32. package/dist/api/branch.js +7 -44
  33. package/dist/api/client.d.ts +71 -224
  34. package/dist/api/client.js +82 -233
  35. package/dist/api/comments.d.ts +2 -4
  36. package/dist/api/comments.js +0 -17
  37. package/dist/api/content.d.ts +0 -6
  38. package/dist/api/content.js +66 -142
  39. package/dist/api/entries-constants.d.ts +5 -9
  40. package/dist/api/entries-constants.js +5 -9
  41. package/dist/api/entries.d.ts +8 -13
  42. package/dist/api/entries.js +20 -51
  43. package/dist/api/github-sync.d.ts +2 -4
  44. package/dist/api/github-sync.js +4 -8
  45. package/dist/api/groups.d.ts +3 -0
  46. package/dist/api/groups.js +8 -21
  47. package/dist/api/guards.d.ts +4 -16
  48. package/dist/api/guards.js +3 -22
  49. package/dist/api/index.d.ts +4 -4
  50. package/dist/api/permissions.d.ts +2 -0
  51. package/dist/api/permissions.js +18 -40
  52. package/dist/api/reference-options.d.ts +0 -1
  53. package/dist/api/reference-options.js +3 -11
  54. package/dist/api/request-body-hash.d.ts +12 -23
  55. package/dist/api/request-body-hash.js +12 -23
  56. package/dist/api/resolve-references.d.ts +0 -1
  57. package/dist/api/resolve-references.js +13 -28
  58. package/dist/api/route-builder.d.ts +3 -7
  59. package/dist/api/route-builder.js +1 -1
  60. package/dist/api/routes.d.ts +12 -0
  61. package/dist/api/routes.js +47 -0
  62. package/dist/api/schema.d.ts +23 -33
  63. package/dist/api/schema.js +20 -74
  64. package/dist/api/settings-helpers.js +4 -5
  65. package/dist/api/types.d.ts +0 -5
  66. package/dist/api/user.js +0 -5
  67. package/dist/api/validators.d.ts +14 -52
  68. package/dist/api/validators.js +14 -52
  69. package/dist/assets/asset-prefixes.d.ts +4 -8
  70. package/dist/assets/asset-prefixes.js +4 -8
  71. package/dist/assets/asset-src.d.ts +5 -22
  72. package/dist/assets/asset-src.js +5 -21
  73. package/dist/assets/factory.d.ts +1 -2
  74. package/dist/assets/factory.js +1 -2
  75. package/dist/assets/finalize.d.ts +3 -1
  76. package/dist/assets/finalize.js +3 -1
  77. package/dist/assets/index.d.ts +3 -3
  78. package/dist/assets/index.js +1 -1
  79. package/dist/assets/keys.d.ts +5 -3
  80. package/dist/assets/keys.js +6 -3
  81. package/dist/assets/pipeline.d.ts +3 -2
  82. package/dist/assets/pipeline.js +22 -56
  83. package/dist/assets/sharp-loader.d.ts +2 -10
  84. package/dist/assets/sharp-loader.js +2 -10
  85. package/dist/assets/store-local.d.ts +1 -2
  86. package/dist/assets/store-local.js +1 -2
  87. package/dist/assets/store-s3.d.ts +3 -4
  88. package/dist/assets/svg-sanitizer.d.ts +6 -14
  89. package/dist/assets/svg-sanitizer.js +6 -14
  90. package/dist/assets/transform-directives.d.ts +3 -4
  91. package/dist/assets/transform-directives.js +1 -1
  92. package/dist/assets/transform.d.ts +19 -30
  93. package/dist/assets/transform.js +18 -31
  94. package/dist/auth/cache.d.ts +2 -3
  95. package/dist/auth/cache.js +2 -3
  96. package/dist/auth/caching-auth-plugin.d.ts +11 -22
  97. package/dist/auth/caching-auth-plugin.js +12 -14
  98. package/dist/auth/context-helpers.d.ts +6 -20
  99. package/dist/auth/context-helpers.js +5 -17
  100. package/dist/auth/file-based-auth-cache.d.ts +10 -21
  101. package/dist/auth/file-based-auth-cache.js +23 -51
  102. package/dist/auth/plugin.d.ts +29 -61
  103. package/dist/auth/plugin.js +9 -13
  104. package/dist/auth/types.d.ts +11 -20
  105. package/dist/authorization/branch.d.ts +30 -49
  106. package/dist/authorization/branch.js +16 -42
  107. package/dist/authorization/content.d.ts +11 -40
  108. package/dist/authorization/content.js +13 -45
  109. package/dist/authorization/groups/index.d.ts +0 -3
  110. package/dist/authorization/groups/index.js +0 -3
  111. package/dist/authorization/groups/loader.d.ts +14 -28
  112. package/dist/authorization/groups/loader.js +14 -38
  113. package/dist/authorization/groups/schema.d.ts +0 -6
  114. package/dist/authorization/groups/schema.js +4 -7
  115. package/dist/authorization/helpers.d.ts +9 -28
  116. package/dist/authorization/helpers.js +9 -28
  117. package/dist/authorization/index.d.ts +3 -25
  118. package/dist/authorization/index.js +3 -35
  119. package/dist/authorization/path.d.ts +6 -13
  120. package/dist/authorization/path.js +8 -25
  121. package/dist/authorization/permissions/index.d.ts +0 -3
  122. package/dist/authorization/permissions/index.js +0 -3
  123. package/dist/authorization/permissions/loader.d.ts +14 -27
  124. package/dist/authorization/permissions/loader.js +14 -32
  125. package/dist/authorization/permissions/schema.d.ts +1 -6
  126. package/dist/authorization/permissions/schema.js +6 -13
  127. package/dist/authorization/protected-branch.d.ts +36 -65
  128. package/dist/authorization/protected-branch.js +29 -41
  129. package/dist/authorization/settings-file-store.d.ts +38 -81
  130. package/dist/authorization/settings-file-store.js +38 -79
  131. package/dist/authorization/types.d.ts +4 -26
  132. package/dist/authorization/types.js +0 -6
  133. package/dist/authorization/validation.d.ts +1 -23
  134. package/dist/authorization/validation.js +1 -24
  135. package/dist/branch-health.d.ts +39 -67
  136. package/dist/branch-health.js +27 -43
  137. package/dist/branch-metadata-file.d.ts +16 -32
  138. package/dist/branch-metadata-file.js +13 -26
  139. package/dist/branch-metadata.d.ts +49 -80
  140. package/dist/branch-metadata.js +57 -87
  141. package/dist/branch-registry.d.ts +26 -64
  142. package/dist/branch-registry.js +44 -93
  143. package/dist/branch-schema-cache.d.ts +34 -124
  144. package/dist/branch-schema-cache.js +49 -155
  145. package/dist/branch-workspace.d.ts +4 -4
  146. package/dist/branch-workspace.js +15 -19
  147. package/dist/build/generate-ai-content.d.ts +1 -0
  148. package/dist/build/generate-ai-content.js +12 -25
  149. package/dist/build-canopy.d.ts +17 -27
  150. package/dist/build-canopy.js +16 -23
  151. package/dist/build-mode.d.ts +25 -27
  152. package/dist/build-mode.js +25 -29
  153. package/dist/cli/cli.d.ts +15 -26
  154. package/dist/cli/cli.js +601 -978
  155. package/dist/cli/generate-ai-content.js +351 -628
  156. package/dist/cli/github-app-manifest.d.ts +84 -0
  157. package/dist/cli/github-app-manifest.js +161 -0
  158. package/dist/cli/init-github-app.d.ts +110 -444
  159. package/dist/cli/init-github-app.js +236 -773
  160. package/dist/cli/init.js +39 -80
  161. package/dist/cli/migrate.d.ts +13 -10
  162. package/dist/cli/migrate.js +22 -30
  163. package/dist/cli/project-detect.d.ts +17 -31
  164. package/dist/cli/project-detect.js +31 -42
  165. package/dist/cli/project-root.d.ts +4 -11
  166. package/dist/cli/project-root.js +4 -11
  167. package/dist/cli/prompt.d.ts +10 -0
  168. package/dist/cli/prompt.js +67 -0
  169. package/dist/cli/sync.d.ts +0 -8
  170. package/dist/cli/sync.js +8 -28
  171. package/dist/cli/template-files/middleware.ts.template +15 -29
  172. package/dist/cli/templates.d.ts +2 -12
  173. package/dist/cli/templates.js +4 -4
  174. package/dist/client.d.ts +1 -1
  175. package/dist/comment-store.d.ts +32 -53
  176. package/dist/comment-store.js +32 -52
  177. package/dist/config/flatten.d.ts +0 -3
  178. package/dist/config/flatten.js +2 -12
  179. package/dist/config/helpers.js +2 -2
  180. package/dist/config/index.d.ts +2 -2
  181. package/dist/config/index.js +1 -4
  182. package/dist/config/schemas/collection.d.ts +0 -8
  183. package/dist/config/schemas/collection.js +0 -10
  184. package/dist/config/schemas/config.d.ts +6 -78
  185. package/dist/config/schemas/config.js +38 -54
  186. package/dist/config/schemas/field.d.ts +2 -242
  187. package/dist/config/schemas/field.js +9 -20
  188. package/dist/config/schemas/media.js +1 -1
  189. package/dist/config/schemas/permissions.js +0 -2
  190. package/dist/config/schemas/url.d.ts +5 -6
  191. package/dist/config/schemas/url.js +5 -6
  192. package/dist/config/types.d.ts +45 -33
  193. package/dist/config/types.js +0 -1
  194. package/dist/config.d.ts +1 -8
  195. package/dist/config.js +1 -9
  196. package/dist/content-id-index.d.ts +76 -188
  197. package/dist/content-id-index.js +79 -230
  198. package/dist/content-index-generation.d.ts +27 -48
  199. package/dist/content-index-generation.js +35 -84
  200. package/dist/content-index-registry.d.ts +15 -24
  201. package/dist/content-index-registry.js +5 -9
  202. package/dist/content-listing.d.ts +64 -107
  203. package/dist/content-listing.js +68 -118
  204. package/dist/content-reader.d.ts +20 -29
  205. package/dist/content-reader.js +10 -18
  206. package/dist/content-store.d.ts +210 -336
  207. package/dist/content-store.js +413 -657
  208. package/dist/content-tree.d.ts +44 -86
  209. package/dist/content-tree.js +26 -54
  210. package/dist/context.d.ts +67 -94
  211. package/dist/context.js +53 -72
  212. package/dist/dev-content-watcher.d.ts +18 -18
  213. package/dist/dev-content-watcher.js +41 -44
  214. package/dist/editor/BranchManager.d.ts +3 -6
  215. package/dist/editor/BranchManager.js +24 -44
  216. package/dist/editor/CanopyEditor.js +5 -2
  217. package/dist/editor/CommentsPanel.js +0 -2
  218. package/dist/editor/Editor.js +19 -76
  219. package/dist/editor/EditorAuthGate.d.ts +27 -0
  220. package/dist/editor/EditorAuthGate.js +140 -0
  221. package/dist/editor/EntryNavigator.js +0 -20
  222. package/dist/editor/FormRenderer.d.ts +1 -2
  223. package/dist/editor/FormRenderer.js +8 -23
  224. package/dist/editor/admin/SystemHealthPanel.js +20 -37
  225. package/dist/editor/admin/useSystemHealth.d.ts +2 -3
  226. package/dist/editor/admin/useSystemHealth.js +10 -12
  227. package/dist/editor/client-reference-resolver.d.ts +2 -5
  228. package/dist/editor/client-reference-resolver.js +2 -19
  229. package/dist/editor/comments/BranchComments.js +0 -4
  230. package/dist/editor/comments/EntryComments.js +0 -4
  231. package/dist/editor/comments/FieldWrapper.js +0 -4
  232. package/dist/editor/comments/InlineCommentThread.js +0 -2
  233. package/dist/editor/comments/ThreadCarousel.d.ts +0 -58
  234. package/dist/editor/comments/ThreadCarousel.js +0 -12
  235. package/dist/editor/components/EditorFooter.d.ts +0 -8
  236. package/dist/editor/components/EditorFooter.js +0 -5
  237. package/dist/editor/components/EditorHeader.d.ts +0 -31
  238. package/dist/editor/components/EditorHeader.js +21 -71
  239. package/dist/editor/components/EditorSidebar.d.ts +0 -19
  240. package/dist/editor/components/EditorSidebar.js +0 -16
  241. package/dist/editor/components/EntryCreateModal.d.ts +4 -4
  242. package/dist/editor/components/EntryCreateModal.js +7 -22
  243. package/dist/editor/components/RenameEntryModal.js +0 -4
  244. package/dist/editor/components/UserBadge.js +0 -10
  245. package/dist/editor/components/index.js +0 -2
  246. package/dist/editor/context/ApiClientContext.d.ts +8 -7
  247. package/dist/editor/context/ApiClientContext.js +39 -11
  248. package/dist/editor/context/AssetContext.d.ts +7 -17
  249. package/dist/editor/context/AssetContext.js +7 -17
  250. package/dist/editor/context/EditorIdentityContext.d.ts +13 -0
  251. package/dist/editor/context/EditorIdentityContext.js +7 -0
  252. package/dist/editor/context/EditorStateContext.d.ts +10 -41
  253. package/dist/editor/context/EditorStateContext.js +7 -23
  254. package/dist/editor/context/SWRProvider.d.ts +3 -6
  255. package/dist/editor/context/index.d.ts +1 -20
  256. package/dist/editor/context/index.js +1 -20
  257. package/dist/editor/editor-utils.d.ts +8 -47
  258. package/dist/editor/editor-utils.js +19 -72
  259. package/dist/editor/fields/BlockField.d.ts +2 -2
  260. package/dist/editor/fields/BlockField.js +1 -2
  261. package/dist/editor/fields/CodeField.d.ts +0 -1
  262. package/dist/editor/fields/CodeField.js +0 -1
  263. package/dist/editor/fields/DateTimeField.d.ts +15 -22
  264. package/dist/editor/fields/DateTimeField.js +17 -26
  265. package/dist/editor/fields/ImageField.d.ts +2 -2
  266. package/dist/editor/fields/ImageField.js +8 -14
  267. package/dist/editor/fields/InlineGroupField.d.ts +0 -1
  268. package/dist/editor/fields/InlineGroupField.js +0 -1
  269. package/dist/editor/fields/MarkdownField.d.ts +0 -1
  270. package/dist/editor/fields/MarkdownField.js +6 -11
  271. package/dist/editor/fields/MdxImageDialog.d.ts +1 -1
  272. package/dist/editor/fields/MdxImageDialog.js +0 -1
  273. package/dist/editor/fields/NumberField.d.ts +9 -19
  274. package/dist/editor/fields/NumberField.js +11 -22
  275. package/dist/editor/fields/NumberListField.d.ts +7 -10
  276. package/dist/editor/fields/NumberListField.js +7 -10
  277. package/dist/editor/fields/ObjectField.d.ts +5 -8
  278. package/dist/editor/fields/ObjectField.js +0 -1
  279. package/dist/editor/fields/ReferenceField.d.ts +1 -1
  280. package/dist/editor/fields/ReferenceField.js +11 -16
  281. package/dist/editor/fields/SelectField.d.ts +2 -2
  282. package/dist/editor/fields/SelectField.js +0 -1
  283. package/dist/editor/fields/StringListField.d.ts +0 -4
  284. package/dist/editor/fields/StringListField.js +4 -9
  285. package/dist/editor/fields/TextField.d.ts +0 -1
  286. package/dist/editor/fields/TextField.js +0 -1
  287. package/dist/editor/fields/ToggleField.d.ts +0 -1
  288. package/dist/editor/fields/ToggleField.js +0 -1
  289. package/dist/editor/fields/entry-link/EntryLinkContext.js +2 -4
  290. package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +0 -3
  291. package/dist/editor/fields/entry-link/InsertEntryLink.js +0 -4
  292. package/dist/editor/group-manager/ExternalGroupsTab.d.ts +0 -3
  293. package/dist/editor/group-manager/ExternalGroupsTab.js +0 -1
  294. package/dist/editor/group-manager/GroupCard.d.ts +0 -3
  295. package/dist/editor/group-manager/GroupForm.d.ts +0 -3
  296. package/dist/editor/group-manager/InternalGroupsTab.d.ts +0 -3
  297. package/dist/editor/group-manager/InternalGroupsTab.js +0 -2
  298. package/dist/editor/group-manager/MemberList.d.ts +0 -3
  299. package/dist/editor/group-manager/hooks/useExternalGroupSearch.d.ts +0 -3
  300. package/dist/editor/group-manager/hooks/useExternalGroupSearch.js +0 -3
  301. package/dist/editor/group-manager/hooks/useGroupState.d.ts +0 -3
  302. package/dist/editor/group-manager/hooks/useGroupState.js +0 -5
  303. package/dist/editor/group-manager/hooks/useUserSearch.d.ts +0 -3
  304. package/dist/editor/group-manager/hooks/useUserSearch.js +0 -3
  305. package/dist/editor/group-manager/index.d.ts +0 -6
  306. package/dist/editor/group-manager/index.js +0 -10
  307. package/dist/editor/group-manager/types.d.ts +2 -5
  308. package/dist/editor/group-manager/types.js +0 -3
  309. package/dist/editor/hooks/index.d.ts +6 -11
  310. package/dist/editor/hooks/index.js +6 -12
  311. package/dist/editor/hooks/useBranchActions.d.ts +0 -14
  312. package/dist/editor/hooks/useBranchActions.js +0 -22
  313. package/dist/editor/hooks/useBranchManager.d.ts +2 -48
  314. package/dist/editor/hooks/useBranchManager.js +4 -64
  315. package/dist/editor/hooks/useBranchesData.d.ts +7 -6
  316. package/dist/editor/hooks/useBranchesData.js +7 -6
  317. package/dist/editor/hooks/useCommentSystem.d.ts +0 -49
  318. package/dist/editor/hooks/useCommentSystem.js +1 -36
  319. package/dist/editor/hooks/useDraftManager.d.ts +2 -35
  320. package/dist/editor/hooks/useDraftManager.js +23 -64
  321. package/dist/editor/hooks/useEditorLayout.d.ts +0 -20
  322. package/dist/editor/hooks/useEditorLayout.js +0 -23
  323. package/dist/editor/hooks/useEntriesData.d.ts +1 -0
  324. package/dist/editor/hooks/useEntriesData.js +2 -3
  325. package/dist/editor/hooks/useEntryLinkResolution.d.ts +2 -2
  326. package/dist/editor/hooks/useEntryLinkResolution.js +2 -2
  327. package/dist/editor/hooks/useEntryManager.d.ts +2 -27
  328. package/dist/editor/hooks/useEntryManager.js +29 -78
  329. package/dist/editor/hooks/useGroupManager.d.ts +0 -21
  330. package/dist/editor/hooks/useGroupManager.js +0 -21
  331. package/dist/editor/hooks/usePermissionManager.d.ts +0 -20
  332. package/dist/editor/hooks/usePermissionManager.js +0 -20
  333. package/dist/editor/hooks/useReferenceResolution.d.ts +2 -33
  334. package/dist/editor/hooks/useReferenceResolution.js +1 -48
  335. package/dist/editor/hooks/useSchemaManager.d.ts +8 -27
  336. package/dist/editor/hooks/useSchemaManager.js +0 -19
  337. package/dist/editor/hooks/useUserContext.d.ts +2 -9
  338. package/dist/editor/hooks/useUserContext.js +10 -10
  339. package/dist/editor/hooks/useUserMetadata.d.ts +0 -2
  340. package/dist/editor/hooks/useUserMetadata.js +0 -3
  341. package/dist/editor/media/AssetCard.d.ts +0 -1
  342. package/dist/editor/media/AssetCard.js +1 -2
  343. package/dist/editor/media/CropStep.d.ts +0 -1
  344. package/dist/editor/media/CropStep.js +0 -1
  345. package/dist/editor/media/MediaLibrary.d.ts +1 -2
  346. package/dist/editor/media/MediaLibrary.js +1 -2
  347. package/dist/editor/media/MediaLibraryBody.d.ts +0 -1
  348. package/dist/editor/media/MediaLibraryBody.js +0 -1
  349. package/dist/editor/media/crop-math.d.ts +1 -1
  350. package/dist/editor/media/crop-math.js +1 -1
  351. package/dist/editor/permission-manager/GroupSelector.d.ts +0 -3
  352. package/dist/editor/permission-manager/PermissionEditor.d.ts +0 -4
  353. package/dist/editor/permission-manager/PermissionEditor.js +0 -1
  354. package/dist/editor/permission-manager/PermissionLevelBadge.d.ts +0 -7
  355. package/dist/editor/permission-manager/PermissionLevelBadge.js +0 -4
  356. package/dist/editor/permission-manager/PermissionTree.d.ts +0 -4
  357. package/dist/editor/permission-manager/UserSelector.d.ts +0 -3
  358. package/dist/editor/permission-manager/constants.d.ts +0 -3
  359. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +0 -3
  360. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +0 -10
  361. package/dist/editor/permission-manager/hooks/usePermissionTree.d.ts +0 -14
  362. package/dist/editor/permission-manager/hooks/usePermissionTree.js +0 -11
  363. package/dist/editor/permission-manager/index.d.ts +0 -7
  364. package/dist/editor/permission-manager/index.js +0 -16
  365. package/dist/editor/permission-manager/types.d.ts +2 -12
  366. package/dist/editor/permission-manager/types.js +0 -3
  367. package/dist/editor/permission-manager/utils.d.ts +0 -28
  368. package/dist/editor/permission-manager/utils.js +9 -23
  369. package/dist/editor/preview-bridge.d.ts +5 -1
  370. package/dist/editor/preview-bridge.js +4 -4
  371. package/dist/editor/schema-editor/CollectionEditor.d.ts +0 -5
  372. package/dist/editor/schema-editor/CollectionEditor.js +9 -31
  373. package/dist/editor/schema-editor/EntryTypeEditor.d.ts +0 -6
  374. package/dist/editor/schema-editor/EntryTypeEditor.js +3 -24
  375. package/dist/editor/schema-editor/index.d.ts +0 -7
  376. package/dist/editor/schema-editor/index.js +0 -7
  377. package/dist/editor/utils/env.d.ts +3 -18
  378. package/dist/editor/utils/env.js +6 -25
  379. package/dist/entry-link-resolver.d.ts +13 -35
  380. package/dist/entry-link-resolver.js +20 -53
  381. package/dist/entry-schema-registry.d.ts +20 -60
  382. package/dist/entry-schema-registry.js +20 -69
  383. package/dist/entry-schema.d.ts +118 -223
  384. package/dist/entry-schema.js +46 -91
  385. package/dist/git-manager.d.ts +101 -200
  386. package/dist/git-manager.js +211 -384
  387. package/dist/github-service.d.ts +34 -75
  388. package/dist/github-service.js +37 -91
  389. package/dist/http/handler.d.ts +6 -37
  390. package/dist/http/handler.js +65 -120
  391. package/dist/http/router.d.ts +15 -32
  392. package/dist/http/router.js +34 -99
  393. package/dist/http/types.d.ts +15 -40
  394. package/dist/http/types.js +3 -7
  395. package/dist/id.d.ts +4 -10
  396. package/dist/id.js +4 -10
  397. package/dist/index.js +6 -9
  398. package/dist/operating-mode/client-safe-strategy.d.ts +7 -14
  399. package/dist/operating-mode/client-safe-strategy.js +8 -28
  400. package/dist/operating-mode/client-unsafe-strategy.d.ts +6 -16
  401. package/dist/operating-mode/client-unsafe-strategy.js +9 -34
  402. package/dist/operating-mode/client.d.ts +3 -10
  403. package/dist/operating-mode/client.js +3 -8
  404. package/dist/operating-mode/deployment-name-fixtures.d.ts +14 -18
  405. package/dist/operating-mode/deployment-name-fixtures.js +14 -18
  406. package/dist/operating-mode/deployment-name.d.ts +19 -29
  407. package/dist/operating-mode/deployment-name.js +29 -47
  408. package/dist/operating-mode/index.d.ts +4 -25
  409. package/dist/operating-mode/index.js +9 -31
  410. package/dist/operating-mode/mode-env.d.ts +32 -54
  411. package/dist/operating-mode/mode-env.js +36 -58
  412. package/dist/operating-mode/types.d.ts +24 -72
  413. package/dist/operating-mode/types.js +1 -7
  414. package/dist/paths/branch-name.d.ts +30 -40
  415. package/dist/paths/branch-name.js +30 -40
  416. package/dist/paths/branch.d.ts +4 -18
  417. package/dist/paths/branch.js +6 -22
  418. package/dist/paths/index.d.ts +2 -13
  419. package/dist/paths/index.js +3 -23
  420. package/dist/paths/normalize-server.d.ts +3 -15
  421. package/dist/paths/normalize-server.js +3 -15
  422. package/dist/paths/normalize.d.ts +13 -33
  423. package/dist/paths/normalize.js +13 -33
  424. package/dist/paths/resolve.d.ts +4 -17
  425. package/dist/paths/resolve.js +4 -22
  426. package/dist/paths/types.d.ts +12 -34
  427. package/dist/paths/types.js +5 -7
  428. package/dist/paths/validation.d.ts +22 -119
  429. package/dist/paths/validation.js +30 -148
  430. package/dist/reference-resolver.d.ts +0 -13
  431. package/dist/reference-resolver.js +0 -18
  432. package/dist/resolve-canopy-user.d.ts +16 -18
  433. package/dist/resolve-canopy-user.js +17 -26
  434. package/dist/resource-generation.d.ts +16 -25
  435. package/dist/resource-generation.js +34 -97
  436. package/dist/schema/meta-loader.d.ts +2 -14
  437. package/dist/schema/meta-loader.js +15 -64
  438. package/dist/schema/resolver.d.ts +1 -4
  439. package/dist/schema/resolver.js +1 -6
  440. package/dist/schema/schema-store-types.d.ts +0 -12
  441. package/dist/schema/schema-store.d.ts +61 -138
  442. package/dist/schema/schema-store.js +85 -282
  443. package/dist/schema/types.d.ts +0 -4
  444. package/dist/server.d.ts +62 -93
  445. package/dist/server.js +63 -94
  446. package/dist/services.d.ts +23 -47
  447. package/dist/services.js +55 -98
  448. package/dist/settings-workspace.d.ts +17 -30
  449. package/dist/settings-workspace.js +51 -81
  450. package/dist/static/index.d.ts +26 -52
  451. package/dist/static/index.js +33 -67
  452. package/dist/{worker/task-queue.d.ts → task-queue/cms-task-queue.d.ts} +7 -9
  453. package/dist/task-queue/cms-task-queue.js +13 -0
  454. package/dist/task-queue/task-queue-config.d.ts +3 -0
  455. package/dist/{worker → task-queue}/task-queue-config.js +1 -6
  456. package/dist/task-queue/task-queue.d.ts +16 -22
  457. package/dist/task-queue/task-queue.js +20 -44
  458. package/dist/task-queue/types.d.ts +0 -1
  459. package/dist/task-queue/worker-status.d.ts +35 -0
  460. package/dist/task-queue/worker-status.js +40 -0
  461. package/dist/types.d.ts +40 -51
  462. package/dist/url-collision.d.ts +26 -40
  463. package/dist/url-collision.js +47 -63
  464. package/dist/url-exclusivity-fixtures.d.ts +15 -20
  465. package/dist/url-exclusivity-fixtures.js +14 -19
  466. package/dist/url-path-resolver.d.ts +8 -16
  467. package/dist/url-path-resolver.js +19 -29
  468. package/dist/user.d.ts +8 -21
  469. package/dist/user.js +10 -19
  470. package/dist/utils/async-mutex.js +4 -6
  471. package/dist/utils/atomic-write.d.ts +2 -11
  472. package/dist/utils/atomic-write.js +2 -11
  473. package/dist/utils/body-field.d.ts +8 -15
  474. package/dist/utils/body-field.js +8 -15
  475. package/dist/utils/content-serialize.d.ts +18 -24
  476. package/dist/utils/content-serialize.js +109 -160
  477. package/dist/utils/content-write-lock.d.ts +51 -106
  478. package/dist/utils/content-write-lock.js +66 -111
  479. package/dist/utils/debug.d.ts +7 -23
  480. package/dist/utils/debug.js +7 -23
  481. package/dist/utils/entry-url.d.ts +11 -23
  482. package/dist/utils/entry-url.js +11 -26
  483. package/dist/utils/error.d.ts +25 -90
  484. package/dist/utils/error.js +60 -147
  485. package/dist/utils/flatten-group-fields.d.ts +5 -7
  486. package/dist/utils/flatten-group-fields.js +5 -7
  487. package/dist/utils/format.d.ts +1 -5
  488. package/dist/utils/format.js +1 -5
  489. package/dist/utils/fs.d.ts +3 -4
  490. package/dist/utils/fs.js +3 -4
  491. package/dist/utils/git.d.ts +52 -83
  492. package/dist/utils/git.js +79 -125
  493. package/dist/utils/logger.d.ts +35 -50
  494. package/dist/utils/logger.js +35 -52
  495. package/dist/utils/provisioning-lock.d.ts +23 -35
  496. package/dist/utils/provisioning-lock.js +49 -69
  497. package/dist/utils/sanitize-href.d.ts +5 -10
  498. package/dist/utils/sanitize-href.js +8 -18
  499. package/dist/utils/title-field.d.ts +17 -20
  500. package/dist/utils/title-field.js +18 -27
  501. package/dist/utils/typed-filename.d.ts +20 -48
  502. package/dist/utils/typed-filename.js +25 -61
  503. package/dist/utils/url-prefix.d.ts +3 -3
  504. package/dist/utils/url-prefix.js +3 -3
  505. package/dist/validation/block-structural-keys.d.ts +16 -31
  506. package/dist/validation/block-structural-keys.js +19 -29
  507. package/dist/validation/deletion-checker.d.ts +0 -34
  508. package/dist/validation/deletion-checker.js +1 -43
  509. package/dist/validation/entry-link-validator.d.ts +6 -13
  510. package/dist/validation/entry-link-validator.js +4 -13
  511. package/dist/validation/entry-type-reference-validator.d.ts +13 -18
  512. package/dist/validation/entry-type-reference-validator.js +13 -18
  513. package/dist/validation/entry-validator.d.ts +13 -25
  514. package/dist/validation/entry-validator.js +15 -32
  515. package/dist/validation/field-traversal.d.ts +3 -30
  516. package/dist/validation/field-traversal.js +1 -32
  517. package/dist/validation/reference-validator.d.ts +5 -24
  518. package/dist/validation/reference-validator.js +5 -30
  519. package/dist/worker/cms-worker.d.ts +172 -232
  520. package/dist/worker/cms-worker.js +241 -333
  521. package/dist/worker/git-sync.d.ts +32 -133
  522. package/dist/worker/git-sync.js +129 -191
  523. package/dist/worker/github-auth.d.ts +13 -19
  524. package/dist/worker/github-auth.js +13 -19
  525. package/dist/worker/history-rewrite.d.ts +53 -66
  526. package/dist/worker/history-rewrite.js +54 -60
  527. package/dist/worker/log.d.ts +24 -41
  528. package/dist/worker/log.js +25 -42
  529. package/dist/worker/rebase.d.ts +20 -110
  530. package/dist/worker/rebase.js +279 -354
  531. package/dist/worker/task-runner.d.ts +32 -66
  532. package/dist/worker/task-runner.js +126 -162
  533. package/dist/worker/worker-context.d.ts +41 -81
  534. package/package.json +4 -4
  535. package/dist/cli/template-files/middleware-clerk.ts.template +0 -37
  536. package/dist/worker/task-queue-config.d.ts +0 -8
  537. package/dist/worker/task-queue.js +0 -19
  538. package/dist/worker/worker-status.d.ts +0 -47
  539. package/dist/worker/worker-status.js +0 -52
@@ -15,12 +15,6 @@ export interface ReferenceOption {
15
15
  }
16
16
  /**
17
17
  * ReferenceResolver resolves content IDs to display values for reference fields.
18
- *
19
- * This class provides utilities for:
20
- * - Resolving a single ID to its display value (e.g., title)
21
- * - Loading all available options for a reference field
22
- * - Filtering options by collection constraints
23
- * - Searching options by display value
24
18
  */
25
19
  export declare class ReferenceResolver {
26
20
  private store;
@@ -29,9 +23,6 @@ export declare class ReferenceResolver {
29
23
  /**
30
24
  * Resolve a content ID to a display value.
31
25
  * Returns null if the ID doesn't exist or points to a collection.
32
- *
33
- * @param id - The content ID to resolve
34
- * @param displayField - The field to use for display value (default: 'title')
35
26
  */
36
27
  resolve(id: string, displayField?: string): Promise<ResolvedReference | null>;
37
28
  /**
@@ -40,10 +31,6 @@ export declare class ReferenceResolver {
40
31
  * Scans collections (including subcollections) and/or filters by entry type.
41
32
  * At least one of `collections` or `entryTypes` should be provided.
42
33
  *
43
- * @param collections - Collection paths to search, including subcollections (e.g., ['data-catalog'])
44
- * @param displayField - Field to use for option labels (default: 'title')
45
- * @param search - Optional search string to filter options
46
- * @param entryTypes - Optional entry type names to filter by (e.g., ['partner'])
47
34
  * @param canAccess - Optional permission predicate, called with each candidate's
48
35
  * relative path before it is read. Returning false skips the entry entirely --
49
36
  * no file I/O, no label, no option -- so a caller who can't read a path never
@@ -2,12 +2,6 @@ import nodePath from 'node:path';
2
2
  import { extractSlugFromFilename, extractEntryTypeFromFilename } from './content-id-index.js';
3
3
  /**
4
4
  * ReferenceResolver resolves content IDs to display values for reference fields.
5
- *
6
- * This class provides utilities for:
7
- * - Resolving a single ID to its display value (e.g., title)
8
- * - Loading all available options for a reference field
9
- * - Filtering options by collection constraints
10
- * - Searching options by display value
11
5
  */
12
6
  export class ReferenceResolver {
13
7
  constructor(store, idIndex) {
@@ -17,9 +11,6 @@ export class ReferenceResolver {
17
11
  /**
18
12
  * Resolve a content ID to a display value.
19
13
  * Returns null if the ID doesn't exist or points to a collection.
20
- *
21
- * @param id - The content ID to resolve
22
- * @param displayField - The field to use for display value (default: 'title')
23
14
  */
24
15
  async resolve(id, displayField = 'title') {
25
16
  const location = this.idIndex.findById(id);
@@ -56,10 +47,6 @@ export class ReferenceResolver {
56
47
  * Scans collections (including subcollections) and/or filters by entry type.
57
48
  * At least one of `collections` or `entryTypes` should be provided.
58
49
  *
59
- * @param collections - Collection paths to search, including subcollections (e.g., ['data-catalog'])
60
- * @param displayField - Field to use for option labels (default: 'title')
61
- * @param search - Optional search string to filter options
62
- * @param entryTypes - Optional entry type names to filter by (e.g., ['partner'])
63
50
  * @param canAccess - Optional permission predicate, called with each candidate's
64
51
  * relative path before it is read. Returning false skips the entry entirely --
65
52
  * no file I/O, no label, no option -- so a caller who can't read a path never
@@ -69,18 +56,14 @@ export class ReferenceResolver {
69
56
  const options = [];
70
57
  let candidates;
71
58
  if (collections && collections.length > 0) {
72
- // Search within specified collection trees (including subcollections)
73
- // getCollectionEntryPaths handles normalization (e.g., 'authors' → 'content/authors')
74
59
  const results = await Promise.all(collections.map((col) => this.store.getCollectionEntryPaths(col)));
75
60
  candidates = results.flat();
76
61
  }
77
62
  else {
78
- // No collection scope — search all entries via index
79
63
  candidates = this.idIndex
80
64
  .getAllEntryLocations()
81
65
  .filter((loc) => loc.type === 'entry' && !!loc.collection && !!loc.slug);
82
66
  }
83
- // Filter by entry type if specified
84
67
  if (entryTypes && entryTypes.length > 0) {
85
68
  candidates = candidates.filter((loc) => {
86
69
  const entryType = extractEntryTypeFromFilename(nodePath.basename(loc.relativePath));
@@ -101,7 +84,6 @@ export class ReferenceResolver {
101
84
  const normalizedSlug = extractSlugFromFilename(filename);
102
85
  const doc = await this.store.read(location.collection, normalizedSlug);
103
86
  const label = String(doc.data[displayField] || doc.data.title || normalizedSlug);
104
- // Apply search filter if provided
105
87
  if (search && !label.toLowerCase().includes(search.toLowerCase())) {
106
88
  continue;
107
89
  }
@@ -1,33 +1,31 @@
1
1
  import type { AuthenticationResult } from './auth/types.js';
2
2
  import type { CanopyUser } from './user.js';
3
3
  import type { OperatingMode } from './operating-mode/index.js';
4
- /** Test-only: reset the once-per-process "no admins configured" warning latch. */
4
+ /**
5
+ * Test-only: reset the once-per-process "no admins configured" warning latch.
6
+ * @internal No importer; deletion candidate in knip-no-importer-deletion-candidates.md.
7
+ */
5
8
  export declare function resetResolveCanopyUserWarningForTests(): void;
6
9
  export interface ResolveCanopyUserDeps {
7
10
  /**
8
- * Resolves (and ensures) the settings workspace root. Internal groups are
9
- * the single source of truth for group-based privileges and MUST be
10
- * loaded from here — the same root `createContentAccessChecker`
11
- * (authorization/content.ts) uses for path permissions — never from a
12
- * content branch clone.
11
+ * Resolves (and ensures) the settings workspace root. Internal groups are the
12
+ * single source of truth for group-based privileges and MUST be loaded from
13
+ * here — the same root `createContentAccessChecker` (authorization/content.ts)
14
+ * uses for path permissions — never from a content branch clone.
13
15
  *
14
- * Must THROW if the settings workspace cannot be ensured, matching
15
- * `createContentAccessChecker`'s fail-loud contract: a caught error here
16
- * and a silent fallback to an empty group list would read as "no
17
- * privileges", which is a silent authorization change, not a safe
18
- * degradation.
16
+ * MUST THROW if the settings workspace cannot be ensured, matching
17
+ * `createContentAccessChecker`'s fail-loud contract: a silent fallback to an
18
+ * empty group list reads as "no privileges", which is a silent authorization
19
+ * change rather than a safe degradation.
19
20
  */
20
21
  getSettingsBranchRoot: () => Promise<string>;
21
22
  mode: OperatingMode;
22
23
  bootstrapAdminIds: Set<string>;
23
24
  }
24
25
  /**
25
- * Resolve the CanopyUser for a request: load internal groups from the
26
- * settings workspace and merge them (plus bootstrap admins) into an
27
- * authentication result via `authResultToCanopyUser`.
28
- *
29
- * Framework-agnostic: callers supply the already-computed `authResult` (from
30
- * whatever auth-plugin invocation their transport uses) and a small deps
31
- * bag drawn from `CanopyServices`.
26
+ * Resolve the CanopyUser for a request: load internal groups from the settings
27
+ * workspace and merge them, plus bootstrap admins, into an authentication result
28
+ * via `authResultToCanopyUser`. Framework-agnostic — callers supply the
29
+ * already-computed `authResult` and a small deps bag from `CanopyServices`.
32
30
  */
33
31
  export declare function resolveCanopyUser(authResult: AuthenticationResult, deps: ResolveCanopyUserDeps): Promise<CanopyUser>;
@@ -1,29 +1,23 @@
1
1
  /**
2
- * Shared "authenticate -> resolve internal groups -> merge into CanopyUser"
3
- * pipeline.
2
+ * The shared "authenticate -> resolve internal groups -> merge into CanopyUser"
3
+ * pipeline: the single resolution point for `http/handler.ts` and
4
+ * `canopycms-next`'s `context-wrapper.ts`, so the two cannot diverge over where
5
+ * group-based privileges come from.
4
6
  *
5
- * This used to be duplicated between `http/handler.ts` (the core API
6
- * handler) and `canopycms-next`'s `context-wrapper.ts` (Next.js SSR user
7
- * extraction) - including a module-level `warnedNoAdmins` flag in each copy.
8
- * The duplication let the two drift: `http/handler.ts` loaded internal
9
- * groups from the BASE BRANCH content clone's `groups.json`, which nothing
10
- * in the product ever writes (writes go to the settings workspace via
11
- * `mutateGroupsFile` - `api/groups.ts`), so group-based privileges never
12
- * actually took effect. Consolidating the pipeline here means both callers
13
- * read from the same place and cannot silently diverge again.
14
- *
15
- * canopyLogWarn, not console.warn: this module has no worker-specific logic,
16
- * but nothing prevents it from becoming reachable from the worker's runtime
17
- * import closure later, and the existing "no admins configured" warning is
18
- * exactly the kind of operationally interesting line that must not be
19
- * silently folded into an unrelated worker.log event (see utils/logger.ts).
7
+ * canopyLogWarn, not console.warn: nothing prevents this module from becoming
8
+ * reachable from the worker's runtime import closure, and the "no admins
9
+ * configured" warning must not be folded silently into an unrelated worker.log
10
+ * event (see utils/logger.ts).
20
11
  */
21
12
  import { canopyLogWarn } from './utils/logger.js';
22
13
  import { authResultToCanopyUser } from './user.js';
23
14
  import { loadInternalGroups, RESERVED_GROUPS } from './authorization/index.js';
24
- /** Module-level, matching the pre-extraction behavior: warn at most once per process. */
15
+ /** Module-level: warn at most once per process. */
25
16
  let warnedNoAdmins = false;
26
- /** Test-only: reset the once-per-process "no admins configured" warning latch. */
17
+ /**
18
+ * Test-only: reset the once-per-process "no admins configured" warning latch.
19
+ * @internal No importer; deletion candidate in knip-no-importer-deletion-candidates.md.
20
+ */
27
21
  export function resetResolveCanopyUserWarningForTests() {
28
22
  warnedNoAdmins = false;
29
23
  }
@@ -38,13 +32,10 @@ function warnIfNoAdmins(internalGroups, bootstrapAdminIds) {
38
32
  warnedNoAdmins = true;
39
33
  }
40
34
  /**
41
- * Resolve the CanopyUser for a request: load internal groups from the
42
- * settings workspace and merge them (plus bootstrap admins) into an
43
- * authentication result via `authResultToCanopyUser`.
44
- *
45
- * Framework-agnostic: callers supply the already-computed `authResult` (from
46
- * whatever auth-plugin invocation their transport uses) and a small deps
47
- * bag drawn from `CanopyServices`.
35
+ * Resolve the CanopyUser for a request: load internal groups from the settings
36
+ * workspace and merge them, plus bootstrap admins, into an authentication result
37
+ * via `authResultToCanopyUser`. Framework-agnostic — callers supply the
38
+ * already-computed `authResult` and a small deps bag from `CanopyServices`.
48
39
  */
49
40
  export async function resolveCanopyUser(authResult, deps) {
50
41
  const settingsRoot = await deps.getSettingsBranchRoot();
@@ -2,13 +2,9 @@
2
2
  export declare function resourceGenerationPath(root: string, resource: string): string;
3
3
  export interface BumpResourceGenerationOptions {
4
4
  /**
5
- * When true, a failed bump rethrows instead of being logged and swallowed.
6
- * Use this for callers where a lost bump means indefinitely stale durable
7
- * data with no bounding backstop (e.g. a registry's invalidate()) — those
8
- * callers must not silently succeed while leaving stale readers unaware.
9
- * Default false (hint flavor): log-warn and swallow, since the mutation
10
- * itself is already durable and a lost bump only degrades to pre-marker
11
- * staleness behavior plus whatever backstop the consumer has.
5
+ * Rethrow a failed bump instead of logging and swallowing it. Set it where a
6
+ * lost bump means indefinitely stale durable data with no bounding backstop
7
+ * (e.g. a registry's invalidate()). Default false.
12
8
  */
13
9
  mustSucceed?: boolean;
14
10
  }
@@ -17,16 +13,15 @@ export interface BumpResourceGenerationOptions {
17
13
  * processes rebuild. Must be called AFTER the filesystem mutation.
18
14
  *
19
15
  * Returns the token written, or null if the write failed and `mustSucceed`
20
- * was not set (logged and swallowed).
16
+ * was not set.
21
17
  */
22
18
  export declare function bumpResourceGeneration(root: string, resource: string, options?: BumpResourceGenerationOptions): Promise<string | null>;
23
19
  /**
24
- * Result of reading a generation marker. `ok: false` means the read failed
25
- * for a reason OTHER than "marker doesn't exist yet" — callers should treat
26
- * this as "force regenerate" rather than folding it into a token value,
27
- * because a legitimate snapshot can embed `token: null` (a fresh clone,
28
- * regenerated before any bump ever occurred) and that must stay
29
- * distinguishable from "we don't actually know the current token".
20
+ * Result of reading a generation marker. `ok: false` means the read failed for
21
+ * a reason OTHER than "marker doesn't exist yet"; callers force-regenerate
22
+ * rather than folding it into a token value, because a legitimate snapshot can
23
+ * embed `token: null` (a fresh clone regenerated before any bump) and that must
24
+ * stay distinguishable from "we don't know the current token".
30
25
  */
31
26
  export type GenerationReadResult = {
32
27
  ok: true;
@@ -35,19 +30,15 @@ export type GenerationReadResult = {
35
30
  ok: false;
36
31
  };
37
32
  /**
38
- * Read the current generation token for `resource` under `root`.
39
- *
40
- * ENOENT maps to `{ok: true, token: null}` — a valid "never bumped" state,
41
- * distinct from every real token. Any OTHER read error maps to `{ok: false}`
42
- * (logged) so callers can force-regenerate instead of trusting a null they
43
- * cannot actually attribute to "never bumped".
33
+ * Read the current generation token for `resource` under `root`. ENOENT maps to
34
+ * `{ok: true, token: null}`, the "never bumped" state; every other read error
35
+ * maps to `{ok: false}`.
44
36
  */
45
37
  export declare function readResourceGeneration(root: string, resource: string): Promise<GenerationReadResult>;
46
38
  /**
47
- * True when a previously-captured snapshot token is still current: the read
48
- * succeeded AND its token matches the snapshot's. A failed read (`ok: false`)
49
- * is never current, even if the snapshot's token happens to be null — an
50
- * unreadable marker means we cannot vouch for freshness either way, and the
51
- * safe default is to treat it as stale.
39
+ * True when a snapshot's captured token is still current: the read succeeded
40
+ * AND its token matches. A failed read (`ok: false`) is never current, even
41
+ * against a null snapshot token — an unreadable marker vouches for nothing, so
42
+ * the safe default is stale.
52
43
  */
53
44
  export declare function isGenerationCurrent(snapshotToken: string | null, read: GenerationReadResult): boolean;
@@ -5,93 +5,34 @@ import { atomicWriteFile } from './utils/atomic-write.js';
5
5
  import { getErrorMessage, isNodeError } from './utils/error.js';
6
6
  import { createDebugLogger } from './utils/debug.js';
7
7
  /**
8
- * Generalized cross-process generation marker for any on-disk resource that
9
- * is durably cached under a branch-clone (or similar) root.
8
+ * Cross-process generation marker for an on-disk resource cached under a
9
+ * branch-clone root: several warm Lambda containers and the EC2 worker share
10
+ * those clones on EFS with no shared memory and no cross-host file watching,
11
+ * so the filesystem coordinates. The marker for `resource` lives at
12
+ * {root}/.canopy-meta/{resource}.generation — dot-prefixed so content and
13
+ * index scans skip it, and excluded from git via .git/info/exclude.
10
14
  *
11
- * Some in-process cache is kept per resource per process (an in-memory index,
12
- * a parsed schema, a registry snapshot). Within one process, mutating code can
13
- * invalidate that cache directly. Across processes (several warm Lambda
14
- * containers + the EC2 worker sharing branch clones on EFS) there is no
15
- * shared memory and no cross-host file watching, so the shared filesystem
16
- * itself is the coordination medium: every operation that mutates the
17
- * resource also rewrites a small marker file with a fresh random token, and
18
- * every consumer cheaply re-reads that marker (throttled) to decide whether
19
- * its cached snapshot is still current.
15
+ * - Mutators bump AFTER mutating, with a fresh random token: a counter would
16
+ * need read-modify-write and lose concurrent bumps without a lock.
17
+ * - Regenerators capture the token BEFORE scanning and embed it in the
18
+ * snapshot; readers compare that token against the live marker and
19
+ * regenerate on mismatch. A regeneration racing an invalidation embeds the
20
+ * old token, so it self-describes as stale and heals on the next read.
21
+ * - Regeneration returns its own scan result and never loops until the tokens
22
+ * match, which would livelock under a bump storm.
23
+ * - `mustSucceed` bumps explicit invalidations, where a swallowed failure
24
+ * means indefinite staleness; bulk `finally`-block callers take the default
25
+ * log-and-swallow hint bump.
26
+ * - A marker read error other than ENOENT stays distinct from "never bumped":
27
+ * the consumer serves the fresh scan but skips persisting a snapshot whose
28
+ * token it cannot attribute to that scan.
20
29
  *
21
- * The marker for a given `resource` lives at {root}/.canopy-meta/{resource}.generation:
22
- * `.canopy-meta/` is the established per-clone internal dir — dot-prefixed (so
23
- * content and index scans skip it) and excluded from git via .git/info/exclude.
24
- *
25
- * ## Why a random token instead of a monotonic counter
26
- *
27
- * Readers only need "did it change since I captured it", so inequality against
28
- * the captured value suffices. A counter would need read-modify-write, which
29
- * silently loses concurrent bumps without a lock (two bumpers read 5, both
30
- * write 6 — a reader that recorded 6 after the first bump never learns of the
31
- * second mutation). A unique token per bump has no lost-update problem, needs
32
- * no lock, and avoids NFS mtime-granularity / cross-host clock-skew issues.
33
- * Each bump is a single atomic temp-file + rename.
34
- *
35
- * ## Ordering protocol (correctness)
36
- *
37
- * - Bumpers write the marker strictly AFTER their filesystem mutations.
38
- * - Readers capture the marker token strictly BEFORE scanning/rebuilding the
39
- * resource, and record it only after the rebuild completes. A bump landing
40
- * mid-rebuild therefore leaves the recorded token older than the file,
41
- * forcing another rebuild on the next probe.
42
- *
43
- * ## Consistency guarantees and residual staleness windows (EFS/NFSv4)
44
- *
45
- * Guaranteed: any completed mutation that bumps the marker is observed by
46
- * every consumer on that root at its next freshness probe. Residual windows
47
- * (bounded in practice by per-request lifetimes and, where implemented, a
48
- * suspicious-lookup backstop):
49
- *
50
- * - (A) NFS attribute caching (benign direction): another host may not see a
51
- * new marker for up to the attribute-cache timeout (~3-60s on default EFS
52
- * mounts; `noac` cannot be assumed). The reader acts on a stale token and
53
- * keeps a stale snapshot until the cache expires.
54
- * - (B) Probe throttle: however long the consumer debounces freshness checks.
55
- * - (C) Self-adoption: after its own mutation a consumer adopts the token it
56
- * wrote; if a concurrent foreign bump landed just before ours, we miss that
57
- * one notification (window: from our last token observation to our rename).
58
- * - (E) Fresh-token/stale-scan (malignant direction, cross-host only): NFS
59
- * revalidates the marker file on open, but a rebuild's reads may be served
60
- * from dentry/attribute caches — a rebuild can record a NEW token against
61
- * PRE-mutation data, leaving that consumer confidently stale until the next
62
- * bump. Structurally unfixable with a filesystem marker; bounded by
63
- * per-request lifetimes and any backstop the consumer implements.
64
- *
65
- * ## Guarantee delta for DURABLE snapshot consumers (registry / schema-cache)
66
- *
67
- * The in-memory ContentIdIndex tolerates window (E) because a stale index is
68
- * scoped to one process's memory: it self-heals on the next probe or process
69
- * recycle, and a wrong-file write is independently guarded by ContentStore's
70
- * existence check. Consumers that persist a durable snapshot ALONGSIDE this
71
- * marker — a branch registry list, a resolved-schema cache file — do not get
72
- * that same containment. If such a consumer's regeneration scan is served
73
- * from stale NFS dentry/attribute caches, window (E) produces a snapshot that
74
- * embeds a FRESH token over STALE data, and that snapshot is written to disk.
75
- * Every other host that reads the marker sees the fresh token, concludes the
76
- * durable snapshot is current, and serves the stale data too — this is now a
77
- * durable, SHARED staleness visible to all hosts until the next bump, not a
78
- * transient one-process condition. A random token cannot distinguish "fresh
79
- * token over fresh data" from "fresh token over stale data" — the token only
80
- * proves a bump happened, not that the bumping host's own scan observed it.
81
- *
82
- * Durable-snapshot consumers must therefore implement mitigations this module
83
- * cannot provide on their behalf:
84
- *
85
- * - Eager regeneration on the mutating host, performed immediately after its
86
- * own bump (in the same request/operation). That host's own scan is
87
- * necessarily coherent with the mutation it just made (no NFS round trip
88
- * was needed to observe its own writes), so regenerating there rather than
89
- * waiting for a lazy pull on some other host avoids handing window (E) a
90
- * chance to run at all for the common case.
91
- * - A get-miss / suspicious-lookup backstop: if a consumer looks up something
92
- * that "should" exist per the durable snapshot but is missing (or vice
93
- * versa), that mismatch is a signal to force a fresh regeneration rather
94
- * than trusting the token match, bounding how long a bad snapshot survives.
30
+ * A consumer that persists its snapshot (branch registry, schema cache) can
31
+ * durably record a fresh token over data its scan read from a stale NFS cache,
32
+ * which every other host then trusts. So the mutating host regenerates eagerly
33
+ * right after its own bump — that scan is coherent with its own mutation — and
34
+ * the registry adds a suspicious-miss backstop. Staleness windows (A/B/C/E) and
35
+ * the rolling-deploy transient: docs/concurrency.md, "Residual staleness windows".
95
36
  */
96
37
  const log = createDebugLogger({ prefix: 'ResourceGeneration' });
97
38
  const META_DIR = '.canopy-meta';
@@ -104,7 +45,7 @@ export function resourceGenerationPath(root, resource) {
104
45
  * processes rebuild. Must be called AFTER the filesystem mutation.
105
46
  *
106
47
  * Returns the token written, or null if the write failed and `mustSucceed`
107
- * was not set (logged and swallowed).
48
+ * was not set.
108
49
  */
109
50
  export async function bumpResourceGeneration(root, resource, options) {
110
51
  const token = randomUUID();
@@ -122,12 +63,9 @@ export async function bumpResourceGeneration(root, resource, options) {
122
63
  }
123
64
  }
124
65
  /**
125
- * Read the current generation token for `resource` under `root`.
126
- *
127
- * ENOENT maps to `{ok: true, token: null}` — a valid "never bumped" state,
128
- * distinct from every real token. Any OTHER read error maps to `{ok: false}`
129
- * (logged) so callers can force-regenerate instead of trusting a null they
130
- * cannot actually attribute to "never bumped".
66
+ * Read the current generation token for `resource` under `root`. ENOENT maps to
67
+ * `{ok: true, token: null}`, the "never bumped" state; every other read error
68
+ * maps to `{ok: false}`.
131
69
  */
132
70
  export async function readResourceGeneration(root, resource) {
133
71
  try {
@@ -144,11 +82,10 @@ export async function readResourceGeneration(root, resource) {
144
82
  }
145
83
  }
146
84
  /**
147
- * True when a previously-captured snapshot token is still current: the read
148
- * succeeded AND its token matches the snapshot's. A failed read (`ok: false`)
149
- * is never current, even if the snapshot's token happens to be null — an
150
- * unreadable marker means we cannot vouch for freshness either way, and the
151
- * safe default is to treat it as stale.
85
+ * True when a snapshot's captured token is still current: the read succeeded
86
+ * AND its token matches. A failed read (`ok: false`) is never current, even
87
+ * against a null snapshot token — an unreadable marker vouches for nothing, so
88
+ * the safe default is stale.
152
89
  */
153
90
  export function isGenerationCurrent(snapshotToken, read) {
154
91
  return read.ok && read.token === snapshotToken;
@@ -1,7 +1,7 @@
1
1
  import type { RootCollectionConfig } from '../config/index.js';
2
2
  import type { ContentId } from '../paths/types.js';
3
3
  import type { EntrySchemaRegistry } from './types.js';
4
- export type EntryTypeMeta = {
4
+ type EntryTypeMeta = {
5
5
  name: string;
6
6
  format: 'md' | 'mdx' | 'json' | 'yaml';
7
7
  schema: string;
@@ -23,11 +23,6 @@ export type RootCollectionMeta = {
23
23
  /**
24
24
  * Loads all .collection.json meta files from contentRoot, including root.
25
25
  *
26
- * This function orchestrates the complete discovery process:
27
- * 1. Attempts to load the root .collection.json (contentRoot/.collection.json) - optional
28
- * 2. Recursively scans all subdirectories for .collection.json files
29
- * 3. Returns both root configuration and nested collections
30
- *
31
26
  * Meta File Structure:
32
27
  * - Root: contentRoot/.collection.json (optional, defines root-level entry types)
33
28
  * - Collections: contentRoot/[path]/.collection.json (defines collection in that directory)
@@ -49,11 +44,6 @@ export declare function loadCollectionMetaFiles(contentRoot: string): Promise<{
49
44
  * This function takes the loaded meta files (which contain string references like "postSchema")
50
45
  * and resolves them to actual EntrySchema arrays from the entry schema registry.
51
46
  *
52
- * Resolution Process:
53
- * 1. Root entry types: Resolve "schema" string to entry schema registry lookup
54
- * 2. Top-level collections: Resolve recursively, building nested tree structure
55
- * 3. Nested collections: Automatically grouped under their parent collections
56
- *
57
47
  * @param metaFiles - Loaded meta files from loadCollectionMetaFiles()
58
48
  * @param entrySchemaRegistry - Map of schema names to EntrySchema arrays
59
49
  * @returns Fully resolved root collection config ready for use by CanopyCMS
@@ -66,7 +56,5 @@ export declare function resolveCollectionReferences(metaFiles: {
66
56
  contentId?: ContentId;
67
57
  }>;
68
58
  }, entrySchemaRegistry: EntrySchemaRegistry): RootCollectionConfig;
69
- /**
70
- * Watch for changes to .collection.json files
71
- */
72
59
  export declare function watchCollectionMetaFiles(contentRoot: string, onChange: () => void): () => void;
60
+ export {};