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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (571) hide show
  1. package/README.md +114 -76
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/build.doc.mjs +4 -3
  4. package/api/build/build.test.mjs +14 -3
  5. package/api/build/build.type.d.mts +36 -2
  6. package/api/build/build.type.mjs +25 -4
  7. package/api/build/help/help.d.mts +8 -5
  8. package/api/build/help/help.mjs +56 -6
  9. package/api/component/_adapter.d.mts +6 -12
  10. package/api/component/_adapter.mjs +20 -10
  11. package/api/component/component.doc.mjs +13 -3
  12. package/api/component/component.mjs +91 -14
  13. package/api/component/component.test.mjs +38 -0
  14. package/api/component/component.type.d.mts +22 -11
  15. package/api/component/component.type.mjs +32 -24
  16. package/api/component/detail/blocks/blocks.d.mts +2 -1
  17. package/api/component/detail/blocks/blocks.mjs +4 -3
  18. package/api/component/list/list.d.mts +0 -5
  19. package/api/component/list/list.mjs +40 -11
  20. package/api/discover/discover.doc.mjs +2 -1
  21. package/api/discover/discover.type.d.mts +4 -4
  22. package/api/discover/discover.type.mjs +10 -10
  23. package/api/docs/_adapter.d.mts +230 -41
  24. package/api/docs/_adapter.mjs +734 -108
  25. package/api/docs/compiled-topics.test.mjs +78 -0
  26. package/api/docs/detail/detail.mjs +22 -63
  27. package/api/docs/detail/section/section.d.mts +1 -1
  28. package/api/docs/detail/section/section.mjs +54 -19
  29. package/api/docs/detail/section/section.test.mjs +50 -0
  30. package/api/docs/docs.d.mts +10 -3
  31. package/api/docs/docs.doc.mjs +54 -16
  32. package/api/docs/docs.mjs +53 -10
  33. package/api/docs/docs.test.mjs +164 -4
  34. package/api/docs/docs.type.d.mts +205 -5
  35. package/api/docs/docs.type.mjs +137 -11
  36. package/api/docs/index/index.d.mts +18 -0
  37. package/api/docs/index/index.mjs +40 -0
  38. package/api/docs/index/index.test.mjs +62 -0
  39. package/api/docs/integration-tree.test.mjs +547 -0
  40. package/api/docs/integrationDocs.test.mjs +114 -8
  41. package/api/docs/list/list.mjs +28 -12
  42. package/api/docs/node/node.d.mts +43 -0
  43. package/api/docs/node/node.mjs +192 -0
  44. package/api/doctor/doctor.d.mts +99 -1
  45. package/api/doctor/doctor.doc.mjs +1 -0
  46. package/api/doctor/doctor.mjs +544 -1
  47. package/api/doctor/doctor.test.mjs +610 -1
  48. package/api/gap-report/gap-report.doc.mjs +8 -4
  49. package/api/hook/_adapter.mjs +19 -5
  50. package/api/hook/hook.doc.mjs +1 -0
  51. package/api/hook/hook.type.d.mts +3 -3
  52. package/api/hook/hook.type.mjs +11 -11
  53. package/api/hook/list/list.d.mts +2 -2
  54. package/api/hook/list/list.mjs +69 -17
  55. package/api/index.d.mts +1 -1
  56. package/api/index.mjs +1 -0
  57. package/api/init/init.doc.mjs +6 -1
  58. package/api/init/init.test.mjs +41 -1
  59. package/api/init/remove/remove.mjs +1 -1
  60. package/api/init/run/run.mjs +20 -10
  61. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  62. package/api/integration/add-contribution.d.mts +2 -1
  63. package/api/integration/add-contribution.mjs +130 -15
  64. package/api/integration/add-contribution.test.mjs +258 -7
  65. package/api/integration/add-theme.mjs +34 -64
  66. package/api/integration/add-theme.test.mjs +105 -21
  67. package/api/integration/authoring-checks.mjs +108 -31
  68. package/api/integration/authoring-checks.test.mjs +171 -6
  69. package/api/integration/authoring-checks.type.d.mts +3 -1
  70. package/api/integration/authoring-checks.type.mjs +3 -1
  71. package/api/integration/integration-authoring.type.d.mts +3 -1
  72. package/api/integration/integration-authoring.type.mjs +2 -0
  73. package/api/integration/integration-block-exports.test.mjs +10 -6
  74. package/api/integration/integrationAdd.doc.mjs +14 -4
  75. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  76. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  77. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  78. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  79. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  80. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  81. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  82. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  83. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  84. package/api/integration/integrationTemplateConflicts.doc.mjs +7 -5
  85. package/api/integration/pack-check.mjs +83 -7
  86. package/api/integration/pack-check.test.mjs +387 -47
  87. package/api/integration/pack-check.type.d.mts +26 -2
  88. package/api/integration/pack-check.type.mjs +14 -1
  89. package/api/integration/summarizeIssues.doc.mjs +1 -0
  90. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  91. package/api/integration/validate-integration.mjs +52 -102
  92. package/api/integration/validate-integration.test.mjs +179 -26
  93. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  94. package/api/integration/validateIntegration.doc.mjs +3 -2
  95. package/api/json/assertResponse.doc.mjs +1 -0
  96. package/api/json/envelope-types.test.mjs +76 -0
  97. package/api/json/index.ts +2 -0
  98. package/api/json/isError.doc.mjs +1 -0
  99. package/api/json/parseResponse.doc.mjs +3 -2
  100. package/api/layout/_adapter.mjs +20 -5
  101. package/api/layout/expand/expand.mjs +7 -5
  102. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  103. package/api/layout/grammar/grammar.mjs +2 -1
  104. package/api/layout/layoutCheck.doc.mjs +1 -0
  105. package/api/layout/layoutExpand.doc.mjs +2 -1
  106. package/api/layout/layoutGrammar.doc.mjs +1 -0
  107. package/api/search/search-return-type.test.mjs +54 -0
  108. package/api/search/search.d.mts +29 -11
  109. package/api/search/search.doc.mjs +8 -2
  110. package/api/search/search.mjs +337 -41
  111. package/api/search/search.test.mjs +124 -1
  112. package/api/search/search.type.d.mts +15 -3
  113. package/api/search/search.type.mjs +5 -2
  114. package/api/swizzle/copy/copy.mjs +28 -11
  115. package/api/swizzle/swizzle.doc.mjs +2 -1
  116. package/api/swizzle/swizzle.type.d.mts +2 -2
  117. package/api/swizzle/swizzle.type.mjs +2 -2
  118. package/api/template/copy/copy.mjs +17 -23
  119. package/api/template/copy/copy.test.mjs +17 -0
  120. package/api/template/list/list.mjs +1 -0
  121. package/api/template/template-integration.test.mjs +1022 -3
  122. package/api/template/template-suffix.test.mjs +41 -21
  123. package/api/template/template.d.mts +1 -1
  124. package/api/template/template.doc.mjs +30 -8
  125. package/api/template/template.mjs +45 -8
  126. package/api/template/template.type.d.mts +12 -14
  127. package/api/template/template.type.mjs +15 -14
  128. package/api/theme/_adapter.d.mts +2 -3
  129. package/api/theme/_adapter.mjs +4 -5
  130. package/api/theme/add/add.binary.test.mjs +84 -0
  131. package/api/theme/add/add.mjs +20 -3
  132. package/api/theme/add/add.staging.test.mjs +66 -0
  133. package/api/theme/add/add.test.mjs +14 -1
  134. package/api/theme/build/build.mjs +133 -42
  135. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  136. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  137. package/api/theme/build/build.test.mjs +127 -0
  138. package/api/theme/build/font-warning.mjs +3 -3
  139. package/api/theme/build/font-warning.test.mjs +5 -2
  140. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  141. package/api/theme/integration-themes.test.mjs +39 -28
  142. package/api/theme/list/list.test.mjs +19 -20
  143. package/api/theme/listThemes.doc.mjs +6 -5
  144. package/api/theme/palette/generate/generate.mjs +8 -3
  145. package/api/theme/palette/generate/generate.test.mjs +96 -0
  146. package/api/theme/palette/generate/generator.d.mts +10 -13
  147. package/api/theme/palette/generate/generator.mjs +15 -4
  148. package/api/theme/palette/generate/generator.test.mjs +10 -0
  149. package/api/theme/template/template.mjs +11 -2
  150. package/api/theme/template/template.test.mjs +20 -0
  151. package/api/theme/theme.type.d.mts +170 -11
  152. package/api/theme/theme.type.mjs +94 -27
  153. package/api/theme/themeAdd.doc.mjs +4 -3
  154. package/api/theme/themeBuild.doc.mjs +8 -4
  155. package/api/theme/themeList.doc.mjs +6 -3
  156. package/api/theme/themeListAvailable.doc.mjs +5 -3
  157. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  158. package/api/theme/themeTargets.doc.mjs +1 -0
  159. package/api/theme/themeTemplate.doc.mjs +6 -2
  160. package/api/upgrade/_adapter.d.mts +32 -5
  161. package/api/upgrade/_adapter.mjs +139 -22
  162. package/api/upgrade/list/list.mjs +2 -1
  163. package/api/upgrade/list/list.test.mjs +73 -0
  164. package/api/upgrade/project-context.test.mjs +272 -0
  165. package/api/upgrade/provider-agreement.test.mjs +152 -0
  166. package/api/upgrade/run/run.mjs +356 -59
  167. package/api/upgrade/status/status.mjs +2 -2
  168. package/api/upgrade/upgrade.doc.mjs +12 -5
  169. package/api/upgrade/upgrade.type.d.mts +43 -5
  170. package/api/upgrade/upgrade.type.mjs +27 -11
  171. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  172. package/assets/codemods/integration-discovery.mjs +48 -4
  173. package/assets/codemods/integration-discovery.test.mjs +73 -0
  174. package/assets/codemods/integration-runner.mjs +56 -4
  175. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  176. package/assets/codemods/run-codemod.mjs +177 -34
  177. package/assets/codemods/runner.mjs +350 -102
  178. package/assets/codemods/term-log.mjs +32 -8
  179. package/assets/codemods/term-log.test.mjs +19 -1
  180. package/assets/codemods/transform-prop.mjs +109 -0
  181. package/assets/codemods/transform-prop.test.mjs +95 -0
  182. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  183. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  184. package/assets/codemods/transforms/next/index.mjs +19 -1
  185. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  186. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  187. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  188. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  189. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  190. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  191. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  192. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  193. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  194. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  195. package/assets/docs/README.md +9 -0
  196. package/assets/docs/authoring.doc.mjs +14 -0
  197. package/assets/docs/getting-started.doc.mjs +2 -2
  198. package/assets/docs/principles.doc.mjs +6 -6
  199. package/assets/docs/styling-libraries.doc.mjs +3 -3
  200. package/assets/docs/styling.doc.mjs +4 -4
  201. package/assets/docs/theme.doc.mjs +4 -4
  202. package/assets/docs/tokens.doc.mjs +1 -1
  203. package/assets/docs/tree/api.doc.mjs +30 -0
  204. package/assets/docs/tree/cli.doc.mjs +23 -0
  205. package/assets/docs/tree/commands.doc.mjs +25 -0
  206. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +124 -25
  207. package/assets/docs/tree/integrations.test.mjs +62 -0
  208. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  209. package/assets/docs/working-with-ai.doc.mjs +1 -1
  210. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  211. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  212. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  213. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  214. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  215. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  216. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  217. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  218. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  219. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  220. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  221. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  222. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  223. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  224. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  225. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  226. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  227. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  228. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  229. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  230. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  231. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  232. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  233. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  234. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  235. package/authoring/_shared/contract.ts +22 -0
  236. package/authoring/codemod/codemod.doc.mjs +7 -2
  237. package/authoring/codemod/parse.d.mts +8 -8
  238. package/authoring/codemod/parse.mjs +8 -6
  239. package/authoring/codemod/type.ts +12 -0
  240. package/authoring/config/config.doc.mjs +2 -2
  241. package/authoring/config/debug-composition.test.mjs +92 -0
  242. package/authoring/config/parse.d.mts +13 -13
  243. package/authoring/config/parse.mjs +8 -8
  244. package/authoring/config/type.ts +18 -6
  245. package/authoring/debug/debug.doc.d.mts +11 -0
  246. package/authoring/debug/debug.doc.mjs +182 -0
  247. package/authoring/debug/parse.d.mts +8 -8
  248. package/authoring/debug/parse.mjs +3 -3
  249. package/authoring/doctypes/_schema.d.mts +718 -23
  250. package/authoring/doctypes/_schema.mjs +519 -39
  251. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  252. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  253. package/authoring/doctypes/base/type.ts +41 -0
  254. package/authoring/doctypes/command/command.doc.mjs +4 -3
  255. package/authoring/doctypes/command/parse.d.mts +2 -2
  256. package/authoring/doctypes/command/parse.mjs +1 -1
  257. package/authoring/doctypes/command/type.ts +5 -4
  258. package/authoring/doctypes/component/component.doc.mjs +6 -3
  259. package/authoring/doctypes/component/parse.d.mts +2 -2
  260. package/authoring/doctypes/component/parse.mjs +1 -1
  261. package/authoring/doctypes/component/type.ts +6 -5
  262. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  263. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  264. package/authoring/doctypes/enum/parse.d.mts +2 -2
  265. package/authoring/doctypes/enum/parse.mjs +1 -1
  266. package/authoring/doctypes/enum/type.ts +4 -2
  267. package/authoring/doctypes/function/function.doc.mjs +7 -2
  268. package/authoring/doctypes/function/parse.d.mts +2 -2
  269. package/authoring/doctypes/function/parse.mjs +1 -1
  270. package/authoring/doctypes/function/type.ts +9 -4
  271. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  272. package/authoring/doctypes/hook/parse.d.mts +2 -2
  273. package/authoring/doctypes/hook/parse.mjs +1 -1
  274. package/authoring/doctypes/hook/type.ts +5 -4
  275. package/authoring/doctypes/legacy.d.mts +8 -6
  276. package/authoring/doctypes/legacy.mjs +5 -4
  277. package/authoring/doctypes/load-contract.test.mjs +208 -0
  278. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  279. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  280. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  281. package/authoring/doctypes/namespace/parse.mjs +25 -0
  282. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  283. package/authoring/doctypes/namespace/type.ts +74 -0
  284. package/authoring/doctypes/parse.d.mts +22 -18
  285. package/authoring/doctypes/parse.mjs +22 -11
  286. package/authoring/doctypes/parse.test.mjs +77 -3
  287. package/authoring/doctypes/reference/parse.d.mts +2 -2
  288. package/authoring/doctypes/reference/parse.mjs +8 -5
  289. package/authoring/doctypes/reference/reference.doc.mjs +20 -5
  290. package/authoring/doctypes/reference/type.ts +53 -5
  291. package/authoring/doctypes/schema/parse.d.mts +2 -2
  292. package/authoring/doctypes/schema/parse.mjs +1 -1
  293. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  294. package/authoring/doctypes/schema/type.ts +4 -4
  295. package/authoring/doctypes/template/parse.d.mts +94 -1
  296. package/authoring/doctypes/template/parse.mjs +40 -2
  297. package/authoring/doctypes/template/parse.test.mjs +26 -2
  298. package/authoring/doctypes/template/template.doc.mjs +13 -3
  299. package/authoring/doctypes/template/type.ts +13 -2
  300. package/authoring/doctypes/theme/parse.d.mts +35 -0
  301. package/authoring/doctypes/theme/parse.mjs +76 -0
  302. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  303. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  304. package/authoring/doctypes/theme/type.ts +42 -0
  305. package/authoring/doctypes/types.ts +12 -10
  306. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  307. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  308. package/authoring/gap-report/parse.d.mts +10 -10
  309. package/authoring/gap-report/parse.mjs +6 -6
  310. package/authoring/gap-report/type.ts +1 -1
  311. package/authoring/identity/identity.doc.d.mts +9 -0
  312. package/authoring/identity/identity.doc.mjs +61 -0
  313. package/authoring/identity/type.ts +132 -0
  314. package/authoring/index.d.mts +2 -0
  315. package/authoring/index.d.ts +52 -17
  316. package/authoring/index.mjs +3 -1
  317. package/authoring/integration/integration.doc.mjs +15 -8
  318. package/authoring/integration/parse.d.mts +2 -2
  319. package/authoring/integration/parse.mjs +1 -1
  320. package/authoring/integration/parse.test.mjs +10 -1
  321. package/authoring/integration/schema.d.mts +6 -4
  322. package/authoring/integration/schema.mjs +9 -3
  323. package/authoring/integration/type.ts +19 -8
  324. package/authoring/shadcn/receipt.d.mts +6 -6
  325. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  326. package/clients/cli/command-load-failure.test.mjs +83 -0
  327. package/clients/cli/commands/blog.doc.mjs +1 -1
  328. package/clients/cli/commands/blog.mjs +23 -8
  329. package/clients/cli/commands/blog.test.mjs +42 -1
  330. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  331. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  332. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  333. package/clients/cli/commands/build-theme.mjs +16 -50
  334. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  335. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  336. package/clients/cli/commands/build.doc.mjs +5 -2
  337. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  338. package/clients/cli/commands/build.mjs +37 -49
  339. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  340. package/clients/cli/commands/build.text-fields.test.mjs +40 -0
  341. package/clients/cli/commands/component/index.mjs +3 -8
  342. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  343. package/clients/cli/commands/component-package.test.mjs +46 -0
  344. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  345. package/clients/cli/commands/component.doc.mjs +1 -1
  346. package/clients/cli/commands/component.test.mjs +19 -0
  347. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  348. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  349. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  350. package/clients/cli/commands/discover.doc.mjs +5 -3
  351. package/clients/cli/commands/discover.mjs +4 -4
  352. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  353. package/clients/cli/commands/docs.doc.mjs +28 -6
  354. package/clients/cli/commands/docs.mjs +238 -24
  355. package/clients/cli/commands/docs.test.mjs +193 -1
  356. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  357. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  358. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  359. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  360. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  361. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  362. package/clients/cli/commands/doctor-integration.test.mjs +83 -8
  363. package/clients/cli/commands/doctor.doc.mjs +1 -1
  364. package/clients/cli/commands/doctor.mjs +30 -25
  365. package/clients/cli/commands/doctor.test.mjs +42 -0
  366. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  367. package/clients/cli/commands/gap-report.test.mjs +72 -0
  368. package/clients/cli/commands/hook/index.mjs +7 -17
  369. package/clients/cli/commands/hook.doc.mjs +1 -1
  370. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  371. package/clients/cli/commands/init.doc.mjs +20 -9
  372. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  373. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  374. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  375. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  376. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  377. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  378. package/clients/cli/commands/integration.doc.mjs +1 -1
  379. package/clients/cli/commands/integration.mjs +1 -0
  380. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  381. package/clients/cli/commands/json-contract.test.mjs +33 -0
  382. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  383. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  384. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  385. package/clients/cli/commands/layout.doc.mjs +3 -3
  386. package/clients/cli/commands/layout.mjs +21 -9
  387. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  388. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  389. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  390. package/clients/cli/commands/manifest.doc.mjs +1 -1
  391. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  392. package/clients/cli/commands/search.doc.mjs +7 -4
  393. package/clients/cli/commands/search.mjs +28 -9
  394. package/clients/cli/commands/search.test.mjs +75 -0
  395. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  396. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  397. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  398. package/clients/cli/commands/template.doc.mjs +52 -13
  399. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  400. package/clients/cli/commands/template.mjs +4 -91
  401. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  402. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  403. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  404. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  405. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  406. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  407. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  408. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  409. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  410. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  411. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  412. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  413. package/clients/cli/commands/theme.doc.mjs +1 -1
  414. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  415. package/clients/cli/commands/upgrade.doc.mjs +22 -10
  416. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  417. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  418. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  419. package/clients/cli/commands/upgrade.mjs +29 -7
  420. package/clients/cli/formatters/index.mjs +164 -1
  421. package/clients/cli/formatters/index.test.mjs +97 -0
  422. package/clients/cli/index.mjs +21 -30
  423. package/clients/cli/latest-version-env.test.mjs +50 -0
  424. package/clients/cli/lib/cli-error.test.mjs +7 -0
  425. package/clients/cli/lib/component-format.mjs +9 -9
  426. package/clients/cli/lib/component-format.test.mjs +1 -1
  427. package/clients/cli/lib/define-command.mjs +32 -6
  428. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  429. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  430. package/clients/cli/lib/hook-format.mjs +19 -10
  431. package/clients/cli/lib/json-shim.mjs +38 -2
  432. package/clients/cli/lib/json-shim.test.mjs +83 -0
  433. package/clients/cli/lib/manifest.d.ts +2 -0
  434. package/clients/cli/lib/manifest.mjs +36 -2
  435. package/clients/cli/lib/manifest.test.mjs +17 -0
  436. package/foundation/agent-docs/agent-docs.d.mts +4 -0
  437. package/foundation/agent-docs/agent-docs.mjs +70 -3
  438. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  439. package/foundation/agent-docs/agent-docs.test.mjs +10 -1
  440. package/foundation/config/integration-debug.test.mjs +28 -3
  441. package/foundation/config/project-themes.test.mjs +11 -19
  442. package/foundation/config/project.d.mts +20 -11
  443. package/foundation/config/project.mjs +263 -91
  444. package/foundation/config/project.test.mjs +270 -21
  445. package/foundation/discovery/authoring-self-docs.d.mts +75 -0
  446. package/foundation/discovery/authoring-self-docs.mjs +224 -0
  447. package/foundation/discovery/authoring-self-docs.test.mjs +165 -0
  448. package/foundation/discovery/authoring-surface.d.mts +74 -0
  449. package/foundation/discovery/authoring-surface.mjs +525 -0
  450. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  451. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  452. package/foundation/discovery/cli-self-docs.mjs +490 -0
  453. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  454. package/foundation/discovery/component-discovery.d.mts +39 -1
  455. package/foundation/discovery/component-discovery.mjs +50 -1
  456. package/foundation/discovery/component-loader.d.mts +35 -38
  457. package/foundation/discovery/component-loader.mjs +53 -222
  458. package/foundation/discovery/docs-discovery.d.mts +116 -11
  459. package/foundation/discovery/docs-discovery.mjs +389 -108
  460. package/foundation/discovery/docs-discovery.test.mjs +325 -20
  461. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  462. package/foundation/discovery/docs-output-budget.mjs +50 -0
  463. package/foundation/discovery/docs-section-key.d.mts +116 -0
  464. package/foundation/discovery/docs-section-key.mjs +322 -0
  465. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  466. package/foundation/discovery/template-adapter.d.mts +113 -11
  467. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  468. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  469. package/foundation/discovery/template-adapter.mjs +774 -83
  470. package/foundation/discovery/template-adapter.test.mjs +57 -0
  471. package/foundation/discovery/theme-discovery.d.mts +67 -7
  472. package/foundation/discovery/theme-discovery.mjs +916 -186
  473. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  474. package/foundation/discovery/theming-targets.test.mjs +4 -0
  475. package/foundation/doc-compiler/bundle.d.mts +47 -0
  476. package/foundation/doc-compiler/bundle.mjs +278 -0
  477. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  478. package/foundation/doc-compiler/compile.d.mts +343 -0
  479. package/foundation/doc-compiler/compile.mjs +558 -0
  480. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  481. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  482. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  483. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  484. package/foundation/doc-compiler/import.d.mts +24 -0
  485. package/foundation/doc-compiler/import.mjs +59 -0
  486. package/foundation/doc-compiler/inputs.d.mts +102 -0
  487. package/foundation/doc-compiler/inputs.mjs +291 -0
  488. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  489. package/foundation/doc-compiler/ir.d.mts +22 -0
  490. package/foundation/doc-compiler/ir.mjs +471 -0
  491. package/foundation/doc-compiler/lenses.d.mts +34 -0
  492. package/foundation/doc-compiler/lenses.mjs +128 -0
  493. package/foundation/doc-compiler/links.d.mts +135 -0
  494. package/foundation/doc-compiler/links.mjs +253 -0
  495. package/foundation/doc-compiler/links.test.mjs +139 -0
  496. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  497. package/foundation/doc-compiler/overlays.d.mts +37 -0
  498. package/foundation/doc-compiler/overlays.mjs +206 -0
  499. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  500. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  501. package/foundation/doc-compiler/read.d.mts +127 -0
  502. package/foundation/doc-compiler/read.mjs +325 -0
  503. package/foundation/doc-compiler/read.test.mjs +313 -0
  504. package/foundation/doc-compiler/source.d.mts +33 -0
  505. package/foundation/doc-compiler/source.mjs +128 -0
  506. package/foundation/doc-compiler/tree.d.mts +288 -0
  507. package/foundation/doc-compiler/tree.mjs +876 -0
  508. package/foundation/doc-compiler/tree.test.mjs +598 -0
  509. package/foundation/fs/file-protection.d.mts +33 -0
  510. package/foundation/fs/file-protection.mjs +825 -0
  511. package/foundation/fs/file-protection.test.mjs +250 -0
  512. package/foundation/fs/module-loader.d.mts +1 -0
  513. package/foundation/fs/module-loader.mjs +50 -1
  514. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  515. package/foundation/fs/path-safety.d.mts +3 -2
  516. package/foundation/fs/path-safety.mjs +49 -19
  517. package/foundation/fs/path-safety.test.mjs +50 -0
  518. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  519. package/foundation/identity/provider-identity.d.mts +90 -0
  520. package/foundation/identity/provider-identity.mjs +320 -0
  521. package/foundation/identity/provider-identity.test.mjs +254 -0
  522. package/foundation/identity/providers.d.mts +7 -0
  523. package/foundation/identity/providers.mjs +16 -0
  524. package/foundation/integrations/autolink.d.mts +58 -1
  525. package/foundation/integrations/autolink.mjs +143 -45
  526. package/foundation/integrations/autolink.test.mjs +1 -1
  527. package/foundation/integrations/cli-requirement.d.mts +45 -0
  528. package/foundation/integrations/cli-requirement.mjs +154 -0
  529. package/foundation/integrations/cli-requirement.test.mjs +109 -0
  530. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  531. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  532. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  533. package/foundation/integrations/contribution-inventory.mjs +27 -24
  534. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  535. package/foundation/integrations/integration-warnings.d.mts +9 -2
  536. package/foundation/integrations/integration-warnings.mjs +52 -21
  537. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  538. package/foundation/integrations/integrations.d.mts +49 -2
  539. package/foundation/integrations/integrations.mjs +81 -8
  540. package/foundation/integrations/integrations.test.mjs +384 -1
  541. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  542. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  543. package/foundation/integrations/provider-resolution.d.mts +152 -0
  544. package/foundation/integrations/provider-resolution.mjs +576 -0
  545. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  546. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  547. package/foundation/integrations/theme-descriptor.mjs +44 -0
  548. package/foundation/integrations/validate-contributions.d.mts +2 -0
  549. package/foundation/integrations/validate-contributions.mjs +131 -29
  550. package/foundation/response/base.d.ts +8 -4
  551. package/foundation/response/error-codes.d.mts +3 -1
  552. package/foundation/response/error-codes.d.ts +2 -0
  553. package/foundation/response/error-codes.doc.mjs +13 -4
  554. package/foundation/response/error-codes.mjs +8 -2
  555. package/foundation/response/error-codes.test.mjs +137 -10
  556. package/foundation/response/json-contract.test.mjs +57 -17
  557. package/foundation/response/json.d.mts +4 -2
  558. package/foundation/response/json.mjs +8 -10
  559. package/foundation/response/response-types.doc.mjs +26 -16
  560. package/foundation/response/response-types.doc.test.mjs +158 -0
  561. package/foundation/response/response.doc.mjs +1 -1
  562. package/foundation/text/string-utils.mjs +22 -10
  563. package/foundation/xle/expand.d.mts +2 -0
  564. package/foundation/xle/expand.mjs +4 -3
  565. package/foundation/xle/expand.test.mjs +54 -0
  566. package/foundation/xle/xle.test.mjs +13 -0
  567. package/package.json +10 -11
  568. package/assets/templates/themes/manifest.json +0 -95
  569. package/clients/cli/lib/update-check.mjs +0 -83
  570. package/clients/cli/lib/update-check.test.mjs +0 -137
  571. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -0,0 +1,103 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx discover` text output projects every field of its JSON entry.
5
+ *
6
+ * The text views of `discover.list` and `discover.detail` are renderings of the
7
+ * same entries `--json` returns, so each entry key must appear as a `key:` line
8
+ * carrying the same value.
9
+ */
10
+
11
+ import {describe, it, expect, beforeEach, afterEach} from 'vitest';
12
+ import * as fs from 'node:fs';
13
+ import * as path from 'node:path';
14
+ import * as os from 'node:os';
15
+ import {runCli} from '../../../test-utils/run-cli.mjs';
16
+
17
+ let tmpDir;
18
+ let project;
19
+
20
+ beforeEach(() => {
21
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-discover-text-'));
22
+ project = path.join(tmpDir, 'project');
23
+ const pkgDir = path.join(project, 'node_modules', '@test', 'kit');
24
+ fs.mkdirSync(path.join(pkgDir, 'components'), {recursive: true});
25
+ fs.writeFileSync(
26
+ path.join(project, 'package.json'),
27
+ JSON.stringify({name: 'proj', version: '1.0.0'}),
28
+ );
29
+ fs.writeFileSync(
30
+ path.join(project, 'astryx.config.mjs'),
31
+ `export default {integrations: ['@test/kit']};\n`,
32
+ );
33
+ fs.writeFileSync(
34
+ path.join(pkgDir, 'package.json'),
35
+ JSON.stringify({name: '@test/kit', version: '3.1.4'}),
36
+ );
37
+ fs.writeFileSync(
38
+ path.join(pkgDir, 'astryx.integration.mjs'),
39
+ `export default {components: './components'};\n`,
40
+ );
41
+ for (const name of ['Dial', 'Gauge']) {
42
+ fs.writeFileSync(
43
+ path.join(pkgDir, 'components', `${name}.doc.mjs`),
44
+ `export const docs = {name: '${name}', usage: {description: 'A ${name}.'}};\n`,
45
+ );
46
+ fs.writeFileSync(
47
+ path.join(pkgDir, 'components', `${name}.tsx`),
48
+ `export function ${name}() { return null; }\n`,
49
+ );
50
+ }
51
+ });
52
+
53
+ afterEach(() => {
54
+ fs.rmSync(tmpDir, {recursive: true, force: true});
55
+ });
56
+
57
+ /**
58
+ * @param {Record<string, unknown>} entry
59
+ * @param {string} text
60
+ */
61
+ function expectEveryField(entry, text) {
62
+ const lines = text.split('\n');
63
+ for (const [key, value] of Object.entries(entry)) {
64
+ const rendered = Array.isArray(value) ? value.join(', ') : String(value);
65
+ expect(lines).toContainEqual(
66
+ expect.stringMatching(new RegExp(`^${key}:\\s+${escape(rendered)}$`)),
67
+ );
68
+ }
69
+ }
70
+
71
+ /** @param {string} s */
72
+ function escape(s) {
73
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
74
+ }
75
+
76
+ describe('astryx discover text output', () => {
77
+ it('lists every field of each discover.list entry', async () => {
78
+ const asJson = await runCli(['discover', '--json'], {cwd: project});
79
+ const [entry] = JSON.parse(asJson.stdout).data;
80
+ expect(Object.keys(entry)).toEqual(
81
+ expect.arrayContaining(['name', 'category', 'components', 'version']),
82
+ );
83
+
84
+ const {status, stdout} = await runCli(['discover'], {cwd: project});
85
+
86
+ expect(status).toBe(0);
87
+ expectEveryField(entry, stdout);
88
+ });
89
+
90
+ it('shows every field of the discover.detail entry', async () => {
91
+ const asJson = await runCli(['discover', '@test/kit', '--json'], {
92
+ cwd: project,
93
+ });
94
+ const {data} = JSON.parse(asJson.stdout);
95
+
96
+ const {status, stdout} = await runCli(['discover', '@test/kit'], {
97
+ cwd: project,
98
+ });
99
+
100
+ expect(status).toBe(0);
101
+ expectEveryField(data, stdout);
102
+ });
103
+ });
@@ -12,26 +12,48 @@ export const doc = {
12
12
  type: 'command',
13
13
  name: 'docs',
14
14
  displayName: 'astryx docs',
15
- namespace: 'cli',
15
+ namespace: 'cli/commands',
16
16
  summary: 'Print reference docs',
17
17
  description:
18
- 'Reads the reference docs: with no topic it lists every topic; a topic prints that ' +
19
- 'full doc; a topic plus a section returns the first section whose title contains the ' +
20
- '(case-insensitive) query.',
18
+ 'Reads the reference docs one level at a time: with no topic it lists every topic; a ' +
19
+ 'topic lists its sections, each with the key to read it by (a topic with one section ' +
20
+ 'prints whole); a topic plus a section prints that section; `--full` prints the whole ' +
21
+ 'topic, as does `--dense`. With `--json`, a topic returns its whole doc, as docs() ' +
22
+ 'does, and `--index` its section index. A route ' +
23
+ 'opens a node of the docs tree: `cli` lists its guides and reference, ' +
24
+ '`cli/api/functions` lists every API function, and `cli/api/functions/search` prints ' +
25
+ 'one.',
21
26
  fn: 'docs',
22
27
  args: [
23
28
  {name: 'topic', param: 'topic', required: false},
24
29
  {name: 'section', param: 'section', required: false},
25
30
  ],
31
+ options: [
32
+ {
33
+ flag: '--index',
34
+ param: 'options.index',
35
+ description: "List the topic's sections and their keys, even for a topic with one section",
36
+ },
37
+ {
38
+ flag: '--full',
39
+ description:
40
+ 'Print the whole topic instead of its sections (text; `--json` returns the whole topic unless --index). Cannot be set with --index',
41
+ },
42
+ ],
26
43
  examples: [
27
44
  {label: 'List topics', cli: 'astryx docs'},
28
- {label: 'One topic as JSON', cli: 'astryx docs spacing --json'},
45
+ {label: "A topic's sections", cli: 'astryx docs theme'},
46
+ {label: 'A whole topic as JSON', cli: 'astryx docs spacing --json'},
47
+ {label: 'One section', cli: 'astryx docs theme quick-start'},
48
+ {label: 'The CLI docs tree', cli: 'astryx docs cli'},
49
+ {label: 'One API function', cli: 'astryx docs cli/api/functions/search'},
50
+ {label: 'A whole guide', cli: 'astryx docs cli/integrations --full'},
29
51
  ],
30
52
  exitCodes: [
31
53
  {code: 0, when: 'success'},
32
54
  {
33
55
  code: 1,
34
- when: 'unknown topic, or a section that matches no title in the topic',
56
+ when: 'unknown topic or route, or a section that matches no section or more than one',
35
57
  },
36
58
  ],
37
59
  related: ['search', 'component', 'hook', 'template'],
@@ -3,19 +3,37 @@
3
3
  /**
4
4
  * @file docs command — Print Astryx reference docs
5
5
  *
6
- * Auto-discovers .doc.mjs files from the docs/ directory.
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.
7
10
  * Supports --detail (full|compact|brief) and --lang (en|zh|dense).
8
11
  *
9
12
  * Usage:
10
13
  * astryx docs List available topics
11
- * astryx docs <topic> Print full doc
14
+ * astryx docs <topic> List the topic's sections (a topic
15
+ * with one section prints whole)
12
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
13
20
  */
14
21
 
15
- import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
22
+ import {
23
+ formatCliCommand,
24
+ getCliInvocation,
25
+ } from '../../../foundation/env/package-manager.mjs';
16
26
  import {jsonOut} from '../../../foundation/response/json.mjs';
17
- import {emit, section, records, text, code} from '../formatters/index.mjs';
27
+ import {
28
+ emit,
29
+ section,
30
+ records,
31
+ text,
32
+ code,
33
+ wrapText,
34
+ } from '../formatters/index.mjs';
18
35
  import {cliError} from '../lib/cli-error.mjs';
36
+ import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
19
37
  import {defineCommand} from '../lib/define-command.mjs';
20
38
  import {resultSet} from '../../../foundation/debug/index.mjs';
21
39
  import {docs as docsApi} from '../../../api/docs/docs.mjs';
@@ -80,10 +98,14 @@ function formatBlock(block, detail) {
80
98
  return formatTable(block.headers, block.rows);
81
99
 
82
100
  case 'list': {
83
- const prefix = block.style === 'ordered' ? (/** @type {number} */ i) => `${i + 1}. `
84
- : block.style === 'dont' ? () => 'x '
85
- : block.style === 'do' ? () => '+ '
86
- : () => '- ';
101
+ const prefix =
102
+ block.style === 'ordered'
103
+ ? (/** @type {number} */ i) => `${i + 1}. `
104
+ : block.style === 'dont'
105
+ ? () => 'x '
106
+ : block.style === 'do'
107
+ ? () => '+ '
108
+ : () => '- ';
87
109
  return block.items.map((item, i) => `${prefix(i)}${item}`).join('\n');
88
110
  }
89
111
 
@@ -107,7 +129,8 @@ function formatSection(section, detail) {
107
129
  return `${section.title}: ${first.split('\n')[0]}`;
108
130
  }
109
131
 
110
- const heading = detail === 'compact' ? `[${section.title}]` : `## ${section.title}`;
132
+ const heading =
133
+ detail === 'compact' ? `[${section.title}]` : `## ${section.title}`;
111
134
  return `${heading}\n\n${blocks.join('\n\n')}`;
