cursedbelt 1.0.0 → 2.5.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 (537) hide show
  1. package/dist/client/index.js +1 -1
  2. package/dist/core/category/index.d.ts.map +1 -1
  3. package/dist/core/category/index.js +2 -1
  4. package/dist/core/category/index.js.map +1 -1
  5. package/dist/core/category/types.js +1 -1
  6. package/dist/core/category/types.js.map +1 -1
  7. package/dist/core/file-tree/fileTreeModel.d.ts +49 -0
  8. package/dist/core/file-tree/fileTreeModel.d.ts.map +1 -1
  9. package/dist/core/file-tree/fileTreeModel.js +84 -0
  10. package/dist/core/file-tree/fileTreeModel.js.map +1 -1
  11. package/dist/core/layout/index.js +1 -1
  12. package/dist/core/layout/index.js.map +1 -1
  13. package/dist/core/media/index.js +1 -1
  14. package/dist/core/media/index.js.map +1 -1
  15. package/dist/core/media/types.js +1 -1
  16. package/dist/core/media/types.js.map +1 -1
  17. package/dist/core/media/uploadLimits.js +1 -1
  18. package/dist/core/media/uploadLimits.js.map +1 -1
  19. package/dist/core/sharing/model.d.ts +1 -1
  20. package/dist/ctgr/index.js +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/react/activity-bar/ActivityBar.d.ts +17 -0
  24. package/dist/react/activity-bar/ActivityBar.d.ts.map +1 -1
  25. package/dist/react/activity-bar/ActivityBar.js.map +1 -1
  26. package/dist/react/analytics/index.d.ts +1 -1
  27. package/dist/react/analytics/index.js +1 -1
  28. package/dist/react/chat/MessageComposer.d.ts.map +1 -1
  29. package/dist/react/chat/MessageComposer.js +5 -4
  30. package/dist/react/chat/MessageComposer.js.map +1 -1
  31. package/dist/react/components/Button.d.ts.map +1 -1
  32. package/dist/react/components/Button.js +3 -2
  33. package/dist/react/components/Button.js.map +1 -1
  34. package/dist/react/components/Checkbox.d.ts +19 -3
  35. package/dist/react/components/Checkbox.d.ts.map +1 -1
  36. package/dist/react/components/Checkbox.js +29 -12
  37. package/dist/react/components/Checkbox.js.map +1 -1
  38. package/dist/react/components/CodeArea.d.ts.map +1 -1
  39. package/dist/react/components/CodeArea.js +2 -1
  40. package/dist/react/components/CodeArea.js.map +1 -1
  41. package/dist/react/components/Collapsible.d.ts.map +1 -1
  42. package/dist/react/components/Collapsible.js +2 -1
  43. package/dist/react/components/Collapsible.js.map +1 -1
  44. package/dist/react/components/ComboboxField.d.ts.map +1 -1
  45. package/dist/react/components/ComboboxField.js +3 -2
  46. package/dist/react/components/ComboboxField.js.map +1 -1
  47. package/dist/react/components/CopyButton.d.ts.map +1 -1
  48. package/dist/react/components/CopyButton.js +2 -1
  49. package/dist/react/components/CopyButton.js.map +1 -1
  50. package/dist/react/components/DataTable/ColumnChecklist.d.ts.map +1 -1
  51. package/dist/react/components/DataTable/ColumnChecklist.js +2 -1
  52. package/dist/react/components/DataTable/ColumnChecklist.js.map +1 -1
  53. package/dist/react/components/DataTable/Pagination.d.ts.map +1 -1
  54. package/dist/react/components/DataTable/Pagination.js +2 -1
  55. package/dist/react/components/DataTable/Pagination.js.map +1 -1
  56. package/dist/react/components/DataTable/SortHeader.d.ts.map +1 -1
  57. package/dist/react/components/DataTable/SortHeader.js +2 -1
  58. package/dist/react/components/DataTable/SortHeader.js.map +1 -1
  59. package/dist/react/components/DataTable/TableFilterBuilder.d.ts +61 -0
  60. package/dist/react/components/DataTable/TableFilterBuilder.d.ts.map +1 -0
  61. package/dist/react/components/DataTable/{FilterBuilder.js → TableFilterBuilder.js} +26 -3
  62. package/dist/react/components/DataTable/TableFilterBuilder.js.map +1 -0
  63. package/dist/react/components/DataTable/Toolbar.d.ts +1 -1
  64. package/dist/react/components/DataTable/Toolbar.js +3 -3
  65. package/dist/react/components/DataTable/Toolbar.js.map +1 -1
  66. package/dist/react/components/DataTable/cells/LinkCell.d.ts.map +1 -1
  67. package/dist/react/components/DataTable/cells/LinkCell.js +2 -1
  68. package/dist/react/components/DataTable/cells/LinkCell.js.map +1 -1
  69. package/dist/react/components/DataTable/index.d.ts +1 -1
  70. package/dist/react/components/DataTable/index.d.ts.map +1 -1
  71. package/dist/react/components/DataTable/index.js +4 -1
  72. package/dist/react/components/DataTable/index.js.map +1 -1
  73. package/dist/react/components/DragHandle.d.ts.map +1 -1
  74. package/dist/react/components/DragHandle.js +2 -1
  75. package/dist/react/components/DragHandle.js.map +1 -1
  76. package/dist/react/components/EmojiField.d.ts.map +1 -1
  77. package/dist/react/components/EmojiField.js +2 -1
  78. package/dist/react/components/EmojiField.js.map +1 -1
  79. package/dist/react/components/EventTimeline.d.ts +3 -2
  80. package/dist/react/components/EventTimeline.d.ts.map +1 -1
  81. package/dist/react/components/EventTimeline.js +3 -2
  82. package/dist/react/components/EventTimeline.js.map +1 -1
  83. package/dist/react/components/IconButton.d.ts +1 -1
  84. package/dist/react/components/IconButton.js +1 -1
  85. package/dist/react/components/InfoHint.d.ts.map +1 -1
  86. package/dist/react/components/InfoHint.js +5 -4
  87. package/dist/react/components/InfoHint.js.map +1 -1
  88. package/dist/react/components/InheritBadge.js +1 -1
  89. package/dist/react/components/InheritBadge.js.map +1 -1
  90. package/dist/react/components/InlineEditableText.d.ts.map +1 -1
  91. package/dist/react/components/InlineEditableText.js +2 -1
  92. package/dist/react/components/InlineEditableText.js.map +1 -1
  93. package/dist/react/components/MeterList.d.ts.map +1 -1
  94. package/dist/react/components/MeterList.js +2 -1
  95. package/dist/react/components/MeterList.js.map +1 -1
  96. package/dist/react/components/PathText.d.ts +2 -2
  97. package/dist/react/components/PathText.d.ts.map +1 -1
  98. package/dist/react/components/PathText.js +2 -1
  99. package/dist/react/components/PathText.js.map +1 -1
  100. package/dist/react/components/RatingField.d.ts.map +1 -1
  101. package/dist/react/components/RatingField.js +2 -1
  102. package/dist/react/components/RatingField.js.map +1 -1
  103. package/dist/react/components/SecretInput.js +3 -2
  104. package/dist/react/components/SecretInput.js.map +1 -1
  105. package/dist/react/components/SegmentedControl.d.ts.map +1 -1
  106. package/dist/react/components/SegmentedControl.js +2 -1
  107. package/dist/react/components/SegmentedControl.js.map +1 -1
  108. package/dist/react/components/StarRating.d.ts.map +1 -1
  109. package/dist/react/components/StarRating.js +9 -5
  110. package/dist/react/components/StarRating.js.map +1 -1
  111. package/dist/react/components/StatStrip.d.ts.map +1 -1
  112. package/dist/react/components/StatStrip.js +2 -1
  113. package/dist/react/components/StatStrip.js.map +1 -1
  114. package/dist/react/components/StatTile.d.ts.map +1 -1
  115. package/dist/react/components/StatTile.js +3 -2
  116. package/dist/react/components/StatTile.js.map +1 -1
  117. package/dist/react/components/Tabs.d.ts.map +1 -1
  118. package/dist/react/components/Tabs.js +2 -1
  119. package/dist/react/components/Tabs.js.map +1 -1
  120. package/dist/react/components/TruncatedText.d.ts +2 -1
  121. package/dist/react/components/TruncatedText.d.ts.map +1 -1
  122. package/dist/react/components/TruncatedText.js +2 -1
  123. package/dist/react/components/TruncatedText.js.map +1 -1
  124. package/dist/react/components/calendar/MonthGrid.d.ts.map +1 -1
  125. package/dist/react/components/calendar/MonthGrid.js +2 -1
  126. package/dist/react/components/calendar/MonthGrid.js.map +1 -1
  127. package/dist/react/components/calendar/WeekView.d.ts.map +1 -1
  128. package/dist/react/components/calendar/WeekView.js +2 -1
  129. package/dist/react/components/calendar/WeekView.js.map +1 -1
  130. package/dist/react/components/revealOnHover.d.ts.map +1 -1
  131. package/dist/react/components/revealOnHover.js +2 -1
  132. package/dist/react/components/revealOnHover.js.map +1 -1
  133. package/dist/react/file-tree/FileTree.d.ts +50 -1
  134. package/dist/react/file-tree/FileTree.d.ts.map +1 -1
  135. package/dist/react/file-tree/FileTree.js +234 -6
  136. package/dist/react/file-tree/FileTree.js.map +1 -1
  137. package/dist/react/file-tree/fileTree.css +52 -0
  138. package/dist/react/filter-rail/FilterRail.d.ts.map +1 -1
  139. package/dist/react/filter-rail/FilterRail.js +5 -4
  140. package/dist/react/filter-rail/FilterRail.js.map +1 -1
  141. package/dist/react/folder-tree/FolderTreeRail.d.ts.map +1 -1
  142. package/dist/react/folder-tree/FolderTreeRail.js +2 -1
  143. package/dist/react/folder-tree/FolderTreeRail.js.map +1 -1
  144. package/dist/react/index.d.ts +5 -1
  145. package/dist/react/index.d.ts.map +1 -1
  146. package/dist/react/index.js +5 -1
  147. package/dist/react/index.js.map +1 -1
  148. package/dist/react/layoutEngine/index.js +1 -1
  149. package/dist/react/layoutEngine/index.js.map +1 -1
  150. package/dist/react/lib/field.d.ts.map +1 -1
  151. package/dist/react/lib/field.js +3 -2
  152. package/dist/react/lib/field.js.map +1 -1
  153. package/dist/react/lib/floatingStyles.d.ts.map +1 -1
  154. package/dist/react/lib/floatingStyles.js +2 -1
  155. package/dist/react/lib/floatingStyles.js.map +1 -1
  156. package/dist/react/lib/tapTarget.d.ts +96 -0
  157. package/dist/react/lib/tapTarget.d.ts.map +1 -0
  158. package/dist/react/lib/tapTarget.js +96 -0
  159. package/dist/react/lib/tapTarget.js.map +1 -0
  160. package/dist/react/media/VideoTrimmer.d.ts +1 -1
  161. package/dist/react/media/VideoTrimmer.js +1 -1
  162. package/dist/react/media/denseGallery.css +3 -3
  163. package/dist/react/media/ffmpegWasm.js +2 -2
  164. package/dist/react/media/ffmpegWasm.js.map +1 -1
  165. package/dist/react/media/videoPlayer.css +42 -0
  166. package/dist/react/namespace/NamespaceTargetCapsule.d.ts +2 -2
  167. package/dist/react/namespace/NamespaceTargetCapsule.d.ts.map +1 -1
  168. package/dist/react/nav/BreadcrumbTrail.d.ts.map +1 -1
  169. package/dist/react/nav/BreadcrumbTrail.js +4 -3
  170. package/dist/react/nav/BreadcrumbTrail.js.map +1 -1
  171. package/dist/react/nav/HubTileGrid.d.ts.map +1 -1
  172. package/dist/react/nav/HubTileGrid.js +2 -1
  173. package/dist/react/nav/HubTileGrid.js.map +1 -1
  174. package/dist/react/nav/SideNav.d.ts.map +1 -1
  175. package/dist/react/nav/SideNav.js +4 -3
  176. package/dist/react/nav/SideNav.js.map +1 -1
  177. package/dist/react/nav/SideNavCustomize.d.ts.map +1 -1
  178. package/dist/react/nav/SideNavCustomize.js +2 -1
  179. package/dist/react/nav/SideNavCustomize.js.map +1 -1
  180. package/dist/react/palette/CommandPalette.d.ts.map +1 -1
  181. package/dist/react/palette/CommandPalette.js +3 -2
  182. package/dist/react/palette/CommandPalette.js.map +1 -1
  183. package/dist/server/drivers/pooledControlStores.pg.test.js +1 -0
  184. package/dist/server/drivers/pooledControlStores.pg.test.js.map +1 -1
  185. package/dist/server/drivers/pooledIdentityStore.pg.test.js +1 -0
  186. package/dist/server/drivers/pooledIdentityStore.pg.test.js.map +1 -1
  187. package/dist/server/drivers/retentionPolicy.pg.test.js +1 -0
  188. package/dist/server/drivers/retentionPolicy.pg.test.js.map +1 -1
  189. package/dist/server/guard/argon2Binding.d.ts +1 -1
  190. package/dist/server/guard/argon2Binding.js +1 -1
  191. package/dist/server/incidents/store.d.ts +3 -3
  192. package/dist/server/index.js +1 -1
  193. package/dist/server/index.js.map +1 -1
  194. package/dist/server/master-lock/masterLock.d.ts +1 -1
  195. package/dist/server/media-bun/index.js +1 -1
  196. package/dist/server/media-bun/index.js.map +1 -1
  197. package/dist/server/paths/appDataHome.d.ts +20 -0
  198. package/dist/server/paths/appDataHome.d.ts.map +1 -0
  199. package/dist/server/paths/appDataHome.js +69 -0
  200. package/dist/server/paths/appDataHome.js.map +1 -0
  201. package/dist/server/retention/archive.d.ts +3 -4
  202. package/dist/server/retention/archive.d.ts.map +1 -1
  203. package/dist/server/retention/archive.js +20 -15
  204. package/dist/server/retention/archive.js.map +1 -1
  205. package/dist/server/retention/index.d.ts +1 -1
  206. package/dist/server/retention/index.js +1 -1
  207. package/dist/server/retention/policy.d.ts +2 -2
  208. package/dist/server/retention/policy.d.ts.map +1 -1
  209. package/dist/server/retention/policy.js +1 -1
  210. package/dist/server/retention/store.d.ts.map +1 -1
  211. package/dist/server/retention/store.js +27 -20
  212. package/dist/server/retention/store.js.map +1 -1
  213. package/dist/server/runtime/localHost.d.ts +10 -5
  214. package/dist/server/runtime/localHost.d.ts.map +1 -1
  215. package/dist/server/runtime/localHost.js +12 -8
  216. package/dist/server/runtime/localHost.js.map +1 -1
  217. package/dist/server/runtime/meterRollup.pg.test.js +1 -0
  218. package/dist/server/runtime/meterRollup.pg.test.js.map +1 -1
  219. package/dist/server/runtime/recipe.d.ts +4 -4
  220. package/dist/server/runtime/retentionJob.pg.test.js +1 -0
  221. package/dist/server/runtime/retentionJob.pg.test.js.map +1 -1
  222. package/dist/server/search/pgSearchProvider.pg.test.js +1 -0
  223. package/dist/server/search/pgSearchProvider.pg.test.js.map +1 -1
  224. package/dist/shared/errors.d.ts +1 -1
  225. package/dist/shared/errors.js +1 -1
  226. package/dist/styles-static.css +413 -0
  227. package/dist/styles-utilities.css +5074 -0
  228. package/dist/styles.css +49 -0
  229. package/package.json +30 -168
  230. package/scripts/generateStaticStyles.ts +122 -0
  231. package/scripts/generateUtilityStyles.ts +215 -0
  232. package/scripts/publicSurface.ts +455 -0
  233. package/scripts/testTmpRoot.ts +34 -5
  234. package/src/client/index.ts +1 -1
  235. package/src/core/category/index.ts +2 -1
  236. package/src/core/category/types.ts +1 -1
  237. package/src/core/file-tree/fileTreeModel.spec.ts +134 -0
  238. package/src/core/file-tree/fileTreeModel.ts +104 -0
  239. package/src/core/layout/index.ts +1 -1
  240. package/src/core/media/index.ts +1 -1
  241. package/src/core/media/types.ts +1 -1
  242. package/src/core/media/uploadLimits.ts +1 -1
  243. package/src/core/sharing/model.ts +1 -1
  244. package/src/ctgr/index.ts +1 -1
  245. package/src/declaredDepsAreImported.spec.ts +87 -0
  246. package/src/demoFixture.spec.ts +133 -0
  247. package/src/index.ts +1 -1
  248. package/src/lockfileIsTracked.spec.ts +50 -0
  249. package/src/namedSubpathsResolve.spec.ts +119 -0
  250. package/src/publicSurface.spec.ts +72 -0
  251. package/src/react/activity-bar/ActivityBar.tsx +17 -0
  252. package/src/react/analytics/index.ts +1 -1
  253. package/src/react/chat/MessageComposer.tsx +5 -4
  254. package/src/react/components/Button.tsx +3 -2
  255. package/src/react/components/Checkbox.spec.tsx +51 -0
  256. package/src/react/components/Checkbox.tsx +68 -26
  257. package/src/react/components/CodeArea.tsx +2 -1
  258. package/src/react/components/CodeChip.spec.tsx +2 -2
  259. package/src/react/components/Collapsible.tsx +2 -1
  260. package/src/react/components/ComboboxField.tsx +3 -2
  261. package/src/react/components/CopyButton.tsx +2 -1
  262. package/src/react/components/CopyableText.spec.tsx +1 -1
  263. package/src/react/components/DataTable/ColumnChecklist.tsx +2 -1
  264. package/src/react/components/DataTable/Pagination.tsx +2 -1
  265. package/src/react/components/DataTable/SortHeader.tsx +2 -1
  266. package/src/react/components/DataTable/{FilterBuilder.tsx → TableFilterBuilder.tsx} +33 -5
  267. package/src/react/components/DataTable/Toolbar.tsx +3 -3
  268. package/src/react/components/DataTable/cells/LinkCell.tsx +2 -1
  269. package/src/react/components/DataTable/index.ts +8 -1
  270. package/src/react/components/DragHandle.tsx +2 -1
  271. package/src/react/components/EmojiField.tsx +2 -1
  272. package/src/react/components/EventTimeline.tsx +3 -2
  273. package/src/react/components/FileLocation.spec.tsx +1 -1
  274. package/src/react/components/IconButton.tsx +1 -1
  275. package/src/react/components/InfoHint.tsx +5 -4
  276. package/src/react/components/InheritBadge.tsx +1 -1
  277. package/src/react/components/InlineEditableText.tsx +2 -1
  278. package/src/react/components/MeterList.tsx +2 -1
  279. package/src/react/components/PathText.tsx +4 -3
  280. package/src/react/components/RatingField.tsx +2 -1
  281. package/src/react/components/SecretInput.tsx +3 -3
  282. package/src/react/components/SegmentedControl.tsx +2 -2
  283. package/src/react/components/StarRating.spec.tsx +2 -2
  284. package/src/react/components/StarRating.tsx +9 -5
  285. package/src/react/components/StatStrip.tsx +2 -1
  286. package/src/react/components/StatTile.tsx +3 -3
  287. package/src/react/components/Tabs.spec.tsx +3 -2
  288. package/src/react/components/Tabs.tsx +2 -1
  289. package/src/react/components/TruncatedText.tsx +2 -1
  290. package/src/react/components/calendar/MonthGrid.spec.tsx +2 -1
  291. package/src/react/components/calendar/MonthGrid.tsx +2 -1
  292. package/src/react/components/calendar/WeekView.tsx +2 -1
  293. package/src/react/components/revealOnHover.ts +3 -2
  294. package/src/react/file-tree/FileTree.spec.tsx +248 -0
  295. package/src/react/file-tree/FileTree.tsx +304 -4
  296. package/src/react/file-tree/fileTree.css +52 -0
  297. package/src/react/file-tree/fileTreeGeometry.fixture.json +151 -0
  298. package/src/react/file-tree/fileTreeGeometry.spec.ts +33 -52
  299. package/src/react/filter-rail/FilterRail.spec.tsx +2 -1
  300. package/src/react/filter-rail/FilterRail.tsx +5 -4
  301. package/src/react/folder-tree/FolderTreeRail.tsx +2 -1
  302. package/src/react/index.ts +13 -3
  303. package/src/react/layoutEngine/index.ts +1 -1
  304. package/src/react/layoutEngine/types.ts +1 -1
  305. package/src/react/lib/field.ts +4 -2
  306. package/src/react/lib/floatingStyles.spec.ts +2 -1
  307. package/src/react/lib/floatingStyles.ts +3 -1
  308. package/src/react/lib/tapTarget.ts +100 -0
  309. package/src/react/media/MaskPainter.tsx +2 -2
  310. package/src/react/media/VideoTrimmer.tsx +1 -1
  311. package/src/react/media/denseGallery.css +3 -3
  312. package/src/react/media/ffmpegWasm.ts +2 -2
  313. package/src/react/media/videoPlayer.css +42 -0
  314. package/src/react/namespace/NamespaceTargetCapsule.tsx +2 -2
  315. package/src/react/nav/BreadcrumbTrail.tsx +4 -3
  316. package/src/react/nav/HubTileGrid.tsx +2 -1
  317. package/src/react/nav/SideNav.tsx +4 -3
  318. package/src/react/nav/SideNavCustomize.tsx +2 -1
  319. package/src/react/palette/CommandPalette.tsx +3 -2
  320. package/src/server/ctgr.ts +1 -1
  321. package/src/server/drivers/pooledControlStores.pg.test.ts +1 -0
  322. package/src/server/drivers/pooledIdentityStore.pg.test.ts +1 -0
  323. package/src/server/drivers/retentionPolicy.pg.test.ts +1 -0
  324. package/src/server/guard/argon2Binding.ts +1 -1
  325. package/src/server/incidents/store.ts +3 -3
  326. package/src/server/index.ts +1 -1
  327. package/src/server/master-lock/masterLock.spec.ts +18 -2
  328. package/src/server/master-lock/masterLock.ts +1 -1
  329. package/src/server/media-bun/image.spec.ts +1 -0
  330. package/src/server/media-bun/index.ts +1 -1
  331. package/src/server/media-bun/video.spec.ts +1 -0
  332. package/src/server/paths/appDataHome.spec.ts +87 -0
  333. package/src/server/paths/appDataHome.ts +84 -0
  334. package/src/server/retention/archive.spec.ts +26 -4
  335. package/src/server/retention/archive.ts +20 -15
  336. package/src/server/retention/index.ts +1 -1
  337. package/src/server/retention/policy.ts +2 -2
  338. package/src/server/retention/store.spec.ts +38 -10
  339. package/src/server/retention/store.ts +26 -19
  340. package/src/server/runtime/localHost.spec.ts +22 -3
  341. package/src/server/runtime/localHost.ts +12 -9
  342. package/src/server/runtime/meterRollup.pg.test.ts +1 -0
  343. package/src/server/runtime/recipe.ts +4 -4
  344. package/src/server/runtime/retentionJob.pg.test.ts +1 -0
  345. package/src/server/search/pgSearchProvider.pg.test.ts +1 -0
  346. package/src/server/storage/binaryServerProcessing.integration.spec.ts +6 -2
  347. package/src/server/storage/chunked.integration.spec.ts +5 -2
  348. package/src/server/storage/fileUploadClient-chunked.integration.spec.ts +5 -2
  349. package/src/server/storage/files/adapter.photo.display.spec.ts +1 -0
  350. package/src/server/storage/imageThumbnail.spec.ts +1 -0
  351. package/src/server/storage/transcode.integration.spec.ts +5 -2
  352. package/src/server/storage/videoProcessor.posterOnly.spec.ts +1 -0
  353. package/src/shared/errors.ts +1 -1
  354. package/src/skippedTestsAreAnswered.spec.ts +215 -0
  355. package/src/styles-static.css +413 -0
  356. package/src/styles-utilities.css +5074 -0
  357. package/src/styles.css +49 -0
  358. package/src/stylesStaticMatches.spec.ts +134 -0
  359. package/src/stylesUtilitiesMatches.spec.ts +314 -0
  360. package/src/tapTargetStylesheet.spec.ts +150 -0
  361. package/src/testTmpRoot.spec.ts +102 -0
  362. package/dist/core/duplicates/index.d.ts +0 -116
  363. package/dist/core/duplicates/index.d.ts.map +0 -1
  364. package/dist/core/duplicates/index.js +0 -178
  365. package/dist/core/duplicates/index.js.map +0 -1
  366. package/dist/core/namespace/helpers.d.ts +0 -14
  367. package/dist/core/namespace/helpers.d.ts.map +0 -1
  368. package/dist/core/namespace/helpers.js +0 -29
  369. package/dist/core/namespace/helpers.js.map +0 -1
  370. package/dist/core/namespace/index.d.ts +0 -4
  371. package/dist/core/namespace/index.d.ts.map +0 -1
  372. package/dist/core/namespace/index.js +0 -6
  373. package/dist/core/namespace/index.js.map +0 -1
  374. package/dist/core/namespace/memoryStore.d.ts +0 -19
  375. package/dist/core/namespace/memoryStore.d.ts.map +0 -1
  376. package/dist/core/namespace/memoryStore.js +0 -70
  377. package/dist/core/namespace/memoryStore.js.map +0 -1
  378. package/dist/core/namespace/types.d.ts +0 -44
  379. package/dist/core/namespace/types.d.ts.map +0 -1
  380. package/dist/core/namespace/types.js +0 -8
  381. package/dist/core/namespace/types.js.map +0 -1
  382. package/dist/game/core/DisposeRegistry.d.ts +0 -42
  383. package/dist/game/core/DisposeRegistry.d.ts.map +0 -1
  384. package/dist/game/core/DisposeRegistry.js +0 -67
  385. package/dist/game/core/DisposeRegistry.js.map +0 -1
  386. package/dist/game/core/drawBudget.d.ts +0 -26
  387. package/dist/game/core/drawBudget.d.ts.map +0 -1
  388. package/dist/game/core/drawBudget.js +0 -55
  389. package/dist/game/core/drawBudget.js.map +0 -1
  390. package/dist/game/core/fixedTimestep.d.ts +0 -38
  391. package/dist/game/core/fixedTimestep.d.ts.map +0 -1
  392. package/dist/game/core/fixedTimestep.js +0 -47
  393. package/dist/game/core/fixedTimestep.js.map +0 -1
  394. package/dist/game/core/index.d.ts +0 -9
  395. package/dist/game/core/index.d.ts.map +0 -1
  396. package/dist/game/core/index.js +0 -8
  397. package/dist/game/core/index.js.map +0 -1
  398. package/dist/game/core/inputCollector.d.ts +0 -82
  399. package/dist/game/core/inputCollector.d.ts.map +0 -1
  400. package/dist/game/core/inputCollector.js +0 -176
  401. package/dist/game/core/inputCollector.js.map +0 -1
  402. package/dist/game/core/resizeCanvas.d.ts +0 -19
  403. package/dist/game/core/resizeCanvas.d.ts.map +0 -1
  404. package/dist/game/core/resizeCanvas.js +0 -29
  405. package/dist/game/core/resizeCanvas.js.map +0 -1
  406. package/dist/game/react/index.d.ts +0 -3
  407. package/dist/game/react/index.d.ts.map +0 -1
  408. package/dist/game/react/index.js +0 -5
  409. package/dist/game/react/index.js.map +0 -1
  410. package/dist/game/react/useGameEngine.d.ts +0 -64
  411. package/dist/game/react/useGameEngine.d.ts.map +0 -1
  412. package/dist/game/react/useGameEngine.js +0 -78
  413. package/dist/game/react/useGameEngine.js.map +0 -1
  414. package/dist/react/canvas/CanvasNavHUD.d.ts +0 -64
  415. package/dist/react/canvas/CanvasNavHUD.d.ts.map +0 -1
  416. package/dist/react/canvas/CanvasNavHUD.js +0 -58
  417. package/dist/react/canvas/CanvasNavHUD.js.map +0 -1
  418. package/dist/react/canvas/fitLabel.d.ts +0 -53
  419. package/dist/react/canvas/fitLabel.d.ts.map +0 -1
  420. package/dist/react/canvas/fitLabel.js +0 -104
  421. package/dist/react/canvas/fitLabel.js.map +0 -1
  422. package/dist/react/canvas/index.d.ts +0 -4
  423. package/dist/react/canvas/index.d.ts.map +0 -1
  424. package/dist/react/canvas/index.js +0 -4
  425. package/dist/react/canvas/index.js.map +0 -1
  426. package/dist/react/canvas/lod.d.ts +0 -40
  427. package/dist/react/canvas/lod.d.ts.map +0 -1
  428. package/dist/react/canvas/lod.js +0 -37
  429. package/dist/react/canvas/lod.js.map +0 -1
  430. package/dist/react/components/DataTable/FilterBuilder.d.ts +0 -38
  431. package/dist/react/components/DataTable/FilterBuilder.d.ts.map +0 -1
  432. package/dist/react/components/DataTable/FilterBuilder.js.map +0 -1
  433. package/dist/react/seo/HeadProvider.d.ts +0 -14
  434. package/dist/react/seo/HeadProvider.d.ts.map +0 -1
  435. package/dist/react/seo/HeadProvider.js +0 -44
  436. package/dist/react/seo/HeadProvider.js.map +0 -1
  437. package/dist/react/seo/applyHeadToDocument.d.ts +0 -3
  438. package/dist/react/seo/applyHeadToDocument.d.ts.map +0 -1
  439. package/dist/react/seo/applyHeadToDocument.js +0 -66
  440. package/dist/react/seo/applyHeadToDocument.js.map +0 -1
  441. package/dist/react/seo/index.d.ts +0 -3
  442. package/dist/react/seo/index.d.ts.map +0 -1
  443. package/dist/react/seo/index.js +0 -7
  444. package/dist/react/seo/index.js.map +0 -1
  445. package/dist/react/timeline/ClipView.d.ts +0 -29
  446. package/dist/react/timeline/ClipView.d.ts.map +0 -1
  447. package/dist/react/timeline/ClipView.js +0 -53
  448. package/dist/react/timeline/ClipView.js.map +0 -1
  449. package/dist/react/timeline/Playhead.d.ts +0 -16
  450. package/dist/react/timeline/Playhead.d.ts.map +0 -1
  451. package/dist/react/timeline/Playhead.js +0 -26
  452. package/dist/react/timeline/Playhead.js.map +0 -1
  453. package/dist/react/timeline/TimeRuler.d.ts +0 -21
  454. package/dist/react/timeline/TimeRuler.d.ts.map +0 -1
  455. package/dist/react/timeline/TimeRuler.js +0 -31
  456. package/dist/react/timeline/TimeRuler.js.map +0 -1
  457. package/dist/react/timeline/TimelineSurface.d.ts +0 -29
  458. package/dist/react/timeline/TimelineSurface.d.ts.map +0 -1
  459. package/dist/react/timeline/TimelineSurface.js +0 -56
  460. package/dist/react/timeline/TimelineSurface.js.map +0 -1
  461. package/dist/react/timeline/TrackLane.d.ts +0 -31
  462. package/dist/react/timeline/TrackLane.d.ts.map +0 -1
  463. package/dist/react/timeline/TrackLane.js +0 -32
  464. package/dist/react/timeline/TrackLane.js.map +0 -1
  465. package/dist/react/timeline/index.d.ts +0 -6
  466. package/dist/react/timeline/index.d.ts.map +0 -1
  467. package/dist/react/timeline/index.js +0 -12
  468. package/dist/react/timeline/index.js.map +0 -1
  469. package/dist/server/private-media/index.d.ts +0 -7
  470. package/dist/server/private-media/index.d.ts.map +0 -1
  471. package/dist/server/private-media/index.js +0 -13
  472. package/dist/server/private-media/index.js.map +0 -1
  473. package/dist/server/seo/index.d.ts +0 -3
  474. package/dist/server/seo/index.d.ts.map +0 -1
  475. package/dist/server/seo/index.js +0 -6
  476. package/dist/server/seo/index.js.map +0 -1
  477. package/dist/server/seo/mountSeoRoutes.d.ts +0 -9
  478. package/dist/server/seo/mountSeoRoutes.d.ts.map +0 -1
  479. package/dist/server/seo/mountSeoRoutes.js +0 -19
  480. package/dist/server/seo/mountSeoRoutes.js.map +0 -1
  481. package/dist/server/seo/serveHeadInjectedIndex.d.ts +0 -9
  482. package/dist/server/seo/serveHeadInjectedIndex.d.ts.map +0 -1
  483. package/dist/server/seo/serveHeadInjectedIndex.js +0 -20
  484. package/dist/server/seo/serveHeadInjectedIndex.js.map +0 -1
  485. package/dist/upload.d.ts +0 -148
  486. package/dist/upload.d.ts.map +0 -1
  487. package/dist/upload.js +0 -159
  488. package/dist/upload.js.map +0 -1
  489. package/dist/verify/runtime/index.d.ts +0 -16
  490. package/dist/verify/runtime/index.d.ts.map +0 -1
  491. package/dist/verify/runtime/index.js +0 -16
  492. package/dist/verify/runtime/index.js.map +0 -1
  493. package/scripts/demoCheck.ts +0 -42
  494. package/src/core/duplicates/index.spec.ts +0 -116
  495. package/src/core/duplicates/index.ts +0 -203
  496. package/src/core/namespace/helpers.ts +0 -31
  497. package/src/core/namespace/index.ts +0 -12
  498. package/src/core/namespace/memoryStore.ts +0 -77
  499. package/src/core/namespace/namespace.spec.ts +0 -117
  500. package/src/core/namespace/types.ts +0 -53
  501. package/src/game/core/DisposeRegistry.spec.ts +0 -53
  502. package/src/game/core/DisposeRegistry.ts +0 -70
  503. package/src/game/core/drawBudget.spec.ts +0 -51
  504. package/src/game/core/drawBudget.ts +0 -75
  505. package/src/game/core/fixedTimestep.spec.ts +0 -91
  506. package/src/game/core/fixedTimestep.ts +0 -79
  507. package/src/game/core/index.ts +0 -16
  508. package/src/game/core/inputCollector.spec.ts +0 -29
  509. package/src/game/core/inputCollector.ts +0 -245
  510. package/src/game/core/resizeCanvas.ts +0 -31
  511. package/src/game/react/index.ts +0 -10
  512. package/src/game/react/useGameEngine.ts +0 -125
  513. package/src/react/canvas/CanvasNavHUD.spec.tsx +0 -62
  514. package/src/react/canvas/CanvasNavHUD.tsx +0 -210
  515. package/src/react/canvas/fitLabel.spec.ts +0 -82
  516. package/src/react/canvas/fitLabel.ts +0 -150
  517. package/src/react/canvas/index.ts +0 -15
  518. package/src/react/canvas/lod.ts +0 -53
  519. package/src/react/seo/HeadProvider.tsx +0 -67
  520. package/src/react/seo/applyHeadToDocument.ts +0 -73
  521. package/src/react/seo/index.ts +0 -12
  522. package/src/react/seo/seo.spec.tsx +0 -101
  523. package/src/react/timeline/ClipView.tsx +0 -146
  524. package/src/react/timeline/Playhead.tsx +0 -63
  525. package/src/react/timeline/TimeRuler.tsx +0 -85
  526. package/src/react/timeline/TimelineSurface.tsx +0 -157
  527. package/src/react/timeline/TrackLane.tsx +0 -87
  528. package/src/react/timeline/index.ts +0 -12
  529. package/src/react/timeline/timeline.spec.tsx +0 -175
  530. package/src/server/private-media/index.ts +0 -45
  531. package/src/server/seo/index.ts +0 -8
  532. package/src/server/seo/mountSeoRoutes.ts +0 -37
  533. package/src/server/seo/seo.spec.ts +0 -128
  534. package/src/server/seo/serveHeadInjectedIndex.ts +0 -36
  535. package/src/upload.spec.ts +0 -300
  536. package/src/upload.ts +0 -288
  537. package/src/verify/runtime/index.ts +0 -64
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Generate `src/styles-utilities.css` — cursedbelt's component utilities, PRECOMPILED.
3
+ *
4
+ * ── The hole this fills ─────────────────────────────────────────────────────
5
+ * `src/styles-static.css` (the sibling generator, `generateStaticStyles.ts`) is
6
+ * `styles.css` minus its `@source "."`. It was shipped for "an app that pays for
7
+ * its own scanning" — and until this file existed, no app could pay. Tailwind v4
8
+ * (4.3.3, measured) resolves every `@source` to a DIRECTORY and scans it
9
+ * recursively: a file path is silently widened to its parent, a glob is widened
10
+ * the same way, and `@source not` over a package's own tree subtracts nothing.
11
+ * All four of these emit byte-for-byte identical CSS in a consuming app:
12
+ *
13
+ * @source ".../cursedbelt/src/react/index.*";
14
+ * @source ".../cursedbelt/src/react/styling.*";
15
+ * @source ".../cursedbelt/src/react/Virtual*.tsx";
16
+ * @source ".../cursedbelt/src/react/*.{ts,tsx}";
17
+ *
18
+ * `VirtualList` and `VirtualCardGrid` sit at the ROOT of `src/react/`, so the
19
+ * finest grain an app can ask for is that directory — whose recursive contents
20
+ * are the whole design system. Scanning it is the union; not scanning it is an
21
+ * UNSTYLED app. There was no third option, which made `styles-static.css` as
22
+ * published a subpath with no correct use. (It also retires a long-standing
23
+ * misreading: the previous generation's hand-written 29-line `@source` list in
24
+ * `satellite-kit` was never file-level scoping — every line was widened to its
25
+ * parent directory, which is why that arrangement still emitted ~113 KB.)
26
+ *
27
+ * So the utilities become a BUILD ARTIFACT: compiled once, here, and shipped.
28
+ * The consumer scans nothing.
29
+ *
30
+ * ── What it is worth, measured, so nobody re-runs this blind ────────────────
31
+ * 🔴 It is NOT smaller. Compiling cursedbelt's own surface both ways (this repo,
32
+ * tailwindcss 4.3.3, lightningcss-minified):
33
+ *
34
+ * @import "cursedbelt/styles.css" 131,795 B · 22,490 gz
35
+ * styles-static.css + styles-utilities.css 131,741 B · 22,462 gz
36
+ *
37
+ * — a 54-byte difference, i.e. the same stylesheet by another route. The union
38
+ * is the union however it is assembled. The 10.3 kB gzip saving flix measured
39
+ * came from scanning exactly the 29 modules Rollup put in its chunk, and that is
40
+ * per-app tree-shaking, which no single shared artifact can do. What this DOES
41
+ * buy: `styles-static.css` gains a correct use, a consuming app stops reaching
42
+ * into another package's source tree from its CSS (a `file:` dependency wearing
43
+ * a stylesheet's clothes), and the app's Tailwind build stops walking 827 files
44
+ * it does not own. Reaching the 16 KB-of-utilities floor flix measured needs
45
+ * per-module CSS the bundler can tree-shake — a different, larger change.
46
+ *
47
+ * ── Why GENERATED, and what holds it honest ─────────────────────────────────
48
+ * Same bargain as `styles-static.css`: this script writes it, `bun run build`
49
+ * runs this script, and `src/stylesUtilitiesMatches.spec.ts` fails when what is
50
+ * on disk is not what `src/react/**` currently produces. That spec does not
51
+ * compare SIZE — an unstyled app is invisible to a byte count read in one
52
+ * direction — it compiles a consumer both ways and compares the emitted rules.
53
+ *
54
+ * Usage:
55
+ * bun run styles:utilities # write src/styles-utilities.css
56
+ * bun run styles:utilities --check # exit 1 if it is stale, write nothing
57
+ */
58
+ import { compile } from '@tailwindcss/node';
59
+ import { Scanner } from '@tailwindcss/oxide';
60
+ import { REPO_ROOT, STATIC_STYLESHEET, readStylesheets } from './generateStaticStyles';
61
+
62
+ export { REPO_ROOT };
63
+
64
+ export const UTILITY_STYLESHEET = 'src/styles-utilities.css';
65
+
66
+ /** Every relative specifier below resolves against `src/`, like `styles.css` does. */
67
+ export const STYLES_BASE = `${REPO_ROOT}/src`;
68
+
69
+ /**
70
+ * The compile input.
71
+ *
72
+ * `@reference` rather than `@import` for the two cursedbelt stylesheets: it makes
73
+ * their `@theme` tokens, `@custom-variant dark` and `tw-animate-css`'s `@utility`
74
+ * definitions available to the compiler while emitting NONE of their CSS — the
75
+ * consumer imports those files itself, and duplicating them here would be the
76
+ * drift this whole arrangement exists to prevent. Dropping the
77
+ * `@reference "./styles-static.css"` line costs 41 rules: every `animate-in` /
78
+ * `fade-out` / `slide-in-from-*` / `data-[state=open]:*` utility the dialog,
79
+ * tooltip and collapsible families animate with, plus
80
+ * `.animate-progress-indeterminate`.
81
+ *
82
+ * `./react` and not `.`: `.` would scan `src/` — including this file's own output,
83
+ * making each generation depend on the last one. It buys nothing anyway; the whole
84
+ * of `src/` outside `src/react` adds 32 bytes.
85
+ */
86
+ export const UTILITY_INPUT = `@layer theme, base, components, utilities;
87
+ @import "tailwindcss/theme.css" layer(theme);
88
+ @reference "./styles-static.css";
89
+ @reference "./theme.css";
90
+ @import "tailwindcss/utilities.css" layer(utilities);
91
+ @source "./react";
92
+ `;
93
+
94
+ /**
95
+ * What a consuming app's CSS is, today and after adoption — the two inputs
96
+ * `src/stylesUtilitiesMatches.spec.ts` compiles and compares rule by rule.
97
+ *
98
+ * `source(none)` on the second one is the point of the exercise: it forbids
99
+ * Tailwind from scanning anything at all, so whatever comes out is what the
100
+ * precompiled artifact supplies and nothing else. A real app drops it and keeps
101
+ * scanning its OWN sources.
102
+ */
103
+ export const CONSUMER_SCANNING = '@import "tailwindcss";\n@import "./styles.css";\n@import "./theme.css";\n';
104
+ export const CONSUMER_PRECOMPILED =
105
+ '@import "tailwindcss" source(none);\n' +
106
+ '@import "./styles-static.css";\n' +
107
+ '@import "./styles-utilities.css";\n' +
108
+ '@import "./theme.css";\n';
109
+
110
+ /**
111
+ * A floor on the scan, because the failure this artifact can have is SILENT.
112
+ * If `src/react` moves, or a `.gitignore` starts swallowing it, or oxide's walk
113
+ * returns nothing, the compile still succeeds — it just emits an empty utility
114
+ * layer, and every consumer ships an unstyled app. 16,594 candidates today; this
115
+ * is a collapse tripwire, not a ratchet.
116
+ */
117
+ export const MIN_CANDIDATES = 1_000;
118
+
119
+ /** cursedbelt's stylesheets are self-contained — nothing here loads a JS config. */
120
+ const noDependency = (): void => {};
121
+
122
+ /** Compile one of the inputs above against `src/`. */
123
+ export const compileStylesheet = (
124
+ input: string,
125
+ ): ReturnType<typeof compile> => compile(input, { base: STYLES_BASE, onDependency: noDependency });
126
+
127
+ /** The banner the artifact carries, so a reader never mistakes it for a source file. */
128
+ export const BANNER = `/*
129
+ * cursedbelt component utilities — GENERATED BUILD ARTIFACT. Never hand-edit.
130
+ *
131
+ * Every Tailwind utility class cursedbelt's own components (\`src/react/**\`) use,
132
+ * compiled once at this package's build time so a consuming app does not have to
133
+ * scan this package's source tree — which Tailwind v4 cannot do at any grain
134
+ * finer than "the whole design system" anyway. Import it after Tailwind itself,
135
+ * beside the static entry point:
136
+ *
137
+ * @import "tailwindcss";
138
+ * @import "cursedbelt/styles-static.css";
139
+ * @import "cursedbelt/styles-utilities.css";
140
+ * @import "cursedbelt/theme.css";
141
+ *
142
+ * That pair emits the same rules as \`@import "cursedbelt/styles.css"\` — proved
143
+ * rule by rule, not by byte count, in src/stylesUtilitiesMatches.spec.ts. It is
144
+ * not SMALLER; see the header of scripts/generateUtilityStyles.ts for the
145
+ * measurements and for what it does buy.
146
+ *
147
+ * Written by scripts/generateUtilityStyles.ts (\`bun run styles:utilities\`),
148
+ * which \`bun run build\` runs. src/stylesUtilitiesMatches.spec.ts fails when what
149
+ * is on disk is not what src/react/** currently produces.
150
+ */
151
+ `;
152
+
153
+ /**
154
+ * Compile the utility layer from `src/react/**`.
155
+ *
156
+ * Refuses to run against a stale `styles-static.css`, rather than quietly baking
157
+ * the stale one's tokens in: the two artifacts are generated from the same
158
+ * `styles.css`, and `bun run build` orders them, but `bun run styles:utilities`
159
+ * on its own would not.
160
+ */
161
+ export const buildUtilityStyles = async (): Promise<{ css: string; candidates: string[] }> => {
162
+ const { expected, onDisk } = await readStylesheets();
163
+ if (onDisk !== expected) {
164
+ throw new Error(
165
+ `${STATIC_STYLESHEET} is ${onDisk === null ? 'missing' : 'stale'}, and this artifact is compiled\n` +
166
+ `against it (\`@reference\`), so it would bake in the wrong tokens. Run:\n` +
167
+ ` cd ${REPO_ROOT} && bun run styles:static`,
168
+ );
169
+ }
170
+ const compiled = await compileStylesheet(UTILITY_INPUT);
171
+ const candidates = new Scanner({ sources: compiled.sources }).scan();
172
+ if (candidates.length < MIN_CANDIDATES) {
173
+ throw new Error(
174
+ `the scan of src/react found ${candidates.length} candidates (floor ${MIN_CANDIDATES}).\n` +
175
+ 'That is a collapsed scan, not a small design system — the artifact it would write\n' +
176
+ 'emits an empty utility layer and every consuming app ships UNSTYLED. Check that\n' +
177
+ `${STYLES_BASE}/react exists and is not excluded by a .gitignore.`,
178
+ );
179
+ }
180
+ return { css: `${BANNER}${compiled.build(candidates)}`, candidates };
181
+ };
182
+
183
+ /** The artifact's expected contents and what is on disk right now. */
184
+ export const readUtilityStylesheet = async (): Promise<{
185
+ expected: string;
186
+ onDisk: string | null;
187
+ candidates: string[];
188
+ }> => {
189
+ const { css, candidates } = await buildUtilityStyles();
190
+ const target = Bun.file(`${REPO_ROOT}/${UTILITY_STYLESHEET}`);
191
+ return { expected: css, onDisk: (await target.exists()) ? await target.text() : null, candidates };
192
+ };
193
+
194
+ if (import.meta.main) {
195
+ const { expected, onDisk, candidates } = await readUtilityStylesheet();
196
+ if (process.argv.includes('--check')) {
197
+ if (onDisk === expected) {
198
+ console.log(`✅ ${UTILITY_STYLESHEET} is current (${candidates.length} candidates).`);
199
+ process.exit(0);
200
+ }
201
+ console.error(
202
+ `❌ ${UTILITY_STYLESHEET} is ${onDisk === null ? 'missing' : 'stale'}. Run:\n` +
203
+ ` cd ${REPO_ROOT} && bun run styles:utilities`,
204
+ );
205
+ process.exit(1);
206
+ }
207
+ if (onDisk === expected) {
208
+ console.log(`✅ ${UTILITY_STYLESHEET} already current (${candidates.length} candidates).`);
209
+ } else {
210
+ await Bun.write(`${REPO_ROOT}/${UTILITY_STYLESHEET}`, expected);
211
+ console.log(
212
+ `✅ wrote ${UTILITY_STYLESHEET} — ${candidates.length} candidates scanned from src/react.`,
213
+ );
214
+ }
215
+ }
@@ -0,0 +1,455 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * `bun scripts/publicSurface.ts [--prune]` — refuse a public surface that grows
4
+ * without a recorded reason.
5
+ *
6
+ * ## What this exists for
7
+ *
8
+ * Measured 2026-09-13 across all 845 consumer files on this machine that mention
9
+ * `cursedbelt`: `1.0.0` published **108 export subpaths and 3,359 exported
10
+ * symbols**, of which every consumer together imported **406 — 12.1%**.
11
+ * `cursedbelt/react` alone exposed 1,037 and 178 were used. Nothing objected at
12
+ * any single step, because no single step was large; the owner's own account of
13
+ * how it got there is *"worked on over many projects with tons of features
14
+ * changing"*.
15
+ *
16
+ * 🔴 **This is NOT a dead-code check, and 12.1% is not a bug to delete.** Most of
17
+ * that surface is alive: the `react` barrel re-exports components that live
18
+ * imports keep mounted, and a design system is SUPPOSED to ship more than any one
19
+ * app has adopted. Deleting everything safely deletable removed 4% of the package
20
+ * (tasks 32/33). What was missing was not restraint, it was an INSTRUMENT — the
21
+ * total was never measured anywhere, so growth was invisible at the only moment
22
+ * anyone could have judged it. This file makes growth visible and deliberate; it
23
+ * does not forbid it.
24
+ *
25
+ * Both rows below are a DATED RECORD, not a live claim — the live number is
26
+ * `publicSurface.baseline`, checked against the tree every run, and it can only
27
+ * go down from the second row:
28
+ *
29
+ * subpaths symbols dependencies peers
30
+ * 1.0.0, before tasks 32/33 108 4,167 47 51
31
+ * seeded 2026-09-13 85 3,808 44 47
32
+ *
33
+ * 🔴 Both rows were measured by THIS file, run against `c01b119` and against the
34
+ * tree it was seeded from, so they are commensurable with each other and with
35
+ * every future run. They are NOT the 3,359 in the task that asked for this file:
36
+ * that number came from an independent walk of the same shape, and this one counts
37
+ * 4,167 for the same tree. The gap is method, not surface — a `default` export,
38
+ * a destructured `export const {a, b}`, and a bare `export * from 'cwip/layout'`
39
+ * are each counted here and were not counted there. Which is the point of the
40
+ * "What it counts, exactly" section below: two numbers that do not say what they
41
+ * counted cannot be compared, and only one of them can be a ratchet.
42
+ *
43
+ * `subpaths` excludes the three stylesheet exports, which have no symbols; the
44
+ * `exports` map has three more keys than the count above. The dependency columns
45
+ * are the second half of the same failure and are asserted by
46
+ * `src/declaredDepsAreImported.spec.ts` — see "The dependency half" below.
47
+ *
48
+ * This file is the reason that second row cannot quietly become the first one
49
+ * again: **document the WHY; automate the WHETHER.** A paragraph in a doc asking
50
+ * the next agent to think about whether a new subpath is needed is the failure
51
+ * mode, not the fix.
52
+ *
53
+ * ## The ratchet
54
+ *
55
+ * `publicSurface.baseline` holds a COUNT PER SUBPATH, the same shape as
56
+ * `tools/check-paths.baseline`, which is the mechanism this generation already
57
+ * trusts. Four ways to fail, and the last two are what make it a ratchet rather
58
+ * than a high-water mark:
59
+ *
60
+ * 1. a subpath in `exports` that the baseline does not list → NEW SURFACE
61
+ * 2. a listed subpath whose symbol count went UP → GREW
62
+ * 3. a listed subpath whose count went DOWN, or that is gone → run --prune
63
+ * 4. an entry matching no subpath at all → run --prune
64
+ *
65
+ * (3) and (4) mean a deleted module cannot leave a stale allowance behind for the
66
+ * next module to grow into. Inherited surface can only fall.
67
+ *
68
+ * `--prune` records the burn-down in one deliberate command and REFUSES to raise
69
+ * anything, so a genuine new export is `--prune`-then-review rather than a number
70
+ * edited by hand, and it shows up in the diff as surface.
71
+ *
72
+ * ## 🔴 What it counts, exactly — and what it does not
73
+ *
74
+ * A count is only worth having if it says what it counted; a count that silently
75
+ * measures less than it claims is a guess wearing a measurement's clothes. This
76
+ * walks, per export subpath in `package.json`, the TypeScript AST of the entry
77
+ * module and every `export * from` beneath it, transitively, deduped by name:
78
+ *
79
+ * · `export const/let/var/function/class/interface/type/enum/namespace`
80
+ * · `export { x }`, `export { x as y }`, `export type { x }`
81
+ * · `export * as ns from './m'` (one symbol: `ns`)
82
+ * · `export default` / `export default function Foo` (one symbol: `default`)
83
+ * · `export * from './m'` (transitive; cycles are visited once)
84
+ * · `export * from 'some-package'` — RESOLVED and walked, not skipped. There is
85
+ * one today (`src/core/layout/index.ts` re-exports `cwip/layout`) and a
86
+ * package's symbols re-exported under this package's name are this package's
87
+ * surface. If such a specifier ever resolves to something this cannot parse
88
+ * (a `.js` build with no types), the run FAILS rather than counting zero.
89
+ *
90
+ * Deliberately NOT counted, each because counting it would make the number lie:
91
+ *
92
+ * · non-TS export targets — `./styles.css`, `./theme.css`, `./workspace.css`.
93
+ * A stylesheet has no symbols. They are reported as "asset export(s)" so they
94
+ * cannot vanish from the accounting.
95
+ * · anything not reachable from an `exports` subpath. Internal modules are not
96
+ * public surface. What `src/react/components/**` contains is not the measure;
97
+ * what the `./react` barrel re-exports is.
98
+ * · the two `bin` targets, `cc-verify` and `cc-promote`. 🔴 They ARE public
99
+ * surface — and they are NOT reachable through `exports`, which is exactly why
100
+ * an earlier reachability walk seeded from `exports` alone reported a shipped
101
+ * CLI as removable. A CLI's interface is its argv, not its export list, so
102
+ * counting its exported symbols would measure the wrong thing. Their SHAPE is
103
+ * already asserted by `src/publishShape.spec.ts` ("declares bin paths npm will
104
+ * actually keep"), and nothing here concludes anything is dead — this tool
105
+ * only ever compares `cursedbelt` to its own baseline.
106
+ *
107
+ * ## What this may NOT become
108
+ *
109
+ * · Not a usage check. It must never try to know who imports `cursedbelt`; that
110
+ * is cross-repo, and a repo's gate proves that repo.
111
+ * · Not a ban on growth. New surface is one hand-added line plus a commit
112
+ * message that says why — a reviewable moment, not a wall.
113
+ * · Not a second guard. One check, one baseline, entry criteria in this header.
114
+ *
115
+ * ## The dependency half
116
+ *
117
+ * 47 hard dependencies is the number that decides what a consumer pays, and it is
118
+ * surface by the same argument. It is NOT re-checked here, because it is already
119
+ * checked once: `src/declaredDepsAreImported.spec.ts` fails on any `dependencies`
120
+ * or `peerDependencies` entry that no file under `src/` or `scripts/` imports, and
121
+ * `src/noPathDeps.spec.ts` fails on a `file:`/`link:`/`workspace:`/`portal:` range
122
+ * in any dependency block. Two ratchets that disagree is the guard sprawl this
123
+ * generation is trying to avoid, so this file points at them instead of repeating
124
+ * them.
125
+ *
126
+ * 🔴 If you ever move that check here, keep the property that made it correct: it
127
+ * scans EVERY file type, not just `.ts`. `tw-animate-css` is imported from
128
+ * `src/styles.css` and a `.ts`-only scan calls it dead.
129
+ *
130
+ * Exit 1 on any failure, so it can sit in a verify chain. It sits in the suite
131
+ * instead — `src/publicSurface.spec.ts` — so `bun run verify` needs no new script
132
+ * and cannot be a script somebody forgot to chain.
133
+ */
134
+ import { dirname, join } from 'node:path';
135
+ import ts from 'typescript';
136
+
137
+ // Resolved from this file, never from `process.cwd()`: the suite imports it and
138
+ // `bun test` can be started from anywhere.
139
+ const ROOT = dirname(import.meta.dir);
140
+ const BASELINE = join(ROOT, 'publicSurface.baseline');
141
+
142
+ const DEFAULT_HEADER = [
143
+ '# Public surface of `cursedbelt`: one line per export subpath, `<exported symbols> <subpath>`.',
144
+ '#',
145
+ '# A CEILING, not an amnesty. The check fails on a subpath NOT listed here, on a listed',
146
+ '# subpath that gained a symbol, and on an entry that no longer matches `package.json`',
147
+ '# exports — so a deleted module cannot leave a stale allowance behind. Surface can only fall.',
148
+ '#',
149
+ '# To record a deliberate change: bun scripts/publicSurface.ts --prune',
150
+ '# It refuses to RAISE anything, so new surface is a reviewed diff, never a silent one.',
151
+ '#',
152
+ '# What a count includes, what it excludes and why, and the measurement this file is a',
153
+ '# ratchet against, are in the header of scripts/publicSurface.ts. Say nothing here that',
154
+ '# the entries below already say.',
155
+ ];
156
+
157
+ export type Surface = {
158
+ /** subpath (as written in `exports`) → deduped exported symbol count */
159
+ counts: Map<string, number>;
160
+ /** subpaths skipped because they resolve to a non-TS asset (the three stylesheets) */
161
+ assets: string[];
162
+ };
163
+
164
+ const isRelative = (spec: string): boolean => spec.startsWith('./') || spec.startsWith('../');
165
+ const isWalkable = (file: string): boolean => /\.(m|c)?tsx?$/.test(file);
166
+
167
+ /** `./a/b` from `src/x/y.tsx` → the first of `src/a/b.ts(x)`, `src/a/b/index.ts(x)`, … that exists. */
168
+ const resolveRelative = async (fromFile: string, spec: string): Promise<string | null> => {
169
+ const base = join(dirname(fromFile), spec);
170
+ const candidates = [`${base}.ts`, `${base}.tsx`, `${base}/index.ts`, `${base}/index.tsx`, base];
171
+ for (const c of candidates) {
172
+ if (await Bun.file(c).exists()) return c;
173
+ }
174
+ return null;
175
+ };
176
+
177
+ /**
178
+ * A bare `export * from 'pkg'` — resolved through node resolution so its symbols
179
+ * are counted rather than silently dropped. Throws when the package resolves to
180
+ * something with no parseable types, because a zero there would be a lie.
181
+ */
182
+ const resolveBare = (fromFile: string, spec: string): string => {
183
+ let resolved: string;
184
+ try {
185
+ resolved = Bun.resolveSync(spec, dirname(fromFile));
186
+ } catch (cause) {
187
+ throw new Error(
188
+ `${fromFile}: \`export * from '${spec}'\` re-exports a package that does not resolve, so its ` +
189
+ 'symbols cannot be counted. Install it, or name the symbols — do not let the count lie.',
190
+ { cause },
191
+ );
192
+ }
193
+ if (!isWalkable(resolved)) {
194
+ throw new Error(
195
+ `${fromFile}: \`export * from '${spec}'\` resolves to ${resolved}, which this measurement cannot ` +
196
+ 'parse. Point it at TypeScript, name the symbols, or teach scripts/publicSurface.ts to read ' +
197
+ 'a declaration bundle — do not let the count lie.',
198
+ );
199
+ }
200
+ return resolved;
201
+ };
202
+
203
+ // One parse per file, shared across all 88 subpaths: the barrels overlap heavily
204
+ // (every `./react/*` subpath re-parses a slice of what `./react` already walked).
205
+ const parsed = new Map<string, ts.SourceFile>();
206
+ const sourceOf = async (file: string): Promise<ts.SourceFile> => {
207
+ const hit = parsed.get(file);
208
+ if (hit !== undefined) return hit;
209
+ // 🔴 Bun.file, NOT node:fs — this package's test preload shares one process with
210
+ // specs that virtualize node:fs, so a readFileSync scan reads MOCK data and the
211
+ // measurement passes against files it never opened. Same trap as
212
+ // publishShape.spec.ts; see its header.
213
+ const source = ts.createSourceFile(file, await Bun.file(file).text(), ts.ScriptTarget.ES2022, true);
214
+ parsed.set(file, source);
215
+ return source;
216
+ };
217
+
218
+ /** Every name a binding pattern introduces — `export const { a, b: [c] } = …` is three. */
219
+ const bindingNames = (name: ts.BindingName, out: Set<string>): void => {
220
+ if (ts.isIdentifier(name)) {
221
+ out.add(name.text);
222
+ return;
223
+ }
224
+ for (const el of name.elements) {
225
+ if (ts.isBindingElement(el)) bindingNames(el.name, out);
226
+ }
227
+ };
228
+
229
+ /** Deduped exported names of `file`, following `export * from` chains. */
230
+ const exportedNames = async (file: string, seen = new Set<string>()): Promise<Set<string>> => {
231
+ const names = new Set<string>();
232
+ if (seen.has(file)) return names;
233
+ seen.add(file);
234
+
235
+ const source = await sourceOf(file);
236
+ const modifiersOf = (node: ts.Node): readonly ts.Modifier[] =>
237
+ ts.canHaveModifiers(node) ? (ts.getModifiers(node) ?? []) : [];
238
+
239
+ for (const st of source.statements) {
240
+ if (ts.isExportDeclaration(st)) {
241
+ if (st.exportClause && ts.isNamedExports(st.exportClause)) {
242
+ for (const el of st.exportClause.elements) names.add(el.name.text);
243
+ } else if (st.exportClause && ts.isNamespaceExport(st.exportClause)) {
244
+ names.add(st.exportClause.name.text);
245
+ } else {
246
+ const spec =
247
+ st.moduleSpecifier && ts.isStringLiteral(st.moduleSpecifier) ? st.moduleSpecifier.text : null;
248
+ if (spec === null) continue;
249
+ let target: string | null;
250
+ if (isRelative(spec)) {
251
+ target = await resolveRelative(file, spec);
252
+ if (target === null) throw new Error(`${file}: \`export * from '${spec}'\` resolves to nothing.`);
253
+ } else {
254
+ target = resolveBare(file, spec);
255
+ }
256
+ for (const n of await exportedNames(target, seen)) names.add(n);
257
+ }
258
+ continue;
259
+ }
260
+ if (ts.isExportAssignment(st)) {
261
+ names.add('default');
262
+ continue;
263
+ }
264
+ const modifiers = modifiersOf(st);
265
+ if (!modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword)) continue;
266
+ // `export default function Foo()` is imported as `default`, not as `Foo`.
267
+ if (modifiers.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword)) {
268
+ names.add('default');
269
+ continue;
270
+ }
271
+ if (ts.isVariableStatement(st)) {
272
+ for (const d of st.declarationList.declarations) bindingNames(d.name, names);
273
+ } else if (
274
+ (ts.isFunctionDeclaration(st) ||
275
+ ts.isClassDeclaration(st) ||
276
+ ts.isInterfaceDeclaration(st) ||
277
+ ts.isTypeAliasDeclaration(st) ||
278
+ ts.isEnumDeclaration(st) ||
279
+ ts.isModuleDeclaration(st)) &&
280
+ st.name !== undefined
281
+ ) {
282
+ if (ts.isIdentifier(st.name) || ts.isStringLiteral(st.name)) names.add(st.name.text);
283
+ }
284
+ }
285
+ return names;
286
+ };
287
+
288
+ /** The `./src/**` or `./scripts/**` TypeScript file a subpath resolves to, or null when it is an asset. */
289
+ const entryOf = (value: unknown): string | null => {
290
+ if (typeof value === 'string')
291
+ return (value.startsWith('./src/') || value.startsWith('./scripts/')) && isWalkable(value)
292
+ ? join(ROOT, value.slice(2))
293
+ : null;
294
+ if (typeof value !== 'object' || value === null) return null;
295
+ // `bun` and `source` are the conditions that point at TypeScript; `types` and
296
+ // `import` point into `dist`, which is build output and may not exist. Reading
297
+ // the conditions in this order is what makes the measurement work on a clean
298
+ // checkout, before `bun run build` has ever run.
299
+ for (const key of ['bun', 'source', 'types', 'import', 'default']) {
300
+ if (key in (value as Record<string, unknown>)) {
301
+ const hit = entryOf((value as Record<string, unknown>)[key]);
302
+ if (hit !== null) return hit;
303
+ }
304
+ }
305
+ for (const v of Object.values(value as Record<string, unknown>)) {
306
+ const hit = entryOf(v);
307
+ if (hit !== null) return hit;
308
+ }
309
+ return null;
310
+ };
311
+
312
+ export const measureSurface = async (pkg: { exports: Record<string, unknown> }): Promise<Surface> => {
313
+ const counts = new Map<string, number>();
314
+ const assets: string[] = [];
315
+ for (const [subpath, value] of Object.entries(pkg.exports)) {
316
+ const entry = entryOf(value);
317
+ if (entry === null) {
318
+ assets.push(subpath);
319
+ continue;
320
+ }
321
+ counts.set(subpath, (await exportedNames(entry)).size);
322
+ }
323
+ return { counts, assets };
324
+ };
325
+
326
+ // ── the baseline ────────────────────────────────────────────────────────────────
327
+
328
+ export type Baseline = { header: string[]; counts: Map<string, number> };
329
+
330
+ export const parseBaseline = (text: string): Baseline => {
331
+ const header = text.split('\n').filter((l) => l.startsWith('#'));
332
+ const counts = new Map<string, number>();
333
+ for (const line of text.split('\n')) {
334
+ if (!line.trim() || line.startsWith('#')) continue;
335
+ const m = line.match(/^\s*(\d+)\s+(\S.*)$/);
336
+ if (m?.[2] !== undefined) counts.set(m[2].trim(), Number(m[1]));
337
+ }
338
+ return { header: header.length > 0 ? header : DEFAULT_HEADER, counts };
339
+ };
340
+
341
+ export const readBaseline = async (): Promise<Baseline> => {
342
+ const f = Bun.file(BASELINE);
343
+ return parseBaseline((await f.exists()) ? await f.text() : '');
344
+ };
345
+
346
+ export const formatBaseline = (header: string[], counts: Map<string, number>): string =>
347
+ `${[...header, ...[...counts.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([k, n]) => `${n} ${k}`)].join(
348
+ '\n',
349
+ )}\n`;
350
+
351
+ export type Failures = { grown: string[]; fresh: string[]; stale: string[] };
352
+
353
+ export const compare = (surface: Surface, baseline: Baseline): Failures => {
354
+ const fresh: string[] = [];
355
+ const grown: string[] = [];
356
+ for (const [subpath, n] of surface.counts) {
357
+ const allowed = baseline.counts.get(subpath);
358
+ if (allowed === undefined) fresh.push(`${subpath} — NEW subpath, ${n} exported symbol(s)`);
359
+ else if (n > allowed) grown.push(`${subpath} — baseline allows ${allowed}, exports ${n} now`);
360
+ }
361
+ const stale = [...baseline.counts.entries()]
362
+ .filter(([subpath, n]) => (surface.counts.get(subpath) ?? 0) < n)
363
+ .map(([subpath, n]) =>
364
+ surface.counts.has(subpath)
365
+ ? `${subpath} — baseline says ${n}, exports ${surface.counts.get(subpath)}`
366
+ : `${subpath} — baseline says ${n}, the subpath is gone`,
367
+ );
368
+ return { fresh, grown, stale };
369
+ };
370
+
371
+ export const run = async (): Promise<Failures & { surface: Surface; baseline: Baseline }> => {
372
+ const pkg = (await Bun.file(join(ROOT, 'package.json')).json()) as { exports: Record<string, unknown> };
373
+ const surface = await measureSurface(pkg);
374
+ const baseline = await readBaseline();
375
+ return { ...compare(surface, baseline), surface, baseline };
376
+ };
377
+
378
+ // ── CLI ─────────────────────────────────────────────────────────────────────────
379
+
380
+ if (import.meta.main) {
381
+ const argv = process.argv.slice(2);
382
+ const prune = argv.includes('--prune');
383
+ const { fresh, grown, stale, surface, baseline } = await run();
384
+ const total = [...surface.counts.values()].reduce((a, b) => a + b, 0);
385
+
386
+ // `--seed` exists once, to record the surface the ratchet starts from. It REFUSES
387
+ // over an existing baseline, so re-seeding means deleting the file first — two
388
+ // visible steps and a whole-file diff, rather than one command that quietly
389
+ // re-baselines whatever grew.
390
+ if (argv.includes('--seed')) {
391
+ if (baseline.counts.size > 0) {
392
+ console.error(`publicSurface --seed refuses: ${BASELINE} already records ${baseline.counts.size} subpath(s).`);
393
+ console.error('Lower it with --prune. Raising it is a hand edit in a commit that says why.');
394
+ process.exit(1);
395
+ }
396
+ await Bun.write(BASELINE, formatBaseline(baseline.header, surface.counts));
397
+ console.log(`publicSurface: seeded ${surface.counts.size} subpath(s), ${total} exported symbol(s).`);
398
+ process.exit(0);
399
+ }
400
+
401
+ if (prune) {
402
+ // 🔴 It may only LOWER. Growth is the thing this file exists to make visible;
403
+ // a prune that could absorb it would be the disable switch.
404
+ if (fresh.length > 0 || grown.length > 0) {
405
+ console.error('publicSurface --prune refuses while the surface has GROWN — it may only lower the baseline.\n');
406
+ for (const v of [...fresh, ...grown]) console.error(` ${v}`);
407
+ console.error(
408
+ '\nTo record deliberate new surface, add the line by hand and say in the commit message why the\npackage needs it — that is the reviewable moment this check exists to create.\n',
409
+ );
410
+ process.exit(1);
411
+ }
412
+ const lowered = new Map<string, number>();
413
+ for (const [subpath, n] of baseline.counts) {
414
+ const now = surface.counts.get(subpath);
415
+ if (now !== undefined) lowered.set(subpath, Math.min(n, now));
416
+ }
417
+ await Bun.write(BASELINE, formatBaseline(baseline.header, lowered));
418
+ console.log(
419
+ `publicSurface: baseline pruned to ${lowered.size} subpath(s), ` +
420
+ `${baseline.counts.size - lowered.size} removed, ${[...lowered.values()].reduce((a, b) => a + b, 0)} symbols.`,
421
+ );
422
+ process.exit(0);
423
+ }
424
+
425
+ let bad = false;
426
+ const report = (label: string, lines: string[], advice: string): void => {
427
+ if (lines.length === 0) return;
428
+ bad = true;
429
+ console.error(`\n${lines.length} ${label}:\n`);
430
+ for (const l of lines) console.error(` ${l}`);
431
+ console.error(`\n${advice}\n`);
432
+ };
433
+ report(
434
+ 'export subpath(s) the baseline does not know',
435
+ fresh,
436
+ 'A new subpath is a permanent public promise. If it is genuinely wanted, add its line to\n' +
437
+ `${BASELINE} and say why in the commit message.`,
438
+ );
439
+ report(
440
+ 'subpath(s) that gained exported symbols',
441
+ grown,
442
+ 'A baseline entry is a ceiling. Raise it by hand, in a commit that says why.',
443
+ );
444
+ report(
445
+ 'baseline entr(y|ies) that no longer match `exports`',
446
+ stale,
447
+ `Surface came off and the ratchet was not tightened. Run:\n cd ${ROOT} && bun scripts/publicSurface.ts --prune`,
448
+ );
449
+ if (bad) process.exit(1);
450
+
451
+ console.log(
452
+ `publicSurface: ${surface.counts.size} subpath(s), ${total} exported symbol(s), ` +
453
+ `${surface.assets.length} asset export(s) — none grown.`,
454
+ );
455
+ }