@astryxdesign/cli 0.6.3 → 0.6.4-canary.078fd25

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 (728) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +152 -107
  3. package/api/blog/blog.doc.mjs +1 -0
  4. package/api/build/_adapter.d.mts +50 -0
  5. package/api/build/_adapter.mjs +60 -0
  6. package/api/build/build.doc.mjs +22 -10
  7. package/api/build/build.test.mjs +219 -8
  8. package/api/build/build.type.d.mts +91 -2
  9. package/api/build/build.type.mjs +52 -8
  10. package/api/build/help/help.d.mts +12 -5
  11. package/api/build/help/help.mjs +69 -6
  12. package/api/build/kit/kit.d.mts +4 -1
  13. package/api/build/kit/kit.mjs +208 -53
  14. package/api/build/kit/rank.d.mts +44 -0
  15. package/api/build/kit/rank.mjs +432 -0
  16. package/api/build/kit/rank.test.mjs +196 -0
  17. package/api/component/_adapter.d.mts +31 -12
  18. package/api/component/_adapter.mjs +79 -15
  19. package/api/component/component.d.mts +6 -3
  20. package/api/component/component.doc.mjs +49 -19
  21. package/api/component/component.mjs +339 -22
  22. package/api/component/component.test.mjs +38 -0
  23. package/api/component/component.type.d.mts +47 -11
  24. package/api/component/component.type.mjs +76 -24
  25. package/api/component/detail/blocks/blocks.d.mts +2 -1
  26. package/api/component/detail/blocks/blocks.mjs +4 -3
  27. package/api/component/list/list.d.mts +0 -5
  28. package/api/component/list/list.mjs +40 -11
  29. package/api/discover/_adapter.d.mts +114 -6
  30. package/api/discover/_adapter.mjs +372 -17
  31. package/api/discover/_adapter.test.mjs +215 -0
  32. package/api/discover/_catalog-view.d.mts +115 -0
  33. package/api/discover/_catalog-view.mjs +203 -0
  34. package/api/discover/_catalog-view.test.mjs +128 -0
  35. package/api/discover/detail/detail.d.mts +18 -6
  36. package/api/discover/detail/detail.mjs +67 -13
  37. package/api/discover/detail/detail.test.mjs +85 -0
  38. package/api/discover/detail/item/item.d.mts +26 -0
  39. package/api/discover/detail/item/item.mjs +78 -0
  40. package/api/discover/detail/item/item.test.mjs +73 -0
  41. package/api/discover/discover.d.mts +3 -9
  42. package/api/discover/discover.doc.mjs +62 -18
  43. package/api/discover/discover.mjs +220 -36
  44. package/api/discover/discover.test.mjs +11 -2
  45. package/api/discover/discover.type.d.mts +150 -11
  46. package/api/discover/discover.type.mjs +107 -17
  47. package/api/discover/list/list.d.mts +20 -6
  48. package/api/discover/list/list.mjs +45 -12
  49. package/api/discover/list/list.test.mjs +46 -0
  50. package/api/discover/search/search.d.mts +18 -16
  51. package/api/discover/search/search.mjs +102 -56
  52. package/api/discover/search/search.test.mjs +144 -10
  53. package/api/docs/_adapter.d.mts +277 -41
  54. package/api/docs/_adapter.mjs +993 -108
  55. package/api/docs/compiled-topics.test.mjs +78 -0
  56. package/api/docs/detail/detail.mjs +22 -63
  57. package/api/docs/detail/section/section.d.mts +1 -1
  58. package/api/docs/detail/section/section.mjs +54 -19
  59. package/api/docs/detail/section/section.test.mjs +50 -0
  60. package/api/docs/docOverlays.test.mjs +27 -1
  61. package/api/docs/docs.d.mts +10 -3
  62. package/api/docs/docs.doc.mjs +55 -16
  63. package/api/docs/docs.mjs +53 -10
  64. package/api/docs/docs.type.d.mts +221 -5
  65. package/api/docs/docs.type.mjs +153 -11
  66. package/api/docs/index/index.d.mts +18 -0
  67. package/api/docs/index/index.mjs +40 -0
  68. package/api/docs/index/index.test.mjs +62 -0
  69. package/api/docs/list/list.mjs +28 -12
  70. package/api/docs/node/node.d.mts +43 -0
  71. package/api/docs/node/node.mjs +192 -0
  72. package/api/docs/reference-blocks.test.mjs +406 -0
  73. package/api/doctor/doctor.d.mts +104 -1
  74. package/api/doctor/doctor.doc.mjs +18 -8
  75. package/api/doctor/doctor.mjs +635 -7
  76. package/api/doctor/doctor.test.mjs +732 -11
  77. package/api/doctor/doctor.type.d.mts +1 -1
  78. package/api/doctor/doctor.type.mjs +1 -1
  79. package/api/gap-report/gap-report.doc.mjs +27 -14
  80. package/api/hook/_adapter.mjs +19 -5
  81. package/api/hook/hook.doc.mjs +7 -3
  82. package/api/hook/hook.type.d.mts +3 -3
  83. package/api/hook/hook.type.mjs +11 -11
  84. package/api/hook/list/list.d.mts +2 -2
  85. package/api/hook/list/list.mjs +69 -17
  86. package/api/index.d.mts +2 -1
  87. package/api/index.mjs +6 -3
  88. package/api/init/init.doc.mjs +22 -12
  89. package/api/init/init.test.mjs +41 -1
  90. package/api/init/remove/remove.mjs +1 -1
  91. package/api/init/run/run.mjs +20 -10
  92. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  93. package/api/integration/add-contribution.d.mts +2 -1
  94. package/api/integration/add-contribution.mjs +130 -15
  95. package/api/integration/add-contribution.test.mjs +258 -7
  96. package/api/integration/add-helpers.d.mts +5 -2
  97. package/api/integration/add-helpers.mjs +36 -9
  98. package/api/integration/add-theme.mjs +56 -65
  99. package/api/integration/add-theme.test.mjs +139 -21
  100. package/api/integration/authoring-checks.mjs +138 -28
  101. package/api/integration/authoring-checks.test.mjs +179 -7
  102. package/api/integration/authoring-checks.type.mjs +6 -1
  103. package/api/integration/integration-authoring.type.d.mts +3 -1
  104. package/api/integration/integration-authoring.type.mjs +2 -0
  105. package/api/integration/integration-block-exports.test.mjs +10 -6
  106. package/api/integration/integrationAdd.doc.mjs +14 -4
  107. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  108. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  109. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  110. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  111. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  112. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  113. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  114. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  115. package/api/integration/integrationPackCheck.doc.mjs +5 -4
  116. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  117. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  118. package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
  119. package/api/integration/pack-check.mjs +160 -11
  120. package/api/integration/pack-check.test.mjs +477 -47
  121. package/api/integration/pack-check.type.d.mts +26 -2
  122. package/api/integration/pack-check.type.mjs +15 -2
  123. package/api/integration/summarizeIssues.doc.mjs +1 -0
  124. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  126. package/api/integration/validate-integration.mjs +52 -102
  127. package/api/integration/validate-integration.test.mjs +179 -26
  128. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  129. package/api/integration/validateIntegration.doc.mjs +3 -2
  130. package/api/json/assertResponse.doc.mjs +2 -1
  131. package/api/json/envelope-types.test.mjs +76 -0
  132. package/api/json/index.ts +2 -0
  133. package/api/json/isError.doc.mjs +2 -1
  134. package/api/json/parseResponse.doc.mjs +3 -2
  135. package/api/layout/_adapter.mjs +20 -5
  136. package/api/layout/expand/expand.mjs +7 -5
  137. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  138. package/api/layout/grammar/grammar.mjs +2 -1
  139. package/api/layout/layoutCheck.doc.mjs +1 -0
  140. package/api/layout/layoutExpand.doc.mjs +2 -1
  141. package/api/layout/layoutGrammar.doc.mjs +1 -0
  142. package/api/search/search-return-type.test.mjs +54 -0
  143. package/api/search/search.d.mts +89 -12
  144. package/api/search/search.doc.mjs +8 -2
  145. package/api/search/search.mjs +697 -97
  146. package/api/search/search.type.d.mts +15 -3
  147. package/api/search/search.type.mjs +5 -2
  148. package/api/swizzle/copy/copy.mjs +28 -11
  149. package/api/swizzle/swizzle.doc.mjs +8 -5
  150. package/api/swizzle/swizzle.type.d.mts +2 -2
  151. package/api/swizzle/swizzle.type.mjs +2 -2
  152. package/api/template/copy/copy.mjs +18 -24
  153. package/api/template/copy/copy.test.mjs +26 -0
  154. package/api/template/list/list.mjs +1 -0
  155. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  156. package/api/template/template-integration.test.mjs +1072 -3
  157. package/api/template/template-suffix.test.mjs +41 -21
  158. package/api/template/template.d.mts +1 -1
  159. package/api/template/template.doc.mjs +32 -9
  160. package/api/template/template.mjs +45 -8
  161. package/api/template/template.type.d.mts +12 -14
  162. package/api/template/template.type.mjs +15 -14
  163. package/api/theme/_adapter.d.mts +2 -3
  164. package/api/theme/_adapter.mjs +4 -5
  165. package/api/theme/add/add.binary.test.mjs +84 -0
  166. package/api/theme/add/add.mjs +31 -22
  167. package/api/theme/add/add.rollback.test.mjs +158 -0
  168. package/api/theme/add/add.staging.test.mjs +83 -0
  169. package/api/theme/add/add.test.mjs +14 -1
  170. package/api/theme/build/build.family.test.mjs +7 -12
  171. package/api/theme/build/build.mjs +140 -59
  172. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  173. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  174. package/api/theme/build/build.rollback.test.mjs +148 -0
  175. package/api/theme/build/build.test.mjs +127 -0
  176. package/api/theme/build/font-warning.mjs +3 -3
  177. package/api/theme/build/font-warning.test.mjs +5 -2
  178. package/api/theme/generateTonalPalette.doc.mjs +2 -2
  179. package/api/theme/integration-themes.test.mjs +39 -28
  180. package/api/theme/list/list.test.mjs +19 -20
  181. package/api/theme/listThemes.doc.mjs +6 -5
  182. package/api/theme/palette/generate/generate.mjs +8 -3
  183. package/api/theme/palette/generate/generate.test.mjs +96 -0
  184. package/api/theme/palette/generate/generator.d.mts +10 -13
  185. package/api/theme/palette/generate/generator.mjs +15 -4
  186. package/api/theme/palette/generate/generator.test.mjs +10 -0
  187. package/api/theme/template/template.mjs +11 -2
  188. package/api/theme/template/template.test.mjs +20 -0
  189. package/api/theme/theme.type.d.mts +170 -11
  190. package/api/theme/theme.type.mjs +94 -27
  191. package/api/theme/themeAdd.doc.mjs +12 -12
  192. package/api/theme/themeBuild.doc.mjs +21 -17
  193. package/api/theme/themeList.doc.mjs +6 -3
  194. package/api/theme/themeListAvailable.doc.mjs +6 -3
  195. package/api/theme/themePaletteGenerate.doc.mjs +16 -8
  196. package/api/theme/themeTargets.doc.mjs +4 -2
  197. package/api/theme/themeTemplate.doc.mjs +8 -3
  198. package/api/upgrade/_adapter.d.mts +32 -5
  199. package/api/upgrade/_adapter.mjs +139 -22
  200. package/api/upgrade/list/list.mjs +2 -1
  201. package/api/upgrade/list/list.test.mjs +73 -0
  202. package/api/upgrade/project-context.test.mjs +272 -0
  203. package/api/upgrade/provider-agreement.test.mjs +152 -0
  204. package/api/upgrade/run/files-changed.test.mjs +111 -0
  205. package/api/upgrade/run/run.mjs +358 -59
  206. package/api/upgrade/status/status.mjs +2 -2
  207. package/api/upgrade/upgrade.doc.mjs +32 -23
  208. package/api/upgrade/upgrade.type.d.mts +43 -5
  209. package/api/upgrade/upgrade.type.mjs +29 -13
  210. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  211. package/assets/codemods/__tests__/runner.test.mjs +332 -8
  212. package/assets/codemods/file-count.test.mjs +163 -0
  213. package/assets/codemods/integration-discovery.mjs +48 -4
  214. package/assets/codemods/integration-discovery.test.mjs +73 -0
  215. package/assets/codemods/integration-runner.mjs +59 -7
  216. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  217. package/assets/codemods/registry.mjs +1 -0
  218. package/assets/codemods/run-codemod.mjs +177 -34
  219. package/assets/codemods/runner.mjs +353 -104
  220. package/assets/codemods/term-log.mjs +32 -8
  221. package/assets/codemods/term-log.test.mjs +19 -1
  222. package/assets/codemods/transform-prop.mjs +109 -0
  223. package/assets/codemods/transform-prop.test.mjs +95 -0
  224. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  225. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  226. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  227. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  228. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  229. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  230. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  231. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  232. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  233. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  234. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  235. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  236. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  237. package/assets/docs/README.md +12 -1
  238. package/assets/docs/authoring.doc.mjs +14 -0
  239. package/assets/docs/browser-support.doc.mjs +11 -11
  240. package/assets/docs/color.doc.mjs +8 -2
  241. package/assets/docs/elevation.doc.mjs +6 -4
  242. package/assets/docs/getting-started.doc.mjs +6 -17
  243. package/assets/docs/icons.doc.mjs +2 -21
  244. package/assets/docs/illustrations.doc.mjs +7 -15
  245. package/assets/docs/internationalization.doc.mjs +7 -5
  246. package/assets/docs/layout.doc.dense.mjs +132 -84
  247. package/assets/docs/layout.doc.mjs +134 -78
  248. package/assets/docs/migration.doc.mjs +19 -21
  249. package/assets/docs/motion.doc.mjs +16 -3
  250. package/assets/docs/principles.doc.dense.mjs +5 -5
  251. package/assets/docs/principles.doc.mjs +14 -6
  252. package/assets/docs/principles.doc.zh.mjs +6 -6
  253. package/assets/docs/shape.doc.mjs +8 -3
  254. package/assets/docs/spacing.doc.mjs +7 -2
  255. package/assets/docs/styling-libraries.doc.mjs +10 -6
  256. package/assets/docs/styling.doc.mjs +22 -26
  257. package/assets/docs/theme.doc.dense.mjs +58 -18
  258. package/assets/docs/theme.doc.mjs +60 -50
  259. package/assets/docs/theme.doc.zh.mjs +9 -8
  260. package/assets/docs/tokens.doc.dense.mjs +2 -2
  261. package/assets/docs/tokens.doc.mjs +390 -9
  262. package/assets/docs/tokens.doc.zh.mjs +2 -2
  263. package/assets/docs/tree/add-a-component.doc.mjs +75 -0
  264. package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
  265. package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
  266. package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
  267. package/assets/docs/tree/api.doc.mjs +30 -0
  268. package/assets/docs/tree/block-template.doc.mjs +130 -0
  269. package/assets/docs/tree/build-the-template.doc.mjs +28 -0
  270. package/assets/docs/tree/building-blocks.doc.mjs +46 -0
  271. package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
  272. package/assets/docs/tree/checks.doc.mjs +119 -0
  273. package/assets/docs/tree/cli.doc.mjs +23 -0
  274. package/assets/docs/tree/codemods.doc.mjs +147 -0
  275. package/assets/docs/tree/commands.doc.mjs +25 -0
  276. package/assets/docs/tree/component-family.doc.mjs +113 -0
  277. package/assets/docs/tree/component-imports.doc.mjs +69 -0
  278. package/assets/docs/tree/component-lookups.doc.mjs +149 -0
  279. package/assets/docs/tree/components.doc.mjs +23 -0
  280. package/assets/docs/tree/configuration.doc.mjs +23 -0
  281. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
  282. package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
  283. package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
  284. package/assets/docs/tree/docs.doc.mjs +21 -0
  285. package/assets/docs/tree/document-the-template.doc.mjs +28 -0
  286. package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
  287. package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
  288. package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
  291. package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
  292. package/assets/docs/tree/help.doc.mjs +16 -0
  293. package/assets/docs/tree/integrations.doc.mjs +40 -0
  294. package/assets/docs/tree/links.doc.mjs +98 -0
  295. package/assets/docs/tree/package-and-test.doc.mjs +32 -0
  296. package/assets/docs/tree/page-template.doc.mjs +71 -0
  297. package/assets/docs/tree/publishing.doc.mjs +111 -0
  298. package/assets/docs/tree/quick-start.doc.mjs +272 -0
  299. package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
  300. package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
  301. package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
  302. package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
  303. package/assets/docs/tree/ship.doc.mjs +16 -0
  304. package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
  305. package/assets/docs/tree/single-component.doc.mjs +165 -0
  306. package/assets/docs/tree/start-a-template.doc.mjs +143 -0
  307. package/assets/docs/tree/subcomponent.doc.mjs +115 -0
  308. package/assets/docs/tree/template-assets.doc.mjs +64 -0
  309. package/assets/docs/tree/template-doc-overview.doc.mjs +109 -0
  310. package/assets/docs/tree/template-fonts.doc.mjs +102 -0
  311. package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
  312. package/assets/docs/tree/template-icons.doc.mjs +97 -0
  313. package/assets/docs/tree/template-images-media.doc.mjs +127 -0
  314. package/assets/docs/tree/template-styles.doc.mjs +93 -0
  315. package/assets/docs/tree/templates.doc.mjs +34 -0
  316. package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
  317. package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
  318. package/assets/docs/tree/themes.doc.mjs +39 -0
  319. package/assets/docs/tree/troubleshooting.doc.mjs +149 -0
  320. package/assets/docs/tree/upgrading.doc.mjs +103 -0
  321. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
  322. package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
  323. package/assets/docs/tree/versioning.doc.mjs +161 -0
  324. package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
  325. package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
  326. package/assets/docs/typography.doc.mjs +24 -4
  327. package/assets/docs/working-with-ai.doc.mjs +34 -26
  328. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  329. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  330. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  331. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  332. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  333. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  334. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  335. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  336. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  337. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  338. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  339. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  340. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  341. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  342. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  343. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  344. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  345. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  346. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  347. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  348. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  349. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  350. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  351. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  352. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  353. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  354. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  355. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  356. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  357. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  358. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  359. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  360. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  361. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  362. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  363. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  364. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  365. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  366. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  367. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  368. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  369. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  370. package/authoring/_shared/contract.ts +22 -0
  371. package/authoring/codemod/codemod.doc.mjs +7 -2
  372. package/authoring/codemod/parse.d.mts +8 -8
  373. package/authoring/codemod/parse.mjs +8 -6
  374. package/authoring/codemod/type.ts +12 -0
  375. package/authoring/config/config.doc.mjs +11 -3
  376. package/authoring/config/debug-composition.test.mjs +92 -0
  377. package/authoring/config/parse.d.mts +15 -13
  378. package/authoring/config/parse.mjs +27 -8
  379. package/authoring/config/parse.test.mjs +8 -0
  380. package/authoring/config/type.ts +29 -6
  381. package/authoring/debug/debug.doc.d.mts +11 -0
  382. package/authoring/debug/debug.doc.mjs +182 -0
  383. package/authoring/debug/parse.d.mts +8 -8
  384. package/authoring/debug/parse.mjs +3 -3
  385. package/authoring/discover/discover.doc.d.mts +13 -0
  386. package/authoring/discover/discover.doc.mjs +138 -0
  387. package/authoring/discover/parse.d.mts +24 -0
  388. package/authoring/discover/parse.mjs +128 -0
  389. package/authoring/discover/parse.test.mjs +124 -0
  390. package/authoring/discover/type.ts +87 -0
  391. package/authoring/doctypes/_schema.d.mts +792 -24
  392. package/authoring/doctypes/_schema.mjs +549 -39
  393. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  394. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  395. package/authoring/doctypes/base/type.ts +43 -0
  396. package/authoring/doctypes/command/command.doc.mjs +4 -3
  397. package/authoring/doctypes/command/parse.d.mts +2 -2
  398. package/authoring/doctypes/command/parse.mjs +1 -1
  399. package/authoring/doctypes/command/type.ts +5 -4
  400. package/authoring/doctypes/component/component.doc.mjs +12 -3
  401. package/authoring/doctypes/component/parse.d.mts +2 -2
  402. package/authoring/doctypes/component/parse.mjs +1 -1
  403. package/authoring/doctypes/component/type.ts +14 -5
  404. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  405. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  406. package/authoring/doctypes/enum/parse.d.mts +2 -2
  407. package/authoring/doctypes/enum/parse.mjs +1 -1
  408. package/authoring/doctypes/enum/type.ts +4 -2
  409. package/authoring/doctypes/function/function.doc.mjs +7 -2
  410. package/authoring/doctypes/function/parse.d.mts +2 -2
  411. package/authoring/doctypes/function/parse.mjs +1 -1
  412. package/authoring/doctypes/function/type.ts +9 -4
  413. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  414. package/authoring/doctypes/hook/parse.d.mts +2 -2
  415. package/authoring/doctypes/hook/parse.mjs +1 -1
  416. package/authoring/doctypes/hook/type.ts +5 -4
  417. package/authoring/doctypes/legacy.d.mts +8 -6
  418. package/authoring/doctypes/legacy.mjs +5 -4
  419. package/authoring/doctypes/load-contract.test.mjs +233 -0
  420. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  421. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  422. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  423. package/authoring/doctypes/namespace/parse.mjs +25 -0
  424. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  425. package/authoring/doctypes/namespace/type.ts +74 -0
  426. package/authoring/doctypes/parse.d.mts +22 -18
  427. package/authoring/doctypes/parse.mjs +22 -11
  428. package/authoring/doctypes/parse.test.mjs +77 -3
  429. package/authoring/doctypes/reference/parse.d.mts +2 -2
  430. package/authoring/doctypes/reference/parse.mjs +8 -5
  431. package/authoring/doctypes/reference/reference.doc.mjs +55 -6
  432. package/authoring/doctypes/reference/type.ts +75 -7
  433. package/authoring/doctypes/schema/parse.d.mts +2 -2
  434. package/authoring/doctypes/schema/parse.mjs +1 -1
  435. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  436. package/authoring/doctypes/schema/type.ts +4 -4
  437. package/authoring/doctypes/template/parse.d.mts +94 -1
  438. package/authoring/doctypes/template/parse.mjs +40 -2
  439. package/authoring/doctypes/template/parse.test.mjs +26 -2
  440. package/authoring/doctypes/template/template.doc.mjs +13 -3
  441. package/authoring/doctypes/template/type.ts +13 -2
  442. package/authoring/doctypes/theme/parse.d.mts +35 -0
  443. package/authoring/doctypes/theme/parse.mjs +76 -0
  444. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  445. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  446. package/authoring/doctypes/theme/type.ts +42 -0
  447. package/authoring/doctypes/types.ts +12 -10
  448. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  449. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  450. package/authoring/gap-report/parse.d.mts +10 -10
  451. package/authoring/gap-report/parse.mjs +6 -6
  452. package/authoring/gap-report/type.ts +1 -1
  453. package/authoring/identity/identity.doc.d.mts +9 -0
  454. package/authoring/identity/identity.doc.mjs +61 -0
  455. package/authoring/identity/type.ts +132 -0
  456. package/authoring/index.d.mts +3 -0
  457. package/authoring/index.d.ts +62 -17
  458. package/authoring/index.mjs +4 -1
  459. package/authoring/integration/integration.doc.mjs +22 -13
  460. package/authoring/integration/parse.d.mts +2 -2
  461. package/authoring/integration/parse.mjs +1 -1
  462. package/authoring/integration/parse.test.mjs +10 -1
  463. package/authoring/integration/schema.d.mts +6 -4
  464. package/authoring/integration/schema.mjs +9 -3
  465. package/authoring/integration/type.ts +19 -8
  466. package/authoring/shadcn/receipt.d.mts +6 -6
  467. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  468. package/clients/cli/command-load-failure.test.mjs +83 -0
  469. package/clients/cli/commands/blog.doc.mjs +1 -1
  470. package/clients/cli/commands/blog.mjs +23 -8
  471. package/clients/cli/commands/blog.test.mjs +42 -1
  472. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  473. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  474. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  475. package/clients/cli/commands/build-theme.mjs +16 -50
  476. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  477. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  478. package/clients/cli/commands/build.doc.mjs +16 -8
  479. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  480. package/clients/cli/commands/build.mjs +137 -114
  481. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  482. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  483. package/clients/cli/commands/component/index.mjs +153 -61
  484. package/clients/cli/commands/component-batch.test.mjs +341 -0
  485. package/clients/cli/commands/component-ownership.test.mjs +92 -3
  486. package/clients/cli/commands/component-package.test.mjs +46 -0
  487. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  488. package/clients/cli/commands/component.doc.mjs +28 -10
  489. package/clients/cli/commands/component.test.mjs +19 -0
  490. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  491. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  492. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  493. package/clients/cli/commands/discover.doc.mjs +55 -9
  494. package/clients/cli/commands/discover.mjs +393 -118
  495. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  496. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  497. package/clients/cli/commands/docs.doc.mjs +28 -6
  498. package/clients/cli/commands/docs.mjs +295 -38
  499. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  500. package/clients/cli/commands/doctor-integration-docs.doc.mjs +6 -5
  501. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  502. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  503. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  504. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  505. package/clients/cli/commands/doctor-integration.test.mjs +143 -8
  506. package/clients/cli/commands/doctor.doc.mjs +4 -2
  507. package/clients/cli/commands/doctor.mjs +108 -37
  508. package/clients/cli/commands/doctor.test.mjs +42 -0
  509. package/clients/cli/commands/gap-report.doc.mjs +27 -15
  510. package/clients/cli/commands/gap-report.test.mjs +72 -0
  511. package/clients/cli/commands/hook/index.mjs +7 -17
  512. package/clients/cli/commands/hook.doc.mjs +1 -1
  513. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  514. package/clients/cli/commands/init.doc.mjs +24 -10
  515. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  516. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  517. package/clients/cli/commands/integration-add.doc.mjs +39 -13
  518. package/clients/cli/commands/integration-authoring.test.mjs +74 -19
  519. package/clients/cli/commands/integration-pack.doc.mjs +6 -10
  520. package/clients/cli/commands/integration-real-world.test.mjs +4 -10
  521. package/clients/cli/commands/integration-verify.doc.mjs +22 -0
  522. package/clients/cli/commands/integration.doc.mjs +5 -5
  523. package/clients/cli/commands/integration.mjs +75 -43
  524. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  525. package/clients/cli/commands/json-contract.test.mjs +33 -0
  526. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  527. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  528. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  529. package/clients/cli/commands/layout.doc.mjs +3 -3
  530. package/clients/cli/commands/layout.mjs +21 -9
  531. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  532. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  533. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  534. package/clients/cli/commands/manifest.doc.mjs +2 -2
  535. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  536. package/clients/cli/commands/search.doc.mjs +16 -6
  537. package/clients/cli/commands/search.mjs +49 -11
  538. package/clients/cli/commands/search.test.mjs +92 -0
  539. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  540. package/clients/cli/commands/swizzle.doc.mjs +4 -3
  541. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  542. package/clients/cli/commands/template.doc.mjs +53 -14
  543. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  544. package/clients/cli/commands/template.mjs +4 -91
  545. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  546. package/clients/cli/commands/text-json-parity.test.mjs +725 -0
  547. package/clients/cli/commands/theme-add.doc.mjs +5 -4
  548. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  549. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  550. package/clients/cli/commands/theme-palette-generate.doc.mjs +12 -7
  551. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  552. package/clients/cli/commands/theme-palette.doc.mjs +2 -3
  553. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  554. package/clients/cli/commands/theme-targets.doc.mjs +3 -3
  555. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  556. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  557. package/clients/cli/commands/theme.doc.mjs +3 -2
  558. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  559. package/clients/cli/commands/upgrade.doc.mjs +83 -12
  560. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  561. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  562. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  563. package/clients/cli/commands/upgrade.mjs +29 -7
  564. package/clients/cli/formatters/index.mjs +164 -1
  565. package/clients/cli/formatters/index.test.mjs +97 -0
  566. package/clients/cli/index.mjs +47 -34
  567. package/clients/cli/latest-version-env.test.mjs +50 -0
  568. package/clients/cli/lib/cli-error.test.mjs +7 -0
  569. package/clients/cli/lib/component-format.mjs +9 -9
  570. package/clients/cli/lib/component-format.test.mjs +1 -1
  571. package/clients/cli/lib/define-command.mjs +56 -6
  572. package/clients/cli/lib/define-command.test.mjs +54 -0
  573. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  574. package/clients/cli/lib/exit-codes.test.mjs +113 -0
  575. package/clients/cli/lib/hook-format.mjs +19 -10
  576. package/clients/cli/lib/json-shim.mjs +62 -16
  577. package/clients/cli/lib/json-shim.test.mjs +83 -0
  578. package/clients/cli/lib/manifest.d.ts +2 -0
  579. package/clients/cli/lib/manifest.mjs +53 -6
  580. package/clients/cli/lib/manifest.test.mjs +22 -2
  581. package/clients/cli/lib/parse-error-format.test.mjs +81 -0
  582. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  583. package/foundation/agent-docs/agent-docs.mjs +83 -13
  584. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  585. package/foundation/config/integration-debug.test.mjs +28 -3
  586. package/foundation/config/project-themes.test.mjs +11 -19
  587. package/foundation/config/project.d.mts +20 -11
  588. package/foundation/config/project.mjs +263 -91
  589. package/foundation/config/project.test.mjs +270 -21
  590. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  591. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  592. package/foundation/discovery/authoring-self-docs.test.mjs +174 -0
  593. package/foundation/discovery/authoring-surface.d.mts +74 -0
  594. package/foundation/discovery/authoring-surface.mjs +525 -0
  595. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  596. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  597. package/foundation/discovery/cli-self-docs.mjs +504 -0
  598. package/foundation/discovery/cli-self-docs.test.mjs +395 -0
  599. package/foundation/discovery/component-discovery.d.mts +39 -1
  600. package/foundation/discovery/component-discovery.mjs +50 -1
  601. package/foundation/discovery/component-loader.d.mts +35 -38
  602. package/foundation/discovery/component-loader.mjs +53 -222
  603. package/foundation/discovery/docs-discovery.d.mts +119 -11
  604. package/foundation/discovery/docs-discovery.mjs +427 -108
  605. package/foundation/discovery/docs-discovery.test.mjs +386 -20
  606. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  607. package/foundation/discovery/docs-output-budget.mjs +50 -0
  608. package/foundation/discovery/docs-section-key.d.mts +116 -0
  609. package/foundation/discovery/docs-section-key.mjs +322 -0
  610. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  611. package/foundation/discovery/template-adapter.d.mts +113 -11
  612. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  613. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  614. package/foundation/discovery/template-adapter.mjs +774 -83
  615. package/foundation/discovery/template-adapter.test.mjs +57 -0
  616. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  617. package/foundation/discovery/template-conflict-release.mjs +40 -0
  618. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  619. package/foundation/discovery/theme-discovery.d.mts +67 -7
  620. package/foundation/discovery/theme-discovery.mjs +916 -186
  621. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  622. package/foundation/discovery/theming-targets.test.mjs +4 -0
  623. package/foundation/doc-compiler/bundle.d.mts +47 -0
  624. package/foundation/doc-compiler/bundle.mjs +278 -0
  625. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  626. package/foundation/doc-compiler/compile.d.mts +343 -0
  627. package/foundation/doc-compiler/compile.mjs +558 -0
  628. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  629. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  630. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  631. package/foundation/doc-compiler/doc-loads.test.mjs +1643 -0
  632. package/foundation/doc-compiler/import.d.mts +24 -0
  633. package/foundation/doc-compiler/import.mjs +59 -0
  634. package/foundation/doc-compiler/inputs.d.mts +102 -0
  635. package/foundation/doc-compiler/inputs.mjs +291 -0
  636. package/foundation/doc-compiler/inputs.test.mjs +298 -0
  637. package/foundation/doc-compiler/ir.d.mts +22 -0
  638. package/foundation/doc-compiler/ir.mjs +471 -0
  639. package/foundation/doc-compiler/lenses.d.mts +36 -0
  640. package/foundation/doc-compiler/lenses.mjs +173 -0
  641. package/foundation/doc-compiler/links.d.mts +162 -0
  642. package/foundation/doc-compiler/links.mjs +294 -0
  643. package/foundation/doc-compiler/links.test.mjs +192 -0
  644. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  645. package/foundation/doc-compiler/overlays.d.mts +37 -0
  646. package/foundation/doc-compiler/overlays.mjs +206 -0
  647. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  648. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  649. package/foundation/doc-compiler/read.d.mts +127 -0
  650. package/foundation/doc-compiler/read.mjs +325 -0
  651. package/foundation/doc-compiler/read.test.mjs +313 -0
  652. package/foundation/doc-compiler/source.d.mts +33 -0
  653. package/foundation/doc-compiler/source.mjs +128 -0
  654. package/foundation/doc-compiler/tree.d.mts +292 -0
  655. package/foundation/doc-compiler/tree.mjs +881 -0
  656. package/foundation/fs/file-protection.d.mts +33 -0
  657. package/foundation/fs/file-protection.mjs +825 -0
  658. package/foundation/fs/file-protection.test.mjs +250 -0
  659. package/foundation/fs/module-loader.d.mts +1 -0
  660. package/foundation/fs/module-loader.mjs +50 -1
  661. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  662. package/foundation/fs/path-safety.d.mts +3 -2
  663. package/foundation/fs/path-safety.mjs +49 -19
  664. package/foundation/fs/path-safety.test.mjs +50 -0
  665. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  666. package/foundation/identity/provider-identity.d.mts +90 -0
  667. package/foundation/identity/provider-identity.mjs +320 -0
  668. package/foundation/identity/provider-identity.test.mjs +254 -0
  669. package/foundation/identity/providers.d.mts +7 -0
  670. package/foundation/identity/providers.mjs +16 -0
  671. package/foundation/integrations/autolink.d.mts +58 -1
  672. package/foundation/integrations/autolink.mjs +143 -45
  673. package/foundation/integrations/autolink.test.mjs +1 -1
  674. package/foundation/integrations/cli-requirement.d.mts +65 -0
  675. package/foundation/integrations/cli-requirement.mjs +189 -0
  676. package/foundation/integrations/cli-requirement.test.mjs +89 -0
  677. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  678. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  679. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  680. package/foundation/integrations/contribution-inventory.mjs +28 -25
  681. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  682. package/foundation/integrations/integration-warnings.d.mts +9 -2
  683. package/foundation/integrations/integration-warnings.mjs +52 -21
  684. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  685. package/foundation/integrations/integrations.d.mts +63 -3
  686. package/foundation/integrations/integrations.mjs +122 -9
  687. package/foundation/integrations/integrations.test.mjs +415 -1
  688. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  689. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  690. package/foundation/integrations/provider-resolution.d.mts +152 -0
  691. package/foundation/integrations/provider-resolution.mjs +576 -0
  692. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  693. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  694. package/foundation/integrations/theme-descriptor.mjs +44 -0
  695. package/foundation/integrations/validate-contributions.d.mts +2 -0
  696. package/foundation/integrations/validate-contributions.mjs +131 -29
  697. package/foundation/response/base.d.ts +8 -4
  698. package/foundation/response/batch.type.d.mts +33 -0
  699. package/foundation/response/batch.type.mjs +34 -0
  700. package/foundation/response/error-codes.d.mts +3 -1
  701. package/foundation/response/error-codes.d.ts +2 -0
  702. package/foundation/response/error-codes.doc.mjs +19 -12
  703. package/foundation/response/error-codes.mjs +8 -2
  704. package/foundation/response/error-codes.test.mjs +166 -14
  705. package/foundation/response/json-contract.test.mjs +57 -17
  706. package/foundation/response/json.d.mts +4 -2
  707. package/foundation/response/json.mjs +8 -10
  708. package/foundation/response/response-types.doc.d.mts +7 -2
  709. package/foundation/response/response-types.doc.mjs +69 -25
  710. package/foundation/response/response-types.doc.test.mjs +181 -0
  711. package/foundation/response/response.doc.mjs +12 -11
  712. package/foundation/text/string-utils.d.mts +8 -0
  713. package/foundation/text/string-utils.mjs +40 -10
  714. package/foundation/xle/expand.d.mts +2 -0
  715. package/foundation/xle/expand.mjs +4 -3
  716. package/foundation/xle/expand.test.mjs +54 -0
  717. package/foundation/xle/xle.test.mjs +13 -0
  718. package/package.json +10 -11
  719. package/api/docs/docs.test.mjs +0 -83
  720. package/api/docs/integrationDocs.test.mjs +0 -208
  721. package/api/search/search.test.mjs +0 -389
  722. package/assets/docs/cli-integrations.doc.mjs +0 -367
  723. package/assets/templates/themes/manifest.json +0 -95
  724. package/clients/cli/commands/docs.test.mjs +0 -102
  725. package/clients/cli/lib/update-check.mjs +0 -83
  726. package/clients/cli/lib/update-check.test.mjs +0 -137
  727. package/clients/cli/update-hint-commands.test.mjs +0 -54
  728. package/foundation/agent-docs/agent-docs.test.mjs +0 -1141