112
135
  }
113
136
 
@@ -123,22 +146,129 @@ function formatReferenceFull(docs, detail) {
123
146
  return `${header}\n${sections.join('\n')}`;
124
147
  }
125
148
 
126
- const header = detail === 'compact'
127
- ? `# ${docs.title}\n${docs.description}`
128
- : `# ${docs.title}\n\n${docs.description}`;
149
+ const header =
150
+ detail === 'compact'
151
+ ? `# ${docs.title}\n${docs.description}`
152
+ : `# ${docs.title}\n\n${docs.description}`;
129
153
  const sections = docs.sections.map(s => formatSection(s, detail));
130
154
  const sep = detail === 'compact' ? '\n\n' : '\n\n';
131
155
  return `${header}\n\n${sections.join(sep)}`;
132
156
  }
133
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
+
176
+ /**
177
+ * A topic's section index: what the topic is, one line per section with the
178
+ * key to read it by, and how to read further.
179
+ * @param {import('../../../api/docs/docs.type.mjs').DocsIndex} index
180
+ * @param {string} run
181
+ */
182
+ function emitIndex(index, run) {
183
+ emit(
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.
190
+ records(index.sections, {
191
+ fields: ['id', 'title', 'summary'],
192
+ layout: 'inline',
193
+ }),
194
+ text(
195
+ [
196
+ `Read one section: ${run} docs ${index.name} <section>`,
197
+ `Read everything: ${run} docs ${index.name} --full`,
198
+ ...linkLines(index.links),
199
+ ].join('\n'),
200
+ ),
201
+ );
202
+ }
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
+
134
262
  /**
135
263
  * What the run answered with. A named topic (or one of its sections) resolves
136
264
  * or throws, so it is always a direct match of one doc; the bare form lists
137
265
  * every topic there is.
138
266
  *
139
267
  * @param {import('../../../api/docs/docs.type.mjs').DocsListResponse
268
+ * | import('../../../api/docs/docs.type.mjs').DocsIndexResponse
140
269
  * | import('../../../api/docs/docs.type.mjs').DocsDetailResponse
141
- * | 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
142
272
  * @returns {import('../../../foundation/debug/command-result.mjs').CommandResult}
143
273
  */
