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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (728) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +152 -107
  3. package/api/blog/blog.doc.mjs +1 -0
  4. package/api/build/_adapter.d.mts +50 -0
  5. package/api/build/_adapter.mjs +60 -0
  6. package/api/build/build.doc.mjs +22 -10
  7. package/api/build/build.test.mjs +219 -8
  8. package/api/build/build.type.d.mts +91 -2
  9. package/api/build/build.type.mjs +52 -8
  10. package/api/build/help/help.d.mts +12 -5
  11. package/api/build/help/help.mjs +69 -6
  12. package/api/build/kit/kit.d.mts +4 -1
  13. package/api/build/kit/kit.mjs +208 -53
  14. package/api/build/kit/rank.d.mts +44 -0
  15. package/api/build/kit/rank.mjs +432 -0
  16. package/api/build/kit/rank.test.mjs +196 -0
  17. package/api/component/_adapter.d.mts +31 -12
  18. package/api/component/_adapter.mjs +79 -15
  19. package/api/component/component.d.mts +6 -3
  20. package/api/component/component.doc.mjs +49 -19
  21. package/api/component/component.mjs +339 -22
  22. package/api/component/component.test.mjs +38 -0
  23. package/api/component/component.type.d.mts +47 -11
  24. package/api/component/component.type.mjs +76 -24
  25. package/api/component/detail/blocks/blocks.d.mts +2 -1
  26. package/api/component/detail/blocks/blocks.mjs +4 -3
  27. package/api/component/list/list.d.mts +0 -5
  28. package/api/component/list/list.mjs +40 -11
  29. package/api/discover/_adapter.d.mts +114 -6
  30. package/api/discover/_adapter.mjs +372 -17
  31. package/api/discover/_adapter.test.mjs +215 -0
  32. package/api/discover/_catalog-view.d.mts +115 -0
  33. package/api/discover/_catalog-view.mjs +203 -0
  34. package/api/discover/_catalog-view.test.mjs +128 -0
  35. package/api/discover/detail/detail.d.mts +18 -6
  36. package/api/discover/detail/detail.mjs +67 -13
  37. package/api/discover/detail/detail.test.mjs +85 -0
  38. package/api/discover/detail/item/item.d.mts +26 -0
  39. package/api/discover/detail/item/item.mjs +78 -0
  40. package/api/discover/detail/item/item.test.mjs +73 -0
  41. package/api/discover/discover.d.mts +3 -9
  42. package/api/discover/discover.doc.mjs +62 -18
  43. package/api/discover/discover.mjs +220 -36
  44. package/api/discover/discover.test.mjs +11 -2
  45. package/api/discover/discover.type.d.mts +150 -11
  46. package/api/discover/discover.type.mjs +107 -17
  47. package/api/discover/list/list.d.mts +20 -6
  48. package/api/discover/list/list.mjs +45 -12
  49. package/api/discover/list/list.test.mjs +46 -0
  50. package/api/discover/search/search.d.mts +18 -16
  51. package/api/discover/search/search.mjs +102 -56
  52. package/api/discover/search/search.test.mjs +144 -10
  53. package/api/docs/_adapter.d.mts +277 -41
  54. package/api/docs/_adapter.mjs +993 -108
  55. package/api/docs/compiled-topics.test.mjs +78 -0
  56. package/api/docs/detail/detail.mjs +22 -63
  57. package/api/docs/detail/section/section.d.mts +1 -1
  58. package/api/docs/detail/section/section.mjs +54 -19
  59. package/api/docs/detail/section/section.test.mjs +50 -0
  60. package/api/docs/docOverlays.test.mjs +27 -1
  61. package/api/docs/docs.d.mts +10 -3
  62. package/api/docs/docs.doc.mjs +55 -16
  63. package/api/docs/docs.mjs +53 -10
  64. package/api/docs/docs.type.d.mts +221 -5
  65. package/api/docs/docs.type.mjs +153 -11
  66. package/api/docs/index/index.d.mts +18 -0
  67. package/api/docs/index/index.mjs +40 -0
  68. package/api/docs/index/index.test.mjs +62 -0
  69. package/api/docs/list/list.mjs +28 -12
  70. package/api/docs/node/node.d.mts +43 -0
  71. package/api/docs/node/node.mjs +192 -0
  72. package/api/docs/reference-blocks.test.mjs +406 -0
  73. package/api/doctor/doctor.d.mts +104 -1
  74. package/api/doctor/doctor.doc.mjs +18 -8
  75. package/api/doctor/doctor.mjs +635 -7
  76. package/api/doctor/doctor.test.mjs +732 -11
  77. package/api/doctor/doctor.type.d.mts +1 -1
  78. package/api/doctor/doctor.type.mjs +1 -1
  79. package/api/gap-report/gap-report.doc.mjs +27 -14
  80. package/api/hook/_adapter.mjs +19 -5
  81. package/api/hook/hook.doc.mjs +7 -3
  82. package/api/hook/hook.type.d.mts +3 -3
  83. package/api/hook/hook.type.mjs +11 -11
  84. package/api/hook/list/list.d.mts +2 -2
  85. package/api/hook/list/list.mjs +69 -17
  86. package/api/index.d.mts +2 -1
  87. package/api/index.mjs +6 -3
  88. package/api/init/init.doc.mjs +22 -12
  89. package/api/init/init.test.mjs +41 -1
  90. package/api/init/remove/remove.mjs +1 -1
  91. package/api/init/run/run.mjs +20 -10
  92. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  93. package/api/integration/add-contribution.d.mts +2 -1
  94. package/api/integration/add-contribution.mjs +130 -15
  95. package/api/integration/add-contribution.test.mjs +258 -7
  96. package/api/integration/add-helpers.d.mts +5 -2
  97. package/api/integration/add-helpers.mjs +36 -9
  98. package/api/integration/add-theme.mjs +56 -65
  99. package/api/integration/add-theme.test.mjs +139 -21
  100. package/api/integration/authoring-checks.mjs +138 -28
  101. package/api/integration/authoring-checks.test.mjs +179 -7
  102. package/api/integration/authoring-checks.type.mjs +6 -1
  103. package/api/integration/integration-authoring.type.d.mts +3 -1
  104. package/api/integration/integration-authoring.type.mjs +2 -0
  105. package/api/integration/integration-block-exports.test.mjs +10 -6
  106. package/api/integration/integrationAdd.doc.mjs +14 -4
  107. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  108. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  109. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  110. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  111. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  112. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  113. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  114. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  115. package/api/integration/integrationPackCheck.doc.mjs +5 -4
  116. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  117. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  118. package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
  119. package/api/integration/pack-check.mjs +160 -11
  120. package/api/integration/pack-check.test.mjs +477 -47
  121. package/api/integration/pack-check.type.d.mts +26 -2
  122. package/api/integration/pack-check.type.mjs +15 -2
  123. package/api/integration/summarizeIssues.doc.mjs +1 -0
  124. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  126. package/api/integration/validate-integration.mjs +52 -102
  127. package/api/integration/validate-integration.test.mjs +179 -26
  128. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  129. package/api/integration/validateIntegration.doc.mjs +3 -2
  130. package/api/json/assertResponse.doc.mjs +2 -1
  131. package/api/json/envelope-types.test.mjs +76 -0
  132. package/api/json/index.ts +2 -0
  133. package/api/json/isError.doc.mjs +2 -1
  134. package/api/json/parseResponse.doc.mjs +3 -2
  135. package/api/layout/_adapter.mjs +20 -5
  136. package/api/layout/expand/expand.mjs +7 -5
  137. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  138. package/api/layout/grammar/grammar.mjs +2 -1
  139. package/api/layout/layoutCheck.doc.mjs +1 -0
  140. package/api/layout/layoutExpand.doc.mjs +2 -1
  141. package/api/layout/layoutGrammar.doc.mjs +1 -0
  142. package/api/search/search-return-type.test.mjs +54 -0
  143. package/api/search/search.d.mts +89 -12
  144. package/api/search/search.doc.mjs +8 -2
  145. package/api/search/search.mjs +697 -97
  146. package/api/search/search.type.d.mts +15 -3
  147. package/api/search/search.type.mjs +5 -2
  148. package/api/swizzle/copy/copy.mjs +28 -11
  149. package/api/swizzle/swizzle.doc.mjs +8 -5
  150. package/api/swizzle/swizzle.type.d.mts +2 -2
  151. package/api/swizzle/swizzle.type.mjs +2 -2
  152. package/api/template/copy/copy.mjs +18 -24
  153. package/api/template/copy/copy.test.mjs +26 -0
  154. package/api/template/list/list.mjs +1 -0
  155. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  156. package/api/template/template-integration.test.mjs +1072 -3
  157. package/api/template/template-suffix.test.mjs +41 -21
  158. package/api/template/template.d.mts +1 -1
  159. package/api/template/template.doc.mjs +32 -9
  160. package/api/template/template.mjs +45 -8
  161. package/api/template/template.type.d.mts +12 -14
  162. package/api/template/template.type.mjs +15 -14
  163. package/api/theme/_adapter.d.mts +2 -3
  164. package/api/theme/_adapter.mjs +4 -5
  165. package/api/theme/add/add.binary.test.mjs +84 -0
  166. package/api/theme/add/add.mjs +31 -22
  167. package/api/theme/add/add.rollback.test.mjs +158 -0
  168. package/api/theme/add/add.staging.test.mjs +83 -0
  169. package/api/theme/add/add.test.mjs +14 -1
  170. package/api/theme/build/build.family.test.mjs +7 -12
  171. package/api/theme/build/build.mjs +140 -59
  172. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  173. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  174. package/api/theme/build/build.rollback.test.mjs +148 -0
  175. package/api/theme/build/build.test.mjs +127 -0
  176. package/api/theme/build/font-warning.mjs +3 -3
  177. package/api/theme/build/font-warning.test.mjs +5 -2
  178. package/api/theme/generateTonalPalette.doc.mjs +2 -2
  179. package/api/theme/integration-themes.test.mjs +39 -28
  180. package/api/theme/list/list.test.mjs +19 -20
  181. package/api/theme/listThemes.doc.mjs +6 -5
  182. package/api/theme/palette/generate/generate.mjs +8 -3
  183. package/api/theme/palette/generate/generate.test.mjs +96 -0
  184. package/api/theme/palette/generate/generator.d.mts +10 -13
  185. package/api/theme/palette/generate/generator.mjs +15 -4
  186. package/api/theme/palette/generate/generator.test.mjs +10 -0
  187. package/api/theme/template/template.mjs +11 -2
  188. package/api/theme/template/template.test.mjs +20 -0
  189. package/api/theme/theme.type.d.mts +170 -11
  190. package/api/theme/theme.type.mjs +94 -27
  191. package/api/theme/themeAdd.doc.mjs +12 -12
  192. package/api/theme/themeBuild.doc.mjs +21 -17
  193. package/api/theme/themeList.doc.mjs +6 -3
  194. package/api/theme/themeListAvailable.doc.mjs +6 -3
  195. package/api/theme/themePaletteGenerate.doc.mjs +16 -8
  196. package/api/theme/themeTargets.doc.mjs +4 -2
  197. package/api/theme/themeTemplate.doc.mjs +8 -3
  198. package/api/upgrade/_adapter.d.mts +32 -5
  199. package/api/upgrade/_adapter.mjs +139 -22
  200. package/api/upgrade/list/list.mjs +2 -1
  201. package/api/upgrade/list/list.test.mjs +73 -0
  202. package/api/upgrade/project-context.test.mjs +272 -0
  203. package/api/upgrade/provider-agreement.test.mjs +152 -0
  204. package/api/upgrade/run/files-changed.test.mjs +111 -0
  205. package/api/upgrade/run/run.mjs +358 -59
  206. package/api/upgrade/status/status.mjs +2 -2
  207. package/api/upgrade/upgrade.doc.mjs +32 -23
  208. package/api/upgrade/upgrade.type.d.mts +43 -5
  209. package/api/upgrade/upgrade.type.mjs +29 -13
  210. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  211. package/assets/codemods/__tests__/runner.test.mjs +332 -8
  212. package/assets/codemods/file-count.test.mjs +163 -0
  213. package/assets/codemods/integration-discovery.mjs +48 -4
  214. package/assets/codemods/integration-discovery.test.mjs +73 -0
  215. package/assets/codemods/integration-runner.mjs +59 -7
  216. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  217. package/assets/codemods/registry.mjs +1 -0
  218. package/assets/codemods/run-codemod.mjs +177 -34
  219. package/assets/codemods/runner.mjs +353 -104
  220. package/assets/codemods/term-log.mjs +32 -8
  221. package/assets/codemods/term-log.test.mjs +19 -1
  222. package/assets/codemods/transform-prop.mjs +109 -0
  223. package/assets/codemods/transform-prop.test.mjs +95 -0
  224. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  225. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  226. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  227. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  228. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  229. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  230. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  231. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  232. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  233. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  234. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  235. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  236. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  237. package/assets/docs/README.md +12 -1
  238. package/assets/docs/authoring.doc.mjs +14 -0
  239. package/assets/docs/browser-support.doc.mjs +11 -11
  240. package/assets/docs/color.doc.mjs +8 -2
  241. package/assets/docs/elevation.doc.mjs +6 -4
  242. package/assets/docs/getting-started.doc.mjs +6 -17
  243. package/assets/docs/icons.doc.mjs +2 -21
  244. package/assets/docs/illustrations.doc.mjs +7 -15
  245. package/assets/docs/internationalization.doc.mjs +7 -5
  246. package/assets/docs/layout.doc.dense.mjs +132 -84
  247. package/assets/docs/layout.doc.mjs +134 -78
  248. package/assets/docs/migration.doc.mjs +19 -21
  249. package/assets/docs/motion.doc.mjs +16 -3
  250. package/assets/docs/principles.doc.dense.mjs +5 -5
  251. package/assets/docs/principles.doc.mjs +14 -6
  252. package/assets/docs/principles.doc.zh.mjs +6 -6
  253. package/assets/docs/shape.doc.mjs +8 -3
  254. package/assets/docs/spacing.doc.mjs +7 -2
  255. package/assets/docs/styling-libraries.doc.mjs +10 -6
  256. package/assets/docs/styling.doc.mjs +22 -26
  257. package/assets/docs/theme.doc.dense.mjs +58 -18
  258. package/assets/docs/theme.doc.mjs +60 -50
  259. package/assets/docs/theme.doc.zh.mjs +9 -8
  260. package/assets/docs/tokens.doc.dense.mjs +2 -2
  261. package/assets/docs/tokens.doc.mjs +390 -9
  262. package/assets/docs/tokens.doc.zh.mjs +2 -2
  263. package/assets/docs/tree/add-a-component.doc.mjs +75 -0
  264. package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
  265. package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
  266. package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
  267. package/assets/docs/tree/api.doc.mjs +30 -0
  268. package/assets/docs/tree/block-template.doc.mjs +130 -0
  269. package/assets/docs/tree/build-the-template.doc.mjs +28 -0
  270. package/assets/docs/tree/building-blocks.doc.mjs +46 -0
  271. package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
  272. package/assets/docs/tree/checks.doc.mjs +119 -0
  273. package/assets/docs/tree/cli.doc.mjs +23 -0
  274. package/assets/docs/tree/codemods.doc.mjs +147 -0
  275. package/assets/docs/tree/commands.doc.mjs +25 -0
  276. package/assets/docs/tree/component-family.doc.mjs +113 -0
  277. package/assets/docs/tree/component-imports.doc.mjs +69 -0
  278. package/assets/docs/tree/component-lookups.doc.mjs +149 -0
  279. package/assets/docs/tree/components.doc.mjs +23 -0
  280. package/assets/docs/tree/configuration.doc.mjs +23 -0
  281. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
  282. package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
  283. package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
  284. package/assets/docs/tree/docs.doc.mjs +21 -0
  285. package/assets/docs/tree/document-the-template.doc.mjs +28 -0
  286. package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
  287. package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
  288. package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
  291. package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
  292. package/assets/docs/tree/help.doc.mjs +16 -0
  293. package/assets/docs/tree/integrations.doc.mjs +40 -0
  294. package/assets/docs/tree/links.doc.mjs +98 -0
  295. package/assets/docs/tree/package-and-test.doc.mjs +32 -0
  296. package/assets/docs/tree/page-template.doc.mjs +71 -0
  297. package/assets/docs/tree/publishing.doc.mjs +111 -0
  298. package/assets/docs/tree/quick-start.doc.mjs +272 -0
  299. package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
  300. package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
  301. package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
  302. package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
  303. package/assets/docs/tree/ship.doc.mjs +16 -0
  304. package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
  305. package/assets/docs/tree/single-component.doc.mjs +165 -0
  306. package/assets/docs/tree/start-a-template.doc.mjs +143 -0
  307. package/assets/docs/tree/subcomponent.doc.mjs +115 -0
  308. package/assets/docs/tree/template-assets.doc.mjs +64 -0
  309. package/assets/docs/tree/template-doc-overview.doc.mjs +109 -0
  310. package/assets/docs/tree/template-fonts.doc.mjs +102 -0
  311. package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
  312. package/assets/docs/tree/template-icons.doc.mjs +97 -0
  313. package/assets/docs/tree/template-images-media.doc.mjs +127 -0
  314. package/assets/docs/tree/template-styles.doc.mjs +93 -0
  315. package/assets/docs/tree/templates.doc.mjs +34 -0
  316. package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
  317. package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
  318. package/assets/docs/tree/themes.doc.mjs +39 -0
  319. package/assets/docs/tree/troubleshooting.doc.mjs +149 -0
  320. package/assets/docs/tree/upgrading.doc.mjs +103 -0
  321. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
  322. package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
  323. package/assets/docs/tree/versioning.doc.mjs +161 -0
  324. package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
  325. package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
  326. package/assets/docs/typography.doc.mjs +24 -4
  327. package/assets/docs/working-with-ai.doc.mjs +34 -26
  328. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  329. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  330. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  331. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  332. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  333. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  334. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  335. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  336. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  337. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  338. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  339. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  340. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  341. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  342. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  343. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  344. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  345. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  346. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  347. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  348. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  349. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  350. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  351. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  352. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  353. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  354. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  355. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  356. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  357. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  358. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  359. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  360. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  361. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  362. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  363. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  364. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  365. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  366. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  367. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  368. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  369. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  370. package/authoring/_shared/contract.ts +22 -0
  371. package/authoring/codemod/codemod.doc.mjs +7 -2
  372. package/authoring/codemod/parse.d.mts +8 -8
  373. package/authoring/codemod/parse.mjs +8 -6
  374. package/authoring/codemod/type.ts +12 -0
  375. package/authoring/config/config.doc.mjs +11 -3
  376. package/authoring/config/debug-composition.test.mjs +92 -0
  377. package/authoring/config/parse.d.mts +15 -13
  378. package/authoring/config/parse.mjs +27 -8
  379. package/authoring/config/parse.test.mjs +8 -0
  380. package/authoring/config/type.ts +29 -6
  381. package/authoring/debug/debug.doc.d.mts +11 -0
  382. package/authoring/debug/debug.doc.mjs +182 -0
  383. package/authoring/debug/parse.d.mts +8 -8
  384. package/authoring/debug/parse.mjs +3 -3
  385. package/authoring/discover/discover.doc.d.mts +13 -0
  386. package/authoring/discover/discover.doc.mjs +138 -0
  387. package/authoring/discover/parse.d.mts +24 -0
  388. package/authoring/discover/parse.mjs +128 -0
  389. package/authoring/discover/parse.test.mjs +124 -0
  390. package/authoring/discover/type.ts +87 -0
  391. package/authoring/doctypes/_schema.d.mts +792 -24
  392. package/authoring/doctypes/_schema.mjs +549 -39
  393. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  394. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  395. package/authoring/doctypes/base/type.ts +43 -0
  396. package/authoring/doctypes/command/command.doc.mjs +4 -3
  397. package/authoring/doctypes/command/parse.d.mts +2 -2
  398. package/authoring/doctypes/command/parse.mjs +1 -1
  399. package/authoring/doctypes/command/type.ts +5 -4
  400. package/authoring/doctypes/component/component.doc.mjs +12 -3
  401. package/authoring/doctypes/component/parse.d.mts +2 -2
  402. package/authoring/doctypes/component/parse.mjs +1 -1
  403. package/authoring/doctypes/component/type.ts +14 -5
  404. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  405. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  406. package/authoring/doctypes/enum/parse.d.mts +2 -2
  407. package/authoring/doctypes/enum/parse.mjs +1 -1
  408. package/authoring/doctypes/enum/type.ts +4 -2
  409. package/authoring/doctypes/function/function.doc.mjs +7 -2
  410. package/authoring/doctypes/function/parse.d.mts +2 -2
  411. package/authoring/doctypes/function/parse.mjs +1 -1
  412. package/authoring/doctypes/function/type.ts +9 -4
  413. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  414. package/authoring/doctypes/hook/parse.d.mts +2 -2
  415. package/authoring/doctypes/hook/parse.mjs +1 -1
  416. package/authoring/doctypes/hook/type.ts +5 -4
  417. package/authoring/doctypes/legacy.d.mts +8 -6
  418. package/authoring/doctypes/legacy.mjs +5 -4
  419. package/authoring/doctypes/load-contract.test.mjs +233 -0
  420. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  421. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  422. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  423. package/authoring/doctypes/namespace/parse.mjs +25 -0
  424. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  425. package/authoring/doctypes/namespace/type.ts +74 -0
  426. package/authoring/doctypes/parse.d.mts +22 -18
  427. package/authoring/doctypes/parse.mjs +22 -11
  428. package/authoring/doctypes/parse.test.mjs +77 -3
  429. package/authoring/doctypes/reference/parse.d.mts +2 -2
  430. package/authoring/doctypes/reference/parse.mjs +8 -5
  431. package/authoring/doctypes/reference/reference.doc.mjs +55 -6
  432. package/authoring/doctypes/reference/type.ts +75 -7
  433. package/authoring/doctypes/schema/parse.d.mts +2 -2
  434. package/authoring/doctypes/schema/parse.mjs +1 -1
  435. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  436. package/authoring/doctypes/schema/type.ts +4 -4
  437. package/authoring/doctypes/template/parse.d.mts +94 -1
  438. package/authoring/doctypes/template/parse.mjs +40 -2
  439. package/authoring/doctypes/template/parse.test.mjs +26 -2
  440. package/authoring/doctypes/template/template.doc.mjs +13 -3
  441. package/authoring/doctypes/template/type.ts +13 -2
  442. package/authoring/doctypes/theme/parse.d.mts +35 -0
  443. package/authoring/doctypes/theme/parse.mjs +76 -0
  444. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  445. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  446. package/authoring/doctypes/theme/type.ts +42 -0
  447. package/authoring/doctypes/types.ts +12 -10
  448. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  449. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  450. package/authoring/gap-report/parse.d.mts +10 -10
  451. package/authoring/gap-report/parse.mjs +6 -6
  452. package/authoring/gap-report/type.ts +1 -1
  453. package/authoring/identity/identity.doc.d.mts +9 -0
  454. package/authoring/identity/identity.doc.mjs +61 -0
  455. package/authoring/identity/type.ts +132 -0
  456. package/authoring/index.d.mts +3 -0
  457. package/authoring/index.d.ts +62 -17
  458. package/authoring/index.mjs +4 -1
  459. package/authoring/integration/integration.doc.mjs +22 -13
  460. package/authoring/integration/parse.d.mts +2 -2
  461. package/authoring/integration/parse.mjs +1 -1
  462. package/authoring/integration/parse.test.mjs +10 -1
  463. package/authoring/integration/schema.d.mts +6 -4
  464. package/authoring/integration/schema.mjs +9 -3
  465. package/authoring/integration/type.ts +19 -8
  466. package/authoring/shadcn/receipt.d.mts +6 -6
  467. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  468. package/clients/cli/command-load-failure.test.mjs +83 -0
  469. package/clients/cli/commands/blog.doc.mjs +1 -1
  470. package/clients/cli/commands/blog.mjs +23 -8
  471. package/clients/cli/commands/blog.test.mjs +42 -1
  472. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  473. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  474. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  475. package/clients/cli/commands/build-theme.mjs +16 -50
  476. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  477. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  478. package/clients/cli/commands/build.doc.mjs +16 -8
  479. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  480. package/clients/cli/commands/build.mjs +137 -114
  481. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  482. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  483. package/clients/cli/commands/component/index.mjs +153 -61
  484. package/clients/cli/commands/component-batch.test.mjs +341 -0
  485. package/clients/cli/commands/component-ownership.test.mjs +92 -3
  486. package/clients/cli/commands/component-package.test.mjs +46 -0
  487. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  488. package/clients/cli/commands/component.doc.mjs +28 -10
  489. package/clients/cli/commands/component.test.mjs +19 -0
  490. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  491. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  492. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  493. package/clients/cli/commands/discover.doc.mjs +55 -9
  494. package/clients/cli/commands/discover.mjs +393 -118
  495. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  496. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  497. package/clients/cli/commands/docs.doc.mjs +28 -6
  498. package/clients/cli/commands/docs.mjs +295 -38
  499. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  500. package/clients/cli/commands/doctor-integration-docs.doc.mjs +6 -5
  501. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  502. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  503. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  504. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  505. package/clients/cli/commands/doctor-integration.test.mjs +143 -8
  506. package/clients/cli/commands/doctor.doc.mjs +4 -2
  507. package/clients/cli/commands/doctor.mjs +108 -37
  508. package/clients/cli/commands/doctor.test.mjs +42 -0
  509. package/clients/cli/commands/gap-report.doc.mjs +27 -15
  510. package/clients/cli/commands/gap-report.test.mjs +72 -0
  511. package/clients/cli/commands/hook/index.mjs +7 -17
  512. package/clients/cli/commands/hook.doc.mjs +1 -1
  513. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  514. package/clients/cli/commands/init.doc.mjs +24 -10
  515. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  516. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  517. package/clients/cli/commands/integration-add.doc.mjs +39 -13
  518. package/clients/cli/commands/integration-authoring.test.mjs +74 -19
  519. package/clients/cli/commands/integration-pack.doc.mjs +6 -10
  520. package/clients/cli/commands/integration-real-world.test.mjs +4 -10
  521. package/clients/cli/commands/integration-verify.doc.mjs +22 -0
  522. package/clients/cli/commands/integration.doc.mjs +5 -5
  523. package/clients/cli/commands/integration.mjs +75 -43
  524. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  525. package/clients/cli/commands/json-contract.test.mjs +33 -0
  526. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  527. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  528. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  529. package/clients/cli/commands/layout.doc.mjs +3 -3
  530. package/clients/cli/commands/layout.mjs +21 -9
  531. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  532. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  533. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  534. package/clients/cli/commands/manifest.doc.mjs +2 -2
  535. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  536. package/clients/cli/commands/search.doc.mjs +16 -6
  537. package/clients/cli/commands/search.mjs +49 -11
  538. package/clients/cli/commands/search.test.mjs +92 -0
  539. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  540. package/clients/cli/commands/swizzle.doc.mjs +4 -3
  541. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  542. package/clients/cli/commands/template.doc.mjs +53 -14
  543. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  544. package/clients/cli/commands/template.mjs +4 -91
  545. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  546. package/clients/cli/commands/text-json-parity.test.mjs +725 -0
  547. package/clients/cli/commands/theme-add.doc.mjs +5 -4
  548. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  549. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  550. package/clients/cli/commands/theme-palette-generate.doc.mjs +12 -7
  551. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  552. package/clients/cli/commands/theme-palette.doc.mjs +2 -3
  553. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  554. package/clients/cli/commands/theme-targets.doc.mjs +3 -3
  555. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  556. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  557. package/clients/cli/commands/theme.doc.mjs +3 -2
  558. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  559. package/clients/cli/commands/upgrade.doc.mjs +83 -12
  560. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  561. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  562. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  563. package/clients/cli/commands/upgrade.mjs +29 -7
  564. package/clients/cli/formatters/index.mjs +164 -1
  565. package/clients/cli/formatters/index.test.mjs +97 -0
  566. package/clients/cli/index.mjs +47 -34
  567. package/clients/cli/latest-version-env.test.mjs +50 -0
  568. package/clients/cli/lib/cli-error.test.mjs +7 -0
  569. package/clients/cli/lib/component-format.mjs +9 -9
  570. package/clients/cli/lib/component-format.test.mjs +1 -1
  571. package/clients/cli/lib/define-command.mjs +56 -6
  572. package/clients/cli/lib/define-command.test.mjs +54 -0
  573. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  574. package/clients/cli/lib/exit-codes.test.mjs +113 -0
  575. package/clients/cli/lib/hook-format.mjs +19 -10
  576. package/clients/cli/lib/json-shim.mjs +62 -16
  577. package/clients/cli/lib/json-shim.test.mjs +83 -0
  578. package/clients/cli/lib/manifest.d.ts +2 -0
  579. package/clients/cli/lib/manifest.mjs +53 -6
  580. package/clients/cli/lib/manifest.test.mjs +22 -2
  581. package/clients/cli/lib/parse-error-format.test.mjs +81 -0
  582. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  583. package/foundation/agent-docs/agent-docs.mjs +83 -13
  584. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  585. package/foundation/config/integration-debug.test.mjs +28 -3
  586. package/foundation/config/project-themes.test.mjs +11 -19
  587. package/foundation/config/project.d.mts +20 -11
  588. package/foundation/config/project.mjs +263 -91
  589. package/foundation/config/project.test.mjs +270 -21
  590. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  591. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  592. package/foundation/discovery/authoring-self-docs.test.mjs +174 -0
  593. package/foundation/discovery/authoring-surface.d.mts +74 -0
  594. package/foundation/discovery/authoring-surface.mjs +525 -0
  595. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  596. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  597. package/foundation/discovery/cli-self-docs.mjs +504 -0
  598. package/foundation/discovery/cli-self-docs.test.mjs +395 -0
  599. package/foundation/discovery/component-discovery.d.mts +39 -1
  600. package/foundation/discovery/component-discovery.mjs +50 -1
  601. package/foundation/discovery/component-loader.d.mts +35 -38
  602. package/foundation/discovery/component-loader.mjs +53 -222
  603. package/foundation/discovery/docs-discovery.d.mts +119 -11
  604. package/foundation/discovery/docs-discovery.mjs +427 -108
  605. package/foundation/discovery/docs-discovery.test.mjs +386 -20
  606. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  607. package/foundation/discovery/docs-output-budget.mjs +50 -0
  608. package/foundation/discovery/docs-section-key.d.mts +116 -0
  609. package/foundation/discovery/docs-section-key.mjs +322 -0
  610. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  611. package/foundation/discovery/template-adapter.d.mts +113 -11
  612. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  613. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  614. package/foundation/discovery/template-adapter.mjs +774 -83
  615. package/foundation/discovery/template-adapter.test.mjs +57 -0
  616. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  617. package/foundation/discovery/template-conflict-release.mjs +40 -0
  618. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  619. package/foundation/discovery/theme-discovery.d.mts +67 -7
  620. package/foundation/discovery/theme-discovery.mjs +916 -186
  621. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  622. package/foundation/discovery/theming-targets.test.mjs +4 -0
  623. package/foundation/doc-compiler/bundle.d.mts +47 -0
  624. package/foundation/doc-compiler/bundle.mjs +278 -0
  625. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  626. package/foundation/doc-compiler/compile.d.mts +343 -0
  627. package/foundation/doc-compiler/compile.mjs +558 -0
  628. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  629. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  630. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  631. package/foundation/doc-compiler/doc-loads.test.mjs +1643 -0
  632. package/foundation/doc-compiler/import.d.mts +24 -0
  633. package/foundation/doc-compiler/import.mjs +59 -0
  634. package/foundation/doc-compiler/inputs.d.mts +102 -0
  635. package/foundation/doc-compiler/inputs.mjs +291 -0
  636. package/foundation/doc-compiler/inputs.test.mjs +298 -0
  637. package/foundation/doc-compiler/ir.d.mts +22 -0
  638. package/foundation/doc-compiler/ir.mjs +471 -0
  639. package/foundation/doc-compiler/lenses.d.mts +36 -0
  640. package/foundation/doc-compiler/lenses.mjs +173 -0
  641. package/foundation/doc-compiler/links.d.mts +162 -0
  642. package/foundation/doc-compiler/links.mjs +294 -0
  643. package/foundation/doc-compiler/links.test.mjs +192 -0
  644. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  645. package/foundation/doc-compiler/overlays.d.mts +37 -0
  646. package/foundation/doc-compiler/overlays.mjs +206 -0
  647. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  648. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  649. package/foundation/doc-compiler/read.d.mts +127 -0
  650. package/foundation/doc-compiler/read.mjs +325 -0
  651. package/foundation/doc-compiler/read.test.mjs +313 -0
  652. package/foundation/doc-compiler/source.d.mts +33 -0
  653. package/foundation/doc-compiler/source.mjs +128 -0
  654. package/foundation/doc-compiler/tree.d.mts +292 -0
  655. package/foundation/doc-compiler/tree.mjs +881 -0
  656. package/foundation/fs/file-protection.d.mts +33 -0
  657. package/foundation/fs/file-protection.mjs +825 -0
  658. package/foundation/fs/file-protection.test.mjs +250 -0
  659. package/foundation/fs/module-loader.d.mts +1 -0
  660. package/foundation/fs/module-loader.mjs +50 -1
  661. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  662. package/foundation/fs/path-safety.d.mts +3 -2
  663. package/foundation/fs/path-safety.mjs +49 -19
  664. package/foundation/fs/path-safety.test.mjs +50 -0
  665. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  666. package/foundation/identity/provider-identity.d.mts +90 -0
  667. package/foundation/identity/provider-identity.mjs +320 -0
  668. package/foundation/identity/provider-identity.test.mjs +254 -0
  669. package/foundation/identity/providers.d.mts +7 -0
  670. package/foundation/identity/providers.mjs +16 -0
  671. package/foundation/integrations/autolink.d.mts +58 -1
  672. package/foundation/integrations/autolink.mjs +143 -45
  673. package/foundation/integrations/autolink.test.mjs +1 -1
  674. package/foundation/integrations/cli-requirement.d.mts +65 -0
  675. package/foundation/integrations/cli-requirement.mjs +189 -0
  676. package/foundation/integrations/cli-requirement.test.mjs +89 -0
  677. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  678. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  679. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  680. package/foundation/integrations/contribution-inventory.mjs +28 -25
  681. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  682. package/foundation/integrations/integration-warnings.d.mts +9 -2
  683. package/foundation/integrations/integration-warnings.mjs +52 -21
  684. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  685. package/foundation/integrations/integrations.d.mts +63 -3
  686. package/foundation/integrations/integrations.mjs +122 -9
  687. package/foundation/integrations/integrations.test.mjs +415 -1
  688. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  689. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  690. package/foundation/integrations/provider-resolution.d.mts +152 -0
  691. package/foundation/integrations/provider-resolution.mjs +576 -0
  692. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  693. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  694. package/foundation/integrations/theme-descriptor.mjs +44 -0
  695. package/foundation/integrations/validate-contributions.d.mts +2 -0
  696. package/foundation/integrations/validate-contributions.mjs +131 -29
  697. package/foundation/response/base.d.ts +8 -4
  698. package/foundation/response/batch.type.d.mts +33 -0
  699. package/foundation/response/batch.type.mjs +34 -0
  700. package/foundation/response/error-codes.d.mts +3 -1
  701. package/foundation/response/error-codes.d.ts +2 -0
  702. package/foundation/response/error-codes.doc.mjs +19 -12
  703. package/foundation/response/error-codes.mjs +8 -2
  704. package/foundation/response/error-codes.test.mjs +166 -14
  705. package/foundation/response/json-contract.test.mjs +57 -17
  706. package/foundation/response/json.d.mts +4 -2
  707. package/foundation/response/json.mjs +8 -10
  708. package/foundation/response/response-types.doc.d.mts +7 -2
  709. package/foundation/response/response-types.doc.mjs +69 -25
  710. package/foundation/response/response-types.doc.test.mjs +181 -0
  711. package/foundation/response/response.doc.mjs +12 -11
  712. package/foundation/text/string-utils.d.mts +8 -0
  713. package/foundation/text/string-utils.mjs +40 -10
  714. package/foundation/xle/expand.d.mts +2 -0
  715. package/foundation/xle/expand.mjs +4 -3
  716. package/foundation/xle/expand.test.mjs +54 -0
  717. package/foundation/xle/xle.test.mjs +13 -0
  718. package/package.json +10 -11
  719. package/api/docs/docs.test.mjs +0 -83
  720. package/api/docs/integrationDocs.test.mjs +0 -208
  721. package/api/search/search.test.mjs +0 -389
  722. package/assets/docs/cli-integrations.doc.mjs +0 -367
  723. package/assets/templates/themes/manifest.json +0 -95
  724. package/clients/cli/commands/docs.test.mjs +0 -102
  725. package/clients/cli/lib/update-check.mjs +0 -83
  726. package/clients/cli/lib/update-check.test.mjs +0 -137
  727. package/clients/cli/update-hint-commands.test.mjs +0 -54
  728. package/foundation/agent-docs/agent-docs.test.mjs +0 -1141
