@astryxdesign/cli 0.6.3-canary.98a2e4e → 0.6.3-canary.9c4d44d

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 (612) hide show
  1. package/README.md +117 -79
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/_adapter.d.mts +50 -0
  4. package/api/build/_adapter.mjs +60 -0
  5. package/api/build/build.doc.mjs +16 -9
  6. package/api/build/build.test.mjs +197 -8
  7. package/api/build/build.type.d.mts +91 -2
  8. package/api/build/build.type.mjs +52 -8
  9. package/api/build/help/help.d.mts +12 -5
  10. package/api/build/help/help.mjs +69 -6
  11. package/api/build/kit/kit.d.mts +4 -1
  12. package/api/build/kit/kit.mjs +165 -49
  13. package/api/build/kit/rank.d.mts +44 -0
  14. package/api/build/kit/rank.mjs +432 -0
  15. package/api/build/kit/rank.test.mjs +196 -0
  16. package/api/component/_adapter.d.mts +6 -12
  17. package/api/component/_adapter.mjs +20 -10
  18. package/api/component/component.doc.mjs +13 -3
  19. package/api/component/component.mjs +91 -14
  20. package/api/component/component.test.mjs +38 -0
  21. package/api/component/component.type.d.mts +22 -11
  22. package/api/component/component.type.mjs +32 -24
  23. package/api/component/detail/blocks/blocks.d.mts +2 -1
  24. package/api/component/detail/blocks/blocks.mjs +4 -3
  25. package/api/component/list/list.d.mts +0 -5
  26. package/api/component/list/list.mjs +40 -11
  27. package/api/discover/_adapter.d.mts +114 -6
  28. package/api/discover/_adapter.mjs +372 -17
  29. package/api/discover/_adapter.test.mjs +215 -0
  30. package/api/discover/_catalog-view.d.mts +115 -0
  31. package/api/discover/_catalog-view.mjs +203 -0
  32. package/api/discover/_catalog-view.test.mjs +128 -0
  33. package/api/discover/detail/detail.d.mts +18 -6
  34. package/api/discover/detail/detail.mjs +67 -13
  35. package/api/discover/detail/detail.test.mjs +85 -0
  36. package/api/discover/detail/item/item.d.mts +26 -0
  37. package/api/discover/detail/item/item.mjs +78 -0
  38. package/api/discover/detail/item/item.test.mjs +73 -0
  39. package/api/discover/discover.d.mts +3 -9
  40. package/api/discover/discover.doc.mjs +62 -18
  41. package/api/discover/discover.mjs +220 -36
  42. package/api/discover/discover.test.mjs +11 -2
  43. package/api/discover/discover.type.d.mts +150 -11
  44. package/api/discover/discover.type.mjs +107 -17
  45. package/api/discover/list/list.d.mts +20 -6
  46. package/api/discover/list/list.mjs +45 -12
  47. package/api/discover/list/list.test.mjs +46 -0
  48. package/api/discover/search/search.d.mts +18 -16
  49. package/api/discover/search/search.mjs +102 -56
  50. package/api/discover/search/search.test.mjs +144 -10
  51. package/api/docs/_adapter.d.mts +268 -47
  52. package/api/docs/_adapter.mjs +970 -149
  53. package/api/docs/compiled-topics.test.mjs +78 -0
  54. package/api/docs/detail/detail.d.mts +0 -15
  55. package/api/docs/detail/detail.mjs +22 -78
  56. package/api/docs/detail/section/section.mjs +39 -24
  57. package/api/docs/detail/section/section.test.mjs +19 -9
  58. package/api/docs/docs.d.mts +5 -3
  59. package/api/docs/docs.doc.mjs +39 -17
  60. package/api/docs/docs.mjs +44 -8
  61. package/api/docs/docs.test.mjs +158 -4
  62. package/api/docs/docs.type.d.mts +185 -6
  63. package/api/docs/docs.type.mjs +127 -13
  64. package/api/docs/index/index.mjs +15 -6
  65. package/api/docs/index/index.test.mjs +1 -1
  66. package/api/docs/integration-tree.test.mjs +555 -0
  67. package/api/docs/integrationDocs.test.mjs +14 -14
  68. package/api/docs/list/list.mjs +28 -12
  69. package/api/docs/node/node.d.mts +43 -0
  70. package/api/docs/node/node.mjs +192 -0
  71. package/api/docs/reference-blocks.test.mjs +406 -0
  72. package/api/doctor/doctor.d.mts +54 -4
  73. package/api/doctor/doctor.doc.mjs +1 -0
  74. package/api/doctor/doctor.mjs +332 -21
  75. package/api/doctor/doctor.test.mjs +420 -7
  76. package/api/gap-report/gap-report.doc.mjs +8 -4
  77. package/api/hook/_adapter.mjs +19 -5
  78. package/api/hook/hook.doc.mjs +1 -0
  79. package/api/hook/hook.type.d.mts +3 -3
  80. package/api/hook/hook.type.mjs +11 -11
  81. package/api/hook/list/list.d.mts +1 -1
  82. package/api/hook/list/list.mjs +69 -17
  83. package/api/index.d.mts +1 -1
  84. package/api/index.mjs +1 -0
  85. package/api/init/init.doc.mjs +6 -1
  86. package/api/init/init.test.mjs +41 -1
  87. package/api/init/remove/remove.mjs +1 -1
  88. package/api/init/run/run.mjs +20 -10
  89. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  90. package/api/integration/add-contribution.d.mts +2 -1
  91. package/api/integration/add-contribution.mjs +130 -15
  92. package/api/integration/add-contribution.test.mjs +258 -7
  93. package/api/integration/add-helpers.d.mts +5 -2
  94. package/api/integration/add-helpers.mjs +36 -9
  95. package/api/integration/add-theme.mjs +34 -64
  96. package/api/integration/add-theme.test.mjs +105 -21
  97. package/api/integration/authoring-checks.mjs +138 -28
  98. package/api/integration/authoring-checks.test.mjs +179 -7
  99. package/api/integration/authoring-checks.type.mjs +6 -1
  100. package/api/integration/integration-authoring.type.d.mts +2 -0
  101. package/api/integration/integration-authoring.type.mjs +2 -0
  102. package/api/integration/integration-block-exports.test.mjs +10 -6
  103. package/api/integration/integrationAdd.doc.mjs +14 -4
  104. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  105. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  106. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  107. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  108. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  109. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  110. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  111. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  112. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  113. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  114. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  115. package/api/integration/pack-check.mjs +83 -7
  116. package/api/integration/pack-check.test.mjs +387 -47
  117. package/api/integration/pack-check.type.d.mts +26 -2
  118. package/api/integration/pack-check.type.mjs +14 -1
  119. package/api/integration/summarizeIssues.doc.mjs +1 -0
  120. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  121. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  122. package/api/integration/validate-integration.mjs +52 -102
  123. package/api/integration/validate-integration.test.mjs +179 -26
  124. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  125. package/api/integration/validateIntegration.doc.mjs +3 -2
  126. package/api/json/assertResponse.doc.mjs +1 -0
  127. package/api/json/envelope-types.test.mjs +76 -0
  128. package/api/json/index.ts +2 -0
  129. package/api/json/isError.doc.mjs +1 -0
  130. package/api/json/parseResponse.doc.mjs +3 -2
  131. package/api/layout/_adapter.mjs +20 -5
  132. package/api/layout/expand/expand.mjs +7 -5
  133. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  134. package/api/layout/grammar/grammar.mjs +2 -1
  135. package/api/layout/layoutCheck.doc.mjs +1 -0
  136. package/api/layout/layoutExpand.doc.mjs +2 -1
  137. package/api/layout/layoutGrammar.doc.mjs +1 -0
  138. package/api/search/search-return-type.test.mjs +54 -0
  139. package/api/search/search.d.mts +61 -10
  140. package/api/search/search.doc.mjs +8 -2
  141. package/api/search/search.mjs +471 -83
  142. package/api/search/search.test.mjs +124 -1
  143. package/api/search/search.type.d.mts +14 -2
  144. package/api/search/search.type.mjs +5 -2
  145. package/api/swizzle/copy/copy.mjs +28 -11
  146. package/api/swizzle/swizzle.doc.mjs +2 -1
  147. package/api/swizzle/swizzle.type.d.mts +2 -2
  148. package/api/swizzle/swizzle.type.mjs +2 -2
  149. package/api/template/copy/copy.mjs +17 -23
  150. package/api/template/copy/copy.test.mjs +17 -0
  151. package/api/template/list/list.mjs +1 -0
  152. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  153. package/api/template/template-integration.test.mjs +1072 -3
  154. package/api/template/template-suffix.test.mjs +41 -21
  155. package/api/template/template.doc.mjs +30 -8
  156. package/api/template/template.mjs +45 -8
  157. package/api/template/template.type.d.mts +11 -13
  158. package/api/template/template.type.mjs +15 -14
  159. package/api/theme/_adapter.d.mts +2 -3
  160. package/api/theme/_adapter.mjs +4 -5
  161. package/api/theme/add/add.binary.test.mjs +84 -0
  162. package/api/theme/add/add.mjs +31 -22
  163. package/api/theme/add/add.rollback.test.mjs +158 -0
  164. package/api/theme/add/add.staging.test.mjs +83 -0
  165. package/api/theme/add/add.test.mjs +14 -1
  166. package/api/theme/build/build.family.test.mjs +7 -12
  167. package/api/theme/build/build.mjs +140 -59
  168. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  169. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  170. package/api/theme/build/build.rollback.test.mjs +148 -0
  171. package/api/theme/build/build.test.mjs +127 -0
  172. package/api/theme/build/font-warning.mjs +3 -3
  173. package/api/theme/build/font-warning.test.mjs +5 -2
  174. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  175. package/api/theme/integration-themes.test.mjs +39 -28
  176. package/api/theme/list/list.test.mjs +19 -20
  177. package/api/theme/listThemes.doc.mjs +6 -5
  178. package/api/theme/palette/generate/generate.mjs +8 -3
  179. package/api/theme/palette/generate/generate.test.mjs +96 -0
  180. package/api/theme/palette/generate/generator.d.mts +10 -13
  181. package/api/theme/palette/generate/generator.mjs +15 -4
  182. package/api/theme/palette/generate/generator.test.mjs +10 -0
  183. package/api/theme/template/template.mjs +11 -2
  184. package/api/theme/template/template.test.mjs +20 -0
  185. package/api/theme/theme.type.d.mts +170 -11
  186. package/api/theme/theme.type.mjs +94 -27
  187. package/api/theme/themeAdd.doc.mjs +4 -3
  188. package/api/theme/themeBuild.doc.mjs +8 -4
  189. package/api/theme/themeList.doc.mjs +6 -3
  190. package/api/theme/themeListAvailable.doc.mjs +5 -3
  191. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  192. package/api/theme/themeTargets.doc.mjs +1 -0
  193. package/api/theme/themeTemplate.doc.mjs +6 -2
  194. package/api/upgrade/_adapter.d.mts +32 -5
  195. package/api/upgrade/_adapter.mjs +124 -73
  196. package/api/upgrade/list/list.mjs +2 -1
  197. package/api/upgrade/list/list.test.mjs +73 -0
  198. package/api/upgrade/provider-agreement.test.mjs +152 -0
  199. package/api/upgrade/run/run.mjs +356 -59
  200. package/api/upgrade/status/status.mjs +2 -2
  201. package/api/upgrade/upgrade.doc.mjs +8 -2
  202. package/api/upgrade/upgrade.type.d.mts +42 -4
  203. package/api/upgrade/upgrade.type.mjs +26 -10
  204. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  205. package/assets/codemods/integration-discovery.mjs +48 -4
  206. package/assets/codemods/integration-discovery.test.mjs +73 -0
  207. package/assets/codemods/integration-runner.mjs +56 -4
  208. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  209. package/assets/codemods/run-codemod.mjs +177 -34
  210. package/assets/codemods/runner.mjs +350 -102
  211. package/assets/codemods/term-log.mjs +32 -8
  212. package/assets/codemods/term-log.test.mjs +19 -1
  213. package/assets/codemods/transform-prop.mjs +109 -0
  214. package/assets/codemods/transform-prop.test.mjs +95 -0
  215. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  216. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  217. package/assets/codemods/transforms/next/index.mjs +19 -1
  218. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  219. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  220. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  221. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  222. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  223. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  224. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  225. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  226. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  227. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  228. package/assets/docs/getting-started.doc.mjs +2 -2
  229. package/assets/docs/internationalization.doc.mjs +7 -5
  230. package/assets/docs/layout.doc.dense.mjs +2 -2
  231. package/assets/docs/layout.doc.mjs +1 -1
  232. package/assets/docs/principles.doc.mjs +6 -6
  233. package/assets/docs/styling-libraries.doc.mjs +4 -4
  234. package/assets/docs/styling.doc.mjs +4 -4
  235. package/assets/docs/theme.doc.mjs +5 -5
  236. package/assets/docs/tokens.doc.mjs +1 -1
  237. package/assets/docs/tree/api.doc.mjs +30 -0
  238. package/assets/docs/tree/cli.doc.mjs +23 -0
  239. package/assets/docs/tree/commands.doc.mjs +25 -0
  240. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +95 -39
  241. package/assets/docs/tree/integrations.test.mjs +62 -0
  242. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  243. package/assets/docs/working-with-ai.doc.mjs +4 -4
  244. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  245. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  246. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  247. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  248. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  249. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  250. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  251. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  252. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  253. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  254. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  255. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  256. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  257. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  258. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  259. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  260. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  261. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  262. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  263. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  264. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  265. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  266. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  267. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  268. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  269. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  270. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  271. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  272. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  273. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  274. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  275. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  276. package/authoring/_shared/contract.ts +22 -0
  277. package/authoring/codemod/codemod.doc.mjs +7 -2
  278. package/authoring/codemod/parse.d.mts +8 -8
  279. package/authoring/codemod/parse.mjs +8 -6
  280. package/authoring/codemod/type.ts +12 -0
  281. package/authoring/config/config.doc.mjs +10 -2
  282. package/authoring/config/debug-composition.test.mjs +92 -0
  283. package/authoring/config/parse.d.mts +15 -13
  284. package/authoring/config/parse.mjs +27 -8
  285. package/authoring/config/parse.test.mjs +8 -0
  286. package/authoring/config/type.ts +29 -6
  287. package/authoring/debug/debug.doc.d.mts +11 -0
  288. package/authoring/debug/debug.doc.mjs +182 -0
  289. package/authoring/debug/parse.d.mts +7 -7
  290. package/authoring/debug/parse.mjs +3 -3
  291. package/authoring/discover/discover.doc.d.mts +13 -0
  292. package/authoring/discover/discover.doc.mjs +138 -0
  293. package/authoring/discover/parse.d.mts +24 -0
  294. package/authoring/discover/parse.mjs +128 -0
  295. package/authoring/discover/parse.test.mjs +124 -0
  296. package/authoring/discover/type.ts +87 -0
  297. package/authoring/doctypes/_schema.d.mts +240 -128
  298. package/authoring/doctypes/_schema.mjs +198 -16
  299. package/authoring/doctypes/base/graph-fields.doc.mjs +15 -6
  300. package/authoring/doctypes/base/type.ts +9 -4
  301. package/authoring/doctypes/command/command.doc.mjs +4 -3
  302. package/authoring/doctypes/command/parse.d.mts +2 -2
  303. package/authoring/doctypes/command/parse.mjs +1 -1
  304. package/authoring/doctypes/command/type.ts +4 -4
  305. package/authoring/doctypes/component/component.doc.mjs +5 -2
  306. package/authoring/doctypes/component/parse.d.mts +2 -2
  307. package/authoring/doctypes/component/parse.mjs +1 -1
  308. package/authoring/doctypes/component/type.ts +3 -3
  309. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  310. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  311. package/authoring/doctypes/enum/parse.d.mts +2 -2
  312. package/authoring/doctypes/enum/parse.mjs +1 -1
  313. package/authoring/doctypes/enum/type.ts +2 -2
  314. package/authoring/doctypes/function/function.doc.mjs +7 -2
  315. package/authoring/doctypes/function/parse.d.mts +2 -2
  316. package/authoring/doctypes/function/parse.mjs +1 -1
  317. package/authoring/doctypes/function/type.ts +4 -3
  318. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  319. package/authoring/doctypes/hook/parse.d.mts +2 -2
  320. package/authoring/doctypes/hook/parse.mjs +1 -1
  321. package/authoring/doctypes/hook/type.ts +3 -3
  322. package/authoring/doctypes/legacy.d.mts +6 -6
  323. package/authoring/doctypes/legacy.mjs +3 -3
  324. package/authoring/doctypes/load-contract.test.mjs +233 -0
  325. package/authoring/doctypes/namespace/namespace.doc.mjs +9 -9
  326. package/authoring/doctypes/namespace/parse.d.mts +2 -2
  327. package/authoring/doctypes/namespace/parse.mjs +1 -1
  328. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  329. package/authoring/doctypes/namespace/type.ts +6 -3
  330. package/authoring/doctypes/parse.d.mts +22 -20
  331. package/authoring/doctypes/parse.mjs +19 -14
  332. package/authoring/doctypes/reference/parse.d.mts +2 -2
  333. package/authoring/doctypes/reference/parse.mjs +1 -1
  334. package/authoring/doctypes/reference/reference.doc.mjs +39 -6
  335. package/authoring/doctypes/reference/type.ts +31 -14
  336. package/authoring/doctypes/schema/parse.d.mts +2 -2
  337. package/authoring/doctypes/schema/parse.mjs +1 -1
  338. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  339. package/authoring/doctypes/schema/type.ts +3 -4
  340. package/authoring/doctypes/template/parse.d.mts +94 -1
  341. package/authoring/doctypes/template/parse.mjs +37 -1
  342. package/authoring/doctypes/template/parse.test.mjs +18 -0
  343. package/authoring/doctypes/template/template.doc.mjs +13 -3
  344. package/authoring/doctypes/template/type.ts +12 -1
  345. package/authoring/doctypes/theme/parse.d.mts +35 -0
  346. package/authoring/doctypes/theme/parse.mjs +76 -0
  347. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  348. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  349. package/authoring/doctypes/theme/type.ts +42 -0
  350. package/authoring/doctypes/types.ts +12 -11
  351. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  352. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  353. package/authoring/gap-report/parse.d.mts +9 -9
  354. package/authoring/gap-report/parse.mjs +6 -6
  355. package/authoring/gap-report/type.ts +1 -1
  356. package/authoring/identity/identity.doc.mjs +3 -2
  357. package/authoring/identity/type.ts +10 -10
  358. package/authoring/index.d.mts +2 -0
  359. package/authoring/index.d.ts +32 -19
  360. package/authoring/index.mjs +3 -1
  361. package/authoring/integration/integration.doc.mjs +2 -2
  362. package/authoring/integration/parse.d.mts +2 -2
  363. package/authoring/integration/parse.mjs +1 -1
  364. package/authoring/integration/schema.d.mts +4 -4
  365. package/authoring/integration/schema.mjs +3 -3
  366. package/authoring/integration/type.ts +5 -11
  367. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  368. package/clients/cli/command-load-failure.test.mjs +83 -0
  369. package/clients/cli/commands/blog.doc.mjs +1 -1
  370. package/clients/cli/commands/blog.mjs +23 -8
  371. package/clients/cli/commands/blog.test.mjs +42 -1
  372. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  373. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  374. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  375. package/clients/cli/commands/build-theme.mjs +16 -50
  376. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  377. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  378. package/clients/cli/commands/build.doc.mjs +16 -8
  379. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  380. package/clients/cli/commands/build.mjs +137 -114
  381. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  382. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  383. package/clients/cli/commands/component/index.mjs +3 -8
  384. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  385. package/clients/cli/commands/component-package.test.mjs +46 -0
  386. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  387. package/clients/cli/commands/component.doc.mjs +1 -1
  388. package/clients/cli/commands/component.test.mjs +19 -0
  389. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  390. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  391. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  392. package/clients/cli/commands/discover.doc.mjs +55 -9
  393. package/clients/cli/commands/discover.mjs +393 -118
  394. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  395. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  396. package/clients/cli/commands/docs.doc.mjs +21 -9
  397. package/clients/cli/commands/docs.mjs +184 -70
  398. package/clients/cli/commands/docs.test.mjs +120 -16
  399. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  400. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  401. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  402. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  403. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  404. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  405. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  406. package/clients/cli/commands/doctor.doc.mjs +1 -1
  407. package/clients/cli/commands/doctor.mjs +59 -32
  408. package/clients/cli/commands/doctor.test.mjs +42 -0
  409. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  410. package/clients/cli/commands/gap-report.test.mjs +72 -0
  411. package/clients/cli/commands/hook/index.mjs +7 -17
  412. package/clients/cli/commands/hook.doc.mjs +1 -1
  413. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  414. package/clients/cli/commands/init.doc.mjs +20 -9
  415. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  416. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  417. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  418. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  419. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  420. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  421. package/clients/cli/commands/integration.doc.mjs +1 -1
  422. package/clients/cli/commands/integration.mjs +1 -0
  423. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  424. package/clients/cli/commands/json-contract.test.mjs +33 -0
  425. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  426. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  427. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  428. package/clients/cli/commands/layout.doc.mjs +3 -3
  429. package/clients/cli/commands/layout.mjs +21 -9
  430. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  431. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  432. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  433. package/clients/cli/commands/manifest.doc.mjs +1 -1
  434. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  435. package/clients/cli/commands/search.doc.mjs +7 -4
  436. package/clients/cli/commands/search.mjs +28 -9
  437. package/clients/cli/commands/search.test.mjs +75 -0
  438. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  439. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  440. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  441. package/clients/cli/commands/template.doc.mjs +52 -13
  442. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  443. package/clients/cli/commands/template.mjs +4 -91
  444. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  445. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  446. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  447. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  448. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  449. package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
  450. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  451. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  452. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  453. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  454. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  455. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  456. package/clients/cli/commands/theme.doc.mjs +1 -1
  457. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  458. package/clients/cli/commands/upgrade.doc.mjs +20 -8
  459. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  460. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  461. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  462. package/clients/cli/commands/upgrade.mjs +29 -7
  463. package/clients/cli/formatters/index.mjs +2 -0
  464. package/clients/cli/formatters/index.test.mjs +6 -0
  465. package/clients/cli/index.mjs +21 -30
  466. package/clients/cli/latest-version-env.test.mjs +50 -0
  467. package/clients/cli/lib/cli-error.test.mjs +7 -0
  468. package/clients/cli/lib/component-format.mjs +9 -9
  469. package/clients/cli/lib/component-format.test.mjs +1 -1
  470. package/clients/cli/lib/define-command.mjs +32 -6
  471. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  472. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  473. package/clients/cli/lib/hook-format.mjs +19 -10
  474. package/clients/cli/lib/json-shim.mjs +38 -2
  475. package/clients/cli/lib/json-shim.test.mjs +83 -0
  476. package/clients/cli/lib/manifest.d.ts +2 -0
  477. package/clients/cli/lib/manifest.mjs +32 -2
  478. package/clients/cli/lib/manifest.test.mjs +17 -0
  479. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  480. package/foundation/agent-docs/agent-docs.mjs +82 -12
  481. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  482. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  483. package/foundation/config/integration-debug.test.mjs +28 -3
  484. package/foundation/config/project-themes.test.mjs +11 -19
  485. package/foundation/config/project.d.mts +20 -11
  486. package/foundation/config/project.mjs +246 -89
  487. package/foundation/config/project.test.mjs +270 -21
  488. package/foundation/discovery/authoring-self-docs.d.mts +18 -0
  489. package/foundation/discovery/authoring-self-docs.mjs +38 -15
  490. package/foundation/discovery/authoring-self-docs.test.mjs +87 -12
  491. package/foundation/discovery/authoring-surface.d.mts +74 -0
  492. package/foundation/discovery/authoring-surface.mjs +525 -0
  493. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  494. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  495. package/foundation/discovery/cli-self-docs.mjs +490 -0
  496. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  497. package/foundation/discovery/component-discovery.d.mts +38 -0
  498. package/foundation/discovery/component-discovery.mjs +48 -0
  499. package/foundation/discovery/component-loader.d.mts +35 -38
  500. package/foundation/discovery/component-loader.mjs +53 -222
  501. package/foundation/discovery/docs-discovery.d.mts +114 -9
  502. package/foundation/discovery/docs-discovery.mjs +239 -30
  503. package/foundation/discovery/docs-discovery.test.mjs +150 -35
  504. package/foundation/discovery/docs-output-budget.d.mts +2 -2
  505. package/foundation/discovery/docs-output-budget.mjs +1 -1
  506. package/foundation/discovery/docs-section-key.d.mts +28 -10
  507. package/foundation/discovery/docs-section-key.mjs +134 -33
  508. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  509. package/foundation/discovery/template-adapter.d.mts +113 -11
  510. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  511. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  512. package/foundation/discovery/template-adapter.mjs +772 -82
  513. package/foundation/discovery/template-adapter.test.mjs +57 -0
  514. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  515. package/foundation/discovery/template-conflict-release.mjs +40 -0
  516. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  517. package/foundation/discovery/theme-discovery.d.mts +67 -7
  518. package/foundation/discovery/theme-discovery.mjs +916 -186
  519. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  520. package/foundation/discovery/theming-targets.test.mjs +4 -0
  521. package/foundation/doc-compiler/bundle.d.mts +47 -0
  522. package/foundation/doc-compiler/bundle.mjs +278 -0
  523. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  524. package/foundation/doc-compiler/compile.d.mts +343 -0
  525. package/foundation/doc-compiler/compile.mjs +558 -0
  526. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  527. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  528. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  529. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  530. package/foundation/doc-compiler/import.d.mts +24 -0
  531. package/foundation/doc-compiler/import.mjs +59 -0
  532. package/foundation/doc-compiler/inputs.d.mts +102 -0
  533. package/foundation/doc-compiler/inputs.mjs +291 -0
  534. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  535. package/foundation/doc-compiler/ir.d.mts +22 -0
  536. package/foundation/doc-compiler/ir.mjs +471 -0
  537. package/foundation/doc-compiler/lenses.d.mts +36 -0
  538. package/foundation/doc-compiler/lenses.mjs +173 -0
  539. package/foundation/doc-compiler/links.d.mts +162 -0
  540. package/foundation/doc-compiler/links.mjs +294 -0
  541. package/foundation/doc-compiler/links.test.mjs +192 -0
  542. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  543. package/foundation/doc-compiler/overlays.d.mts +37 -0
  544. package/foundation/doc-compiler/overlays.mjs +206 -0
  545. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  546. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  547. package/foundation/doc-compiler/read.d.mts +127 -0
  548. package/foundation/doc-compiler/read.mjs +325 -0
  549. package/foundation/doc-compiler/read.test.mjs +313 -0
  550. package/foundation/doc-compiler/source.d.mts +33 -0
  551. package/foundation/doc-compiler/source.mjs +128 -0
  552. package/foundation/doc-compiler/tree.d.mts +288 -0
  553. package/foundation/doc-compiler/tree.mjs +876 -0
  554. package/foundation/doc-compiler/tree.test.mjs +598 -0
  555. package/foundation/fs/file-protection.d.mts +33 -0
  556. package/foundation/fs/file-protection.mjs +825 -0
  557. package/foundation/fs/file-protection.test.mjs +250 -0
  558. package/foundation/fs/module-loader.d.mts +1 -0
  559. package/foundation/fs/module-loader.mjs +50 -1
  560. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  561. package/foundation/fs/path-safety.d.mts +3 -2
  562. package/foundation/fs/path-safety.mjs +49 -19
  563. package/foundation/fs/path-safety.test.mjs +50 -0
  564. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  565. package/foundation/integrations/autolink.d.mts +58 -1
  566. package/foundation/integrations/autolink.mjs +143 -52
  567. package/foundation/integrations/autolink.test.mjs +1 -1
  568. package/foundation/integrations/cli-requirement.d.mts +45 -0
  569. package/foundation/integrations/cli-requirement.mjs +154 -0
  570. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  571. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  572. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  573. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  574. package/foundation/integrations/contribution-inventory.mjs +27 -24
  575. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  576. package/foundation/integrations/integration-warnings.d.mts +9 -2
  577. package/foundation/integrations/integration-warnings.mjs +51 -26
  578. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  579. package/foundation/integrations/integrations.d.mts +17 -1
  580. package/foundation/integrations/integrations.mjs +52 -98
  581. package/foundation/integrations/integrations.test.mjs +31 -0
  582. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  583. package/foundation/integrations/provider-resolution.d.mts +152 -0
  584. package/foundation/integrations/provider-resolution.mjs +576 -0
  585. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  586. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  587. package/foundation/integrations/theme-descriptor.mjs +44 -0
  588. package/foundation/integrations/validate-contributions.mjs +121 -29
  589. package/foundation/response/base.d.ts +8 -4
  590. package/foundation/response/error-codes.d.mts +3 -1
  591. package/foundation/response/error-codes.d.ts +2 -0
  592. package/foundation/response/error-codes.doc.mjs +13 -4
  593. package/foundation/response/error-codes.mjs +8 -2
  594. package/foundation/response/error-codes.test.mjs +137 -10
  595. package/foundation/response/json-contract.test.mjs +11 -0
  596. package/foundation/response/json.d.mts +4 -2
  597. package/foundation/response/json.mjs +8 -10
  598. package/foundation/response/response-types.doc.d.mts +5 -1
  599. package/foundation/response/response-types.doc.mjs +37 -22
  600. package/foundation/response/response-types.doc.test.mjs +158 -0
  601. package/foundation/response/response.doc.mjs +1 -1
  602. package/foundation/text/string-utils.d.mts +8 -0
  603. package/foundation/text/string-utils.mjs +40 -10
  604. package/foundation/xle/expand.d.mts +2 -0
  605. package/foundation/xle/expand.mjs +4 -3
  606. package/foundation/xle/expand.test.mjs +54 -0
  607. package/foundation/xle/xle.test.mjs +13 -0
  608. package/package.json +10 -11
  609. package/assets/templates/themes/manifest.json +0 -95
  610. package/clients/cli/lib/update-check.mjs +0 -83
  611. package/clients/cli/lib/update-check.test.mjs +0 -137
  612. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -25,6 +25,7 @@
