@astryxdesign/cli 0.6.3-canary.db4e378 → 0.6.3-canary.db52d98

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 (397) hide show
  1. package/README.md +38 -15
  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 +14 -7
  6. package/api/build/build.test.mjs +184 -6
  7. package/api/build/build.type.d.mts +57 -2
  8. package/api/build/build.type.mjs +30 -7
  9. package/api/build/help/help.d.mts +4 -0
  10. package/api/build/help/help.mjs +24 -11
  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 +1 -0
  19. package/api/component/component.mjs +60 -12
  20. package/api/component/list/list.mjs +3 -2
  21. package/api/discover/discover.doc.mjs +1 -0
  22. package/api/docs/_adapter.d.mts +252 -34
  23. package/api/docs/_adapter.mjs +923 -132
  24. package/api/docs/detail/detail.mjs +11 -3
  25. package/api/docs/detail/section/section.mjs +24 -13
  26. package/api/docs/detail/section/section.test.mjs +15 -6
  27. package/api/docs/docs.d.mts +5 -3
  28. package/api/docs/docs.doc.mjs +39 -17
  29. package/api/docs/docs.mjs +44 -8
  30. package/api/docs/docs.test.mjs +158 -4
  31. package/api/docs/docs.type.d.mts +181 -2
  32. package/api/docs/docs.type.mjs +117 -3
  33. package/api/docs/index/index.mjs +11 -3
  34. package/api/docs/index/index.test.mjs +1 -1
  35. package/api/docs/integration-tree.test.mjs +555 -0
  36. package/api/docs/integrationDocs.test.mjs +14 -14
  37. package/api/docs/list/list.mjs +28 -12
  38. package/api/docs/node/node.d.mts +43 -0
  39. package/api/docs/node/node.mjs +192 -0
  40. package/api/docs/reference-blocks.test.mjs +406 -0
  41. package/api/doctor/doctor.d.mts +54 -4
  42. package/api/doctor/doctor.doc.mjs +1 -0
  43. package/api/doctor/doctor.mjs +331 -16
  44. package/api/doctor/doctor.test.mjs +420 -7
  45. package/api/gap-report/gap-report.doc.mjs +1 -0
  46. package/api/hook/_adapter.mjs +19 -5
  47. package/api/hook/hook.doc.mjs +1 -0
  48. package/api/hook/list/list.d.mts +1 -1
  49. package/api/hook/list/list.mjs +69 -17
  50. package/api/index.d.mts +1 -1
  51. package/api/index.mjs +1 -0
  52. package/api/init/init.doc.mjs +2 -1
  53. package/api/integration/add-contribution.d.mts +2 -1
  54. package/api/integration/add-contribution.mjs +114 -12
  55. package/api/integration/add-contribution.test.mjs +174 -3
  56. package/api/integration/add-theme.mjs +34 -64
  57. package/api/integration/add-theme.test.mjs +105 -21
  58. package/api/integration/authoring-checks.mjs +138 -28
  59. package/api/integration/authoring-checks.test.mjs +179 -7
  60. package/api/integration/authoring-checks.type.mjs +6 -1
  61. package/api/integration/integration-authoring.type.d.mts +2 -0
  62. package/api/integration/integration-authoring.type.mjs +2 -0
  63. package/api/integration/integration-block-exports.test.mjs +10 -6
  64. package/api/integration/integrationAdd.doc.mjs +7 -0
  65. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  66. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  67. package/api/integration/integrationAddComponent.doc.mjs +1 -0
  68. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  69. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  70. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  71. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  72. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  73. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  74. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  75. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  76. package/api/integration/pack-check.mjs +34 -0
  77. package/api/integration/pack-check.test.mjs +138 -47
  78. package/api/integration/pack-check.type.d.mts +26 -2
  79. package/api/integration/pack-check.type.mjs +14 -1
  80. package/api/integration/summarizeIssues.doc.mjs +1 -0
  81. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  82. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  83. package/api/integration/validate-integration.mjs +50 -102
  84. package/api/integration/validate-integration.test.mjs +88 -26
  85. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  86. package/api/integration/validateIntegration.doc.mjs +2 -1
  87. package/api/json/assertResponse.doc.mjs +1 -0
  88. package/api/json/index.ts +2 -0
  89. package/api/json/isError.doc.mjs +1 -0
  90. package/api/json/parseResponse.doc.mjs +1 -0
  91. package/api/layout/_adapter.mjs +20 -5
  92. package/api/layout/layoutCheck.doc.mjs +1 -0
  93. package/api/layout/layoutExpand.doc.mjs +1 -0
  94. package/api/layout/layoutGrammar.doc.mjs +1 -0
  95. package/api/search/search.d.mts +59 -1
  96. package/api/search/search.doc.mjs +5 -3
  97. package/api/search/search.mjs +458 -77
  98. package/api/search/search.test.mjs +91 -2
  99. package/api/search/search.type.d.mts +13 -1
  100. package/api/search/search.type.mjs +4 -1
  101. package/api/swizzle/swizzle.doc.mjs +1 -0
  102. package/api/template/list/list.mjs +1 -0
  103. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  104. package/api/template/template-integration.test.mjs +1072 -3
  105. package/api/template/template-suffix.test.mjs +41 -21
  106. package/api/template/template.doc.mjs +28 -7
  107. package/api/template/template.mjs +45 -8
  108. package/api/template/template.type.d.mts +6 -8
  109. package/api/template/template.type.mjs +3 -2
  110. package/api/theme/_adapter.d.mts +2 -3
  111. package/api/theme/_adapter.mjs +4 -5
  112. package/api/theme/add/add.binary.test.mjs +10 -17
  113. package/api/theme/add/add.test.mjs +14 -1
  114. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  115. package/api/theme/integration-themes.test.mjs +39 -28
  116. package/api/theme/list/list.test.mjs +19 -20
  117. package/api/theme/listThemes.doc.mjs +6 -5
  118. package/api/theme/template/template.test.mjs +5 -0
  119. package/api/theme/themeAdd.doc.mjs +4 -3
  120. package/api/theme/themeBuild.doc.mjs +1 -0
  121. package/api/theme/themeList.doc.mjs +6 -3
  122. package/api/theme/themeListAvailable.doc.mjs +5 -3
  123. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  124. package/api/theme/themeTargets.doc.mjs +1 -0
  125. package/api/theme/themeTemplate.doc.mjs +2 -1
  126. package/api/upgrade/_adapter.d.mts +32 -5
  127. package/api/upgrade/_adapter.mjs +97 -69
  128. package/api/upgrade/provider-agreement.test.mjs +152 -0
  129. package/api/upgrade/run/run.mjs +356 -59
  130. package/api/upgrade/upgrade.doc.mjs +6 -1
  131. package/api/upgrade/upgrade.type.d.mts +34 -0
  132. package/api/upgrade/upgrade.type.mjs +15 -0
  133. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  134. package/assets/codemods/integration-discovery.mjs +8 -2
  135. package/assets/codemods/integration-discovery.test.mjs +15 -0
  136. package/assets/codemods/integration-runner.mjs +56 -4
  137. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  138. package/assets/codemods/run-codemod.mjs +177 -34
  139. package/assets/codemods/runner.mjs +350 -102
  140. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  141. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  142. package/assets/codemods/transforms/next/index.mjs +19 -1
  143. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  144. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  145. package/assets/docs/getting-started.doc.mjs +2 -2
  146. package/assets/docs/layout.doc.dense.mjs +2 -2
  147. package/assets/docs/layout.doc.mjs +1 -1
  148. package/assets/docs/principles.doc.mjs +6 -6
  149. package/assets/docs/styling-libraries.doc.mjs +3 -3
  150. package/assets/docs/styling.doc.mjs +4 -4
  151. package/assets/docs/theme.doc.mjs +5 -5
  152. package/assets/docs/tokens.doc.mjs +1 -1
  153. package/assets/docs/tree/api.doc.mjs +30 -0
  154. package/assets/docs/tree/cli.doc.mjs +23 -0
  155. package/assets/docs/tree/commands.doc.mjs +25 -0
  156. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +66 -38
  157. package/assets/docs/tree/integrations.test.mjs +62 -0
  158. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  159. package/assets/docs/working-with-ai.doc.mjs +3 -3
  160. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  161. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  162. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  163. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  164. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  165. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  166. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  167. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  168. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  169. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  170. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  171. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  172. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  173. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  174. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  175. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  176. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  177. package/authoring/codemod/codemod.doc.mjs +1 -1
  178. package/authoring/codemod/type.ts +12 -0
  179. package/authoring/config/config.doc.mjs +1 -1
  180. package/authoring/debug/debug.doc.d.mts +11 -0
  181. package/authoring/debug/debug.doc.mjs +182 -0
  182. package/authoring/debug/parse.d.mts +3 -3
  183. package/authoring/doctypes/_schema.d.mts +119 -117
  184. package/authoring/doctypes/_schema.mjs +54 -3
  185. package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
  186. package/authoring/doctypes/base/type.ts +6 -5
  187. package/authoring/doctypes/command/command.doc.mjs +1 -1
  188. package/authoring/doctypes/command/type.ts +2 -2
  189. package/authoring/doctypes/component/type.ts +2 -2
  190. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  191. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  192. package/authoring/doctypes/enum/type.ts +1 -1
  193. package/authoring/doctypes/function/function.doc.mjs +3 -2
  194. package/authoring/doctypes/function/type.ts +3 -2
  195. package/authoring/doctypes/hook/type.ts +2 -2
  196. package/authoring/doctypes/load-contract.test.mjs +28 -2
  197. package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
  198. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  199. package/authoring/doctypes/namespace/type.ts +5 -2
  200. package/authoring/doctypes/parse.d.mts +4 -2
  201. package/authoring/doctypes/parse.mjs +10 -5
  202. package/authoring/doctypes/reference/reference.doc.mjs +35 -6
  203. package/authoring/doctypes/reference/type.ts +30 -13
  204. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  205. package/authoring/doctypes/schema/type.ts +1 -2
  206. package/authoring/doctypes/template/parse.d.mts +2 -0
  207. package/authoring/doctypes/template/parse.mjs +4 -0
  208. package/authoring/doctypes/template/parse.test.mjs +18 -0
  209. package/authoring/doctypes/template/template.doc.mjs +9 -3
  210. package/authoring/doctypes/template/type.ts +8 -0
  211. package/authoring/doctypes/theme/parse.d.mts +35 -0
  212. package/authoring/doctypes/theme/parse.mjs +76 -0
  213. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  214. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  215. package/authoring/doctypes/theme/type.ts +42 -0
  216. package/authoring/doctypes/types.ts +2 -1
  217. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  218. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  219. package/authoring/identity/identity.doc.mjs +2 -2
  220. package/authoring/index.d.mts +1 -0
  221. package/authoring/index.d.ts +7 -4
  222. package/authoring/index.mjs +2 -1
  223. package/authoring/integration/integration.doc.mjs +2 -2
  224. package/authoring/integration/type.ts +4 -10
  225. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  226. package/clients/cli/commands/blog.doc.mjs +1 -1
  227. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  228. package/clients/cli/commands/build-theme.mjs +11 -45
  229. package/clients/cli/commands/build.doc.mjs +12 -7
  230. package/clients/cli/commands/build.mjs +105 -67
  231. package/clients/cli/commands/build.text-fields.test.mjs +41 -0
  232. package/clients/cli/commands/component/index.mjs +1 -1
  233. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  234. package/clients/cli/commands/component.doc.mjs +1 -1
  235. package/clients/cli/commands/discover.broken-integration.test.mjs +7 -8
  236. package/clients/cli/commands/discover.doc.mjs +1 -1
  237. package/clients/cli/commands/discover.mjs +1 -1
  238. package/clients/cli/commands/docs.doc.mjs +21 -9
  239. package/clients/cli/commands/docs.mjs +184 -70
  240. package/clients/cli/commands/docs.test.mjs +120 -16
  241. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  242. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  243. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  244. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  245. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  246. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  247. package/clients/cli/commands/doctor.doc.mjs +1 -1
  248. package/clients/cli/commands/doctor.mjs +53 -16
  249. package/clients/cli/commands/gap-report.doc.mjs +1 -1
  250. package/clients/cli/commands/hook.doc.mjs +1 -1
  251. package/clients/cli/commands/init.doc.mjs +1 -1
  252. package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
  253. package/clients/cli/commands/integration-add.doc.mjs +11 -1
  254. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  255. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  256. package/clients/cli/commands/integration.doc.mjs +1 -1
  257. package/clients/cli/commands/integration.mjs +1 -0
  258. package/clients/cli/commands/layout-check.doc.mjs +1 -1
  259. package/clients/cli/commands/layout-expand.doc.mjs +1 -1
  260. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  261. package/clients/cli/commands/layout.doc.mjs +1 -1
  262. package/clients/cli/commands/manifest.doc.mjs +1 -1
  263. package/clients/cli/commands/search.doc.mjs +1 -1
  264. package/clients/cli/commands/search.mjs +11 -2
  265. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  266. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  267. package/clients/cli/commands/template.doc.mjs +24 -7
  268. package/clients/cli/commands/template.mjs +4 -91
  269. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  270. package/clients/cli/commands/theme-add.doc.mjs +2 -2
  271. package/clients/cli/commands/theme-build.doc.mjs +1 -1
  272. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  273. package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
  274. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  275. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  276. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  277. package/clients/cli/commands/theme-template.doc.mjs +1 -1
  278. package/clients/cli/commands/theme.doc.mjs +1 -1
  279. package/clients/cli/commands/upgrade.doc.mjs +3 -2
  280. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  281. package/clients/cli/commands/upgrade.mjs +29 -7
  282. package/clients/cli/formatters/index.mjs +2 -0
  283. package/clients/cli/formatters/index.test.mjs +6 -0
  284. package/clients/cli/index.mjs +8 -0
  285. package/clients/cli/lib/hook-format.mjs +14 -5
  286. package/clients/cli/lib/manifest.mjs +9 -2
  287. package/foundation/agent-docs/agent-docs.d.mts +3 -2
  288. package/foundation/agent-docs/agent-docs.mjs +13 -9
  289. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  290. package/foundation/config/project-themes.test.mjs +11 -19
  291. package/foundation/config/project.d.mts +20 -11
  292. package/foundation/config/project.mjs +123 -80
  293. package/foundation/config/project.test.mjs +144 -21
  294. package/foundation/discovery/authoring-self-docs.d.mts +18 -0
  295. package/foundation/discovery/authoring-self-docs.mjs +37 -15
  296. package/foundation/discovery/authoring-self-docs.test.mjs +25 -9
  297. package/foundation/discovery/authoring-surface.d.mts +74 -0
  298. package/foundation/discovery/authoring-surface.mjs +525 -0
  299. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  300. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  301. package/foundation/discovery/cli-self-docs.mjs +490 -0
  302. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  303. package/foundation/discovery/component-discovery.d.mts +38 -0
  304. package/foundation/discovery/component-discovery.mjs +48 -0
  305. package/foundation/discovery/component-loader.d.mts +35 -38
  306. package/foundation/discovery/component-loader.mjs +53 -222
  307. package/foundation/discovery/docs-discovery.d.mts +112 -11
  308. package/foundation/discovery/docs-discovery.mjs +231 -36
  309. package/foundation/discovery/docs-discovery.test.mjs +111 -32
  310. package/foundation/discovery/docs-output-budget.d.mts +2 -2
  311. package/foundation/discovery/docs-output-budget.mjs +1 -1
  312. package/foundation/discovery/docs-section-key.d.mts +28 -10
  313. package/foundation/discovery/docs-section-key.mjs +134 -33
  314. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  315. package/foundation/discovery/template-adapter.d.mts +99 -6
  316. package/foundation/discovery/template-adapter.mjs +480 -57
  317. package/foundation/discovery/template-adapter.test.mjs +57 -0
  318. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  319. package/foundation/discovery/template-conflict-release.mjs +40 -0
  320. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  321. package/foundation/discovery/theme-discovery.d.mts +67 -7
  322. package/foundation/discovery/theme-discovery.mjs +916 -186
  323. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  324. package/foundation/doc-compiler/bundle.d.mts +47 -0
  325. package/foundation/doc-compiler/bundle.mjs +278 -0
  326. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  327. package/foundation/doc-compiler/compile.d.mts +220 -39
  328. package/foundation/doc-compiler/compile.mjs +311 -15
  329. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  330. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  331. package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
  332. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  333. package/foundation/doc-compiler/import.d.mts +24 -0
  334. package/foundation/doc-compiler/import.mjs +59 -0
  335. package/foundation/doc-compiler/inputs.d.mts +102 -0
  336. package/foundation/doc-compiler/inputs.mjs +291 -0
  337. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  338. package/foundation/doc-compiler/ir.d.mts +13 -0
  339. package/foundation/doc-compiler/ir.mjs +196 -12
  340. package/foundation/doc-compiler/lenses.d.mts +8 -5
  341. package/foundation/doc-compiler/lenses.mjs +50 -4
  342. package/foundation/doc-compiler/links.d.mts +162 -0
  343. package/foundation/doc-compiler/links.mjs +294 -0
  344. package/foundation/doc-compiler/links.test.mjs +192 -0
  345. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  346. package/foundation/doc-compiler/overlays.d.mts +37 -0
  347. package/foundation/doc-compiler/overlays.mjs +206 -0
  348. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  349. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  350. package/foundation/doc-compiler/read.d.mts +127 -0
  351. package/foundation/doc-compiler/read.mjs +325 -0
  352. package/foundation/doc-compiler/read.test.mjs +313 -0
  353. package/foundation/doc-compiler/source.d.mts +33 -0
  354. package/foundation/doc-compiler/source.mjs +128 -0
  355. package/foundation/doc-compiler/tree.d.mts +288 -0
  356. package/foundation/doc-compiler/tree.mjs +876 -0
  357. package/foundation/doc-compiler/tree.test.mjs +598 -0
  358. package/foundation/fs/file-protection.d.mts +33 -0
  359. package/foundation/fs/file-protection.mjs +825 -0
  360. package/foundation/fs/file-protection.test.mjs +250 -0
  361. package/foundation/integrations/autolink.d.mts +58 -1
  362. package/foundation/integrations/autolink.mjs +143 -57
  363. package/foundation/integrations/autolink.test.mjs +1 -1
  364. package/foundation/integrations/cli-requirement.d.mts +45 -0
  365. package/foundation/integrations/cli-requirement.mjs +154 -0
  366. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  367. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  368. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  369. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  370. package/foundation/integrations/contribution-inventory.mjs +27 -24
  371. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  372. package/foundation/integrations/integration-warnings.d.mts +9 -2
  373. package/foundation/integrations/integration-warnings.mjs +51 -26
  374. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  375. package/foundation/integrations/integrations.d.mts +3 -0
  376. package/foundation/integrations/integrations.mjs +11 -97
  377. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  378. package/foundation/integrations/provider-resolution.d.mts +152 -0
  379. package/foundation/integrations/provider-resolution.mjs +576 -0
  380. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  381. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  382. package/foundation/integrations/theme-descriptor.mjs +44 -0
  383. package/foundation/integrations/validate-contributions.mjs +121 -29
  384. package/foundation/response/error-codes.d.mts +3 -1
  385. package/foundation/response/error-codes.d.ts +2 -0
  386. package/foundation/response/error-codes.doc.mjs +12 -2
  387. package/foundation/response/error-codes.mjs +7 -1
  388. package/foundation/response/error-codes.test.mjs +55 -11
  389. package/foundation/response/response-types.doc.d.mts +5 -1
  390. package/foundation/response/response-types.doc.mjs +20 -11
  391. package/foundation/response/response.doc.mjs +1 -1
  392. package/foundation/text/string-utils.d.mts +8 -0
  393. package/foundation/text/string-utils.mjs +40 -10
  394. package/foundation/xle/expand.mjs +1 -1
  395. package/foundation/xle/xle.test.mjs +13 -0
  396. package/package.json +10 -9
  397. package/assets/templates/themes/manifest.json +0 -95
