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

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 (505) hide show
  1. package/README.md +106 -72
  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/component.doc.mjs +13 -3
  10. package/api/component/component.mjs +31 -2
  11. package/api/component/component.test.mjs +38 -0
  12. package/api/component/component.type.d.mts +22 -11
  13. package/api/component/component.type.mjs +32 -24
  14. package/api/component/detail/blocks/blocks.d.mts +2 -1
  15. package/api/component/detail/blocks/blocks.mjs +4 -3
  16. package/api/component/list/list.d.mts +0 -5
  17. package/api/component/list/list.mjs +37 -9
  18. package/api/discover/discover.doc.mjs +2 -1
  19. package/api/discover/discover.type.d.mts +4 -4
  20. package/api/discover/discover.type.mjs +10 -10
  21. package/api/docs/_adapter.d.mts +32 -24
  22. package/api/docs/_adapter.mjs +81 -87
  23. package/api/docs/compiled-topics.test.mjs +78 -0
  24. package/api/docs/detail/detail.mjs +14 -63
  25. package/api/docs/detail/section/section.d.mts +1 -1
  26. package/api/docs/detail/section/section.mjs +44 -20
  27. package/api/docs/detail/section/section.test.mjs +41 -0
  28. package/api/docs/docs.d.mts +7 -2
  29. package/api/docs/docs.doc.mjs +28 -10
  30. package/api/docs/docs.mjs +16 -9
  31. package/api/docs/docs.test.mjs +6 -0
  32. package/api/docs/docs.type.d.mts +40 -3
  33. package/api/docs/docs.type.mjs +36 -8
  34. package/api/docs/index/index.d.mts +18 -0
  35. package/api/docs/index/index.mjs +32 -0
  36. package/api/docs/index/index.test.mjs +62 -0
  37. package/api/docs/integrationDocs.test.mjs +106 -0
  38. package/api/docs/list/list.mjs +3 -7
  39. package/api/doctor/doctor.d.mts +70 -0
  40. package/api/doctor/doctor.doc.mjs +1 -0
  41. package/api/doctor/doctor.mjs +404 -0
  42. package/api/doctor/doctor.test.mjs +522 -1
  43. package/api/gap-report/gap-report.doc.mjs +8 -4
  44. package/api/hook/_adapter.mjs +19 -5
  45. package/api/hook/hook.doc.mjs +1 -0
  46. package/api/hook/hook.type.d.mts +3 -3
  47. package/api/hook/hook.type.mjs +11 -11
  48. package/api/hook/list/list.d.mts +2 -2
  49. package/api/hook/list/list.mjs +69 -17
  50. package/api/init/init.doc.mjs +5 -0
  51. package/api/init/init.test.mjs +41 -1
  52. package/api/init/remove/remove.mjs +1 -1
  53. package/api/init/run/run.mjs +20 -10
  54. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  55. package/api/integration/add-contribution.mjs +23 -10
  56. package/api/integration/add-contribution.test.mjs +121 -7
  57. package/api/integration/add-theme.mjs +34 -64
  58. package/api/integration/add-theme.test.mjs +105 -21
  59. package/api/integration/authoring-checks.test.mjs +8 -4
  60. package/api/integration/integration-authoring.type.d.mts +1 -1
  61. package/api/integration/integration-block-exports.test.mjs +10 -6
  62. package/api/integration/integrationAdd.doc.mjs +8 -4
  63. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  64. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  65. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  66. package/api/integration/integrationAddDoc.doc.mjs +1 -0
  67. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  68. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  69. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  70. package/api/integration/integrationDocConflicts.doc.mjs +1 -0
  71. package/api/integration/integrationPackCheck.doc.mjs +1 -0
  72. package/api/integration/integrationTemplateConflicts.doc.mjs +1 -0
  73. package/api/integration/pack-check.mjs +49 -7
  74. package/api/integration/pack-check.test.mjs +266 -47
  75. package/api/integration/summarizeIssues.doc.mjs +1 -0
  76. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  77. package/api/integration/validate-integration.mjs +52 -102
  78. package/api/integration/validate-integration.test.mjs +176 -23
  79. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  80. package/api/integration/validateIntegration.doc.mjs +2 -1
  81. package/api/json/assertResponse.doc.mjs +1 -0
  82. package/api/json/envelope-types.test.mjs +76 -0
  83. package/api/json/isError.doc.mjs +1 -0
  84. package/api/json/parseResponse.doc.mjs +3 -2
  85. package/api/layout/expand/expand.mjs +7 -5
  86. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  87. package/api/layout/grammar/grammar.mjs +2 -1
  88. package/api/layout/layoutCheck.doc.mjs +1 -0
  89. package/api/layout/layoutExpand.doc.mjs +2 -1
  90. package/api/layout/layoutGrammar.doc.mjs +1 -0
  91. package/api/search/search-return-type.test.mjs +54 -0
  92. package/api/search/search.d.mts +3 -10
  93. package/api/search/search.doc.mjs +6 -1
  94. package/api/search/search.mjs +31 -14
  95. package/api/search/search.test.mjs +34 -0
  96. package/api/search/search.type.d.mts +2 -2
  97. package/api/search/search.type.mjs +1 -1
  98. package/api/swizzle/copy/copy.mjs +28 -11
  99. package/api/swizzle/swizzle.doc.mjs +2 -1
  100. package/api/swizzle/swizzle.type.d.mts +2 -2
  101. package/api/swizzle/swizzle.type.mjs +2 -2
  102. package/api/template/copy/copy.mjs +17 -23
  103. package/api/template/copy/copy.test.mjs +17 -0
  104. package/api/template/template-suffix.test.mjs +41 -21
  105. package/api/template/template.d.mts +1 -1
  106. package/api/template/template.doc.mjs +3 -1
  107. package/api/template/template.type.d.mts +6 -6
  108. package/api/template/template.type.mjs +12 -12
  109. package/api/theme/_adapter.d.mts +2 -3
  110. package/api/theme/_adapter.mjs +4 -5
  111. package/api/theme/add/add.binary.test.mjs +84 -0
  112. package/api/theme/add/add.mjs +20 -3
  113. package/api/theme/add/add.staging.test.mjs +66 -0
  114. package/api/theme/add/add.test.mjs +14 -1
  115. package/api/theme/build/build.mjs +133 -42
  116. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  117. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  118. package/api/theme/build/build.test.mjs +127 -0
  119. package/api/theme/build/font-warning.mjs +3 -3
  120. package/api/theme/build/font-warning.test.mjs +5 -2
  121. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  122. package/api/theme/integration-themes.test.mjs +39 -28
  123. package/api/theme/list/list.test.mjs +19 -20
  124. package/api/theme/listThemes.doc.mjs +6 -5
  125. package/api/theme/palette/generate/generate.mjs +8 -3
  126. package/api/theme/palette/generate/generate.test.mjs +96 -0
  127. package/api/theme/palette/generate/generator.d.mts +10 -13
  128. package/api/theme/palette/generate/generator.mjs +15 -4
  129. package/api/theme/palette/generate/generator.test.mjs +10 -0
  130. package/api/theme/template/template.mjs +11 -2
  131. package/api/theme/template/template.test.mjs +15 -0
  132. package/api/theme/theme.type.d.mts +170 -11
  133. package/api/theme/theme.type.mjs +94 -27
  134. package/api/theme/themeAdd.doc.mjs +4 -3
  135. package/api/theme/themeBuild.doc.mjs +8 -4
  136. package/api/theme/themeList.doc.mjs +6 -3
  137. package/api/theme/themeListAvailable.doc.mjs +5 -3
  138. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  139. package/api/theme/themeTargets.doc.mjs +1 -0
  140. package/api/theme/themeTemplate.doc.mjs +5 -1
  141. package/api/upgrade/_adapter.d.mts +12 -3
  142. package/api/upgrade/_adapter.mjs +123 -19
  143. package/api/upgrade/list/list.mjs +2 -1
  144. package/api/upgrade/list/list.test.mjs +73 -0
  145. package/api/upgrade/project-context.test.mjs +272 -0
  146. package/api/upgrade/provider-agreement.test.mjs +152 -0
  147. package/api/upgrade/run/run.mjs +1 -0
  148. package/api/upgrade/status/status.mjs +2 -2
  149. package/api/upgrade/upgrade.doc.mjs +7 -4
  150. package/api/upgrade/upgrade.type.d.mts +9 -5
  151. package/api/upgrade/upgrade.type.mjs +12 -11
  152. package/assets/codemods/integration-discovery.mjs +48 -4
  153. package/assets/codemods/integration-discovery.test.mjs +73 -0
  154. package/assets/codemods/runner.mjs +115 -5
  155. package/assets/codemods/term-log.mjs +32 -8
  156. package/assets/codemods/term-log.test.mjs +19 -1
  157. package/assets/codemods/transform-prop.mjs +109 -0
  158. package/assets/codemods/transform-prop.test.mjs +95 -0
  159. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +216 -0
  160. package/assets/codemods/transforms/next/index.mjs +11 -1
  161. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  162. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  163. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  164. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  165. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  166. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  167. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  168. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  169. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  170. package/assets/docs/README.md +9 -0
  171. package/assets/docs/authoring.doc.mjs +14 -0
  172. package/assets/docs/cli-integrations.doc.mjs +78 -20
  173. package/assets/docs/cli.doc.mjs +15 -0
  174. package/assets/docs/styling-libraries.doc.mjs +1 -1
  175. package/assets/docs/theme.doc.mjs +1 -1
  176. package/assets/docs/working-with-ai.doc.mjs +1 -1
  177. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  178. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  179. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  180. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  181. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  182. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  183. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  184. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  185. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  186. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  187. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  188. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  189. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  190. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  191. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  192. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  193. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  194. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  195. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  196. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  197. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  198. package/authoring/_shared/contract.ts +22 -0
  199. package/authoring/codemod/codemod.doc.mjs +7 -2
  200. package/authoring/codemod/parse.d.mts +8 -8
  201. package/authoring/codemod/parse.mjs +8 -6
  202. package/authoring/config/config.doc.mjs +2 -2
  203. package/authoring/config/debug-composition.test.mjs +92 -0
  204. package/authoring/config/parse.d.mts +13 -13
  205. package/authoring/config/parse.mjs +8 -8
  206. package/authoring/config/type.ts +18 -6
  207. package/authoring/debug/debug.doc.d.mts +11 -0
  208. package/authoring/debug/debug.doc.mjs +182 -0
  209. package/authoring/debug/parse.d.mts +5 -5
  210. package/authoring/debug/parse.mjs +3 -3
  211. package/authoring/doctypes/_schema.d.mts +788 -23
  212. package/authoring/doctypes/_schema.mjs +492 -39
  213. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  214. package/authoring/doctypes/base/graph-fields.doc.mjs +62 -0
  215. package/authoring/doctypes/base/type.ts +40 -0
  216. package/authoring/doctypes/command/command.doc.mjs +4 -3
  217. package/authoring/doctypes/command/parse.d.mts +2 -2
  218. package/authoring/doctypes/command/parse.mjs +1 -1
  219. package/authoring/doctypes/command/type.ts +4 -3
  220. package/authoring/doctypes/component/component.doc.mjs +6 -3
  221. package/authoring/doctypes/component/parse.d.mts +2 -2
  222. package/authoring/doctypes/component/parse.mjs +1 -1
  223. package/authoring/doctypes/component/type.ts +6 -5
  224. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  225. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  226. package/authoring/doctypes/enum/parse.d.mts +2 -2
  227. package/authoring/doctypes/enum/parse.mjs +1 -1
  228. package/authoring/doctypes/enum/type.ts +4 -2
  229. package/authoring/doctypes/function/function.doc.mjs +5 -1
  230. package/authoring/doctypes/function/parse.d.mts +2 -2
  231. package/authoring/doctypes/function/parse.mjs +1 -1
  232. package/authoring/doctypes/function/type.ts +7 -3
  233. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  234. package/authoring/doctypes/hook/parse.d.mts +2 -2
  235. package/authoring/doctypes/hook/parse.mjs +1 -1
  236. package/authoring/doctypes/hook/type.ts +5 -4
  237. package/authoring/doctypes/legacy.d.mts +8 -6
  238. package/authoring/doctypes/legacy.mjs +5 -4
  239. package/authoring/doctypes/load-contract.test.mjs +208 -0
  240. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  241. package/authoring/doctypes/namespace/namespace.doc.mjs +132 -0
  242. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  243. package/authoring/doctypes/namespace/parse.mjs +25 -0
  244. package/authoring/doctypes/namespace/parse.test.mjs +165 -0
  245. package/authoring/doctypes/namespace/type.ts +71 -0
  246. package/authoring/doctypes/parse.d.mts +22 -18
  247. package/authoring/doctypes/parse.mjs +22 -12
  248. package/authoring/doctypes/parse.test.mjs +77 -3
  249. package/authoring/doctypes/reference/parse.d.mts +2 -2
  250. package/authoring/doctypes/reference/parse.mjs +8 -5
  251. package/authoring/doctypes/reference/reference.doc.mjs +18 -5
  252. package/authoring/doctypes/reference/type.ts +53 -7
  253. package/authoring/doctypes/schema/parse.d.mts +2 -2
  254. package/authoring/doctypes/schema/parse.mjs +1 -1
  255. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  256. package/authoring/doctypes/schema/type.ts +4 -4
  257. package/authoring/doctypes/template/parse.d.mts +92 -1
  258. package/authoring/doctypes/template/parse.mjs +36 -2
  259. package/authoring/doctypes/template/parse.test.mjs +8 -2
  260. package/authoring/doctypes/template/template.doc.mjs +7 -3
  261. package/authoring/doctypes/template/type.ts +5 -2
  262. package/authoring/doctypes/theme/parse.d.mts +35 -0
  263. package/authoring/doctypes/theme/parse.mjs +76 -0
  264. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  265. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  266. package/authoring/doctypes/theme/type.ts +42 -0
  267. package/authoring/doctypes/types.ts +12 -10
  268. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  269. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  270. package/authoring/gap-report/parse.d.mts +10 -10
  271. package/authoring/gap-report/parse.mjs +6 -6
  272. package/authoring/gap-report/type.ts +1 -1
  273. package/authoring/identity/identity.doc.d.mts +9 -0
  274. package/authoring/identity/identity.doc.mjs +61 -0
  275. package/authoring/identity/type.ts +132 -0
  276. package/authoring/index.d.mts +2 -0
  277. package/authoring/index.d.ts +51 -17
  278. package/authoring/index.mjs +3 -1
  279. package/authoring/integration/integration.doc.mjs +15 -8
  280. package/authoring/integration/parse.d.mts +2 -2
  281. package/authoring/integration/parse.mjs +1 -1
  282. package/authoring/integration/parse.test.mjs +10 -1
  283. package/authoring/integration/schema.d.mts +6 -4
  284. package/authoring/integration/schema.mjs +9 -3
  285. package/authoring/integration/type.ts +18 -7
  286. package/authoring/shadcn/receipt.d.mts +6 -6
  287. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  288. package/clients/cli/command-load-failure.test.mjs +83 -0
  289. package/clients/cli/commands/blog.doc.mjs +1 -1
  290. package/clients/cli/commands/blog.mjs +23 -8
  291. package/clients/cli/commands/blog.test.mjs +42 -1
  292. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  293. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  294. package/clients/cli/commands/build-theme.mjs +5 -5
  295. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  296. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  297. package/clients/cli/commands/build.doc.mjs +5 -2
  298. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  299. package/clients/cli/commands/build.mjs +32 -47
  300. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  301. package/clients/cli/commands/build.text-fields.test.mjs +40 -0
  302. package/clients/cli/commands/component/index.mjs +2 -7
  303. package/clients/cli/commands/component-package.test.mjs +46 -0
  304. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  305. package/clients/cli/commands/component.doc.mjs +1 -1
  306. package/clients/cli/commands/component.test.mjs +19 -0
  307. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  308. package/clients/cli/commands/discover.broken-integration.test.mjs +48 -0
  309. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  310. package/clients/cli/commands/discover.doc.mjs +5 -3
  311. package/clients/cli/commands/discover.mjs +3 -3
  312. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  313. package/clients/cli/commands/docs.doc.mjs +14 -4
  314. package/clients/cli/commands/docs.mjs +121 -21
  315. package/clients/cli/commands/docs.test.mjs +88 -0
  316. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  317. package/clients/cli/commands/doctor-integration-docs.doc.mjs +1 -1
  318. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -1
  319. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  320. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  321. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  322. package/clients/cli/commands/doctor-integration.test.mjs +15 -7
  323. package/clients/cli/commands/doctor.doc.mjs +1 -1
  324. package/clients/cli/commands/doctor.mjs +6 -16
  325. package/clients/cli/commands/doctor.test.mjs +42 -0
  326. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  327. package/clients/cli/commands/gap-report.test.mjs +72 -0
  328. package/clients/cli/commands/hook/index.mjs +7 -17
  329. package/clients/cli/commands/hook.doc.mjs +1 -1
  330. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  331. package/clients/cli/commands/init.doc.mjs +20 -9
  332. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  333. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  334. package/clients/cli/commands/integration-add.doc.mjs +22 -6
  335. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  336. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  337. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  338. package/clients/cli/commands/integration.doc.mjs +1 -1
  339. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  340. package/clients/cli/commands/json-contract.test.mjs +33 -0
  341. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  342. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  343. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  344. package/clients/cli/commands/layout.doc.mjs +3 -3
  345. package/clients/cli/commands/layout.mjs +21 -9
  346. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  347. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  348. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  349. package/clients/cli/commands/manifest.doc.mjs +1 -1
  350. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  351. package/clients/cli/commands/search.doc.mjs +7 -4
  352. package/clients/cli/commands/search.mjs +17 -7
  353. package/clients/cli/commands/search.test.mjs +75 -0
  354. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  355. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  356. package/clients/cli/commands/template.doc.mjs +29 -7
  357. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  358. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  359. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  360. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  361. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  362. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  363. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  364. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  365. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  366. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  367. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  368. package/clients/cli/commands/theme.doc.mjs +1 -1
  369. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  370. package/clients/cli/commands/upgrade.doc.mjs +20 -9
  371. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  372. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  373. package/clients/cli/formatters/index.mjs +162 -1
  374. package/clients/cli/formatters/index.test.mjs +91 -0
  375. package/clients/cli/index.mjs +13 -30
  376. package/clients/cli/latest-version-env.test.mjs +50 -0
  377. package/clients/cli/lib/cli-error.test.mjs +7 -0
  378. package/clients/cli/lib/component-format.mjs +9 -9
  379. package/clients/cli/lib/component-format.test.mjs +1 -1
  380. package/clients/cli/lib/define-command.mjs +32 -6
  381. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  382. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  383. package/clients/cli/lib/hook-format.mjs +19 -10
  384. package/clients/cli/lib/json-shim.mjs +38 -2
  385. package/clients/cli/lib/json-shim.test.mjs +83 -0
  386. package/clients/cli/lib/manifest.d.ts +2 -0
  387. package/clients/cli/lib/manifest.mjs +29 -2
  388. package/clients/cli/lib/manifest.test.mjs +17 -0
  389. package/foundation/agent-docs/agent-docs.d.mts +4 -0
  390. package/foundation/agent-docs/agent-docs.mjs +69 -3
  391. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  392. package/foundation/config/integration-debug.test.mjs +28 -3
  393. package/foundation/config/project-themes.test.mjs +11 -19
  394. package/foundation/config/project.d.mts +8 -0
  395. package/foundation/config/project.mjs +190 -32
  396. package/foundation/config/project.test.mjs +129 -16
  397. package/foundation/discovery/authoring-self-docs.d.mts +75 -0
  398. package/foundation/discovery/authoring-self-docs.mjs +224 -0
  399. package/foundation/discovery/authoring-self-docs.test.mjs +154 -0
  400. package/foundation/discovery/authoring-surface.d.mts +74 -0
  401. package/foundation/discovery/authoring-surface.mjs +525 -0
  402. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  403. package/foundation/discovery/cli-self-docs.d.mts +113 -0
  404. package/foundation/discovery/cli-self-docs.mjs +514 -0
  405. package/foundation/discovery/cli-self-docs.test.mjs +437 -0
  406. package/foundation/discovery/component-discovery.d.mts +1 -1
  407. package/foundation/discovery/component-discovery.mjs +2 -1
  408. package/foundation/discovery/component-loader.d.mts +35 -38
  409. package/foundation/discovery/component-loader.mjs +53 -222
  410. package/foundation/discovery/docs-discovery.d.mts +12 -4
  411. package/foundation/discovery/docs-discovery.mjs +214 -98
  412. package/foundation/discovery/docs-discovery.test.mjs +284 -15
  413. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  414. package/foundation/discovery/docs-output-budget.mjs +50 -0
  415. package/foundation/discovery/docs-section-key.d.mts +98 -0
  416. package/foundation/discovery/docs-section-key.mjs +221 -0
  417. package/foundation/discovery/docs-section-key.test.mjs +224 -0
  418. package/foundation/discovery/template-adapter.d.mts +21 -5
  419. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  420. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  421. package/foundation/discovery/template-adapter.mjs +321 -66
  422. package/foundation/discovery/template-adapter.test.mjs +15 -0
  423. package/foundation/discovery/theme-discovery.d.mts +67 -7
  424. package/foundation/discovery/theme-discovery.mjs +916 -186
  425. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  426. package/foundation/discovery/theming-targets.test.mjs +4 -0
  427. package/foundation/doc-compiler/bundle.d.mts +47 -0
  428. package/foundation/doc-compiler/bundle.mjs +218 -0
  429. package/foundation/doc-compiler/bundle.test.mjs +255 -0
  430. package/foundation/doc-compiler/compile.d.mts +362 -0
  431. package/foundation/doc-compiler/compile.mjs +511 -0
  432. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  433. package/foundation/doc-compiler/diagnostics.mjs +277 -0
  434. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  435. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  436. package/foundation/doc-compiler/import.d.mts +24 -0
  437. package/foundation/doc-compiler/import.mjs +59 -0
  438. package/foundation/doc-compiler/inputs.d.mts +102 -0
  439. package/foundation/doc-compiler/inputs.mjs +286 -0
  440. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  441. package/foundation/doc-compiler/ir.d.mts +22 -0
  442. package/foundation/doc-compiler/ir.mjs +464 -0
  443. package/foundation/doc-compiler/lenses.d.mts +33 -0
  444. package/foundation/doc-compiler/lenses.mjs +127 -0
  445. package/foundation/doc-compiler/lower-doc.test.mjs +492 -0
  446. package/foundation/doc-compiler/overlays.d.mts +37 -0
  447. package/foundation/doc-compiler/overlays.mjs +206 -0
  448. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  449. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  450. package/foundation/doc-compiler/read.d.mts +126 -0
  451. package/foundation/doc-compiler/read.mjs +320 -0
  452. package/foundation/doc-compiler/read.test.mjs +313 -0
  453. package/foundation/doc-compiler/source.d.mts +33 -0
  454. package/foundation/doc-compiler/source.mjs +128 -0
  455. package/foundation/fs/module-loader.d.mts +1 -0
  456. package/foundation/fs/module-loader.mjs +50 -1
  457. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  458. package/foundation/fs/path-safety.d.mts +3 -2
  459. package/foundation/fs/path-safety.mjs +49 -19
  460. package/foundation/fs/path-safety.test.mjs +50 -0
  461. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  462. package/foundation/identity/provider-identity.d.mts +90 -0
  463. package/foundation/identity/provider-identity.mjs +320 -0
  464. package/foundation/identity/provider-identity.test.mjs +254 -0
  465. package/foundation/identity/providers.d.mts +7 -0
  466. package/foundation/identity/providers.mjs +16 -0
  467. package/foundation/integrations/autolink.d.mts +58 -1
  468. package/foundation/integrations/autolink.mjs +143 -45
  469. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  470. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  471. package/foundation/integrations/contribution-inventory.d.mts +1 -1
  472. package/foundation/integrations/contribution-inventory.mjs +17 -20
  473. package/foundation/integrations/contribution-inventory.test.mjs +67 -27
  474. package/foundation/integrations/integration-warnings.mjs +6 -0
  475. package/foundation/integrations/integrations.d.mts +49 -2
  476. package/foundation/integrations/integrations.mjs +81 -8
  477. package/foundation/integrations/integrations.test.mjs +384 -1
  478. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  479. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  480. package/foundation/integrations/provider-resolution.d.mts +152 -0
  481. package/foundation/integrations/provider-resolution.mjs +576 -0
  482. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  483. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  484. package/foundation/integrations/theme-descriptor.mjs +44 -0
  485. package/foundation/integrations/validate-contributions.d.mts +2 -0
  486. package/foundation/integrations/validate-contributions.mjs +114 -10
  487. package/foundation/response/base.d.ts +8 -4
  488. package/foundation/response/error-codes.doc.mjs +3 -4
  489. package/foundation/response/error-codes.mjs +2 -2
  490. package/foundation/response/error-codes.test.mjs +83 -0
  491. package/foundation/response/json-contract.test.mjs +57 -17
  492. package/foundation/response/json.d.mts +4 -2
  493. package/foundation/response/json.mjs +8 -10
  494. package/foundation/response/response-types.doc.mjs +16 -11
  495. package/foundation/response/response-types.doc.test.mjs +158 -0
  496. package/foundation/response/response.doc.mjs +1 -1
  497. package/foundation/text/string-utils.mjs +22 -10
  498. package/foundation/xle/expand.d.mts +2 -0
  499. package/foundation/xle/expand.mjs +3 -2
  500. package/foundation/xle/expand.test.mjs +54 -0
  501. package/package.json +9 -11
  502. package/assets/templates/themes/manifest.json +0 -95
  503. package/clients/cli/lib/update-check.mjs +0 -83
  504. package/clients/cli/lib/update-check.test.mjs +0 -137
  505. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -10,6 +10,7 @@
