@astryxdesign/cli 0.6.3 → 0.6.4-canary.06c8fa3

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 (670) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +121 -85
  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 +16 -9
  7. package/api/build/build.test.mjs +197 -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 +165 -49
  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 +36 -13
  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 +272 -41
  54. package/api/docs/_adapter.mjs +985 -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/docs.d.mts +10 -3
  61. package/api/docs/docs.doc.mjs +55 -16
  62. package/api/docs/docs.mjs +53 -10
  63. package/api/docs/docs.test.mjs +166 -4
  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/integration-tree.test.mjs +555 -0
  70. package/api/docs/integrationDocs.test.mjs +114 -8
  71. package/api/docs/list/list.mjs +28 -12
  72. package/api/docs/node/node.d.mts +43 -0
  73. package/api/docs/node/node.mjs +192 -0
  74. package/api/docs/reference-blocks.test.mjs +406 -0
  75. package/api/doctor/doctor.d.mts +104 -1
  76. package/api/doctor/doctor.doc.mjs +1 -0
  77. package/api/doctor/doctor.mjs +635 -7
  78. package/api/doctor/doctor.test.mjs +732 -11
  79. package/api/gap-report/gap-report.doc.mjs +8 -4
  80. package/api/hook/_adapter.mjs +19 -5
  81. package/api/hook/hook.doc.mjs +1 -0
  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 -3
  87. package/api/index.mjs +5 -4
  88. package/api/init/init.doc.mjs +6 -1
  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 +34 -64
  99. package/api/integration/add-theme.test.mjs +105 -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 +2 -1
  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 +105 -0
  119. package/api/integration/pack-check.mjs +111 -10
  120. package/api/integration/pack-check.test.mjs +387 -47
  121. package/api/integration/pack-check.type.d.mts +26 -2
  122. package/api/integration/pack-check.type.mjs +14 -1
  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 +1 -0
  131. package/api/json/envelope-types.test.mjs +76 -0
  132. package/api/json/index.ts +2 -1
  133. package/api/json/isError.doc.mjs +1 -0
  134. package/api/json/parseResponse.doc.mjs +3 -2
  135. package/api/search/search-return-type.test.mjs +54 -0
  136. package/api/search/search.d.mts +62 -11
  137. package/api/search/search.doc.mjs +8 -2
  138. package/api/search/search.mjs +471 -83
  139. package/api/search/search.test.mjs +142 -1
  140. package/api/search/search.type.d.mts +15 -3
  141. package/api/search/search.type.mjs +5 -2
  142. package/api/swizzle/copy/copy.mjs +28 -11
  143. package/api/swizzle/swizzle.doc.mjs +2 -1
  144. package/api/swizzle/swizzle.type.d.mts +2 -2
  145. package/api/swizzle/swizzle.type.mjs +2 -2
  146. package/api/template/copy/copy.mjs +17 -23
  147. package/api/template/copy/copy.test.mjs +17 -0
  148. package/api/template/list/list.mjs +1 -0
  149. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  150. package/api/template/template-integration.test.mjs +1008 -3
  151. package/api/template/template-suffix.test.mjs +41 -21
  152. package/api/template/template.d.mts +1 -1
  153. package/api/template/template.doc.mjs +30 -8
  154. package/api/template/template.mjs +46 -9
  155. package/api/template/template.type.d.mts +12 -14
  156. package/api/template/template.type.mjs +15 -14
  157. package/api/theme/_adapter.d.mts +2 -3
  158. package/api/theme/_adapter.mjs +4 -5
  159. package/api/theme/add/add.binary.test.mjs +84 -0
  160. package/api/theme/add/add.mjs +31 -22
  161. package/api/theme/add/add.rollback.test.mjs +158 -0
  162. package/api/theme/add/add.staging.test.mjs +83 -0
  163. package/api/theme/add/add.test.mjs +14 -1
  164. package/api/theme/build/build.family.test.mjs +7 -12
  165. package/api/theme/build/build.mjs +140 -59
  166. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  167. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  168. package/api/theme/build/build.rollback.test.mjs +148 -0
  169. package/api/theme/build/build.test.mjs +127 -0
  170. package/api/theme/build/font-warning.mjs +3 -3
  171. package/api/theme/build/font-warning.test.mjs +5 -2
  172. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  173. package/api/theme/integration-themes.test.mjs +39 -28
  174. package/api/theme/list/list.test.mjs +19 -20
  175. package/api/theme/listThemes.doc.mjs +6 -5
  176. package/api/theme/palette/generate/generate.mjs +8 -3
  177. package/api/theme/palette/generate/generate.test.mjs +96 -0
  178. package/api/theme/palette/generate/generator.d.mts +10 -13
  179. package/api/theme/palette/generate/generator.mjs +15 -4
  180. package/api/theme/palette/generate/generator.test.mjs +10 -0
  181. package/api/theme/template/template.mjs +11 -2
  182. package/api/theme/template/template.test.mjs +20 -0
  183. package/api/theme/theme.type.d.mts +170 -11
  184. package/api/theme/theme.type.mjs +94 -27
  185. package/api/theme/themeAdd.doc.mjs +4 -3
  186. package/api/theme/themeBuild.doc.mjs +8 -4
  187. package/api/theme/themeList.doc.mjs +6 -3
  188. package/api/theme/themeListAvailable.doc.mjs +5 -3
  189. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  190. package/api/theme/themeTargets.doc.mjs +1 -0
  191. package/api/theme/themeTemplate.doc.mjs +6 -2
  192. package/api/upgrade/_adapter.d.mts +32 -5
  193. package/api/upgrade/_adapter.mjs +139 -22
  194. package/api/upgrade/list/list.mjs +2 -1
  195. package/api/upgrade/list/list.test.mjs +73 -0
  196. package/api/upgrade/project-context.test.mjs +272 -0
  197. package/api/upgrade/provider-agreement.test.mjs +152 -0
  198. package/api/upgrade/run/files-changed.test.mjs +111 -0
  199. package/api/upgrade/run/run.mjs +359 -60
  200. package/api/upgrade/status/status.mjs +2 -2
  201. package/api/upgrade/upgrade.doc.mjs +12 -5
  202. package/api/upgrade/upgrade.type.d.mts +43 -5
  203. package/api/upgrade/upgrade.type.mjs +29 -13
  204. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  205. package/assets/codemods/__tests__/runner.test.mjs +332 -8
  206. package/assets/codemods/file-count.test.mjs +163 -0
  207. package/assets/codemods/integration-discovery.mjs +48 -4
  208. package/assets/codemods/integration-discovery.test.mjs +73 -0
  209. package/assets/codemods/integration-runner.mjs +59 -7
  210. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  211. package/assets/codemods/registry.mjs +1 -0
  212. package/assets/codemods/run-codemod.mjs +177 -34
  213. package/assets/codemods/runner.mjs +353 -104
  214. package/assets/codemods/term-log.mjs +32 -8
  215. package/assets/codemods/term-log.test.mjs +19 -1
  216. package/assets/codemods/transform-prop.mjs +109 -0
  217. package/assets/codemods/transform-prop.test.mjs +95 -0
  218. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  219. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  220. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  221. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  222. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  223. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  224. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  225. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  226. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  227. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  228. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  229. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  230. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  231. package/assets/docs/README.md +9 -0
  232. package/assets/docs/authoring.doc.mjs +14 -0
  233. package/assets/docs/getting-started.doc.mjs +2 -2
  234. package/assets/docs/internationalization.doc.mjs +7 -5
  235. package/assets/docs/layout.doc.dense.mjs +2 -2
  236. package/assets/docs/layout.doc.mjs +1 -1
  237. package/assets/docs/principles.doc.mjs +6 -6
  238. package/assets/docs/styling-libraries.doc.mjs +4 -4
  239. package/assets/docs/styling.doc.mjs +4 -4
  240. package/assets/docs/theme.doc.mjs +5 -5
  241. package/assets/docs/tokens.doc.mjs +1 -1
  242. package/assets/docs/tree/api.doc.mjs +30 -0
  243. package/assets/docs/tree/cli.doc.mjs +23 -0
  244. package/assets/docs/tree/commands.doc.mjs +25 -0
  245. package/assets/docs/tree/component-lookups.doc.mjs +149 -0
  246. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +144 -26
  247. package/assets/docs/tree/integrations.test.mjs +62 -0
  248. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  249. package/assets/docs/working-with-ai.doc.mjs +4 -4
  250. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  251. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  252. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  253. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  254. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  255. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  256. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  257. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  258. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  259. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  260. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  261. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  262. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  263. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  264. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  265. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  266. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  267. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  268. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  269. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  270. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  271. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  272. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  273. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  274. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  275. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  276. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  277. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  278. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  279. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  280. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  281. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  282. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  283. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  284. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  285. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  286. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  287. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  288. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  289. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  290. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  291. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  292. package/authoring/_shared/contract.ts +22 -0
  293. package/authoring/codemod/codemod.doc.mjs +7 -2
  294. package/authoring/codemod/parse.d.mts +8 -8
  295. package/authoring/codemod/parse.mjs +8 -6
  296. package/authoring/codemod/type.ts +12 -0
  297. package/authoring/config/config.doc.mjs +11 -3
  298. package/authoring/config/debug-composition.test.mjs +92 -0
  299. package/authoring/config/parse.d.mts +15 -13
  300. package/authoring/config/parse.mjs +27 -8
  301. package/authoring/config/parse.test.mjs +8 -0
  302. package/authoring/config/type.ts +31 -8
  303. package/authoring/debug/debug.doc.d.mts +11 -0
  304. package/authoring/debug/debug.doc.mjs +182 -0
  305. package/authoring/debug/parse.d.mts +8 -8
  306. package/authoring/debug/parse.mjs +3 -3
  307. package/authoring/discover/discover.doc.d.mts +13 -0
  308. package/authoring/discover/discover.doc.mjs +138 -0
  309. package/authoring/discover/parse.d.mts +24 -0
  310. package/authoring/discover/parse.mjs +128 -0
  311. package/authoring/discover/parse.test.mjs +124 -0
  312. package/authoring/discover/type.ts +87 -0
  313. package/authoring/doctypes/_schema.d.mts +790 -23
  314. package/authoring/doctypes/_schema.mjs +543 -39
  315. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  316. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  317. package/authoring/doctypes/base/type.ts +41 -0
  318. package/authoring/doctypes/command/command.doc.mjs +5 -4
  319. package/authoring/doctypes/command/parse.d.mts +2 -2
  320. package/authoring/doctypes/command/parse.mjs +1 -1
  321. package/authoring/doctypes/command/type.ts +6 -5
  322. package/authoring/doctypes/component/component.doc.mjs +6 -3
  323. package/authoring/doctypes/component/parse.d.mts +2 -2
  324. package/authoring/doctypes/component/parse.mjs +1 -1
  325. package/authoring/doctypes/component/type.ts +6 -5
  326. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  327. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  328. package/authoring/doctypes/enum/parse.d.mts +2 -2
  329. package/authoring/doctypes/enum/parse.mjs +1 -1
  330. package/authoring/doctypes/enum/type.ts +4 -2
  331. package/authoring/doctypes/function/function.doc.mjs +7 -2
  332. package/authoring/doctypes/function/parse.d.mts +2 -2
  333. package/authoring/doctypes/function/parse.mjs +1 -1
  334. package/authoring/doctypes/function/type.ts +9 -4
  335. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  336. package/authoring/doctypes/hook/parse.d.mts +2 -2
  337. package/authoring/doctypes/hook/parse.mjs +1 -1
  338. package/authoring/doctypes/hook/type.ts +5 -4
  339. package/authoring/doctypes/legacy.d.mts +8 -6
  340. package/authoring/doctypes/legacy.mjs +5 -4
  341. package/authoring/doctypes/load-contract.test.mjs +233 -0
  342. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  343. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  344. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  345. package/authoring/doctypes/namespace/parse.mjs +25 -0
  346. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  347. package/authoring/doctypes/namespace/type.ts +74 -0
  348. package/authoring/doctypes/parse.d.mts +22 -18
  349. package/authoring/doctypes/parse.mjs +22 -11
  350. package/authoring/doctypes/parse.test.mjs +77 -3
  351. package/authoring/doctypes/reference/parse.d.mts +2 -2
  352. package/authoring/doctypes/reference/parse.mjs +8 -5
  353. package/authoring/doctypes/reference/reference.doc.mjs +48 -6
  354. package/authoring/doctypes/reference/type.ts +70 -7
  355. package/authoring/doctypes/schema/parse.d.mts +2 -2
  356. package/authoring/doctypes/schema/parse.mjs +1 -1
  357. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  358. package/authoring/doctypes/schema/type.ts +4 -4
  359. package/authoring/doctypes/template/parse.d.mts +94 -1
  360. package/authoring/doctypes/template/parse.mjs +40 -2
  361. package/authoring/doctypes/template/parse.test.mjs +26 -2
  362. package/authoring/doctypes/template/template.doc.mjs +13 -3
  363. package/authoring/doctypes/template/type.ts +13 -2
  364. package/authoring/doctypes/theme/parse.d.mts +35 -0
  365. package/authoring/doctypes/theme/parse.mjs +76 -0
  366. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  367. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  368. package/authoring/doctypes/theme/type.ts +42 -0
  369. package/authoring/doctypes/types.ts +12 -10
  370. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  371. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  372. package/authoring/gap-report/parse.d.mts +10 -10
  373. package/authoring/gap-report/parse.mjs +6 -6
  374. package/authoring/gap-report/type.ts +1 -1
  375. package/authoring/identity/identity.doc.d.mts +9 -0
  376. package/authoring/identity/identity.doc.mjs +61 -0
  377. package/authoring/identity/type.ts +132 -0
  378. package/authoring/index.d.mts +3 -0
  379. package/authoring/index.d.ts +62 -17
  380. package/authoring/index.mjs +4 -1
  381. package/authoring/integration/integration.doc.mjs +15 -8
  382. package/authoring/integration/parse.d.mts +2 -2
  383. package/authoring/integration/parse.mjs +1 -1
  384. package/authoring/integration/parse.test.mjs +10 -1
  385. package/authoring/integration/schema.d.mts +6 -4
  386. package/authoring/integration/schema.mjs +9 -3
  387. package/authoring/integration/type.ts +19 -8
  388. package/authoring/shadcn/receipt.d.mts +6 -6
  389. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  390. package/clients/cli/command-load-failure.test.mjs +83 -0
  391. package/clients/cli/command-result-coverage.test.mjs +7 -7
  392. package/clients/cli/commands/blog.doc.mjs +1 -1
  393. package/clients/cli/commands/blog.mjs +23 -8
  394. package/clients/cli/commands/blog.test.mjs +42 -1
  395. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  396. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  397. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  398. package/clients/cli/commands/build-theme.mjs +16 -50
  399. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  400. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  401. package/clients/cli/commands/build.doc.mjs +16 -8
  402. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  403. package/clients/cli/commands/build.mjs +137 -114
  404. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  405. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  406. package/clients/cli/commands/component/index.mjs +153 -61
  407. package/clients/cli/commands/component-batch.test.mjs +341 -0
  408. package/clients/cli/commands/component-ownership.test.mjs +92 -3
  409. package/clients/cli/commands/component-package.test.mjs +46 -0
  410. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  411. package/clients/cli/commands/component.doc.mjs +24 -7
  412. package/clients/cli/commands/component.test.mjs +19 -0
  413. package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
  414. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  415. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  416. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  417. package/clients/cli/commands/discover.doc.mjs +55 -9
  418. package/clients/cli/commands/discover.mjs +393 -118
  419. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  420. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  421. package/clients/cli/commands/docs.doc.mjs +28 -6
  422. package/clients/cli/commands/docs.mjs +240 -26
  423. package/clients/cli/commands/docs.test.mjs +222 -1
  424. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  425. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  426. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  427. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  428. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  429. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  430. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  431. package/clients/cli/commands/doctor.doc.mjs +1 -1
  432. package/clients/cli/commands/doctor.mjs +59 -32
  433. package/clients/cli/commands/doctor.test.mjs +42 -0
  434. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  435. package/clients/cli/commands/gap-report.test.mjs +72 -0
  436. package/clients/cli/commands/hook/index.mjs +7 -17
  437. package/clients/cli/commands/hook.doc.mjs +1 -1
  438. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  439. package/clients/cli/commands/init.doc.mjs +20 -9
  440. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  441. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  442. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  443. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  444. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  445. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  446. package/clients/cli/commands/integration.doc.mjs +1 -1
  447. package/clients/cli/commands/integration.mjs +1 -0
  448. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  449. package/clients/cli/commands/json-contract.test.mjs +33 -0
  450. package/clients/cli/commands/manifest.doc.mjs +1 -1
  451. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  452. package/clients/cli/commands/search.doc.mjs +7 -4
  453. package/clients/cli/commands/search.mjs +28 -9
  454. package/clients/cli/commands/search.test.mjs +75 -0
  455. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  456. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  457. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  458. package/clients/cli/commands/template.doc.mjs +52 -13
  459. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  460. package/clients/cli/commands/template.mjs +4 -91
  461. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  462. package/clients/cli/commands/text-json-parity.test.mjs +702 -0
  463. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  464. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  465. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  466. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  467. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  468. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  469. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  470. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  471. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  472. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  473. package/clients/cli/commands/theme.doc.mjs +1 -1
  474. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  475. package/clients/cli/commands/upgrade.doc.mjs +22 -10
  476. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  477. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  478. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  479. package/clients/cli/commands/upgrade.mjs +29 -7
  480. package/clients/cli/formatters/index.mjs +164 -1
  481. package/clients/cli/formatters/index.test.mjs +97 -0
  482. package/clients/cli/index.mjs +21 -34
  483. package/clients/cli/latest-version-env.test.mjs +50 -0
  484. package/clients/cli/lib/cli-error.test.mjs +7 -0
  485. package/clients/cli/lib/component-format.mjs +9 -9
  486. package/clients/cli/lib/component-format.test.mjs +1 -1
  487. package/clients/cli/lib/define-command.mjs +32 -6
  488. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  489. package/clients/cli/lib/exit-codes.test.mjs +90 -0
  490. package/clients/cli/lib/hook-format.mjs +19 -10
  491. package/clients/cli/lib/json-shim.mjs +62 -16
  492. package/clients/cli/lib/json-shim.test.mjs +69 -0
  493. package/clients/cli/lib/manifest.d.ts +2 -0
  494. package/clients/cli/lib/manifest.mjs +39 -10
  495. package/clients/cli/lib/manifest.test.mjs +22 -2
  496. package/clients/cli/lib/parse-error-format.test.mjs +81 -0
  497. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  498. package/foundation/agent-docs/agent-docs.mjs +82 -12
  499. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  500. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  501. package/foundation/config/integration-debug.test.mjs +28 -3
  502. package/foundation/config/project-themes.test.mjs +11 -19
  503. package/foundation/config/project.d.mts +20 -11
  504. package/foundation/config/project.mjs +263 -91
  505. package/foundation/config/project.test.mjs +270 -21
  506. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  507. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  508. package/foundation/discovery/authoring-self-docs.test.mjs +170 -0
  509. package/foundation/discovery/authoring-surface.d.mts +74 -0
  510. package/foundation/discovery/authoring-surface.mjs +525 -0
  511. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  512. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  513. package/foundation/discovery/cli-self-docs.mjs +490 -0
  514. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  515. package/foundation/discovery/component-discovery.d.mts +39 -1
  516. package/foundation/discovery/component-discovery.mjs +50 -1
  517. package/foundation/discovery/component-loader.d.mts +35 -38
  518. package/foundation/discovery/component-loader.mjs +53 -222
  519. package/foundation/discovery/docs-discovery.d.mts +119 -11
  520. package/foundation/discovery/docs-discovery.mjs +423 -108
  521. package/foundation/discovery/docs-discovery.test.mjs +365 -20
  522. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  523. package/foundation/discovery/docs-output-budget.mjs +50 -0
  524. package/foundation/discovery/docs-section-key.d.mts +116 -0
  525. package/foundation/discovery/docs-section-key.mjs +322 -0
  526. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  527. package/foundation/discovery/template-adapter.d.mts +113 -11
  528. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  529. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  530. package/foundation/discovery/template-adapter.mjs +775 -84
  531. package/foundation/discovery/template-adapter.test.mjs +57 -0
  532. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  533. package/foundation/discovery/template-conflict-release.mjs +40 -0
  534. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  535. package/foundation/discovery/theme-discovery.d.mts +67 -7
  536. package/foundation/discovery/theme-discovery.mjs +916 -186
  537. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  538. package/foundation/discovery/theming-targets.test.mjs +4 -0
  539. package/foundation/doc-compiler/bundle.d.mts +47 -0
  540. package/foundation/doc-compiler/bundle.mjs +278 -0
  541. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  542. package/foundation/doc-compiler/compile.d.mts +343 -0
  543. package/foundation/doc-compiler/compile.mjs +558 -0
  544. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  545. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  546. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  547. package/foundation/doc-compiler/doc-loads.test.mjs +1630 -0
  548. package/foundation/doc-compiler/import.d.mts +24 -0
  549. package/foundation/doc-compiler/import.mjs +59 -0
  550. package/foundation/doc-compiler/inputs.d.mts +102 -0
  551. package/foundation/doc-compiler/inputs.mjs +291 -0
  552. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  553. package/foundation/doc-compiler/ir.d.mts +22 -0
  554. package/foundation/doc-compiler/ir.mjs +471 -0
  555. package/foundation/doc-compiler/lenses.d.mts +36 -0
  556. package/foundation/doc-compiler/lenses.mjs +173 -0
  557. package/foundation/doc-compiler/links.d.mts +162 -0
  558. package/foundation/doc-compiler/links.mjs +294 -0
  559. package/foundation/doc-compiler/links.test.mjs +192 -0
  560. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  561. package/foundation/doc-compiler/overlays.d.mts +37 -0
  562. package/foundation/doc-compiler/overlays.mjs +206 -0
  563. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  564. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  565. package/foundation/doc-compiler/read.d.mts +127 -0
  566. package/foundation/doc-compiler/read.mjs +325 -0
  567. package/foundation/doc-compiler/read.test.mjs +313 -0
  568. package/foundation/doc-compiler/source.d.mts +33 -0
  569. package/foundation/doc-compiler/source.mjs +128 -0
  570. package/foundation/doc-compiler/tree.d.mts +288 -0
  571. package/foundation/doc-compiler/tree.mjs +876 -0
  572. package/foundation/doc-compiler/tree.test.mjs +606 -0
  573. package/foundation/fs/file-protection.d.mts +33 -0
  574. package/foundation/fs/file-protection.mjs +825 -0
  575. package/foundation/fs/file-protection.test.mjs +250 -0
  576. package/foundation/fs/module-loader.d.mts +1 -0
  577. package/foundation/fs/module-loader.mjs +50 -1
  578. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  579. package/foundation/fs/path-safety.d.mts +3 -2
  580. package/foundation/fs/path-safety.mjs +49 -19
  581. package/foundation/fs/path-safety.test.mjs +50 -0
  582. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  583. package/foundation/identity/provider-identity.d.mts +90 -0
  584. package/foundation/identity/provider-identity.mjs +320 -0
  585. package/foundation/identity/provider-identity.test.mjs +254 -0
  586. package/foundation/identity/providers.d.mts +7 -0
  587. package/foundation/identity/providers.mjs +16 -0
  588. package/foundation/integrations/autolink.d.mts +58 -1
  589. package/foundation/integrations/autolink.mjs +143 -45
  590. package/foundation/integrations/autolink.test.mjs +1 -1
  591. package/foundation/integrations/cli-requirement.d.mts +45 -0
  592. package/foundation/integrations/cli-requirement.mjs +154 -0
  593. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  594. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  595. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  596. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  597. package/foundation/integrations/contribution-inventory.mjs +27 -24
  598. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  599. package/foundation/integrations/integration-warnings.d.mts +9 -2
  600. package/foundation/integrations/integration-warnings.mjs +52 -21
  601. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  602. package/foundation/integrations/integrations.d.mts +63 -3
  603. package/foundation/integrations/integrations.mjs +122 -9
  604. package/foundation/integrations/integrations.test.mjs +415 -1
  605. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  606. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  607. package/foundation/integrations/provider-resolution.d.mts +152 -0
  608. package/foundation/integrations/provider-resolution.mjs +576 -0
  609. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  610. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  611. package/foundation/integrations/theme-descriptor.mjs +44 -0
  612. package/foundation/integrations/validate-contributions.d.mts +2 -0
  613. package/foundation/integrations/validate-contributions.mjs +131 -29
  614. package/foundation/response/base.d.ts +8 -4
  615. package/foundation/response/batch.type.d.mts +33 -0
  616. package/foundation/response/batch.type.mjs +34 -0
  617. package/foundation/response/error-codes.d.mts +3 -1
  618. package/foundation/response/error-codes.d.ts +2 -0
  619. package/foundation/response/error-codes.doc.mjs +13 -4
  620. package/foundation/response/error-codes.mjs +8 -2
  621. package/foundation/response/error-codes.test.mjs +137 -10
  622. package/foundation/response/json-contract.test.mjs +57 -17
  623. package/foundation/response/json.d.mts +4 -2
  624. package/foundation/response/json.mjs +8 -10
  625. package/foundation/response/response-types.doc.d.mts +5 -1
  626. package/foundation/response/response-types.doc.mjs +46 -38
  627. package/foundation/response/response-types.doc.test.mjs +181 -0
  628. package/foundation/response/response.doc.mjs +1 -1
  629. package/foundation/text/string-utils.d.mts +8 -0
  630. package/foundation/text/string-utils.mjs +40 -10
  631. package/foundation/xle/browser.d.mts +3 -3
  632. package/foundation/xle/browser.mjs +3 -3
  633. package/foundation/xle/expand.d.mts +2 -0
  634. package/foundation/xle/expand.mjs +6 -5
  635. package/foundation/xle/expand.test.mjs +54 -0
  636. package/foundation/xle/parse.mjs +1 -1
  637. package/foundation/xle/print.mjs +2 -2
  638. package/foundation/xle/splice.mjs +1 -1
  639. package/foundation/xle/xle.test.mjs +13 -0
  640. package/package.json +10 -11
  641. package/api/layout/_adapter.d.mts +0 -34
  642. package/api/layout/_adapter.mjs +0 -133
  643. package/api/layout/check/check.d.mts +0 -16
  644. package/api/layout/check/check.mjs +0 -40
  645. package/api/layout/expand/expand.d.mts +0 -22
  646. package/api/layout/expand/expand.mjs +0 -153
  647. package/api/layout/grammar/grammar.d.mts +0 -13
  648. package/api/layout/grammar/grammar.mjs +0 -86
  649. package/api/layout/layout.d.mts +0 -6
  650. package/api/layout/layout.mjs +0 -17
  651. package/api/layout/layout.test.mjs +0 -297
  652. package/api/layout/layout.type.d.mts +0 -89
  653. package/api/layout/layout.type.mjs +0 -103
  654. package/api/layout/layoutCheck.doc.d.mts +0 -11
  655. package/api/layout/layoutCheck.doc.mjs +0 -84
  656. package/api/layout/layoutExpand.doc.d.mts +0 -11
  657. package/api/layout/layoutExpand.doc.mjs +0 -106
  658. package/api/layout/layoutGrammar.doc.d.mts +0 -11
  659. package/api/layout/layoutGrammar.doc.mjs +0 -56
  660. package/assets/templates/themes/manifest.json +0 -95
  661. package/clients/cli/commands/layout-check.doc.mjs +0 -54
  662. package/clients/cli/commands/layout-expand.doc.mjs +0 -66
  663. package/clients/cli/commands/layout-grammar.doc.mjs +0 -30
  664. package/clients/cli/commands/layout.doc.mjs +0 -34
  665. package/clients/cli/commands/layout.error-codes.test.mjs +0 -66
  666. package/clients/cli/commands/layout.exit-parity.test.mjs +0 -41
  667. package/clients/cli/commands/layout.mjs +0 -263
  668. package/clients/cli/lib/update-check.mjs +0 -83
  669. package/clients/cli/lib/update-check.test.mjs +0 -137
  670. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -0,0 +1,341 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Multi-selector component lookup contract: one ordered batch envelope,