25
25
  */
26
26
 
27
27
  import {recordCommandResult} from '../../../foundation/debug/index.mjs';
28
+ import {text} from '../formatters/index.mjs';
28
29
 
29
30
  /**
30
31
  * Marks a Commander command that reports what it answered with, and says HOW:
@@ -78,6 +79,21 @@ export function markReportsResult(cmd) {
78
79
  return cmd;
79
80
  }
80
81
 
82
+ /** The CommandDoc and wrapped FunctionDoc a command was built from. */
83
+ export const COMMAND_DOCS = Symbol.for('astryx.command.docs');
84
+
85
+ /**
86
+ * The docs a command was built from; undefined for a hand-registered command.
87
+ * @param {import('commander').Command} cmd
88
+ * @returns {{
89
+ * doc: import('@astryxdesign/cli/authoring').CommandDoc,
90
+ * fn?: import('@astryxdesign/cli/authoring').FunctionDoc,
91
+ * } | undefined}
92
+ */
93
+ export function commandDocsOf(cmd) {
94
+ return /** @type {any} */ (cmd)?.[COMMAND_DOCS];
95
+ }
96
+
81
97
  /**
82
98
  * Build a Commander command from a CommandDoc and attach it to `parent`.
83
99
  *
@@ -102,6 +118,7 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
102
118
  .join(' ');
103
119
 
104
120
  const cmd = parent.command(argSpec ? `${token} ${argSpec}` : token);
121
+ Object.defineProperty(cmd, COMMAND_DOCS, {value: {doc, fn}, configurable: true});
105
122
  if (doc.summary) cmd.description(doc.summary);
106
123
 
107
124
  const paramDesc = (/** @type {string | undefined} */ name) =>
