@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
@@ -3,18 +3,26 @@
3
3
  /**
4
4
  * @file docs command — Print Astryx reference docs
5
5
  *
6
- * A topic prints its whole doc; `--index` lists its sections instead, so a
7
- * reader can open one section by its key.
6
+ * In text, every read is one level: a topic lists its sections, so a reader can
7
+ * open one section by its key, and `--full` prints the whole topic. `--json`
8
+ * keeps the docs() contract: a topic returns its whole doc, and `--index` its
9
+ * sections.
8
10
  * Supports --detail (full|compact|brief) and --lang (en|zh|dense).
9
11
  *
10
12
  * Usage:
11
13
  * astryx docs List available topics
12
- * astryx docs <topic> Print the whole topic
13
- * astryx docs <topic> --index List the topic's sections
14
+ * astryx docs <topic> List the topic's sections (a topic
15
+ * with one section prints whole)
14
16
  * astryx docs <topic> <section> Print one section
17
+ * astryx docs <topic> --full Print the whole topic
18
+ * astryx docs <route> Open a node of the docs tree, such as
19
+ * cli, cli/api, or cli/api/functions/search
15
20
  */
16
21
 
17
- import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
22
+ import {
23
+ formatCliCommand,
24
+ getCliInvocation,
25
+ } from '../../../foundation/env/package-manager.mjs';
18
26
  import {jsonOut} from '../../../foundation/response/json.mjs';