@@ -0,0 +1,598 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Tests for the docs tree (spec:AST-046): one home per doc, decided by
5
+ * explicit placement, then one adoption rule; every way a placement can fail;
6
+ * generated kind levels; deterministic order; and the CLI's own tree.
7
+ *
8
+ * @input Plain fixture inputs for the pure builder, and this package's own
9
+ * tree files and typed docs for the loader.
10
+ * @output Assertions on routes, parents, slots, children order, and
11
+ * diagnostics.
12
+ * @position packages/cli/foundation/doc-compiler — tests for tree.mjs.
13
+ */
14
+
15
+ import {describe, expect, it} from 'vitest';
16
+ import {
17
+ buildDocsTree,
18
+ KIND_GROUPS,
19
+ loadDocsTree,
20
+ loadTreeInputs,
21
+ routeSegment,
22
+ } from './tree.mjs';
23
+ import {loadCliSelfDocs} from '../discovery/cli-self-docs.mjs';
24
+ import * as api from '../../api/index.mjs';
25
+ import {createDocId} from '../identity/provider-identity.mjs';
26
+ import {CLI_PROVIDER_ID} from '../identity/providers.mjs';
27
+
28
+ const SLOW = 60_000;
29
+ const P = '@acme/kit';
30
+
31
+ /**
32
+ * @param {string} name
33
+ * @param {object} [extra]
34
+ * @returns {import('./tree.mjs').TreeNamespaceInput}
35
+ */
36
+ const ns = (name, extra = {}) => ({
37
+ provider: P,
38
+ providerId: P,
39
+ source: `${P}/tree/${name}.doc.mjs`,
40
+ doc: /** @type {any} */ ({
41
+ type: 'namespace',
42
+ name,
43
+ title: name.toUpperCase(),
44
+ summary: `The ${name} level.`,
45
+ slots: {
46
+ items: {title: 'Items', accepts: {kinds: ['generic', 'namespace']}},
47
+ },
48
+ ...extra,
49
+ }),
50
+ });
51
+
52
+ /**
53
+ * @param {string} name
54
+ * @param {object} [extra]
55
+ * @returns {import('./tree.mjs').TreeDocInput}
56
+ */
57
+ const guide = (name, extra = {}) => ({
58
+ provider: P,
59
+ providerId: P,
60
+ source: `${P}/tree/${name}.doc.mjs`,
61
+ kind: 'generic',
62
+ name,
63
+ title: `Guide ${name}`,
64
+ summary: `About ${name}.`,
65
+ group: null,
66
+ placement: undefined,
67
+ ...extra,
68
+ });
69
+
70
+ /**
71
+ * @param {string} kind
72
+ * @param {string} name
73
+ * @param {string} group
74
+ * @returns {import('./tree.mjs').TreeDocInput}
75
+ */
76
+ const typed = (kind, name, group) => ({
77
+ provider: P,
78
+ providerId: P,
79
+ source: `${P}/api/${name}.doc.mjs`,
80
+ kind,
81
+ name,
82
+ title: name,
83
+ summary: `The ${name} ${kind}.`,
84
+ group,
85
+ placement: undefined,
86
+ });
87
+
88
+ /** @param {ReturnType<typeof buildDocsTree>} tree */
89
+ const routes = tree => [...tree.nodes.keys()];
90
+
91
+ /** @param {ReturnType<typeof buildDocsTree>} tree */
92
+ const problems = tree => tree.diagnostics.map(d => [d.code, d.message]);
93
+
94
+ describe('buildDocsTree', () => {
95
+
96
+ it('withdraws a namespace placed in a withdrawn namespace, and what is placed in it', () => {
97
+ const CLI = '@astryxdesign/cli';
98
+ const tree = buildDocsTree({
99
+ namespaces: [
100
+ ns('tokens'),
101
+ ns('alpha', {placement: {parent: 'namespace:tokens', slot: 'items'}}),
102
+ ],
103
+ docs: [guide('deep', {placement: {parent: 'namespace:alpha', slot: 'items'}})],
104
+ topics: [
105
+ {provider: CLI, providerId: CLI, name: 'tokens', title: 'Tokens', summary: 'Tokens.', source: `${CLI}/tokens.doc.mjs`},
106
+ ],
107
+ });
108
+ expect(tree.get('tokens')?.provider).toBe(CLI);
109
+ expect(routes(tree).filter(route => route.startsWith('tokens/'))).toEqual([]);
110
+ expect(problems(tree)).toEqual(
111
+ expect.arrayContaining([
112
+ ['duplicate_route', expect.stringContaining('takes the route "tokens"')],
113
+ ['invalid_placement', 'Namespace "alpha" has no route: the namespace it is placed in was withdrawn.'],
114
+ ['invalid_placement', expect.stringContaining('names a namespace that has no route')],
115
+ ]),
116
+ );
117
+ });
118
+
119
+ it("keeps a name a topic answers to through replaces as that topic's route", () => {
120
+ const tree = buildDocsTree({
121
+ namespaces: [ns('tokens')],
122
+ docs: [],
123
+ topics: [
124
+ {provider: '@acme/a', providerId: '@acme/a', name: 'acme-tokens', title: 'Acme tokens', summary: 'Acme tokens.', source: '@acme/a:acme-tokens', aliases: ['tokens', 'old-tokens']},
125
+ ],
126
+ });
127
+ expect(tree.get('tokens')).toBeUndefined();
128
+ expect(tree.get('acme-tokens')?.provider).toBe('@acme/a');
129
+ expect(problems(tree)).toEqual([
130
+ ['duplicate_route', expect.stringContaining('takes the route "tokens", which the topic "acme-tokens" also answers to')],
131
+ ]);
132
+ // Every name it answers to is reserved, not only the last one it replaced.
133
+ const older = buildDocsTree({
134
+ namespaces: [ns('old-tokens')],
135
+ docs: [],
136
+ topics: [
137
+ {provider: '@acme/a', providerId: '@acme/a', name: 'acme-tokens', title: 'Acme tokens', summary: 'Acme tokens.', source: '@acme/a:acme-tokens', aliases: ['tokens', 'old-tokens']},
138
+ ],
139
+ });
140
+ expect(older.get('old-tokens')).toBeUndefined();
141
+ });
142
+
143
+ it("keeps the CLI's own routes from an integration, compared without case", () => {
144
+ const CLI = '@astryxdesign/cli';
145
+ /** @param {string} name @param {string} [provider] */
146
+ const topic = (name, provider = P) => ({
147
+ provider,
148
+ providerId: provider,
149
+ name,
150
+ title: name,
151
+ summary: `The ${name} topic.`,
152
+ source: `${provider}/${name}.doc.mjs`,
153
+ });
154
+ const cliNs = {...ns('cli'), provider: CLI, providerId: CLI, source: `${CLI}/tree/cli.doc.mjs`};
155
+ // An integration's topics named `CLI` and `UNORGANIZED` claim the CLI's
156
+ // namespace and the generated level; both are withdrawn.
157
+ const tree = buildDocsTree({
158
+ namespaces: [cliNs],
159
+ docs: [],
160
+ topics: [topic('theme', CLI), topic('CLI'), topic('UNORGANIZED')],
161
+ });
162
+ expect(tree.get('cli')?.provider).toBe(CLI);
163
+ expect(tree.get('unorganized')?.provider).toBe(CLI);
164
+ expect(routes(tree)).not.toContain('CLI');
165
+ expect(routes(tree)).not.toContain('UNORGANIZED');
166
+ expect(problems(tree)).toEqual(
167
+ expect.arrayContaining([
168
+ ['duplicate_route', expect.stringContaining('both have the route "CLI"')],
169
+ ['duplicate_route', expect.stringContaining('takes the route "UNORGANIZED", which the CLI\'s own docs keep')],
170
+ ]),
171
+ );
172
+ expect(tree.getFolded('THEME')?.provider).toBe(CLI);
173
+ // A CLI topic whose own name has capitals keeps its route against a
174
+ // lowercase namespace, although namespaces go into the tree first.
175
+ const caps = buildDocsTree({namespaces: [ns('tokens')], docs: [], topics: [topic('Tokens', CLI)]});
176
+ expect(caps.get('Tokens')?.provider).toBe(CLI);
177
+ expect(caps.get('tokens')).toBeUndefined();
178
+ expect(problems(caps)).toEqual([
179
+ ['duplicate_route', expect.stringContaining('takes the route "tokens", which the CLI\'s own docs keep')],
180
+ ]);
181
+ });
182
+ it('builds three authored levels and a guide below them', () => {
183
+ const tree = buildDocsTree({
184
+ namespaces: [
185
+ ns('top'),
186
+ ns('middle', {placement: {parent: 'namespace:top', slot: 'items'}}),
187
+ ns('bottom', {placement: {parent: 'namespace:middle'}}),
188
+ ],
189
+ docs: [
190
+ guide('deep', {placement: {parent: 'namespace:bottom', order: 1}}),
191
+ ],
192
+ });
193
+ expect(problems(tree)).toEqual([]);
194
+ expect(routes(tree)).toEqual([
195
+ 'top',
196
+ 'top/middle',
197
+ 'top/middle/bottom',
198
+ 'top/middle/bottom/deep',
199
+ ]);
200
+ const deep = /** @type {any} */ (tree.get('top/middle/bottom/deep'));
201
+ expect(deep).toMatchObject({
202
+ id: 'astryx:artifact:v1/%40acme%2Fkit/generic/deep',
203
+ parent: 'top/middle/bottom',
204
+ slot: 'items',
205
+ order: 1,
206
+ generated: false,
207
+ });
208
+ expect(tree.ancestors(deep).map(node => node.route)).toEqual([
209
+ 'top',
210
+ 'top/middle',
211
+ 'top/middle/bottom',
212
+ ]);
213
+ expect(tree.roots().map(node => node.route)).toEqual(['top']);
214
+ });
215
+
216
+ it('adopts typed docs by group, with one generated level per kind', () => {
217
+ const tree = buildDocsTree({
218
+ namespaces: [
219
+ ns('api', {
220
+ slots: {kinds: {title: 'Reference', accepts: {kinds: ['namespace']}}},
221
+ adopts: [
222
+ {
223
+ source: {group: 'kit/api', kinds: ['function', 'enum']},
224
+ into: 'kinds',
225
+ groupBy: 'kind',
226
+ },
227
+ ],
228
+ }),
229
+ ],
230
+ docs: [
231
+ typed('enum', 'errorCodes', 'kit/api'),
232
+ typed('function', 'search', 'kit/api'),
233
+ typed('function', 'build', 'kit/api'),
234
+ typed('schema', 'config', 'kit/api'),
235
+ typed('function', 'other', 'kit/elsewhere'),
236
+ ],
237
+ });
238
+ expect(problems(tree)).toEqual([]);
239
+ expect(routes(tree)).toEqual([
240
+ 'api',
241
+ 'api/enums',
242
+ 'api/enums/error-codes',
243
+ 'api/functions',
244
+ 'api/functions/build',
245
+ 'api/functions/search',
246
+ ]);
247
+ const functions = /** @type {any} */ (tree.get('api/functions'));
248
+ expect(functions).toMatchObject({
249
+ id: null,
250
+ kind: 'namespace',
251
+ title: KIND_GROUPS.function.title,
252
+ generated: true,
253
+ parent: 'api',
254
+ slot: 'kinds',
255
+ });
256
+ // Kind levels follow the rule's kind order; docs inside sort by title.
257
+ expect(tree.get('api')?.slots[0].children).toEqual([
258
+ 'api/functions',
259
+ 'api/enums',
260
+ ]);
261
+ expect(functions.slots[0].children).toEqual([
262
+ 'api/functions/build',
263
+ 'api/functions/search',
264
+ ]);
265
+ });
266
+
267
+ it('adopts without grouping straight into the named slot', () => {
268
+ const tree = buildDocsTree({
269
+ namespaces: [
270
+ ns('commands', {
271
+ slots: {all: {title: 'All', accepts: {kinds: ['command']}}},
272
+ adopts: [{source: {group: 'kit/commands'}, into: 'all'}],
273
+ }),
274
+ ],
275
+ docs: [typed('command', 'theme add', 'kit/commands')],
276
+ });
277
+ expect(routes(tree)).toEqual(['commands', 'commands/theme-add']);
278
+ expect(tree.get('commands')?.slots[0].children).toEqual([
279
+ 'commands/theme-add',
280
+ ]);
281
+ });
282
+
283
+ it('prefers explicit placement over adoption, and never falls back', () => {
284
+ const namespaces = [
285
+ ns('guides'),
286
+ ns('api', {
287
+ slots: {all: {title: 'All', accepts: {kinds: ['generic']}}},
288
+ adopts: [{source: {group: 'kit/api'}, into: 'all'}],
289
+ }),
290
+ ];
291
+ const placed = buildDocsTree({
292
+ namespaces,
293
+ docs: [
294
+ guide('intro', {
295
+ group: 'kit/api',
296
+ placement: {parent: 'namespace:guides'},
297
+ }),
298
+ ],
299
+ });
300
+ expect(routes(placed)).toContain('guides/intro');
301
+ expect(routes(placed)).not.toContain('api/intro');
302
+
303
+ const broken = buildDocsTree({
304
+ namespaces,
305
+ docs: [
306
+ guide('intro', {
307
+ group: 'kit/api',
308
+ placement: {parent: 'namespace:nope'},
309
+ }),
310
+ ],
311
+ });
312
+ expect(routes(broken).some(route => route.endsWith('/intro'))).toBe(false);
313
+ expect(problems(broken)).toEqual([
314
+ [
315
+ 'invalid_placement',
316
+ 'placement.parent "namespace:nope" names no namespace; @acme/kit declares "api", "guides".',
317
+ ],
318
+ ]);
319
+ });
320
+
321
+ it('reports every way a placement can fail', () => {
322
+ const tree = buildDocsTree({
323
+ namespaces: [
324
+ ns('home', {
325
+ slots: {
326
+ one: {title: 'One', accepts: {kinds: ['generic']}},
327
+ two: {title: 'Two', accepts: {kinds: ['command']}},
328
+ },
329
+ }),
330
+ ],
331
+ docs: [
332
+ guide('no-slot', {placement: {parent: 'namespace:home'}}),
333
+ guide('bad-slot', {
334
+ placement: {parent: 'namespace:home', slot: 'three'},
335
+ }),
336
+ guide('wrong-kind', {
337
+ placement: {parent: 'namespace:home', slot: 'two'},
338
+ }),
339
+ guide('other-package', {
340
+ placement: {parent: '@other/pkg/namespace/home'},
341
+ }),
342
+ guide('not-a-ref', {placement: {parent: 'home'}}),
343
+ ],
344
+ });
345
+ expect(routes(tree)).toEqual(['home']);
346
+ expect(
347
+ problems(tree)
348
+ .map(([, message]) => message)
349
+ .sort(),
350
+ ).toEqual(
351
+ [
352
+ 'placement names no slot, and namespace "home" has 2 (one, two). Name one with placement.slot.',
353
+ 'placement.slot "three" is not a slot of namespace "home"; it declares one, two.',
354
+ 'slot "two" of namespace "home" does not accept generic docs; it accepts command.',
355
+ 'placement.parent "@other/pkg/namespace/home" belongs to @other/pkg. A doc can only be placed in a namespace of its own package (@acme/kit).',
356
+ 'placement.parent "home" is not a namespace reference. Write "namespace:<name>".',
357
+ ].sort(),
358
+ );
359
+ expect(tree.diagnostics.every(d => d.code === 'invalid_placement')).toBe(
360
+ true,
361
+ );
362
+ expect(tree.diagnostics.every(d => d.severity === 'error')).toBe(true);
363
+ });
364
+
365
+ it('fails a doc two namespaces adopt, naming both', () => {
366
+ const rule = {source: {group: 'kit/api'}, into: 'items'};
367
+ const tree = buildDocsTree({
368
+ namespaces: [ns('a', {adopts: [rule]}), ns('b', {adopts: [rule]})],
369
+ docs: [guide('shared', {group: 'kit/api'})],
370
+ });
371
+ expect(routes(tree)).toEqual(['a', 'b']);
372
+ expect(problems(tree)).toEqual([
373
+ [
374
+ 'overlapping_adoption',
375
+ '@acme/kit/generic/shared is adopted by "a" and "b"; exactly one namespace may adopt a doc.',
376
+ ],
377
+ ]);
378
+ });
379
+
380
+ it('fails two docs at one route, keeping the first by identity', () => {
381
+ const tree = buildDocsTree({
382
+ namespaces: [ns('home')],
383
+ docs: [
384
+ guide('fooBar', {placement: {parent: 'namespace:home'}}),
385
+ guide('foo_bar', {placement: {parent: 'namespace:home'}}),
386
+ ],
387
+ });
388
+ expect(routes(tree)).toEqual(['home', 'home/foo-bar']);
389
+ expect(tree.get('home/foo-bar')?.id).toBe(
390
+ 'astryx:artifact:v1/%40acme%2Fkit/generic/fooBar',
391
+ );
392
+ expect(problems(tree)).toEqual([
393
+ [
394
+ 'duplicate_route',
395
+ 'astryx:artifact:v1/%40acme%2Fkit/generic/foo_bar and astryx:artifact:v1/%40acme%2Fkit/generic/fooBar both have the route "home/foo-bar". Rename or move one of them.',
396
+ ],
397
+ ]);
398
+ });
399
+
400
+ it('fails a namespace cycle and everything under it', () => {
401
+ const tree = buildDocsTree({
402
+ namespaces: [
403
+ ns('a', {placement: {parent: 'namespace:b'}}),
404
+ ns('b', {placement: {parent: 'namespace:a'}}),
405
+ ],
406
+ docs: [guide('lost', {placement: {parent: 'namespace:a'}})],
407
+ });
408
+ expect(routes(tree)).toEqual([]);
409
+ expect(problems(tree).map(([code]) => code)).toEqual([
410
+ 'invalid_placement',
411
+ 'invalid_placement',
412
+ 'invalid_placement',
413
+ ]);
414
+ });
415
+
416
+ it('fails a duplicate or unsafe namespace name', () => {
417
+ const tree = buildDocsTree({
418
+ namespaces: [
419
+ ns('twice'),
420
+ {...ns('twice'), source: `${P}/other.doc.mjs`},
421
+ ns('Bad Name'),
422
+ ],
423
+ docs: [],
424
+ });
425
+ expect(routes(tree)).toEqual(['twice']);
426
+ expect(tree.diagnostics.map(d => d.code)).toEqual([
427
+ 'invalid_namespace',
428
+ 'invalid_namespace',
429
+ ]);
430
+ });
431
+
432
+ it('leaves a doc with no placement and no adoption out, in phase 1', () => {
433
+ const tree = buildDocsTree({
434
+ namespaces: [ns('home')],
435
+ docs: [guide('loose'), typed('function', 'free', 'kit/nowhere')],
436
+ });
437
+ expect(routes(tree)).toEqual(['home']);
438
+ expect(tree.diagnostics).toEqual([]);
439
+ });
440
+
441
+ it('is the same tree whatever order its inputs arrive in', () => {
442
+ const namespaces = [
443
+ ns('top'),
444
+ ns('child', {placement: {parent: 'namespace:top'}}),
445
+ ];
446
+ const docs = [
447
+ guide('b', {placement: {parent: 'namespace:child'}}),
448
+ guide('a', {placement: {parent: 'namespace:child'}}),
449
+ ];
450
+ const one = buildDocsTree({namespaces, docs});
451
+ const two = buildDocsTree({
452
+ namespaces: [...namespaces].reverse(),
453
+ docs: [...docs].reverse(),
454
+ });
455
+ expect(JSON.stringify([...two.nodes])).toBe(JSON.stringify([...one.nodes]));
456
+ });
457
+
458
+ it('orders children by order, then title', () => {
459
+ const tree = buildDocsTree({
460
+ namespaces: [ns('home')],
461
+ docs: [
462
+ guide('z', {
463
+ title: 'Zed',
464
+ placement: {parent: 'namespace:home', order: 1},
465
+ }),
466
+ guide('b', {title: 'Beta', placement: {parent: 'namespace:home'}}),
467
+ guide('a', {title: 'Alpha', placement: {parent: 'namespace:home'}}),
468
+ ],
469
+ });
470
+ expect(tree.get('home')?.slots[0].children).toEqual([
471
+ 'home/z',
472
+ 'home/a',
473
+ 'home/b',
474
+ ]);
475
+ });
476
+ });
477
+
478
+ describe('routeSegment', () => {
479
+ it('joins lowercase words with hyphens, whatever the name looks like', () => {
480
+ expect(routeSegment('integrationPackCheck')).toBe('integration-pack-check');
481
+ expect(routeSegment('doctor integration validate')).toBe(
482
+ 'doctor-integration-validate',
483
+ );
484
+ expect(routeSegment('error-codes')).toBe('error-codes');
485
+ expect(routeSegment('isError')).toBe('is-error');
486
+ expect(routeSegment('!!')).toBe('');
487
+ });
488
+ });
489
+
490
+ describe("the CLI's own docs tree", () => {
491
+ it(
492
+ 'builds with no diagnostic, rooted at cli',
493
+ async () => {
494
+ const tree = await loadDocsTree({fresh: true});
495
+ expect(tree.diagnostics).toEqual([]);
496
+ expect(tree.roots().map(node => node.route)).toEqual(['cli']);
497
+ expect(
498
+ tree.get('cli')?.slots.map(slot => [slot.name, slot.children]),
499
+ ).toEqual([
500
+ ['guides', ['cli/integrations', 'cli/writing-docs']],
501
+ ['reference', ['cli/commands', 'cli/api']],
502
+ ]);
503
+ expect(tree.get('cli/api')?.slots[0].children).toEqual([
504
+ 'cli/api/functions',
505
+ 'cli/api/schemas',
506
+ 'cli/api/enums',
507
+ ]);
508
+ },
509
+ SLOW,
510
+ );
511
+
512
+ it(
513
+ 'gives every CLI typed doc in a cli group one route, by its kind',
514
+ async () => {
515
+ const tree = await loadDocsTree();
516
+ const {loaded} = await loadCliSelfDocs();
517
+ const inTree = loaded.filter(({doc}) =>
518
+ String(doc.namespace).startsWith('cli/'),
519
+ );
520
+ expect(inTree.length).toBeGreaterThan(0);
521
+ const expected = inTree.map(({doc}) =>
522
+ doc.type === 'command'
523
+ ? `cli/commands/${routeSegment(doc.name)}`
524
+ : `cli/api/${KIND_GROUPS[doc.type].segment}/${routeSegment(doc.name)}`,
525
+ );
526
+ expect(expected.filter(route => tree.get(route) == null)).toEqual([]);
527
+ // A doc in the authoring group stays a section of `astryx docs authoring`.
528
+ const authoring = loaded.filter(({doc}) => doc.namespace === 'authoring');
529
+ expect(authoring.length).toBeGreaterThan(0);
530
+ const ids = new Set([...tree.nodes.values()].map(node => node.id));
531
+ expect(
532
+ authoring.filter(({doc}) =>
533
+ ids.has(createDocId(CLI_PROVIDER_ID, doc.type, doc.name)),
534
+ ),
535
+ ).toEqual([]);
536
+ },
537
+ SLOW,
538
+ );
539
+
540
+ it(
541
+ 'gives every function @astryxdesign/cli/api exports a route',
542
+ async () => {
543
+ const tree = await loadDocsTree();
544
+ const exported = Object.entries(api)
545
+ .filter(
546
+ ([, value]) =>
547
+ typeof value === 'function' &&
548
+ Object.getOwnPropertyDescriptor(value, 'prototype')?.writable !==
549
+ false,
550
+ )
551
+ .map(([name]) => `cli/api/functions/${routeSegment(name)}`);
552
+ expect(exported.length).toBeGreaterThan(0);
553
+ expect(exported.filter(route => tree.get(route) == null)).toEqual([]);
554
+ },
555
+ SLOW,
556
+ );
557
+
558
+ it(
559
+ 'reads only namespace and generic docs from the tree directory, each named after its file',
560
+ async () => {
561
+ const inputs = await loadTreeInputs({selfDocs: false});
562
+ expect(inputs.diagnostics).toEqual([]);
563
+ expect(inputs.namespaces.map(n => n.doc.name).sort()).toEqual([
564
+ 'api',
565
+ 'cli',
566
+ 'commands',
567
+ ]);
568
+ expect(inputs.docs.map(d => [d.name, d.placement?.parent])).toEqual([
569
+ ['integrations', 'namespace:cli'],
570
+ ['writing-docs', 'namespace:cli'],
571
+ ]);
572
+ },
573
+ SLOW,
574
+ );
575
+ });
576
+
577
+ describe('doc identity', () => {
578
+ it('builds each id from the provider id, never the package name', () => {
579
+ const provider = '@acme/tree-provider';
580
+ const tree = buildDocsTree({
581
+ namespaces: [{...ns('home'), providerId: provider}],
582
+ docs: [
583
+ {
584
+ ...guide('intro', {placement: {parent: 'namespace:home'}}),
585
+ providerId: provider,
586
+ },
587
+ ],
588
+ });
589
+ expect(problems(tree)).toEqual([]);
590
+ expect(tree.get('home')?.id).toBe(
591
+ 'astryx:artifact:v1/%40acme%2Ftree-provider/namespace/home',
592
+ );
593
+ expect(tree.get('home/intro')).toMatchObject({
594
+ id: 'astryx:artifact:v1/%40acme%2Ftree-provider/generic/intro',
595
+ provider: P,
596
+ });
597
+ });
598
+ });
@@ -0,0 +1,33 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * @typedef {{file: string, reason: 'generated'|'vendored'|'ignored'|'dependency'|'vcs'|'symlink'|'outside-root', declaration: string, source?: string, line?: number, command?: string}} FileProtection
6
+ */
7
+ /**
8
+ * Create an eager, fail-closed resolver. Every declaration under root is parsed
9
+ * before the caller can begin writing consumer files.
10
+ * @param {string} root
11
+ * @param {{overrides?: Map<string, string|null>}} [options]
12
+ */
13
+ export function createFileProtectionResolver(root: string, { overrides }?: {
14
+ overrides?: Map<string, string | null>;
15
+ }): Readonly<{
16
+ root: string;
17
+ classify: (filePath: string) => FileProtection[];
18
+ }>;
19
+ /** A stable failure raised before any consumer write. */
20
+ export class ProtectionSourceError extends Error {
21
+ /** @param {string} source @param {string} reason */
22
+ constructor(source: string, reason: string);
23
+ code: string;
24
+ source: string;
25
+ }
26
+ export type FileProtection = {
27
+ file: string;
28
+ reason: "generated" | "vendored" | "ignored" | "dependency" | "vcs" | "symlink" | "outside-root";
29
+ declaration: string;
30
+ source?: string;
31
+ line?: number;
32
+ command?: string;
33
+ };