@@ -25,6 +25,9 @@
25
25
  */
26
26
 
27
27
  import {recordCommandResult} from '../../../foundation/debug/index.mjs';
28
+ import {routeSegment} from '../../../foundation/discovery/docs-section-key.mjs';
29
+ import {formatCliCommand} from '../../../foundation/env/package-manager.mjs';
30
+ import {text} from '../formatters/index.mjs';
28
31
 
29
32
  /**
30
33
  * Marks a Commander command that reports what it answered with, and says HOW:
@@ -78,6 +81,21 @@ export function markReportsResult(cmd) {
78
81
  return cmd;
79
82
  }
80
83
 
84
+ /** The CommandDoc and wrapped FunctionDoc a command was built from. */
85
+ export const COMMAND_DOCS = Symbol.for('astryx.command.docs');
86
+
87
+ /**
88
+ * The docs a command was built from; undefined for a hand-registered command.
89
+ * @param {import('commander').Command} cmd
90
+ * @returns {{
91
+ * doc: import('@astryxdesign/cli/authoring').CommandDoc,
92
+ * fn?: import('@astryxdesign/cli/authoring').FunctionDoc,
93
+ * } | undefined}
94
+ */
95
+ export function commandDocsOf(cmd) {
96
+ return /** @type {any} */ (cmd)?.[COMMAND_DOCS];
97
+ }
98
+
81
99
  /**
82
100
  * Build a Commander command from a CommandDoc and attach it to `parent`.
83
101
  *
@@ -102,6 +120,7 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
102
120
  .join(' ');
103
121
 
104
122
  const cmd = parent.command(argSpec ? `${token} ${argSpec}` : token);
123
+ Object.defineProperty(cmd, COMMAND_DOCS, {value: {doc, fn}, configurable: true});
105
124
  if (doc.summary) cmd.description(doc.summary);
106
125
 
107
126
  const paramDesc = (/** @type {string | undefined} */ name) =>
