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
package/dist/server.js CHANGED
@@ -96,6 +96,11 @@ export { collectRoutableEntries } from './static/index.js';
96
96
  * hand-rolling the same scan over `listEntries`.
97
97
  */
98
98
  export { findDuplicateUrlPaths } from './static/index.js';
99
+ /**
100
+ * Find every reference naming no entry — the check a production build runs and fails on unless
101
+ * `danglingReferences: 'warn'`. Pass an unscoped `listEntries()`.
102
+ */
103
+ export { findDanglingReferences } from './static/index.js';
99
104
  /**
100
105
  * SEO field extraction and URL shaping, framework-agnostic. `isNoindexEntry` is the single
101
106
  * predicate behind both `robots: noindex` and sitemap exclusion.
@@ -115,28 +120,77 @@ export { createAssetStore } from './assets/factory.js';
115
120
  /**
116
121
  * The five S3/local bucket-prefix strings (`asset-originals/`, `asset-staging/`, `asset-meta/`,
117
122
  * `assets/`, `assets/t/`). Exported so server-only consumers outside this package — notably the
118
- * prod transform Lambda (`packages/canopycms-cdk/lambda/asset-transform`) — build and parse
123
+ * lazy transform Lambda (`packages/canopycms-cdk/lambda/asset-transform`) — build and parse
119
124
  * asset keys through the same constants `S3AssetStore` uses rather than duplicating the strings.
120
125
  */
121
126
  export { ASSET_PREFIXES } from './assets/keys.js';
122
127
  /**
123
128
  * Parse the three path segments after `assets/t/` (`{directives}/{hash32}/{slug}.{ext}`) into a
124
- * validated `TransformDirectives` set, or a structured parse error. Reused unchanged by the
125
- * dev-mode lazy `/assets/t/*` emulation (`api/assets.ts`) and the prod transform Lambda, so the
126
- * URL grammar is defined in exactly one place.
129
+ * validated `TransformDirectives` set, or a structured parse error, so the URL grammar is
130
+ * defined in exactly one place.
127
131
  */
128
132
  export { parseTransformPath } from './assets/transform-directives.js';
129
133
  /**
130
134
  * Canonical string form of a `TransformDirectives` set — the cache key every transform output is
131
135
  * stored under (`assets/t/{formatDirectives(...)}/{hash32}/{slug}.{ext}`). Equivalent directive
132
- * sets (different key order or float formatting) always format to the same string. Reused by the
133
- * prod transform Lambda so its writes agree with the dev-mode emulation and `assetUrl()`.
136
+ * sets (different key order or float formatting) always format to the same string.
134
137
  */
135
138
  export { formatDirectives } from './assets/transform-directives.js';
139
+ /**
140
+ * Parse `assets/t/` path segments and resolve them to the canonical spelling their output is
141
+ * stored under, with directives re-parsed from that spelling. The lazy transform Lambda 301s a
142
+ * non-canonical request to it; the authenticated raw route serves the canonical bytes.
143
+ */
144
+ export { canonicalizeTransformPath } from './assets/transform-directives.js';
136
145
  /**
137
146
  * Apply a parsed `TransformDirectives` set to source image bytes with sharp:
138
147
  * resize/format/quality/crop, EXIF stripped on every re-encode, identity included. Server-only
139
- * (sharp); reused unchanged by the dev-mode lazy `/assets/t/*` emulation and the prod transform
140
- * Lambda.
148
+ * (sharp); `storeTransform` below wraps it for every caller that stores the output.
141
149
  */
142
150
  export { applyTransform } from './assets/transform.js';
