@astryxdesign/cli 0.6.3-canary.ea2f048 → 0.6.3-canary.ee13359

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 (571) hide show
  1. package/README.md +114 -76
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/build.doc.mjs +4 -3
  4. package/api/build/build.test.mjs +14 -3
  5. package/api/build/build.type.d.mts +36 -2
  6. package/api/build/build.type.mjs +25 -4
  7. package/api/build/help/help.d.mts +8 -5
  8. package/api/build/help/help.mjs +56 -6
  9. package/api/component/_adapter.d.mts +6 -12
  10. package/api/component/_adapter.mjs +20 -10
  11. package/api/component/component.doc.mjs +13 -3
  12. package/api/component/component.mjs +91 -14
  13. package/api/component/component.test.mjs +38 -0
  14. package/api/component/component.type.d.mts +22 -11
  15. package/api/component/component.type.mjs +32 -24
  16. package/api/component/detail/blocks/blocks.d.mts +2 -1
  17. package/api/component/detail/blocks/blocks.mjs +4 -3
  18. package/api/component/list/list.d.mts +0 -5
  19. package/api/component/list/list.mjs +40 -11
  20. package/api/discover/discover.doc.mjs +2 -1
  21. package/api/discover/discover.type.d.mts +4 -4
  22. package/api/discover/discover.type.mjs +10 -10
  23. package/api/docs/_adapter.d.mts +230 -41
  24. package/api/docs/_adapter.mjs +734 -108
  25. package/api/docs/compiled-topics.test.mjs +78 -0
  26. package/api/docs/detail/detail.mjs +22 -63
  27. package/api/docs/detail/section/section.d.mts +1 -1
  28. package/api/docs/detail/section/section.mjs +54 -19
  29. package/api/docs/detail/section/section.test.mjs +50 -0
  30. package/api/docs/docs.d.mts +10 -3
  31. package/api/docs/docs.doc.mjs +54 -16
  32. package/api/docs/docs.mjs +53 -10
  33. package/api/docs/docs.test.mjs +164 -4
  34. package/api/docs/docs.type.d.mts +205 -5
  35. package/api/docs/docs.type.mjs +137 -11
  36. package/api/docs/index/index.d.mts +18 -0
  37. package/api/docs/index/index.mjs +40 -0
  38. package/api/docs/index/index.test.mjs +62 -0
  39. package/api/docs/integration-tree.test.mjs +547 -0
  40. package/api/docs/integrationDocs.test.mjs +114 -8
  41. package/api/docs/list/list.mjs +28 -12
  42. package/api/docs/node/node.d.mts +43 -0
  43. package/api/docs/node/node.mjs +192 -0
  44. package/api/doctor/doctor.d.mts +99 -1
  45. package/api/doctor/doctor.doc.mjs +1 -0
  46. package/api/doctor/doctor.mjs +544 -1
  47. package/api/doctor/doctor.test.mjs +610 -1
  48. package/api/gap-report/gap-report.doc.mjs +8 -4
  49. package/api/hook/_adapter.mjs +19 -5
  50. package/api/hook/hook.doc.mjs +1 -0
  51. package/api/hook/hook.type.d.mts +3 -3
  52. package/api/hook/hook.type.mjs +11 -11
  53. package/api/hook/list/list.d.mts +2 -2
  54. package/api/hook/list/list.mjs +69 -17
  55. package/api/index.d.mts +1 -1
  56. package/api/index.mjs +1 -0
  57. package/api/init/init.doc.mjs +6 -1
  58. package/api/init/init.test.mjs +41 -1
  59. package/api/init/remove/remove.mjs +1 -1
  60. package/api/init/run/run.mjs +20 -10
  61. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  62. package/api/integration/add-contribution.d.mts +2 -1
  63. package/api/integration/add-contribution.mjs +130 -15
  64. package/api/integration/add-contribution.test.mjs +258 -7
  65. package/api/integration/add-theme.mjs +34 -64
  66. package/api/integration/add-theme.test.mjs +105 -21
  67. package/api/integration/authoring-checks.mjs +108 -31
  68. package/api/integration/authoring-checks.test.mjs +171 -6
  69. package/api/integration/authoring-checks.type.d.mts +3 -1
  70. package/api/integration/authoring-checks.type.mjs +3 -1
  71. package/api/integration/integration-authoring.type.d.mts +3 -1
  72. package/api/integration/integration-authoring.type.mjs +2 -0
  73. package/api/integration/integration-block-exports.test.mjs +10 -6
  74. package/api/integration/integrationAdd.doc.mjs +14 -4
  75. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  76. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  77. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  78. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  79. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  80. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  81. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  82. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  83. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  84. package/api/integration/integrationTemplateConflicts.doc.mjs +7 -5
  85. package/api/integration/pack-check.mjs +83 -7
  86. package/api/integration/pack-check.test.mjs +387 -47
  87. package/api/integration/pack-check.type.d.mts +26 -2
  88. package/api/integration/pack-check.type.mjs +14 -1
  89. package/api/integration/summarizeIssues.doc.mjs +1 -0
  90. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  91. package/api/integration/validate-integration.mjs +52 -102
  92. package/api/integration/validate-integration.test.mjs +179 -26
  93. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  94. package/api/integration/validateIntegration.doc.mjs +3 -2
  95. package/api/json/assertResponse.doc.mjs +1 -0
  96. package/api/json/envelope-types.test.mjs +76 -0
  97. package/api/json/index.ts +2 -0
  98. package/api/json/isError.doc.mjs +1 -0
  99. package/api/json/parseResponse.doc.mjs +3 -2
  100. package/api/layout/_adapter.mjs +20 -5
  101. package/api/layout/expand/expand.mjs +7 -5
  102. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  103. package/api/layout/grammar/grammar.mjs +2 -1
  104. package/api/layout/layoutCheck.doc.mjs +1 -0
  105. package/api/layout/layoutExpand.doc.mjs +2 -1
  106. package/api/layout/layoutGrammar.doc.mjs +1 -0
  107. package/api/search/search-return-type.test.mjs +54 -0
  108. package/api/search/search.d.mts +29 -11
  109. package/api/search/search.doc.mjs +8 -2
  110. package/api/search/search.mjs +337 -41
  111. package/api/search/search.test.mjs +124 -1
  112. package/api/search/search.type.d.mts +15 -3
  113. package/api/search/search.type.mjs +5 -2
  114. package/api/swizzle/copy/copy.mjs +28 -11
  115. package/api/swizzle/swizzle.doc.mjs +2 -1
  116. package/api/swizzle/swizzle.type.d.mts +2 -2
  117. package/api/swizzle/swizzle.type.mjs +2 -2
  118. package/api/template/copy/copy.mjs +17 -23
  119. package/api/template/copy/copy.test.mjs +17 -0
  120. package/api/template/list/list.mjs +1 -0
  121. package/api/template/template-integration.test.mjs +1022 -3
  122. package/api/template/template-suffix.test.mjs +41 -21
  123. package/api/template/template.d.mts +1 -1
  124. package/api/template/template.doc.mjs +30 -8
  125. package/api/template/template.mjs +45 -8
  126. package/api/template/template.type.d.mts +12 -14
  127. package/api/template/template.type.mjs +15 -14
  128. package/api/theme/_adapter.d.mts +2 -3
  129. package/api/theme/_adapter.mjs +4 -5
  130. package/api/theme/add/add.binary.test.mjs +84 -0
  131. package/api/theme/add/add.mjs +20 -3
  132. package/api/theme/add/add.staging.test.mjs +66 -0
  133. package/api/theme/add/add.test.mjs +14 -1
  134. package/api/theme/build/build.mjs +133 -42
  135. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  136. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  137. package/api/theme/build/build.test.mjs +127 -0
  138. package/api/theme/build/font-warning.mjs +3 -3
  139. package/api/theme/build/font-warning.test.mjs +5 -2
  140. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  141. package/api/theme/integration-themes.test.mjs +39 -28
  142. package/api/theme/list/list.test.mjs +19 -20
  143. package/api/theme/listThemes.doc.mjs +6 -5
  144. package/api/theme/palette/generate/generate.mjs +8 -3
  145. package/api/theme/palette/generate/generate.test.mjs +96 -0
  146. package/api/theme/palette/generate/generator.d.mts +10 -13
  147. package/api/theme/palette/generate/generator.mjs +15 -4
  148. package/api/theme/palette/generate/generator.test.mjs +10 -0
  149. package/api/theme/template/template.mjs +11 -2
  150. package/api/theme/template/template.test.mjs +20 -0
  151. package/api/theme/theme.type.d.mts +170 -11
  152. package/api/theme/theme.type.mjs +94 -27
  153. package/api/theme/themeAdd.doc.mjs +4 -3
  154. package/api/theme/themeBuild.doc.mjs +8 -4
  155. package/api/theme/themeList.doc.mjs +6 -3
  156. package/api/theme/themeListAvailable.doc.mjs +5 -3
  157. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  158. package/api/theme/themeTargets.doc.mjs +1 -0
  159. package/api/theme/themeTemplate.doc.mjs +6 -2
  160. package/api/upgrade/_adapter.d.mts +32 -5
  161. package/api/upgrade/_adapter.mjs +139 -22
  162. package/api/upgrade/list/list.mjs +2 -1
  163. package/api/upgrade/list/list.test.mjs +73 -0
  164. package/api/upgrade/project-context.test.mjs +272 -0
  165. package/api/upgrade/provider-agreement.test.mjs +152 -0
  166. package/api/upgrade/run/run.mjs +356 -59
  167. package/api/upgrade/status/status.mjs +2 -2
  168. package/api/upgrade/upgrade.doc.mjs +12 -5
  169. package/api/upgrade/upgrade.type.d.mts +43 -5
  170. package/api/upgrade/upgrade.type.mjs +27 -11
  171. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  172. package/assets/codemods/integration-discovery.mjs +48 -4
  173. package/assets/codemods/integration-discovery.test.mjs +73 -0
  174. package/assets/codemods/integration-runner.mjs +56 -4
  175. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  176. package/assets/codemods/run-codemod.mjs +177 -34
  177. package/assets/codemods/runner.mjs +350 -102
  178. package/assets/codemods/term-log.mjs +32 -8
  179. package/assets/codemods/term-log.test.mjs +19 -1
  180. package/assets/codemods/transform-prop.mjs +109 -0
  181. package/assets/codemods/transform-prop.test.mjs +95 -0
  182. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  183. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  184. package/assets/codemods/transforms/next/index.mjs +19 -1
  185. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  186. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  187. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  188. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  189. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  190. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  191. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  192. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  193. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  194. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  195. package/assets/docs/README.md +9 -0
  196. package/assets/docs/authoring.doc.mjs +14 -0
  197. package/assets/docs/getting-started.doc.mjs +2 -2
  198. package/assets/docs/principles.doc.mjs +6 -6
  199. package/assets/docs/styling-libraries.doc.mjs +3 -3
  200. package/assets/docs/styling.doc.mjs +4 -4
  201. package/assets/docs/theme.doc.mjs +4 -4
  202. package/assets/docs/tokens.doc.mjs +1 -1
  203. package/assets/docs/tree/api.doc.mjs +30 -0
  204. package/assets/docs/tree/cli.doc.mjs +23 -0
  205. package/assets/docs/tree/commands.doc.mjs +25 -0
  206. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +124 -25
  207. package/assets/docs/tree/integrations.test.mjs +62 -0
  208. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  209. package/assets/docs/working-with-ai.doc.mjs +1 -1
  210. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  211. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  212. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  213. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  214. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  215. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  216. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  217. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  218. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  219. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  220. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  221. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  222. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  223. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  224. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  225. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  226. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  227. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  228. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  229. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  230. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  231. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  232. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  233. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  234. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  235. package/authoring/_shared/contract.ts +22 -0
  236. package/authoring/codemod/codemod.doc.mjs +7 -2
  237. package/authoring/codemod/parse.d.mts +8 -8
  238. package/authoring/codemod/parse.mjs +8 -6
  239. package/authoring/codemod/type.ts +12 -0
  240. package/authoring/config/config.doc.mjs +2 -2
  241. package/authoring/config/debug-composition.test.mjs +92 -0
  242. package/authoring/config/parse.d.mts +13 -13
  243. package/authoring/config/parse.mjs +8 -8
  244. package/authoring/config/type.ts +18 -6
  245. package/authoring/debug/debug.doc.d.mts +11 -0
  246. package/authoring/debug/debug.doc.mjs +182 -0
  247. package/authoring/debug/parse.d.mts +8 -8
  248. package/authoring/debug/parse.mjs +3 -3
  249. package/authoring/doctypes/_schema.d.mts +718 -23
  250. package/authoring/doctypes/_schema.mjs +519 -39
  251. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  252. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  253. package/authoring/doctypes/base/type.ts +41 -0
  254. package/authoring/doctypes/command/command.doc.mjs +4 -3
  255. package/authoring/doctypes/command/parse.d.mts +2 -2
  256. package/authoring/doctypes/command/parse.mjs +1 -1
  257. package/authoring/doctypes/command/type.ts +5 -4
  258. package/authoring/doctypes/component/component.doc.mjs +6 -3
  259. package/authoring/doctypes/component/parse.d.mts +2 -2
  260. package/authoring/doctypes/component/parse.mjs +1 -1
  261. package/authoring/doctypes/component/type.ts +6 -5
  262. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  263. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  264. package/authoring/doctypes/enum/parse.d.mts +2 -2
  265. package/authoring/doctypes/enum/parse.mjs +1 -1
  266. package/authoring/doctypes/enum/type.ts +4 -2
  267. package/authoring/doctypes/function/function.doc.mjs +7 -2
  268. package/authoring/doctypes/function/parse.d.mts +2 -2
  269. package/authoring/doctypes/function/parse.mjs +1 -1
  270. package/authoring/doctypes/function/type.ts +9 -4
  271. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  272. package/authoring/doctypes/hook/parse.d.mts +2 -2
  273. package/authoring/doctypes/hook/parse.mjs +1 -1
  274. package/authoring/doctypes/hook/type.ts +5 -4
  275. package/authoring/doctypes/legacy.d.mts +8 -6
  276. package/authoring/doctypes/legacy.mjs +5 -4
  277. package/authoring/doctypes/load-contract.test.mjs +208 -0
  278. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  279. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  280. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  281. package/authoring/doctypes/namespace/parse.mjs +25 -0
  282. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  283. package/authoring/doctypes/namespace/type.ts +74 -0
  284. package/authoring/doctypes/parse.d.mts +22 -18
  285. package/authoring/doctypes/parse.mjs +22 -11
  286. package/authoring/doctypes/parse.test.mjs +77 -3
  287. package/authoring/doctypes/reference/parse.d.mts +2 -2
  288. package/authoring/doctypes/reference/parse.mjs +8 -5
  289. package/authoring/doctypes/reference/reference.doc.mjs +20 -5
  290. package/authoring/doctypes/reference/type.ts +53 -5
  291. package/authoring/doctypes/schema/parse.d.mts +2 -2
  292. package/authoring/doctypes/schema/parse.mjs +1 -1
  293. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  294. package/authoring/doctypes/schema/type.ts +4 -4
  295. package/authoring/doctypes/template/parse.d.mts +94 -1
  296. package/authoring/doctypes/template/parse.mjs +40 -2
  297. package/authoring/doctypes/template/parse.test.mjs +26 -2
  298. package/authoring/doctypes/template/template.doc.mjs +13 -3
  299. package/authoring/doctypes/template/type.ts +13 -2
  300. package/authoring/doctypes/theme/parse.d.mts +35 -0
  301. package/authoring/doctypes/theme/parse.mjs +76 -0
  302. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  303. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  304. package/authoring/doctypes/theme/type.ts +42 -0
  305. package/authoring/doctypes/types.ts +12 -10
  306. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  307. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  308. package/authoring/gap-report/parse.d.mts +10 -10
  309. package/authoring/gap-report/parse.mjs +6 -6
  310. package/authoring/gap-report/type.ts +1 -1
  311. package/authoring/identity/identity.doc.d.mts +9 -0
  312. package/authoring/identity/identity.doc.mjs +61 -0
  313. package/authoring/identity/type.ts +132 -0
  314. package/authoring/index.d.mts +2 -0
  315. package/authoring/index.d.ts +52 -17
  316. package/authoring/index.mjs +3 -1
  317. package/authoring/integration/integration.doc.mjs +15 -8
  318. package/authoring/integration/parse.d.mts +2 -2
  319. package/authoring/integration/parse.mjs +1 -1
  320. package/authoring/integration/parse.test.mjs +10 -1
  321. package/authoring/integration/schema.d.mts +6 -4
  322. package/authoring/integration/schema.mjs +9 -3
  323. package/authoring/integration/type.ts +19 -8
  324. package/authoring/shadcn/receipt.d.mts +6 -6
  325. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  326. package/clients/cli/command-load-failure.test.mjs +83 -0
  327. package/clients/cli/commands/blog.doc.mjs +1 -1
  328. package/clients/cli/commands/blog.mjs +23 -8
  329. package/clients/cli/commands/blog.test.mjs +42 -1
  330. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  331. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  332. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  333. package/clients/cli/commands/build-theme.mjs +16 -50
  334. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  335. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  336. package/clients/cli/commands/build.doc.mjs +5 -2
  337. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  338. package/clients/cli/commands/build.mjs +37 -49
  339. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  340. package/clients/cli/commands/build.text-fields.test.mjs +40 -0
  341. package/clients/cli/commands/component/index.mjs +3 -8
  342. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  343. package/clients/cli/commands/component-package.test.mjs +46 -0
  344. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  345. package/clients/cli/commands/component.doc.mjs +1 -1
  346. package/clients/cli/commands/component.test.mjs +19 -0
  347. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  348. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  349. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  350. package/clients/cli/commands/discover.doc.mjs +5 -3
  351. package/clients/cli/commands/discover.mjs +4 -4
  352. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  353. package/clients/cli/commands/docs.doc.mjs +28 -6
  354. package/clients/cli/commands/docs.mjs +238 -24
  355. package/clients/cli/commands/docs.test.mjs +193 -1
  356. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  357. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  358. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  359. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  360. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  361. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  362. package/clients/cli/commands/doctor-integration.test.mjs +83 -8
  363. package/clients/cli/commands/doctor.doc.mjs +1 -1
  364. package/clients/cli/commands/doctor.mjs +30 -25
  365. package/clients/cli/commands/doctor.test.mjs +42 -0
  366. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  367. package/clients/cli/commands/gap-report.test.mjs +72 -0
  368. package/clients/cli/commands/hook/index.mjs +7 -17
  369. package/clients/cli/commands/hook.doc.mjs +1 -1
  370. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  371. package/clients/cli/commands/init.doc.mjs +20 -9
  372. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  373. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  374. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  375. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  376. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  377. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  378. package/clients/cli/commands/integration.doc.mjs +1 -1
  379. package/clients/cli/commands/integration.mjs +1 -0
  380. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  381. package/clients/cli/commands/json-contract.test.mjs +33 -0
  382. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  383. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  384. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  385. package/clients/cli/commands/layout.doc.mjs +3 -3
  386. package/clients/cli/commands/layout.mjs +21 -9
  387. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  388. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  389. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  390. package/clients/cli/commands/manifest.doc.mjs +1 -1
  391. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  392. package/clients/cli/commands/search.doc.mjs +7 -4
  393. package/clients/cli/commands/search.mjs +28 -9
  394. package/clients/cli/commands/search.test.mjs +75 -0
  395. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  396. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  397. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  398. package/clients/cli/commands/template.doc.mjs +52 -13
  399. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  400. package/clients/cli/commands/template.mjs +4 -91
  401. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  402. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  403. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  404. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  405. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  406. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  407. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  408. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  409. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  410. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  411. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  412. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  413. package/clients/cli/commands/theme.doc.mjs +1 -1
  414. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  415. package/clients/cli/commands/upgrade.doc.mjs +22 -10
  416. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  417. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  418. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  419. package/clients/cli/commands/upgrade.mjs +29 -7
  420. package/clients/cli/formatters/index.mjs +164 -1
  421. package/clients/cli/formatters/index.test.mjs +97 -0
  422. package/clients/cli/index.mjs +21 -30
  423. package/clients/cli/latest-version-env.test.mjs +50 -0
  424. package/clients/cli/lib/cli-error.test.mjs +7 -0
  425. package/clients/cli/lib/component-format.mjs +9 -9
  426. package/clients/cli/lib/component-format.test.mjs +1 -1
  427. package/clients/cli/lib/define-command.mjs +32 -6
  428. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  429. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  430. package/clients/cli/lib/hook-format.mjs +19 -10
  431. package/clients/cli/lib/json-shim.mjs +38 -2
  432. package/clients/cli/lib/json-shim.test.mjs +83 -0
  433. package/clients/cli/lib/manifest.d.ts +2 -0
  434. package/clients/cli/lib/manifest.mjs +36 -2
  435. package/clients/cli/lib/manifest.test.mjs +17 -0
  436. package/foundation/agent-docs/agent-docs.d.mts +4 -0
  437. package/foundation/agent-docs/agent-docs.mjs +70 -3
  438. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  439. package/foundation/agent-docs/agent-docs.test.mjs +10 -1
  440. package/foundation/config/integration-debug.test.mjs +28 -3
  441. package/foundation/config/project-themes.test.mjs +11 -19
  442. package/foundation/config/project.d.mts +20 -11
  443. package/foundation/config/project.mjs +263 -91
  444. package/foundation/config/project.test.mjs +270 -21
  445. package/foundation/discovery/authoring-self-docs.d.mts +75 -0
  446. package/foundation/discovery/authoring-self-docs.mjs +224 -0
  447. package/foundation/discovery/authoring-self-docs.test.mjs +165 -0
  448. package/foundation/discovery/authoring-surface.d.mts +74 -0
  449. package/foundation/discovery/authoring-surface.mjs +525 -0
  450. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  451. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  452. package/foundation/discovery/cli-self-docs.mjs +490 -0
  453. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  454. package/foundation/discovery/component-discovery.d.mts +39 -1
  455. package/foundation/discovery/component-discovery.mjs +50 -1
  456. package/foundation/discovery/component-loader.d.mts +35 -38
  457. package/foundation/discovery/component-loader.mjs +53 -222
  458. package/foundation/discovery/docs-discovery.d.mts +116 -11
  459. package/foundation/discovery/docs-discovery.mjs +389 -108
  460. package/foundation/discovery/docs-discovery.test.mjs +325 -20
  461. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  462. package/foundation/discovery/docs-output-budget.mjs +50 -0
  463. package/foundation/discovery/docs-section-key.d.mts +116 -0
  464. package/foundation/discovery/docs-section-key.mjs +322 -0
  465. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  466. package/foundation/discovery/template-adapter.d.mts +113 -11
  467. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  468. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  469. package/foundation/discovery/template-adapter.mjs +774 -83
  470. package/foundation/discovery/template-adapter.test.mjs +57 -0
  471. package/foundation/discovery/theme-discovery.d.mts +67 -7
  472. package/foundation/discovery/theme-discovery.mjs +916 -186
  473. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  474. package/foundation/discovery/theming-targets.test.mjs +4 -0
  475. package/foundation/doc-compiler/bundle.d.mts +47 -0
  476. package/foundation/doc-compiler/bundle.mjs +278 -0
  477. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  478. package/foundation/doc-compiler/compile.d.mts +343 -0
  479. package/foundation/doc-compiler/compile.mjs +558 -0
  480. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  481. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  482. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  483. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  484. package/foundation/doc-compiler/import.d.mts +24 -0
  485. package/foundation/doc-compiler/import.mjs +59 -0
  486. package/foundation/doc-compiler/inputs.d.mts +102 -0
  487. package/foundation/doc-compiler/inputs.mjs +291 -0
  488. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  489. package/foundation/doc-compiler/ir.d.mts +22 -0
  490. package/foundation/doc-compiler/ir.mjs +471 -0
  491. package/foundation/doc-compiler/lenses.d.mts +34 -0
  492. package/foundation/doc-compiler/lenses.mjs +128 -0
  493. package/foundation/doc-compiler/links.d.mts +135 -0
  494. package/foundation/doc-compiler/links.mjs +253 -0
  495. package/foundation/doc-compiler/links.test.mjs +139 -0
  496. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  497. package/foundation/doc-compiler/overlays.d.mts +37 -0
  498. package/foundation/doc-compiler/overlays.mjs +206 -0
  499. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  500. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  501. package/foundation/doc-compiler/read.d.mts +127 -0
  502. package/foundation/doc-compiler/read.mjs +325 -0
  503. package/foundation/doc-compiler/read.test.mjs +313 -0
  504. package/foundation/doc-compiler/source.d.mts +33 -0
  505. package/foundation/doc-compiler/source.mjs +128 -0
  506. package/foundation/doc-compiler/tree.d.mts +288 -0
  507. package/foundation/doc-compiler/tree.mjs +876 -0
  508. package/foundation/doc-compiler/tree.test.mjs +598 -0
  509. package/foundation/fs/file-protection.d.mts +33 -0
  510. package/foundation/fs/file-protection.mjs +825 -0
  511. package/foundation/fs/file-protection.test.mjs +250 -0
  512. package/foundation/fs/module-loader.d.mts +1 -0
  513. package/foundation/fs/module-loader.mjs +50 -1
  514. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  515. package/foundation/fs/path-safety.d.mts +3 -2
  516. package/foundation/fs/path-safety.mjs +49 -19
  517. package/foundation/fs/path-safety.test.mjs +50 -0
  518. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  519. package/foundation/identity/provider-identity.d.mts +90 -0
  520. package/foundation/identity/provider-identity.mjs +320 -0
  521. package/foundation/identity/provider-identity.test.mjs +254 -0
  522. package/foundation/identity/providers.d.mts +7 -0
  523. package/foundation/identity/providers.mjs +16 -0
  524. package/foundation/integrations/autolink.d.mts +58 -1
  525. package/foundation/integrations/autolink.mjs +143 -45
  526. package/foundation/integrations/autolink.test.mjs +1 -1
  527. package/foundation/integrations/cli-requirement.d.mts +45 -0
  528. package/foundation/integrations/cli-requirement.mjs +154 -0
  529. package/foundation/integrations/cli-requirement.test.mjs +109 -0
  530. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  531. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  532. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  533. package/foundation/integrations/contribution-inventory.mjs +27 -24
  534. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  535. package/foundation/integrations/integration-warnings.d.mts +9 -2
  536. package/foundation/integrations/integration-warnings.mjs +52 -21
  537. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  538. package/foundation/integrations/integrations.d.mts +49 -2
  539. package/foundation/integrations/integrations.mjs +81 -8
  540. package/foundation/integrations/integrations.test.mjs +384 -1
  541. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  542. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  543. package/foundation/integrations/provider-resolution.d.mts +152 -0
  544. package/foundation/integrations/provider-resolution.mjs +576 -0
  545. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  546. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  547. package/foundation/integrations/theme-descriptor.mjs +44 -0
  548. package/foundation/integrations/validate-contributions.d.mts +2 -0
  549. package/foundation/integrations/validate-contributions.mjs +131 -29
  550. package/foundation/response/base.d.ts +8 -4
  551. package/foundation/response/error-codes.d.mts +3 -1
  552. package/foundation/response/error-codes.d.ts +2 -0
  553. package/foundation/response/error-codes.doc.mjs +13 -4
  554. package/foundation/response/error-codes.mjs +8 -2
  555. package/foundation/response/error-codes.test.mjs +137 -10
  556. package/foundation/response/json-contract.test.mjs +57 -17
  557. package/foundation/response/json.d.mts +4 -2
  558. package/foundation/response/json.mjs +8 -10
  559. package/foundation/response/response-types.doc.mjs +26 -16
  560. package/foundation/response/response-types.doc.test.mjs +158 -0
  561. package/foundation/response/response.doc.mjs +1 -1
  562. package/foundation/text/string-utils.mjs +22 -10
  563. package/foundation/xle/expand.d.mts +2 -0
  564. package/foundation/xle/expand.mjs +4 -3
  565. package/foundation/xle/expand.test.mjs +54 -0
  566. package/foundation/xle/xle.test.mjs +13 -0
  567. package/package.json +10 -11
  568. package/assets/templates/themes/manifest.json +0 -95
  569. package/clients/cli/lib/update-check.mjs +0 -83
  570. package/clients/cli/lib/update-check.test.mjs +0 -137
  571. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -0,0 +1,75 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The no-query `build` playbook is data. `--json` carries every step,
