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
@@ -1,27 +1,5 @@
1
- /**
2
- * Authorization validation utilities.
3
- *
4
- * SECURITY CRITICAL: These functions validate permission paths
5
- * to prevent path traversal attacks.
6
- */
7
1
  import type { PermissionPath } from './types.js';
8
- /**
9
- * Parse and validate a PermissionPath.
10
- *
11
- * SECURITY: Prevents path traversal attacks in permission rules.
12
- *
13
- * @param path - The permission path to validate
14
- * @returns Object with success flag and either the typed path or an error
15
- *
16
- * @example
17
- * ```ts
18
- * const result = parsePermissionPath(rule.path)
19
- * if (!result.ok) {
20
- * throw new Error(`Invalid permission path: ${result.error}`)
21
- * }
22
- * const permissionPath: PermissionPath = result.path
23
- * ```
24
- */
2
+ /** Parse a PermissionPath. SECURITY: rejects path traversal in permission rules. */
25
3
  export declare function parsePermissionPath(path: string): {
26
4
  ok: true;
27
5
  path: PermissionPath;
@@ -1,27 +1,5 @@
1
- /**
2
- * Authorization validation utilities.
3
- *
4
- * SECURITY CRITICAL: These functions validate permission paths
5
- * to prevent path traversal attacks.
6
- */
7
1
  import { hasTraversalSequence } from '../paths/normalize.js';
8
- /**
9
- * Parse and validate a PermissionPath.
10
- *
11
- * SECURITY: Prevents path traversal attacks in permission rules.
12
- *
13
- * @param path - The permission path to validate
14
- * @returns Object with success flag and either the typed path or an error
15
- *
16
- * @example
17
- * ```ts
18
- * const result = parsePermissionPath(rule.path)
19
- * if (!result.ok) {
20
- * throw new Error(`Invalid permission path: ${result.error}`)
21
- * }
22
- * const permissionPath: PermissionPath = result.path
23
- * ```
24
- */
2
+ /** Parse a PermissionPath. SECURITY: rejects path traversal in permission rules. */
25
3
  export function parsePermissionPath(path) {
26
4
  if (!path || typeof path !== 'string') {
27
5
  return { ok: false, error: 'Permission path is required' };
@@ -35,7 +13,6 @@ export function parsePermissionPath(path) {
35
13
  }
36
14
  // Normalize separators to prevent bypass via backslashes
37
15
  const normalized = path.replace(/\\/g, '/');
38
- // Additional security checks
39
16
  if (normalized.startsWith('/') || normalized.endsWith('/')) {
40
17
  return {
41
18
  ok: false,
@@ -1,21 +1,18 @@
1
1
  import type { BranchMetadata } from './types.js';
2
2
  import { type DuplicateContentId } from './content-id-index.js';
3
3
  /**
4
- * Admin-facing health classification of every directory under a branches
5
- * root (`baseRoot`), including ones the {@link BranchRegistry} quarantines
6
- * out of normal listings. Two stuck states have no in-product recovery
7
- * without this: a branch dir whose `.canopy-meta/branch.json` is corrupt
8
- * (registry now silently drops it — see branch-registry.ts's
9
- * `scanBranchDirectories` quarantine), and an orphan dir with no
10
- * `branch.json` at all (left behind by a partial delete crash — see
11
- * `api/branch.ts`'s delete handler). Both are invisible to admins in prod,
12
- * who have no filesystem access.
4
+ * Admin-facing health classification of every directory under a branches root,
5
+ * including the ones {@link BranchRegistry} quarantines out of normal listings.
6
+ * Without it two stuck states have no in-product recovery, and prod admins have
7
+ * no filesystem access to see them: a branch dir whose `.canopy-meta/branch.json`
8
+ * is corrupt (the registry drops it silently) and an orphan dir with no
9
+ * `branch.json` at all (a partial delete crash — see `api/branch.ts`).
13
10
  *
14
- * `scanBranchHealth` mirrors the registry's own directory-listing rules
15
- * (skip non-directories and dot-prefixed names) so its classification never
16
- * disagrees with what the registry itself would show as "missing".
11
+ * `scanBranchHealth` mirrors the registry's own directory-listing rules (skip
12
+ * non-directories and dot-prefixed names) so the two never disagree about what
13
+ * counts as missing.
17
14
  */
18
- export type BranchHealthKind = 'healthy' | 'corrupt-metadata' | 'orphan';
15
+ type BranchHealthKind = 'healthy' | 'corrupt-metadata' | 'orphan';
19
16
  export interface BranchHealthEntry {
20
17
  dirName: string;
21
18
  kind: BranchHealthKind;
@@ -24,34 +21,29 @@ export interface BranchHealthEntry {
24
21
  /** healthy only */
25
22
  branch?: BranchMetadata;
26
23
  /**
27
- * healthy only, and only when non-empty: duplicate content IDs found in
28
- * this branch's content tree (see content-id-index.ts's "Duplicate-ID
29
- * quarantine" section). The branch itself stays fully usable -- content
30
- * operations degrade only for the specific quarantined ID(s), which are
31
- * excluded from ID-based lookups, and whose entries refuse saves
32
- * (`DuplicateContentIdError`, a 409 naming this repair action) rather than
33
- * mutate an ambiguous target, until repaired via the
34
- * repair-content-duplicates admin action.
24
+ * healthy only, non-empty only: duplicate content IDs in this branch's
25
+ * content tree (see content-id-index.ts). The branch stays usable — only the
26
+ * quarantined IDs degrade, dropping out of ID-based lookups and refusing
27
+ * saves (`DuplicateContentIdError`, a 409 naming the repair action) rather
28
+ * than mutating an ambiguous target.
35
29
  */
36
30
  duplicateContentIds?: DuplicateContentId[];
37
31
  /**
38
- * healthy only, and only when true: this clone has an interrupted rebase on
39
- * disk (`.git/rebase-merge` / `.git/rebase-apply`).
32
+ * healthy only, true only: this clone has an interrupted rebase on disk
33
+ * (`.git/rebase-merge` / `.git/rebase-apply`).
40
34
  *
41
- * Deliberately an advisory flag on `healthy` rather than its own
42
- * `BranchHealthKind`, for the same reason `duplicateContentIds` is: the
43
- * branch's metadata is intact and the state is USUALLY transient -- the
44
- * worker's sync loop aborts an interrupted rebase at the top of its next
45
- * per-branch pass. What this flag buys is visibility in the window BEFORE
46
- * that pass runs, where the branch otherwise scanned as unqualified
47
- * `healthy` while being skipped as dirty every cycle.
35
+ * Advisory on `healthy` rather than its own `BranchHealthKind`, like
36
+ * `duplicateContentIds`: the metadata is intact and the state is usually
37
+ * transient, since the worker's sync loop aborts an interrupted rebase at the
38
+ * top of its next per-branch pass. The flag buys visibility in the window
39
+ * before that, where the branch otherwise scans as plain `healthy` while
40
+ * being skipped as dirty every cycle.
48
41
  *
49
- * NOT self-recovering in every case, so a persisting value is the real
50
- * signal and needs an operator. Two ways it sticks: the abort itself keeps
51
- * failing, or the branch's status moved off `editing` after it wedged --
52
- * the rebase loop filters by status BEFORE reaching the recovery step, so a
53
- * clone that crashed mid-rebase and was then submitted or archived is never
54
- * revisited, and this flag is the only thing that surfaces it.
42
+ * A value that persists is the real signal and needs an operator, because
43
+ * recovery is not guaranteed: the abort can keep failing, or the status can
44
+ * move off `editing` after the branch wedged — the rebase loop filters by
45
+ * status BEFORE the recovery step, so a clone that crashed mid-rebase and was
46
+ * then submitted or archived is never revisited, and only this flag shows it.
55
47
  */
56
48
  rebaseInProgress?: boolean;
57
49
  /** corrupt-metadata only: message describing why the file failed to load. */
@@ -65,12 +57,11 @@ export interface BranchHealthEntry {
65
57
  /** orphan only: age of the directory's mtime in ms, clamped to >= 0. */
66
58
  ageMs?: number;
67
59
  /**
68
- * [H1] Present iff the dir's provisioning init-lock marker exists on disk,
69
- * for orphan and corrupt-metadata entries only. Presence alone means
70
- * nothing -- a crashed provisioner's lock lingers forever (proper-lockfile
71
- * stale locks are only reaped by a later acquisition attempt, and a health
72
- * scan never acquires). Freshness (`ageMs`) is the actual signal admin
73
- * actions gate on.
60
+ * [H1] Present iff the dir's provisioning init-lock marker is on disk, for orphan
61
+ * and corrupt-metadata entries only. Presence alone means nothing: a crashed
62
+ * provisioner's lock lingers forever, since proper-lockfile reaps a stale
63
+ * lock only on a later acquisition and a health scan never acquires.
64
+ * Freshness (`ageMs`) is what admin actions gate on.
74
65
  */
75
66
  provisioningLock?: {
76
67
  mtime: string;
@@ -78,33 +69,14 @@ export interface BranchHealthEntry {
78
69
  };
79
70
  }
80
71
  /**
81
- * The on-disk path of the cross-process provisioning lock marker for a
82
- * given branch directory, matching `branch-workspace.ts`'s
83
- * `ensureGitWorkspace()` exactly:
84
- *
85
- * ```ts
86
- * acquireProvisioningLock(
87
- * path.dirname(branchRoot), // === baseRoot
88
- * `.${path.basename(branchRoot)}.init.lock`,
89
- * )
90
- * ```
91
- *
92
- * `acquireProvisioningLock` passes this name as `lockfilePath`, which
93
- * overrides proper-lockfile's default `${target}.lock` naming, so the lock
94
- * marker itself (a directory, mkdir-based) lives at exactly this path -- no
95
- * extra `.lock` suffix.
96
- */
97
- export declare function provisioningLockPath(baseRoot: string, dirName: string): string;
98
- /**
99
- * Scan every directory under `baseRoot` and classify it as healthy,
100
- * corrupt-metadata, or orphan. Never throws for a single bad directory --
101
- * one dir's unreadable/unparseable metadata must not take down the whole
102
- * scan (same rationale as the registry's own quarantine behavior).
103
- *
104
- * Tolerates a missing `baseRoot` (returns `[]`) so the admin endpoint can
105
- * call this unconditionally without a pre-existence check.
72
+ * Classify every directory under `baseRoot` as healthy, corrupt-metadata, or
73
+ * orphan. Never throws for a single bad directory — one dir's unreadable
74
+ * metadata must not take down the whole scan, as in the registry's quarantine.
75
+ * A missing `baseRoot` returns `[]`, so the admin endpoint can call this
76
+ * without a pre-existence check.
106
77
  */
107
78
  export declare function scanBranchHealth(baseRoot: string, opts: {
108
79
  baseBranchName: string;
109
80
  contentRootName?: string;
110
81
  }): Promise<BranchHealthEntry[]>;
82
+ export {};
@@ -6,23 +6,14 @@ import { sanitizeBranchName } from './paths/branch-name.js';
6
6
  import { getErrorMessage, isNodeError, isNotFoundError } from './utils/error.js';
7
7
  import { isRebaseInProgress } from './utils/git.js';
8
8
  /**
9
- * The on-disk path of the cross-process provisioning lock marker for a
10
- * given branch directory, matching `branch-workspace.ts`'s
11
- * `ensureGitWorkspace()` exactly:
9
+ * The provisioning lock marker's path for a branch directory, matching what
10
+ * `branch-workspace.ts`'s `ensureGitWorkspace()` passes exactly.
12
11
  *
13
- * ```ts
14
- * acquireProvisioningLock(
15
- * path.dirname(branchRoot), // === baseRoot
16
- * `.${path.basename(branchRoot)}.init.lock`,
17
- * )
18
- * ```
19
- *
20
- * `acquireProvisioningLock` passes this name as `lockfilePath`, which
21
- * overrides proper-lockfile's default `${target}.lock` naming, so the lock
22
- * marker itself (a directory, mkdir-based) lives at exactly this path -- no
23
- * extra `.lock` suffix.
12
+ * `acquireProvisioningLock` passes the name as `lockfilePath`, overriding
13
+ * proper-lockfile's default `${target}.lock`, so the marker (a mkdir-based
14
+ * directory) sits at exactly this path — no extra `.lock` suffix.
24
15
  */
25
- export function provisioningLockPath(baseRoot, dirName) {
16
+ function provisioningLockPath(baseRoot, dirName) {
26
17
  return path.join(baseRoot, `.${dirName}.init.lock`);
27
18
  }
28
19
  /** Stat the provisioning lock marker, if present. Never throws. */
@@ -32,8 +23,8 @@ async function readProvisioningLock(baseRoot, dirName) {
32
23
  return { mtime: stat.mtime.toISOString(), ageMs: Math.max(0, Date.now() - stat.mtimeMs) };
33
24
  }
34
25
  catch {
35
- // Missing, or unreadable for some other reason -- either way, "no signal"
36
- // is the safe default rather than failing the whole scan.
26
+ // Missing or unreadable: "no signal" is the safe default, rather than
27
+ // failing the whole scan.
37
28
  return undefined;
38
29
  }
39
30
  }
@@ -48,13 +39,11 @@ async function readMetaMtime(branchRoot) {
48
39
  }
49
40
  }
50
41
  /**
51
- * Scan a healthy branch's content tree for duplicate-embedded-ID pairs (see
52
- * content-id-index.ts's "Duplicate-ID quarantine" section). Never throws --
53
- * one branch's unreadable/unusual content tree must not take down the whole
54
- * health scan (same rationale as the corrupt-metadata handling below). Costs
55
- * a full recursive readdir of the content tree, same class of cost as the
56
- * lazy warm-up every ContentStore already pays on first access -- acceptable
57
- * for an admin-triggered scan, not a hot path.
42
+ * Scan a healthy branch's content tree for duplicate embedded IDs (see
43
+ * content-id-index.ts). Never throws: one branch's unreadable content tree must
44
+ * not take down the whole health scan. Costs a full recursive readdir — the
45
+ * same class of cost as a ContentStore's first-access warm-up, fine for an
46
+ * admin-triggered scan and not for a hot path.
58
47
  */
59
48
  async function scanDuplicateContentIds(branchRoot, contentRootName) {
60
49
  try {
@@ -67,13 +56,11 @@ async function scanDuplicateContentIds(branchRoot, contentRootName) {
67
56
  }
68
57
  }
69
58
  /**
70
- * Scan every directory under `baseRoot` and classify it as healthy,
71
- * corrupt-metadata, or orphan. Never throws for a single bad directory --
72
- * one dir's unreadable/unparseable metadata must not take down the whole
73
- * scan (same rationale as the registry's own quarantine behavior).
74
- *
75
- * Tolerates a missing `baseRoot` (returns `[]`) so the admin endpoint can
76
- * call this unconditionally without a pre-existence check.
59
+ * Classify every directory under `baseRoot` as healthy, corrupt-metadata, or
60
+ * orphan. Never throws for a single bad directory — one dir's unreadable
61
+ * metadata must not take down the whole scan, as in the registry's quarantine.
62
+ * A missing `baseRoot` returns `[]`, so the admin endpoint can call this
63
+ * without a pre-existence check.
77
64
  */
78
65
  export async function scanBranchHealth(baseRoot, opts) {
79
66
  const resolvedRoot = path.resolve(baseRoot);
@@ -107,19 +94,16 @@ export async function scanBranchHealth(baseRoot, opts) {
107
94
  loadErr = err;
108
95
  }
109
96
  if (loadErr) {
110
- // Both the documented BranchMetadataCorruptError (bad JSON) and any
111
- // other loadOnly failure (EACCES, EISDIR from a directory named
112
- // branch.json, etc.) land here: all are "needs admin attention",
113
- // and none may throw out of the scan.
97
+ // Every loadOnly failure lands here — BranchMetadataCorruptError for bad
98
+ // JSON, EACCES/EISDIR and the rest for everything else — since all of
99
+ // them need admin attention and none may throw out of the scan.
114
100
  //
115
- // [REDACT] parseError is served to the browser via the admin
116
- // branch-health endpoint, so it must never leak the absolute
117
- // workspace path. BranchMetadataCorruptError carries `parseCause`
118
- // (the raw JSON.parse message, path-free) for exactly this --
119
- // `message` embeds branchRoot and is for server logs only. Other node
120
- // errors (EISDIR from a directory named branch.json, EACCES, etc.)
121
- // embed the path in their `message`, so only their `code` is safe to
122
- // surface; non-node errors fall back to getErrorMessage.
101
+ // [REDACT] parseError reaches the browser through the admin branch-health
102
+ // endpoint, so it must never carry the absolute workspace path.
103
+ // BranchMetadataCorruptError's `parseCause` is the path-free JSON.parse
104
+ // message for exactly this, while its `message` embeds branchRoot and is
105
+ // for server logs only. Node errors embed the path in `message` too, so
106
+ // only their `code` is safe to surface.
123
107
  const parseError = loadErr instanceof BranchMetadataCorruptError
124
108
  ? loadErr.parseCause
125
109
  : isNodeError(loadErr)
@@ -1,20 +1,10 @@
1
1
  /**
2
2
  * Reading `branch.json` — the file format, nothing else.
3
3
  *
4
- * Deliberately a LEAF: it imports only node built-ins, a type, and the error
5
- * helper. That is the whole point of the file.
6
- *
7
- * `branch-registry.ts` scans every branch directory and reads each one's
8
- * `branch.json`; `branch-metadata.ts` owns writing it and, after a write,
9
- * invalidates the registry cache. Both of those are correct, but together they
10
- * were a runtime import cycle (`branch-metadata` -> `branch-registry` ->
11
- * `branch-metadata`), with value imports on both edges — the only cycle in the
12
- * package when `no-circular` was first turned on, 2026-08-23.
13
- *
14
- * Hoisting the READ here breaks it without changing either module's behavior:
15
- * the registry gets its reader from a leaf, and the metadata manager keeps its
16
- * invalidation edge. `BranchMetadataFileManager.loadOnly` stays as a thin
17
- * delegate so its ~16 existing call sites are untouched.
4
+ * Deliberately a LEAF, importing only node built-ins, a type, and the error
5
+ * helper. That is what keeps `branch-registry.ts` (which reads every branch's
6
+ * `branch.json`) out of a runtime import cycle with `branch-metadata.ts` (which
7
+ * writes it and then invalidates the registry cache).
18
8
  */
19
9
  import type { BranchMetadata } from './types.js';
20
10
  export declare const BRANCH_META_DIR = ".canopy-meta";
@@ -26,33 +16,27 @@ export interface BranchMetadataFile {
26
16
  branch: BranchMetadata;
27
17
  }
28
18
  /**
29
- * branch.json exists but its content is not valid JSON. Distinguished from
30
- * provisioning/IO failures so callers can degrade instead of failing hard:
31
- * the registry scan quarantines the branch, and the request handler keeps
32
- * serving (with empty internal groups) when the BASE branch is the corrupt
33
- * one — otherwise the admin recovery surface would be unreachable exactly
34
- * when it is needed.
19
+ * branch.json exists but is not valid JSON. Distinguished from provisioning and
20
+ * IO failures so callers can degrade instead of failing hard: the registry scan
21
+ * quarantines the branch, and the request handler keeps serving (with empty
22
+ * internal groups) when the BASE branch is the corrupt one — otherwise the
23
+ * admin recovery surface is unreachable exactly when it is needed.
35
24
  */
36
25
  export declare class BranchMetadataCorruptError extends Error {
37
26
  readonly branchRoot: string;
38
27
  /**
39
- * [REDACT] The raw JSON.parse failure message (e.g. "Unexpected token
40
- * ..."), with no embedded path. `message` above deliberately keeps the
41
- * full `branchRoot`-qualified text for server logs; `parseCause` is what
42
- * callers should surface to clients (see branch-health.ts's `parseError`)
43
- * so the admin branch-health scan never leaks the absolute workspace path.
28
+ * [REDACT] The raw JSON.parse failure message, with no embedded path.
29
+ * `message` above keeps the `branchRoot`-qualified text for server logs;
30
+ * `parseCause` is the one callers surface to clients (branch-health.ts's
31
+ * `parseError`), so no scan leaks the absolute workspace path.
44
32
  */
45
33
  readonly parseCause: string;
46
34
  constructor(branchRoot: string, cause: string);
47
35
  }
48
- /** Absolute path to a branch workspace's `branch.json`. */
49
- export declare const branchMetadataFilePath: (branchRoot: string) => string;
50
36
  /**
51
37
  * Read and parse `branch.json`, with no locking, no OCC and no side effects.
52
- *
53
- * Returns `null` when the file does not exist (an un-provisioned or
54
- * non-branch directory), throws `BranchMetadataCorruptError` on malformed
55
- * JSON, and rethrows every other IO failure unchanged — callers distinguish
56
- * all three.
38
+ * Callers distinguish three outcomes: `null` when the file does not exist (an
39
+ * un-provisioned or non-branch directory), `BranchMetadataCorruptError` on
40
+ * malformed JSON, and every other IO failure rethrown unchanged.
57
41
  */
58
42
  export declare function readBranchMetadataFile(branchRoot: string): Promise<BranchMetadataFile | null>;
@@ -1,20 +1,10 @@
1
1
  /**
2
2
  * Reading `branch.json` — the file format, nothing else.
3
3
  *
4
- * Deliberately a LEAF: it imports only node built-ins, a type, and the error
5
- * helper. That is the whole point of the file.
6
- *
7
- * `branch-registry.ts` scans every branch directory and reads each one's
8
- * `branch.json`; `branch-metadata.ts` owns writing it and, after a write,
9
- * invalidates the registry cache. Both of those are correct, but together they
10
- * were a runtime import cycle (`branch-metadata` -> `branch-registry` ->
11
- * `branch-metadata`), with value imports on both edges — the only cycle in the
12
- * package when `no-circular` was first turned on, 2026-08-23.
13
- *
14
- * Hoisting the READ here breaks it without changing either module's behavior:
15
- * the registry gets its reader from a leaf, and the metadata manager keeps its
16
- * invalidation edge. `BranchMetadataFileManager.loadOnly` stays as a thin
17
- * delegate so its ~16 existing call sites are untouched.
4
+ * Deliberately a LEAF, importing only node built-ins, a type, and the error
5
+ * helper. That is what keeps `branch-registry.ts` (which reads every branch's
6
+ * `branch.json`) out of a runtime import cycle with `branch-metadata.ts` (which
7
+ * writes it and then invalidates the registry cache).
18
8
  */
19
9
  import fs from 'node:fs/promises';
20
10
  import path from 'node:path';
@@ -22,12 +12,11 @@ import { isNotFoundError } from './utils/error.js';
22
12
  export const BRANCH_META_DIR = '.canopy-meta';
23
13
  export const BRANCH_META_FILE = 'branch.json';
24
14
  /**
25
- * branch.json exists but its content is not valid JSON. Distinguished from
26
- * provisioning/IO failures so callers can degrade instead of failing hard:
27
- * the registry scan quarantines the branch, and the request handler keeps
28
- * serving (with empty internal groups) when the BASE branch is the corrupt
29
- * one — otherwise the admin recovery surface would be unreachable exactly
30
- * when it is needed.
15
+ * branch.json exists but is not valid JSON. Distinguished from provisioning and
16
+ * IO failures so callers can degrade instead of failing hard: the registry scan
17
+ * quarantines the branch, and the request handler keeps serving (with empty
18
+ * internal groups) when the BASE branch is the corrupt one — otherwise the
19
+ * admin recovery surface is unreachable exactly when it is needed.
31
20
  */
32
21
  export class BranchMetadataCorruptError extends Error {
33
22
  constructor(branchRoot, cause) {
@@ -38,14 +27,12 @@ export class BranchMetadataCorruptError extends Error {
38
27
  }
39
28
  }
40
29
  /** Absolute path to a branch workspace's `branch.json`. */
41
- export const branchMetadataFilePath = (branchRoot) => path.join(path.resolve(branchRoot), BRANCH_META_DIR, BRANCH_META_FILE);
30
+ const branchMetadataFilePath = (branchRoot) => path.join(path.resolve(branchRoot), BRANCH_META_DIR, BRANCH_META_FILE);
42
31
  /**
43
32
  * Read and parse `branch.json`, with no locking, no OCC and no side effects.
44
- *
45
- * Returns `null` when the file does not exist (an un-provisioned or
46
- * non-branch directory), throws `BranchMetadataCorruptError` on malformed
47
- * JSON, and rethrows every other IO failure unchanged — callers distinguish
48
- * all three.
33
+ * Callers distinguish three outcomes: `null` when the file does not exist (an
34
+ * un-provisioned or non-branch directory), `BranchMetadataCorruptError` on
35
+ * malformed JSON, and every other IO failure rethrown unchanged.
49
36
  */
50
37
  export async function readBranchMetadataFile(branchRoot) {
51
38
  const resolvedRoot = path.resolve(branchRoot);