@@ -126,12 +143,10 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
126
143
  cmd.addOption(option);
127
144
  }
128
145
 
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.
146
+ // Help ends with the documented exit codes. `choices` stay in the option
147
+ // text: Commander `.choices()` would replace the api layer's
148
+ // ERR_INVALID_ARGUMENT validation.
149
+ addExitCodesHelp(cmd, doc.exitCodes);
135
150
 
136
151
  if (action) {
137
152
  // The recording seam. An action's job ends at "here is what I answered
@@ -149,3 +164,14 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
149
164
  }
150
165
  return cmd;
151
166
  }
167
+
168
+ /**
169
+ * End `cmd`'s help with a CommandDoc's exit codes.
170
+ * @param {import('commander').Command} cmd
171
+ * @param {import('@astryxdesign/cli/authoring').CommandDoc['exitCodes']} exitCodes
172
+ */
173
+ export function addExitCodesHelp(cmd, exitCodes) {
174
+ if (!exitCodes?.length) return;
175
+ const lines = exitCodes.map(({code, when}) => ` ${code} ${when}`);
176
+ cmd.addHelpText('after', `\n${text(['Exit codes:', ...lines].join('\n')).toString()}`);
177
+ }
@@ -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,97 @@
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',
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
+ },
55
+ );
56
+
57
+ it('bare `astryx layout` exits 1 in both modes, as documented', async () => {
58
+ const doc = commandDocs.find((d) => d.name === 'layout');
59
+ expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/^no subcommand/);
60
+ expect((await runCli(['layout'])).status).toBe(1);
61
+ expect((await runCli(['layout', '--json'])).status).toBe(1);
62
+ });
63
+
64
+ it('`astryx discover` with a blank query exits 1 only when packages are discovered', async () => {
65
+ const doc = commandDocs.find((d) => d.name === 'discover');
66
+ expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/blank query when packages are discovered/);
67
+ const project = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-exit-discover-'));
68
+ try {
69
+ expect((await runCli(['discover', ' ', '--json'], {cwd: project})).status).toBe(0);
70
+ const pkg = path.join(project, 'node_modules/@acme/ui');
71
+ fs.mkdirSync(path.join(pkg, 'components'), {recursive: true});
72
+ fs.writeFileSync(path.join(pkg, 'package.json'), '{"name":"@acme/ui","version":"1.0.0","type":"module"}');
73
+ fs.writeFileSync(path.join(pkg, 'astryx.integration.mjs'), "export default {components: './components'};\n");
74
+ fs.writeFileSync(
75
+ path.join(pkg, 'components/Widget.doc.mjs'),
76
+ 'export const doc = {type: "component", name: "Widget", description: "A widget"};\n',
77
+ );
78
+ fs.writeFileSync(path.join(pkg, 'components/Widget.tsx'), 'export function Widget() { return null; }\n');
79
+ fs.writeFileSync(path.join(project, 'package.json'), '{"name":"app","type":"module"}');
80
+ fs.writeFileSync(path.join(project, 'astryx.config.mjs'), "export default {integrations: ['@acme/ui']};\n");
81
+ expect((await runCli(['discover', '--json'], {cwd: project})).status).toBe(0);
82
+ const blank = await runCli(['discover', ' ', '--json'], {cwd: project});
83
+ expect(blank.status).toBe(1);
84
+ expect(JSON.parse(blank.stdout).code).toBe('ERR_INVALID_ARGUMENT');
85
+ } finally {
86
+ fs.rmSync(project, {recursive: true, force: true});
87
+ }
88
+ });
89
+
90
+ it('the manifest carries every command exit code', () => {
91
+ for (const doc of commandDocs) {
92
+ expect(entries.get(doc.name)?.exitCodes, doc.name).toEqual(
93
+ doc.exitCodes.map(({code, when}) => ({code, when})),
94
+ );
95
+ }
96
+ });
97
+ });
@@ -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,6 +29,9 @@
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
36
  * Non-JSON behavior is preserved exactly: every code path that printed