@@ -12,7 +12,8 @@ import * as fs from 'node:fs';
12
12
  import * as path from 'node:path';
13
13
  import * as p from './term-log.mjs';
14
14
  import {humanLog} from '../../foundation/response/json.mjs';
15
- import {runConfigCodemod} from './run-codemod.mjs';
15
+ import {runCodeCodemod, runConfigCodemod} from './run-codemod.mjs';
16
+ import {createFileProtectionResolver} from '../../foundation/fs/file-protection.mjs';
16
17
 
17
18
  // Known corruption patterns that indicate a broken transform.
18
19
  // Each entry: [regex, human-readable description]
@@ -46,20 +47,30 @@ export function fixDirectiveCorruption(code) {
46
47
  }
47
48
 
48
49
  /**
49
- * Directories a source scan must never descend into: dependencies, VCS, and
50
- * generated build output (codemods rewrite source, not artifacts).
50
+ * Directories a source scan must never descend into. Generated-looking names
51
+ * are intentionally absent: protection comes from checkout declarations, not a
52
+ * directory-name heuristic.
51
53
  */
52
54
  const IGNORED_DIRS = new Set([
53
55
  'node_modules',
56
+ 'bower_components',
57
+ 'jspm_packages',
54
58
  '.git',
55
- 'dist',
56
- 'build',
57
- 'out',
58
- '.next',
59
- 'coverage',
59
+ '.hg',
60
+ '.sl',
60
61
  ]);