10
10
  import {describe, it, expect} from 'vitest';
11
11
  import {section} from './section.mjs';
12
12
  import {AstryxError} from '../../../error.mjs';
13
+ import {loadDocsCatalog, lowerTopic} from '../../_adapter.mjs';
13
14
 
14
15
  const SLOW = 30_000;
15
16
 
@@ -39,4 +40,44 @@ describe('docs.detail.section leaf', () => {
39
40
  code: 'ERR_UNKNOWN_SECTION',
40
41
  });
41
42
  }, SLOW);
43
+
44
+ it('reads a section by its stable key', async () => {
45
+ const catalog = await loadDocsCatalog();
46
+ const {doc} = await lowerTopic(catalog, catalog.resolve('theme'));
47
+ const target = doc.sections[doc.sections.length - 1];
48
+ const res = await section('theme', target.id);
49
+ expect(res.data.title).toBe(target.title);
50
+ expect(res.data.id).toBe(target.id);
51
+ }, SLOW);
52
+
53
+ it('refuses a query that matches more than one section', async () => {
54
+ const err = await section('theme', 'e').catch(e => e);
55
+ expect(err).toBeInstanceOf(AstryxError);
56
+ expect(err.code).toBe('ERR_UNKNOWN_SECTION');
57
+ expect(err.message).toMatch(/matches \d+ sections/);
58
+ expect(err.suggestions.length).toBeGreaterThan(1);
59
+ }, SLOW);
60
+
61
+ it.each([null, 'zh', 'dense'])(
62
+ 'inlines token refs when a section is read on its own (lang %s)',
63
+ async lang => {
64
+ const catalog = await loadDocsCatalog();
65
+ let checked = 0;
66
+ for (const entry of catalog.entries()) {
67
+ const {doc} = await lowerTopic(catalog, entry);
68
+ for (const own of doc.sections) {
69
+ if (!own.content.some(block => block.type === 'token-ref')) continue;
70
+ const res = await section(entry.name, own.id, lang ? {lang} : {});
71
+ expect(res.data.content.length).toBeGreaterThan(0);
72
+ expect(res.data.content.some(block => block.type === 'token-ref')).toBe(
73
+ false,
74
+ );
75
+ expect(JSON.stringify(res.data.content)).not.toContain('[token-ref:');
76
+ checked += 1;
77
+ }
78
+ }
79
+ expect(checked).toBeGreaterThan(0);
80
+ },
81
+ SLOW,
82
+ );
42
83
  });