151
+ /**
152
+ * Compute the transform a canonical `assets/t/` path names and store it under that key: meta
153
+ * lookup, raster-only, slug and ext checks, then `applyTransform`. Shared by the authenticated raw
154
+ * route, `materialize-assets` and the lazy transform Lambda. A 404's `error` names hashes and
155
+ * slugs, so a caller answering a browser replaces it.
156
+ */
157
+ export { storeTransform } from './assets/materialize.js';
158
+ /** The `Cache-Control` every stored transform output carries: content-addressed, so immutable. */
159
+ export { TRANSFORM_CACHE_CONTROL } from './assets/materialize.js';
160
+ /** The object tag the lazy transform Lambda's outputs carry, which its `assets/t/` expiry filters on. */
161
+ export { LAZY_TRANSFORM_TAG } from './assets/materialize.js';
162
+ /**
163
+ * Make every `assets/t/` key a build references exist in `store` (transforming only the missing
164
+ * ones from the stored originals) and check every referenced svg/pdf key exists. Under an
165
+ * `outputPrefix`, keys are written beneath it, and those production already stores are copied. A
166
+ * release job that bundles its own tool calls this with a store from `createAssetStore` and gates
167
+ * on the returned report; no site config is involved. Needs sharp only when something is missing.
168
+ */
169
+ export { materializeAssets } from './assets/materialize.js';
170
+ /**
171
+ * The live preview's asset prefix on the server: the signed-in raw route under a `basePath`, the
172
+ * same-origin check every preview prefix passes, and the hook registering the request-scoped getter
173
+ * `assetUrl` reads.
174
+ * @internal `canopycms-next`'s preview page is their consumer.
175
+ */
176
+ export { authenticatedAssetBase, readAssetBase } from './editor/raw-asset-base.js';
177
+ /** @internal */
178
+ export { setServerPreviewAssetBaseGetter } from './editor/preview-asset-base.js';
179
+ /** Thrown by `materializeAssets` when sharp cannot load and keys are missing, so none can be produced. */
180
+ export { SharpUnavailableError } from './assets/materialize.js';
181
+ /**
182
+ * Thrown by `materializeAssets` before any store request when `outputPrefix` is not a relative,
183
+ * `/`-terminated run of `[A-Za-z0-9._-]` segments outside every canopy prefix.
184
+ */
185
+ export { InvalidOutputPrefixError } from './assets/materialize.js';
186
+ /** The `schemaVersion` carried by every `MaterializeReport`. */
187
+ export { MATERIALIZE_REPORT_SCHEMA_VERSION } from './assets/materialize.js';
188
+ /**
189
+ * Scan a static build's output for `/assets/…` URLs and write `canopy-asset-refs.json` into it.
190
+ * Throws `AssetRefsError` for a URL no stored object can answer (non-canonical or malformed).
191
+ */
192
+ export { collectAssetRefs } from './build/asset-refs.js';
193
+ /** Read and validate a `canopy-asset-refs.json`; throws when it is unreadable or malformed. */
194
+ export { readAssetRefsFile } from './build/asset-refs.js';
195
+ /** Thrown by `collectAssetRefs`; `problems` lists each offending file and URL. */
196
+ export { AssetRefsError } from './build/asset-refs.js';
@@ -17,22 +17,35 @@
17
17
  */
18
18
  import type { CanopyConfig } from './config/index.js';
19
19
  import type { EntrySchemaRegistry } from './schema/types.js';
20
- import type { BranchContext } from './types.js';
20
+ import type { BranchContext, BranchPaths } from './types.js';
21
21
  import type { CanopyUser } from './user.js';
22
22
  import { createCheckBranchAccess, createCheckContentAccess, type ContentAccessChecker } from './authorization/index.js';
23
23
  import { GitManager } from './git-manager.js';
24
24
  import { BranchRegistry } from './branch-registry.js';
25
25
  import { type GitHubService } from './github-service.js';
26
26
  import { BranchSchemaCache } from './branch-schema-cache.js';
27
- import { type SubmissionEditor } from './submission-attribution.js';
27
+ import { type EditorLookup, type SubmissionEditor } from './submission-attribution.js';
28
+ import { type StampedEntry } from './stamp-on-publish.js';
28
29
  /**
29
30
  * Bootstrap admin IDs from the environment. These users are treated as Admins
30
31
  * whatever their group membership.
31
32
  */
32
33
  export declare const getBootstrapAdminIds: () => Set<string>;