@@ -126,12 +145,11 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
126
145
  cmd.addOption(option);
127
146
  }
128
147
 
129
- // `choices` and `examples` are doc metadata surfaced by `astryx docs` and the
130
- // doc site; they are intentionally NOT injected into `--help` here. Choices
131
- // stay described in the option text (Commander `.choices()` would also change
132
- // validation from the api layer's ERR_INVALID_ARGUMENT), and the current CLI
133
- // help carries no per-command examples epilog. Keeping both out preserves the
134
- // exact `--help`/manifest surface as registrations migrate to this converter.
148
+ // Help ends with the documented exit codes, the examples, and the docs
149
+ // route that reads the whole command. `choices` stay in the option text:
150
+ // Commander `.choices()` would replace the api layer's ERR_INVALID_ARGUMENT
151
+ // validation.
152
+ addDocHelp(cmd, doc);
135
153
 
136
154
  if (action) {
137
155
  // The recording seam. An action's job ends at "here is what I answered
@@ -149,3 +167,35 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
149
167
  }
150
168
  return cmd;
151
169
  }
170
+
171
+ /**
172
+ * End `cmd`'s help with what its CommandDoc says: the exit codes, then the
173
+ * examples, then `More:`, the `astryx docs` route that reads the whole command.
174
+ * @param {import('commander').Command} cmd
175
+ * @param {import('@astryxdesign/cli/authoring').CommandDoc} doc
176
+ */
177
+ export function addDocHelp(cmd, doc) {
178
+ addExitCodesHelp(cmd, doc.exitCodes);
179
+ // Rendered when help is shown, so the run prefix (npx astryx, pnpm astryx,
180
+ // ...) is looked up then, not on every start.
181
+ cmd.addHelpText('after', () => {
182
+ const examples = (doc.examples ?? []).flatMap(({label, cli}) => [
183
+ ...(label ? [` # ${label}`] : []),
184
+ ` ${formatCliCommand(cli)}`,
185
+ ]);
186
+ const more = `More: ${formatCliCommand(`docs cli/commands/${routeSegment(doc.name)}`)}`;
187
+ const blocks = examples.length > 0 ? [['Examples:', ...examples].join('\n'), more] : [more];
188
+ return `\n${text(blocks.join('\n\n')).toString()}`;
189
+ });
190
+ }
191
+
192
+ /**
193
+ * End `cmd`'s help with a CommandDoc's exit codes.
194
+ * @param {import('commander').Command} cmd
195
+ * @param {import('@astryxdesign/cli/authoring').CommandDoc['exitCodes']} exitCodes
196
+ */
197
+ export function addExitCodesHelp(cmd, exitCodes) {
198
+ if (!exitCodes?.length) return;
199
+ const lines = exitCodes.map(({code, when}) => ` ${code} ${when}`);
200
+ cmd.addHelpText('after', `\n${text(['Exit codes:', ...lines].join('\n')).toString()}`);
201
+ }
@@ -7,6 +7,7 @@
7
7
  import {Command} from 'commander';