34
37
  * to stderr before still prints to stderr. Commander writes its
@@ -117,6 +120,35 @@ export function buildHelpEnvelope(cmd) {
117
120
  };
118
121
  }
119
122
 
123
+ /**
124
+ * The error envelope for help Commander shows because the invocation failed
125
+ * (it then exits 1): `help <name>` for an unknown name on the root, or a
126
+ * command group run without a subcommand.
127
+ *
128
+ * @param {import('commander').Command} cmd the command whose help was shown
129
+ * @returns {ReturnType<typeof toErrorEnvelope>}
130
+ */
131
+ export function buildHelpErrorEnvelope(cmd) {
132
+ const available = cmd.commands
133
+ .filter(s => !(/** @type {any} */ (s))._hidden && s.name() !== 'help')
134
+ .map(s => s.name());
135
+ if (!cmd.parent) {
136
+ // Commander dispatches `help <name>` with ['help', <name>, ...] in args.
137
+ const requested = cmd.args[1];
138
+ return toErrorEnvelope(
139
+ requested ? `unknown command '${requested}'` : 'unknown command',
140
+ available.map(name => ({name, reason: 'available command'})),
141
+ ERROR_CODES.ERR_UNKNOWN_COMMAND,
142
+ );
143
+ }
144
+ const group = fullNameOf(cmd);
145
+ return toErrorEnvelope(
146
+ `'${group}' needs a subcommand`,
147
+ available.map(name => ({name: `${group} ${name}`, reason: 'available subcommand'})),
148
+ ERROR_CODES.ERR_MISSING_ARGUMENT,
149
+ );
150
+ }
151
+
120
152
  /**
121
153
  * Emit a JSON error envelope to stdout (the JSON contract uses stdout
122
154
  * for both success and error).
@@ -310,7 +342,9 @@ function patchOutputHelp(cmd) {
310
342
  if (jsonActive()) {
311
343
  if (!process.__xdsJsonHandled) {
312
344
  process.__xdsJsonHandled = true;
313
- const env = buildHelpEnvelope(cmd);
345
+ const env = contextOptions?.error
346
+ ? buildHelpErrorEnvelope(cmd)
347
+ : buildHelpEnvelope(cmd);
314
348
  process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
315
349
  }
316
350
  return;
@@ -334,7 +368,9 @@ function patchPrototype(CommandCtor) {
334
368
  if (jsonActive()) {
335
369
  if (!process.__xdsJsonHandled) {
336
370
  process.__xdsJsonHandled = true;
337
- const env = buildHelpEnvelope(this);
371
+ const env = contextOptions?.error
372
+ ? buildHelpErrorEnvelope(this)
373
+ : buildHelpEnvelope(this);
338
374
  process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
339
375
  }
340
376
  return;
@@ -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
  }
@@ -35,6 +35,8 @@
35
35
  */