19
27
  import {
20
28
  emit,
@@ -23,10 +31,9 @@ import {
23
31
  text,
24
32
  code,
25
33
  wrapText,
26
- displayWidth,
27
- WRAP_WIDTH,
28
34
  } from '../formatters/index.mjs';
29
35
  import {cliError} from '../lib/cli-error.mjs';
36
+ import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
30
37
  import {defineCommand} from '../lib/define-command.mjs';
31
38
  import {resultSet} from '../../../foundation/debug/index.mjs';
32
39
  import {docs as docsApi} from '../../../api/docs/docs.mjs';
@@ -52,28 +59,6 @@ function formatTable(headers, rows) {
52
59
  return `${head}\n${sep}\n${body}`;
53
60
  }
54
61
 
55
- /**
56
- * A table too wide for {@link WRAP_WIDTH}: one `header: cell` line per cell and
57
- * a blank line between rows, so nothing runs off the side of a terminal.
58
- * @param {string[]} headers
59
- * @param {string[][]} rows
60
- * @returns {string}
61
- */
62
- function formatTableVertical(headers, rows) {
63
- const width = Math.max(...headers.map(h => h.length)) + 2;
64
- return rows
65
- .map(row =>
66
- headers
67
- .map((h, i) =>
68
- wrapText(`${`${h}:`.padEnd(width)}${row[i] ?? ''}`, {
69
- indent: ' '.repeat(width),
70
- }),
71
- )
72
- .join('\n'),
73
- )
74
- .join('\n\n');
75
- }
76
-
77
62
  /**
78
63
  * @param {string[]} headers
79
64
  * @param {string[][]} rows
@@ -91,7 +76,7 @@ function formatTableCompact(headers, rows) {
91
76
  function formatBlock(block, detail) {
92
77
  switch (block.type) {
93
78
  case 'prose':
94
- return wrapText(block.text);
79
+ return block.text;
95
80
 
96
81
  case 'heading':
97
82
  return `${'#'.repeat(block.level || 3)} ${block.text}`;
@@ -110,12 +95,7 @@ function formatBlock(block, detail) {
110
95
  if (detail === 'compact') {
111
96
  return formatTableCompact(block.headers, block.rows);
112
97
  }
113
- {
114
- const table = formatTable(block.headers, block.rows);
115
- return table.split('\n').some(line => displayWidth(line) > WRAP_WIDTH)
116
- ? formatTableVertical(block.headers, block.rows)
117
- : table;
118
- }
98
+ return formatTable(block.headers, block.rows);
119
99
 
120
100
  case 'list': {
121
101
  const prefix =
@@ -126,28 +106,16 @@ function formatBlock(block, detail) {
126
106
  : block.style === 'do'
127
107
  ? () => '+ '
128
108
  : () => '- ';
129
- return block.items
130
- .map((item, i) => {
131
- const head = prefix(i);
132
- return wrapText(`${head}${item}`, {indent: ' '.repeat(head.length)});
133
- })
134
- .join('\n');
109
+ return block.items.map((item, i) => `${prefix(i)}${item}`).join('\n');
135
110
  }
136
111
 
137
- case 'workflow':
138
- case 'collection':
139
- case 'reference':
140
- throw new Error(
141
- `Documentation block "${block.type}" requires the compiled graph renderer.`,
142
- );
143
-
144
112
  default:
145
113
  return null;
146
114
  }
147
115
  }
148
116
 
149
117
  /**
150
- * @param {import('@astryxdesign/cli/authoring').ReferenceSection} section
118
+ * @param {import('../../../api/docs/docs.type.mjs').DocsReadSection} section
151
119
  * @param {'full' | 'compact' | 'brief'} detail
152
120
  * @returns {string}
153
121
  */
@@ -167,27 +135,44 @@ function formatSection(section, detail) {
167
135
  }
168
136
 
169
137
  /**
170
- * @param {import('@astryxdesign/cli/authoring').ReferenceDoc} docs
138
+ * @param {import('../../../api/docs/docs.type.mjs').DocsReadDoc} docs
171
139
  * @param {'full' | 'compact' | 'brief'} detail
172
140
  * @returns {string}
173
141
  */
174
142
  function formatReferenceFull(docs, detail) {
175
143
  if (detail === 'brief') {
176
- const header = wrapText(`${docs.title}: ${docs.description}`);
144
+ const header = `${docs.title}: ${docs.description}`;
177
145
  const sections = docs.sections.map(s => formatSection(s, detail));
178
146
  return `${header}\n${sections.join('\n')}`;
179
147
  }
180
148
 
181
- const description = wrapText(docs.description);
182
149
  const header =
183
150
  detail === 'compact'
184
- ? `# ${docs.title}\n${description}`
185
- : `# ${docs.title}\n\n${description}`;
151
+ ? `# ${docs.title}\n${docs.description}`
152
+ : `# ${docs.title}\n\n${docs.description}`;
186
153
  const sections = docs.sections.map(s => formatSection(s, detail));
187
154
  const sep = detail === 'compact' ? '\n\n' : '\n\n';
188
155
  return `${header}\n\n${sections.join(sep)}`;
189
156
  }
190
157
 
158
+ /**
159
+ * The moves a read offers (spec:AST-047), one runnable command per line: up to
160
+ * the level it sits in, the item before and after it, and the docs it names.
161
+ * @param {import('../../../api/docs/docs.type.mjs').DocsLinks | undefined} links
162
+ * @returns {string[]}
163
+ */
164
+ function linkLines(links) {
165
+ if (!links) return [];
166
+ return [
167
+ `Up: ${formatCliCommand(links.up)}`,
168
+ ...(links.previous ? [`Previous: ${formatCliCommand(links.previous)}`] : []),
169
+ ...(links.next ? [`Next: ${formatCliCommand(links.next)}`] : []),
170
+ ...(links.related ?? []).map(
171
+ (command, i) => `${i === 0 ? 'Related: ' : ' '}${formatCliCommand(command)}`,
172
+ ),
173
+ ];
174
+ }
175
+
191
176
  /**
192
177
  * A topic's section index: what the topic is, one line per section with the
193
178
  * key to read it by, and how to read further.
@@ -196,21 +181,84 @@ function formatReferenceFull(docs, detail) {
196
181
  */
197
182
  function emitIndex(index, run) {
198
183
  emit(
199
- section(index.title, index.description ? wrapText(index.description) : undefined),
184
+ section(
185
+ index.title,
186
+ index.description ? wrapText(index.description) : undefined,
187
+ ),
188
+ // Summaries wrap rather than being cut: the summary is how a reader picks
189
+ // the one section to open.
200
190
  records(index.sections, {
201
191
  fields: ['id', 'title', 'summary'],
202
192
  layout: 'inline',
203
- overflow: 'truncate',
204
193
  }),
205
194
  text(
206
195
  [
207
196
  `Read one section: ${run} docs ${index.name} <section>`,
208
- `Read everything: ${run} docs ${index.name}`,
197
+ `Read everything: ${run} docs ${index.name} --full`,
198
+ ...linkLines(index.links),
209
199
  ].join('\n'),
210
200
  ),
211
201
  );
212
202
  }
213
203
 
204
+ /**
205
+ * One child row of a namespace: its route name, then the doc's own title when
206
+ * it is not the route name (`assertResponse()`, `search()`), then its summary.
207
+ * @param {import('../../../api/docs/docs.type.mjs').DocsNodeChild} child
208
+ * @returns {{name: string, summary: string}}
209
+ */
210
+ function childRow(child) {
211
+ return {
212
+ name: child.name,
213
+ summary:
214
+ child.title === child.name ? child.summary : `${child.title}: ${child.summary}`,
215
+ };
216
+ }
217
+
218
+ /**
219
+ * One node of the docs tree. A namespace lists each slot's children, one level
220
+ * down, with the command to open one; a typed doc prints its content. Both end
221
+ * with the way back up.
222
+ * @param {import('../../../api/docs/docs.type.mjs').DocsNode} node
223
+ * @param {'full' | 'compact' | 'brief'} detail
224
+ * @param {string} run
225
+ */
226
+ function emitNode(node, detail, run) {
227
+ if (node.kind === 'namespace') {
228
+ emit(
229
+ section(node.title, wrapText(node.summary)),
230
+ ...node.slots.flatMap(slot => [
231
+ // A namespace with one slot titled like itself needs no second heading.
232
+ ...(node.slots.length === 1 && slot.title === node.title
233
+ ? []
234
+ : [section(slot.title)]),
235
+ records(slot.children.map(childRow), {
236
+ fields: ['name', 'summary'],
237
+ layout: 'inline',
238
+ overflow: 'truncate',
239
+ }),
240
+ ]),
241
+ text(
242
+ [
243
+ // A child's route is its parent's route and its name, except a flat
244
+ // topic in the Unorganized level, which keeps its own name.
245
+ node.slots.every(slot =>
246
+ slot.children.every(child => child.route.startsWith(`${node.route}/`)),
247
+ )
248
+ ? `Open one: ${run} docs ${node.route}/<name>`
249
+ : `Open one: ${run} docs <name>`,
250
+ ...linkLines(node.links),
251
+ ].join('\n'),
252
+ ),
253
+ );
254
+ return;
255
+ }
256
+ emit(
257
+ code(formatSection({title: node.title, content: node.content}, detail)),
258
+ text(linkLines(node.links).join('\n')),
259
+ );
260
+ }
261
+
214
262
  /**
215
263
  * What the run answered with. A named topic (or one of its sections) resolves
216
264
  * or throws, so it is always a direct match of one doc; the bare form lists
@@ -219,7 +267,8 @@ function emitIndex(index, run) {
219
267
  * @param {import('../../../api/docs/docs.type.mjs').DocsListResponse
220
268
  * | import('../../../api/docs/docs.type.mjs').DocsIndexResponse
221
269
  * | import('../../../api/docs/docs.type.mjs').DocsDetailResponse
222
- * | import('../../../api/docs/docs.type.mjs').DocsDetailSectionResponse} result
270
+ * | import('../../../api/docs/docs.type.mjs').DocsDetailSectionResponse
271
+ * | import('../../../api/docs/docs.type.mjs').DocsNodeResponse} result
223
272
  * @returns {import('../../../foundation/debug/command-result.mjs').CommandResult}
224
273
  */
225
274
  function summarize(result) {
@@ -239,7 +288,7 @@ export function registerDocs(program) {
239
288
  action: async (
240
289
  /** @type {string | undefined} */ topic,
241
290
  /** @type {string | undefined} */ sectionName,
242
- /** @type {{index?: boolean}} */ options = {},
291
+ /** @type {{index?: boolean, full?: boolean}} */ options = {},
243
292
  ) => {
244
293
  const run = getCliInvocation();
245
294
  const lang = program.opts().lang || null;
@@ -248,14 +297,37 @@ export function registerDocs(program) {
248
297
  const detail = program.opts().detail || 'full';
249
298
  const json = program.opts().json || false;
250
299
 
300
+ if (options.index && options.full) {
301
+ return cliError(
302
+ 'Ask for the section list or the whole topic, not both: --index and --full cannot both be set.',
303
+ {code: ERROR_CODES.ERR_INVALID_ARGUMENT},
304
+ );
305
+ }
306
+ // Text reads one level: a topic lists its sections (one with a single
307
+ // section prints whole). JSON keeps docs(): the whole topic unless
308
+ // --index. The dense variant is written to be read whole.
309
+ const listSections =
310
+ Boolean(options.index) ||
311
+ (!json &&
312
+ !options.full &&
313
+ !dense &&
314
+ lang !== 'dense' &&
315
+ sectionName == null);
251
316
  let result;
252
317
  try {
253
318
  result = await docsApi(topic, sectionName, {
254
319
  lang,
255
320
  zh,
256
321
  dense,
257
- index: Boolean(options.index),
322
+ index: listSections,
258
323
  });
324
+ if (
325
+ !options.index &&
326
+ result.type === 'docs.index' &&
327
+ result.data.sections.length <= 1
328
+ ) {
329
+ result = await docsApi(topic, sectionName, {lang, zh, dense});
330
+ }
259
331
  } catch (e) {
260
332
  // docs API throws structured errors with {name, reason} suggestions —
261
333
  // pass them through untouched so the CLI envelope matches the API.
@@ -275,21 +347,50 @@ export function registerDocs(program) {
275
347
 
276
348
  switch (result.type) {
277
349
  case 'docs.list': {
278
- // The text view mirrors the JSON list: one record per topic (topic +
279
- // description), then the usage footer as plain prose.
350
+ // The text view mirrors the JSON list, with the docs tree's
351
+ // namespaces (`meta.namespaces`) first under their own heading: that
352
+ // is where the CLI's own docs start, and a namespace reads
353
+ // differently from a topic.
354
+ const namespaces = result.meta?.namespaces ?? [];
355
+ const topics = result.data;
280
356
  emit(
281
- section('Available docs'),
282
- records(result.data, {
283
- fields: ['topic', 'description'],
357
+ ...(namespaces.length > 0
358
+ ? [
359
+ section('Docs tree'),
360
+ records(namespaces, {
361
+ fields: ['topic', 'description', 'package'],
362
+ layout: 'inline',
363
+ }),
364
+ ]
365
+ : []),
366
+ section('Topics'),
367
+ records(topics, {
368
+ fields: ['topic', 'description', 'package'],
284
369
  layout: 'inline',
285
370
  }),
286
371
  text(
287
372
  [
288
- `Usage: ${run} docs <topic> read the whole topic`,
289
- ` ${run} docs <topic> --index list its sections`,
373
+ `Usage: ${run} docs <topic> list a topic's sections`,
290
374
  ` ${run} docs <topic> <section> read one section`,
375
+ ` ${run} docs <topic> --full read the whole topic`,
376
+ ` ${run} docs cli/api go down the docs tree one level at a time`,
377
+ `With --json, a topic returns its whole doc; add --index for its section list.`,
291
378
  ].join('\n'),
292
379
  ),
380
+ // A package whose doc files did not load has no topics here; say
381
+ // so, and where to look, instead of leaving them silently missing.
382
+ ...(result.meta?.notLoaded?.length
383
+ ? [
384
+ section('Not loaded'),
385
+ records(result.meta.notLoaded, {
386
+ fields: ['package', 'message'],
387
+ layout: 'inline',
388
+ }),
389
+ text(
390
+ `Run \`${run} doctor integration docs\` in that package to see every problem.`,
391
+ ),
392
+ ]
393
+ : []),
293
394
  );
294
395
  break;
295
396
  }
@@ -300,12 +401,25 @@ export function registerDocs(program) {
300
401
  }
301
402
 
302
403
  case 'docs.detail': {
303
- emit(code(formatReferenceFull(result.data, detail)));
404
+ emit(
405
+ code(formatReferenceFull(result.data, detail)),
406
+ text(linkLines(result.data.links).join('\n')),
407
+ );
304
408
  break;
305
409
  }
306
410
 
307
411
  case 'docs.detail.section': {
308
- emit(code(formatSection(result.data, detail)));
412
+ // One section ends with its moves: up to its topic's index, and to
413
+ // the sections before and after it.
414
+ emit(
415
+ code(formatSection(result.data, detail)),
416
+ text(linkLines(result.data.links).join('\n')),
417
+ );
418
+ break;
419
+ }
420
+
421
+ case 'docs.node': {
422
+ emitNode(result.data, detail, run);
309
423
  break;
310
424
  }
311
425
  }
@@ -75,7 +75,7 @@ describe('hyphenated doc filenames', () => {
75
75
 
76
76
  it('returns docs.detail via API for hyphenated topic', async () => {
77
77
  const {docs: docsApi} = await import('../../../api/docs/docs.mjs');
78
- const result = await docsApi('getting-started');
78
+ const result = await docsApi('getting-started', undefined, {full: true});
79
79
  expect(result.type).toBe('docs.detail');
80
80
  expect(result.data).toBeDefined();
81
81
  expect(result.data.description).toBeDefined();
@@ -113,6 +113,7 @@ describe('progressive reads', () => {
113
113
  expect(status).toBe(0);
114
114
  expect(stdout).toMatch(/^principles +\S/m);
115
115
  expect(widest(stdout)).toBeLessThanOrEqual(120);
116
+ expect(stdout).toContain('Usage: pnpm exec astryx docs <topic>');
116
117
  }, SLOW);
117
118
 
118
119
  it("prints a topic's section index with the keys to read by", async () => {
@@ -120,7 +121,7 @@ describe('progressive reads', () => {
120
121
  expect(status).toBe(0);
121
122
  expect(stdout).toMatch(/^quick-start +Quick Start/m);
122
123
  expect(stdout).toContain('docs theme <section>');
123
- expect(stdout).toMatch(/Read everything: +\S.* docs theme$/m);
124
+ expect(stdout).toMatch(/Read everything: +\S.* docs theme --full$/m);
124
125
  expect(widest(stdout)).toBeLessThanOrEqual(120);
125
126
  }, SLOW);
126
127
 
@@ -130,23 +131,23 @@ describe('progressive reads', () => {
130
131
  expect(stdout).toMatch(/^## Quick Start/m);
131
132
  }, SLOW);
132
133
 
133
- it('prints the whole topic by default, as before', async () => {
134
+ it("lists a topic's sections by default; --full prints the whole topic", async () => {
134
135
  const index = await runCli(['docs', 'theme', '--index']);
135
- const full = await runCli(['docs', 'theme']);
136
+ expect((await runCli(['docs', 'theme'])).stdout).toBe(index.stdout);
137
+ const full = await runCli(['docs', 'theme', '--full']);
136
138
  expect(full.status).toBe(0);
137
139
  expect(full.stdout).toMatch(/^## Quick Start/m);
138
140
  expect(full.stdout.length).toBeGreaterThan(index.stdout.length * 3);
139
- expect((await runCli(['--detail', 'full', 'docs', 'theme'])).stdout).toBe(
141
+ expect((await runCli(['--detail', 'full', 'docs', 'theme', '--full'])).stdout).toBe(
140
142
  full.stdout,
141
143
  );
142
- expect(widest(full.stdout.replace(/```[\s\S]*?```/g, ''))).toBeLessThanOrEqual(
143
- 120,
144
- );
145
144
  }, SLOW);
146
145
 
147
146
  it('returns the matching envelopes as JSON', async () => {
148
147
  const envelope = async args => JSON.parse((await runCli([...args, '--json'])).stdout);
148
+ // JSON keeps docs(): a bare read is the whole topic.
149
149
  expect((await envelope(['docs', 'theme'])).type).toBe('docs.detail');
150
+ expect((await envelope(['docs', 'theme', '--full'])).type).toBe('docs.detail');
150
151
  expect((await envelope(['docs', 'theme', '--index'])).type).toBe(
151
152
  'docs.index',
152
153
  );
@@ -156,6 +157,109 @@ describe('progressive reads', () => {
156
157
  }, SLOW);
157
158
  });
158
159
 
160
+ describe('the docs tree, one level at a time', () => {
161
+ const SLOW = 60_000;
162
+ /** @param {string} out */
163
+ const widest = out => Math.max(...out.split('\n').map(line => line.length));
164
+
165
+ it('lists the docs tree first, under its own heading, then the topics', async () => {
166
+ const {status, stdout} = await runCli(['docs']);
167
+ expect(status).toBe(0);
168
+ expect(stdout).toMatch(/^Docs tree$/m);
169
+ expect(stdout).toMatch(/^Topics$/m);
170
+ expect(stdout).toMatch(/^cli +Commands, programmatic APIs/m);
171
+ expect(stdout.indexOf('\ncli ')).toBeLessThan(stdout.indexOf('\nprinciples '));
172
+ expect(stdout).not.toMatch(/^cli-integrations /m);
173
+ }, SLOW);
174
+
175
+ it("shows a child's own name when its route name does not spell it", async () => {
176
+ const {status, stdout} = await runCli(['docs', 'cli/api/functions']);
177
+ expect(status).toBe(0);
178
+ expect(stdout).toMatch(/^assert-response +assertResponse\(\): \S/m);
179
+ expect(stdout).toMatch(/^search +search\(\): Unified ranked search/m);
180
+ }, SLOW);
181
+
182
+ it('prints a namespace: each slot, its children, and how to go down and up', async () => {
183
+ const {status, stdout} = await runCli(['docs', 'cli/api']);
184
+ expect(status).toBe(0);
185
+ expect(stdout).toMatch(/^API$/m);
186
+ expect(stdout).toMatch(/^Reference$/m);
187
+ expect(stdout).toMatch(/^functions +Functions: Every function/m);
188
+ expect(stdout).toMatch(/^schemas +/m);
189
+ expect(stdout).toMatch(/^enums +/m);
190
+ // One level only: no function is listed on the api page.
191
+ expect(stdout).not.toMatch(/^search +/m);
192
+ expect(stdout).toMatch(/Open one: .*docs cli\/api\/<name>$/m);
193
+ expect(stdout).toMatch(/Up: .*docs cli$/m);
194
+ expect(widest(stdout)).toBeLessThanOrEqual(120);
195
+ }, SLOW);
196
+
197
+ it('prints a typed doc and the way back up', async () => {
198
+ const {status, stdout} = await runCli(['docs', 'cli/api/functions/search']);
199
+ expect(status).toBe(0);
200
+ expect(stdout).toMatch(/^## search\(\)/m);
201
+ expect(stdout).toContain('Read it with `astryx docs cli/commands/search`.');
202
+ expect(stdout).toMatch(/Up: .*docs cli\/api\/functions$/m);
203
+ }, SLOW);
204
+
205
+ it('reads the dense variant whole, asked with --dense or with --lang dense', async () => {
206
+ for (const args of [['--dense', 'docs', 'theme'], ['--lang', 'dense', 'docs', 'theme']]) {
207
+ const {status, stdout} = await runCli(args);
208
+ expect(status).toBe(0);
209
+ expect(stdout).not.toContain('Read one section:');
210
+ }
211
+ }, SLOW);
212
+
213
+ it('refuses --index with --full', async () => {
214
+ const both = await runCli(['docs', 'theme', '--index', '--full', '--json']);
215
+ expect(both.status).toBe(1);
216
+ expect(JSON.parse(both.stdout).code).toBe('ERR_INVALID_ARGUMENT');
217
+ }, SLOW);
218
+
219
+ it('reads the integration guide by its route, and not by its old name', async () => {
220
+ const guide = await runCli(['docs', 'cli/integrations', '--index']);
221
+ expect(guide.status).toBe(0);
222
+ expect(guide.stdout).toMatch(/Read one section: .*docs cli\/integrations <section>/);
223
+ // A bare read is one level too: the sections, and how to read it all.
224
+ const bare = await runCli(['docs', 'cli/integrations']);
225
+ expect(bare.status).toBe(0);
226
+ expect(bare.stdout).toBe(guide.stdout);
227
+ expect(bare.stdout).toMatch(/Read everything: +.*docs cli\/integrations --full$/m);
228
+ const one = await runCli(['docs', 'cli/integrations', 'codemods']);
229
+ expect(one.status).toBe(0);
230
+ expect(one.stdout).toMatch(/^## Codemods$/m);
231
+ expect(one.stdout).toMatch(/^Up: .*docs cli\/integrations --index$/m);
232
+ expect(one.stdout).toMatch(/^Previous: .*docs cli\/integrations agent-docs$/m);
233
+ expect(one.stdout).toMatch(/^Next: .*docs cli\/integrations recording-runs$/m);
234
+ const full = await runCli(['docs', 'cli/integrations', '--full']);
235
+ expect(full.status).toBe(0);
236
+ expect(full.stdout).toMatch(/^## Overview$/m);
237
+ expect(full.stdout.length).toBeGreaterThan(bare.stdout.length * 4);
238
+ const old = await runCli(['docs', 'cli-integrations']);
239
+ expect(old.status).toBe(1);
240
+ expect(old.stderr).toContain('Unknown topic "cli-integrations"');
241
+ }, SLOW);
242
+
243
+ it('returns docs.node as JSON, and fails a section of a namespace', async () => {
244
+ const node = JSON.parse((await runCli(['docs', 'cli', '--json'])).stdout);
245
+ expect(node).toMatchObject({
246
+ type: 'docs.node',
247
+ data: {route: 'cli', kind: 'namespace', breadcrumb: []},
248
+ });
249
+ expect(node.data.slots.map(slot => slot.name)).toEqual(['guides', 'reference']);
250
+ const section = await runCli(['docs', 'cli', 'commands', '--json']);
251
+ expect(section.status).toBe(1);
252
+ const error = JSON.parse(section.stdout);
253
+ expect(error).toMatchObject({code: 'ERR_UNKNOWN_SECTION'});
254
+ expect(error.suggestions.map(s => s.name)).toEqual([
255
+ 'cli/integrations',
256
+ 'cli/writing-docs',
257
+ 'cli/commands',
258
+ 'cli/api',
259
+ ]);
260
+ }, SLOW);
261
+ });
262
+
159
263
  describe('text width in every language', () => {
160
264
  const SLOW = 60_000;
161
265
  /** Widest line outside code blocks, in terminal columns. */
@@ -176,14 +280,14 @@ describe('text width in every language', () => {
176
280
  return max;
177
281
  };
178
282
 
179
- it.each([
180
- [['docs', 'theme', '--index', '--lang', 'zh']],
181
- [['docs', 'theme', '--lang', 'zh']],
182
- [['--detail', 'full', 'docs', 'theme', '--lang', 'zh']],
183
- [['--detail', 'full', 'docs', 'internationalization']],
184
- [['--detail', 'full', 'docs', 'styling']],
185
- ])('%j fits in 120 columns', async args => {
186
- const {status, stdout} = await runCli(args);
283
+ it('keeps the additive section index within 120 columns', async () => {
284
+ const {status, stdout} = await runCli([
285
+ 'docs',
286
+ 'theme',
287
+ '--index',
288
+ '--lang',
289
+ 'zh',
290
+ ]);
187
291
  expect(status).toBe(0);
188
292
  expect(widest(stdout)).toBeLessThanOrEqual(120);
189
293
  }, SLOW);
@@ -7,7 +7,7 @@ export const doc = {
7
7
  type: 'command',
8
8
  name: 'doctor integration components',
9
9
  displayName: 'astryx doctor integration components',
10
- namespace: 'cli',
10
+ namespace: 'cli/commands',
11
11
  summary: 'Warn when integration component names conflict with Core',
12
12
  description:
13
13
  'Compares one local or installed integration with Core component names. A ' +
@@ -7,8 +7,8 @@ export const doc = {
7
7
  type: 'command',
8
8
  name: 'doctor integration docs',
9
9
  displayName: 'astryx doctor integration docs',
10
- namespace: 'cli',
11
- summary: 'Classify integration doc overlaps with Core topics',
10
+ namespace: 'cli/commands',
11
+ summary: 'Check an integration\'s docs: the docs tree they add, every link, and overlaps with Core topics',
12
12
  description:
13
13
  'Reports intentional Core topic replacements and extensions as information. ' +
14
14
  'A same-name topic without `replaces` or `extends` is an accidental conflict ' +
@@ -32,7 +32,7 @@ export const doc = {
32
32
  ],
33
33
  exitCodes: [
34
34
  {code: 0, when: 'all Core overlaps are explicitly declared or no overlap exists'},
35
- {code: 1, when: 'an overlap is accidental or the integration docs are invalid'},
35
+ {code: 1, when: 'an overlap is accidental, a doc is invalid, a namespace or placement fails, or a reference block cannot include what it names. A link that names no doc is a warning, and does not change the exit code'},
36
36
  ],
37
37
  related: ['doctor integration validate', 'docs'],
38
38
  };
@@ -9,13 +9,14 @@ export const doc = {
9
9
  type: 'command',
10
10
  name: 'doctor integration templates',
11
11
  displayName: 'astryx doctor integration templates',
12
- namespace: 'cli',
13
- summary: 'Warn when integration template ids conflict with Core',
12
+ namespace: 'cli/commands',
13
+ summary: 'Validate integration template replacements and Core id overlaps',
14
14
  description:
15
- 'Compares one local or installed integration with the built-in Core page and ' +
16
- 'block template ids. A conflict is allowed and exits successfully, but the ' +
17
- 'report recommends renaming and gives the exact --package command required ' +
18
- 'to select the integration template when the overlap is intentional.',
15
+ 'Validates one local or installed integration against the built-in Core page ' +
16
+ 'and block template ids. Intentional replacements are informational and name ' +
17
+ 'the command for selecting the Core original. Missing targets, ambiguous ' +
18
+ 'replacements, and invalid declarations are errors; undeclared same-id overlaps ' +
19
+ 'remain warnings that require package selection.',
19
20
  fn: 'integrationTemplateConflicts',
20
21
  args: [
21
22
  {
@@ -37,8 +38,14 @@ export const doc = {
37
38
  },
38
39
  ],
39
40
  exitCodes: [
40
- {code: 0, when: 'the check completed; template conflicts are warnings'},
41
- {code: 1, when: 'the integration or one of its templates is invalid'},
41
+ {
42
+ code: 0,
43
+ when: 'replacement declarations are valid; undeclared id conflicts are warnings',
44
+ },
45
+ {
46
+ code: 1,
47
+ when: 'the integration, a template, or a replacement declaration is invalid',
48
+ },
42
49
  ],
43
50
  related: ['doctor integration validate', 'template'],
44
51
  };
@@ -9,7 +9,7 @@ export const doc = {
9
9
  type: 'command',
10
10
  name: 'doctor integration validate',
11
11
  displayName: 'astryx doctor integration validate',
12
- namespace: 'cli',
12
+ namespace: 'cli/commands',
13
13
  summary: 'Validate an integration manifest and its contributions',
14
14
  description:
15
15
  'Validates one integration at a time: the local package rooted at cwd, or an ' +