@@ -8,9 +8,12 @@
8
8
  * @param {string} [options.lang]
9
9
  * @param {boolean} [options.zh]
10
10
  * @param {boolean} [options.dense]
11
+ * @param {boolean} [options.index] return the topic's section index instead of
12
+ * the whole doc
11
13
  * @param {string} [options.cwd]
12
14
  * @returns {Promise<
13
15
  * import('./docs.type.mjs').DocsListResponse |
16
+ * import('./docs.type.mjs').DocsIndexResponse |
14
17
  * import('./docs.type.mjs').DocsDetailResponse |
15
18
  * import('./docs.type.mjs').DocsDetailSectionResponse
16
19
  * >}
@@ -19,9 +22,11 @@ export function docs(topic?: string, section?: string, options?: {
19
22
  lang?: string | undefined;
20
23
  zh?: boolean | undefined;
21
24
  dense?: boolean | undefined;
25
+ index?: boolean | undefined;
22
26
  cwd?: string | undefined;
23
- }): Promise<import("./docs.type.mjs").DocsListResponse | import("./docs.type.mjs").DocsDetailResponse | import("./docs.type.mjs").DocsDetailSectionResponse>;
27
+ }): Promise<import("./docs.type.mjs").DocsListResponse | import("./docs.type.mjs").DocsIndexResponse | import("./docs.type.mjs").DocsDetailResponse | import("./docs.type.mjs").DocsDetailSectionResponse>;
24
28
  import { list } from './list/list.mjs';