34
+ /**
35
+ * Submit found nothing to send: the branch's saved content, committed or not, matches its base
36
+ * as of the fork point. Raised before anything is pushed and after undoing any commit the
37
+ * submit made, so the branch's commits and saved edits are as they were.
38
+ */
39
+ export declare class NothingToSubmitError extends Error {
40
+ constructor(branch: string, base: string);
41
+ }
33
42
  export interface SubmitBranchResult {
34
43
  /** Repo-relative paths the branch changes, excluding canopycms runtime metadata. */
35
44
  changedPaths: string[];
45
+ /** Every recorded editor of the branch, for the PR body. */
46
+ editors: SubmissionEditor[];
47
+ /** The entries this submit stamped (stamp-on-publish.ts), for the editor's open forms. */
48
+ stamped: StampedEntry[];
36
49
  }
37
50
  export interface CanopyServices {
38
51
  config: CanopyConfig;
@@ -42,6 +55,14 @@ export interface CanopyServices {
42
55
  * content serving since the editor is pinned to its own branch via URL params.
43
56
  */
44
57
  refreshActiveBranch: () => Promise<void>;
58
+ /**
59
+ * Resolve a prod base branch that was still pending at creation because the worker had not yet
60
+ * created the remote it is read from; a no-op once resolved. Rejects with RemoteNotReadyError
61
+ * (a 503) until the remote exists. The HTTP handler (http/handler.ts) and
62
+ * createCanopyContext's getContext (context.ts) await it before reading
63
+ * `config.defaultBaseBranch`.
64
+ */
65
+ resolvePendingBaseBranch: () => Promise<void>;
45
66
  /** Entry schema registry mapping entry schema names to field definitions */
46
67
  entrySchemaRegistry: EntrySchemaRegistry;
47
68
  /** Per-branch schema cache */
@@ -73,14 +94,19 @@ export interface CanopyServices {
73
94
  message: string;
74
95
  }) => Promise<void>;
75
96
  /**
76
- * Submit branch: commit all changes (with the submitter's trailers) and push
77
- * to remote. Resolves with every path the branch changes against its base.
97
+ * Submit branch: fill new entries' empty `stampOnPublish` fields
98
+ * (stamp-on-publish.ts), commit all changes (with the submitter's trailers)
99
+ * and push to remote. Resolves with every path the branch changes against its base,
100
+ * and with `stamped`, the entries this submit stamped.
78
101
  * Holds the branch's content-write lock; rejects with
79
- * `ContentWriteLockBusyError` when busy.
102
+ * `ContentWriteLockBusyError` when busy, and with `NothingToSubmitError`
103
+ * before pushing when the branch changes nothing.
80
104
  */
81
105
  submitBranch: (options: {
82
106
  context: BranchContext;
83
107
  submitter?: SubmissionEditor;
108
+ /** Names the recorded editors; without it they are credited by id. */
109
+ lookupEditor?: EditorLookup;
84
110
  message?: string;
85
111
  }) => Promise<SubmitBranchResult>;
86
112
  /** Commit to the settings branch (for permissions/groups) and push it; never opens a PR */
@@ -96,6 +122,8 @@ export interface CanopyServices {
96
122
  }>;
97
123
  /** Get the root path for settings storage (ensures workspace exists) */
98
124
  getSettingsBranchRoot: () => Promise<string>;
125
+ /** Records `user` as an editor of the branch for its next submit (branch-metadata.ts). */
126
+ recordBranchEditor: (context: BranchPaths, user: CanopyUser) => Promise<void>;
99
127
  }