61
62
  export {IGNORED_DIRS};
62
63
 
64
+ /** @param {string} root @param {string} fullPath @param {string} name */
65
+ export function isIgnoredDirectory(root, fullPath, name) {
66
+ if (IGNORED_DIRS.has(name)) return true;
67
+ const parts = path.relative(root, fullPath).split(path.sep);
68
+ return (
69
+ parts[0] === '.yarn' &&
70
+ ['__virtual__', 'cache', 'sdks', 'unplugged'].includes(parts[1])
71
+ );
72
+ }
73
+
63
74
  /**
64
75
  * Recursively find all source files in a directory.
65
76
  * @param {string} dir
@@ -81,8 +92,17 @@ function findSourceFiles(dir) {
81
92
  '.less',
82
93
  ]);
83
94
 
84
- /** @param {string} currentDir */
85
- function walk(currentDir) {
95
+ /** @param {string} currentDir @param {Set<string>} [ancestors] */
96
+ function walk(currentDir, ancestors = new Set()) {
97
+ let realDirectory;
98
+ try {
99
+ realDirectory = fs.realpathSync(currentDir);
100
+ } catch {
101
+ return;
102
+ }
103
+ if (ancestors.has(realDirectory)) return;
104
+ const nextAncestors = new Set(ancestors);
105
+ nextAncestors.add(realDirectory);
86
106
  let entries;
87
107
  try {
88
108
  entries = fs.readdirSync(currentDir, {withFileTypes: true});
@@ -91,16 +111,27 @@ function findSourceFiles(dir) {
91
111
  }
92
112
  for (const entry of entries) {
93
113
  const fullPath = path.join(currentDir, entry.name);
94
- // Never follow symlinks: readFileSync/writeFileSync would traverse a
95
- // symlinked file and rewrite its target OUTSIDE the scan tree (e.g. into
96
- // node_modules or anywhere on disk). A codemod must only edit real files
97
- // it reaches directly under the scanned path.
98
- if (entry.isSymbolicLink()) continue;
114
+ // Symlinked files and descendants remain read-only candidates so a
115
+ // required change can be reported. Real-path ancestors prevent cycles.
116
+ if (entry.isSymbolicLink()) {
117
+ try {
118
+ const target = fs.statSync(fullPath);
119
+ if (target.isFile() && extensions.has(path.extname(entry.name))) {
120
+ results.push(fullPath);
121
+ } else if (target.isDirectory()) {
122
+ walk(fullPath, nextAncestors);
123
+ }
124
+ } catch {
125
+ // Broken links have no source bytes to evaluate.
126
+ }
127
+ continue;
128
+ }
99
129
  if (entry.isDirectory()) {
100
- // Skip dependency, VCS, and generated-output dirs — codemods rewrite
101
- // source, not build artifacts.
102
- if (IGNORED_DIRS.has(entry.name)) continue;
103
- walk(fullPath);
130
+ // Only hard boundaries are skipped by name. Generated and vendored
131
+ // content is discovered, transformed in memory, and classified by the
132
+ // shared protection resolver so required changes can be reported.
133
+ if (isIgnoredDirectory(dir, fullPath, entry.name)) continue;
134
+ walk(fullPath, nextAncestors);
104
135
  } else if (extensions.has(path.extname(entry.name))) {
105
136
  results.push(fullPath);
106
137
  }
@@ -194,6 +225,187 @@ function toUnifiedEntry(transformEntry, version) {
194
225
  };
195
226
  }
196
227
 
228
+ /**
229
+ * What a core PROJECT codemod plans: whole files to write and delete under the
230
+ * project root, or the problems that stop it. Paths in `writes` and `deletes`
231
+ * are absolute; `problems` name package-relative files.
232
+ *
233
+ * @typedef {object} ProjectCodemodPlan
234
+ * @property {Array<{path: string, contents: string}>} writes
235
+ * @property {string[]} deletes
236
+ * @property {Array<{file: string, message: string}>} problems
237
+ */
238
+
239
+ /**
240
+ * Run one core PROJECT codemod (`meta.codemodType === 'project'`): instead of
241
+ * rewriting the files it is handed, it reads the project and plans whole-file
242
+ * writes and deletions, which this applies (or previews) as one unit. A plan
243
+ * that names a problem changes nothing. Core-only: integration codemods keep
244
+ * the file contract.
245
+ *
246
+ * @param {{name: string, transform: unknown}} transformEntry
247
+ * @param {{apply: boolean, root: string, protection: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, log: {success: (m: string) => void, warn: (m: string) => void, error: (m: string) => void}}} options
248
+ * @returns {Promise<import('../../authoring/codemod/type').CodemodRunResult & {stagedOverrides?: Map<string, string|null>}>}
249
+ */
250
+ async function runProjectCodemod(
251
+ {name, transform},
252
+ {apply, root, protection, log},
253
+ ) {
254
+ /** @param {string} file */
255
+ const rel = file => path.relative(root, file).split(path.sep).join('/');
256
+ /** @type {ProjectCodemodPlan} */
257
+ let plan;
258
+ try {
259
+ plan = await /** @type {(root: string) => Promise<ProjectCodemodPlan>} */ (
260
+ transform
261
+ )(root);
262
+ } catch (err) {
263
+ const message = err instanceof Error ? err.message : String(err);
264
+ log.error(` ✗ ${message}`);
265
+ return {
266
+ filesChanged: 0,
267
+ changedFiles: [],
268
+ writtenFiles: [],
269
+ protectedFiles: [],
270
+ errors: [{file: '.', codemod: name, error: message}],
271
+ };
272
+ }
273
+ if (plan.problems.length > 0) {
274
+ for (const {file, message} of plan.problems) {
275
+ log.error(` ✗ ${file} — ${message}`);
276
+ }
277
+ return {
278
+ filesChanged: 0,
279
+ changedFiles: [],
280
+ writtenFiles: [],
281
+ protectedFiles: [],
282
+ errors: plan.problems.map(({file, message}) => ({
283
+ file,
284
+ codemod: name,
285
+ error: message,
286
+ })),
287
+ };
288
+ }
289
+
290
+ const candidates = [
291
+ ...plan.writes.map(write => ({
292
+ file: write.path,
293
+ existing: fs.existsSync(write.path),
294
+ })),
295
+ ...plan.deletes.map(file => ({file, existing: true})),
296
+ ];
297
+ /** @param {{file: string, existing: boolean}} candidate */
298
+ const currentDeclarations = candidate =>
299
+ protection
300
+ .classify(candidate.file)
301
+ .filter(
302
+ item =>
303
+ candidate.existing ||
304
+ ['outside-root', 'dependency', 'vcs', 'symlink'].includes(
305
+ item.reason,
306
+ ),
307
+ );
308
+ const currentlyBlocked = new Set(
309
+ candidates
310
+ .filter(candidate => currentDeclarations(candidate).length > 0)
311
+ .map(candidate => candidate.file),
312
+ );
313
+ /** @type {Map<string, string|null>} */
314
+ const stagedOverrides = new Map();
315
+ for (const write of plan.writes) {
316
+ if (!currentlyBlocked.has(write.path)) {
317
+ stagedOverrides.set(write.path, write.contents);
318
+ }
319
+ }
320
+ for (const file of plan.deletes) {
321
+ if (!currentlyBlocked.has(file)) stagedOverrides.set(file, null);
322
+ }
323
+ // A plan cannot introduce a protection declaration and then overwrite the
324
+ // file it protects in the same transaction. Only declarations whose own
325
+ // writes are allowed participate in the staged view.
326
+ const stagedProtection = createFileProtectionResolver(root, {
327
+ overrides: stagedOverrides,
328
+ });
329
+ /** @type {import('../../authoring/codemod/type').CodemodRunResult['protectedFiles']} */
330
+ const protectedFiles = [];
331
+ const blocked = new Set();
332
+ for (const candidate of candidates) {
333
+ const file = candidate.file;
334
+ const declarations = [
335
+ ...currentDeclarations(candidate),
336
+ ...stagedProtection.classify(file),
337
+ ]
338
+ .filter(
339
+ item =>
340
+ candidate.existing ||
341
+ ['outside-root', 'dependency', 'vcs', 'symlink'].includes(
342
+ item.reason,
343
+ ),
344
+ )
345
+ .filter(
346
+ (item, index, all) =>
347
+ all.findIndex(
348
+ candidate =>
349
+ candidate.file === item.file &&
350
+ candidate.reason === item.reason &&
351
+ candidate.declaration === item.declaration,
352
+ ) === index,
353
+ );
354
+ if (declarations.length === 0) continue;
355
+ blocked.add(file);
356
+ const rows = declarations.map(item => ({
357
+ file: item.file,
358
+ codemod: name,
359
+ reason: item.reason,
360
+ declaration: item.declaration,
361
+ generated: item.reason === 'generated',
362
+ ...(item.command ? {command: item.command} : {}),
363
+ }));
364
+ protectedFiles.push(...rows);
365
+ log.warn(
366
+ ` ! ${rel(file)} — protected by ${rows.map(item => item.declaration).join('; ')}`,
367
+ );
368
+ }
369
+
370
+ const writes = plan.writes.filter(write => !blocked.has(write.path));
371
+ const deletes = plan.deletes.filter(file => !blocked.has(file));
372
+ const changedFiles = [...writes.map(write => write.path), ...deletes];
373
+ /** @type {string[]} */
374
+ const writtenFiles = [];
375
+ for (const write of writes) {
376
+ if (apply) {
377
+ fs.mkdirSync(path.dirname(write.path), {recursive: true});
378
+ fs.writeFileSync(write.path, write.contents, 'utf-8');
379
+ writtenFiles.push(write.path);
380
+ log.success(` ✓ ${rel(write.path)}`);
381
+ } else {
382
+ log.warn(` ~ ${rel(write.path)} (would write)`);
383
+ }
384
+ }
385
+ // Deletions go last, so a failed write leaves a state a rerun completes.
386
+ for (const file of deletes) {
387
+ if (apply) {
388
+ fs.rmSync(file);
389
+ writtenFiles.push(file);
390
+ log.success(` ✓ ${rel(file)} (removed)`);
391
+ } else {
392
+ log.warn(` ~ ${rel(file)} (would remove)`);
393
+ }
394
+ }
395
+ /** @type {Map<string, string|null>} */
396
+ const appliedOverrides = new Map();
397
+ for (const write of writes) appliedOverrides.set(write.path, write.contents);
398
+ for (const file of deletes) appliedOverrides.set(file, null);
399
+ return {
400
+ filesChanged: changedFiles.length,
401
+ changedFiles,
402
+ writtenFiles,
403
+ protectedFiles,
404
+ stagedOverrides: appliedOverrides,
405
+ errors: [],
406
+ };
407
+ }
408
+
197
409
  /**
198
410
  * Run codemods against source files.
199
411
  *
@@ -204,11 +416,21 @@ function toUnifiedEntry(transformEntry, version) {
204
416
  * @param {string|undefined} options.codemod - Run only this specific transform
205
417
  * @param {Set<string>} [options.skipCodemods] - Transform names to exclude
206
418
  * @param {boolean} [options.silent] - Suppress all human-facing output (for --json)
207
- * @returns {Promise<{totalFilesChanged: number, totalTransformsApplied: number, totalValidationBlocked: number, writtenFiles: string[], errors: Array<{file: string, codemod: string, error: string}>, skippedOptional: Array<{name: string, meta: {title: string, description?: string, fileExtensions?: string[], codemodType?: string}, version: string}>} | {ok: false, reason: string, resolvedPath: string}>}
419
+ * @param {string} [options.root] - Project root a project codemod reads (default: the process cwd)
420
+ * @param {{root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}} [options.protection] - Preloaded protection resolver
421
+ * @returns {Promise<{totalFilesChanged: number, totalTransformsApplied: number, totalValidationBlocked: number, changedFiles: string[], writtenFiles: string[], stagedContents: Map<string, string>, protectedFiles: import('../../authoring/codemod/type').CodemodRunResult['protectedFiles'], errors: Array<{file: string, codemod: string, error: string}>, skippedOptional: Array<{name: string, meta: {title: string, description?: string, fileExtensions?: string[], codemodType?: string}, version: string}>} | {ok: false, reason: string, resolvedPath: string}>}
208
422
  */
209
423
  export async function runCodemods(
210
424
  versionManifests,
211
- {apply, path: srcPath, codemod, skipCodemods, silent = false},
425
+ {
426
+ apply,
427
+ path: srcPath,
428
+ codemod,
429
+ skipCodemods,
430
+ silent = false,
431
+ root = process.cwd(),
432
+ protection: providedProtection,
433
+ },
212
434
  ) {
213
435
  // No-op stub object so silent mode skips log output entirely without
214
436
  // littering the body with `if (!silent)` guards.
@@ -220,12 +442,22 @@ export async function runCodemods(
220
442
  };
221
443
 
222
444
  const resolvedPath = path.resolve(srcPath);
223
-
224
- // Config codemods target the consumer's astryx.config.* and never read
225
- // source files, so a missing --path should not block them. Only hard-fail
226
- // on a missing source path when there is at least one CODE codemod to run.
445
+ // Eager construction is the fail-closed barrier: every working-tree
446
+ // declaration is read and parsed before the first codemod can write.
447
+ let protection =
448
+ providedProtection ?? createFileProtectionResolver(path.resolve(root));
449
+ /** @type {Map<string, string|null>} */
450
+ const protectionOverrides = new Map();
451
+ let protectionWriteCount = 0;
452
+
453
+ // Config and project codemods never read the files under --path, so a
454
+ // missing --path should not block them. Only hard-fail on a missing source
455
+ // path when there is at least one CODE codemod to run.
227
456
  const hasCodeCodemod = versionManifests.some(({transforms}) =>
228
- transforms.some(t => t.meta?.codemodType !== 'config'),
457
+ transforms.some(
458
+ t =>
459
+ t.meta?.codemodType !== 'config' && t.meta?.codemodType !== 'project',
460
+ ),
229
461
  );
230
462
  const sourcePathExists = fs.existsSync(resolvedPath);
231
463
 
@@ -254,13 +486,18 @@ export async function runCodemods(
254
486
  (await import('jscodeshift')).default
255
487
  );
256
488
 
257
- let totalFilesChanged = 0;
258
489
  let totalTransformsApplied = 0;
259
490
  let totalValidationBlocked = 0;
260
491
  /** @type {Array<{file: string, codemod: string, error: string}>} */
261
492
  const errors = [];
493
+ /** In-memory pipeline state keeps ordered dry-runs equivalent to apply. */
494
+ const virtualContents = new Map();
495
+ /** @type {string[]} */
496
+ const changedFiles = [];
262
497
  /** @type {string[]} */
263
498
  const writtenFiles = [];
499
+ /** @type {import('../../authoring/codemod/type').CodemodRunResult['protectedFiles']} */
500
+ const protectedFiles = [];
264
501
  /** @type {Array<{name: string, meta: {title: string, description?: string, fileExtensions?: string[], codemodType?: string}, version: string}>} */
265
502
  const skippedOptional = [];
266
503
  for (const {version, transforms} of versionManifests) {
@@ -272,10 +509,7 @@ export async function runCodemods(
272
509
  // Exclude explicitly skipped codemods (by transform name).
273
510
  if (skipCodemods?.has(transformEntry.name)) continue;
274
511
 
275
- const {name, transform, meta, optional} = transformEntry;
276
- const transformExtensions = new Set(
277
- meta.fileExtensions ?? ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'],
278
- );
512
+ const {name, meta, optional} = transformEntry;
279
513
 
280
514
  // Skip optional codemods unless explicitly requested via --codemod
281
515
  if (optional && !codemod) {
@@ -283,6 +517,13 @@ export async function runCodemods(
283
517
  continue;
284
518
  }
285
519
 
520
+ if (apply && writtenFiles.length !== protectionWriteCount) {
521
+ protection = createFileProtectionResolver(path.resolve(root), {
522
+ overrides: protectionOverrides,
523
+ });
524
+ protectionWriteCount = writtenFiles.length;
525
+ }
526
+
286
527
  log.info(` ${meta.title}`);
287
528
 
288
529
  // Config codemods are routed through the SAME shared runner that
@@ -290,90 +531,75 @@ export async function runCodemods(
290
531
  // `(file, api)` contract and targets the consumer's astryx.config.*.
291
532
  // A core entry signals "config" via `meta.codemodType === 'config'`
292
533
  // (see toUnifiedEntry).
293
- if (meta?.codemodType === 'config') {
294
- const result = runConfigCodemod(toUnifiedEntry(transformEntry, version), {
534
+ if (meta?.codemodType === 'project') {
535
+ const result = await runProjectCodemod(transformEntry, {
295
536
  apply,
537
+ root,
538
+ protection,
296
539
  log,
297
- jscodeshift,
298
540
  });
299
- if (result.errors.length > 0) {
300
- errors.push(...result.errors);
301
- } else if (result.filesChanged > 0) {
302
- totalFilesChanged += result.filesChanged;
303
- totalTransformsApplied += result.filesChanged;
304
- writtenFiles.push(...result.writtenFiles);
541
+ errors.push(...result.errors);
542
+ protectedFiles.push(...result.protectedFiles);
543
+ changedFiles.push(...result.changedFiles);
544
+ writtenFiles.push(...result.writtenFiles);
545
+ if (result.stagedOverrides) {
546
+ for (const [file, contents] of result.stagedOverrides) {
547
+ protectionOverrides.set(file, contents);
548
+ if (contents !== null) virtualContents.set(file, contents);
549
+ }
550
+ protection = createFileProtectionResolver(path.resolve(root), {
551
+ overrides: protectionOverrides,
552
+ });
553
+ protectionWriteCount = writtenFiles.length;
554
+ }
555
+ if (result.filesChanged > 0) {
556
+ totalTransformsApplied += 1;
305
557
  }
306
558
  continue;
307
559
  }
308
560
 
309
- let filesChanged = 0;
310
-
311
- for (const filePath of files) {
312
- const relativePath = path.relative(process.cwd(), filePath);
313
-
314
- try {
315
- const ext = path.extname(filePath);
316
- if (!transformExtensions.has(ext)) {
317
- continue;
318
- }
319
-
320
- const source = fs.readFileSync(filePath, 'utf-8');
321
- // Configure parser based on file extension
322
- const parser = ext === '.tsx' || ext === '.ts' ? 'tsx' : 'babel';
323
- const j = jscodeshift.withParser(parser);
324
- const api = {
325
- jscodeshift: j,
326
- stats: () => {},
327
- report: () => {},
328
- };
329
- const file = {source, path: filePath};
330
-
331
- let result = transform(file, api);
332
-
333
- if (result != null && result !== source) {
334
- // Fix known jscodeshift output corruption before validation
335
- result = fixDirectiveCorruption(result);
336
-
337
- // Validate output before writing
338
- const validation = validateOutput(result, source, j, {
339
- parse: ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'].includes(
340
- ext,
341
- ),
342
- });
343
- if (!validation.valid) {
344
- totalValidationBlocked++;
345
- log.error(` ✗ ${relativePath} — ${validation.reason}`);
346
- errors.push({
347
- file: relativePath,
348
- codemod: name,
349
- error: validation.reason,
350
- });
351
- continue;
352
- }
353
-
354
- filesChanged++;
355
- totalFilesChanged++;
356
- totalTransformsApplied++;
357
-
358
- if (apply) {
359
- fs.writeFileSync(filePath, result, 'utf-8');
360
- writtenFiles.push(filePath);
361
- log.success(` ✓ ${relativePath}`);
362
- } else {
363
- log.warn(` ~ ${relativePath} (would change)`);
364
- }
365
- }
366
- } catch (err) {
367
- const message = /** @type {any} */ (err).message;
368
- log.error(` ✗ ${relativePath} — ${message}`);
369
- errors.push({file: relativePath, codemod: name, error: message});
561
+ if (meta?.codemodType === 'config') {
562
+ const result = runConfigCodemod(
563
+ toUnifiedEntry(transformEntry, version),
564
+ {
565
+ apply,
566
+ log,
567
+ jscodeshift,
568
+ root,
569
+ protection,
570
+ contents: virtualContents,
571
+ },
572
+ );
573
+ errors.push(...result.errors);
574
+ protectedFiles.push(...result.protectedFiles);
575
+ changedFiles.push(...result.changedFiles);
576
+ writtenFiles.push(...result.writtenFiles);
577
+ if (result.filesChanged > 0) {
578
+ totalTransformsApplied += result.filesChanged;
370
579
  }
580
+ continue;
371
581
  }
372
582
 
373
- if (filesChanged > 0) {
583
+ const result = runCodeCodemod(
584
+ toUnifiedEntry(transformEntry, version),
585
+ files,
586
+ {apply, log, jscodeshift, root, protection, contents: virtualContents},
587
+ );
588
+ errors.push(...result.errors);
589
+ protectedFiles.push(...result.protectedFiles);
590
+ changedFiles.push(...result.changedFiles);
591
+ writtenFiles.push(...result.writtenFiles);
592
+ totalTransformsApplied += result.filesChanged;
593
+ totalValidationBlocked += result.errors.filter(
594
+ error =>
595
+ error.error.startsWith('transform produced unparseable output') ||
596
+ error.error.startsWith('detected corruption:'),
597
+ ).length;
598
+
599
+ if (result.filesChanged > 0) {
374
600
  const verb = apply ? 'Updated' : 'Would update';
375
601
  log.info(
376
- ` ${verb} ${filesChanged} file${filesChanged === 1 ? '' : 's'}`,
602
+ ` ${verb} ${result.filesChanged} file${result.filesChanged === 1 ? '' : 's'}`,
377
603
  );
378
604
  }
379
605
  }
@@ -400,8 +626,28 @@ export async function runCodemods(
400
626
  );
401
627
  }
402
628
 
403
- if (totalFilesChanged === 0 && errors.length === 0) {
629
+ // A file several codemods changed is one file. `totalTransformsApplied` is
630
+ // unchanged: a code or config codemod counts each file it changed, and a
631
+ // project codemod counts once. The two answer different questions.
632
+ const totalFilesChanged = new Set(changedFiles).size;
633
+
634
+ if (protectedFiles.length > 0) {
635
+ const files = [...new Set(protectedFiles.map(item => item.file))];
636
+ log.warn(
637
+ `${files.length} protected file${files.length === 1 ? '' : 's'} require${files.length === 1 ? 's' : ''} regeneration or manual review.`,
638
+ );
639
+ }
640
+
641
+ if (
642
+ totalFilesChanged === 0 &&
643
+ errors.length === 0 &&
644
+ protectedFiles.length === 0
645
+ ) {
404
646
  log.success('No changes needed — your code is already up to date!');
647
+ } else if (apply && protectedFiles.length > 0) {
648
+ log.warn(
649
+ `Applied ${totalTransformsApplied} owned change${totalTransformsApplied === 1 ? '' : 's'} across ${totalFilesChanged} file${totalFilesChanged === 1 ? '' : 's'}; protected changes remain.`,
650
+ );
405
651
  } else if (apply) {
406
652
  log.success(
407
653
  `Done! Applied ${totalTransformsApplied} change${totalTransformsApplied === 1 ? '' : 's'} across ${totalFilesChanged} file${totalFilesChanged === 1 ? '' : 's'}.`,
@@ -438,7 +684,10 @@ export async function runCodemods(
438
684
  totalFilesChanged,
439
685
  totalTransformsApplied,
440
686
  totalValidationBlocked,
687
+ changedFiles,
441
688
  writtenFiles,
689
+ protectedFiles,
690
+ stagedContents: virtualContents,
442
691
  errors,
443
692
  skippedOptional,
444
693
  };
@@ -11,6 +11,8 @@
11
11
  * `p.log.step(...)`, `p.log.success(...)`, etc. All output routes through
12
12
  * `humanLog`, the CLI's stdout-discipline primitive, which is a no-op in
13
13
  * `--json` mode — so these human logs can never corrupt a JSON envelope.
14
+ * Every line is plain ASCII: level prefixes are ASCII and typographic glyphs
15
+ * in a message are transliterated before it is printed.
14
16
  *
15
17
  * The side-effecting API commands (upgrade/init/themeBuild) do NOT use this;
16
18
  * they write through the shared `logger` (api/logger.mjs).
@@ -18,8 +20,30 @@
18
20
 
19
21
  import {humanLog} from '../../foundation/response/json.mjs';
20
22
 
21
- /** @param {unknown} msg */
22
- const toStr = (msg) => (msg === undefined || msg === null ? '' : String(msg));
23
+ /** @type {Array<[RegExp, string]>} */
24
+ const ASCII_GLYPHS = [
25
+ [/[\u2014\u2013]/g, '-'],
26
+ [/\u2192/g, '->'],
27
+ [/\u2713/g, '[ok]'],
28
+ [/\u2717/g, '!!'],
29
+ [/\u26a0\ufe0f?/g, '!'],
30
+ [/\u2022/g, '-'],
31
+ [/\u2026/g, '...'],
32
+ [/[\u2018\u2019]/g, "'"],
33
+ [/[\u201c\u201d]/g, '"'],
34
+ [/\u00a0/g, ' '],
35
+ ];
36
+
37
+ /**
38
+ * A message as plain ASCII: typographic glyphs become their ASCII spelling.
39
+ * @param {unknown} msg
40
+ * @returns {string}
41
+ */
42
+ export function toAscii(msg) {
43
+ let text = msg === undefined || msg === null ? '' : String(msg);
44
+ for (const [glyph, ascii] of ASCII_GLYPHS) text = text.replace(glyph, ascii);
45
+ return text;
46
+ }
23
47
 
24
48
  /**
25
49
  * Human-facing log surface (the small `log` API codemods use). All lines go to
@@ -28,15 +52,15 @@ const toStr = (msg) => (msg === undefined || msg === null ? '' : String(msg));
28
52
  */
29
53
  export const log = {
30
54
  /** @param {unknown} msg */
31
- message: (msg) => humanLog(toStr(msg)),
55
+ message: (msg) => humanLog(toAscii(msg)),
32
56
  /** @param {unknown} msg */
33
- info: (msg) => humanLog(toStr(msg)),
57
+ info: (msg) => humanLog(toAscii(msg)),
34
58
  /** @param {unknown} msg */
35
- step: (msg) => humanLog(toStr(msg)),
59
+ step: (msg) => humanLog(toAscii(msg)),
36
60
  /** @param {unknown} msg */
37
- success: (msg) => humanLog(`✓ ${toStr(msg)}`),
61
+ success: (msg) => humanLog(`[ok] ${toAscii(msg)}`),
38
62
  /** @param {unknown} msg */
39
- warn: (msg) => humanLog(`⚠ ${toStr(msg)}`),
63
+ warn: (msg) => humanLog(`! ${toAscii(msg)}`),
40
64
  /** @param {unknown} msg */
41
- error: (msg) => humanLog(`✗ ${toStr(msg)}`),
65
+ error: (msg) => humanLog(`!! ${toAscii(msg)}`),
42
66
  };
@@ -51,7 +51,7 @@ describe('sanity: helpers are live in human mode', () => {
51
51
  setJsonMode(false);
52
52
  p.log.success('done');
53
53
  expect(logSpy).toHaveBeenCalledTimes(1);
54
- expect(logSpy).toHaveBeenCalledWith('✓ done');
54
+ expect(logSpy).toHaveBeenCalledWith('[ok] done');
55
55
  });
56
56
 
57
57
  it('every log helper emits exactly one stdout line in human mode', () => {
@@ -60,3 +60,21 @@ describe('sanity: helpers are live in human mode', () => {
60
60
  expect(logSpy).toHaveBeenCalledTimes(6);
61
61
  });
62
62
  });
63
+
64
+ describe('ASCII output', () => {
65
+ it('prints ASCII level prefixes and transliterates glyphs in messages', () => {
66
+ setJsonMode(false);
67
+ p.log.success('src/a.tsx');
68
+ p.log.warn('stale \u2014 refresh');
69
+ p.log.error(' \u2717 src/b.tsx \u2014 rename \u2192 failed');
70
+ p.log.info(' \u2022 name \u2014 title\u2026');
71
+ const lines = logSpy.mock.calls.map(call => call.join(' '));
72
+ expect(lines).toEqual([
73
+ '[ok] src/a.tsx',
74
+ '! stale - refresh',
75
+ '!! !! src/b.tsx - rename -> failed',
76
+ ' - name - title...',
77
+ ]);
78
+ for (const line of lines) expect(line).not.toMatch(/[\u0080-\uFFFF]/);
79
+ });
80
+ });