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
@@ -0,0 +1,358 @@
1
+ import fs from 'node:fs/promises';
2
+ import net from 'node:net';
3
+ import path from 'node:path';
4
+ import { getErrorMessage, isNodeError } from '../utils/error.js';
5
+ /** The instance metadata service's IPv4 address; the launch template sets no IPv6 endpoint. */
6
+ const IMDS_HOST = '169.254.169.254';
7
+ /** How long the IMDS connect may take before it counts as unreachable. */
8
+ const IMDS_CONNECT_TIMEOUT_MS = 1_000;
9
+ /** Connect failures that prove no route: no network, or no IPv4 sockets at all. */
10
+ const NO_ROUTE_CODES = new Set(['ENETUNREACH', 'EAFNOSUPPORT']);
11
+ /**
12
+ * The variables that hold a secret, or name one (ARNs, JSON fields), and belong to the gateway:
13
+ * CanopyCMS's GitHub and Clerk settings.
14
+ */
15
+ const SECRET_ENV_PATTERN = /^(?:CANOPYCMS_GITHUB_TOKEN|CANOPYCMS_GITHUB_APP_|CLERK_SECRET_KEY)/;
16
+ /**
17
+ * The conventional credential variables: GitHub tokens (`GITHUB_BOT_TOKEN` is canopycms's default
18
+ * `githubTokenEnvVar`) and the AWS SDK's static credentials. The worker's git reads none (its
19
+ * environment is git-manager.ts's allowlist), but code that becomes the worker reads its
20
+ * environment. Exact names, so a look-alike such as `GITHUB_TOKEN_PATH` passes.
21
+ * `CLERK_JWT_KEY` is not here: it is a public verification key.
22
+ */
23
+ const AMBIENT_CREDENTIAL_ENV_NAMES = new Set([
24
+ 'GH_TOKEN',
25
+ 'GITHUB_TOKEN',
26
+ 'GITHUB_BOT_TOKEN',
27
+ 'AWS_ACCESS_KEY_ID',
28
+ 'AWS_SECRET_ACCESS_KEY',
29
+ 'AWS_SESSION_TOKEN',
30
+ 'AWS_SECURITY_TOKEN',
31
+ ]);
32
+ /** The worker unit's checks, in the plan's order. */
33
+ export async function workerSelfChecks(environment = {}) {
34
+ return [
35
+ await imdsUnreachable(environment),
36
+ await onlyLoopback(environment),
37
+ await procShowsOnlyOwnProcesses(environment),
38
+ await homeIsEmpty(environment),
39
+ noSecretsInEnv(environment),
40
+ ];
41
+ }
42
+ /** The gateway unit's checks. */
43
+ export async function gatewaySelfChecks(environment = {}) {
44
+ return [
45
+ await efsUnreadable(environment),
46
+ await corePatternNotPiped(environment),
47
+ await coreLimitZero(environment),
48
+ ...(environment.listenFd === undefined ? [] : [await socketAccessIsOthers(environment)]),
49
+ ];
50
+ }
51
+ /** Throw one error naming every failed check, or return. */
52
+ export function assertSelfChecks(results) {
53
+ const failed = results.filter((result) => !result.ok);
54
+ if (failed.length === 0)
55
+ return;
56
+ throw new Error(`Refusing to start: ${failed.map((result) => `${result.check}: ${result.detail}`).join('; ')}`);
57
+ }
58
+ /**
59
+ * A TCP connect to IMDS fails with no route (`ENETUNREACH`, or `EAFNOSUPPORT` under
60
+ * `RestrictAddressFamilies=AF_UNIX`) or times out. Any other outcome, a refusal included, means a
61
+ * route exists.
62
+ * @internal Exported for tests.
63
+ */
64
+ export async function imdsUnreachable(environment = {}) {
65
+ const connect = environment.connect ?? tcpConnect;
66
+ const outcome = await connect(IMDS_HOST, 80, IMDS_CONNECT_TIMEOUT_MS);
67
+ if (outcome === 'timeout' || (outcome !== 'connected' && NO_ROUTE_CODES.has(outcome.code))) {
68
+ return {
69
+ check: 'imds',
70
+ ok: true,
71
+ detail: outcome === 'timeout' ? 'timed out' : outcome.code,
72
+ };
73
+ }
74
+ return {
75
+ check: 'imds',
76
+ ok: false,
77
+ detail: `the worker unit can reach the instance metadata service (${outcome === 'connected' ? 'connected' : outcome.code}), ` +
78
+ 'so the process split protects nothing',
79
+ };
80
+ }
81
+ /**
82
+ * `/proc/self/net/dev` lists only `lo`: `PrivateNetwork=` took effect. Not `/sys/class/net`, which
83
+ * `PrivateNetwork=` does not remount, so it shows the host's interfaces even inside the cut.
84
+ * @internal Exported for tests.
85
+ */
86
+ export async function onlyLoopback(environment = {}) {
87
+ const file = path.join(rootOf(environment), 'proc', 'self', 'net', 'dev');
88
+ let text;
89
+ try {
90
+ text = await fs.readFile(file, 'utf8');
91
+ }
92
+ catch (err) {
93
+ return {
94
+ check: 'network-namespace',
95
+ ok: false,
96
+ detail: `cannot read ${file}: ${getErrorMessage(err)}`,
97
+ };
98
+ }
99
+ const interfaces = text
100
+ .split('\n')
101
+ .slice(2)
102
+ .map((line) => line.split(':')[0]?.trim() ?? '')
103
+ .filter((name) => name !== '');
104
+ const ok = interfaces.length === 1 && interfaces[0] === 'lo';
105
+ return {
106
+ check: 'network-namespace',
107
+ ok,
108
+ detail: ok
109
+ ? 'only lo'
110
+ : `the worker unit sees network interfaces besides lo (${interfaces.join(', ')}): it is not in a private network namespace`,
111
+ };
112
+ }
113
+ /**
114
+ * Every process `/proc` lists is this uid's: `ProtectProc=invisible` took effect.
115
+ * @internal Exported for tests.
116
+ */
117
+ export async function procShowsOnlyOwnProcesses(environment = {}) {
118
+ const proc = path.join(rootOf(environment), 'proc');
119
+ const uid = environment.uid ?? process.getuid?.();
120
+ if (uid === undefined) {
121
+ return { check: 'proc', ok: false, detail: 'this platform has no process uid to compare' };
122
+ }
123
+ let entries;
124
+ try {
125
+ entries = await fs.readdir(proc);
126
+ }
127
+ catch (err) {
128
+ return { check: 'proc', ok: false, detail: `cannot list ${proc}: ${getErrorMessage(err)}` };
129
+ }
130
+ const others = [];
131
+ for (const entry of entries.filter((name) => /^\d+$/.test(name))) {
132
+ try {
133
+ const stat = await fs.stat(path.join(proc, entry));
134
+ if (stat.uid !== uid)
135
+ others.push(`${entry} (uid ${stat.uid})`);
136
+ }
137
+ catch (err) {
138
+ // A process that exited between the listing and the stat.
139
+ if (!(isNodeError(err) && err.code === 'ENOENT')) {
140
+ others.push(`${entry} (${getErrorMessage(err)})`);
141
+ }
142
+ }
143
+ }
144
+ const ok = others.length === 0;
145
+ return {
146
+ check: 'proc',
147
+ ok,
148
+ detail: ok
149
+ ? `only uid ${uid}`
150
+ : `the worker unit sees other users' processes: ${others.slice(0, 5).join(', ')}`,
151
+ };
152
+ }
153
+ /**
154
+ * `/home` is empty: `ProtectHome=tmpfs`'s always-observable effect. `/run/user`, which it also
155
+ * hides, is empty anyway whenever nobody is logged in.
156
+ * @internal Exported for tests.
157
+ */
158
+ export async function homeIsEmpty(environment = {}) {
159
+ const home = path.join(rootOf(environment), 'home');
160
+ try {
161
+ const entries = await fs.readdir(home);
162
+ return {
163
+ check: 'home',
164
+ ok: entries.length === 0,
165
+ detail: entries.length === 0
166
+ ? 'empty'
167
+ : `the worker unit sees ${home}'s entries: ProtectHome=tmpfs did not apply`,
168
+ };
169
+ }
170
+ catch (err) {
171
+ return { check: 'home', ok: false, detail: `cannot list ${home}: ${getErrorMessage(err)}` };
172
+ }
173
+ }
174
+ /**
175
+ * No GitHub or Clerk secret, nor the ARN or JSON field naming one, is in the worker's environment:
176
+ * they belong to the gateway's env file. Nor is a conventional credential variable (a GitHub token,
177
+ * the AWS SDK's static credentials). Names only are reported.
178
+ * @internal Exported for tests.
179
+ */
180
+ export function noSecretsInEnv(environment = {}) {
181
+ const env = environment.env ?? process.env;
182
+ const found = Object.keys(env)
183
+ .filter((key) => env[key] !== undefined &&
184
+ (SECRET_ENV_PATTERN.test(key) || AMBIENT_CREDENTIAL_ENV_NAMES.has(key)))
185
+ .sort();
186
+ const ok = found.length === 0;
187
+ return {
188
+ check: 'secrets-in-env',
189
+ ok,
190
+ detail: ok
191
+ ? 'none'
192
+ : `the worker unit's environment holds ${found.join(', ')}, which the worker must not hold`,
193
+ };
194
+ }
195
+ /**
196
+ * The gateway cannot list `/mnt/efs`: `InaccessiblePaths=/mnt/efs` took effect.
197
+ * @internal Exported for tests.
198
+ */
199
+ export async function efsUnreadable(environment = {}) {
200
+ const efs = path.join(rootOf(environment), 'mnt', 'efs');
201
+ try {
202
+ await fs.readdir(efs);
203
+ }
204
+ catch (err) {
205
+ // Denied is the directive at work. Absent (a unit without `RequiresMountsFor=`, started before
206
+ // the mount) or any other failure proves nothing: a mount made later could still reach it.
207
+ const code = isNodeError(err) ? err.code : undefined;
208
+ const denied = code === 'EACCES' || code === 'EPERM';
209
+ return {
210
+ check: 'efs-unreadable',
211
+ ok: denied,
212
+ detail: denied
213
+ ? (code ?? '')
214
+ : `cannot tell that ${efs} is inaccessible: ${getErrorMessage(err)}`,
215
+ };
216
+ }
217
+ return {
218
+ check: 'efs-unreadable',
219
+ ok: false,
220
+ detail: `the GitHub gateway can read ${efs}, where the CMS Lambda writes`,
221
+ };
222
+ }
223
+ /**
224
+ * `kernel.core_pattern` does not begin with `|`: a piped pattern would hand a crashing gateway
225
+ * git's memory (the credential file's contents) to a helper.
226
+ * @internal Exported for tests.
227
+ */
228
+ export async function corePatternNotPiped(environment = {}) {
229
+ const file = path.join(rootOf(environment), 'proc', 'sys', 'kernel', 'core_pattern');
230
+ try {
231
+ const pattern = (await fs.readFile(file, 'utf8')).trim();
232
+ const ok = !pattern.startsWith('|');
233
+ return {
234
+ check: 'core-pattern',
235
+ ok,
236
+ detail: ok ? pattern : `kernel.core_pattern pipes core dumps to a program (${pattern})`,
237
+ };
238
+ }
239
+ catch (err) {
240
+ return {
241
+ check: 'core-pattern',
242
+ ok: false,
243
+ detail: `cannot read ${file}: ${getErrorMessage(err)}`,
244
+ };
245
+ }
246
+ }
247
+ /**
248
+ * `/proc/self/limits` shows a zero core limit, soft and hard: `LimitCORE=0` took effect.
249
+ * @internal Exported for tests.
250
+ */
251
+ export async function coreLimitZero(environment = {}) {
252
+ const file = path.join(rootOf(environment), 'proc', 'self', 'limits');
253
+ let text;
254
+ try {
255
+ text = await fs.readFile(file, 'utf8');
256
+ }
257
+ catch (err) {
258
+ return {
259
+ check: 'core-limit',
260
+ ok: false,
261
+ detail: `cannot read ${file}: ${getErrorMessage(err)}`,
262
+ };
263
+ }
264
+ const line = text.split('\n').find((row) => row.startsWith('Max core file size'));
265
+ const [soft, hard] = line?.slice('Max core file size'.length).trim().split(/\s+/) ?? [];
266
+ const ok = soft === '0' && hard === '0';
267
+ return {
268
+ check: 'core-limit',
269
+ ok,
270
+ detail: ok
271
+ ? 'zero'
272
+ : `the core file size limit is ${soft ?? '?'} (soft) and ${hard ?? '?'} (hard), not zero`,
273
+ };
274
+ }
275
+ /**
276
+ * The socket systemd passed is one only another user (and root) can connect to: its node is not
277
+ * this process's uid, and grants no group or other access. Whoever owns it is the worker, so a
278
+ * gateway running as that user (a unit without `User=canopy-github`) would hand the worker its
279
+ * own environment and memory. A socket's own descriptor reports the creating process (systemd,
280
+ * root), not the node's owner, so the node is found by the socket's inode in
281
+ * `/proc/self/net/unix`.
282
+ * @internal Exported for tests.
283
+ */
284
+ export async function socketAccessIsOthers(environment = {}) {
285
+ const fail = (detail) => ({ check: 'socket-access', ok: false, detail });
286
+ const uid = environment.uid ?? process.getuid?.();
287
+ if (uid === undefined)
288
+ return fail('this platform has no process uid to compare');
289
+ const fd = environment.listenFd ?? 3;
290
+ const proc = path.join(rootOf(environment), 'proc', 'self');
291
+ let socketPath;
292
+ try {
293
+ const inode = (await fs.stat(path.join(proc, 'fd', String(fd)))).ino;
294
+ const table = await fs.readFile(path.join(proc, 'net', 'unix'), 'utf8');
295
+ // Num RefCount Protocol Flags Type St Inode Path; the path is absent for an unbound socket.
296
+ for (const line of table.split('\n').slice(1)) {
297
+ const fields = line.trim().split(/\s+/);
298
+ if (fields[6] === String(inode) && fields.length > 7)
299
+ socketPath = fields.slice(7).join(' ');
300
+ }
301
+ }
302
+ catch (err) {
303
+ return fail(`cannot find the socket on descriptor ${fd}: ${getErrorMessage(err)}`);
304
+ }
305
+ if (socketPath === undefined || !path.isAbsolute(socketPath)) {
306
+ return fail(`the socket on descriptor ${fd} is not bound to a path`);
307
+ }
308
+ let node;
309
+ try {
310
+ node = await fs.lstat(socketPath);
311
+ }
312
+ catch (err) {
313
+ return fail(`cannot read ${socketPath}: ${getErrorMessage(err)}`);
314
+ }
315
+ if (!node.isSocket())
316
+ return fail(`${socketPath} is not a socket`);
317
+ if (node.uid === uid) {
318
+ return fail(`the GitHub gateway runs as uid ${uid}, which owns its socket ${socketPath} and so is the ` +
319
+ "worker's user: give the gateway unit User=canopy-github");
320
+ }
321
+ if ((node.mode & 0o077) !== 0) {
322
+ return fail(`${socketPath} has mode ${(node.mode & 0o777).toString(8)}, so users besides its owner can ` +
323
+ 'reach the gateway: give the socket unit SocketMode=0600');
324
+ }
325
+ return { check: 'socket-access', ok: true, detail: `${socketPath} is uid ${node.uid}'s alone` };
326
+ }
327
+ function rootOf(environment) {
328
+ return environment.root ?? '/';
329
+ }
330
+ /**
331
+ * One TCP connect, as the IMDS check makes it.
332
+ * @internal Exported for tests.
333
+ */
334
+ export function tcpConnect(host, port, timeoutMs) {
335
+ return new Promise((resolve) => {
336
+ let socket;
337
+ try {
338
+ socket = net.connect({ host, port });
339
+ }
340
+ catch (err) {
341
+ resolve({ code: isNodeError(err) && err.code !== undefined ? err.code : 'ERROR' });
342
+ return;
343
+ }
344
+ const timer = setTimeout(() => {
345
+ socket.destroy();
346
+ resolve('timeout');
347
+ }, timeoutMs);
348
+ socket.once('connect', () => {
349
+ clearTimeout(timer);
350
+ socket.destroy();
351
+ resolve('connected');
352
+ });
353
+ socket.once('error', (err) => {
354
+ clearTimeout(timer);
355
+ resolve({ code: isNodeError(err) && err.code !== undefined ? err.code : 'ERROR' });
356
+ });
357
+ });
358
+ }
@@ -0,0 +1,96 @@
1
+ import { type SimpleGit, type SimpleGitOptions } from 'simple-git';
2
+ export type SharedRepoKind = 'bare' | 'worktree';
3
+ /**
4
+ * The pins alone, without the environment {@link sharedRepoGit} adds (an explicit `GIT_DIR`, no
5
+ * lazy fetches), which every worker git in a shared repository needs too.
6
+ * @internal Exported for tests.
7
+ */
8
+ export declare function sharedRepoGitOptions(kind: SharedRepoKind): Pick<SimpleGitOptions, 'config' | 'unsafe'>;
9
+ /**
10
+ * A worker git instance in the shared repository at `repoPath` (the bare repository itself, or a
11
+ * clone's working tree), with the pins applied. The repository is named outright, as
12
+ * {@link assertSharedRepoConfig} names it, so both read the same config: discovery would take a
13
+ * planted `remote.git/.git`, or a `.git` above a clone whose own was removed. A clone's working
14
+ * tree is named too, which also overrides `core.worktree`.
15
+ *
16
+ * `options` are the caller's own (`timeout`, `abort`), applied under the pins. The child env is
17
+ * `gitChildEnv`'s: every shared-repository operation is local.
18
+ */
19
+ export declare function sharedRepoGit(repoPath: string, kind: SharedRepoKind, options?: Partial<SimpleGitOptions>): SimpleGit;
20
+ /** simple-git options for the worker's private GitHub mirror. */
21
+ export declare function mirrorGitOptions(): Pick<SimpleGitOptions, 'config' | 'unsafe'>;
22
+ /** {@link mirrorGitOptions}'s pins, for a git the mirror runs without simple-git (worker/git-process.ts). */
23
+ export declare function mirrorPins(): string[];
24
+ /**
25
+ * The pins of a quarantine repository, where the GitHub gateway takes in a pushed bundle
26
+ * (worker/github-mirror.ts): the mirror's, without `core.alternateRefsCommand=true`. That pin
27
+ * guards an alternates file the Lambda can write; a quarantine's names the mirror and is written
28
+ * by the gateway. With it, the fetch's connectivity check could not stop at the mirror's heads and
29
+ * would walk the mirror's whole history for every push.
30
+ */
31
+ export declare function quarantinePins(): string[];
32
+ /**
33
+ * {@link sharedRepoGit}'s pins, environment and working directory, for a git run through
34
+ * worker/git-process.ts: one whose stdin or stdout is a stream.
35
+ */
36
+ export declare function sharedRepoProcessOptions(repoPath: string, kind: SharedRepoKind): {
37
+ cwd: string;
38
+ env: Record<string, string>;
39
+ config: string[];
40
+ };
41
+ /**
42
+ * `--upload-pack` for a fetch FROM `remote.git` into a clone.
43
+ * @internal Exported for tests.
44
+ */
45
+ export declare function pinnedUploadPack(): string;
46
+ /**
47
+ * `--receive-pack` for a push INTO `remote.git`. Without it the push runs remote.git's own hooks
48
+ * as the worker. The `receive.deny*` pins keep a planted setting from blocking the forced update
49
+ * that publishes a rewritten history (worker/history-rewrite.ts).
50
+ */
51
+ export declare function pinnedReceivePack(): string;
52
+ /**
53
+ * Fetch `branch` from `remote.git` into the clone `git` runs in, through
54
+ * {@link pinnedUploadPack}. The result is in FETCH_HEAD only.
55
+ */
56
+ export declare function fetchFromRemoteGit(git: SimpleGit, remoteGitPath: string, branch: string): Promise<void>;
57
+ /** @internal Exported for tests. */
58
+ export interface UnexpectedConfigKey {
59
+ key: string;
60
+ /** The file git read it from, absolute. */
61
+ file: string;
62
+ }
63
+ /** Every refusal to run git in a shared repository, so a caller can tell one from git's own errors. */
64
+ export declare class SharedRepoRefusalError extends Error {
65
+ constructor(message: string);
66
+ }
67
+ /**
68
+ * A shared repository whose own config holds a key CanopyCMS never writes.
69
+ * @internal Exported for tests.
70
+ */
71
+ export declare class UntrustedRepoConfigError extends SharedRepoRefusalError {
72
+ readonly repoPath: string;
73
+ readonly keys: readonly UnexpectedConfigKey[];
74
+ constructor(repoPath: string, keys: readonly UnexpectedConfigKey[]);
75
+ }
76
+ /**
77
+ * Refuse a shared repository whose own config (with its includes, and `config.worktree`) holds a
78
+ * key outside {@link ALLOWED_REPO_CONFIG_KEYS}, or a submodule with a repository in it. Throws
79
+ * {@link UntrustedRepoConfigError} for a key. A config git cannot read, or does not finish reading,
80
+ * is also refused, with git's own message for a bad line, which names the line but not its content.
81
+ *
82
+ * `repoPath` is the bare repository itself for `bare`, the working tree for `worktree`.
83
+ */
84
+ export declare function assertSharedRepoConfig(repoPath: string, kind: SharedRepoKind, options?: {
85
+ timeoutMs?: number;
86
+ }): Promise<void>;
87
+ /**
88
+ * Refuse a rebase or fast-forward from `from` to `to` in `clone` that would bring in a submodule
89
+ * at a path where a repository already sits, as one planted ahead of it would.
90
+ */
91
+ export declare function assertNoIncomingSubmodules(git: SimpleGit, clone: string, from: string, to: string): Promise<void>;
92
+ /**
93
+ * Arguments for every worker `git status` in a clone. On the command line, unlike in config, the
94
+ * setting outranks a `.gitmodules` entry's own `ignore`.
95
+ */
96
+ export declare const SHARED_REPO_STATUS_ARGS: readonly string[];