100
128
  export interface CreateCanopyServicesOptions {
101
129
  /** Entry schema names → field definitions, for resolving .collection.json references. */
package/dist/services.js CHANGED
@@ -9,18 +9,22 @@ import { operatingStrategy } from './operating-mode/index.js';
9
9
  import { BranchSchemaCache } from './branch-schema-cache.js';
10
10
  import { enqueueTask } from './task-queue/cms-task-queue.js';
11
11
  import { getTaskQueueDir } from './task-queue/task-queue-config.js';
12
+ import { baseBranchOf } from './utils/base-branch.js';
12
13
  import { detectHeadBranch, isCanopyInternalPath } from './utils/git.js';
13
14
  import { readsFromCheckout } from './build-mode.js';
14
15
  import { timeRequestPhase } from './utils/request-timing.js';
15
- import { BRANCH_META_DIR } from './branch-metadata-file.js';
16
- import { appendTrailers, buildEditorTrailers, } from './submission-attribution.js';
16
+ import { appendTrailers, buildEditorTrailers, describeEditors, } from './submission-attribution.js';
17
+ import { getBranchMetadataFileManager, recordBranchEditor } from './branch-metadata.js';
18
+ import { readBranchMetadataFile } from './branch-metadata-file.js';
17
19
  import { getErrorMessage, redactCredentials } from './utils/error.js';
18
20
  import { withContentWriteLock } from './utils/content-write-lock.js';
21
+ import { ContentStore } from './content-store.js';
22
+ import { stampNewEntries } from './stamp-on-publish.js';
19
23
  /**
20
24
  * A per-instance active-branch detector with its own 5s TTL cache, in priority
21
25
  * order: an explicitly configured value; `defaultBaseBranch ?? 'main'` with no
22
26
  * git for static deployments and builds; git HEAD in dev; and
23
- * `defaultBaseBranch ?? 'main'` in prod.
27
+ * `defaultBaseBranch` in prod, `undefined` while that is still unresolved.
24
28
  */
25
29
  function createActiveBranchDetector() {
26
30
  let cache = null;
@@ -42,7 +46,7 @@ function createActiveBranchDetector() {
42
46
  cache = { value: branch, expiresAt: now + 5000 };
43
47
  return branch;
44
48
  }
45
- return config.defaultBaseBranch ?? 'main';
49
+ return config.defaultBaseBranch;
46
50
  };
47
51
  }