5
+ * rule and command; the text output is rendered from those values and shows
6
+ * nothing the envelope lacks.
7
+ */
8
+
9
+ import {describe, it, expect} from 'vitest';
10
+ import * as path from 'node:path';
11
+ import {fileURLToPath} from 'node:url';
12
+ import {runCli} from '../../../test-utils/run-cli.mjs';
13
+ import {program} from '../index.mjs';
14
+
15
+ // Run against the monorepo root so @astryxdesign/core is discoverable.
16
+ const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
17
+ const SLOW = 30_000;
18
+
19
+ /** @param {string} s */
20
+ const ascii = s => s.replace(/[\u2014\u2013]/g, '-');
21
+
22
+ describe('build playbook: text is a projection of the JSON', () => {
23
+ it('prints exactly the commands, steps and rules the envelope carries', async () => {
24
+ const json = await runCli(['build', '--json'], REPO);
25
+ expect(json.status).toBe(0);
26
+ const {type, data} = JSON.parse(json.stdout);
27
+ expect(type).toBe('build.help');
28
+ expect(data.steps.length).toBeGreaterThan(0);
29
+ expect(data.rules.length).toBeGreaterThan(0);
30
+
31
+ const human = await runCli(['build'], REPO);
32
+ expect(human.status).toBe(0);
33
+ const out = human.stdout;
34
+
35
+ expect(out).toContain(ascii(data.title));
36
+ for (const step of data.steps) {
37
+ expect(out).toContain(ascii(step.title));
38
+ if (step.returns) expect(out).toContain(ascii(step.returns));
39
+ }
40
+ for (const rule of data.rules) expect(out).toContain(ascii(rule));
41
+
42
+ /** @type {Array<{command: string, purpose?: string}>} */
43
+ const commands = [
44
+ ...data.steps.flatMap((/** @type {any} */ s) => s.commands),
45
+ ...data.related,
46
+ ];
47
+ // Each command is one record whose field names are the JSON keys:
48
+ // `command:` (run with the caller's invocation), then `purpose:`.
49
+ const printed = out
50
+ .split('\n')
51
+ .filter(line => line.startsWith('command: '))
52
+ .map(line => line.slice('command: '.length).trim());
53
+ expect(printed).toHaveLength(commands.length);
54
+ commands.forEach(({command, purpose}, i) => {
55
+ expect(printed[i].endsWith(` ${command}`)).toBe(true);
56
+ if (purpose) expect(out).toContain(`purpose: ${ascii(purpose)}`);
57
+ });
58
+ // No column the handler drew itself.
59
+ expect(out).not.toMatch(/ {2,}# /);
60
+ }, SLOW);
61
+
62
+ it('names only commands this CLI registers', async () => {
63
+ const {stdout} = await runCli(['build', '--json'], REPO);
64
+ const {data} = JSON.parse(stdout);
65
+ const registered = new Set(program.commands.map(c => c.name()));
66
+ const commands = [
67
+ ...data.steps.flatMap((/** @type {any} */ s) => s.commands),
68
+ ...data.related,
69
+ ];
70
+ expect(commands.length).toBeGreaterThan(0);
71
+ for (const {command} of commands) {
72
+ expect(registered.has(command.split(' ')[0])).toBe(true);
73
+ }
74
+ }, SLOW);
75
+ });
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `build "<idea>"` text output names only fields the `build.kit`
5
+ * envelope carries — on the kit itself or on its entries.
6
+ */
7
+
8
+ import {describe, it, expect} from 'vitest';
9
+ import * as path from 'node:path';
10
+ import {fileURLToPath} from 'node:url';
11
+ import {runCli} from '../../../test-utils/run-cli.mjs';
12
+
13
+ // Run against the monorepo root so @astryxdesign/core is discoverable.
14
+ const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
15
+ const SLOW = 60_000;
16
+
17
+ describe('build kit text fields mirror the JSON keys', () => {
18
+ it('prints no field the envelope lacks', async () => {
19
+ const json = await runCli(['build', 'analytics dashboard', '--json', '--verbose'], REPO);
20
+ expect(json.status).toBe(0);
21
+ const {data} = JSON.parse(json.stdout);
22
+ const keys = new Set([
23
+ ...Object.keys(data),
24
+ ...[...data.pages, ...data.blocks, ...data.domain].flatMap(e => Object.keys(e)),
25
+ ]);
26
+
27
+ const human = await runCli(['build', 'analytics dashboard', '--verbose'], REPO);
28
+ expect(human.status).toBe(0);
29
+ const fields = [
30
+ ...new Set(
31
+ human.stdout
32
+ .split('\n')
33
+ .map(line => /^([A-Za-z]+):\s/.exec(line)?.[1])
34
+ .filter(Boolean),
35
+ ),
36
+ ];
37
+ expect(fields).toContain('frame');
38
+ for (const field of fields) expect(keys).toContain(field);
39
+ }, SLOW);
40
+ });
@@ -26,7 +26,6 @@ import {defineCommand} from '../../lib/define-command.mjs';
26
26
  import {resultSet} from '../../../../foundation/debug/index.mjs';
27
27
  import {ERROR_CODES} from '../../../../foundation/response/error-codes.mjs';
28
28
  import {component as componentApi} from '../../../../api/component/component.mjs';
29
- import {findRelatedBlocks} from '../../../../api/template/template.mjs';
30
29
  import {Project} from '../../../../foundation/config/project.mjs';
31
30
  import {warnOnIntegrationIssues} from '../../../../foundation/integrations/integration-warnings.mjs';
32
31
  import {doc as componentCommand} from '../component.doc.mjs';
@@ -112,7 +111,7 @@ export function registerComponent(program) {
112
111
  // doctor integration validate. Best-effort; suppressed in --json mode.
113
112
  try {
114
113
  const project = await Project.load(process.cwd());
115
- await warnOnIntegrationIssues(project.loadedIntegrations, {json});
114
+ await warnOnIntegrationIssues(project, {json});
116
115
  } catch {
117
116
  // Never let the nudge break the command.
118
117
  }
@@ -235,18 +234,14 @@ export function registerComponent(program) {
235
234
  case 'component.detail': {
236
235
  const resolvedName = (name || '').replace(/^XDS/, '');
237
236
  const importHint = result.data.import;
237
+ if (result.data.parentDoc) emit(record(result.data, {fields: ['parentDoc']}));
238
238
  const doc =
239
239
  detail === 'brief'
240
240
  ? code(formatBrief(result.data, resolvedName, importHint, {themeData}))
241
241
  : detail === 'compact'
242
242
  ? code(formatCompact(result.data, resolvedName, importHint))
243
243
  : code(formatFull(result.data, {themeData, importHint}));
244
- const related = await findRelatedBlocks(resolvedName);
245
- emit(
246
- doc,
247
- related.length > 0 && section('Related block templates'),
248
- related.length > 0 && records(related, {fields: ['dirName', 'description']}),
249
- );
244
+ emit(doc);
250
245
  break;
251
246
  }
252
247
 
@@ -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
 
@@ -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,7 +13,7 @@ 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
19
  'Resolves a component by name across core and integration packages and prints ' +
@@ -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
+ });
@@ -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
  });