36
36
 
37
37
  import {API_VERSION} from '../../../foundation/response/json.mjs';
38
+ import {commandDocsOf} from './define-command.mjs';
39
+ import {doc as manifestDoc} from '../commands/manifest.doc.mjs';
38
40
 
39
41
  /**
40
42
  * Response `type` discriminators each fully-qualified command can emit in
@@ -55,12 +57,19 @@ export const RESPONSE_TYPES = {
55
57
  'component.detail.showcase',
56
58
  'component.detail.blocks',
57
59
  ],
58
- docs: ['docs.list', 'docs.index', 'docs.detail', 'docs.detail.section'],
60
+ docs: [
61
+ 'docs.list',
62
+ 'docs.index',
63
+ 'docs.detail',
64
+ 'docs.detail.section',
65
+ 'docs.node',
66
+ ],
59
67
  blog: ['blog.list', 'blog.detail'],
60
68
  discover: [
61
69
  'discover.list',
62
70
  'discover.detail',
63
71
  'discover.detail.doc',
72
+ 'discover.item',
64
73
  'discover.search',
65
74
  ],
66
75
  search: ['search'],
@@ -108,8 +117,9 @@ const EXAMPLES = {
108
117
  docs: [
109
118
  'astryx docs',
110
119
  'astryx docs spacing --json',
111
- 'astryx docs theme --index',
120
+ 'astryx docs theme',
112
121
  'astryx docs theme quick-start',
122
+ 'astryx docs cli/integrations --full',
113
123
  ],
114
124
  discover: ['astryx discover --json'],
115
125
  search: [
@@ -237,6 +247,18 @@ function fullName(cmd, root) {
237
247
  return parts.join(' ');
238
248
  }
239
249
 
250
+ /**
251
+ * The docs a command was built from. `manifest` is registered by hand in
252
+ * index.mjs, so its CommandDoc is read here.
253
+ * @param {import('commander').Command} cmd
254
+ * @param {string} name
255
+ */
256
+ function docsOf(cmd, name) {
257
+ return (
258
+ commandDocsOf(cmd) ?? (name === 'manifest' ? {doc: manifestDoc} : undefined)
259
+ );
260
+ }
261
+
240
262
  /**
241
263
  * Recursively describe a Commander command and its subcommands.
242
264
  *
@@ -252,6 +274,8 @@ function describeCommand(cmd, root, jsonSupported) {
252
274
  // `_hidden` is a Commander internal not present on its public types.
253
275
  if (!name || /** @type {any} */ (cmd)._hidden || name === 'help') return null;