48
52
  /**
@@ -58,6 +62,42 @@ export const getBootstrapAdminIds = () => {
58
62
  .map((id) => id.trim())
59
63
  .filter(Boolean));
60
64
  };
65
+ /**
66
+ * Submit found nothing to send: the branch's saved content, committed or not, matches its base
67
+ * as of the fork point. Raised before anything is pushed and after undoing any commit the
68
+ * submit made, so the branch's commits and saved edits are as they were.
69
+ */
70
+ export class NothingToSubmitError extends Error {
71
+ constructor(branch, base) {
72
+ super(`Nothing to submit yet: "${branch}" has no saved changes compared with "${base}". ` +
73
+ 'Save your edits, then submit.');
74
+ this.name = 'NothingToSubmitError';
75
+ }
76
+ }
77
+ /** The branch's recorded editor ids, or undefined, with a warning, when branch.json cannot be read. */
78
+ async function readRecordedEditors(context) {
79
+ try {
80
+ return (await readBranchMetadataFile(context.branchRoot))?.branch;
81
+ }
82
+ catch (err) {
83
+ console.warn(`CanopyCMS: Could not read the recorded editors of ${context.branch.name}:`, getErrorMessage(err));
84
+ return undefined;
85
+ }
86
+ }
87
+ /** One lookup per user per submit, however often the submit asks. */
88
+ function memoizeLookup(lookup) {
89
+ if (!lookup)
90
+ return undefined;
91
+ const seen = new Map();
92
+ return (userId) => {
93
+ let found = seen.get(userId);
94
+ if (!found) {
95
+ found = lookup(userId);
96
+ seen.set(userId, found);
97
+ }
98
+ return found;
99
+ };
100
+ }
61
101
  /**
62
102
  * Build the reusable helpers from a validated CanopyConfig — once at startup,
63
103
  * then injected into request handlers and loaders. Schema is not loaded here;
@@ -89,25 +129,30 @@ async function _createCanopyServicesInternal(config, options) {
89
129
  const detectActiveBranch = createActiveBranchDetector();
90
130
  const explicitActiveBranch = config.defaultActiveBranch;
91
131
  const explicitBaseBranch = config.defaultBaseBranch;
92
- const defaultActiveBranch = await detectActiveBranch(config);
93
- // Unset, the base branch follows the same dev-mode HEAD detection, matching
94
- // resolveBaseBranch in utils/git.ts — the canonical definition workspace
95
- // provisioning uses.
132
+ // Unset, the base branch follows the rule workspace provisioning uses
133
+ // (GitManager.resolveWorkspaceBaseBranch): dev detects git HEAD, prod reads
134
+ // the remote's HEAD and fails loudly when it cannot. Prod stays pending
135
+ // (undefined) only while the worker has not created the remote yet; see
136
+ // resolvePendingBaseBranch.
96
137
  const defaultBaseBranch = explicitBaseBranch ??
97
- (config.mode === 'dev' && !readsFromCheckout(config)
98
- ? await detectActiveBranch({ ...config, defaultActiveBranch: undefined })
99
- : 'main');
138
+ (readsFromCheckout(config)
139
+ ? 'main'
140
+ : config.mode === 'dev'
141
+ ? await detectActiveBranch({ ...config, defaultActiveBranch: undefined })
142
+ : await GitManager.detectBaseBranch(config, 'pending'));
143
+ const defaultActiveBranch = await detectActiveBranch({ ...config, defaultBaseBranch });
100
144
  config = { ...config, defaultActiveBranch, defaultBaseBranch };
101
145
  const bootstrapAdminIds = getBootstrapAdminIds();
102
146
  const branchSchemaCache = options.branchSchemaCache ?? new BranchSchemaCache(config.mode);
103
- const checkBranchAccess = createCheckBranchAccess(config.defaultBranchAccess ?? 'deny', config);
147
+ // Reads services.config per call: the protected base branch may resolve after creation.
148
+ const checkBranchAccess = (context, user) => createCheckBranchAccess(config.defaultBranchAccess ?? 'deny', services.config)(context, user);
104
149
  // Content access loads permissions dynamically from the settings branch (orphan git branch)
105
150
  const ensureSettingsBranchRoot = options.getSettingsBranchRoot ??
106
151
  (async () => {
107
152
  const strategy = operatingStrategy(config.mode);
108
153
  const settingsRoot = strategy.getSettingsRoot();
109
154
  const branchName = strategy.getSettingsBranchName(config);
110
- const manager = new SettingsWorkspaceManager(config);
155
+ const manager = new SettingsWorkspaceManager(services.config);
111
156
  await manager.ensureGitWorkspace({
112
157
  settingsRoot,
113
158
  branchName,
@@ -129,7 +174,7 @@ async function _createCanopyServicesInternal(config, options) {
129
174
  const configDefaults = getConfigDefaults();
130
175
  const createGitManagerFor = (repoPath, opts) => new GitManager({
131
176
  repoPath,
132
- baseBranch: opts?.baseBranch ?? config.defaultBaseBranch ?? 'main',
177
+ baseBranch: opts?.baseBranch ?? baseBranchOf(services.config),
133
178
  remote: opts?.remote ?? config.defaultRemoteName ?? configDefaults.remoteName,
134
179
  skipIndexMarker: opts?.skipIndexMarker,
135
180
  });
@@ -151,12 +196,33 @@ async function _createCanopyServicesInternal(config, options) {
151
196
  await git.commit(options.message);
152
197
  });
153
198
  };
199
+ /** Runs inside submitBranch's content-write lock; a stamp that fails never blocks the submit. */
200
+ const stampNewEntriesOrWarn = async (context, git) => {
201
+ const contentRoot = services.config.contentRoot || 'content';
202
+ try {
203
+ const { flatSchema } = await services.branchSchemaCache.getSchema(context.branchRoot, services.entrySchemaRegistry, contentRoot);
204
+ return await stampNewEntries({
205
+ git,
206
+ store: new ContentStore(context.branchRoot, flatSchema, { contentRootName: contentRoot }),
207
+ branchRoot: context.branchRoot,
208
+ flatSchema,
209
+ contentRoot,
210
+ stampedAt: new Date().toISOString(),
211
+ warn: (message) => console.warn(redactCredentials(message)),
212
+ });
213
+ }
214
+ catch (err) {
215
+ console.warn(`CanopyCMS: Could not finish stamping the new entries on ${context.branch.name}; ` +
216
+ 'submitting with only the stamps already written:', redactCredentials(getErrorMessage(err)));
217
+ return [];
218
+ }
219
+ };
154
220
  const submitBranch = async (options) => {
155
221
  // Defense-in-depth: refuse to push the base branch to itself even if the
156
222
  // 'submittableBranch' guard was somehow bypassed. Prefer the recorded fork
157
- // point (context.branch.baseBranch) over config.defaultBaseBranch — the
158
- // closure-captured `config` can go stale after dev refreshActiveBranch().
159
- const effectiveBase = options.context.branch.baseBranch ?? config.defaultBaseBranch ?? 'main';
223
+ // point (context.branch.baseBranch) over the config value, which dev's
224
+ // refreshActiveBranch() can move.
225
+ const effectiveBase = options.context.branch.baseBranch ?? baseBranchOf(services.config);
160
226
  if (sanitizeBranchName(options.context.branch.name) === sanitizeBranchName(effectiveBase)) {
161
227
  throw new Error(`Refusing to commit and push the base branch "${options.context.branch.name}" — submitting requires a separate editing branch`);
162
228
  }
@@ -173,9 +239,25 @@ async function _createCanopyServicesInternal(config, options) {
173
239
  // lands on the branch, and the rebase's `--abort` resets the branch past it
174
240
  // after this reported success. The push stays inside so no rebase rewrites
175
241
  // the commit between commit and push.
242
+ const lookupEditor = memoizeLookup(options.lookupEditor);
243
+ const readRecorded = () => readRecordedEditors(options.context);
244
+ // Names are looked up before taking the lock, so a slow auth provider never holds it.
245
+ const named = new Map((await describeEditors((await readRecorded())?.editors ?? [], lookupEditor)).map((e) => [
246
+ e.userId,
247
+ e,
248
+ ]));
249
+ let recorded = {};
250
+ let stamped = [];
176
251
  const submitted = await withContentWriteLock(options.context.branchRoot, async () => {
177
252
  await git.checkoutBranch(options.context.branch.name);
253
+ // Before the status read, so the stamp joins this commit even when an earlier attempt
254
+ // already committed the entry and only its push failed.
255
+ stamped = await stampNewEntriesOrWarn(options.context, git);
178
256
  const status = await git.status();
257
+ // A save records its editor only after releasing this lock, so a save that lands just
258
+ // before this submit can be committed here while its editor is named by the next commit.
259
+ recorded = (await readRecorded()) ?? {};
260
+ const uncommitted = recorded.uncommittedEditors ?? [];
179
261
  // Commit and push answer two DIFFERENT questions. Committing cleans the
180
262
  // working tree, so one combined "tree is dirty" gate makes a retry after a
181
263
  // failed push a silent no-op: nothing left to commit, the block is skipped,
@@ -185,34 +267,56 @@ async function _createCanopyServicesInternal(config, options) {
185
267
  // canopycms's own state under .canopy-meta/ is never content, so it neither
186
268
  // makes a commit worth creating nor gets staged into one.
187
269
  let committed = false;
270
+ const preCommitSha = await git.headSha();
188
271
  if (status.files.some((f) => !isCanopyInternalPath(f.path))) {
189
272
  await git.addAllExceptCanopyState();
190
- const trailers = buildEditorTrailers(options.submitter ? [options.submitter] : [], {
273
+ const committers = uncommitted.map((userId) => named.get(userId) ?? { userId });
274
+ const trailers = buildEditorTrailers(options.submitter ? [options.submitter, ...committers] : committers, {
191
275
  editedBy: config.gitEditedByTrailers ?? true,
192
276
  coAuthoredBy: config.gitCoAuthoredByTrailers ?? false,
193
277
  });
194
278
  await git.commit(appendTrailers(options.message ?? `Submit ${options.context.branch.name}`, trailers));
195
279
  committed = true;
196
280
  }
281
+ // The diff runs after the commit so it covers saved-but-uncommitted edits too, and
282
+ // before the push so a branch with nothing to submit never reaches the remote. A diff
283
+ // that cannot be computed lets the submit through: the list only feeds the PR body, and
284
+ // GitHub's own refusal of an empty branch is handled on both paths (api/github-sync.ts,
285
+ // worker/task-runner.ts).
286
+ let changedPaths;
287
+ try {
288
+ changedPaths = (await git.listChangedPathsSinceBase()).filter((p) => !isCanopyInternalPath(p));
289
+ }
290
+ catch (err) {
291
+ console.warn(`CanopyCMS: Could not list the changes on ${options.context.branch.name} against its base; ` +
292
+ "the PR body lists only this submit's changes:", redactCredentials(getErrorMessage(err)));
293
+ }
294
+ if (changedPaths?.length === 0) {
295
+ if (committed)
296
+ await git.resetKeepingChanges(preCommitSha);
297
+ throw new NothingToSubmitError(options.context.branch.name, effectiveBase);
298
+ }
299
+ // A failure here leaves them uncommitted, so the next commit names them again.
300
+ if (committed && uncommitted.length > 0) {
301
+ try {
302
+ await getBranchMetadataFileManager(options.context.branchRoot, options.context.baseRoot).markEditorsCommitted(uncommitted);
303
+ }
304
+ catch (err) {
305
+ console.warn(`CanopyCMS: Could not clear the committed editors of ${options.context.branch.name}:`, getErrorMessage(err));
306
+ }
307
+ }
197
308
  if (committed || (await git.hasUnpushedCommits(options.context.branch.name))) {
198
309
  await git.push(options.context.branch.name);
199
310
  }
200
- return status;
311
+ return changedPaths ?? status.files.map((f) => f.path).filter((p) => !isCanopyInternalPath(p));
201
312
  });
202
- // The list only feeds the PR body, so a failure to compute it falls back to
203
- // this submit's own working-tree changes rather than failing a submit that
204
- // has already been pushed.
205
- let changedPaths;
206
- try {
207
- changedPaths = await git.listChangedPathsSinceBase();
208
- }
209
- catch (err) {
210
- console.warn(`CanopyCMS: Could not list the changes on ${options.context.branch.name} against its base; ` +
211
- "the PR body lists only this submit's changes:", redactCredentials(getErrorMessage(err)));
212
- changedPaths = submitted.files.map((f) => f.path);
213
- }
313
+ // Re-read after the lock, so the PR body also names an editor recorded after the read above:
314
+ // one whose save this commit carries, or one whose save will reach the PR with a later push.
315
+ const editorIds = (await readRecorded())?.editors ?? recorded.editors ?? [];
214
316
  return {
215
- changedPaths: changedPaths.filter((p) => !p.startsWith(`${BRANCH_META_DIR}/`)),
317
+ changedPaths: submitted,
318
+ editors: await describeEditors(editorIds, lookupEditor),
319
+ stamped,
216
320
  };
217
321
  };
218
322
  // Must be initialized before closures that reference it (commitToSettingsBranch)
@@ -328,6 +432,7 @@ async function _createCanopyServicesInternal(config, options) {
328
432
  submitBranch,
329
433
  commitToSettingsBranch,
330
434
  getSettingsBranchRoot,
435
+ recordBranchEditor,
331
436
  refreshActiveBranch: async () => {
332
437
  if (services.config.mode !== 'dev')
333
438
  return;
@@ -358,14 +463,27 @@ async function _createCanopyServicesInternal(config, options) {
358
463
  changed = true;
359
464
  }
360
465
  if (changed) {
361
- // The closures above (getSettingsBranchRoot, checkContentAccess,
362
- // createGitManagerFor, …) captured the original `config` local. Only
363
- // branch identity changes here: git operations on existing branches use
364
- // the fork point in branch metadata, and anything needing the fresh
365
- // values must read services.config.
466
+ // The closures above captured the original `config` local. Only branch
467
+ // identity changes here: git operations on existing branches use the
468
+ // fork point in branch metadata, and anything needing the fresh values
469
+ // reads services.config.
366
470
  services.config = next;
367
471
  }
368
472
  },
473
+ resolvePendingBaseBranch: async () => {
474
+ if (services.config.defaultBaseBranch)
475
+ return;
476
+ // In-process and write-once in effect: concurrent requests each read the
477
+ // same remote HEAD and assign the same value, and nothing is written to
478
+ // disk, so no lock is needed. Later changes to that HEAD are not followed
479
+ // (configure defaultBaseBranch to move the base branch).
480
+ const detected = await GitManager.detectBaseBranch(services.config, 'throw');
481
+ services.config = {
482
+ ...services.config,
483
+ defaultBaseBranch: detected,
484
+ defaultActiveBranch: services.config.defaultActiveBranch ?? detected,
485
+ };
486
+ },
369
487
  };
370
488
  return services;
371
489
  }
@@ -8,8 +8,8 @@ import type { OperatingMode } from './operating-mode/index.js';
8
8
  * its target, and `GitManager.initializeWorkspace` clones INTO the settings
9
9
  * root, which `git clone` refuses if anything is already there. A dedicated
10
10
  * dot-directory also keeps this marker out of `path.dirname(settingsRoot)`,
11
- * where `ensureLocalSimulatedRemote` puts `.remote-init.lock` — settings init
12
- * calls into that while holding this lock, so separate directories make the
11
+ * where `ensureLocalSimulatedRemote` puts `.remote-init.lock` — an in-place
12
+ * settings re-init calls into that while holding this lock, so separate directories make the
13
13
  * nesting obvious rather than incidental. For how a lock's anchor path is
14
14
  * chosen, see utils/provisioning-lock.ts and docs/concurrency.md.
15
15
  * @internal Exported for tests.
@@ -27,12 +27,32 @@ export interface EnsureSettingsWorkspaceOptions {
27
27
  * BranchWorkspaceManager this writes no metadata files and never touches the
28
28
  * branch registry.
29
29
  *
30
+ * A first clone follows [PROV-1] (branch-provisioning.ts): it is built in a
31
+ * staging sibling and renamed into place, so a process killed mid-clone never
32
+ * leaves a half-made workspace at the settings root. Never sparse: the orphan
33
+ * init's `git rm -rf .` would leave out-of-cone base files in the tree.
34
+ *
30
35
  * Two locking layers, mirroring BranchWorkspaceManager: an in-memory promise
31
36
  * lock within the process, and `acquireProvisioningLock` (proper-lockfile)
32
- * across processes and hosts.
37
+ * across processes and hosts around the publish and every in-place init.
33
38
  */
34
39
  export declare class SettingsWorkspaceManager {
35
40
  private readonly config;
36
41
  constructor(config: CanopyConfig);
37
42
  ensureGitWorkspace(options: EnsureSettingsWorkspaceOptions): Promise<void>;
43
+ private initOptions;
44
+ /**
45
+ * Layer 2 around the init itself (proper-lockfile: heartbeat-refreshed while the holder lives,
46
+ * so a slow EFS operation is not mistaken for a crash, and patient retries so a loser WAITS
47
+ * instead of racing into a concurrent init).
48
+ */
49
+ private withInitLock;
50
+ /** Re-init an existing workspace where it is; false when, under the lock, there is none. */
51
+ private ensureInPlace;
52
+ /**
53
+ * Clone and set up the settings branch in a staging sibling, then publish it under the init
54
+ * lock, moving an interrupted first init aside to `.trash-settings-*`. A workspace someone
55
+ * else published meanwhile wins and the staging copy is dropped.
56
+ */
57
+ private provisionStaged;
38
58
  }