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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (612) hide show
  1. package/README.md +117 -79
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/_adapter.d.mts +50 -0
  4. package/api/build/_adapter.mjs +60 -0
  5. package/api/build/build.doc.mjs +16 -9
  6. package/api/build/build.test.mjs +197 -8
  7. package/api/build/build.type.d.mts +91 -2
  8. package/api/build/build.type.mjs +52 -8
  9. package/api/build/help/help.d.mts +12 -5
  10. package/api/build/help/help.mjs +69 -6
  11. package/api/build/kit/kit.d.mts +4 -1
  12. package/api/build/kit/kit.mjs +165 -49
  13. package/api/build/kit/rank.d.mts +44 -0
  14. package/api/build/kit/rank.mjs +432 -0
  15. package/api/build/kit/rank.test.mjs +196 -0
  16. package/api/component/_adapter.d.mts +6 -12
  17. package/api/component/_adapter.mjs +20 -10
  18. package/api/component/component.doc.mjs +13 -3
  19. package/api/component/component.mjs +91 -14
  20. package/api/component/component.test.mjs +38 -0
  21. package/api/component/component.type.d.mts +22 -11
  22. package/api/component/component.type.mjs +32 -24
  23. package/api/component/detail/blocks/blocks.d.mts +2 -1
  24. package/api/component/detail/blocks/blocks.mjs +4 -3
  25. package/api/component/list/list.d.mts +0 -5
  26. package/api/component/list/list.mjs +40 -11
  27. package/api/discover/_adapter.d.mts +114 -6
  28. package/api/discover/_adapter.mjs +372 -17
  29. package/api/discover/_adapter.test.mjs +215 -0
  30. package/api/discover/_catalog-view.d.mts +115 -0
  31. package/api/discover/_catalog-view.mjs +203 -0
  32. package/api/discover/_catalog-view.test.mjs +128 -0
  33. package/api/discover/detail/detail.d.mts +18 -6
  34. package/api/discover/detail/detail.mjs +67 -13
  35. package/api/discover/detail/detail.test.mjs +85 -0
  36. package/api/discover/detail/item/item.d.mts +26 -0
  37. package/api/discover/detail/item/item.mjs +78 -0
  38. package/api/discover/detail/item/item.test.mjs +73 -0
  39. package/api/discover/discover.d.mts +3 -9
  40. package/api/discover/discover.doc.mjs +62 -18
  41. package/api/discover/discover.mjs +220 -36
  42. package/api/discover/discover.test.mjs +11 -2
  43. package/api/discover/discover.type.d.mts +150 -11
  44. package/api/discover/discover.type.mjs +107 -17
  45. package/api/discover/list/list.d.mts +20 -6
  46. package/api/discover/list/list.mjs +45 -12
  47. package/api/discover/list/list.test.mjs +46 -0
  48. package/api/discover/search/search.d.mts +18 -16
  49. package/api/discover/search/search.mjs +102 -56
  50. package/api/discover/search/search.test.mjs +144 -10
  51. package/api/docs/_adapter.d.mts +268 -47
  52. package/api/docs/_adapter.mjs +970 -149
  53. package/api/docs/compiled-topics.test.mjs +78 -0
  54. package/api/docs/detail/detail.d.mts +0 -15
  55. package/api/docs/detail/detail.mjs +22 -78
  56. package/api/docs/detail/section/section.mjs +39 -24
  57. package/api/docs/detail/section/section.test.mjs +19 -9
  58. package/api/docs/docs.d.mts +5 -3
  59. package/api/docs/docs.doc.mjs +39 -17
  60. package/api/docs/docs.mjs +44 -8
  61. package/api/docs/docs.test.mjs +158 -4
  62. package/api/docs/docs.type.d.mts +185 -6
  63. package/api/docs/docs.type.mjs +127 -13
  64. package/api/docs/index/index.mjs +15 -6
  65. package/api/docs/index/index.test.mjs +1 -1
  66. package/api/docs/integration-tree.test.mjs +555 -0
  67. package/api/docs/integrationDocs.test.mjs +14 -14
  68. package/api/docs/list/list.mjs +28 -12
  69. package/api/docs/node/node.d.mts +43 -0
  70. package/api/docs/node/node.mjs +192 -0
  71. package/api/docs/reference-blocks.test.mjs +406 -0
  72. package/api/doctor/doctor.d.mts +54 -4
  73. package/api/doctor/doctor.doc.mjs +1 -0
  74. package/api/doctor/doctor.mjs +332 -21
  75. package/api/doctor/doctor.test.mjs +420 -7
  76. package/api/gap-report/gap-report.doc.mjs +8 -4
  77. package/api/hook/_adapter.mjs +19 -5
  78. package/api/hook/hook.doc.mjs +1 -0
  79. package/api/hook/hook.type.d.mts +3 -3
  80. package/api/hook/hook.type.mjs +11 -11
  81. package/api/hook/list/list.d.mts +1 -1
  82. package/api/hook/list/list.mjs +69 -17
  83. package/api/index.d.mts +1 -1
  84. package/api/index.mjs +1 -0
  85. package/api/init/init.doc.mjs +6 -1
  86. package/api/init/init.test.mjs +41 -1
  87. package/api/init/remove/remove.mjs +1 -1
  88. package/api/init/run/run.mjs +20 -10
  89. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  90. package/api/integration/add-contribution.d.mts +2 -1
  91. package/api/integration/add-contribution.mjs +130 -15
  92. package/api/integration/add-contribution.test.mjs +258 -7
  93. package/api/integration/add-helpers.d.mts +5 -2
  94. package/api/integration/add-helpers.mjs +36 -9
  95. package/api/integration/add-theme.mjs +34 -64
  96. package/api/integration/add-theme.test.mjs +105 -21
  97. package/api/integration/authoring-checks.mjs +138 -28
  98. package/api/integration/authoring-checks.test.mjs +179 -7
  99. package/api/integration/authoring-checks.type.mjs +6 -1
  100. package/api/integration/integration-authoring.type.d.mts +2 -0
  101. package/api/integration/integration-authoring.type.mjs +2 -0
  102. package/api/integration/integration-block-exports.test.mjs +10 -6
  103. package/api/integration/integrationAdd.doc.mjs +14 -4
  104. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  105. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  106. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  107. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  108. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  109. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  110. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  111. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  112. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  113. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  114. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  115. package/api/integration/pack-check.mjs +83 -7
  116. package/api/integration/pack-check.test.mjs +387 -47
  117. package/api/integration/pack-check.type.d.mts +26 -2
  118. package/api/integration/pack-check.type.mjs +14 -1
  119. package/api/integration/summarizeIssues.doc.mjs +1 -0
  120. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  121. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  122. package/api/integration/validate-integration.mjs +52 -102
  123. package/api/integration/validate-integration.test.mjs +179 -26
  124. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  125. package/api/integration/validateIntegration.doc.mjs +3 -2
  126. package/api/json/assertResponse.doc.mjs +1 -0
  127. package/api/json/envelope-types.test.mjs +76 -0
  128. package/api/json/index.ts +2 -0
  129. package/api/json/isError.doc.mjs +1 -0
  130. package/api/json/parseResponse.doc.mjs +3 -2
  131. package/api/layout/_adapter.mjs +20 -5
  132. package/api/layout/expand/expand.mjs +7 -5
  133. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  134. package/api/layout/grammar/grammar.mjs +2 -1
  135. package/api/layout/layoutCheck.doc.mjs +1 -0
  136. package/api/layout/layoutExpand.doc.mjs +2 -1
  137. package/api/layout/layoutGrammar.doc.mjs +1 -0
  138. package/api/search/search-return-type.test.mjs +54 -0
  139. package/api/search/search.d.mts +61 -10
  140. package/api/search/search.doc.mjs +8 -2
  141. package/api/search/search.mjs +471 -83
  142. package/api/search/search.test.mjs +124 -1
  143. package/api/search/search.type.d.mts +14 -2
  144. package/api/search/search.type.mjs +5 -2
  145. package/api/swizzle/copy/copy.mjs +28 -11
  146. package/api/swizzle/swizzle.doc.mjs +2 -1
  147. package/api/swizzle/swizzle.type.d.mts +2 -2
  148. package/api/swizzle/swizzle.type.mjs +2 -2
  149. package/api/template/copy/copy.mjs +17 -23
  150. package/api/template/copy/copy.test.mjs +17 -0
  151. package/api/template/list/list.mjs +1 -0
  152. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  153. package/api/template/template-integration.test.mjs +1072 -3
  154. package/api/template/template-suffix.test.mjs +41 -21
  155. package/api/template/template.doc.mjs +30 -8
  156. package/api/template/template.mjs +45 -8
  157. package/api/template/template.type.d.mts +11 -13
  158. package/api/template/template.type.mjs +15 -14
  159. package/api/theme/_adapter.d.mts +2 -3
  160. package/api/theme/_adapter.mjs +4 -5
  161. package/api/theme/add/add.binary.test.mjs +84 -0
  162. package/api/theme/add/add.mjs +31 -22
  163. package/api/theme/add/add.rollback.test.mjs +158 -0
  164. package/api/theme/add/add.staging.test.mjs +83 -0
  165. package/api/theme/add/add.test.mjs +14 -1
  166. package/api/theme/build/build.family.test.mjs +7 -12
  167. package/api/theme/build/build.mjs +140 -59
  168. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  169. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  170. package/api/theme/build/build.rollback.test.mjs +148 -0
  171. package/api/theme/build/build.test.mjs +127 -0
  172. package/api/theme/build/font-warning.mjs +3 -3
  173. package/api/theme/build/font-warning.test.mjs +5 -2
  174. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  175. package/api/theme/integration-themes.test.mjs +39 -28
  176. package/api/theme/list/list.test.mjs +19 -20
  177. package/api/theme/listThemes.doc.mjs +6 -5
  178. package/api/theme/palette/generate/generate.mjs +8 -3
  179. package/api/theme/palette/generate/generate.test.mjs +96 -0
  180. package/api/theme/palette/generate/generator.d.mts +10 -13
  181. package/api/theme/palette/generate/generator.mjs +15 -4
  182. package/api/theme/palette/generate/generator.test.mjs +10 -0
  183. package/api/theme/template/template.mjs +11 -2
  184. package/api/theme/template/template.test.mjs +20 -0
  185. package/api/theme/theme.type.d.mts +170 -11
  186. package/api/theme/theme.type.mjs +94 -27
  187. package/api/theme/themeAdd.doc.mjs +4 -3
  188. package/api/theme/themeBuild.doc.mjs +8 -4
  189. package/api/theme/themeList.doc.mjs +6 -3
  190. package/api/theme/themeListAvailable.doc.mjs +5 -3
  191. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  192. package/api/theme/themeTargets.doc.mjs +1 -0
  193. package/api/theme/themeTemplate.doc.mjs +6 -2
  194. package/api/upgrade/_adapter.d.mts +32 -5
  195. package/api/upgrade/_adapter.mjs +124 -73
  196. package/api/upgrade/list/list.mjs +2 -1
  197. package/api/upgrade/list/list.test.mjs +73 -0
  198. package/api/upgrade/provider-agreement.test.mjs +152 -0
  199. package/api/upgrade/run/run.mjs +356 -59
  200. package/api/upgrade/status/status.mjs +2 -2
  201. package/api/upgrade/upgrade.doc.mjs +8 -2
  202. package/api/upgrade/upgrade.type.d.mts +42 -4
  203. package/api/upgrade/upgrade.type.mjs +26 -10
  204. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  205. package/assets/codemods/integration-discovery.mjs +48 -4
  206. package/assets/codemods/integration-discovery.test.mjs +73 -0
  207. package/assets/codemods/integration-runner.mjs +56 -4
  208. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  209. package/assets/codemods/run-codemod.mjs +177 -34
  210. package/assets/codemods/runner.mjs +350 -102
  211. package/assets/codemods/term-log.mjs +32 -8
  212. package/assets/codemods/term-log.test.mjs +19 -1
  213. package/assets/codemods/transform-prop.mjs +109 -0
  214. package/assets/codemods/transform-prop.test.mjs +95 -0
  215. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  216. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  217. package/assets/codemods/transforms/next/index.mjs +19 -1
  218. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  219. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  220. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  221. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  222. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  223. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  224. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  225. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  226. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  227. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  228. package/assets/docs/getting-started.doc.mjs +2 -2
  229. package/assets/docs/internationalization.doc.mjs +7 -5
  230. package/assets/docs/layout.doc.dense.mjs +2 -2
  231. package/assets/docs/layout.doc.mjs +1 -1
  232. package/assets/docs/principles.doc.mjs +6 -6
  233. package/assets/docs/styling-libraries.doc.mjs +4 -4
  234. package/assets/docs/styling.doc.mjs +4 -4
  235. package/assets/docs/theme.doc.mjs +5 -5
  236. package/assets/docs/tokens.doc.mjs +1 -1
  237. package/assets/docs/tree/api.doc.mjs +30 -0
  238. package/assets/docs/tree/cli.doc.mjs +23 -0
  239. package/assets/docs/tree/commands.doc.mjs +25 -0
  240. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +95 -39
  241. package/assets/docs/tree/integrations.test.mjs +62 -0
  242. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  243. package/assets/docs/working-with-ai.doc.mjs +4 -4
  244. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  245. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  246. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  247. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  248. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  249. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  250. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  251. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  252. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  253. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  254. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  255. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  256. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  257. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  258. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  259. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  260. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  261. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  262. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  263. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  264. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  265. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  266. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  267. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  268. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  269. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  270. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  271. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  272. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  273. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  274. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  275. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  276. package/authoring/_shared/contract.ts +22 -0
  277. package/authoring/codemod/codemod.doc.mjs +7 -2
  278. package/authoring/codemod/parse.d.mts +8 -8
  279. package/authoring/codemod/parse.mjs +8 -6
  280. package/authoring/codemod/type.ts +12 -0
  281. package/authoring/config/config.doc.mjs +10 -2
  282. package/authoring/config/debug-composition.test.mjs +92 -0
  283. package/authoring/config/parse.d.mts +15 -13
  284. package/authoring/config/parse.mjs +27 -8
  285. package/authoring/config/parse.test.mjs +8 -0
  286. package/authoring/config/type.ts +29 -6
  287. package/authoring/debug/debug.doc.d.mts +11 -0
  288. package/authoring/debug/debug.doc.mjs +182 -0
  289. package/authoring/debug/parse.d.mts +7 -7
  290. package/authoring/debug/parse.mjs +3 -3
  291. package/authoring/discover/discover.doc.d.mts +13 -0
  292. package/authoring/discover/discover.doc.mjs +138 -0
  293. package/authoring/discover/parse.d.mts +24 -0
  294. package/authoring/discover/parse.mjs +128 -0
  295. package/authoring/discover/parse.test.mjs +124 -0
  296. package/authoring/discover/type.ts +87 -0
  297. package/authoring/doctypes/_schema.d.mts +240 -128
  298. package/authoring/doctypes/_schema.mjs +198 -16
  299. package/authoring/doctypes/base/graph-fields.doc.mjs +15 -6
  300. package/authoring/doctypes/base/type.ts +9 -4
  301. package/authoring/doctypes/command/command.doc.mjs +4 -3
  302. package/authoring/doctypes/command/parse.d.mts +2 -2
  303. package/authoring/doctypes/command/parse.mjs +1 -1
  304. package/authoring/doctypes/command/type.ts +4 -4
  305. package/authoring/doctypes/component/component.doc.mjs +5 -2
  306. package/authoring/doctypes/component/parse.d.mts +2 -2
  307. package/authoring/doctypes/component/parse.mjs +1 -1
  308. package/authoring/doctypes/component/type.ts +3 -3
  309. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  310. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  311. package/authoring/doctypes/enum/parse.d.mts +2 -2
  312. package/authoring/doctypes/enum/parse.mjs +1 -1
  313. package/authoring/doctypes/enum/type.ts +2 -2
  314. package/authoring/doctypes/function/function.doc.mjs +7 -2
  315. package/authoring/doctypes/function/parse.d.mts +2 -2
  316. package/authoring/doctypes/function/parse.mjs +1 -1
  317. package/authoring/doctypes/function/type.ts +4 -3
  318. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  319. package/authoring/doctypes/hook/parse.d.mts +2 -2
  320. package/authoring/doctypes/hook/parse.mjs +1 -1
  321. package/authoring/doctypes/hook/type.ts +3 -3
  322. package/authoring/doctypes/legacy.d.mts +6 -6
  323. package/authoring/doctypes/legacy.mjs +3 -3
  324. package/authoring/doctypes/load-contract.test.mjs +233 -0
  325. package/authoring/doctypes/namespace/namespace.doc.mjs +9 -9
  326. package/authoring/doctypes/namespace/parse.d.mts +2 -2
  327. package/authoring/doctypes/namespace/parse.mjs +1 -1
  328. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  329. package/authoring/doctypes/namespace/type.ts +6 -3
  330. package/authoring/doctypes/parse.d.mts +22 -20
  331. package/authoring/doctypes/parse.mjs +19 -14
  332. package/authoring/doctypes/reference/parse.d.mts +2 -2
  333. package/authoring/doctypes/reference/parse.mjs +1 -1
  334. package/authoring/doctypes/reference/reference.doc.mjs +39 -6
  335. package/authoring/doctypes/reference/type.ts +31 -14
  336. package/authoring/doctypes/schema/parse.d.mts +2 -2
  337. package/authoring/doctypes/schema/parse.mjs +1 -1
  338. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  339. package/authoring/doctypes/schema/type.ts +3 -4
  340. package/authoring/doctypes/template/parse.d.mts +94 -1
  341. package/authoring/doctypes/template/parse.mjs +37 -1
  342. package/authoring/doctypes/template/parse.test.mjs +18 -0
  343. package/authoring/doctypes/template/template.doc.mjs +13 -3
  344. package/authoring/doctypes/template/type.ts +12 -1
  345. package/authoring/doctypes/theme/parse.d.mts +35 -0
  346. package/authoring/doctypes/theme/parse.mjs +76 -0
  347. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  348. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  349. package/authoring/doctypes/theme/type.ts +42 -0
  350. package/authoring/doctypes/types.ts +12 -11
  351. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  352. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  353. package/authoring/gap-report/parse.d.mts +9 -9
  354. package/authoring/gap-report/parse.mjs +6 -6
  355. package/authoring/gap-report/type.ts +1 -1
  356. package/authoring/identity/identity.doc.mjs +3 -2
  357. package/authoring/identity/type.ts +10 -10
  358. package/authoring/index.d.mts +2 -0
  359. package/authoring/index.d.ts +32 -19
  360. package/authoring/index.mjs +3 -1
  361. package/authoring/integration/integration.doc.mjs +2 -2
  362. package/authoring/integration/parse.d.mts +2 -2
  363. package/authoring/integration/parse.mjs +1 -1
  364. package/authoring/integration/schema.d.mts +4 -4
  365. package/authoring/integration/schema.mjs +3 -3
  366. package/authoring/integration/type.ts +5 -11
  367. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  368. package/clients/cli/command-load-failure.test.mjs +83 -0
  369. package/clients/cli/commands/blog.doc.mjs +1 -1
  370. package/clients/cli/commands/blog.mjs +23 -8
  371. package/clients/cli/commands/blog.test.mjs +42 -1
  372. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  373. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  374. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  375. package/clients/cli/commands/build-theme.mjs +16 -50
  376. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  377. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  378. package/clients/cli/commands/build.doc.mjs +16 -8
  379. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  380. package/clients/cli/commands/build.mjs +137 -114
  381. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  382. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  383. package/clients/cli/commands/component/index.mjs +3 -8
  384. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  385. package/clients/cli/commands/component-package.test.mjs +46 -0
  386. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  387. package/clients/cli/commands/component.doc.mjs +1 -1
  388. package/clients/cli/commands/component.test.mjs +19 -0
  389. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  390. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  391. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  392. package/clients/cli/commands/discover.doc.mjs +55 -9
  393. package/clients/cli/commands/discover.mjs +393 -118
  394. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  395. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  396. package/clients/cli/commands/docs.doc.mjs +21 -9
  397. package/clients/cli/commands/docs.mjs +184 -70
  398. package/clients/cli/commands/docs.test.mjs +120 -16
  399. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  400. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  401. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  402. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  403. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  404. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  405. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  406. package/clients/cli/commands/doctor.doc.mjs +1 -1
  407. package/clients/cli/commands/doctor.mjs +59 -32
  408. package/clients/cli/commands/doctor.test.mjs +42 -0
  409. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  410. package/clients/cli/commands/gap-report.test.mjs +72 -0
  411. package/clients/cli/commands/hook/index.mjs +7 -17
  412. package/clients/cli/commands/hook.doc.mjs +1 -1
  413. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  414. package/clients/cli/commands/init.doc.mjs +20 -9
  415. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  416. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  417. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  418. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  419. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  420. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  421. package/clients/cli/commands/integration.doc.mjs +1 -1
  422. package/clients/cli/commands/integration.mjs +1 -0
  423. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  424. package/clients/cli/commands/json-contract.test.mjs +33 -0
  425. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  426. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  427. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  428. package/clients/cli/commands/layout.doc.mjs +3 -3
  429. package/clients/cli/commands/layout.mjs +21 -9
  430. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  431. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  432. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  433. package/clients/cli/commands/manifest.doc.mjs +1 -1
  434. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  435. package/clients/cli/commands/search.doc.mjs +7 -4
  436. package/clients/cli/commands/search.mjs +28 -9
  437. package/clients/cli/commands/search.test.mjs +75 -0
  438. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  439. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  440. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  441. package/clients/cli/commands/template.doc.mjs +52 -13
  442. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  443. package/clients/cli/commands/template.mjs +4 -91
  444. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  445. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  446. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  447. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  448. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  449. package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
  450. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  451. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  452. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  453. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  454. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  455. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  456. package/clients/cli/commands/theme.doc.mjs +1 -1
  457. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  458. package/clients/cli/commands/upgrade.doc.mjs +20 -8
  459. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  460. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  461. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  462. package/clients/cli/commands/upgrade.mjs +29 -7
  463. package/clients/cli/formatters/index.mjs +2 -0
  464. package/clients/cli/formatters/index.test.mjs +6 -0
  465. package/clients/cli/index.mjs +21 -30
  466. package/clients/cli/latest-version-env.test.mjs +50 -0
  467. package/clients/cli/lib/cli-error.test.mjs +7 -0
  468. package/clients/cli/lib/component-format.mjs +9 -9
  469. package/clients/cli/lib/component-format.test.mjs +1 -1
  470. package/clients/cli/lib/define-command.mjs +32 -6
  471. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  472. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  473. package/clients/cli/lib/hook-format.mjs +19 -10
  474. package/clients/cli/lib/json-shim.mjs +38 -2
  475. package/clients/cli/lib/json-shim.test.mjs +83 -0
  476. package/clients/cli/lib/manifest.d.ts +2 -0
  477. package/clients/cli/lib/manifest.mjs +32 -2
  478. package/clients/cli/lib/manifest.test.mjs +17 -0
  479. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  480. package/foundation/agent-docs/agent-docs.mjs +82 -12
  481. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  482. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  483. package/foundation/config/integration-debug.test.mjs +28 -3
  484. package/foundation/config/project-themes.test.mjs +11 -19
  485. package/foundation/config/project.d.mts +20 -11
  486. package/foundation/config/project.mjs +246 -89
  487. package/foundation/config/project.test.mjs +270 -21
  488. package/foundation/discovery/authoring-self-docs.d.mts +18 -0
  489. package/foundation/discovery/authoring-self-docs.mjs +38 -15
  490. package/foundation/discovery/authoring-self-docs.test.mjs +87 -12
  491. package/foundation/discovery/authoring-surface.d.mts +74 -0
  492. package/foundation/discovery/authoring-surface.mjs +525 -0
  493. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  494. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  495. package/foundation/discovery/cli-self-docs.mjs +490 -0
  496. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  497. package/foundation/discovery/component-discovery.d.mts +38 -0
  498. package/foundation/discovery/component-discovery.mjs +48 -0
  499. package/foundation/discovery/component-loader.d.mts +35 -38
  500. package/foundation/discovery/component-loader.mjs +53 -222
  501. package/foundation/discovery/docs-discovery.d.mts +114 -9
  502. package/foundation/discovery/docs-discovery.mjs +239 -30
  503. package/foundation/discovery/docs-discovery.test.mjs +150 -35
  504. package/foundation/discovery/docs-output-budget.d.mts +2 -2
  505. package/foundation/discovery/docs-output-budget.mjs +1 -1
  506. package/foundation/discovery/docs-section-key.d.mts +28 -10
  507. package/foundation/discovery/docs-section-key.mjs +134 -33
  508. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  509. package/foundation/discovery/template-adapter.d.mts +113 -11
  510. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  511. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  512. package/foundation/discovery/template-adapter.mjs +772 -82
  513. package/foundation/discovery/template-adapter.test.mjs +57 -0
  514. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  515. package/foundation/discovery/template-conflict-release.mjs +40 -0
  516. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  517. package/foundation/discovery/theme-discovery.d.mts +67 -7
  518. package/foundation/discovery/theme-discovery.mjs +916 -186
  519. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  520. package/foundation/discovery/theming-targets.test.mjs +4 -0
  521. package/foundation/doc-compiler/bundle.d.mts +47 -0
  522. package/foundation/doc-compiler/bundle.mjs +278 -0
  523. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  524. package/foundation/doc-compiler/compile.d.mts +343 -0
  525. package/foundation/doc-compiler/compile.mjs +558 -0
  526. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  527. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  528. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  529. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  530. package/foundation/doc-compiler/import.d.mts +24 -0
  531. package/foundation/doc-compiler/import.mjs +59 -0
  532. package/foundation/doc-compiler/inputs.d.mts +102 -0
  533. package/foundation/doc-compiler/inputs.mjs +291 -0
  534. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  535. package/foundation/doc-compiler/ir.d.mts +22 -0
  536. package/foundation/doc-compiler/ir.mjs +471 -0
  537. package/foundation/doc-compiler/lenses.d.mts +36 -0
  538. package/foundation/doc-compiler/lenses.mjs +173 -0
  539. package/foundation/doc-compiler/links.d.mts +162 -0
  540. package/foundation/doc-compiler/links.mjs +294 -0
  541. package/foundation/doc-compiler/links.test.mjs +192 -0
  542. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  543. package/foundation/doc-compiler/overlays.d.mts +37 -0
  544. package/foundation/doc-compiler/overlays.mjs +206 -0
  545. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  546. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  547. package/foundation/doc-compiler/read.d.mts +127 -0
  548. package/foundation/doc-compiler/read.mjs +325 -0
  549. package/foundation/doc-compiler/read.test.mjs +313 -0
  550. package/foundation/doc-compiler/source.d.mts +33 -0
  551. package/foundation/doc-compiler/source.mjs +128 -0
  552. package/foundation/doc-compiler/tree.d.mts +288 -0
  553. package/foundation/doc-compiler/tree.mjs +876 -0
  554. package/foundation/doc-compiler/tree.test.mjs +598 -0
  555. package/foundation/fs/file-protection.d.mts +33 -0
  556. package/foundation/fs/file-protection.mjs +825 -0
  557. package/foundation/fs/file-protection.test.mjs +250 -0
  558. package/foundation/fs/module-loader.d.mts +1 -0
  559. package/foundation/fs/module-loader.mjs +50 -1
  560. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  561. package/foundation/fs/path-safety.d.mts +3 -2
  562. package/foundation/fs/path-safety.mjs +49 -19
  563. package/foundation/fs/path-safety.test.mjs +50 -0
  564. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  565. package/foundation/integrations/autolink.d.mts +58 -1
  566. package/foundation/integrations/autolink.mjs +143 -52
  567. package/foundation/integrations/autolink.test.mjs +1 -1
  568. package/foundation/integrations/cli-requirement.d.mts +45 -0
  569. package/foundation/integrations/cli-requirement.mjs +154 -0
  570. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  571. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  572. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  573. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  574. package/foundation/integrations/contribution-inventory.mjs +27 -24
  575. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  576. package/foundation/integrations/integration-warnings.d.mts +9 -2
  577. package/foundation/integrations/integration-warnings.mjs +51 -26
  578. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  579. package/foundation/integrations/integrations.d.mts +17 -1
  580. package/foundation/integrations/integrations.mjs +52 -98
  581. package/foundation/integrations/integrations.test.mjs +31 -0
  582. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  583. package/foundation/integrations/provider-resolution.d.mts +152 -0
  584. package/foundation/integrations/provider-resolution.mjs +576 -0
  585. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  586. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  587. package/foundation/integrations/theme-descriptor.mjs +44 -0
  588. package/foundation/integrations/validate-contributions.mjs +121 -29
  589. package/foundation/response/base.d.ts +8 -4
  590. package/foundation/response/error-codes.d.mts +3 -1
  591. package/foundation/response/error-codes.d.ts +2 -0
  592. package/foundation/response/error-codes.doc.mjs +13 -4
  593. package/foundation/response/error-codes.mjs +8 -2
  594. package/foundation/response/error-codes.test.mjs +137 -10
  595. package/foundation/response/json-contract.test.mjs +11 -0
  596. package/foundation/response/json.d.mts +4 -2
  597. package/foundation/response/json.mjs +8 -10
  598. package/foundation/response/response-types.doc.d.mts +5 -1
  599. package/foundation/response/response-types.doc.mjs +37 -22
  600. package/foundation/response/response-types.doc.test.mjs +158 -0
  601. package/foundation/response/response.doc.mjs +1 -1
  602. package/foundation/text/string-utils.d.mts +8 -0
  603. package/foundation/text/string-utils.mjs +40 -10
  604. package/foundation/xle/expand.d.mts +2 -0
  605. package/foundation/xle/expand.mjs +4 -3
  606. package/foundation/xle/expand.test.mjs +54 -0
  607. package/foundation/xle/xle.test.mjs +13 -0
  608. package/package.json +10 -11
  609. package/assets/templates/themes/manifest.json +0 -95
  610. package/clients/cli/lib/update-check.mjs +0 -83
  611. package/clients/cli/lib/update-check.test.mjs +0 -137
  612. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -74,16 +74,16 @@ describe('discoverBuiltinTopics', () => {
74
74
 
75
75
  describe('discoverIntegrationDocs', () => {
76
76
  it('contributes nothing when no docs root is declared or the root is gone', async () => {
77
- expect(await discoverIntegrationDocs({name: '@acme/widgets'})).toEqual({
78
- records: [],
79
- errors: [],
80
- });
77
+ const nothing = {records: [], errors: [], namespaces: [], guides: []};
78
+ expect(await discoverIntegrationDocs({name: '@acme/widgets'})).toEqual(
79
+ nothing,
80
+ );
81
81
  expect(
82
82
  await discoverIntegrationDocs({
83
83
  name: '@acme/widgets',
84
84
  docs: path.join(tmpDir, 'nope'),
85
85
  }),
86
- ).toEqual({records: [], errors: []});
86
+ ).toEqual(nothing);
87
87
  });
88
88
 
89
89
  it('reads every topic under the root, with what it declares', async () => {
@@ -169,10 +169,7 @@ describe('discoverIntegrationDocs', () => {
169
169
  id: 'steps',
170
170
  title: 'Steps',
171
171
  content: [
172
- {
173
- type: 'workflow',
174
- steps: [{title: 'Install', description: 'Run install.'}],
175
- },
172
+ {type: 'collection', source: {slot: 'guides'}},
176
173
  ],
177
174
  },
178
175
  ],
@@ -180,7 +177,69 @@ describe('discoverIntegrationDocs', () => {
180
177
  }),
181
178
  );
182
179
  expect(records).toEqual([]);
183
- expect(errors[0].message).toContain('requires the compiled graph renderer');
180
+ expect(errors[0].message).toContain('Invalid discriminator value');
181
+ });
182
+
183
+ it('hands namespace docs and placed guides to the docs tree, by provider id', async () => {
184
+ const found = await discoverIntegrationDocs({
185
+ ...integration('@acme/namespace', {
186
+ 'guides.doc.mjs': {
187
+ type: 'namespace',
188
+ name: 'guides',
189
+ title: 'Guides',
190
+ summary: 'Every guide.',
191
+ slots: {guides: {title: 'Guides', accepts: {kinds: ['generic']}}},
192
+ },
193
+ 'setup.doc.mjs': topic({
194
+ name: 'setup',
195
+ title: 'Set up',
196
+ placement: {parent: 'namespace:guides', slot: 'guides', order: 1},
197
+ }),
198
+ 'deploying.doc.mjs': topic(),
199
+ }),
200
+ providerId: '@acme/tree-provider',
201
+ });
202
+ expect(found.errors).toEqual([]);
203
+ expect(found.records.map(record => record.name)).toEqual(['deploying']);
204
+ expect(found.records[0].providerId).toBe('@acme/tree-provider');
205
+ expect(found.namespaces).toMatchObject([
206
+ {
207
+ provider: '@acme/namespace',
208
+ providerId: '@acme/tree-provider',
209
+ source: '@acme/namespace/guides.doc.mjs',
210
+ doc: {name: 'guides'},
211
+ },
212
+ ]);
213
+ expect(found.guides).toMatchObject([
214
+ {
215
+ provider: '@acme/namespace',
216
+ providerId: '@acme/tree-provider',
217
+ kind: 'generic',
218
+ name: 'setup',
219
+ placement: {parent: 'namespace:guides', slot: 'guides', order: 1},
220
+ },
221
+ ]);
222
+ });
223
+
224
+ it('names what a namespace doc lacks, and refuses a placed guide that replaces a topic', async () => {
225
+ const {errors, namespaces, guides} = await discoverIntegrationDocs(
226
+ integration('@acme/namespace', {
227
+ 'guides.doc.mjs': {type: 'namespace', name: 'guides', title: 'Guides'},
228
+ 'setup.doc.mjs': topic({
229
+ name: 'setup',
230
+ replaces: 'getting-started',
231
+ placement: {parent: 'namespace:guides', slot: 'guides'},
232
+ }),
233
+ }),
234
+ );
235
+ expect(namespaces).toEqual([]);
236
+ expect(guides).toEqual([]);
237
+ expect(errors.map(error => error.message).join('\n')).toMatch(
238
+ /guides\.doc\.mjs.*slots/,
239
+ );
240
+ expect(errors.map(error => error.message).join('\n')).toContain(
241
+ 'is placed in the docs tree and also declares `replaces`',
242
+ );
184
243
  });
185
244
  });