8
8
  import {describe, it, expect} from 'vitest';
9
9
  import {defineCommand} from './define-command.mjs';
10
+ import {formatCliCommand} from '../../../foundation/env/package-manager.mjs';
10
11
  import {doc as searchCommand} from '../commands/search.doc.mjs';
11
12
  import {doc as searchFn} from '../../../api/search/search.doc.mjs';
12
13
 
@@ -46,4 +47,57 @@ describe('defineCommand', () => {
46
47
  expect(cmd.name()).toBe('build');
47
48
  expect(cmd.registeredArguments.map(a => a.name())).toEqual(['file']);
48
49
  });
50
+
51
+ it('ends help with the exit codes, the examples, and the docs route', () => {
52
+ const program = new Command();
53
+ const group = program.command('grp');
54
+ const cmd = defineCommand(
55
+ group,
56
+ {
57
+ type: 'command',
58
+ name: 'grp sub',
59
+ displayName: 'astryx grp sub',
60
+ summary: 'Sub.',
61
+ examples: [
62
+ {label: 'Run it', cli: 'astryx grp sub x'},
63
+ {cli: 'astryx grp sub y --json'},
64
+ ],
65
+ exitCodes: [{code: 0, when: 'it works'}],
66
+ },
67
+ {action: () => {}},
68
+ );
69
+ let out = '';
70
+ cmd.configureOutput({writeOut: s => (out += s)});
71
+ cmd.outputHelp();
72
+ const stem = formatCliCommand('');
73
+ expect(out.slice(out.indexOf('\nExit codes:\n'))).toBe(
74
+ [
75
+ '',
76
+ 'Exit codes:',
77
+ ' 0 it works',
78
+ '',
79
+ 'Examples:',
80
+ ' # Run it',
81
+ ` ${stem} grp sub x`,
82
+ ` ${stem} grp sub y --json`,
83
+ '',
84
+ `More: ${stem} docs cli/commands/grp-sub`,
85
+ '',
86
+ ].join('\n'),
87
+ );
88
+ });
89
+
90
+ it('still names the docs route when a command has no examples', () => {
91
+ const program = new Command();
92
+ const cmd = defineCommand(
93
+ program,
94
+ {type: 'command', name: 'solo', summary: 'Solo.', exitCodes: [{code: 0, when: 'ok'}]},
95
+ {action: () => {}},
96
+ );
97
+ let out = '';
98
+ cmd.configureOutput({writeOut: s => (out += s)});
99
+ cmd.outputHelp();
100
+ expect(out).not.toContain('Examples:');
101
+ expect(out.endsWith(`\n\nMore: ${formatCliCommand('docs cli/commands/solo')}\n`)).toBe(true);
102
+ });
49
103
  });
