@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.3-canary.02f5fe4

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 (694) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +216 -162
  3. package/api/build/_adapter.d.mts +66 -0
  4. package/api/build/_adapter.mjs +139 -4
  5. package/api/build/blocks/blocks.d.mts +92 -0
  6. package/api/build/blocks/blocks.mjs +528 -0
  7. package/api/build/blocks/blocks.test.mjs +238 -0
  8. package/api/build/blocks/blocks.weights.json +1 -0
  9. package/api/build/build.doc.mjs +4 -0
  10. package/api/build/build.mjs +25 -6
  11. package/api/build/build.type.mjs +1 -1
  12. package/api/build/help/help.mjs +1 -1
  13. package/api/build/kit/answer.d.mts +18 -0
  14. package/api/build/kit/answer.mjs +195 -0
  15. package/api/build/kit/answer.test.mjs +108 -0
  16. package/api/build/kit/kind.d.mts +25 -0
  17. package/api/build/kit/kind.mjs +170 -0
  18. package/api/build/kit/kit.d.mts +2 -4
  19. package/api/build/kit/kit.mjs +8 -406
  20. package/api/build/kit/rank.d.mts +3 -32
  21. package/api/build/kit/rank.mjs +25 -342
  22. package/api/build/kit/rank.test.mjs +2 -1
  23. package/api/build/kit/signals.d.mts +79 -0
  24. package/api/build/kit/signals.mjs +295 -0
  25. package/api/build/kit/start.d.mts +32 -0
  26. package/api/build/kit/start.mjs +163 -0
  27. package/api/build/kit/words.d.mts +72 -0
  28. package/api/build/kit/words.mjs +202 -0
  29. package/api/build/tree.d.mts +20 -0
  30. package/api/build/tree.mjs +53 -0
  31. package/api/build/tree.test.mjs +185 -0
  32. package/api/build/tree.weights.json +1 -0
  33. package/api/component/_adapter.d.mts +72 -1
  34. package/api/component/_adapter.mjs +251 -23
  35. package/api/component/component-replacement.test.mjs +1 -0
  36. package/api/component/component.doc.mjs +6 -1
  37. package/api/component/component.mjs +97 -16
  38. package/api/component/component.test.mjs +95 -0
  39. package/api/component/doc-links.test.mjs +386 -0
  40. package/api/component/integration-export-name.test.mjs +644 -0
  41. package/api/component/list/list.mjs +42 -4
  42. package/api/discover/_adapter.d.mts +131 -12
  43. package/api/discover/_adapter.mjs +520 -34
  44. package/api/discover/_adapter.test.mjs +641 -17
  45. package/api/discover/_catalog-view.d.mts +16 -5
  46. package/api/discover/_catalog-view.mjs +32 -8
  47. package/api/discover/detail/doc/doc.mjs +9 -1
  48. package/api/discover/discover.d.mts +11 -0
  49. package/api/discover/discover.doc.mjs +9 -7
  50. package/api/discover/discover.mjs +120 -19
  51. package/api/discover/discover.type.d.mts +20 -7
  52. package/api/discover/discover.type.mjs +17 -7
  53. package/api/discover/list/list.d.mts +4 -3
  54. package/api/discover/list/list.mjs +17 -10
  55. package/api/docs/_adapter.d.mts +76 -2
  56. package/api/docs/_adapter.mjs +630 -34
  57. package/api/docs/docs-homes.test.mjs +127 -0
  58. package/api/docs/docs.doc.mjs +5 -4
  59. package/api/docs/docs.mjs +2 -1
  60. package/api/docs/docs.test.mjs +39 -20
  61. package/api/docs/integration-tree.test.mjs +42 -20
  62. package/api/docs/integrationDocs.test.mjs +125 -1
  63. package/api/docs/list/list.mjs +12 -2
  64. package/api/docs/namespace-section.test.mjs +6 -6
  65. package/api/docs/reference-blocks.test.mjs +3 -5
  66. package/api/doctor/_adapter.d.mts +128 -0
  67. package/api/doctor/_adapter.mjs +253 -4
  68. package/api/doctor/doctor.d.mts +217 -0
  69. package/api/doctor/doctor.doc.mjs +3 -2
  70. package/api/doctor/doctor.mjs +691 -52
  71. package/api/doctor/doctor.test.mjs +267 -18
  72. package/api/doctor/release-checks.test.mjs +156 -0
  73. package/api/doctor/theme-checks.mjs +17 -4
  74. package/api/doctor/theme-checks.test.mjs +223 -7
  75. package/api/error.d.mts +10 -0
  76. package/api/error.mjs +25 -0
  77. package/api/gap-report/gap-report.d.mts +3 -0
  78. package/api/gap-report/gap-report.doc.mjs +11 -3
  79. package/api/gap-report/gap-report.mjs +219 -52
  80. package/api/gap-report/gap-report.test.mjs +233 -0
  81. package/api/gap-report/gap-report.type.d.mts +41 -0
  82. package/api/gap-report/gap-report.type.mjs +18 -0
  83. package/api/hook/_adapter.mjs +3 -11
  84. package/api/hook/hook.doc.mjs +4 -0
  85. package/api/hook/hook.mjs +1 -1
  86. package/api/hook/list/list.d.mts +1 -1
  87. package/api/index.d.mts +2 -0
  88. package/api/index.mjs +2 -0
  89. package/api/init/_adapter.d.mts +22 -0
  90. package/api/init/_adapter.mjs +59 -0
  91. package/api/init/init.d.mts +7 -5
  92. package/api/init/init.doc.mjs +45 -10
  93. package/api/init/init.mjs +28 -4
  94. package/api/init/init.test.mjs +18 -2
  95. package/api/init/init.type.d.mts +50 -5
  96. package/api/init/init.type.mjs +39 -5
  97. package/api/init/remove/remove.mjs +17 -4
  98. package/api/init/remove/remove.test.mjs +114 -2
  99. package/api/init/run/run.d.mts +1 -1
  100. package/api/init/run/run.mjs +86 -12
  101. package/api/init/user/user.d.mts +14 -0
  102. package/api/init/user/user.mjs +87 -0
  103. package/api/init/user/user.test.mjs +232 -0
  104. package/api/integration/_adapter.d.mts +53 -0
  105. package/api/integration/_adapter.mjs +132 -0
  106. package/api/integration/add-contribution.component-names.test.mjs +66 -0
  107. package/api/integration/add-contribution.mjs +8 -4
  108. package/api/integration/add-contribution.test.mjs +4 -2
  109. package/api/integration/authoring-checks.mjs +192 -14
  110. package/api/integration/authoring-checks.test.mjs +1028 -0
  111. package/api/integration/authoring-checks.type.d.mts +143 -0
  112. package/api/integration/authoring-checks.type.mjs +74 -2
  113. package/api/integration/check/check.d.mts +96 -0
  114. package/api/integration/check/check.mjs +357 -0
  115. package/api/integration/check/check.test.mjs +489 -0
  116. package/api/integration/integration-check.type.d.mts +118 -0
  117. package/api/integration/integration-check.type.mjs +84 -0
  118. package/api/integration/integrationCheck.doc.d.mts +10 -0
  119. package/api/integration/integrationCheck.doc.mjs +73 -0
  120. package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
  121. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  122. package/api/integration/pack-check.mjs +486 -123
  123. package/api/integration/pack-check.test.mjs +817 -10
  124. package/api/integration/validate-integration-case-disk.test.mjs +111 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +73 -5
  126. package/api/integration/validate-integration-gaps.test.mjs +1975 -0
  127. package/api/integration/validate-integration.d.mts +23 -2
  128. package/api/integration/validate-integration.mjs +358 -45
  129. package/api/integration/validate-integration.test.mjs +88 -8
  130. package/api/integration/validate-integration.type.d.mts +105 -0
  131. package/api/integration/validate-integration.type.mjs +79 -1
  132. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  133. package/api/integration/validateIntegration.doc.mjs +19 -3
  134. package/api/search/ORDERING.md +28 -0
  135. package/api/search/_adapter.d.mts +91 -0
  136. package/api/search/_adapter.mjs +172 -0
  137. package/api/search/_adapter.test.mjs +173 -0
  138. package/api/search/_candidate-score.d.mts +40 -0
  139. package/api/search/_candidate-score.mjs +238 -0
  140. package/api/search/_cards.json +6098 -0
  141. package/api/search/_compound.d.mts +50 -0
  142. package/api/search/_compound.mjs +170 -0
  143. package/api/search/_doc-searcher.d.mts +4 -0
  144. package/api/search/_doc-searcher.mjs +23 -0
  145. package/api/search/_doc-searcher.test.mjs +36 -0
  146. package/api/search/_doc-searcher.weights.json +1 -0
  147. package/api/search/_doc-text.d.mts +30 -0
  148. package/api/search/_doc-text.mjs +87 -0
  149. package/api/search/_entries.d.mts +63 -0
  150. package/api/search/_entries.mjs +232 -0
  151. package/api/search/_entries.test.mjs +48 -0
  152. package/api/search/_features.d.mts +35 -0
  153. package/api/search/_features.mjs +155 -0
  154. package/api/search/_gather-components.d.mts +26 -0
  155. package/api/search/_gather-components.mjs +284 -0
  156. package/api/search/_gather-docs.d.mts +20 -0
  157. package/api/search/_gather-docs.mjs +254 -0
  158. package/api/search/_gather-hooks.d.mts +12 -0
  159. package/api/search/_gather-hooks.mjs +52 -0
  160. package/api/search/_gather-templates.d.mts +25 -0
  161. package/api/search/_gather-templates.mjs +107 -0
  162. package/api/search/_lexical.d.mts +135 -0
  163. package/api/search/_lexical.mjs +351 -0
  164. package/api/search/_main-searcher.d.mts +19 -0
  165. package/api/search/_main-searcher.mjs +115 -0
  166. package/api/search/_main-searcher.test.mjs +106 -0
  167. package/api/search/_main-searcher.weights.json +1 -0
  168. package/api/search/_module-doc.d.mts +32 -0
  169. package/api/search/_module-doc.mjs +78 -0
  170. package/api/search/_order.d.mts +32 -0
  171. package/api/search/_order.mjs +162 -0
  172. package/api/search/_order.test.mjs +72 -0
  173. package/api/search/_priority.d.mts +50 -0
  174. package/api/search/_priority.mjs +139 -0
  175. package/api/search/_query-words.d.mts +25 -0
  176. package/api/search/_query-words.mjs +92 -0
  177. package/api/search/_query.d.mts +65 -0
  178. package/api/search/_query.mjs +176 -0
  179. package/api/search/_result.d.mts +97 -0
  180. package/api/search/_result.mjs +150 -0
  181. package/api/search/_score.d.mts +60 -0
  182. package/api/search/_score.mjs +283 -0
  183. package/api/search/_synonyms.d.mts +21 -0
  184. package/api/search/_synonyms.mjs +67 -0
  185. package/api/search/_template-searcher.d.mts +4 -0
  186. package/api/search/_template-searcher.mjs +23 -0
  187. package/api/search/_template-searcher.test.mjs +40 -0
  188. package/api/search/_template-searcher.weights.json +1 -0
  189. package/api/search/_titles.d.mts +33 -0
  190. package/api/search/_titles.mjs +65 -0
  191. package/api/search/_words.d.mts +64 -0
  192. package/api/search/_words.mjs +157 -0
  193. package/api/search/search.d.mts +22 -236
  194. package/api/search/search.doc.mjs +14 -7
  195. package/api/search/search.domain-priority.test.mjs +108 -18
  196. package/api/search/search.integration-check.test.mjs +24 -0
  197. package/api/search/search.mjs +59 -1904
  198. package/api/search/search.test.mjs +193 -15
  199. package/api/search/search.type.d.mts +20 -2
  200. package/api/search/search.type.mjs +12 -2
  201. package/api/search/tree.d.mts +15 -0
  202. package/api/search/tree.mjs +40 -0
  203. package/api/search/tree.test.mjs +66 -0
  204. package/api/search/tree.weights.json +1 -0
  205. package/api/swizzle/_adapter.mjs +2 -2
  206. package/api/swizzle/copy/copy.mjs +29 -15
  207. package/api/template/template-integration.test.mjs +1 -1
  208. package/api/template/template.mjs +5 -1
  209. package/api/template/template.test.mjs +120 -3
  210. package/api/theme/_adapter.d.mts +16 -0
  211. package/api/theme/_adapter.mjs +32 -5
  212. package/api/theme/build/build.d.mts +2 -1
  213. package/api/theme/build/build.family.test.mjs +64 -0
  214. package/api/theme/build/build.mjs +250 -38
  215. package/api/theme/build/build.packed-old-core.test.mjs +21 -3
  216. package/api/theme/build/font-warning.mjs +5 -3
  217. package/api/theme/build/font-warning.test.mjs +2 -1
  218. package/api/theme/remove/remove.test.mjs +2 -2
  219. package/api/theme/targets/targets.mjs +3 -10
  220. package/api/theme/themeBuild.doc.mjs +4 -4
  221. package/api/theme/themeTargets.doc.mjs +4 -0
  222. package/api/theme/use/use.test.mjs +1 -1
  223. package/api/upgrade/_adapter.d.mts +97 -11
  224. package/api/upgrade/_adapter.mjs +315 -32
  225. package/api/upgrade/registry/registry.d.mts +10 -4
  226. package/api/upgrade/registry/registry.mjs +33 -16
  227. package/api/upgrade/registry/registry.test.mjs +85 -0
  228. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  229. package/api/upgrade/run/run.d.mts +4 -2
  230. package/api/upgrade/run/run.mjs +48 -4
  231. package/api/upgrade/run/run.test.mjs +417 -3
  232. package/api/upgrade/status/status.d.mts +21 -5
  233. package/api/upgrade/status/status.mjs +45 -8
  234. package/api/upgrade/upgrade.doc.mjs +16 -8
  235. package/api/upgrade/upgrade.mjs +18 -3
  236. package/api/upgrade/upgrade.test.mjs +194 -0
  237. package/api/upgrade/upgrade.type.d.mts +28 -3
  238. package/api/upgrade/upgrade.type.mjs +24 -7
  239. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  240. package/assets/codemods/registry.mjs +1 -0
  241. package/assets/codemods/runner.mjs +7 -1
  242. package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
  243. package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
  244. package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
  245. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  246. package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
  247. package/assets/discover/official-packages.json +367 -0
  248. package/assets/docs/README.md +10 -0
  249. package/assets/docs/author-a-theme.doc.mjs +5 -5
  250. package/assets/docs/browser-support.doc.mjs +1 -1
  251. package/assets/docs/getting-started.doc.mjs +26 -6
  252. package/assets/docs/is-my-code-good.doc.mjs +287 -0
  253. package/assets/docs/styling-overview.doc.mjs +1 -1
  254. package/assets/docs/theme.doc.dense.mjs +1 -1
  255. package/assets/docs/theme.doc.mjs +2 -2
  256. package/assets/docs/theme.doc.zh.mjs +1 -1
  257. package/assets/docs/tree/add-a-component.doc.mjs +22 -2
  258. package/assets/docs/tree/add-a-theme.doc.mjs +14 -4
  259. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  260. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  261. package/assets/docs/tree/api.doc.mjs +6 -0
  262. package/assets/docs/tree/authoring.doc.mjs +61 -0
  263. package/assets/docs/tree/block-template.doc.mjs +8 -20
  264. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  265. package/assets/docs/tree/building-blocks.doc.mjs +6 -2
  266. package/assets/docs/tree/check-the-props.doc.mjs +201 -0
  267. package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
  268. package/assets/docs/tree/checks.doc.mjs +32 -24
  269. package/assets/docs/tree/ci-and-containers.doc.mjs +101 -0
  270. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  271. package/assets/docs/tree/cli.doc.mjs +7 -1
  272. package/assets/docs/tree/codemods.doc.mjs +17 -7
  273. package/assets/docs/tree/commands.doc.mjs +7 -1
  274. package/assets/docs/tree/component-family.doc.mjs +8 -6
  275. package/assets/docs/tree/component-imports.doc.mjs +21 -3
  276. package/assets/docs/tree/components.doc.mjs +7 -1
  277. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  278. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  279. package/assets/docs/tree/configuration.doc.mjs +8 -4
  280. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  281. package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
  282. package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
  283. package/assets/docs/tree/docs.doc.mjs +9 -3
  284. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  285. package/assets/docs/tree/document-the-theme.doc.mjs +4 -4
  286. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  287. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  288. package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
  291. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  292. package/assets/docs/tree/global.doc.mjs +131 -0
  293. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  294. package/assets/docs/tree/help.doc.mjs +2 -2
  295. package/assets/docs/tree/host-entry.doc.mjs +128 -0
  296. package/assets/docs/tree/install-once.doc.mjs +105 -0
  297. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  298. package/assets/docs/tree/layout.doc.mjs +6 -6
  299. package/assets/docs/tree/links.doc.mjs +7 -6
  300. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  301. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  302. package/assets/docs/tree/migration.doc.mjs +0 -1
  303. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  304. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  305. package/assets/docs/tree/page-template.doc.mjs +4 -8
  306. package/assets/docs/tree/problems.doc.mjs +205 -0
  307. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  308. package/assets/docs/tree/publishing.doc.mjs +6 -6
  309. package/assets/docs/tree/quick-start.doc.mjs +54 -28
  310. package/assets/docs/tree/reference.doc.mjs +192 -0
  311. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  312. package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
  313. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  314. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  315. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  316. package/assets/docs/tree/ship.doc.mjs +2 -2
  317. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  318. package/assets/docs/tree/single-component.doc.mjs +15 -6
  319. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  320. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  321. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  322. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  323. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  324. package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
  325. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  326. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  327. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  328. package/assets/docs/tree/templates.doc.mjs +7 -1
  329. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  330. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  331. package/assets/docs/tree/themes.doc.mjs +5 -1
  332. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  333. package/assets/docs/tree/tokens-data.doc.mjs +2 -2
  334. package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
  335. package/assets/docs/tree/type-scale.doc.mjs +3 -3
  336. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  337. package/assets/docs/tree/updates.doc.mjs +92 -0
  338. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  339. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +15 -3
  340. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  341. package/assets/docs/tree/versioning.doc.mjs +14 -9
  342. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  343. package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
  344. package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
  345. package/assets/docs/use-a-theme.doc.mjs +2 -2
  346. package/assets/docs/use-integrations.doc.mjs +120 -0
  347. package/assets/docs/working-with-ai.doc.mjs +70 -13
  348. package/assets/templates/themes/butter/butterTheme.ts +4 -2
  349. package/assets/templates/themes/stone/stoneTheme.ts +4 -2
  350. package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
  351. package/assets/theme.template.ts +1 -1
  352. package/authoring/codemod/codemod.doc.mjs +7 -3
  353. package/authoring/config/config.doc.mjs +9 -6
  354. package/authoring/config/type.ts +4 -2
  355. package/authoring/debug/parse.d.mts +5 -5
  356. package/authoring/discover/discover.doc.mjs +7 -1
  357. package/authoring/doctypes/_schema.d.mts +8 -3
  358. package/authoring/doctypes/_schema.mjs +1 -0
  359. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  360. package/authoring/doctypes/command/command.doc.mjs +20 -12
  361. package/authoring/doctypes/command/type.ts +14 -0
  362. package/authoring/doctypes/component/component.doc.mjs +30 -27
  363. package/authoring/doctypes/component/type.ts +21 -8
  364. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  365. package/authoring/doctypes/function/function.doc.mjs +9 -8
  366. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  367. package/authoring/doctypes/hook/type.ts +4 -0
  368. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  369. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  370. package/authoring/doctypes/schema/schema.doc.mjs +10 -10
  371. package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
  372. package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
  373. package/authoring/doctypes/template/parse.d.mts +6 -2
  374. package/authoring/doctypes/template/parse.mjs +3 -1
  375. package/authoring/doctypes/template/template.doc.mjs +3 -3
  376. package/authoring/doctypes/template/type.ts +22 -0
  377. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  378. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  379. package/authoring/identity/identity.doc.mjs +3 -3
  380. package/authoring/index.d.ts +2 -0
  381. package/authoring/integration/integration.doc.mjs +30 -6
  382. package/authoring/integration/parse.test.mjs +21 -0
  383. package/authoring/integration/schema.d.mts +16 -3
  384. package/authoring/integration/schema.mjs +34 -2
  385. package/authoring/integration/type.ts +13 -1
  386. package/clients/cli/bin/astryx.mjs +11 -65
  387. package/clients/cli/cli-command.test.mjs +166 -0
  388. package/clients/cli/command-result-coverage.test.mjs +6 -5
  389. package/clients/cli/commands/blog.doc.mjs +1 -0
  390. package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
  391. package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
  392. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  393. package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
  394. package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
  395. package/clients/cli/commands/build.doc.mjs +1 -0
  396. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  397. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  398. package/clients/cli/commands/component.doc.mjs +1 -0
  399. package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
  400. package/clients/cli/commands/component.test.mjs +6 -6
  401. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  402. package/clients/cli/commands/discover.doc.mjs +9 -1
  403. package/clients/cli/commands/discover.mjs +144 -93
  404. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  405. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  406. package/clients/cli/commands/docs.doc.mjs +3 -2
  407. package/clients/cli/commands/docs.mjs +50 -20
  408. package/clients/cli/commands/docs.test.mjs +16 -16
  409. package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
  410. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  411. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  412. package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
  413. package/clients/cli/commands/doctor-integration.test.mjs +936 -3
  414. package/clients/cli/commands/doctor.doc.mjs +12 -2
  415. package/clients/cli/commands/doctor.mjs +332 -7
  416. package/clients/cli/commands/doctor.test.mjs +75 -4
  417. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  418. package/clients/cli/commands/gap-report.mjs +24 -2
  419. package/clients/cli/commands/gap-report.test.mjs +79 -0
  420. package/clients/cli/commands/hook.doc.mjs +1 -0
  421. package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
  422. package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
  423. package/clients/cli/commands/init.behavior.test.mjs +235 -1
  424. package/clients/cli/commands/init.doc.mjs +55 -10
  425. package/clients/cli/commands/init.flag-help.test.mjs +1 -0
  426. package/clients/cli/commands/init.mjs +2 -2
  427. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  428. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  429. package/clients/cli/commands/integration-check.doc.mjs +93 -0
  430. package/clients/cli/commands/integration-check.test.mjs +489 -0
  431. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  432. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  433. package/clients/cli/commands/integration.doc.mjs +6 -2
  434. package/clients/cli/commands/integration.mjs +119 -7
  435. package/clients/cli/commands/json-contract.test.mjs +11 -2
  436. package/clients/cli/commands/manifest.doc.mjs +2 -1
  437. package/clients/cli/commands/manifest.mjs +67 -0
  438. package/clients/cli/commands/outside-project.test.mjs +874 -0
  439. package/clients/cli/commands/postinstall.doc.mjs +23 -0
  440. package/clients/cli/commands/postinstall.mjs +31 -0
  441. package/clients/cli/commands/search.doc.mjs +1 -0
  442. package/clients/cli/commands/search.mjs +16 -11
  443. package/clients/cli/commands/search.test.mjs +429 -296
  444. package/clients/cli/commands/setup-nudge.test.mjs +180 -2
  445. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  446. package/clients/cli/commands/swizzle.mjs +5 -3
  447. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  448. package/clients/cli/commands/template.doc.mjs +1 -0
  449. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  450. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  451. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  452. package/clients/cli/commands/theme-build.doc.mjs +3 -2
  453. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  454. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  455. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  456. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  457. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  458. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  459. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  460. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  461. package/clients/cli/commands/{build-theme.mjs → theme.mjs} +27 -14
  462. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  463. package/clients/cli/commands/upgrade.doc.mjs +26 -3
  464. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  465. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  466. package/clients/cli/commands/upgrade.mjs +9 -2
  467. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  468. package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
  469. package/clients/cli/index.mjs +156 -100
  470. package/clients/cli/lib/cli-error.mjs +4 -1
  471. package/clients/cli/lib/component-format.mjs +1 -1
  472. package/clients/cli/lib/component-format.test.mjs +1 -1
  473. package/clients/cli/lib/define-command.mjs +14 -9
  474. package/clients/cli/lib/exit-codes.test.mjs +5 -0
  475. package/clients/cli/lib/json-shim.mjs +3 -1
  476. package/clients/cli/lib/manifest.d.ts +9 -0
  477. package/clients/cli/lib/manifest.mjs +17 -1
  478. package/clients/cli/lib/manifest.test.mjs +37 -0
  479. package/clients/cli/lib/welcome-box.mjs +50 -0
  480. package/clients/cli/run.mjs +108 -0
  481. package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
  482. package/foundation/agent-docs/agent-doc-state.mjs +123 -14
  483. package/foundation/agent-docs/agent-docs.d.mts +104 -15
  484. package/foundation/agent-docs/agent-docs.mjs +1028 -114
  485. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
  486. package/foundation/agent-docs/agent-docs.test.mjs +683 -39
  487. package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
  488. package/foundation/agent-docs/computer-agent-text.mjs +750 -0
  489. package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
  490. package/foundation/config/project.d.mts +35 -3
  491. package/foundation/config/project.mjs +243 -26
  492. package/foundation/config/project.test.mjs +122 -0
  493. package/foundation/config/theme-state.mjs +5 -4
  494. package/foundation/discovery/authoring-self-docs.d.mts +7 -0
  495. package/foundation/discovery/authoring-self-docs.mjs +17 -4
  496. package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
  497. package/foundation/discovery/authoring-surface.d.mts +1 -1
  498. package/foundation/discovery/authoring-surface.mjs +2 -2
  499. package/foundation/discovery/authoring-surface.test.mjs +1 -1
  500. package/foundation/discovery/cli-self-docs.d.mts +2 -1
  501. package/foundation/discovery/cli-self-docs.mjs +22 -4
  502. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  503. package/foundation/discovery/component-discovery.d.mts +227 -10
  504. package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
  505. package/foundation/discovery/component-discovery.mjs +940 -57
  506. package/foundation/discovery/component-discovery.test.mjs +96 -0
  507. package/foundation/discovery/component-loader.d.mts +1 -1
  508. package/foundation/discovery/component-replacement.mjs +20 -1
  509. package/foundation/discovery/component-replacement.test.mjs +40 -0
  510. package/foundation/discovery/copied-passages.d.mts +216 -0
  511. package/foundation/discovery/copied-passages.mjs +720 -0
  512. package/foundation/discovery/copied-passages.test.mjs +124 -0
  513. package/foundation/discovery/doc-consistency.d.mts +34 -0
  514. package/foundation/discovery/doc-consistency.mjs +513 -0
  515. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  516. package/foundation/discovery/doc-fluff.d.mts +112 -0
  517. package/foundation/discovery/doc-fluff.mjs +328 -0
  518. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  519. package/foundation/discovery/doc-types.d.mts +157 -0
  520. package/foundation/discovery/doc-types.mjs +1231 -0
  521. package/foundation/discovery/doc-types.test.mjs +744 -0
  522. package/foundation/discovery/docs-discovery.d.mts +88 -0
  523. package/foundation/discovery/docs-discovery.mjs +97 -3
  524. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  525. package/foundation/discovery/integration-doc-files.mjs +231 -0
  526. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  527. package/foundation/discovery/module-exports.d.mts +68 -0
  528. package/foundation/discovery/module-exports.mjs +609 -31
  529. package/foundation/discovery/module-exports.test.mjs +172 -0
  530. package/foundation/discovery/package-tsconfig.d.mts +14 -0
  531. package/foundation/discovery/package-tsconfig.mjs +228 -0
  532. package/foundation/discovery/package-tsconfig.test.mjs +210 -0
  533. package/foundation/discovery/project-typescript.d.mts +32 -0
  534. package/foundation/discovery/project-typescript.mjs +89 -0
  535. package/foundation/discovery/prop-drift.d.mts +297 -0
  536. package/foundation/discovery/prop-drift.mjs +2428 -0
  537. package/foundation/discovery/prop-drift.test.mjs +2337 -0
  538. package/foundation/discovery/runner-allowlist.d.mts +38 -0
  539. package/foundation/discovery/runner-allowlist.mjs +51 -0
  540. package/foundation/discovery/runner-commands.d.mts +77 -0
  541. package/foundation/discovery/runner-commands.mjs +294 -0
  542. package/foundation/discovery/runner-commands.test.mjs +128 -0
  543. package/foundation/discovery/stray-pointers.d.mts +52 -0
  544. package/foundation/discovery/stray-pointers.mjs +293 -0
  545. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  546. package/foundation/discovery/template-adapter.mjs +92 -6
  547. package/foundation/discovery/template-needs.mjs +6 -46
  548. package/foundation/discovery/theme-discovery.mjs +147 -3
  549. package/foundation/discovery/theme-imports.mjs +8 -4
  550. package/foundation/discovery/theme-imports.test.mjs +1 -1
  551. package/foundation/discovery/type-match.d.mts +53 -0
  552. package/foundation/discovery/type-match.mjs +660 -0
  553. package/foundation/discovery/type-match.test.mjs +169 -0
  554. package/foundation/discovery/type-text.d.mts +68 -0
  555. package/foundation/discovery/type-text.mjs +658 -0
  556. package/foundation/discovery/type-text.test.mjs +196 -0
  557. package/foundation/discovery/unresolved-references.d.mts +62 -0
  558. package/foundation/discovery/unresolved-references.mjs +790 -0
  559. package/foundation/discovery/unresolved-references.test.mjs +567 -0
  560. package/foundation/doc-compiler/doc-loads.test.mjs +84 -10
  561. package/foundation/doc-compiler/inputs.mjs +27 -1
  562. package/foundation/doc-compiler/inputs.test.mjs +0 -1
  563. package/foundation/doc-compiler/links.d.mts +41 -5
  564. package/foundation/doc-compiler/links.mjs +167 -28
  565. package/foundation/doc-compiler/links.test.mjs +97 -4
  566. package/foundation/doc-compiler/read.d.mts +1 -1
  567. package/foundation/doc-compiler/read.mjs +59 -1
  568. package/foundation/doc-compiler/read.test.mjs +11 -2
  569. package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
  570. package/foundation/doc-compiler/tree.d.mts +32 -6
  571. package/foundation/doc-compiler/tree.mjs +107 -44
  572. package/foundation/doc-compiler/tree.test.mjs +14 -7
  573. package/foundation/env/cli-command.d.mts +83 -0
  574. package/foundation/env/cli-command.mjs +152 -0
  575. package/foundation/env/cli-command.test.mjs +129 -0
  576. package/foundation/env/node-version.test.mjs +15 -3
  577. package/foundation/env/package-manager.d.mts +93 -9
  578. package/foundation/env/package-manager.global.test.mjs +66 -0
  579. package/foundation/env/package-manager.mjs +184 -13
  580. package/foundation/env/package-manager.test.mjs +341 -15
  581. package/foundation/env/project-scope.d.mts +9 -0
  582. package/foundation/env/project-scope.mjs +33 -0
  583. package/foundation/env/search-path.d.mts +42 -0
  584. package/foundation/env/search-path.mjs +205 -0
  585. package/foundation/env/search-path.test.mjs +122 -0
  586. package/foundation/env/user-dirs.d.mts +39 -0
  587. package/foundation/env/user-dirs.mjs +93 -0
  588. package/foundation/env/user-dirs.test.mjs +72 -0
  589. package/foundation/env/user-settings.d.mts +46 -0
  590. package/foundation/env/user-settings.mjs +106 -0
  591. package/foundation/env/user-settings.test.mjs +64 -0
  592. package/foundation/fs/file-protection.mjs +15 -1
  593. package/foundation/fs/module-loader.d.mts +2 -1
  594. package/foundation/fs/module-loader.mjs +60 -4
  595. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  596. package/foundation/fs/module-loader.test.mjs +194 -0
  597. package/foundation/fs/path-compare.d.mts +33 -0
  598. package/foundation/fs/path-compare.mjs +73 -0
  599. package/foundation/fs/paths.d.mts +122 -4
  600. package/foundation/fs/paths.mjs +675 -29
  601. package/foundation/fs/paths.test.mjs +439 -54
  602. package/foundation/fs/read-record.d.mts +18 -0
  603. package/foundation/fs/read-record.mjs +131 -0
  604. package/foundation/fs/read-record.test.mjs +77 -0
  605. package/foundation/integrations/autolink.d.mts +2 -1
  606. package/foundation/integrations/autolink.mjs +4 -13
  607. package/foundation/integrations/cli-peer-version.d.mts +36 -0
  608. package/foundation/integrations/cli-peer-version.mjs +132 -0
  609. package/foundation/integrations/cli-peer-version.test.mjs +354 -0
  610. package/foundation/integrations/computer-integrations.d.mts +81 -0
  611. package/foundation/integrations/computer-integrations.mjs +345 -0
  612. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  613. package/foundation/integrations/contribution-inventory.d.mts +26 -20
  614. package/foundation/integrations/contribution-inventory.mjs +97 -8
  615. package/foundation/integrations/exports-subpaths.d.mts +57 -0
  616. package/foundation/integrations/exports-subpaths.mjs +113 -0
  617. package/foundation/integrations/integration-warnings.mjs +3 -2
  618. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  619. package/foundation/integrations/integrations.d.mts +51 -1
  620. package/foundation/integrations/integrations.mjs +106 -4
  621. package/foundation/integrations/issue.ts +6 -0
  622. package/foundation/integrations/public-imports.d.mts +118 -0
  623. package/foundation/integrations/public-imports.mjs +1769 -0
  624. package/foundation/integrations/public-imports.test.mjs +1793 -0
  625. package/foundation/integrations/validate-contributions.d.mts +117 -0
  626. package/foundation/integrations/validate-contributions.mjs +1209 -14
  627. package/foundation/release/agent-text-worker.d.mts +4 -0
  628. package/foundation/release/agent-text-worker.mjs +52 -0
  629. package/foundation/release/cache.d.mts +310 -0
  630. package/foundation/release/cache.mjs +1216 -0
  631. package/foundation/release/cache.test.mjs +923 -0
  632. package/foundation/release/choose.d.mts +207 -0
  633. package/foundation/release/choose.mjs +677 -0
  634. package/foundation/release/choose.test.mjs +427 -0
  635. package/foundation/release/core-worker.d.mts +4 -0
  636. package/foundation/release/core-worker.mjs +38 -0
  637. package/foundation/release/global-state.d.mts +263 -0
  638. package/foundation/release/global-state.mjs +474 -0
  639. package/foundation/release/global-state.test.mjs +381 -0
  640. package/foundation/release/handoff.d.mts +79 -0
  641. package/foundation/release/handoff.e2e.test.mjs +278 -0
  642. package/foundation/release/handoff.mjs +524 -0
  643. package/foundation/release/lock-lease.d.mts +23 -0
  644. package/foundation/release/lock-lease.mjs +80 -0
  645. package/foundation/release/notices.d.mts +307 -0
  646. package/foundation/release/notices.mjs +707 -0
  647. package/foundation/release/notices.test.mjs +586 -0
  648. package/foundation/release/npm-guard.d.mts +4 -0
  649. package/foundation/release/npm-guard.mjs +126 -0
  650. package/foundation/release/project.d.mts +141 -0
  651. package/foundation/release/project.mjs +466 -0
  652. package/foundation/release/project.test.mjs +288 -0
  653. package/foundation/release/refresh-worker.d.mts +4 -0
  654. package/foundation/release/refresh-worker.mjs +27 -0
  655. package/foundation/release/run-context.d.mts +47 -0
  656. package/foundation/release/run-context.mjs +163 -0
  657. package/foundation/release/update-notice-env.d.mts +28 -0
  658. package/foundation/release/update-notice-env.mjs +39 -0
  659. package/foundation/response/base.d.ts +26 -3
  660. package/foundation/response/error-codes.d.mts +3 -1
  661. package/foundation/response/error-codes.doc.mjs +12 -0
  662. package/foundation/response/error-codes.mjs +17 -0
  663. package/foundation/response/error-codes.test.mjs +2 -0
  664. package/foundation/response/json-contract.test.mjs +7 -2
  665. package/foundation/response/json.mjs +4 -1
  666. package/foundation/response/response-types.doc.mjs +22 -11
  667. package/foundation/response/response-types.doc.test.mjs +46 -0
  668. package/foundation/response/response.doc.mjs +3 -3
  669. package/foundation/route/route.d.mts +285 -0
  670. package/foundation/route/route.mjs +324 -0
  671. package/foundation/route/route.test.mjs +153 -0
  672. package/foundation/runtime/hosted-runtime.test.mjs +403 -0
  673. package/foundation/runtime/locked-versions.d.mts +32 -0
  674. package/foundation/runtime/locked-versions.mjs +65 -0
  675. package/foundation/runtime/package-root.d.mts +91 -0
  676. package/foundation/runtime/package-root.mjs +174 -0
  677. package/foundation/runtime/package-set.d.mts +62 -0
  678. package/foundation/runtime/package-set.mjs +130 -0
  679. package/foundation/runtime/package-set.test.mjs +432 -0
  680. package/foundation/text/string-utils.d.mts +2 -1
  681. package/foundation/text/string-utils.mjs +16 -5
  682. package/foundation/text/suggest-order.d.mts +72 -0
  683. package/foundation/text/suggest-order.mjs +363 -0
  684. package/foundation/text/suggest-order.test.mjs +259 -0
  685. package/foundation/xle/browser-imports.test.mjs +74 -0
  686. package/foundation/xle/registry.mjs +4 -0
  687. package/foundation/xle/registry.test.mjs +28 -0
  688. package/host/door-conformance.test.mjs +274 -0
  689. package/host/index.d.ts +116 -0
  690. package/host/index.mjs +295 -0
  691. package/host/index.test.mjs +302 -0
  692. package/package.json +16 -11
  693. package/scripts/postinstall.mjs +24 -5
  694. package/assets/docs/tree/integrations.doc.mjs +0 -40