29
+ import { index } from './index/index.mjs';
25
30
  import { detail } from './detail/detail.mjs';
26
31
  import { section as sectionLeaf } from './detail/section/section.mjs';
27
- export { list, detail, sectionLeaf as section };
32
+ export { list, index, detail, sectionLeaf as section };
@@ -11,20 +11,23 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'docs',
14
+ namespace: 'cli/api',
14
15
  displayName: 'docs()',
15
16
  summary:
16
- 'Read the reference docs: list every topic, one topic, or a single section of a topic.',
17
+ 'Read the reference docs: list every topic, one topic\'s sections, one section, or a whole topic.',
17
18
  description:
18
- 'Routes on its arguments: no topic lists every reference-doc topic; a topic ' +
19
- 'returns that full ReferenceDoc (with token-ref blocks inlined); a topic ' +
20
- 'plus a section returns the first section whose title contains the ' +
21
- '(case-insensitive) query. The topic set is the CLI\'s own docs plus the ' +
19
+ 'No topic lists every reference-doc topic; a topic returns that full ' +
20
+ 'ReferenceDoc; `index: true` returns the topic\'s section index instead ' +
21
+ '(each section\'s key, title, and summary); a topic plus a section returns ' +
22
+ 'that one section, found by its key, then its exact title, then a unique ' +
23
+ 'part of its title (an ambiguous query is refused). Token-ref blocks are ' +
24
+ 'inlined in every read. The topic set is the CLI\'s own docs plus the ' +
22
25
  'ones the project\'s configured integrations contribute, including any ' +