@@ -0,0 +1,82 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The component and hook text renderers add no non-ASCII characters of
5
+ * their own: given ASCII-only docs, every view they produce is plain ASCII.
6
+ */
7
+
8
+ import {describe, it, expect} from 'vitest';
9
+ import {
10
+ formatBrief,
11
+ formatCompact,
12
+ formatFull,
13
+ formatProps,
14
+ } from './component-format.mjs';
15
+ import {
16
+ formatHookBrief,
17
+ formatHookCompact,
18
+ formatHookFull,
19
+ formatHookParams,
20
+ } from './hook-format.mjs';
21
+
22
+ const NON_ASCII = /[\u0080-\uffff]/g;
23
+
24
+ /** @param {string} out @returns {string[]} */
25
+ const nonAscii = out => out.match(NON_ASCII) ?? [];
26
+
27
+ // Every optional field left empty and every optional path taken, so each
28
+ // placeholder, separator, and arrow the renderers emit shows up at least once.
29
+ const componentDoc = {
30
+ name: 'Widget',
31
+ description: 'A widget for tests.',
32
+ props: [
33
+ {name: 'variant', type: "'solid' | 'ghost'", description: 'Look.'},
34
+ {name: 'label', type: 'string', description: 'Label.', required: true},
35
+ {name: 'disabled', type: 'boolean', description: 'Disables it.'},
36
+ {name: 'tone', type: 'string', description: 'Tone.'},
37
+ ],
38
+ theming: {
39
+ vars: [{name: '--widget-gap', default: '8px', description: 'Gap.'}],
40
+ derived: [
41
+ {property: 'padding', expand: 'container'},
42
+ {property: 'radius', vars: ['--widget-radius']},
43
+ ],
44
+ targets: [
45
+ {className: 'astryx-widget', deprecatedFor: 'astryx-widget-v2'},
46
+ {className: 'astryx-widget-v2', visualProps: ['variant']},
47
+ ],
48
+ },
49
+ };
50
+
51
+ const hookDoc = {
52
+ name: 'useWidget',
53
+ importPath: '@astryxdesign/core/useWidget',
54
+ usage: {description: 'Widget behavior.'},
55
+ params: [
56
+ {name: 'options', type: 'object', description: 'Options.', required: true},
57
+ {name: 'delay', type: 'number', description: 'Delay.'},
58
+ ],
59
+ returns: [{name: 'open', type: 'boolean', description: 'Open state.'}],
60
+ };
61
+
62
+ describe('component text output is ASCII', () => {
63
+ it.each([
64
+ ['formatFull', () => formatFull(componentDoc)],
65
+ ['formatCompact', () => formatCompact(componentDoc, 'Widget')],
66
+ ['formatBrief', () => formatBrief(componentDoc, 'Widget', '@astryxdesign/core/Widget')],
67
+ ['formatProps', () => formatProps(componentDoc, 'Widget')],
68
+ ])('%s', (_name, render) => {
69
+ expect(nonAscii(render())).toEqual([]);
70
+ });
71
+ });
72
+
73
+ describe('hook text output is ASCII', () => {
74
+ it.each([
75
+ ['formatHookFull', () => formatHookFull(hookDoc)],
76
+ ['formatHookCompact', () => formatHookCompact(hookDoc, hookDoc.importPath)],
77
+ ['formatHookBrief', () => formatHookBrief(hookDoc)],
78
+ ['formatHookParams', () => formatHookParams(hookDoc)],
79
+ ])('%s', (_name, render) => {
80
+ expect(nonAscii(render())).toEqual([]);
81
+ });
82
+ });
@@ -0,0 +1,113 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Every CommandDoc's exit codes reach generated help and the manifest.
5
+ */
6
+
7
+ import * as fs from 'node:fs';
8
+ import * as os from 'node:os';
9
+ import * as path from 'node:path';
10
+ import {fileURLToPath, pathToFileURL} from 'node:url';
11
+ import {describe, it, expect} from 'vitest';
12
+ import {program, JSON_SUPPORTED} from '../index.mjs';
13
+ import {buildManifest} from './manifest.mjs';
14
+ import {runCli} from '../../../test-utils/run-cli.mjs';
15
+
16
+ const COMMANDS = path.join(path.dirname(fileURLToPath(import.meta.url)), '../commands');
17
+
18
+ /** @type {any[]} */
19
+ const commandDocs = [];
20
+ for (const file of fs.readdirSync(COMMANDS).sort()) {
21
+ if (!file.endsWith('.doc.mjs')) continue;
22
+ const {doc} = await import(pathToFileURL(path.join(COMMANDS, file)).href);
23
+ if (doc?.type === 'command') commandDocs.push(doc);
24
+ }
25
+
26
+ const manifest = buildManifest(program, {jsonSupported: JSON_SUPPORTED, version: '0.0.0-test'});
27
+ /** @type {Map<string, any>} */
28
+ const entries = new Map();
29
+ const walk = (/** @type {any} */ c) => {
30
+ entries.set(c.name, c);
31
+ (c.subcommands || []).forEach(walk);
32
+ };
33
+ manifest.commands.forEach(walk);
34
+
35
+ describe('command exit codes', () => {
36
+ it('every CommandDoc documents its exit codes', () => {
37
+ expect(commandDocs.length).toBeGreaterThan(30);
38
+ for (const doc of commandDocs) {
39
+ expect(doc.exitCodes?.length, doc.name).toBeGreaterThan(0);
40
+ }
41
+ });
42
+
43
+ it.each(commandDocs.map((d) => [d.name, d]))(
44
+ '`astryx %s --help` lists the documented exit codes, then the examples and the docs route',
45
+ async (name, doc) => {
46
+ const {status, stdout} = await runCli([...name.split(' '), '--help']);
47
+ expect(status).toBe(0);
48
+ const section = stdout.slice(stdout.indexOf('\nExit codes:\n'));
49
+ expect(section.startsWith('\nExit codes:\n'), stdout).toBe(true);
50
+ expect(stdout.match(/\nExit codes?:\n/g), 'one exit-code section').toHaveLength(1);
51
+ for (const {code, when} of doc.exitCodes) {
52
+ expect(section).toContain(`\n ${code} ${when}\n`);
53
+ }
54
+ // Examples follow the exit codes, each under its label, and a `More:`
55
+ // line names the route that reads the whole command.
56
+ const examples = section.indexOf('\nExamples:\n');
57
+ expect(examples > 0, stdout).toBe((doc.examples ?? []).length > 0);
58
+ for (const {label, cli} of doc.examples ?? []) {
59
+ const line = ` ${cli.replace(/^astryx\s+/, '')}\n`;
60
+ expect(section.slice(examples), stdout).toContain(
61
+ label ? `\n # ${label}\n` : line,
62
+ );
63
+ expect(section.slice(examples)).toContain(line);
64
+ }
65
+ const route = `docs cli/commands/${name.replace(/ /g, '-')}`;
66
+ expect(section, stdout).toMatch(
67
+ new RegExp(`\\n\\nMore: \\S.* ${route}\\n`),
68
+ );
69
+ expect(section.indexOf('\nMore: ')).toBeGreaterThan(examples);
70
+ },
71
+ );
72
+
73
+ it('bare `astryx layout` exits 1 in both modes, as documented', async () => {
74
+ const doc = commandDocs.find((d) => d.name === 'layout');
75
+ expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/^no subcommand/);
76
+ expect((await runCli(['layout'])).status).toBe(1);
77
+ expect((await runCli(['layout', '--json'])).status).toBe(1);
78
+ });
79
+
80
+ it('`astryx discover` with a blank query exits 1 only when packages are discovered', async () => {
81
+ const doc = commandDocs.find((d) => d.name === 'discover');
82
+ expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/blank query when packages are discovered/);
83
+ const project = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-exit-discover-'));
84
+ try {
85
+ expect((await runCli(['discover', ' ', '--json'], {cwd: project})).status).toBe(0);
86
+ const pkg = path.join(project, 'node_modules/@acme/ui');
87
+ fs.mkdirSync(path.join(pkg, 'components'), {recursive: true});
88
+ fs.writeFileSync(path.join(pkg, 'package.json'), '{"name":"@acme/ui","version":"1.0.0","type":"module"}');
89
+ fs.writeFileSync(path.join(pkg, 'astryx.integration.mjs'), "export default {components: './components'};\n");
90
+ fs.writeFileSync(
91
+ path.join(pkg, 'components/Widget.doc.mjs'),
92
+ 'export const doc = {type: "component", name: "Widget", description: "A widget"};\n',
93
+ );
94
+ fs.writeFileSync(path.join(pkg, 'components/Widget.tsx'), 'export function Widget() { return null; }\n');
95
+ fs.writeFileSync(path.join(project, 'package.json'), '{"name":"app","type":"module"}');
96
+ fs.writeFileSync(path.join(project, 'astryx.config.mjs'), "export default {integrations: ['@acme/ui']};\n");
97
+ expect((await runCli(['discover', '--json'], {cwd: project})).status).toBe(0);
98
+ const blank = await runCli(['discover', ' ', '--json'], {cwd: project});
99
+ expect(blank.status).toBe(1);
100
+ expect(JSON.parse(blank.stdout).code).toBe('ERR_INVALID_ARGUMENT');
101
+ } finally {
102
+ fs.rmSync(project, {recursive: true, force: true});
103
+ }
104
+ });
105
+
106
+ it('the manifest carries every command exit code', () => {
107
+ for (const doc of commandDocs) {
108
+ expect(entries.get(doc.name)?.exitCodes, doc.name).toEqual(
109
+ doc.exitCodes.map(({code, when}) => ({code, when})),
110
+ );
111
+ }
112
+ });
113
+ });
@@ -9,7 +9,10 @@
9
9
  * - Brief: signature line with import hint, description, key params