254
276
 
277
+ const docs = docsOf(cmd, name);
278
+
255
279
  const subcommands = /** @type {object[]} */ (
256
280
  (cmd.commands || [])
257
281
  .map(sub => describeCommand(sub, root, jsonSupported))
@@ -284,6 +308,12 @@ function describeCommand(cmd, root, jsonSupported) {
284
308
 
285
309
  if (EXAMPLES[name]) entry.examples = [...EXAMPLES[name]];
286
310
 
311
+ const exitCodes = (docs?.doc.exitCodes ?? []).map(({code, when}) => ({
312
+ code,
313
+ when,
314
+ }));
315
+ if (exitCodes.length > 0) entry.exitCodes = exitCodes;
316
+
287
317
  // Sort subcommands by name for a stable, agent-facing contract — the same
288
318
  // guarantee the top-level command list makes. Otherwise Commander
289
319
  // registration order leaks into the manifest and a pure reorder of
@@ -196,3 +196,20 @@ describe('manifest: e2e', () => {
196
196
  .toContain('component.list');
197
197
  });
198
198
  });
199
+
200
+ describe('manifest: text projection', () => {
201
+ it('astryx manifest (text) uses the JSON entry keys as its field names', async () => {
202
+ const text = await runCli(['manifest']);
203
+ expect(text.status).toBe(0);
204
+ const json = JSON.parse((await runCli(['manifest', '--json'])).stdout);
205
+ const jsonKeys = new Set(json.data.commands.flatMap((c) => Object.keys(c)));
206
+ const textKeys = new Set(
207
+ text.stdout
208
+ .split('\n')
209
+ .map((line) => /^([A-Za-z]+):\s/.exec(line)?.[1])
210
+ .filter(Boolean),
211
+ );
212
+ expect(textKeys).toContain('name');
213
+ for (const key of textKeys) expect(jsonKeys).toContain(key);
214
+ });
215
+ });
@@ -78,8 +78,9 @@ export function detectStylingSystem(targetDir: string): "stylex" | "tailwind" |
78
78
  * Generate the agent cheat sheet from live CLI metadata.