23
26
  'topic an integration replaces or extends, so it depends on the cwd. ' +
24
27
  'Overlay options select localized or dense variants.',
25
28
  importPath: '@astryxdesign/cli/api',
26
29
  signature:
27
- 'docs(topic?: string, section?: string, options?: DocsOptions): Promise<DocsListResponse | DocsDetailResponse | DocsDetailSectionResponse>',
30
+ 'docs(topic?: string, section?: string, options?: DocsOptions): Promise<DocsListResponse | DocsIndexResponse | DocsDetailResponse | DocsDetailSectionResponse>',
28
31
  keywords: [
29
32
  'docs',
30
33
  'documentation',
@@ -46,7 +49,7 @@ export const doc = {
46
49
  name: 'section',
47
50
  type: 'string',
48
51
  description:
49
- 'Section within the topic to return; matches the first section title that contains this (case-insensitive).',
52
+ "Section to return: its key (from the topic's index), its title, or a unique part of its title (case-insensitive).",
50
53
  },
51
54
  {
52
55
  name: 'options.lang',
@@ -63,6 +66,12 @@ export const doc = {
63
66
  type: 'boolean',
64
67
  description: 'Return the token-efficient dense doc variant.',
65
68
  },
69
+ {
70
+ name: 'options.index',
71
+ type: 'boolean',
72
+ description:
73
+ "Return the topic's section index (each section's key, title, and summary) instead of the whole doc.",
74
+ },
66
75
  {
67
76
  name: 'options.cwd',
68
77
  type: 'string',
@@ -81,10 +90,15 @@ export const doc = {
81
90
  description:
82
91
  "One topic's full ReferenceDoc, with token-ref blocks inlined.",
83
92
  },
93
+ {
94
+ type: 'docs.index',
95
+ description:
96
+ "One topic's section index (index: true): {name, title, description, sections: [{id, title, summary}]}.",
97
+ },
84
98
  {
85
99
  type: 'docs.detail.section',
86
100
  description:
87
- 'A single ReferenceSection of the topic: the first whose title contains the section query.',
101
+ 'One ReferenceSection of the topic, found by key or title, with token-ref blocks inlined.',
88
102
  },
89
103
  ],
90
104
  throws: [
@@ -94,13 +108,17 @@ export const doc = {
94
108
  },
95
109
  {
96
110
  code: 'ERR_UNKNOWN_SECTION',
97
- when: 'a section is requested but is empty or matches no section title in the topic',
111
+ when: 'a section is requested but is empty, matches no section, or matches more than one',
98
112
  },
99
113
  ],
100
114
  examples: [
101
115
  {label: 'List topics', code: 'const r = await docs();'},
102
116
  {label: 'Load a topic', code: "await docs('principles');"},
103
- {label: 'One section', code: "await docs('tokens', 'spacing');"},
117
+ {
118
+ label: "A topic's sections",
119
+ code: "await docs('principles', undefined, {index: true});",
120
+ },
121
+ {label: 'One section by key', code: "await docs('tokens', 'spacing');"},
104
122
  ],
105
123
  command: 'docs',
106
124
  related: ['search', 'component', 'hook', 'template'],
package/api/docs/docs.mjs CHANGED
@@ -3,24 +3,27 @@
3
3
  /**
4
4
  * @file Programmatic API for the docs command.
5
5
  *
6
- * Dispatcher + barrel. `docs()` routes by argument shape into one of three
6
+ * Dispatcher + barrel. `docs()` routes by argument shape into one of four
7
7
  * leaves, each projecting into a single { type, data } envelope:
8
8
  *
9
- * docs() -> list -> docs.list
10
- * docs(topic) -> detail -> docs.detail
11
- * docs(topic, section) -> section -> docs.detail.section
9
+ * docs() -> list -> docs.list
10
+ * docs(topic) -> detail -> docs.detail
11
+ * docs(topic, undefined, {index: true}) -> index -> docs.index
12
+ * docs(topic, section) -> section -> docs.detail.section
12
13
  *
13
- * The leaves live in list/, detail/, and detail/section/; the discovery,
14
- * overlay loading, and topic resolution they share sit in _adapter.mjs. This
15
- * module keeps the same `docs` export (and re-exports the leaves) so
16
- * api/index.mjs and the CLI consumer import from here unchanged.
14
+ * A topic read returns the whole doc, as it always has. The index is how a
15
+ * reader works progressively instead: list the topic's sections, then read one
16
+ * by its key. The leaves live in list/, index/, detail/, and detail/section/;
17
+ * the discovery, overlay loading, and topic resolution they share sit in
18
+ * _adapter.mjs.
17
19
  */
18
20
 
19
21
  import {list} from './list/list.mjs';
22
+ import {index} from './index/index.mjs';
20
23
  import {detail} from './detail/detail.mjs';
21
24
  import {section as sectionLeaf} from './detail/section/section.mjs';
22
25
 
23
- export {list, detail, sectionLeaf as section};
26
+ export {list, index, detail, sectionLeaf as section};
24
27
 
25
28
  /**
26
29
  * @param {string} [topic]
@@ -29,9 +32,12 @@ export {list, detail, sectionLeaf as section};
29
32
  * @param {string} [options.lang]
30
33
  * @param {boolean} [options.zh]
31
34
  * @param {boolean} [options.dense]
35
+ * @param {boolean} [options.index] return the topic's section index instead of
36
+ * the whole doc
32
37
  * @param {string} [options.cwd]
33
38
  * @returns {Promise<
34
39
  * import('./docs.type.mjs').DocsListResponse |
40
+ * import('./docs.type.mjs').DocsIndexResponse |
35
41
  * import('./docs.type.mjs').DocsDetailResponse |
36
42
  * import('./docs.type.mjs').DocsDetailSectionResponse
37
43
  * >}
@@ -39,5 +45,6 @@ export {list, detail, sectionLeaf as section};
39
45
  export async function docs(topic, section, options = {}) {
40
46
  if (!topic) return list(options);
41
47
  if (section) return sectionLeaf(topic, section, options);
48
+ if (options.index) return index(topic, options);
42
49
  return detail(topic, options);
43
50
  }
@@ -33,6 +33,12 @@ describe('docs() dispatcher routing', () => {
33
33
  expect(r.type).toBe('docs.detail');
34
34
  }, SLOW);
35
35
 
36
+ it('topic + index -> docs.index', async () => {
37
+ const {data} = await docs();
38
+ const r = await docs(data[0].topic, undefined, {index: true});
39
+ expect(r.type).toBe('docs.index');
40
+ }, SLOW);
41
+
36
42
  it('topic + section -> docs.detail.section', async () => {
37
43
  const {data} = await docs();
38
44
  let routed = null;
@@ -2,7 +2,7 @@
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
4
  /**
5
- * xds --json docs
5
+ * astryx --json docs
6
6
  */
7
7
  export type DocsListResponse = {
8
8
  type: "docs.list";
@@ -23,14 +23,46 @@ export type DocsListEntry = {
23
23
  replaces?: string | undefined;
24
24
  };
25
25
  /**
26
- * xds --json docs <topic>
26
+ * astryx --json docs <topic> --index
27
+ */
28
+ export type DocsIndexResponse = {
29
+ type: "docs.index";
30
+ data: DocsIndex;
31
+ };
32
+ /**
33
+ * astryx --json docs <topic>
27
34
  */
28
35
  export type DocsDetailResponse = {
29
36
  type: "docs.detail";
30
37
  data: import("@astryxdesign/cli/authoring").ReferenceDoc;
31
38
  };
32
39
  /**
33
- * xds --json docs <topic> <section>
40
+ * The section index of one topic: what the topic is, and the key each section
41
+ * is read by.
42
+ */
43
+ export type DocsIndex = {
44
+ /**
45
+ * the topic
46
+ */
47
+ name: string;
48
+ title: string;
49
+ description: string;
50
+ sections: DocsIndexSection[];
51
+ };
52
+ export type DocsIndexSection = {
53
+ /**
54
+ * stable key; pass it as the section argument
55
+ */
56
+ id: string;
57
+ title: string;
58
+ /**
59
+ * the section's first line of text, at most 240
60
+ * characters
61
+ */
62
+ summary: string;
63
+ };
64
+ /**
65
+ * astryx --json docs <topic> <section>
34
66
  */
35
67
  export type DocsDetailSectionResponse = {
36
68
  type: "docs.detail.section";
@@ -43,6 +75,11 @@ export type DocsOptions = {
43
75
  lang?: string | undefined;
44
76
  zh?: boolean | undefined;
45
77
  dense?: boolean | undefined;
78
+ /**
79
+ * return a topic's section index instead of its
80
+ * whole doc
81
+ */
82
+ index?: boolean | undefined;
46
83
  /**
47
84
  * project directory whose configured integrations
48
85
  * contribute topics; defaults to process.cwd()
@@ -4,16 +4,17 @@
4
4
  * @file Colocated types for the `docs` command — source of truth for the docs
5
5
  * command JSON responses. `types/docs.d.ts` re-exports these.
6
6
  *
7
- * Invocation -> type discriminator
7
+ * Invocation -> type discriminator
8
8
  * ------------------------------------------------------------
9
- * xds --json docs -> docs.list
10
- * xds --json docs <topic> -> docs.detail
11
- * xds --json docs <topic> <section> -> docs.detail.section
12
- * (unknown topic/section) -> CLIError
9
+ * astryx --json docs -> docs.list
10
+ * astryx --json docs <topic> -> docs.detail
11
+ * astryx --json docs <topic> --index -> docs.index
12
+ * astryx --json docs <topic> <section> -> docs.detail.section
13
+ * (unknown topic/section) -> CLIError
13
14
  */
14
15
 
15
16
  /**
16
- * xds --json docs
17
+ * astryx --json docs
17
18
  * @typedef {object} DocsListResponse
18
19
  * @property {'docs.list'} type
19
20
  * @property {DocsListEntry[]} data
@@ -30,14 +31,39 @@
30
31
  */
31
32
 
32
33
  /**
33
- * xds --json docs <topic>
34
+ * astryx --json docs <topic> --index
35
+ * @typedef {object} DocsIndexResponse
36
+ * @property {'docs.index'} type
37
+ * @property {DocsIndex} data
38
+ */
39
+
40
+ /**
41
+ * astryx --json docs <topic>
34
42
  * @typedef {object} DocsDetailResponse
35
43
  * @property {'docs.detail'} type
36
44
  * @property {import('@astryxdesign/cli/authoring').ReferenceDoc} data
37
45
  */
38
46
 
39
47
  /**
40
- * xds --json docs <topic> <section>
48
+ * The section index of one topic: what the topic is, and the key each section
49
+ * is read by.
50
+ * @typedef {object} DocsIndex
51
+ * @property {string} name the topic
52
+ * @property {string} title
53
+ * @property {string} description
54
+ * @property {DocsIndexSection[]} sections
55
+ */
56
+
57
+ /**
58
+ * @typedef {object} DocsIndexSection
59
+ * @property {string} id stable key; pass it as the section argument
60
+ * @property {string} title
61
+ * @property {string} summary the section's first line of text, at most 240
62
+ * characters
63
+ */
64
+
65
+ /**
66
+ * astryx --json docs <topic> <section>
41
67
  * @typedef {object} DocsDetailSectionResponse
42
68
  * @property {'docs.detail.section'} type
43
69
  * @property {import('@astryxdesign/cli/authoring').ReferenceSection} data
@@ -49,6 +75,8 @@
49
75
  * @property {string} [lang]
50
76
  * @property {boolean} [zh]
51
77
  * @property {boolean} [dense]
78
+ * @property {boolean} [index] return a topic's section index instead of its
79
+ * whole doc
52
80
  * @property {string} [cwd] project directory whose configured integrations
53
81
  * contribute topics; defaults to process.cwd()
54
82
  */
@@ -0,0 +1,18 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * @param {string} topic
6
+ * @param {object} [options]
7
+ * @param {string} [options.lang]
8
+ * @param {boolean} [options.zh]
9
+ * @param {boolean} [options.dense]
10
+ * @param {string} [options.cwd]
11
+ * @returns {Promise<import('../docs.type.mjs').DocsIndexResponse>}
12
+ */
13
+ export function index(topic: string, options?: {
14
+ lang?: string | undefined;
15
+ zh?: boolean | undefined;
16
+ dense?: boolean | undefined;
17
+ cwd?: string | undefined;
18
+ }): Promise<import("../docs.type.mjs").DocsIndexResponse>;
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file docs.index leaf — the section index of one topic.
5
+ *
6
+ * @input A topic name plus optional {lang, zh, dense, cwd}. Resolves the topic
7
+ * via the shared adapter and reads its lowered compiled node; nothing is
8
+ * linked, since the index never inlines a token reference.
9
+ * @output { type: 'docs.index', data: DocsIndex } — the topic's name, title and
10
+ * description and, for each section, the key it is read by, its title, and a
11
+ * one-line summary. Matches `astryx --json docs <topic> --index`.
12
+ * @position Leaf under api/docs: a topic's opt-in progressive read. One section
13
+ * is the section leaf (`docs <topic> <key>`); the whole topic, a plain topic
14
+ * read, is the detail leaf.
15
+ */
16
+
17
+ import {indexView} from '../../../foundation/doc-compiler/lenses.mjs';
18
+ import {resolveTopicDocs} from '../_adapter.mjs';
19
+
20
+ /**
21
+ * @param {string} topic
22
+ * @param {object} [options]
23
+ * @param {string} [options.lang]
24
+ * @param {boolean} [options.zh]
25
+ * @param {boolean} [options.dense]
26
+ * @param {string} [options.cwd]
27
+ * @returns {Promise<import('../docs.type.mjs').DocsIndexResponse>}
28
+ */
29
+ export async function index(topic, options = {}) {
30
+ const {node} = await resolveTopicDocs(topic, options);
31
+ return {type: 'docs.index', data: indexView(node)};
32
+ }
@@ -0,0 +1,62 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import {docs} from '../docs.mjs';
5
+ import {index} from './index.mjs';
6
+ import {loadDocsCatalog} from '../_adapter.mjs';
7
+
8
+ const SLOW = 60_000;
9
+
10
+ describe('docs.index leaf', () => {
11
+ it('lists each section by key, title, and summary', async () => {
12
+ const res = await index('theme');
13
+ expect(res.type).toBe('docs.index');
14
+ expect(res.data).toMatchObject({name: 'theme', title: expect.any(String)});
15
+ const keys = res.data.sections.map(s => s.id);
16
+ expect(new Set(keys).size).toBe(keys.length);
17
+ for (const entry of res.data.sections) {
18
+ expect(Object.keys(entry)).toEqual(['id', 'title', 'summary']);
19
+ expect(entry.summary.length).toBeLessThanOrEqual(240);
20
+ }
21
+ }, SLOW);
22
+
23
+ it('names the sections the full topic has, with the same keys', async () => {
24
+ const full = await docs('theme');
25
+ const {data} = await index('theme');
26
+ expect(data.sections.map(s => [s.id, s.title])).toEqual(
27
+ full.data.sections.map(s => [s.id, s.title]),
28
+ );
29
+ }, SLOW);
30
+
31
+ it('keeps every key the same in every language', async () => {
32
+ const english = (await index('theme')).data.sections.map(s => s.id);
33
+ for (const lang of ['zh', 'dense']) {
34
+ const localized = await index('theme', {lang});
35
+ expect(localized.data.sections.map(s => s.id)).toEqual(english);
36
+ }
37
+ }, SLOW);
38
+
39
+ it('lists keys every section can be read by', async () => {
40
+ const catalog = await loadDocsCatalog();
41
+ for (const entry of catalog.entries()) {
42
+ const {data} = await index(entry.name);
43
+ for (const {id, title} of data.sections) {
44
+ const read = await docs(entry.name, id);
45
+ expect(read.data.title).toBe(title);
46
+ }
47
+ }
48
+ }, SLOW);
49
+ });
50
+
51
+ describe('docs() topic reads', () => {
52
+ it('returns the whole topic by default, as before', async () => {
53
+ const res = await docs('theme');
54
+ expect(res.type).toBe('docs.detail');
55
+ expect(res.data.sections[0].content.length).toBeGreaterThan(0);
56
+ }, SLOW);
57
+
58
+ it('returns the section index on request', async () => {
59
+ const res = await docs('theme', undefined, {index: true});
60
+ expect(res.type).toBe('docs.index');
61
+ }, SLOW);
62
+ });
@@ -177,6 +177,112 @@ describe('integration-contributed topics', () => {
177
177
  expect(extended.data.sections.length).toBe(builtin.data.sections.length + 1);
178
178
  }, SLOW);
179
179
 
180
+ it('migrates a real built-in section to a stable ID without duplicating it', async () => {
181
+ const builtin = await docs('theme');
182
+ // Readers see a key on every section; the migration case is one whose
183
+ // source authors no id.
184
+ const {docs: authored} = await import('../../assets/docs/theme.doc.mjs');
185
+ const target = authored.sections.find(section => section.id == null);
186
+ expect(target).toBeDefined();
187
+ scaffold({
188
+ 'theme-internal.doc.mjs': topic({
189
+ name: 'theme-internal',
190
+ extends: 'theme',
191
+ sections: [
192
+ {
193
+ id: 'acme-theme-setup',
194
+ title: target.title,
195
+ content: [{type: 'prose', text: 'Use the Acme theme.'}],
196
+ },
197
+ ],
198
+ }),
199
+ });
200
+
201
+ const extended = await docs('theme', undefined, {cwd: tmpDir});
202
+ expect(extended.data.sections).toHaveLength(builtin.data.sections.length);
203
+ const matches = extended.data.sections.filter(
204
+ section => section.title === target.title,
205
+ );
206
+ expect(matches).toEqual([
207
+ expect.objectContaining({
208
+ id: 'acme-theme-setup',
209
+ content: [{type: 'prose', text: 'Use the Acme theme.'}],
210
+ }),
211
+ ]);
212
+ }, SLOW);
213
+
214
+ it('replaces a real built-in section by the key its index shows', async () => {
215
+ const index = await docs('theme', undefined, {index: true});
216
+ const target = index.data.sections[0];
217
+ scaffold({
218
+ 'theme-internal.doc.mjs': topic({
219
+ name: 'theme-internal',
220
+ extends: 'theme',
221
+ sections: [
222
+ {
223
+ id: target.id,
224
+ title: `${target.title} with Acme`,
225
+ content: [{type: 'prose', text: 'Acme first.'}],
226
+ },
227
+ ],
228
+ }),
229
+ });
230
+
231
+ const extended = await docs('theme', undefined, {cwd: tmpDir});
232
+ expect(extended.data.sections).toHaveLength(index.data.sections.length);
233
+ expect(extended.data.sections.filter(s => s.id === target.id)).toEqual([
234
+ expect.objectContaining({content: [{type: 'prose', text: 'Acme first.'}]}),
235
+ ]);
236
+ const read = await docs('theme', target.id, {cwd: tmpDir});
237
+ expect(read.data.title).toBe(`${target.title} with Acme`);
238
+ }, SLOW);
239
+
240
+ it.each(['zh', 'dense'])(
241
+ 'replaces translated real sections by their authored titles under --%s',
242
+ async lang => {
243
+ const english = await docs('theme');
244
+ const englishTitles = english.data.sections.map(section => section.title);
245
+ expect(englishTitles).toEqual(
246
+ expect.arrayContaining(['Quick Start', 'Theme Props']),
247
+ );
248
+ scaffold({
249
+ 'theme-internal.doc.mjs': topic({
250
+ name: 'theme-internal',
251
+ extends: 'theme',
252
+ sections: [
253
+ {
254
+ id: 'acme-quick-start',
255
+ title: 'Quick Start',
256
+ content: [{type: 'prose', text: 'Acme quick start.'}],
257
+ },
258
+ {
259
+ title: 'Theme Props',
260
+ content: [{type: 'prose', text: 'Acme props.'}],
261
+ },
262
+ ],
263
+ }),
264
+ });
265
+
266
+ const base = await docs('theme', undefined, {lang});
267
+ expect(base.data.sections.map(section => section.title)).not.toEqual(
268
+ englishTitles,
269
+ );
270
+ const extended = await docs('theme', undefined, {cwd: tmpDir, lang});
271
+ expect(extended.data.sections).toHaveLength(base.data.sections.length);
272
+ expect(
273
+ extended.data.sections.filter(
274
+ section => section.id === 'acme-quick-start',
275
+ ),
276
+ ).toHaveLength(1);
277
+ expect(
278
+ extended.data.sections.filter(
279
+ section => section.content[0]?.text === 'Acme props.',
280
+ ),
281
+ ).toHaveLength(1);
282
+ },
283
+ SLOW,
284
+ );
285
+
180
286
  it('offers the contributed topics as suggestions on an unknown one', async () => {
181
287
  scaffold({'deploying.doc.mjs': topic()});
182
288
  await expect(docs('nope-not-a-topic', undefined, {cwd: tmpDir})).rejects.toBeInstanceOf(
@@ -14,7 +14,7 @@
14
14
  * @position Leaf under api/docs. Sibling of detail; both share _adapter.mjs.
15
15
  */
16
16
 
17
- import {pathToFileURL} from 'node:url';
17
+ import {loadTopicFile} from '../../../foundation/doc-compiler/read.mjs';
18
18
  import {loadDocsCatalog} from '../_adapter.mjs';
19
19
 
20
20
  /**
@@ -29,12 +29,8 @@ export async function list({cwd} = {}) {
29
29
  for (const entry of catalog.entries()) {
30
30
  let description = entry.description ?? '';
31
31
  if (entry.description == null) {
32
- try {
33
- const mod = await import(pathToFileURL(entry.path).href);
34
- description = (mod.docs ?? mod.default)?.description ?? '';
35
- } catch {
36
- description = '';
37
- }
32
+ const file = await loadTopicFile(entry.path, null);
33
+ description = file.doc?.description ?? '';
38
34
  }
39
35
  /** @type {import('../docs.type.mjs').DocsListEntry} */
40
36
  const listed = {