186
245
 
@@ -251,6 +310,46 @@ describe('problemsInTopic', () => {
251
310
  }
252
311
  });
253
312
 
313
+ it('takes a reference block, and checks its projection and presentation', () => {
314
+ /** @param {any[]} content */
315
+ const withBlocks = content =>
316
+ problemsInTopic(topic({sections: [{title: 'Overview', content}]}));
317
+ expect(
318
+ withBlocks([
319
+ {type: 'reference', target: 'schema:integration'},
320
+ {
321
+ type: 'reference',
322
+ target: '@astryxdesign/cli:schema:integration',
323
+ projection: {fields: ['docs']},
324
+ presentation: 'compact',
325
+ },
326
+ ]),
327
+ ).toEqual([]);
328
+ expect(
329
+ withBlocks([
330
+ {type: 'reference', target: ''},
331
+ {type: 'reference', target: 'schema:x', presentation: 'card'},
332
+ {type: 'reference', target: 'schema:x', projection: {fields: []}},
333
+ {type: 'reference', target: 'schema:x', projection: {rows: ['a']}},
334
+ {type: 'reference', target: 'schema:x', projection: ['docs']},
335
+ {type: 'reference', target: 'schema:x', link: {}},
336
+ ]),
337
+ ).toEqual([
338
+ 'sections[0].content[0].target: expected a non-empty string',
339
+ 'sections[0].content[1].presentation: "card" is not one of summary, compact, full',
340
+ 'sections[0].content[2].projection.fields: expected a non-empty array of names',
341
+ 'sections[0].content[3].projection.rows: not a field of a projection',
342
+ 'sections[0].content[4].projection: expected {fields?, sections?}, naming the parts of the doc to include',
343
+ 'sections[0].content[5].link: not a field of a reference block',
344
+ ]);
345
+ // Workflow and collection blocks stay in a namespace doc's `blocks`.
346
+ for (const type of ['workflow', 'collection']) {
347
+ expect(withBlocks([{type}]).join('\n')).toContain(
348
+ 'requires the compiled graph renderer',
349
+ );
350
+ }
351
+ });
352
+
254
353
  it('rejects a name that is not URL-safe', () => {
255
354
  expect(problemsInTopic(topic({name: 'not a topic'})).join('\n')).toContain(
256
355
  'URL-safe',
@@ -485,11 +584,14 @@ describe('mergeTopic', () => {
485
584
  ]);
486
585
  });
487
586
 
488
- it('takes the title and description only when the overlay states them', () => {
489
- expect(mergeTopic(base, {sections: []}).title).toBe('Theme');
490
- expect(mergeTopic(base, {title: 'Theming', sections: []}).title).toBe(
491
- 'Theming',
492
- );
587
+ it('keeps the base title and description: an extension never renames a topic', () => {
588
+ const merged = mergeTopic(base, {
589
+ title: 'Acme theme notes',
590
+ description: 'Our additions.',
591
+ sections: [],
592
+ });
593
+ expect(merged.title).toBe('Theme');
594
+ expect(merged.description).toBe('Theming.');
493
595
  });
494
596
  });
495
597
 
@@ -500,30 +602,29 @@ describe('problemsInTopic section keys', () => {
500
602
  name: 'keys',
501
603
  title: 'Keys',
502
604
  description: 'Section keys.',
503
- sections: sections.map(s => ({content: [{type: 'prose', text: 'x'}], ...s})),
605
+ sections: sections.map(s => ({
606
+ content: [{type: 'prose', text: 'x'}],
607
+ ...s,
608
+ })),
504
609
  });
505
610
 
506
- it('rejects two sections that derive the same key', () => {
611
+ it('keeps legacy title-only key conflicts readable', () => {
507
612
  expect(
508
613
  problemsInTopic(doc([{title: 'Quick Start'}, {title: 'Quick-start'}])),
509
- ).toEqual([
510
- expect.stringContaining('"quick-start" is already used by sections[0]'),
511
- ]);
614
+ ).toEqual([]);
512
615
  });
513
616
 
514
617
  it('rejects an unsafe id', () => {
515
- expect(problemsInTopic(doc([{id: 'Quick Start', title: 'Quick Start'}]))).toEqual(
516
- [expect.stringContaining('is not a stable key')],
517
- );
618
+ expect(
619
+ problemsInTopic(doc([{id: 'Quick Start', title: 'Quick Start'}])),
620
+ ).toEqual([expect.stringContaining('is not a stable key')]);
518
621
  });
519
622
 
520
- it('rejects a title no key derives from, unless it has an id', () => {
521
- expect(problemsInTopic(doc([{title: '亮/暗模式'}]))).toEqual([
522
- expect.stringContaining('Give the section an id'),
523
- ]);
524
- expect(problemsInTopic(doc([{id: 'light-dark', title: '亮/暗模式'}]))).toEqual(
525
- [],
526
- );
623
+ it('keeps a legacy title that has no derived key readable', () => {
624
+ expect(problemsInTopic(doc([{title: '亮/暗模式'}]))).toEqual([]);
625
+ expect(
626
+ problemsInTopic(doc([{id: 'light-dark', title: '亮/暗模式'}])),
627
+ ).toEqual([]);
527
628
  });
528
629
  });
529
630
 
@@ -535,12 +636,17 @@ describe('mergeTopic by section key', () => {
535
636
  {title: 'Light/Dark Mode', content: [{type: 'prose', text: 'base'}]},
536
637
  ],
537
638
  };
538
- const titles = doc => doc.sections.map(s => [s.id ?? null, s.title, s.content[0].text]);
639
+ const titles = doc =>
640
+ doc.sections.map(s => [s.id ?? null, s.title, s.content[0].text]);
539
641
 
540
642
  it('replaces the section whose derived key an extension id names', () => {
541
643
  const merged = mergeTopic(base, {
542
644
  sections: [
543
- {id: 'quick-start', title: 'Quick Start with Acme', content: [{type: 'prose', text: 'acme'}]},
645
+ {
646
+ id: 'quick-start',
647
+ title: 'Quick Start with Acme',
648
+ content: [{type: 'prose', text: 'acme'}],
649
+ },
544
650
  ],
545
651
  });
546
652
  expect(titles(merged)).toEqual([
@@ -549,19 +655,28 @@ describe('mergeTopic by section key', () => {
549
655
  ]);
550
656
  });
551
657
 
552
- it('replaces the section a title variant derives the same key as', () => {
658
+ it('keeps a legacy title variant as a separate section', () => {
553
659
  const merged = mergeTopic(base, {
554
- sections: [{title: 'Light-Dark Mode', content: [{type: 'prose', text: 'acme'}]}],
660
+ sections: [
661
+ {title: 'Light-Dark Mode', content: [{type: 'prose', text: 'acme'}]},
662
+ ],
555
663
  });
556
664
  expect(titles(merged)).toEqual([
557
665
  [null, 'Quick Start', 'base'],
666
+ [null, 'Light/Dark Mode', 'base'],
558
667
  [null, 'Light-Dark Mode', 'acme'],
559
668
  ]);
560
669
  });
561
670
 
562
671
  it('prefers the key over a legacy title for an extension with an id', () => {
563
672
  const merged = mergeTopic(base, {
564
- sections: [{id: 'light-dark-mode', title: 'Quick Start', content: [{type: 'prose', text: 'acme'}]}],
673
+ sections: [
674
+ {
675
+ id: 'light-dark-mode',
676
+ title: 'Quick Start',
677
+ content: [{type: 'prose', text: 'acme'}],
678
+ },
679
+ ],
565
680
  });
566
681
  expect(titles(merged)).toEqual([
567
682
  [null, 'Quick Start', 'base'],
@@ -9,10 +9,10 @@
9
9
  */
10
10
  export function docPayloadBytes(payload: unknown): number;
11
11
  /**
12
- * @param {import('../../api/docs/docs.type.mjs').DocsIndex} index
12
+ * @param {Omit<import('../../api/docs/docs.type.mjs').DocsIndex, 'links'> | import('../../api/docs/docs.type.mjs').DocsIndex} index
13
13
  * @returns {number}
14
14
  */
15
- export function docsIndexBytes(index: import("../../api/docs/docs.type.mjs").DocsIndex): number;
15
+ export function docsIndexBytes(index: Omit<import("../../api/docs/docs.type.mjs").DocsIndex, "links"> | import("../../api/docs/docs.type.mjs").DocsIndex): number;
16
16
  /**
17
17
  * The sections a single read would return more than `budget` bytes for.
18
18
  * @param {any[]} sections
@@ -26,7 +26,7 @@ export function docPayloadBytes(payload) {
26
26
  }
27
27
 
28
28
  /**
29
- * @param {import('../../api/docs/docs.type.mjs').DocsIndex} index
29
+ * @param {Omit<import('../../api/docs/docs.type.mjs').DocsIndex, 'links'> | import('../../api/docs/docs.type.mjs').DocsIndex} index
30
30
  * @returns {number}
31
31
  */
32
32
  export function docsIndexBytes(index) {
@@ -31,9 +31,24 @@ export function sectionTitleKey(title: unknown): string;
31
31
  */
32
32
  export function sectionKey(section: any): string;
33
33
  /**
34
- * Problems with the keys of a topic's sections: an authored id that is not a
35
- * stable key, a title no key derives from, and two sections sharing a key.
36
- * Keys are never suffixed to make them unique, because readers link to them.
34
+ * A name as a docs-tree route segment: lowercase words joined by hyphens, so
35
+ * `integrationPackCheck` and `integration pack` both read naturally.
36
+ * @param {string} name
37
+ * @returns {string}
38
+ */
39
+ export function routeSegment(name: string): string;
40
+ /**
41
+ * Fatal key problems: only an explicitly authored `id` can make a previously
42
+ * readable topic invalid. Derived-key collisions and titles with no Latin
43
+ * letters or digits are handled by {@link withSectionKeys} for 0.6.x
44
+ * compatibility.
45
+ * @param {any[]} sections
46
+ * @returns {string[]}
47
+ */
48
+ export function sectionKeyErrors(sections: any[]): string[];
49
+ /**
50
+ * Compatibility notices for section keys. These inputs loaded in 0.6.x, so
51
+ * readers keep accepting them and assign deterministic fallback keys.
37
52
  * @param {any[]} sections
38
53
  * @returns {string[]}
39
54
  */
@@ -49,13 +64,16 @@ export function withSectionKeys<T extends {
49
64
  sections: any[];
50
65
  }>(doc: T): T;
51
66
  /**
52
- * Find the section a reader asked for: by key, then by exact title (or the
53
- * key the query derives), then by a title that contains the query. More than
54
- * one match is refused rather than guessed.
67
+ * Find the section a reader asked for. The 0.6.x first-match title-substring
68
+ * lookup remains first in the authored-title view. In a localized view, an
69
+ * exact stable key resolves before translated title substrings because those
70
+ * translations cannot participate in language-stable key allocation. Generated
71
+ * keys avoid authored-title conflicts, and authored IDs that would shadow an
72
+ * authored legacy query are rejected.
55
73
  * @param {any[]} sections
56
74
  * @param {string} query
57
- * @returns {{section: any | null, candidates: any[]}} `candidates` lists the
58
- * matches when the query is ambiguous, and is empty when nothing matches
75
+ * @returns {{section: any | null, candidates: any[]}} `candidates` lists every
76
+ * legacy title match when the query is ambiguous
59
77
  */
60
78
  export function findDocSection(sections: any[], query: string): {
61
79
  section: any | null;
@@ -73,14 +91,14 @@ export function sectionSummary(section: any, max?: number): string;
73
91
  * The index a topic-only read returns: what the topic is, and one entry per
74
92
  * section with the key to read it by.
75
93
  * @param {{name: string, title: string, description: string, sections: any[]}} doc
76
- * @returns {import('../../api/docs/docs.type.mjs').DocsIndex}
94
+ * @returns {Omit<import('../../api/docs/docs.type.mjs').DocsIndex, 'links'>}
77
95
  */
78
96
  export function buildDocsIndexData(doc: {
79
97
  name: string;
80
98
  title: string;
81
99
  description: string;
82
100
  sections: any[];
83
- }): import("../../api/docs/docs.type.mjs").DocsIndex;
101
+ }): Omit<import("../../api/docs/docs.type.mjs").DocsIndex, "links">;
84
102
  /**
85
103
  * @file Stable section keys, section lookup, and the topic index.
86
104
  *
@@ -34,7 +34,10 @@ const SOURCE_TITLE = Symbol('astryx.docs.sourceTitle');
34
34
  * @returns {T}
35
35
  */
36
36
  export function withSourceTitle(section, title) {
37
- Object.defineProperty(section, SOURCE_TITLE, {value: title, configurable: true});
37
+ Object.defineProperty(section, SOURCE_TITLE, {
38
+ value: title,
39
+ configurable: true,
40
+ });
38
41
  return section;
39
42
  }
40
43
 
@@ -77,9 +80,77 @@ export function sectionKey(section) {
77
80
  }
78
81
 
79
82
  /**
80
- * Problems with the keys of a topic's sections: an authored id that is not a
81
- * stable key, a title no key derives from, and two sections sharing a key.
82
- * Keys are never suffixed to make them unique, because readers link to them.
83
+ * The first section the 0.6.x title-substring lookup would return for a query.
84
+ * @param {any[]} sections
85
+ * @param {string} query
86
+ * @returns {number}
87
+ */
88
+ function legacyTitleMatchIndex(sections, query) {
89
+ const lower = query.toLowerCase();
90
+ return sections.findIndex(section => {
91
+ const title = sourceTitle(section);
92
+ return typeof title === 'string' && title.toLowerCase().includes(lower);
93
+ });
94
+ }
95
+
96
+ /**
97
+ * A name as a docs-tree route segment: lowercase words joined by hyphens, so
98
+ * `integrationPackCheck` and `integration pack` both read naturally.
99
+ * @param {string} name
100
+ * @returns {string}
101
+ */
102
+ export function routeSegment(name) {
103
+ return String(name)
104
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
105
+ .toLowerCase()
106
+ .replace(/[^a-z0-9]+/g, '-')
107
+ .replace(/^-+|-+$/g, '');
108
+ }
109
+
110
+ /**
111
+ * Fatal key problems: only an explicitly authored `id` can make a previously
112
+ * readable topic invalid. Derived-key collisions and titles with no Latin
113
+ * letters or digits are handled by {@link withSectionKeys} for 0.6.x
114
+ * compatibility.
115
+ * @param {any[]} sections
116
+ * @returns {string[]}
117
+ */
118
+ export function sectionKeyErrors(sections) {
119
+ /** @type {string[]} */
120
+ const problems = [];
121
+ /** @type {Map<string, number>} */
122
+ const seen = new Map();
123
+ sections.forEach((section, s) => {
124
+ if (section?.id == null) return;
125
+ const at = `sections[${s}]`;
126
+ if (typeof section.id !== 'string' || !SECTION_KEY_RE.test(section.id)) {
127
+ problems.push(
128
+ `${at}.id: ${JSON.stringify(section.id)} is not a stable key. Use lowercase letters and digits joined by single hyphens.`,
129
+ );
130
+ return;
131
+ }
132
+ const first = seen.get(section.id);
133
+ if (first != null) {
134
+ problems.push(
135
+ `${at}: the key "${section.id}" is already used by sections[${first}]. Give one of them a distinct id.`,
136
+ );
137
+ return;
138
+ }
139
+ const legacyOwner = legacyTitleMatchIndex(sections, section.id);
140
+ if (legacyOwner !== -1 && legacyOwner !== s) {
141
+ problems.push(
142
+ `${at}.id: the key "${section.id}" is already a legacy title query for sections[${legacyOwner}]. Choose an id that resolves to this section.`,
143
+ );
144
+ return;
145
+ }
146
+ seen.set(section.id, s);
147
+ });
148
+ return problems;
149
+ }
150
+
151
+ /**
152
+ * Compatibility notices for section keys. These inputs loaded in 0.6.x, so
153
+ * readers keep accepting them and assign deterministic fallback keys.
83
154
  * @param {any[]} sections
84
155
  * @returns {string[]}
85
156
  */
@@ -90,7 +161,6 @@ export function sectionKeyProblems(sections) {
90
161
  const seen = new Map();
91
162
  sections.forEach((section, s) => {
92
163
  const at = `sections[${s}]`;
93
- // A missing title is reported where titles are checked; no key to judge.
94
164
  if (
95
165
  section?.id == null &&
96
166
  (typeof section?.title !== 'string' || section.title === '')
@@ -109,14 +179,14 @@ export function sectionKeyProblems(sections) {
109
179
  const key = sectionKey(section);
110
180
  if (key === '') {
111
181
  problems.push(
112
- `${at}: no key derives from the title ${JSON.stringify(section?.title)}. Give the section an id.`,
182
+ `${at}: no key derives from the title ${JSON.stringify(section?.title)}. A deterministic section-N compatibility key is used; add an explicit id.`,
113
183
  );
114
184
  return;
115
185
  }
116
186
  const first = seen.get(key);
117
187
  if (first != null) {
118
188
  problems.push(
119
- `${at}: the key "${key}" is already used by sections[${first}]. Give one of them a distinct id or title.`,
189
+ `${at}: the key "${key}" is already used by sections[${first}]. A suffixed compatibility key is used for title-derived collisions; give one of them a distinct id or title.`,
120
190
  );
121
191
  return;
122
192
  }
@@ -133,48 +203,79 @@ export function sectionKeyProblems(sections) {
133
203
  * @returns {T}
134
204
  */
135
205
  export function withSectionKeys(doc) {
206
+ const reserved = new Set(
207
+ doc.sections
208
+ .map(section => section?.id)
209
+ .filter(id => typeof id === 'string' && SECTION_KEY_RE.test(id)),
210
+ );
211
+ const used = new Set();
136
212
  return {
137
213
  ...doc,
138
- sections: doc.sections.map(section =>
139
- section.id != null
140
- ? section
141
- : withSourceTitle(
142
- {...section, id: sectionKey(section)},
143
- sourceTitle(section),
144
- ),
145
- ),
214
+ sections: doc.sections.map((section, index) => {
215
+ if (section.id != null) {
216
+ used.add(section.id);
217
+ return section;
218
+ }
219
+ const base =
220
+ sectionTitleKey(sourceTitle(section)) || `section-${index + 1}`;
221
+ let key = base;
222
+ let suffix = 2;
223
+ while (
224
+ reserved.has(key) ||
225
+ used.has(key) ||
226
+ (legacyTitleMatchIndex(doc.sections, key) !== -1 &&
227
+ legacyTitleMatchIndex(doc.sections, key) !== index)
228
+ ) {
229
+ key = `${base}-${suffix}`;
230
+ suffix += 1;
231
+ }
232
+ used.add(key);
233
+ return withSourceTitle({...section, id: key}, sourceTitle(section));
234
+ }),
146
235
  };
147
236
  }
148
237
 
149
238
  /**
150
- * Find the section a reader asked for: by key, then by exact title (or the
151
- * key the query derives), then by a title that contains the query. More than
152
- * one match is refused rather than guessed.
239
+ * Find the section a reader asked for. The 0.6.x first-match title-substring
240
+ * lookup remains first in the authored-title view. In a localized view, an
241
+ * exact stable key resolves before translated title substrings because those
242
+ * translations cannot participate in language-stable key allocation. Generated
243
+ * keys avoid authored-title conflicts, and authored IDs that would shadow an
244
+ * authored legacy query are rejected.
153
245
  * @param {any[]} sections
154
246
  * @param {string} query
155
- * @returns {{section: any | null, candidates: any[]}} `candidates` lists the
156
- * matches when the query is ambiguous, and is empty when nothing matches
247
+ * @returns {{section: any | null, candidates: any[]}} `candidates` lists every
248
+ * legacy title match when the query is ambiguous
157
249
  */
158
250
  export function findDocSection(sections, query) {
159
251
  const wanted = query.trim();
160
252
  const byKey = sections.find(section => sectionKey(section) === wanted);
161
- if (byKey) return {section: byKey, candidates: []};
253
+ const hasLocalizedTitles = sections.some(
254
+ section => sourceTitle(section) !== section.title,
255
+ );
256
+ if (byKey && hasLocalizedTitles) {
257
+ return {section: byKey, candidates: []};
258
+ }
162
259
 
163
260
  const lower = wanted.toLowerCase();
164
- const derived = sectionTitleKey(wanted);
165
- const exact = sections.filter(
166
- section =>
167
- section.title.toLowerCase() === lower ||
168
- (derived !== '' && sectionTitleKey(sourceTitle(section)) === derived),
261
+ const legacy = sections.filter(section =>
262
+ section.title.toLowerCase().includes(lower),
169
263
  );
170
- if (exact.length === 1) return {section: exact[0], candidates: []};
171
- if (exact.length > 1) return {section: null, candidates: exact};
264
+ if (legacy.length > 0) {
265
+ return {section: legacy[0], candidates: legacy.length > 1 ? legacy : []};
266
+ }
172
267
 
173
- const partial = sections.filter(section =>
174
- section.title.toLowerCase().includes(lower),
268
+ const byFallbackKey = sections.find(
269
+ section => sectionKey(section) === wanted,
270
+ );
271
+ if (byFallbackKey) return {section: byFallbackKey, candidates: []};
272
+
273
+ const derived = sectionTitleKey(wanted);
274
+ const byDerivedKey = sections.find(
275
+ section =>
276
+ derived !== '' && sectionTitleKey(sourceTitle(section)) === derived,
175
277
  );
176
- if (partial.length === 1) return {section: partial[0], candidates: []};
177
- return {section: null, candidates: partial};
278
+ return {section: byDerivedKey ?? null, candidates: []};
178
279
  }
179
280
 
180
281
  /**
@@ -205,7 +306,7 @@ export function sectionSummary(section, max = SECTION_SUMMARY_MAX) {
205
306
  * The index a topic-only read returns: what the topic is, and one entry per
206
307
  * section with the key to read it by.
207
308
  * @param {{name: string, title: string, description: string, sections: any[]}} doc
208
- * @returns {import('../../api/docs/docs.type.mjs').DocsIndex}
309
+ * @returns {Omit<import('../../api/docs/docs.type.mjs').DocsIndex, 'links'>}
209
310
  */
210
311
  export function buildDocsIndexData(doc) {
211
312
  return {