@@ -17,8 +17,11 @@
17
17
  * foundation/discovery/docs-discovery, which the catalog comes from.
18
18
  */
19
19
 
20
+ import * as path from 'node:path';
20
21
  import {Project} from '../../foundation/config/project.mjs';
21
22
  import {DocsCatalog} from '../../foundation/discovery/docs-discovery.mjs';
23
+ import {checkDocTypes} from '../../foundation/discovery/doc-types.mjs';
24
+ import {integrationDocFiles} from '../../foundation/discovery/integration-doc-files.mjs';
22
25
  import {
23
26
  linkReferenceTopic,
24
27
  lowerReferenceTopic,
@@ -37,6 +40,7 @@ import {
37
40
  import {sortDiagnostics} from '../../foundation/doc-compiler/diagnostics.mjs';
38
41
  import {
39
42
  linkBlocks,
43
+ linkFields,
40
44
  parseLinkTarget,
41
45
  } from '../../foundation/doc-compiler/links.mjs';
42
46
  import {
@@ -48,13 +52,27 @@ import {
48
52
  cliDocSection,
49
53
  } from '../../foundation/discovery/cli-self-docs.mjs';
50
54
  import {
55
+ AUTHORING_REFERENCE_ROUTE,
51
56
  loadAuthoringSelfDocs,
52
57
  schemaFieldTable,
53
58
  selfDocSection,
54
59
  } from '../../foundation/discovery/authoring-self-docs.mjs';
55
60
  import {CLI_PROVIDER_ID} from '../../foundation/identity/providers.mjs';
61
+ import {
62
+ CORE_PACKAGE,
63
+ discoverOwnedComponents,
64
+ discoverValidIntegrationComponents,
65
+ } from '../../foundation/discovery/component-discovery.mjs';
66
+ import {loadComponentDoc} from '../../foundation/discovery/component-loader.mjs';
67
+ import {
68
+ discoverCoreTemplates,
69
+ discoverIntegrationTemplatesForOne,
70
+ } from '../../foundation/discovery/template-adapter.mjs';
71
+ import {findCoreDir} from '../../foundation/fs/paths.mjs';
56
72
  import {AstryxError} from '../error.mjs';
57
73
  import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
74
+ import {orderRouteSuggestions} from '../../foundation/text/suggest-order.mjs';
75
+ import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
58
76
 
59
77
  export {OVERLAY_LANGUAGES, overlayLanguages};
60
78
 
@@ -250,8 +268,16 @@ function linkTopic(catalog, entry, lang) {
250
268
  problems.push(...linked.problems);
251
269
  sections.push({...section, content: linked.content});
252
270
  }
271
+ // The topic's own text outside its sections, its description and
272
+ // summary, resolves against the topic's own provider.
273
+ const {resolve} = await linkerFor(providerOf(entry));
274
+ const fields = await linkFields(topicTextFields(raw.doc), resolve);
275
+ problems.push(...fields.problems);
253
276
  return {
254
- node: deepFreeze({...raw, doc: {...raw.doc, sections}}),
277
+ node: deepFreeze({
278
+ ...raw,
279
+ doc: {...raw.doc, ...fields.doc, sections},
280
+ }),
255
281
  problems,
256
282
  };
257
283
  })();
@@ -260,6 +286,82 @@ function linkTopic(catalog, entry, lang) {
260
286
  return linked;
261
287
  }
262
288
 
289
+ /**
290
+ * The text fields of a topic outside its sections: its description and
291
+ * summary, those it has.
292
+ * @param {any} doc
293
+ * @returns {{description?: string, summary?: string}}
294
+ */
295
+ function topicTextFields(doc) {
296
+ /** @type {{description?: string, summary?: string}} */
297
+ const fields = {};
298
+ if (typeof doc?.description === 'string')
299
+ fields.description = doc.description;
300
+ if (typeof doc?.summary === 'string') fields.summary = doc.summary;
301
+ return fields;
302
+ }
303
+
304
+ /**
305
+ * One line of a doc's text, such as a topic's or a tree node's summary, with
306
+ * every inline link resolved against the provider that wrote it (spec:AST-047
307
+ * FR9). A link that names no doc prints as written; doctor names it.
308
+ * @param {DocsCatalog} catalog
309
+ * @param {string} providerId the provider id of the doc the text sits in
310
+ * @param {string} text
311
+ * @returns {Promise<string>}
312
+ */
313
+ export async function linkDocText(catalog, providerId, text) {
314
+ if (typeof text !== 'string' || !text.includes('{@link')) return text;
315
+ let provider;
316
+ try {
317
+ provider = normalizeProviderId(providerId);
318
+ } catch {
319
+ return text;
320
+ }
321
+ const linked = await linkFields(
322
+ {description: text},
323
+ await linkResolver(catalog, provider),
324
+ );
325
+ return linked.doc.description ?? text;
326
+ }
327
+
328
+ /**
329
+ * A component doc with every inline link in its text fields resolved
330
+ * (spec:AST-047 FR9): its description, usage, best practices, and each prop's
331
+ * and example's description. Code fields are shown as written. A Core
332
+ * component's links resolve against the CLI's own docs provider; an
333
+ * integration's against that integration's.
334
+ * @template T
335
+ * @param {DocsCatalog} catalog
336
+ * @param {string} providerId the provider id the component's links resolve
337
+ * against
338
+ * @param {T} doc
339
+ * @returns {Promise<{doc: T, problems: LinkProblem[]}>}
340
+ */
341
+ export async function linkComponentDoc(catalog, providerId, doc) {
342
+ if (!JSON.stringify(doc ?? null).includes('{@link')) {
343
+ return {doc, problems: []};
344
+ }
345
+ return linkFields(
346
+ doc,
347
+ await linkResolver(catalog, normalizeProviderId(providerId)),
348
+ );
349
+ }
350
+
351
+ /**
352
+ * The provider id a component's doc links resolve against: the CLI's own for
353
+ * a Core component, else its owner package's (or the provider id its manifest
354
+ * declares).
355
+ * @param {string} ownerPackage
356
+ * @param {string} [providerId]
357
+ * @returns {string}
358
+ */
359
+ export function componentLinkProvider(ownerPackage, providerId) {
360
+ return ownerPackage === CORE_PACKAGE
361
+ ? CLI_PROVIDER_ID
362
+ : normalizeProviderId(providerId ?? ownerPackage);
363
+ }
364
+
263
365
  /** @type {WeakMap<DocsCatalog, Promise<DocsTree>>} */
264
366
  const treesByCatalog = new WeakMap();
265
367
 
@@ -285,7 +387,7 @@ export function projectTree(catalog, {fresh = false} = {}) {
285
387
  let cliTreeInputs;
286
388
 
287
389
  /**
288
- * Every flat topic in the catalog, as the tree's Unorganized level reads it.
390
+ * Every flat topic in the catalog, as the tree's topic levels read it.
289
391
  * @param {DocsCatalog} catalog
290
392
  * @returns {Promise<import('../../foundation/doc-compiler/tree.mjs').TreeTopicInput[]>}
291
393
  */
@@ -294,12 +396,13 @@ async function flatTopicInputs(catalog) {
294
396
  const topics = [];
295
397
  for (const entry of catalog.entries()) {
296
398
  const aliases = catalog.aliasesOf(entry);
297
- let {title, description} = entry;
298
- if (title == null || description == null) {
399
+ let {title, description, category} = entry;
400
+ if (title == null || description == null || category === undefined) {
299
401
  try {
300
402
  const file = await loadTopicFile(entry.path, null);
301
403
  title ??= file.doc?.title;
302
404
  description ??= file.doc?.description;
405
+ category ??= file.doc?.category;
303
406
  } catch {
304
407
  // A topic that does not load is reported where it is read.
305
408
  }
@@ -310,6 +413,7 @@ async function flatTopicInputs(catalog) {
310
413
  name: entry.name,
311
414
  title: title ?? entry.name,
312
415
  summary: description ?? '',
416
+ category: category ?? null,
313
417
  source: `${entry.package}:${entry.name}`,
314
418
  ...(aliases.length > 0 ? {aliases} : {}),
315
419
  });
@@ -319,7 +423,7 @@ async function flatTopicInputs(catalog) {
319
423
 
320
424
  /**
321
425
  * The CLI's tree, each configured integration's namespaces and guides, and
322
- * every flat topic in the generated Unorganized level.
426
+ * every flat topic in the generated level for its category.
323
427
  * @param {DocsCatalog} catalog
324
428
  * @param {boolean} fresh
325
429
  * @returns {Promise<DocsTree>}
@@ -333,12 +437,50 @@ async function buildProjectTree(catalog, fresh) {
333
437
  docs: [...cli.docs, ...added.flatMap(each => each.guides)],
334
438
  topics: await flatTopicInputs(catalog),
335
439
  });
440
+ // A summary is a doc's text too: each link in it reads as the command that
441
+ // opens its doc, wherever the tree's summaries print (spec:AST-047 FR9).
442
+ for (const node of result.nodes.values()) {
443
+ if (typeof node.summary === 'string' && node.summary.includes('{@link')) {
444
+ node.summary = await linkSummary(
445
+ catalog,
446
+ result,
447
+ node.providerId,
448
+ node.summary,
449
+ );
450
+ }
451
+ }
336
452
  return {
337
453
  ...result,
338
454
  diagnostics: sortDiagnostics([...cli.diagnostics, ...result.diagnostics]),
339
455
  };
340
456
  }
341
457
 
458
+ /**
459
+ * One summary with each inline link resolved to the command that opens its
460
+ * doc, against the provider that wrote it. A link that names no doc prints as
461
+ * written; doctor names it where it checks the doc's own fields.
462
+ * @param {DocsCatalog} catalog
463
+ * @param {DocsTree} tree
464
+ * @param {string} providerId
465
+ * @param {string} summary
466
+ * @returns {Promise<string>}
467
+ */
468
+ async function linkSummary(catalog, tree, providerId, summary) {
469
+ if (!summary.includes('{@link')) return summary;
470
+ let provider;
471
+ try {
472
+ provider = normalizeProviderId(providerId);
473
+ } catch {
474
+ return summary;
475
+ }
476
+ const find = docFinderOver(catalog, tree, provider, false);
477
+ const linked = await linkFields({summary}, async target => {
478
+ const found = await find(target);
479
+ return 'problem' in found ? found : found.link;
480
+ });
481
+ return linked.doc.summary;
482
+ }
483
+
342
484
  /** @type {WeakMap<DocsTree, Map<string, TreeNode>>} */
343
485
  const identitiesByTree = new WeakMap();
344
486
 
@@ -371,23 +513,22 @@ function identitiesOf(tree) {
371
513
  }
372
514
 
373
515
  /**
374
- * The CLI's authoring docs, by kind and name. `astryx docs authoring` reads
375
- * each as one section keyed by its name, so a link to one opens that section.
376
- * Loaded once per process, like the CLI's tree files.
516
+ * The CLI's authoring docs, by kind and name. The field reference under
517
+ * `astryx docs authoring` reads each as one section keyed by its name, so a
518
+ * link to one opens that section. Loaded once per process, like the CLI's
519
+ * tree files.
377
520
  * @type {Promise<Map<string, any>> | undefined}
378
521
  */
379
522
  let authoringDocs;
380
523
 
381
524
  /**
382
- * The CLI authoring doc a link names, while `astryx docs authoring` is the
383
- * CLI's own topic.
384
- * @param {DocsCatalog} catalog
525
+ * The CLI authoring doc a link names. The `authoring` namespace is the CLI's
526
+ * own, so no integration can take its route.
385
527
  * @param {string} kind
386
528
  * @param {string} name
387
529
  * @returns {Promise<any | null>}
388
530
  */
389
- async function authoringDoc(catalog, kind, name) {
390
- if (catalog.resolve('authoring')?.package !== CLI_PROVIDER_ID) return null;
531
+ async function authoringDoc(kind, name) {
391
532
  authoringDocs ??= loadAuthoringSelfDocs().then(
392
533
  ({loaded}) =>
393
534
  new Map(loaded.map(({doc}) => [`${doc.type}\u0000${doc.name}`, doc])),
@@ -416,10 +557,34 @@ async function authoringDoc(catalog, kind, name) {
416
557
  * @returns {Promise<(target: string) => Promise<FoundDoc | {problem: string}>>}
417
558
  */
418
559
  async function docFinder(catalog, fromProvider) {
419
- const identities = identitiesOf(await projectTree(catalog));
560
+ return docFinderOver(catalog, await projectTree(catalog), fromProvider);
561
+ }
562
+
563
+ /**
564
+ * {@link docFinder} over a tree already built, so building the tree can
565
+ * resolve the links in its own summaries.
566
+ * @param {DocsCatalog} catalog
567
+ * @param {DocsTree} tree
568
+ * @param {string} fromProvider
569
+ * @param {boolean} [summaries] resolve the links in a found flat topic's
570
+ * summary; off while a summary is itself being resolved, so two summaries
571
+ * that link each other cannot loop
572
+ * @returns {(target: string) => Promise<FoundDoc | {problem: string}>}
573
+ */
574
+ function docFinderOver(catalog, tree, fromProvider, summaries = true) {
575
+ const identities = identitiesOf(tree);
420
576
  return async target => {
421
577
  const parsed = parseLinkTarget(target);
422
- if ('error' in parsed) return {problem: parsed.error};
578
+ if ('error' in parsed)
579
+ return {
580
+ problem: bareLinkHint(
581
+ parsed.error,
582
+ target,
583
+ catalog,
584
+ identities,
585
+ fromProvider,
586
+ ),
587
+ };
423
588
  let provider;
424
589
  try {
425
590
  provider = normalizeProviderId(parsed.provider ?? fromProvider);
@@ -428,7 +593,9 @@ async function docFinder(catalog, fromProvider) {
428
593
  problem: `"${target}" names "${parsed.provider}", which is not a provider id: an npm package name, or the \`providerId\` its manifest declares`,
429
594
  };
430
595
  }
431
- const node = identities.get(identityKey(provider, parsed.kind, parsed.name));
596
+ const node = identities.get(
597
+ identityKey(provider, parsed.kind, parsed.name),
598
+ );
432
599
  if (node) {
433
600
  return {
434
601
  link: {
@@ -447,14 +614,14 @@ async function docFinder(catalog, fromProvider) {
447
614
  }
448
615
  const authored =
449
616
  provider === CLI_PROVIDER_ID
450
- ? await authoringDoc(catalog, parsed.kind, parsed.name)
617
+ ? await authoringDoc(parsed.kind, parsed.name)
451
618
  : null;
452
619
  if (authored) {
453
620
  return {
454
621
  link: {
455
622
  target,
456
623
  id: createDocId(provider, authored.type, authored.name),
457
- route: 'authoring',
624
+ route: AUTHORING_REFERENCE_ROUTE,
458
625
  title: authored.displayName ?? authored.name,
459
626
  summary: authored.description ?? '',
460
627
  command: `astryx docs authoring ${authored.name}`,
@@ -477,6 +644,14 @@ async function docFinder(catalog, fromProvider) {
477
644
  const raw = await lowerRawTopic(catalog, entry);
478
645
  title = raw.doc.title ?? title;
479
646
  summary = raw.doc.description ?? summary;
647
+ if (summaries) {
648
+ summary = await linkSummary(
649
+ catalog,
650
+ tree,
651
+ providerOf(entry),
652
+ summary,
653
+ );
654
+ }
480
655
  } catch {
481
656
  // The topic budget check reports a topic that does not load; the
482
657
  // link still opens it.
@@ -495,12 +670,265 @@ async function docFinder(catalog, fromProvider) {
495
670
  };
496
671
  }
497
672
  }
673
+ if (CONTRIBUTED_KINDS.has(parsed.kind)) {
674
+ const link = await contributedDocLink(
675
+ catalog,
676
+ provider,
677
+ parsed.kind,
678
+ parsed.name,
679
+ );
680
+ if (link) {
681
+ // The summary is the target doc's own text, so its links resolve
682
+ // against the target's provider, never the linking doc's: a Core
683
+ // component's against the CLI's docs, like its other fields.
684
+ if (summaries && link.summary.includes('{@link')) {
685
+ link.summary = await linkSummary(
686
+ catalog,
687
+ tree,
688
+ provider === CORE_COMPONENT_PROVIDER ? CLI_PROVIDER_ID : provider,
689
+ link.summary,
690
+ );
691
+ }
692
+ return {link: {target, ...link}, kind: parsed.kind, typed: null};
693
+ }
694
+ }
695
+ const searchType =
696
+ parsed.kind === 'component'
697
+ ? 'component'
698
+ : parsed.kind === 'page' || parsed.kind === 'block'
699
+ ? 'template'
700
+ : 'doc';
701
+ return {
702
+ problem: `"${target}" names no doc. Find it with \`astryx search ${parsed.name} --type ${searchType}\`, then name it as \`[<provider>:]<kind>:<name>\`.`,
703
+ };
704
+ };
705
+ }
706
+
707
+ /**
708
+ * What a link written as a bare name (`{@link deploying}`) should say
709
+ * instead: the exact target to write when a topic or tree doc has that
710
+ * name, or that none does.
711
+ * @param {string} error the parse error
712
+ * @param {string} target the target as written
713
+ * @param {DocsCatalog} catalog
714
+ * @param {Map<string, any>} identities
715
+ * @param {string} fromProvider
716
+ * @returns {string}
717
+ */
718
+ function bareLinkHint(error, target, catalog, identities, fromProvider) {
719
+ const name = typeof target === 'string' ? target.trim() : '';
720
+ if (!name || name.includes(':') || /\s/.test(name)) return error;
721
+ /** @param {string} provider */
722
+ const normal = provider => {
723
+ try {
724
+ return normalizeProviderId(provider);
725
+ } catch {
726
+ return provider;
727
+ }
728
+ };
729
+ const from = normal(fromProvider);
730
+ /** @param {string} provider @param {string} kind @param {string} named */
731
+ const written = (provider, kind, named) =>
732
+ `{@link ${normal(provider) === from ? '' : `${provider}:`}${kind}:${named}}`;
733
+ const entry = catalog.resolve(name);
734
+ if (entry) {
735
+ return `${error}. "${name}" is a topic: write \`${written(entry.providerId ?? entry.package, 'generic', entry.name)}\`.`;
736
+ }
737
+ const node = [...identities.values()].find(
738
+ each => String(each.name).toLowerCase() === name.toLowerCase(),
739
+ );
740
+ if (node) {
741
+ return `${error}. "${name}" is a ${node.kind === 'generic' ? 'topic' : `${node.kind} doc`}: write \`${written(node.providerId, node.kind, node.name)}\`.`;
742
+ }
743
+ return `${error}, and no topic is named "${name}". Link a doc that exists, as \`{@link generic:<topic>}\` (\`astryx docs\` lists the topics), or remove the link.`;
744
+ }
745
+
746
+ /** The provider Core's components and templates belong to. */
747
+ const CORE_COMPONENT_PROVIDER = (() => {
748
+ try {
749
+ return normalizeProviderId(CORE_PACKAGE);
750
+ } catch {
751
+ return CORE_PACKAGE;
752
+ }
753
+ })();
754
+
755
+ /** The doc kinds no docs tree holds: components and templates. */
756
+ const CONTRIBUTED_KINDS = new Set(['component', 'page', 'block']);
757
+
758
+ /**
759
+ * The link to a component, page, or block doc (spec:AST-047 FR9). No docs tree
760
+ * holds these, so a link finds them among the component and template records
761
+ * the catalog carries, the ones `astryx component` and `astryx template` open,
762
+ * and reads as that command. A component is named by its export name, a
763
+ * template by its id; anything but Core's names its package.
764
+ * @param {DocsCatalog} catalog
765
+ * @param {string} provider normalized provider id
766
+ * @param {string} kind `component`, `page`, or `block`
767
+ * @param {string} name
768
+ * @returns {Promise<Omit<import('../../foundation/doc-compiler/links.mjs').DocLink, 'target'> | null>}
769
+ */
770
+ async function contributedDocLink(catalog, provider, kind, name) {
771
+ const contributions = await catalog.contributions();
772
+ if (!contributions) return null;
773
+ const sameProvider = (/** @type {string} */ providerId) => {
774
+ try {
775
+ return normalizeProviderId(providerId) === provider;
776
+ } catch {
777
+ return false;
778
+ }
779
+ };
780
+ if (kind === 'component') {
781
+ const record = contributions.components.find(
782
+ component =>
783
+ component.name === name && sameProvider(component.providerId),
784
+ );
785
+ if (!record) return null;
786
+ /** @type {any} */
787
+ let doc = null;
788
+ try {
789
+ doc = record.docPath ? await loadComponentDoc(record.docPath) : null;
790
+ } catch {
791
+ // The component checks report a doc that does not load; the link
792
+ // still opens the component.
793
+ }
794
+ const entry =
795
+ doc?.name === name
796
+ ? doc
797
+ : doc?.components?.find(
798
+ (/** @type {any} */ each) => each.name === name,
799
+ );
800
+ // Bare, Core's name opens Core's component unless another package ships
801
+ // the same name or replaces it (spec:AST-035 FR11); then the link selects
802
+ // Core, as it always selects any other package.
803
+ const selectPackage =
804
+ record.package !== CORE_PACKAGE ||
805
+ contributions.components.some(
806
+ other =>
807
+ other.package !== CORE_PACKAGE &&
808
+ (other.name === name || other.replaces === name),
809
+ );
498
810
  return {
499
- problem: `"${target}" names no doc. Find it with \`astryx search ${parsed.name} --type doc\`, then name it as \`[<provider>:]<kind>:<name>\`.`,
811
+ id: createDocId(provider, 'component', name),
812
+ route: null,
813
+ title: entry?.displayName ?? name,
814
+ summary: entry?.description ?? doc?.description ?? '',
815
+ command: `astryx component ${name}${selectPackage ? ` --package ${record.package}` : ''}`,
500
816
  };
817
+ }
818
+ const template = contributions.templates.find(
819
+ each =>
820
+ each.type === kind && each.id === name && sameProvider(each.providerId),
821
+ );
822
+ if (!template) return null;
823
+ // The same for a Core template: another package's template of its kind
824
+ // with its id, or one that replaces it, takes the bare id.
825
+ const selectPackage =
826
+ template.package !== CORE_PACKAGE ||
827
+ contributions.templates.some(
828
+ other =>
829
+ other.package !== CORE_PACKAGE &&
830
+ other.type === template.type &&
831
+ (other.id === name || other.replaces === name),
832
+ );
833
+ return {
834
+ id: createDocId(provider, template.type, name),
835
+ route: null,
836
+ title: template.displayName ?? template.name,
837
+ summary: template.description ?? '',
838
+ command: `astryx template ${name} --type ${template.type}${selectPackage ? ` --package ${template.package}` : ''}`,
501
839
  };
502
840
  }
503
841
 
842
+ /**
843
+ * The component and template docs one integration package's links can name:
844
+ * Core's and its own, as `doctor integration docs` checks it before any app
845
+ * configures it.
846
+ * @param {any} integration a loaded integration: its name, provider id, roots,
847
+ * and package directory
848
+ * @returns {Promise<import('../../foundation/discovery/docs-discovery.mjs').LinkableContributions>}
849
+ */
850
+ async function packageContributions(integration) {
851
+ const own = integration.providerId ?? integration.name;
852
+ /** @type {import('../../foundation/discovery/docs-discovery.mjs').LinkableComponent[]} */
853
+ const components = [];
854
+ const coreDir = findCoreDir(integration.__packageDir ?? process.cwd());
855
+ if (coreDir) {
856
+ try {
857
+ for (const record of discoverOwnedComponents(coreDir, [])) {
858
+ components.push({
859
+ providerId: CORE_PACKAGE,
860
+ package: CORE_PACKAGE,
861
+ name: record.name,
862
+ docPath: record.docPath,
863
+ });
864
+ }
865
+ } catch {
866
+ // The components check reports a Core it cannot read.
867
+ }
868
+ }
869
+ if (integration.components) {
870
+ try {
871
+ const {components: records} =
872
+ await discoverValidIntegrationComponents(integration);
873
+ for (const record of records) {
874
+ components.push({
875
+ providerId: own,
876
+ package: integration.name,
877
+ name: record.name,
878
+ docPath: record.docPath,
879
+ // Declared: this package alone cannot tell whether an app applies
880
+ // it, so a link to the Core name it names selects Core.
881
+ ...(typeof record.replaces === 'string'
882
+ ? {replaces: record.replaces}
883
+ : {}),
884
+ });
885
+ }
886
+ } catch {
887
+ // `validate` reports components that do not load.
888
+ }
889
+ }
890
+ /** @type {import('../../foundation/discovery/docs-discovery.mjs').LinkableTemplate[]} */
891
+ const templates = [];
892
+ /** @param {any} template @param {string} providerId @param {string} pkg */
893
+ const addTemplate = (template, providerId, pkg) => {
894
+ if (template.type !== 'page' && template.type !== 'block') return;
895
+ templates.push({
896
+ providerId,
897
+ package: pkg,
898
+ type: template.type,
899
+ id: template.dirName,
900
+ name: template.name,
901
+ ...(template.displayName == null
902
+ ? {}
903
+ : {displayName: template.displayName}),
904
+ ...(template.description == null
905
+ ? {}
906
+ : {description: template.description}),
907
+ ...(typeof template.replaces === 'string'
908
+ ? {replaces: template.replaces}
909
+ : {}),
910
+ });
911
+ };
912
+ try {
913
+ for (const template of await discoverCoreTemplates()) {
914
+ addTemplate(template, CORE_PACKAGE, CORE_PACKAGE);
915
+ }
916
+ } catch {
917
+ // Core templates that do not load leave nothing to link to.
918
+ }
919
+ if (integration.templates) {
920
+ try {
921
+ const {templates: records} =
922
+ await discoverIntegrationTemplatesForOne(integration);
923
+ for (const template of records)
924
+ addTemplate(template, own, integration.name);
925
+ } catch {
926
+ // `validate` reports templates that do not load.
927
+ }
928
+ }
929
+ return {components, templates};
930
+ }
931
+
504
932
  /**
505
933
  * How a doc's links find their targets (spec:AST-047 FR9), as
506
934
  * {@link docFinder} finds them: each resolves to the link a read shows.
@@ -654,7 +1082,7 @@ export async function docsLinkProblems(
654
1082
  for (const problem of found) {
655
1083
  if ((problem.include === true) !== references) continue;
656
1084
  problems.push(
657
- `${where}${problem.section ? ` \u00a7 ${problem.section}` : ''}: ${problem.message}`,
1085
+ `${where}${problem.section ? ` \u00a7 ${problem.section}` : ''}${problem.field ? ` (${problem.field})` : ''}: ${problem.message}`,
658
1086
  );
659
1087
  }
660
1088
  };
@@ -689,6 +1117,95 @@ export async function docsLinkProblems(
689
1117
  return problems;
690
1118
  }
691
1119
 
1120
+ /**
1121
+ * The catalog one integration package's docs and links read, as doctor checks
1122
+ * it before any app configures it: the CLI's topics, Core's and the package's
1123
+ * components and templates, and the package's own docs.
1124
+ * @param {any} integration
1125
+ * @param {{records: import('../../foundation/discovery/docs-discovery.mjs').DocsTopicRecord[], namespaces: import('../../foundation/doc-compiler/tree.mjs').TreeNamespaceInput[], guides: import('../../foundation/doc-compiler/tree.mjs').TreeDocInput[]} | null} discovered
1126
+ * @returns {DocsCatalog}
1127
+ */
1128
+ function packageCatalog(integration, discovered) {
1129
+ const catalog = DocsCatalog.fromBuiltins();
1130
+ catalog.setContributions(() => packageContributions(integration));
1131
+ if (discovered) {
1132
+ for (const record of discovered.records) catalog.add(record);
1133
+ catalog.addTreeInputs({
1134
+ namespaces: discovered.namespaces.map(input => ({...input, rank: 1})),
1135
+ guides: discovered.guides.map(input => ({...input, rank: 1})),
1136
+ });
1137
+ }
1138
+ return catalog;
1139
+ }
1140
+
1141
+ /**
1142
+ * What \`astryx doctor integration components\` checks of the links in one
1143
+ * integration's own component docs (spec:AST-047 FR9): each link in a
1144
+ * description, usage, best practice, or prop's or example's description that
1145
+ * names no doc. It prints as written, so each is a warning.
1146
+ * @param {any} integration a loaded integration
1147
+ * @param {Parameters<typeof packageCatalog>[1]} discovered the package's own
1148
+ * docs, which its components' links may name; null when it ships none
1149
+ * @returns {Promise<Array<{severity: 'warning', message: string}>>}
1150
+ */
1151
+ export async function packageComponentLinkProblems(integration, discovered) {
1152
+ // A package with no provider id (its manifest's, else its name) links
1153
+ // nothing, as on the read path: its text reads as written, so there is
1154
+ // nothing to report.
1155
+ try {
1156
+ normalizeProviderId(integration.providerId ?? integration.name);
1157
+ } catch {
1158
+ return [];
1159
+ }
1160
+ const catalog = packageCatalog(integration, discovered);
1161
+ return (await componentLinkProblems(catalog, integration.name)).map(
1162
+ message => ({severity: /** @type {const} */ ('warning'), message}),
1163
+ );
1164
+ }
1165
+
1166
+ /**
1167
+ * Each link in a package's own component docs that names no doc. A family doc
1168
+ * that documents several components is read once.
1169
+ * @param {DocsCatalog} catalog
1170
+ * @param {string} owner the package whose component docs are read
1171
+ * @returns {Promise<string[]>}
1172
+ */
1173
+ async function componentLinkProblems(catalog, owner) {
1174
+ const contributions = await catalog.contributions();
1175
+ /** @type {string[]} */
1176
+ const problems = [];
1177
+ const seen = new Set();
1178
+ for (const record of contributions?.components ?? []) {
1179
+ if (record.package !== owner || !record.docPath) continue;
1180
+ if (seen.has(record.docPath)) continue;
1181
+ seen.add(record.docPath);
1182
+ /** @type {any} */
1183
+ let doc;
1184
+ try {
1185
+ doc = await loadComponentDoc(record.docPath);
1186
+ } catch {
1187
+ // The components check reports a doc that does not load.
1188
+ continue;
1189
+ }
1190
+ let provider;
1191
+ try {
1192
+ provider = componentLinkProvider(record.package, record.providerId);
1193
+ } catch {
1194
+ // An owner that is not a provider id links nothing (as on the read
1195
+ // path); its text reads as written.
1196
+ continue;
1197
+ }
1198
+ const linked = await linkComponentDoc(catalog, provider, doc);
1199
+ const name = typeof doc?.name === 'string' ? doc.name : record.name;
1200
+ for (const problem of linked.problems) {
1201
+ problems.push(
1202
+ `component ${name}${problem.field ? ` (${problem.field})` : ''}: ${problem.message}`,
1203
+ );
1204
+ }
1205
+ }
1206
+ return problems;
1207
+ }
1208
+
692
1209
  /**
693
1210
  * What \`astryx doctor integration docs\` checks in one integration's docs: the
694
1211
  * docs tree they build beside the CLI's (namespaces, placements, routes) and
@@ -700,12 +1217,7 @@ export async function docsLinkProblems(
700
1217
  * @returns {Promise<Array<{severity: 'error' | 'warning', message: string}>>}
701
1218
  */
702
1219
  export async function packageDocsProblems(integration, discovered) {
703
- const catalog = DocsCatalog.fromBuiltins();
704
- for (const record of discovered.records) catalog.add(record);
705
- catalog.addTreeInputs({
706
- namespaces: discovered.namespaces.map(input => ({...input, rank: 1})),
707
- guides: discovered.guides.map(input => ({...input, rank: 1})),
708
- });
1220
+ const catalog = packageCatalog(integration, discovered);
709
1221
  const tree = await projectTree(catalog);
710
1222
  /** @type {Array<{severity: 'error' | 'warning', message: string}>} */
711
1223
  const problems = tree.diagnostics
@@ -794,6 +1306,7 @@ async function namespaceReferenceTarget(catalog, route, lang) {
794
1306
  */
795
1307
  export async function packageReferenceProblems(integration, discovered) {
796
1308
  const catalog = DocsCatalog.fromBuiltins();
1309
+ catalog.setContributions(() => packageContributions(integration));
797
1310
  for (const record of discovered.records) catalog.add(record);
798
1311
  catalog.addTreeInputs({
799
1312
  namespaces: discovered.namespaces.map(input => ({...input, rank: 1})),
@@ -918,7 +1431,7 @@ export function placeLinks(tree, node) {
918
1431
 
919
1432
  /**
920
1433
  * The moves a topic read offers: from its place in the tree, where a guide
921
- * sits in its namespace and a flat topic in the Unorganized level.
1434
+ * sits in its namespace and a flat topic in its topic level.
922
1435
  * @param {DocsCatalog} catalog
923
1436
  * @param {import('../../foundation/discovery/docs-discovery.mjs').DocsTopicEntry} entry
924
1437
  * @returns {Promise<import('./docs.type.mjs').DocsLinks>}
@@ -927,7 +1440,8 @@ export async function topicLinks(catalog, entry) {
927
1440
  const tree = await projectTree(catalog);
928
1441
  const node = tree.get(entry.tree ? (entry.route ?? entry.name) : entry.name);
929
1442
  const placed =
930
- node && (entry.tree ? node.kind === 'generic' : node.ref?.flatTopic === entry.name);
1443
+ node &&
1444
+ (entry.tree ? node.kind === 'generic' : node.ref?.flatTopic === entry.name);
931
1445
  return placed ? placeLinks(tree, node) : {up: topicUp(entry)};
932
1446
  }
933
1447
 
@@ -950,7 +1464,8 @@ export async function resolveDocsArgument(topic, {cwd} = {}) {
950
1464
  const tree = await projectTree(catalog);
951
1465
  const owner = nameOwner(tree, catalog, topic);
952
1466
  if (owner == null) return {kind: 'unknown', catalog};
953
- if (owner.kind === 'topic') return {kind: 'topic', catalog, entry: owner.entry};
1467
+ if (owner.kind === 'topic')
1468
+ return {kind: 'topic', catalog, entry: owner.entry};
954
1469
  return treeArgument(catalog, tree, owner.node);
955
1470
  }
956
1471
 
@@ -1014,7 +1529,7 @@ function treeArgument(catalog, tree, node) {
1014
1529
  /**
1015
1530
  * The doc that took a flat topic's route in the docs tree, when it is not
1016
1531
  * that topic (spec:AST-046 FR11): the CLI keeps its routes, such as `cli`
1017
- * and `unorganized`, and a namespace keeps its route over a topic of the same
1532
+ * and `guides`, and a namespace keeps its route over a topic of the same
1018
1533
  * name. Null when the topic owns its route, or the tree has no node there.
1019
1534
  * @param {DocsTree} tree
1020
1535
  * @param {import('../../foundation/discovery/docs-discovery.mjs').DocsTopicEntry} entry
@@ -1028,6 +1543,35 @@ export function routeOwner(tree, entry) {
1028
1543
  : node;
1029
1544
  }
1030
1545
 
1546
+ /**
1547
+ * Routes that moved, old prefix first: the integration guides moved from
1548
+ * `cli/integrations` (and, before that, the `cli-integrations` topic) into
1549
+ * `authoring`, the one home for integration authors.
1550
+ * Only the not-found error reads this, to name where a doc went; an old route
1551
+ * opens nothing.
1552
+ */
1553
+ const MOVED_ROUTES = [
1554
+ ['cli/integrations', 'authoring'],
1555
+ ['cli-integrations', 'authoring'],
1556
+ ];
1557
+
1558
+ /**
1559
+ * The node an old route moved to, or null.
1560
+ * @param {unknown} topic
1561
+ * @param {DocsTree} tree
1562
+ * @returns {TreeNode | null}
1563
+ */
1564
+ function movedRoute(topic, tree) {
1565
+ if (typeof topic !== 'string') return null;
1566
+ const wanted = topic.toLowerCase();
1567
+ for (const [from, to] of MOVED_ROUTES) {
1568
+ if (wanted !== from && !wanted.startsWith(`${from}/`)) continue;
1569
+ const node = tree.getFolded(`${to}${wanted.slice(from.length)}`);
1570
+ if (node) return node;
1571
+ }
1572
+ return null;
1573
+ }
1574
+
1031
1575
  /**
1032
1576
  * The error for a docs argument that names nothing. For a route, it suggests
1033
1577
  * the children of the deepest namespace the route reaches; otherwise, every
@@ -1060,8 +1604,7 @@ export async function unknownTopicError(topic, catalog) {
1060
1604
  }
1061
1605
  if (suggestions.length === 0 && typeof topic === 'string') {
1062
1606
  // The docs whose own name it is (`doctor` is cli/commands/doctor), or whose
1063
- // route it spells with hyphens (`cli-integrations`, the guide's name before
1064
- // it moved to cli/integrations).
1607
+ // route it spells with hyphens (`cli-host-entry` is cli/host-entry).
1065
1608
  const wanted = topic.toLowerCase();
1066
1609
  suggestions = [...tree.nodes.values()]
1067
1610
  .filter(
@@ -1080,6 +1623,22 @@ export async function unknownTopicError(topic, catalog) {
1080
1623
  ...catalog.names().map(name => ({name, reason: 'available topic'})),
1081
1624
  ];
1082
1625
  }
1626
+ if (typeof topic === 'string') {
1627
+ suggestions = orderRouteSuggestions(topic, suggestions);
1628
+ }
1629
+ // A route that moved names where it went, ahead of the usual suggestions
1630
+ // (spec:AST-046 FR9, FR6).
1631
+ const moved = movedRoute(topic, tree);
1632
+ if (moved) {
1633
+ return new AstryxError(
1634
+ `Unknown topic "${String(topic)}". It moved to "${moved.route}"${notLoaded(catalog)}`,
1635
+ [
1636
+ {name: moved.route, reason: moved.summary},
1637
+ ...suggestions.filter(entry => entry.name !== moved.route),
1638
+ ],
1639
+ ERROR_CODES.ERR_UNKNOWN_TOPIC,
1640
+ );
1641
+ }
1083
1642
  return new AstryxError(
1084
1643
  `Unknown topic "${String(topic)}"${notLoaded(catalog)}`,
1085
1644
  suggestions,
@@ -1097,7 +1656,7 @@ export async function unknownTopicError(topic, catalog) {
1097
1656
  export function notLoaded(catalog) {
1098
1657
  const packages = [...new Set(catalog.issues.map(issue => issue.package))];
1099
1658
  if (packages.length === 0) return '';
1100
- return `. The docs of ${packages.join(', ')} did not load; run \`astryx doctor integration docs\` in that package to see why.`;
1659
+ return `. The docs of ${packages.join(', ')} did not load; run \`${formatCliCommand('doctor integration docs')}\` in that package to see why.`;
1101
1660
  }
1102
1661
 
1103
1662
  /**
@@ -1115,7 +1674,7 @@ export async function resolveTopicDocs(topic, options = {}) {
1115
1674
  if (found.kind !== 'topic') {
1116
1675
  throw found.kind === 'node'
1117
1676
  ? new AstryxError(
1118
- `"${found.node.route}" is a ${found.node.kind === 'namespace' ? 'namespace' : `${found.node.kind} doc`} in the docs tree, not a topic. Read it with \`astryx docs ${found.node.route}\`.`,
1677
+ `"${found.node.route}" is a ${found.node.kind === 'namespace' ? 'namespace' : `${found.node.kind} doc`} in the docs tree, not a topic. Read it with \`${formatCliCommand(`docs ${found.node.route}`)}\`.`,
1119
1678
  undefined,
1120
1679
  ERROR_CODES.ERR_UNKNOWN_TOPIC,
1121
1680
  )
@@ -1125,3 +1684,40 @@ export async function resolveTopicDocs(topic, options = {}) {
1125
1684
  const node = await lowerTopic(catalog, entry, effectiveLang);
1126
1685
  return {catalog, node, lang: effectiveLang, entry};
1127
1686
  }
1687
+
1688
+ /**
1689
+ * Each doc one integration package ships, checked against the published
1690
+ * authoring type for its kind with the project's own TypeScript (spec:AST-039
1691
+ * FR13). Without TypeScript the report says nothing was checked.
1692
+ * @param {any} integration a loaded integration
1693
+ * @param {string} cwd
1694
+ * @returns {Promise<import('../../foundation/discovery/doc-types.mjs').DocTypesReport & {fixtures?: number}>}
1695
+ */
1696
+ export async function integrationDocTypes(integration, cwd) {
1697
+ const packageDir = /** @type {{__packageDir?: string}} */ (integration)
1698
+ .__packageDir;
1699
+ const {files, unread, fixtures} = await integrationDocFiles(integration);
1700
+ const checked = await checkDocTypes(files, {
1701
+ packageDir: packageDir ?? cwd,
1702
+ resolveFrom: [cwd, packageDir],
1703
+ });
1704
+ // Test fixtures no reader serves don't ship as docs: only counted.
1705
+ const report =
1706
+ checked.status === 'checked' && fixtures > 0
1707
+ ? {...checked, fixtures}
1708
+ : checked;
1709
+ if (report.status !== 'checked' || unread.length === 0) return report;
1710
+ // A root its reader cannot read serves no doc; say so rather than skip it.
1711
+ const rel = (/** @type {string} */ file) =>
1712
+ path
1713
+ .relative(packageDir ?? cwd, file)
1714
+ .split(path.sep)
1715
+ .join('/') || '.';
1716
+ return {
1717
+ ...report,
1718
+ unchecked: [
1719
+ ...report.unchecked,
1720
+ ...unread.map(entry => ({doc: rel(entry.path), reason: entry.reason})),
1721
+ ].sort((a, b) => a.doc.localeCompare(b.doc)),
1722
+ };
1723
+ }