@@ -69,11 +69,12 @@ describe('astryx discover with a manifest that fails to load', () => {
69
69
 
70
70
  expect(status).toBe(0);
71
71
  expect(stderr).toContain(
72
- 'Warning: @test/broken has 1 integration issue(s). ' +
73
- 'Run: astryx doctor integration validate @test/broken',
72
+ 'Warning: @test/broken has 1 integration issue(s). Run: astryx doctor',
74
73
  );
75
74
  expect(stdout).not.toContain('No integrations configured.');
76
- expect(stdout).toContain('No external components found in configured integrations.');
75
+ expect(stdout).toContain(
76
+ 'No external components found in configured integrations.',
77
+ );
77
78
  });
78
79
 
79
80
  it('reports meta.configured=true in --json, with the nudge suppressed', async () => {
@@ -87,6 +88,53 @@ describe('astryx discover with a manifest that fails to load', () => {
87
88
  });
88
89
  });
89
90
 
91
+ describe('astryx discover with a configured package that is not installed', () => {
92
+ beforeEach(() => {
93
+ const healthy = path.join(project, 'node_modules', '@test', 'healthy');
94
+ fs.mkdirSync(path.join(healthy, 'components'), {recursive: true});
95
+ fs.writeFileSync(
96
+ path.join(healthy, 'package.json'),
97
+ JSON.stringify({name: '@test/healthy', version: '2.0.0'}),
98
+ );
99
+ fs.writeFileSync(
100
+ path.join(healthy, 'astryx.integration.mjs'),
101
+ `export default {components: './components'};\n`,
102
+ );
103
+ fs.writeFileSync(
104
+ path.join(healthy, 'components', 'Widget.doc.mjs'),
105
+ `export const docs = {name: 'Widget', usage: {description: 'A widget.'}, props: []};\n`,
106
+ );
107
+ fs.writeFileSync(
108
+ path.join(healthy, 'components', 'Widget.tsx'),
109
+ `export function Widget() { return null; }\n`,
110
+ );
111
+ fs.writeFileSync(
112
+ path.join(project, 'astryx.config.mjs'),
113
+ `export default {integrations: ['@test/missing', '@test/healthy']};\n`,
114
+ );
115
+ });
116
+
117
+ it('still lists the healthy package and exits 0', async () => {
118
+ const {status, stdout} = await runCli(['discover', '--json'], {
119
+ cwd: project,
120
+ });
121
+
122
+ expect(status).toBe(0);
123
+ expect(JSON.parse(stdout).data).toEqual([
124
+ expect.objectContaining({name: '@test/healthy', components: ['Widget']}),
125
+ ]);
126
+ });
127
+
128
+ it('names the missing package in the stderr nudge', async () => {
129
+ const {status, stderr} = await runCli(['discover'], {cwd: project});
130
+
131
+ expect(status).toBe(0);
132
+ expect(stderr).toContain(
133
+ 'Warning: @test/missing has 1 integration issue(s). Run: astryx doctor\n',
134
+ );
135
+ });
136
+ });
137
+
90
138
  describe('astryx search with a manifest that fails to load', () => {
91
139
  // search needs a resolvable @astryxdesign/core; without one it errors out
92
140
  // before it can list anything, which is not the case under test.
@@ -101,8 +149,7 @@ describe('astryx search with a manifest that fails to load', () => {
101
149
 
102
150
  expect(status).toBe(0);
103
151
  expect(stderr).toContain(
104
- 'Warning: @test/broken has 1 integration issue(s). ' +
105
- 'Run: astryx doctor integration validate @test/broken',
152
+ 'Warning: @test/broken has 1 integration issue(s). Run: astryx doctor',
106
153
  );
107
154
 
108
155
  const asJson = await runCli(['search', 'button', '--json'], {cwd: project});
@@ -0,0 +1,97 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx discover --components` does what its doc says.
5
+ *
6
+ * The flag only lifts the package list's component summary (the first 10
7
+ * names plus "+N more") so every component prints. It changes nothing in
8
+ * `--json`, whose entries always carry the full array.
9
+ */
10
+
11
+ import {describe, it, expect, beforeEach, afterEach} from 'vitest';
12
+ import * as fs from 'node:fs';
13
+ import * as path from 'node:path';
14
+ import * as os from 'node:os';
15
+ import {runCli} from '../../../test-utils/run-cli.mjs';
16
+ import {doc} from './discover.doc.mjs';
17
+ import {doc as discoverFn} from '../../../api/discover/discover.doc.mjs';
18
+
19
+ const NAMES = Array.from({length: 12}, (_, i) => `Part${String(i).padStart(2, '0')}`);
20
+
21
+ let tmpDir;
22
+ let project;
23
+
24
+ beforeEach(() => {
25
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-discover-components-'));
26
+ project = path.join(tmpDir, 'project');
27
+ const pkgDir = path.join(project, 'node_modules', '@test', 'kit');
28
+ fs.mkdirSync(path.join(pkgDir, 'components'), {recursive: true});
29
+ fs.writeFileSync(
30
+ path.join(project, 'package.json'),
31
+ JSON.stringify({name: 'proj', version: '1.0.0'}),
32
+ );
33
+ fs.writeFileSync(
34
+ path.join(project, 'astryx.config.mjs'),
35
+ `export default {integrations: ['@test/kit']};\n`,
36
+ );
37
+ fs.writeFileSync(
38
+ path.join(pkgDir, 'package.json'),
39
+ JSON.stringify({name: '@test/kit', version: '1.0.0'}),
40
+ );
41
+ fs.writeFileSync(
42
+ path.join(pkgDir, 'astryx.integration.mjs'),
43
+ `export default {components: './components'};\n`,
44
+ );
45
+ for (const name of NAMES) {
46
+ fs.writeFileSync(
47
+ path.join(pkgDir, 'components', `${name}.doc.mjs`),
48
+ `export const docs = {name: '${name}', usage: {description: 'A part.'}};\n`,
49
+ );
50
+ fs.writeFileSync(
51
+ path.join(pkgDir, 'components', `${name}.tsx`),
52
+ `export function ${name}() { return null; }\n`,
53
+ );
54
+ }
55
+ });
56
+
57
+ afterEach(() => {
58
+ fs.rmSync(tmpDir, {recursive: true, force: true});
59
+ });
60
+
61
+ /** @param {string} stdout */
62
+ function componentsLine(stdout) {
63
+ return stdout.split('\n').find(line => line.startsWith('components:'));
64
+ }
65
+
66
+ describe('astryx discover --components', () => {
67
+ it('lists every component where the default list shows the first 10', async () => {
68
+ const summary = await runCli(['discover'], {cwd: project});
69
+ const full = await runCli(['discover', '--components'], {cwd: project});
70
+
71
+ expect(componentsLine(summary.stdout)).toMatch(
72
+ new RegExp(`${NAMES[9]}, \\+2 more$`),
73
+ );
74
+ expect(componentsLine(full.stdout)).toMatch(new RegExp(`${NAMES.join(', ')}$`));
75
+ });
76
+
77
+ it('leaves the --json response unchanged', async () => {
78
+ const plain = await runCli(['discover', '--json'], {cwd: project});
79
+ const flagged = await runCli(['discover', '--components', '--json'], {
80
+ cwd: project,
81
+ });
82
+
83
+ expect(JSON.parse(flagged.stdout)).toEqual(JSON.parse(plain.stdout));
84
+ });
85
+
86
+ it('is documented as that behavior, with an example', () => {
87
+ const option = doc.options?.find(o => o.flag === '--components');
88
+ const param = discoverFn.params?.find(p => p.name === 'options.components');
89
+
90
+ for (const description of [option?.description, param?.description]) {
91
+ expect(description).toMatch(/every component/i);
92
+ expect(description).toMatch(/first 10/);
93
+ expect(description).not.toMatch(/components only/i);
94
+ }
95
+ expect(doc.examples?.some(e => /\s--components\b/.test(e.cli))).toBe(true);
96
+ });
97
+ });
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'discover',
15
15
  displayName: 'astryx discover',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'Discover external packages and components',
18
18
  description:
19
19
  'Explores components contributed by configured external packages and integrations. ' +
@@ -25,18 +25,20 @@ export const doc = {
25
25
  {
26
26
  flag: '--components',
27
27
  param: 'options.components',
28
- description: 'List components only',
28
+ description:
29
+ 'In the package list, print every component of each package instead of the first 10 and a "+N more" count. No effect on --json output or on a package, component, or search query.',
29
30
  },
30
31
  ],
31
32
  examples: [
32
33
  {label: 'List packages', cli: 'astryx discover --json'},
34
+ {label: 'List every component of each package', cli: 'astryx discover --components'},
33
35
  {label: 'Browse a package', cli: 'astryx discover @acme/ui'},
34
36
  ],
35
37
  exitCodes: [
36
38
  {code: 0, when: 'success'},
37
39
  {
38
40
  code: 1,
39
- when: 'unknown package or component, a malformed doc, or an empty free-text query',
41
+ when: 'unknown package or component, a malformed doc, or a blank query when packages are discovered',
40
42
  },
41
43
  ],
42
44
  related: ['component', 'search', 'template'],
@@ -83,7 +83,7 @@ export function registerDiscover(program) {
83
83
  // doctor integration validate. Best-effort; suppressed in --json mode.
84
84
  try {
85
85
  const project = await Project.load(process.cwd());
86
- await warnOnIntegrationIssues(project.loadedIntegrations, {json});
86
+ await warnOnIntegrationIssues(project, {json});
87
87
  } catch {
88
88
  // Never let the nudge break the command.
89
89
  }
@@ -122,11 +122,11 @@ export function registerDiscover(program) {
122
122
  break;
123
123
  }
124
124
 
125
- // One record per package — fields mirror the JSON entry. The default
125
+ // One record per package, every field of the JSON entry. The default
126
126
  // view summarizes each package's components (first N + "+N more");
127
127
  // --components lists them all (record comma-joins the full array).
128
128
  /** @type {import('../formatters/index.mjs').RecordOptions} */
129
- const listOpts = {fields: ['displayName', 'name', 'description', 'components']};
129
+ const listOpts = {};
130
130
  if (!options.components) {
131
131
  listOpts.format = {
132
132
  components: (/** @type {string[]} */ comps) => {
@@ -155,7 +155,7 @@ export function registerDiscover(program) {
155
155
  case 'discover.detail': {
156
156
  const d = result.data;
157
157
  emit(
158
- record(d, {fields: ['displayName', 'name', 'description', 'components']}),
158
+ record(d),
159
159
  text(`Usage: ${run} discover ${d.name}/<ComponentName>`),
160
160
  );
161
161
  break;