10
10
  */
11
11
 
12
- import {discoverHooks, findHookDoc} from '../../../foundation/discovery/hook-discovery.mjs';
12
+ import {
13
+ discoverHooks,
14
+ findHookDoc,
15
+ } from '../../../foundation/discovery/hook-discovery.mjs';
13
16
  import {loadDocs} from '../../../foundation/discovery/component-loader.mjs';
14
17
  import {formatAccessibility, mdCell} from './component-format.mjs';
15
18
 
@@ -23,7 +26,9 @@ function buildSignature(docs) {
23
26
  const name = docs.name;
24
27
 
25
28
  // Build params string — only top-level params (skip options.foo nested params)
26
- const topParams = (docs.params || []).filter((/** @type {any} */ p) => !p.name.includes('.'));
29
+ const topParams = (docs.params || []).filter(
30
+ (/** @type {any} */ p) => !p.name.includes('.'),
31
+ );
27
32
  const paramStr = topParams
28
33
  .map((/** @type {any} */ p) => {
29
34
  const opt = p.required ? '' : '?';
@@ -57,7 +62,7 @@ function formatParamsTable(params) {
57
62
  lines.push('| Param | Type | Default | Description |');
58
63
  lines.push('|-------|------|---------|-------------|');
59
64
  for (const p of params) {
60
- const def = p.default ? `\`${mdCell(p.default)}\`` : '\u2014';
65
+ const def = p.default ? `\`${mdCell(p.default)}\`` : '-';
61
66
  const req = p.required ? ' **(required)**' : '';
62
67
  lines.push(
63
68
  `| \`${mdCell(p.name)}\` | \`${mdCell(p.type)}\` | ${def} | ${mdCell(p.description)}${req} |`,
@@ -150,7 +155,9 @@ export function formatHookCompact(docs, importPath) {
150
155
  const imp = importPath || docs.importPath;
151
156
  if (imp) {
152
157
  sections.push('## Import\n');
153
- sections.push(`\`\`\`tsx\nimport { ${docs.name} } from '${imp}';\n\`\`\`\n`);
158
+ sections.push(
159
+ `\`\`\`tsx\nimport { ${docs.name} } from '${imp}';\n\`\`\`\n`,
160
+ );
154
161
  }
155
162
 
156
163
  // Best Practices (matches component compact)
@@ -198,7 +205,7 @@ export function formatHookCompact(docs, importPath) {
198
205
  /**
199
206
  * Format a brief, LLM-optimized hook summary.
200
207
  * Matches component formatBrief conventions:
201
- * signature ← from 'import/path'
208
+ * signature <- from 'import/path'
202
209
  * description
203
210
  * key params
204
211
  * @param {any} docs
@@ -211,7 +218,7 @@ export function formatHookBrief(docs) {
211
218
  // Signature line with import hint (matches component brief)
212
219
  const sig = buildSignature(docs);
213
220
  const imp = docs.importPath;
214
- output.push(imp ? `${sig} \u2190 from '${imp}'` : sig);
221
+ output.push(imp ? `${sig} <- from '${imp}'` : sig);
215
222
 
216
223
  // Description (shortened, matches component brief)
217
224
  const desc = docs.usage?.description || '';
@@ -225,12 +232,14 @@ export function formatHookBrief(docs) {
225
232
  output.push(` Related: ${docs.relatedComponents.join(', ')}`);
226
233
  }
227
234
 
228
- // Key params (matches component brief 'prop · prop' line)
235
+ // Key params (matches component brief 'prop, prop' line)
229
236
  const paramNames = (docs.params || [])
230
237
  .filter((/** @type {any} */ p) => !p.name.includes('.'))
231
- .map((/** @type {any} */ p) => p.required ? `${p.name}: ${p.type.split('|')[0].trim()}` : p.name);
238
+ .map((/** @type {any} */ p) =>
239
+ p.required ? `${p.name}: ${p.type.split('|')[0].trim()}` : p.name,
240
+ );
232
241
  if (paramNames.length > 0) {
233
- output.push(` ${paramNames.join(' \u00b7 ')}`);
242
+ output.push(` ${paramNames.join(', ')}`);
234
243
  }
235
244
 
236
245
  return output.join('\n') + '\n';
@@ -253,7 +262,7 @@ export async function formatHookBriefAll(coreDir) {
253
262
  const docPath = findHookDoc(coreDir, hookName);
254
263
  if (docPath) {
255
264
  try {
256
- const docs = await loadDocs(docPath);
265
+ const docs = await loadDocs(docPath, {root: 'hooks'});
257
266
  output.push(formatHookBrief(docs));
258
267
  } catch {
259
268
  output.push(`${hookName}\n (no docs)\n`);
@@ -29,11 +29,16 @@
29
29
  * 4. Routing unknown-subcommand attempts through the same error
30
30
  * envelope path (so `astryx bogus-cmd --json` gets exit 1 + envelope
31
31
  * instead of exit 0 + help envelope).
32
+ * 5. Emitting an error envelope, not the help envelope, when Commander
33
+ * shows help because the invocation failed (`help <unknown>`, or a
34
+ * command group with no subcommand), which exits 1.
32
35
  *
33
- * Non-JSON behavior is preserved exactly: every code path that printed
34
- * to stderr before still prints to stderr. Commander writes its
35
- * "error: ..." line via configureOutput.writeErr, which we pass
36
- * through verbatim outside of --json mode.
36
+ * Commander writes its own "error: ..." line via configureOutput.writeErr.
37
+ * The shim drops that line in both modes. Under --json the error envelope
38
+ * replaces it; in text mode `handleCommanderError` writes the Astryx line
39
+ * instead (`Error: <message>`, the same message the envelope carries), so
40
+ * a parse failure reads like every other CLI error. Other stderr output,
41
+ * such as help printed as the failure report, still passes through.
37
42
  */
38
43
 
39
44
  import {API_VERSION, isJsonMode, toErrorEnvelope} from '../../../foundation/response/json.mjs';
@@ -117,6 +122,35 @@ export function buildHelpEnvelope(cmd) {
117
122
  };
118
123
  }
119
124
 
125
+ /**
126
+ * The error envelope for help Commander shows because the invocation failed
127
+ * (it then exits 1): `help <name>` for an unknown name on the root, or a
128
+ * command group run without a subcommand.
129
+ *
130
+ * @param {import('commander').Command} cmd the command whose help was shown
131
+ * @returns {ReturnType<typeof toErrorEnvelope>}
132
+ */
133
+ export function buildHelpErrorEnvelope(cmd) {
134
+ const available = cmd.commands
135
+ .filter(s => !(/** @type {any} */ (s))._hidden && s.name() !== 'help')
136
+ .map(s => s.name());
137
+ if (!cmd.parent) {
138
+ // Commander dispatches `help <name>` with ['help', <name>, ...] in args.
139
+ const requested = cmd.args[1];
140
+ return toErrorEnvelope(
141
+ requested ? `unknown command '${requested}'` : 'unknown command',
142
+ available.map(name => ({name, reason: 'available command'})),
143
+ ERROR_CODES.ERR_UNKNOWN_COMMAND,
144
+ );
145
+ }
146
+ const group = fullNameOf(cmd);
147
+ return toErrorEnvelope(
148
+ `'${group}' needs a subcommand`,
149
+ available.map(name => ({name: `${group} ${name}`, reason: 'available subcommand'})),
150
+ ERROR_CODES.ERR_MISSING_ARGUMENT,
151
+ );
152
+ }
153
+
120
154
  /**
121
155
  * Emit a JSON error envelope to stdout (the JSON contract uses stdout
122
156
  * for both success and error).
@@ -217,11 +251,20 @@ function applyShimRecursively(cmd) {
217
251
  });
218
252
  cmd.configureOutput({
219
253
  writeOut: (str) => process.stdout.write(str),
254
+ // Commander's own "error: ..." line never reaches the user. Under --json a
255
+ // consumer parsing both streams must not see it alongside the envelope;
256
+ // in text mode it is Commander's format, not Astryx's, so an invalid
257
+ // global option (`--lang zh-Hans`) printed `error: option '--lang
258
+ // <locale>' argument 'zh-Hans' is invalid…` where every other CLI error
259
+ // prints `Error: …`. handleCommanderError writes the Astryx line below,
260
+ // for both modes, from the same message.
261
+ //
262
+ // ONLY that line. Commander also writes HELP through this channel when it
263
+ // shows help because the invocation failed (a command group with no
264
+ // subcommand), and that output is still wanted in text mode.
220
265
  writeErr: (str) => {
221
- // Suppress Commander's "error: ..." stderr line when --json is
222
- // active, so a JSON consumer parsing both streams doesn't see
223
- // it alongside the envelope. Non-JSON callers are unaffected.
224
266
  if (jsonActive()) return;
267
+ if (/^error:\s/i.test(str)) return;
225
268
  process.stderr.write(str);
226
269
  },
227
270
  });
@@ -310,7 +353,9 @@ function patchOutputHelp(cmd) {
310
353
  if (jsonActive()) {
311
354
  if (!process.__xdsJsonHandled) {
312
355
  process.__xdsJsonHandled = true;
313
- const env = buildHelpEnvelope(cmd);
356
+ const env = contextOptions?.error
357
+ ? buildHelpErrorEnvelope(cmd)
358
+ : buildHelpEnvelope(cmd);
314
359
  process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
315
360
  }
316
361
  return;
@@ -334,7 +379,9 @@ function patchPrototype(CommandCtor) {
334
379
  if (jsonActive()) {
335
380
  if (!process.__xdsJsonHandled) {
336
381
  process.__xdsJsonHandled = true;
337
- const env = buildHelpEnvelope(this);
382
+ const env = contextOptions?.error
383
+ ? buildHelpErrorEnvelope(this)
384
+ : buildHelpEnvelope(this);
338
385
  process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
339
386
  }
340
387
  return;
@@ -396,16 +443,15 @@ export function handleCommanderError(err) {
396
443
  code: commanderCodeToErrorCode(code, message),
397
444
  });
398
445
 
399
- // Real error paths.
446
+ // Real error paths. Strip Commander's "error: " prefix once: in the envelope
447
+ // the key is already `error`, and in text mode the Astryx prefix replaces it.
448
+ const cleaned = message.replace(/^error:\s*/i, '');
400
449
  if (jsonActive()) {
401
- // Strip Commander's "error: " prefix — the envelope key is `error`
402
- // already, doubled "error" is noise.
403
- const cleaned = message.replace(/^error:\s*/i, '');
404
450
  emitJsonError(cleaned, undefined, commanderCodeToErrorCode(code, cleaned));
405
451
  } else {
406
- // Non-JSON mode: Commander already wrote the "error: ..." line
407
- // to stderr via configureOutput.writeErr before throwing the
408
- // CommanderError. Nothing to do — exit with the original code.
452
+ // Commander's own line was suppressed above, so a parse failure reads the
453
+ // same as every other CLI error — the `Error: …` line cliError prints.
454
+ process.stderr.write(`Error: ${cleaned}\n`);
409
455
  }
410
456
  process.exit(exitCode || 1);
411
457
  }
@@ -20,7 +20,12 @@
20
20
  */
21
21
 
22
22
  import {describe, it, expect} from 'vitest';
23
+ import {spawnSync} from 'node:child_process';
24
+ import {fileURLToPath} from 'node:url';
25
+ import {Command} from 'commander';
23
26
  import {runCli} from '../../../test-utils/run-cli.mjs';
27
+ import {installJsonShim} from './json-shim.mjs';
28
+ import {setJsonMode} from '../../../foundation/response/json.mjs';
24
29
 
25
30
  function parseJson(stdout) {
26
31
  return JSON.parse(stdout);
@@ -207,3 +212,81 @@ describe('--json shim: stdout discipline under --json', () => {
207
212
  }
208
213
  });
209
214
  });
215
+
216
+ describe('--json shim: help shown for a failed invocation is an error envelope', () => {
217
+ it('astryx help bogus --json emits ERR_UNKNOWN_COMMAND, exit 1', async () => {
218
+ const {status, stdout, stderr} = await runCli(['help', 'bogus', '--json']);
219
+ expect(status).toBe(1);
220
+ expect(stderr).toBe('');
221
+ const parsed = parseJson(stdout);
222
+ expect(parsed).not.toHaveProperty('type');
223
+ expect(parsed.apiVersion).toBe(1);
224
+ expect(parsed.code).toBe('ERR_UNKNOWN_COMMAND');
225
+ expect(parsed.error).toMatch(/bogus/);
226
+ });
227
+
228
+ it('astryx layout --json (group, no subcommand) emits ERR_MISSING_ARGUMENT, exit 1', async () => {
229
+ const {status, stdout, stderr} = await runCli(['layout', '--json']);
230
+ expect(status).toBe(1);
231
+ expect(stderr).toBe('');
232
+ const parsed = parseJson(stdout);
233
+ expect(parsed).not.toHaveProperty('type');
234
+ expect(parsed.code).toBe('ERR_MISSING_ARGUMENT');
235
+ expect(parsed.suggestions.map((s) => s.name)).toContain('layout expand');
236
+ });
237
+
238
+ it('astryx layout (no --json) still prints help to stderr, exit 1', async () => {
239
+ const {status, stdout, stderr} = await runCli(['layout']);
240
+ expect(status).toBe(1);
241
+ expect(stdout).toBe('');
242
+ expect(stderr).toMatch(/Usage: astryx layout/);
243
+ });
244
+
245
+ it('the real binary emits the same envelope for help bogus --json', () => {
246
+ // One program per process, so the root's own outputHelp patch is used here.
247
+ const bin = fileURLToPath(new URL('../bin/astryx.mjs', import.meta.url));
248
+ const res = spawnSync(process.execPath, [bin, 'help', 'bogus', '--json'], {
249
+ encoding: 'utf-8',
250
+ timeout: 20_000,
251
+ });
252
+ expect(res.status).toBe(1);
253
+ expect(res.stderr).toBe('');
254
+ const parsed = parseJson(res.stdout);
255
+ expect(parsed).not.toHaveProperty('type');
256
+ expect(parsed.code).toBe('ERR_UNKNOWN_COMMAND');
257
+ });
258
+
259
+ it('a group added after install gets the same error envelope', () => {
260
+ const program = new Command('astryx');
261
+ installJsonShim(program);
262
+ // Added later, so only the prototype-level patch covers its outputHelp.
263
+ const late = new Command('late');
264
+ late.command('child');
265
+ program.addCommand(late);
266
+ /** @type {string[]} */
267
+ const writes = [];
268
+ const origWrite = process.stdout.write;
269
+ // @ts-expect-error - test-only capture
270
+ process.stdout.write = (chunk) => writes.push(String(chunk)) > 0;
271
+ setJsonMode(true);
272
+ delete process.__xdsJsonHandled;
273
+ try {
274
+ late.outputHelp({error: true});
275
+ } finally {
276
+ process.stdout.write = origWrite;
277
+ setJsonMode(false);
278
+ delete process.__xdsJsonHandled;
279
+ }
280
+ const parsed = parseJson(writes.join(''));
281
+ expect(parsed.code).toBe('ERR_MISSING_ARGUMENT');
282
+ expect(parsed.suggestions).toEqual([{name: 'late child', reason: 'available subcommand'}]);
283
+ });
284
+
285
+ it('astryx help layout --json still emits the help envelope, exit 0', async () => {
286
+ const {status, stdout} = await runCli(['help', 'layout', '--json']);
287
+ expect(status).toBe(0);
288
+ const parsed = parseJson(stdout);
289
+ expect(parsed.type).toBe('help');
290
+ expect(parsed.data.command).toBe('astryx layout');
291
+ });
292
+ });
@@ -48,6 +48,8 @@ export interface ManifestCommand {
48
48
  responseTypes?: string[];
49
49
  /** Example invocations. */
50
50
  examples?: string[];
51
+ /** Documented exit codes: the process exit status and when it occurs. */
52
+ exitCodes?: {code: number; when: string}[];
51
53
  /** Nested subcommands (e.g. `theme build` under `theme`). */
52
54
  subcommands?: ManifestCommand[];
53
55
  }