144
274
  function summarize(result) {
@@ -155,7 +285,11 @@ function summarize(result) {
155
285
  export function registerDocs(program) {
156
286
  defineCommand(program, docsCommand, {
157
287
  fn: docsFn,
158
- action: async (/** @type {string | undefined} */ topic, /** @type {string | undefined} */ sectionName) => {
288
+ action: async (
289
+ /** @type {string | undefined} */ topic,
290
+ /** @type {string | undefined} */ sectionName,
291
+ /** @type {{index?: boolean, full?: boolean}} */ options = {},
292
+ ) => {
159
293
  const run = getCliInvocation();
160
294
  const lang = program.opts().lang || null;
161
295
  const zh = program.opts().zh || false;
@@ -163,13 +297,42 @@ export function registerDocs(program) {
163
297
  const detail = program.opts().detail || 'full';
164
298
  const json = program.opts().json || false;
165
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);
166
316
  let result;
167
317
  try {
168
- result = await docsApi(topic, sectionName, {lang, zh, dense});
318
+ result = await docsApi(topic, sectionName, {
319
+ lang,
320
+ zh,
321
+ dense,
322
+ index: listSections,
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
+ }
169
331
  } catch (e) {
170
332
  // docs API throws structured errors with {name, reason} suggestions —
171
333
  // pass them through untouched so the CLI envelope matches the API.
172
- const err = /** @type {import('../../../api/error.mjs').AstryxError} */ (e);
334
+ const err =
335
+ /** @type {import('../../../api/error.mjs').AstryxError} */ (e);
173
336
  return cliError(err.message, {
174
337
  suggestions: err.suggestions || [],
175
338
  code: err.code,
@@ -184,28 +347,79 @@ export function registerDocs(program) {
184
347
 
185
348
  switch (result.type) {
186
349
  case 'docs.list': {
187
- // The text view mirrors the JSON list: one record per topic (topic +
188
- // 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;
189
356
  emit(
190
- section('Available docs'),
191
- records(result.data, {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'],
369
+ layout: 'inline',
370
+ }),
192
371
  text(
193
372
  [
194
- `Usage: ${run} docs <topic>`,
195
- ` ${run} docs <topic> <section>`,
373
+ `Usage: ${run} docs <topic> list a topic's sections`,
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.`,
196
378
  ].join('\n'),
197
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
+ : []),
198
394
  );
199
395
  break;
200
396
  }
201
397
 
398
+ case 'docs.index': {
399
+ emitIndex(result.data, run);
400
+ break;
401
+ }
402
+
202
403
  case 'docs.detail': {
203
- emit(code(formatReferenceFull(result.data, detail)));
404
+ emit(
405
+ code(formatReferenceFull(result.data, detail)),
406
+ text(linkLines(result.data.links).join('\n')),
407
+ );
204
408
  break;
205
409
  }
206
410
 
207
411
  case 'docs.detail.section': {
208
- 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);
209
423
  break;
210
424
  }
211
425
  }