79
79
  *
80
80
  * Structured as: workflow (behavioral) → rules (error prevention) → CLI reference.
81
- * Templates are positioned first in the workflow to teach agents the
82
- * "look at reference code" reflex before writing any UI.
81
+ * Templates lead the workflow: every page starts from a scaffolded template,
82
+ * because the template already carries the frame and spacing that an agent
83
+ * composing from components would have to re-derive, and usually gets wrong.
83
84
  *
84
85
  * `stylingSystem` tailors the custom-styling guidance to what the project has
85
86
  * configured (see {@link detectStylingSystem}) so the agent never reaches for a
@@ -182,6 +183,8 @@ export function removeXdsBlock(filePath: string, { deleteIfEmpty }?: {
182
183
  /**
183
184
  * Remove Astryx section from all known agent doc files.
184
185
  * @param {string} targetDir
186
+ * @throws {PathSafetyError} `ERR_PATH_TRAVERSAL` when a file it would change
187
+ * resolves outside `targetDir`; nothing is changed.
185
188
  */
186
189
  export function removeAgentDocs(targetDir: string): void;
187
190
  /**
@@ -208,6 +211,8 @@ export function removeAgentDocs(targetDir: string): void;
208
211
  * @param {string} [options.renderedBlock] - Fully rendered expected block. Init
209
212
  * and upgrade pass one shared block to every target.
210
213
  * @returns {string[]} List of files written
214
+ * @throws {import('../fs/path-safety.mjs').PathSafetyError} when a file it would
215
+ * write resolves outside `targetDir`; nothing is written.
211
216
  */
212
217
  export function installAgentDocs(targetDir: string, { zh, lang, agent, paths, onlyReplace, topics, renderedBlock, }?: {
213
218
  zh?: boolean | undefined;