5
+ * complete per-selector states, unchanged single-selector responses, and matching
6
+ * text/JSON exit behavior.
7
+ */
8
+
9
+ import {describe, it, expect} from 'vitest';
10
+ import * as path from 'node:path';
11
+ import {
12
+ component,
13
+ COMPONENT_BATCH_SELECTOR_LIMIT,
14
+ } from '../../../api/component/component.mjs';
15
+ import {runCli} from '../../../test-utils/run-cli.mjs';
16
+
17
+ const REPO_ROOT = path.resolve(import.meta.dirname, '../../../../..');
18
+ const SLOW = 60_000;
19
+
20
+ describe('component() batch lookup', () => {
21
+ it(
22
+ 'keeps one found row per selector, in order, including duplicates',
23
+ async () => {
24
+ const result = await component(['Button', 'Badge', 'Button'], {
25
+ cwd: REPO_ROOT,
26
+ detail: 'brief',
27
+ });
28
+
29
+ expect(result.type).toBe('component.batch');
30
+ expect(result.data.count).toBe(3);
31
+ expect(result.data.results.map(row => row.selector)).toEqual([
32
+ 'Button',
33
+ 'Badge',
34
+ 'Button',
35
+ ]);
36
+ expect(result.data.results.map(row => row.status)).toEqual([
37
+ 'found',
38
+ 'found',
39
+ 'found',
40
+ ]);
41
+ expect(
42
+ result.data.results.map(row =>
43
+ row.status === 'found' ? row.result.type : null,
44
+ ),
45
+ ).toEqual(['component.detail', 'component.detail', 'component.detail']);
46
+ },
47
+ SLOW,
48
+ );
49
+
50
+ it(
51
+ 'applies every focused projection to each found row',
52
+ async () => {
53
+ const projections = [
54
+ {options: {props: true}, expectedType: 'component.detail.props'},
55
+ {options: {source: true}, expectedType: 'component.detail.source'},
56
+ {options: {showcase: true}, expectedType: 'component.detail.showcase'},
57
+ {options: {blocks: true}, expectedType: 'component.detail.blocks'},
58
+ ];
59
+ for (const projection of projections) {
60
+ const result = await component(['Button', 'Card'], {
61
+ cwd: REPO_ROOT,
62
+ ...projection.options,
63
+ });
64
+ expect(result.type).toBe('component.batch');
65
+ expect(
66
+ result.data.results.map(row =>
67
+ row.status === 'found' ? row.result.type : null,
68
+ ),
69
+ ).toEqual([projection.expectedType, projection.expectedType]);
70
+ }
71
+ },
72
+ SLOW,
73
+ );
74
+
75
+ it(
76
+ 'uses input shape to distinguish catalog, single, and batch calls',
77
+ async () => {
78
+ expect((await component(undefined, {cwd: REPO_ROOT})).type).toBe(
79
+ 'component.list',
80
+ );
81
+ expect((await component('Button', {cwd: REPO_ROOT})).type).toBe(
82
+ 'component.detail',
83
+ );
84
+
85
+ const emptyBatch = await component([], {cwd: REPO_ROOT});
86
+ expect(emptyBatch).toEqual({
87
+ type: 'component.batch',
88
+ data: {count: 0, results: []},
89
+ });
90
+ expect(
91
+ await component([], {
92
+ cwd: REPO_ROOT,
93
+ list: true,
94
+ category: 'Form',
95
+ }),
96
+ ).toEqual(emptyBatch);
97
+
98
+ const oneRowBatch = await component(['Button'], {
99
+ cwd: REPO_ROOT,
100
+ detail: 'brief',
101
+ });
102
+ expect(oneRowBatch).toMatchObject({
103
+ type: 'component.batch',
104
+ data: {
105
+ count: 1,
106
+ results: [
107
+ {
108
+ selector: 'Button',
109
+ status: 'found',
110
+ result: {type: 'component.detail'},
111
+ },
112
+ ],
113
+ },
114
+ });
115
+ },
116
+ SLOW,
117
+ );
118
+
119
+ it('rejects an oversized array before component resolution starts', async () => {
120
+ const selectors = Array.from(
121
+ {length: COMPONENT_BATCH_SELECTOR_LIMIT + 1},
122
+ () => 'Button',
123
+ );
124
+ await expect(
125
+ component(selectors, {
126
+ cwd: path.join(REPO_ROOT, 'missing-batch-cwd'),
127
+ }),
128
+ ).rejects.toMatchObject({
129
+ code: 'ERR_INVALID_ARGUMENT',
130
+ message: `Component batch accepts at most ${COMPONENT_BATCH_SELECTOR_LIMIT} selectors; received ${selectors.length}`,
131
+ });
132
+ });
133
+
134
+ it(
135
+ 'keeps receipt invariants across a deterministic selector chaos matrix',
136
+ async () => {
137
+ const found = new Set(['Button', 'Card']);
138
+ const selectorCases = [
139
+ [],
140
+ ['Button'],
141
+ ['ZzzNope99'],
142
+ ['Button', 'Button'],
143
+ ['ZzzNope98', 'ZzzNope99'],
144
+ ['Button', 'ZzzNope99', 'Card'],
145
+ ['ZzzNope99', 'Button', 'ZzzNope99', 'Button'],
146
+ ['Card', 'Button', 'Card', 'ZzzNope98', 'Button'],
147
+ ];
148
+
149
+ for (const selectors of selectorCases) {
150
+ const result = await component(selectors, {
151
+ cwd: REPO_ROOT,
152
+ detail: 'brief',
153
+ });
154
+ expect(result.type).toBe('component.batch');
155
+ expect(result.data.count).toBe(selectors.length);
156
+ expect(result.data.results.map(row => row.selector)).toEqual(selectors);
157
+ expect(result.data.results.map(row => row.status)).toEqual(
158
+ selectors.map(selector =>
159
+ found.has(selector) ? 'found' : 'not_found',
160
+ ),
161
+ );
162
+ for (const row of result.data.results) {
163
+ if (row.status === 'found') {
164
+ expect(row.result.type).toBe('component.detail');
165
+ } else {
166
+ expect(row.code).toBe('ERR_UNKNOWN_COMPONENT');
167
+ }
168
+ }
169
+ }
170
+ },
171
+ SLOW,
172
+ );
173
+
174
+ it(
175
+ 'composes every detail and language control over a batch',
176
+ async () => {
177
+ /** @type {Array<{detail?: 'full'|'compact'|'brief'; lang?: string; zh?: boolean; dense?: boolean}>} */
178
+ const controls = [
179
+ {detail: 'brief'},
180
+ {detail: 'compact'},
181
+ {detail: 'full'},
182
+ {lang: 'en'},
183
+ {lang: 'dense'},
184
+ {zh: true},
185
+ {dense: true},
186
+ ];
187
+ for (const control of controls) {
188
+ const result = await component(['Button', 'Card'], {
189
+ cwd: REPO_ROOT,
190
+ ...control,
191
+ });
192
+ expect(result.type).toBe('component.batch');
193
+ expect(result.data.results).toHaveLength(2);
194
+ expect(
195
+ result.data.results.every(
196
+ row =>
197
+ row.status === 'found' && row.result.type === 'component.detail',
198
+ ),
199
+ ).toBe(true);
200
+ }
201
+ },
202
+ SLOW,
203
+ );
204
+ });
205
+
206
+ describe('astryx component batch lookup', () => {
207
+ it('documents variadic selector grammar in --help', async () => {
208
+ const run = await runCli(['component', '--help'], REPO_ROOT);
209
+ expect(run.code).toBe(0);
210
+ expect(run.stdout).toContain(
211
+ 'Usage: astryx component [options] [names...]',
212
+ );
213
+ expect(run.stdout).toContain('@scope/package@version/Name');
214
+ expect(run.stdout).toContain('Two or more return one ordered batch');
215
+ expect(run.stdout).toContain('At most 100 selectors');
216
+ });
217
+
218
+ it(
219
+ 'keeps catalog and single-result CLI envelopes at zero and one selectors',
220
+ async () => {
221
+ const catalog = await runCli(['--json', 'component'], REPO_ROOT);
222
+ expect(catalog.code).toBe(0);
223
+ expect(JSON.parse(catalog.stdout).type).toBe('component.list');
224
+
225
+ const single = await runCli(
226
+ ['--json', '--detail', 'brief', 'component', 'Button'],
227
+ REPO_ROOT,
228
+ );
229
+ expect(single.code).toBe(0);
230
+ expect(JSON.parse(single.stdout).type).toBe('component.detail');
231
+ },
232
+ SLOW,
233
+ );
234
+
235
+ it(
236
+ 'emits one component.batch JSON envelope for several found selectors',
237
+ async () => {
238
+ const run = await runCli(
239
+ ['--json', '--detail', 'brief', 'component', 'Button', 'Badge'],
240
+ REPO_ROOT,
241
+ );
242
+ expect(run.code).toBe(0);
243
+ const envelope = JSON.parse(run.stdout);
244
+ expect(envelope.type).toBe('component.batch');
245
+ expect(envelope.data.count).toBe(2);
246
+ expect(envelope.data.results.map(row => row.selector)).toEqual([
247
+ 'Button',
248
+ 'Badge',
249
+ ]);
250
+ expect(envelope.data.results.every(row => row.status === 'found')).toBe(
251
+ true,
252
+ );
253
+ },
254
+ SLOW,
255
+ );
256
+
257
+ it(
258
+ 'rejects an oversized batch before emitting JSON or text results',
259
+ async () => {
260
+ const selectors = Array.from(
261
+ {length: COMPONENT_BATCH_SELECTOR_LIMIT + 1},
262
+ () => 'Button',
263
+ );
264
+ const json = await runCli(
265
+ ['--json', 'component', ...selectors],
266
+ REPO_ROOT,
267
+ );
268
+ expect(json.code).toBe(1);
269
+ expect(JSON.parse(json.stdout)).toMatchObject({
270
+ code: 'ERR_INVALID_ARGUMENT',
271
+ error: `Component batch accepts at most ${COMPONENT_BATCH_SELECTOR_LIMIT} selectors; received ${selectors.length}`,
272
+ });
273
+ expect(JSON.parse(json.stdout).type).toBeUndefined();
274
+
275
+ const text = await runCli(['component', ...selectors], REPO_ROOT);
276
+ expect(text.code).toBe(1);
277
+ expect(text.stdout + text.stderr).toContain(
278
+ `accepts at most ${COMPONENT_BATCH_SELECTOR_LIMIT} selectors`,
279
+ );
280
+ },
281
+ SLOW,
282
+ );
283
+
284
+ it(
285
+ 'emits every row and exits 1 when one selector is not found',
286
+ async () => {
287
+ const run = await runCli(
288
+ ['--json', '--detail', 'brief', 'component', 'Button', 'ZzzNope99'],
289
+ REPO_ROOT,
290
+ );
291
+ expect(run.code).toBe(1);
292
+ const envelope = JSON.parse(run.stdout);
293
+ expect(envelope.type).toBe('component.batch');
294
+ expect(envelope.data.results).toMatchObject([
295
+ {selector: 'Button', status: 'found'},
296
+ {
297
+ selector: 'ZzzNope99',
298
+ status: 'not_found',
299
+ code: 'ERR_UNKNOWN_COMPONENT',
300
+ },
301
+ ]);
302
+ },
303
+ SLOW,
304
+ );
305
+
306
+ it(
307
+ 'emits every failed row and exits 1 when no selector resolves',
308
+ async () => {
309
+ const run = await runCli(
310
+ ['--json', 'component', 'ZzzNope98', 'ZzzNope99'],
311
+ REPO_ROOT,
312
+ );
313
+ expect(run.code).toBe(1);
314
+ const envelope = JSON.parse(run.stdout);
315
+ expect(envelope.type).toBe('component.batch');
316
+ expect(envelope.data.count).toBe(2);
317
+ expect(envelope.data.results).toMatchObject([
318
+ {selector: 'ZzzNope98', status: 'not_found'},
319
+ {selector: 'ZzzNope99', status: 'not_found'},
320
+ ]);
321
+ },
322
+ SLOW,
323
+ );
324
+
325
+ it(
326
+ 'projects every row in text and keeps the same failing exit status',
327
+ async () => {
328
+ const run = await runCli(
329
+ ['--detail', 'brief', 'component', 'Button', 'ZzzNope99'],
330
+ REPO_ROOT,
331
+ );
332
+ expect(run.code).toBe(1);
333
+ expect(run.stdout).toContain('count: 2');
334
+ expect(run.stdout).toMatch(/selector: Button\nstatus:\s+found/);
335
+ expect(run.stdout).toMatch(
336
+ /selector: ZzzNope99\nstatus:\s+not_found\ncode:\s+ERR_UNKNOWN_COMPONENT/,
337
+ );
338
+ },
339
+ SLOW,
340
+ );
341
+ });
@@ -71,7 +71,7 @@ function createFixture({
71
71
  );
72
72
  fs.writeFileSync(
73
73
  path.join(compDir, 'MetaAppShell.doc.mjs'),
74
- `export const docs = {\n name: 'MetaAppShell',\n usage: { description: 'Meta-flavored app shell.' },\n props: [{ name: 'title', type: 'string', description: 'Header title' }],\n};\n`,
74
+ `export default {\n type: 'component',\n name: 'MetaAppShell',\n usage: { description: 'Meta-flavored app shell.' },\n props: [{ name: 'title', type: 'string', description: 'Header title' }],\n};\n`,
75
75
  );
76
76
  if (withSource) {
77
77
  fs.writeFileSync(
@@ -82,7 +82,7 @@ function createFixture({
82
82
  if (extraComponent) {
83
83
  fs.writeFileSync(
84
84
  path.join(compDir, `${extraComponent}.doc.mjs`),
85
- `export const docs = {\n name: '${extraComponent}',\n usage: { description: '${extraComponent} from meta.' },\n};\n`,
85
+ `export default {\n type: 'component',\n name: '${extraComponent}',\n usage: { description: '${extraComponent} from meta.' },\n props: [],\n};\n`,
86
86
  );
87
87
  fs.writeFileSync(
88
88
  path.join(compDir, `${extraComponent}.tsx`),
@@ -100,7 +100,7 @@ function createFixture({
100
100
  : '';
101
101
  fs.writeFileSync(
102
102
  path.join(entryDir, `${entryPoint.component}.doc.mjs`),
103
- `export const docs = {\n name: '${entryPoint.component}',${ownSpecifier}\n usage: { description: '${entryPoint.component} from an entry point.' },\n};\n`,
103
+ `export default {\n type: 'component',\n name: '${entryPoint.component}',${ownSpecifier}\n usage: { description: '${entryPoint.component} from an entry point.' },\n props: [],\n};\n`,
104
104
  );
105
105
  }
106
106
 
@@ -277,6 +277,95 @@ describe('component() — integration ownership via config', () => {
277
277
  expect(result.data.import).toBe(`${INTEGRATION_NAME}/Toolbar/Search`);
278
278
  });
279
279
 
280
+ it('reports every installed candidate for an ambiguous batch selector', async () => {
281
+ createFixture({extraComponent: 'AppShell'});
282
+ const result = await component(['MetaAppShell', 'AppShell'], {cwd: tmpDir});
283
+ expect(result.type).toBe('component.batch');
284
+ expect(result.data.results[0]).toMatchObject({
285
+ selector: 'MetaAppShell',
286
+ status: 'found',
287
+ });
288
+ expect(result.data.results[1]).toMatchObject({
289
+ selector: 'AppShell',
290
+ status: 'ambiguous',
291
+ code: 'ERR_UNKNOWN_COMPONENT',
292
+ });
293
+ expect(result.data.results[1].candidates).toEqual(
294
+ expect.arrayContaining([
295
+ {
296
+ package: CORE_PACKAGE,
297
+ component: 'AppShell',
298
+ kind: 'component',
299
+ installed: true,
300
+ },
301
+ {
302
+ package: INTEGRATION_NAME,
303
+ component: 'AppShell',
304
+ kind: 'component',
305
+ installed: true,
306
+ },
307
+ ]),
308
+ );
309
+ });
310
+
311
+ it('keeps the single-result envelope for one package-qualified selector', async () => {
312
+ createFixture();
313
+ const result = await component('@test/meta@1.2.3/MetaAppShell', {
314
+ cwd: tmpDir,
315
+ });
316
+ expect(result.type).toBe('component.detail');
317
+ expect(result.data).toMatchObject({
318
+ name: 'MetaAppShell',
319
+ package: INTEGRATION_NAME,
320
+ });
321
+ });
322
+
323
+ it('resolves an exact installed package version and refuses another version', async () => {
324
+ createFixture();
325
+ const result = await component(
326
+ [
327
+ '@test/meta@1.2.3/MetaAppShell',
328
+ '@test/meta@9.9.9/MetaAppShell',
329
+ ],
330
+ {cwd: tmpDir},
331
+ );
332
+ expect(result.type).toBe('component.batch');
333
+ expect(result.data.results[0]).toMatchObject({
334
+ selector: '@test/meta@1.2.3/MetaAppShell',
335
+ status: 'found',
336
+ result: {type: 'component.detail'},
337
+ });
338
+ expect(result.data.results[1]).toMatchObject({
339
+ selector: '@test/meta@9.9.9/MetaAppShell',
340
+ status: 'not_found',
341
+ code: 'ERR_UNKNOWN_PACKAGE',
342
+ suggestions: [
343
+ {
344
+ name: 'astryx discover @test/meta@9.9.9',
345
+ reason: 'look up this package version',
346
+ },
347
+ ],
348
+ });
349
+ });
350
+
351
+ it('reports a package-qualified selector that conflicts with --package', async () => {
352
+ createFixture();
353
+ const result = await component(
354
+ ['@test/meta/MetaAppShell', 'Button'],
355
+ {cwd: tmpDir, package: CORE_PACKAGE},
356
+ );
357
+ expect(result.type).toBe('component.batch');
358
+ expect(result.data.results[0]).toMatchObject({
359
+ selector: '@test/meta/MetaAppShell',
360
+ status: 'error',
361
+ code: 'ERR_INVALID_ARGUMENT',
362
+ });
363
+ expect(result.data.results[1]).toMatchObject({
364
+ selector: 'Button',
365
+ status: 'found',
366
+ });
367
+ });
368
+
280
369
  it('JSON list includes integration components as {name, package} objects', async () => {
281
370
  createFixture();
282
371
  const result = await component(undefined, {cwd: tmpDir, list: true});
@@ -5,6 +5,7 @@ import * as fs from 'node:fs';
5
5
  import * as path from 'node:path';
6
6
  import * as os from 'node:os';
7
7
  import {component} from '../../../api/component/component.mjs';
8
+ import {runCli} from '../../../test-utils/run-cli.mjs';
8
9
 
9
10
  // These tests create a minimal monorepo fixture with:
10
11
  // - packages/core (symlinked to real @astryxdesign/core for loadDocs compatibility)
@@ -120,4 +121,49 @@ describe('component() with --package option', () => {
120
121
  expect(result.data.source).toContain('ProfileCardShowcase');
121
122
  expect(result.data.aspectRatio).toBeCloseTo(16 / 9);
122
123
  });
124
+
125
+ // A legacy package ships docs only: --source and --blocks answer the same
126
+ // way scoped as unscoped, never falling back to the plain doc.
127
+ it('--package + --source reports the missing source, like the unscoped lookup', async () => {
128
+ await expect(
129
+ component('ProfileCard', {cwd: tmpDir, source: true}),
130
+ ).rejects.toMatchObject({code: 'ERR_NO_SOURCE'});
131
+ await expect(
132
+ component('ProfileCard', {cwd: tmpDir, package: '@test/ext', source: true}),
133
+ ).rejects.toMatchObject({code: 'ERR_NO_SOURCE'});
134
+ });
135
+
136
+ it('--package + --blocks returns the blocks, like the unscoped lookup', async () => {
137
+ const unscoped = await component('ProfileCard', {cwd: tmpDir, blocks: true});
138
+ const scoped = await component('ProfileCard', {cwd: tmpDir, package: '@test/ext', blocks: true});
139
+ expect(scoped.type).toBe('component.detail.blocks');
140
+ expect(scoped.data).toEqual(unscoped.data);
141
+ });
142
+
143
+ // `cwd` is an explicit API input: --blocks must discover from it, as
144
+ // --showcase does, not from the process working directory.
145
+ it('--blocks discovers blocks from options.cwd, like --showcase', async () => {
146
+ const showcase = await component('ProfileCard', {cwd: tmpDir, showcase: true});
147
+ expect(showcase.data.source).toContain('ProfileCardShowcase');
148
+
149
+ const blocks = await component('ProfileCard', {cwd: tmpDir, blocks: true});
150
+ expect(blocks.type).toBe('component.detail.blocks');
151
+ expect(blocks.data.showcase?.name).toBe('ProfileCardShowcase');
152
+ });
153
+
154
+ // List and detail report one import for a legacy package component; the
155
+ // text list projects the JSON value instead of deriving a Core path.
156
+ it('the names list gives a legacy package component the import its detail reports', async () => {
157
+ const detail = await component('ProfileCard', {cwd: tmpDir});
158
+ const list = await component(undefined, {cwd: tmpDir, list: true});
159
+ const entry = Object.values(list.data.components)
160
+ .flat()
161
+ .find(e => e.name === 'ProfileCard' && e.package === '@test/ext');
162
+ expect(entry?.import).toBe(detail.data.import);
163
+
164
+ const text = await runCli(['component', '--list'], tmpDir);
165
+ expect(text.code).toBe(0);
166
+ expect(text.stdout).toContain(`name: ProfileCard\nimport: ${detail.data.import} [@test/ext]`);
167
+ expect(text.stdout).not.toMatch(/^import: +@astryxdesign\/core\S* +\[@test\/ext\]$/m);
168
+ });
123
169
  });
@@ -3,6 +3,7 @@
3
3
  import {describe, it, expect} from 'vitest';
4
4
  import {component} from '../../../api/component/component.mjs';
5
5
  import {findShowcase, findRelatedBlocks} from '../../../api/template/template.mjs';
6
+ import {runCli} from '../../../test-utils/run-cli.mjs';
6
7
 
7
8
  const CWD = {cwd: '.'};
8
9
 
@@ -74,6 +75,26 @@ describe('component() sub-component scoping', () => {
74
75
  const result = await component('SideNav', CWD);
75
76
  expect(result.data.name).toBe('SideNav');
76
77
  });
78
+
79
+ // `parentDoc` is part of the component.detail schema: the text view
80
+ // projects it under the same key.
81
+ it('component("HStack") names its parent doc in JSON and text', async () => {
82
+ const result = await component('HStack', CWD);
83
+ expect(result.data.parentDoc).toBe('Stack');
84
+
85
+ const text = await runCli(['component', 'HStack'], process.cwd());
86
+ expect(text.code).toBe(0);
87
+ expect(text.stdout).toMatch(/^parentDoc: +Stack$/m);
88
+ });
89
+
90
+ it('component("Stack") carries no parentDoc in JSON or text', async () => {
91
+ const result = await component('Stack', CWD);
92
+ expect(result.data).not.toHaveProperty('parentDoc');
93
+
94
+ const text = await runCli(['component', 'Stack'], process.cwd());
95
+ expect(text.code).toBe(0);
96
+ expect(text.stdout).not.toMatch(/^parentDoc:/m);
97
+ });
77
98
  }, SCAN_TIMEOUT);
78
99
 
79
100
  // ─── Bug: findShowcase priority ─────────────────────────────────
@@ -13,14 +13,26 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'component',
15
15
  displayName: 'astryx component',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'List components or print component docs',
18
18
  description:
19
- 'Resolves a component by name across core and integration packages and prints ' +
20
- 'its authored doc, or lists the catalog grouped by category. Boolean flags narrow ' +
21
- 'a single component to just its props, source, showcase, or example blocks.',
19
+ 'Resolves one or several components by exact selector across core and integration ' +
20
+ 'packages and prints each authored doc, or lists the catalog grouped by category. ' +
21
+ "Use 'Button', 'widgets/Button', '@acme/widgets/Button', or " +
22
+ "'@acme/widgets@1.2.3/Button'. A version applies to the package and must match the " +
23
+ 'installed version. Boolean flags narrow every resolved component to just its props, ' +
24
+ 'source, showcase, or example blocks.',
22
25
  fn: 'component',
23
- args: [{name: 'name', param: 'name', required: false}],
26
+ args: [
27
+ {
28
+ name: 'names',
29
+ param: 'name',
30
+ description:
31
+ 'One or more exact selectors. Use Name, package/Name, @scope/package/Name, or @scope/package@version/Name. Two or more return one ordered batch. At most 100 selectors are accepted.',
32
+ required: false,
33
+ variadic: true,
34
+ },
35
+ ],
24
36
  options: [
25
37
  {
26
38
  flag: '--list',
@@ -55,11 +67,16 @@ export const doc = {
55
67
  {
56
68
  flag: '--package <name>',
57
69
  param: 'options.package',
58
- description: 'Scope lookup to an external package (e.g. @acme/xds-widgets)',
70
+ description:
71
+ 'Scope lookup to an external package (e.g. @acme/xds-widgets)',
59
72
  },
60
73
  ],
61
74
  examples: [
62
75
  {label: 'Browse the catalog', cli: 'astryx component --list'},
76
+ {
77
+ label: 'Look up several components',
78
+ cli: 'astryx component Button Badge Text',
79
+ },
63
80
  {
64
81
  label: 'Props table as JSON',
65
82
  cli: 'astryx component XDSButton --props --json',
@@ -69,7 +86,7 @@ export const doc = {
69
86
  {code: 0, when: 'success'},
70
87
  {
71
88
  code: 1,
72
- when: 'unknown component, category, or package, or @astryxdesign/core cannot be resolved',
89
+ when: 'unknown component, category, or package; more than 100 selectors; any batch row is unresolved; or @astryxdesign/core cannot be resolved',
73
90
  },
74
91
  ],
75
92
  related: ['search', 'hook', 'docs', 'template', 'swizzle'],
@@ -13,6 +13,9 @@ import {
13
13
  levenshteinDistance,
14
14
  findClosestComponents,
15
15
  } from './component/index.mjs';
16
+ import {runCli} from '../../../test-utils/run-cli.mjs';
17
+
18
+ const REPO_ROOT = path.resolve(import.meta.dirname, '../../../../..');
16
19
 
17
20
  let tmpDir;
18
21
 
@@ -591,3 +594,19 @@ describe('searchComponents', () => {
591
594
  expect(results.length).toBe(0);
592
595
  });
593
596
  });
597
+
598
+ describe('component <Name> text output', () => {
599
+ // The text is a projection of the JSON envelope: it may show less, never
600
+ // data the envelope does not carry.
601
+ it('shows no related-block records that the JSON lacks', async () => {
602
+ const json = await runCli(['--json', 'component', 'Button'], REPO_ROOT);
603
+ expect(json.code).toBe(0);
604
+ expect(JSON.stringify(JSON.parse(json.stdout).data)).not.toContain('dirName');
605
+
606
+ const text = await runCli(['component', 'Button'], REPO_ROOT);
607
+ expect(text.code).toBe(0);
608
+ expect(text.stdout).toContain('# Button');
609
+ expect(text.stdout).not.toMatch(/^dirName:/m);
610
+ expect(text.stdout).not.toContain('Related block templates');
611
+ }, 30_000);
612
+ });
@@ -179,9 +179,9 @@ describe('DebugEvent result summary', () => {
179
179
  it(
180
180
  'says so explicitly when a command has no result set',
181
181
  async () => {
182
- // `layout check` returns a verdict on one expression: nothing was looked
182
+ // Bare `integration` prints its subcommand list: nothing was looked
183
183
  // up, and the run says that rather than leaving four ambiguous nulls.
184
- const {event} = await runWithDebug(['layout', 'check', 'VStack>Text']);
184
+ const {event} = await runWithDebug(['integration']);
185
185
  expect(event.output).toMatchObject({
186
186
  resultKind: 'none',
187
187
  resultCount: null,
@@ -52,7 +52,7 @@ describe('--detail level ordering: component --list', () => {
52
52
 
53
53
  it('brief is names-only (no targets, import hints, or prose descriptions)', () => {
54
54
  expect(brief).not.toMatch(/Targets:/);
55
- expect(brief).not.toMatch(/\u2190 from/);
55
+ expect(brief).not.toMatch(/<- from/);
56
56
  // Names only — should contain XDS component names but no " — " desc separator.
57
57
  expect(brief).toMatch(/Button/);
58
58
  expect(brief).not.toMatch(/ \u2014 /);
@@ -66,7 +66,7 @@ describe('--detail level ordering: component --list', () => {
66
66
 
67
67
  it('full has dense per-entry docs (props, targets, and import hints)', () => {
68
68
  expect(full).toMatch(/Targets:/);
69
- expect(full).toMatch(/\u2190 from/);
69
+ expect(full).toMatch(/<- from/);
70
70
  // Prop name lists appear in the dense brief-all rendering.
71
71
  expect(full).toMatch(/children/);
72
72
  });