@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4

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 (331) hide show
  1. package/README.md +96 -99
  2. package/api/build/build.doc.mjs +1 -6
  3. package/api/build/build.test.mjs +0 -22
  4. package/api/build/kit/kit.mjs +5 -44
  5. package/api/component/_adapter.d.mts +0 -25
  6. package/api/component/_adapter.mjs +5 -59
  7. package/api/component/component.d.mts +3 -6
  8. package/api/component/component.doc.mjs +17 -37
  9. package/api/component/component.mjs +9 -249
  10. package/api/component/component.type.d.mts +0 -25
  11. package/api/component/component.type.mjs +0 -44
  12. package/api/discover/_adapter.d.mts +6 -114
  13. package/api/discover/_adapter.mjs +17 -372
  14. package/api/discover/detail/detail.d.mts +6 -18
  15. package/api/discover/detail/detail.mjs +13 -67
  16. package/api/discover/detail/detail.test.mjs +0 -85
  17. package/api/discover/discover.d.mts +9 -3
  18. package/api/discover/discover.doc.mjs +18 -61
  19. package/api/discover/discover.mjs +36 -220
  20. package/api/discover/discover.test.mjs +2 -11
  21. package/api/discover/discover.type.d.mts +8 -147
  22. package/api/discover/discover.type.mjs +12 -102
  23. package/api/discover/list/list.d.mts +6 -20
  24. package/api/discover/list/list.mjs +12 -45
  25. package/api/discover/list/list.test.mjs +0 -46
  26. package/api/discover/search/search.d.mts +16 -18
  27. package/api/discover/search/search.mjs +56 -102
  28. package/api/discover/search/search.test.mjs +10 -144
  29. package/api/docs/_adapter.d.mts +3 -8
  30. package/api/docs/_adapter.mjs +6 -14
  31. package/api/docs/docOverlays.test.mjs +1 -27
  32. package/api/docs/docs.doc.mjs +2 -2
  33. package/api/docs/docs.test.mjs +243 -0
  34. package/api/docs/integration-tree.test.mjs +555 -0
  35. package/api/docs/integrationDocs.test.mjs +314 -0
  36. package/api/doctor/doctor.d.mts +3 -8
  37. package/api/doctor/doctor.doc.mjs +8 -17
  38. package/api/doctor/doctor.mjs +9 -90
  39. package/api/doctor/doctor.test.mjs +10 -122
  40. package/api/doctor/doctor.type.d.mts +1 -1
  41. package/api/doctor/doctor.type.mjs +1 -1
  42. package/api/gap-report/gap-report.doc.mjs +10 -19
  43. package/api/hook/hook.doc.mjs +3 -6
  44. package/api/index.d.mts +2 -1
  45. package/api/index.mjs +5 -5
  46. package/api/init/init.doc.mjs +12 -17
  47. package/api/integration/add-helpers.d.mts +2 -5
  48. package/api/integration/add-helpers.mjs +9 -36
  49. package/api/integration/add-theme.mjs +1 -22
  50. package/api/integration/add-theme.test.mjs +0 -34
  51. package/api/integration/authoring-checks.mjs +2 -2
  52. package/api/integration/integrationPackCheck.doc.mjs +3 -3
  53. package/api/integration/pack-check.mjs +9 -82
  54. package/api/integration/pack-check.test.mjs +0 -90
  55. package/api/integration/pack-check.type.mjs +1 -1
  56. package/api/json/assertResponse.doc.mjs +1 -1
  57. package/api/json/index.ts +1 -0
  58. package/api/json/isError.doc.mjs +1 -1
  59. package/api/layout/_adapter.d.mts +34 -0
  60. package/api/layout/_adapter.mjs +148 -0
  61. package/api/layout/check/check.d.mts +16 -0
  62. package/api/layout/check/check.mjs +40 -0
  63. package/api/layout/expand/expand.d.mts +22 -0
  64. package/api/layout/expand/expand.mjs +155 -0
  65. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  66. package/api/layout/grammar/grammar.d.mts +13 -0
  67. package/api/layout/grammar/grammar.mjs +87 -0
  68. package/api/layout/layout.d.mts +6 -0
  69. package/api/layout/layout.mjs +17 -0
  70. package/api/layout/layout.test.mjs +297 -0
  71. package/api/layout/layout.type.d.mts +89 -0
  72. package/api/layout/layout.type.mjs +103 -0
  73. package/api/layout/layoutCheck.doc.d.mts +11 -0
  74. package/api/layout/layoutCheck.doc.mjs +85 -0
  75. package/api/layout/layoutExpand.doc.d.mts +11 -0
  76. package/api/layout/layoutExpand.doc.mjs +107 -0
  77. package/api/layout/layoutGrammar.doc.d.mts +11 -0
  78. package/api/layout/layoutGrammar.doc.mjs +57 -0
  79. package/api/search/search.d.mts +1 -27
  80. package/api/search/search.doc.mjs +2 -2
  81. package/api/search/search.mjs +16 -228
  82. package/api/search/search.test.mjs +512 -0
  83. package/api/swizzle/swizzle.doc.mjs +5 -7
  84. package/api/template/copy/copy.mjs +1 -1
  85. package/api/template/copy/copy.test.mjs +0 -9
  86. package/api/template/template-integration.test.mjs +65 -1
  87. package/api/template/template.doc.mjs +1 -2
  88. package/api/template/template.mjs +1 -1
  89. package/api/theme/add/add.mjs +25 -17
  90. package/api/theme/add/add.staging.test.mjs +23 -40
  91. package/api/theme/build/build.family.test.mjs +12 -7
  92. package/api/theme/build/build.mjs +18 -8
  93. package/api/theme/generateTonalPalette.doc.mjs +2 -1
  94. package/api/theme/listThemes.doc.mjs +1 -1
  95. package/api/theme/themeAdd.doc.mjs +10 -9
  96. package/api/theme/themeBuild.doc.mjs +13 -13
  97. package/api/theme/themeList.doc.mjs +1 -1
  98. package/api/theme/themeListAvailable.doc.mjs +1 -2
  99. package/api/theme/themePaletteGenerate.doc.mjs +8 -15
  100. package/api/theme/themeTargets.doc.mjs +2 -3
  101. package/api/theme/themeTemplate.doc.mjs +1 -2
  102. package/api/upgrade/run/run.mjs +4 -6
  103. package/api/upgrade/upgrade.doc.mjs +22 -24
  104. package/api/upgrade/upgrade.type.mjs +2 -2
  105. package/assets/codemods/__tests__/runner.test.mjs +1 -3
  106. package/assets/codemods/integration-runner.mjs +3 -3
  107. package/assets/codemods/runner.mjs +4 -5
  108. package/assets/docs/README.md +2 -4
  109. package/assets/docs/browser-support.doc.mjs +11 -11
  110. package/assets/docs/color.doc.mjs +2 -8
  111. package/assets/docs/elevation.doc.mjs +4 -6
  112. package/assets/docs/getting-started.doc.mjs +16 -5
  113. package/assets/docs/icons.doc.mjs +21 -2
  114. package/assets/docs/illustrations.doc.mjs +15 -7
  115. package/assets/docs/internationalization.doc.mjs +5 -7
  116. package/assets/docs/layout.doc.dense.mjs +82 -130
  117. package/assets/docs/layout.doc.mjs +77 -133
  118. package/assets/docs/migration.doc.mjs +21 -19
  119. package/assets/docs/motion.doc.mjs +3 -16
  120. package/assets/docs/principles.doc.dense.mjs +5 -5
  121. package/assets/docs/principles.doc.mjs +0 -8
  122. package/assets/docs/principles.doc.zh.mjs +6 -6
  123. package/assets/docs/shape.doc.mjs +3 -8
  124. package/assets/docs/spacing.doc.mjs +2 -7
  125. package/assets/docs/styling-libraries.doc.mjs +2 -6
  126. package/assets/docs/styling.doc.mjs +23 -19
  127. package/assets/docs/theme.doc.dense.mjs +18 -58
  128. package/assets/docs/theme.doc.mjs +46 -56
  129. package/assets/docs/theme.doc.zh.mjs +8 -9
  130. package/assets/docs/tokens.doc.dense.mjs +2 -2
  131. package/assets/docs/tokens.doc.mjs +8 -389
  132. package/assets/docs/tokens.doc.zh.mjs +2 -2
  133. package/assets/docs/tree/integrations.doc.mjs +451 -25
  134. package/assets/docs/tree/integrations.test.mjs +62 -0
  135. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  136. package/assets/docs/typography.doc.mjs +4 -24
  137. package/assets/docs/working-with-ai.doc.mjs +22 -30
  138. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  139. package/authoring/config/config.doc.mjs +2 -10
  140. package/authoring/config/parse.d.mts +0 -2
  141. package/authoring/config/parse.mjs +0 -19
  142. package/authoring/config/parse.test.mjs +0 -8
  143. package/authoring/config/type.ts +2 -13
  144. package/authoring/doctypes/_schema.d.mts +2 -3
  145. package/authoring/doctypes/_schema.mjs +0 -6
  146. package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
  147. package/authoring/doctypes/base/type.ts +2 -4
  148. package/authoring/doctypes/command/command.doc.mjs +1 -1
  149. package/authoring/doctypes/command/type.ts +1 -1
  150. package/authoring/doctypes/component/component.doc.mjs +0 -6
  151. package/authoring/doctypes/component/type.ts +0 -8
  152. package/authoring/doctypes/reference/reference.doc.mjs +0 -7
  153. package/authoring/doctypes/reference/type.ts +0 -5
  154. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  155. package/authoring/doctypes/template/template.doc.mjs +1 -1
  156. package/authoring/doctypes/template/type.ts +2 -2
  157. package/authoring/index.d.mts +0 -1
  158. package/authoring/index.d.ts +0 -10
  159. package/authoring/index.mjs +0 -1
  160. package/authoring/integration/integration.doc.mjs +10 -12
  161. package/clients/cli/command-result-coverage.test.mjs +7 -7
  162. package/clients/cli/commands/component/index.mjs +55 -152
  163. package/clients/cli/commands/component-ownership.test.mjs +0 -89
  164. package/clients/cli/commands/component.doc.mjs +9 -27
  165. package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
  166. package/clients/cli/commands/discover.doc.mjs +9 -53
  167. package/clients/cli/commands/discover.mjs +118 -393
  168. package/clients/cli/commands/docs.doc.mjs +1 -1
  169. package/clients/cli/commands/docs.mjs +17 -60
  170. package/clients/cli/commands/docs.test.mjs +294 -0
  171. package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
  172. package/clients/cli/commands/doctor-integration.test.mjs +0 -53
  173. package/clients/cli/commands/doctor.doc.mjs +1 -3
  174. package/clients/cli/commands/doctor.mjs +5 -49
  175. package/clients/cli/commands/gap-report.doc.mjs +9 -10
  176. package/clients/cli/commands/init.doc.mjs +6 -9
  177. package/clients/cli/commands/integration-add.doc.mjs +9 -9
  178. package/clients/cli/commands/integration-authoring.test.mjs +10 -61
  179. package/clients/cli/commands/integration-pack.doc.mjs +9 -5
  180. package/clients/cli/commands/integration-real-world.test.mjs +1 -1
  181. package/clients/cli/commands/integration.doc.mjs +4 -4
  182. package/clients/cli/commands/integration.mjs +43 -74
  183. package/clients/cli/commands/layout-check.doc.mjs +65 -0
  184. package/clients/cli/commands/layout-expand.doc.mjs +83 -0
  185. package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
  186. package/clients/cli/commands/layout.doc.mjs +34 -0
  187. package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
  188. package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
  189. package/clients/cli/commands/layout.mjs +275 -0
  190. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  191. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  192. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  193. package/clients/cli/commands/manifest.doc.mjs +1 -1
  194. package/clients/cli/commands/search.doc.mjs +3 -10
  195. package/clients/cli/commands/search.mjs +2 -21
  196. package/clients/cli/commands/search.test.mjs +4 -21
  197. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  198. package/clients/cli/commands/template.doc.mjs +1 -1
  199. package/clients/cli/commands/text-json-parity.test.mjs +16 -5
  200. package/clients/cli/commands/theme-add.doc.mjs +1 -1
  201. package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
  202. package/clients/cli/commands/theme-palette.doc.mjs +2 -1
  203. package/clients/cli/commands/theme-targets.doc.mjs +2 -2
  204. package/clients/cli/commands/theme.doc.mjs +1 -2
  205. package/clients/cli/commands/upgrade.doc.mjs +3 -62
  206. package/clients/cli/index.mjs +10 -28
  207. package/clients/cli/lib/define-command.mjs +4 -28
  208. package/clients/cli/lib/define-command.test.mjs +0 -54
  209. package/clients/cli/lib/exit-codes.test.mjs +9 -18
  210. package/clients/cli/lib/json-shim.mjs +14 -24
  211. package/clients/cli/lib/json-shim.test.mjs +20 -6
  212. package/clients/cli/lib/manifest.mjs +13 -18
  213. package/clients/cli/lib/manifest.test.mjs +2 -5
  214. package/foundation/agent-docs/agent-docs.mjs +1 -1
  215. package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
  216. package/foundation/discovery/authoring-self-docs.mjs +0 -1
  217. package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
  218. package/foundation/discovery/cli-self-docs.mjs +2 -16
  219. package/foundation/discovery/cli-self-docs.test.mjs +0 -20
  220. package/foundation/discovery/docs-discovery.mjs +1 -5
  221. package/foundation/discovery/docs-discovery.test.mjs +0 -21
  222. package/foundation/discovery/docs-section-key.d.mts +1 -1
  223. package/foundation/discovery/docs-section-key.mjs +1 -1
  224. package/foundation/discovery/template-adapter.mjs +1 -1
  225. package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
  226. package/foundation/doc-compiler/tree.d.mts +0 -4
  227. package/foundation/doc-compiler/tree.mjs +1 -6
  228. package/foundation/doc-compiler/tree.test.mjs +598 -0
  229. package/foundation/integrations/cli-requirement.d.mts +6 -26
  230. package/foundation/integrations/cli-requirement.mjs +11 -46
  231. package/foundation/integrations/cli-requirement.test.mjs +2 -7
  232. package/foundation/integrations/contribution-inventory.mjs +1 -1
  233. package/foundation/integrations/integrations.d.mts +1 -14
  234. package/foundation/integrations/integrations.mjs +1 -41
  235. package/foundation/integrations/integrations.test.mjs +0 -31
  236. package/foundation/response/error-codes.doc.mjs +8 -6
  237. package/foundation/response/error-codes.test.mjs +5 -30
  238. package/foundation/response/response-types.doc.d.mts +3 -4
  239. package/foundation/response/response-types.doc.mjs +27 -40
  240. package/foundation/response/response-types.doc.test.mjs +0 -23
  241. package/foundation/response/response.doc.mjs +10 -11
  242. package/foundation/xle/browser.d.mts +3 -3
  243. package/foundation/xle/browser.mjs +3 -3
  244. package/foundation/xle/expand.mjs +2 -2
  245. package/foundation/xle/parse.mjs +1 -1
  246. package/foundation/xle/print.mjs +2 -2
  247. package/foundation/xle/splice.mjs +1 -1
  248. package/package.json +9 -9
  249. package/api/discover/_adapter.test.mjs +0 -215
  250. package/api/discover/_catalog-view.d.mts +0 -115
  251. package/api/discover/_catalog-view.mjs +0 -203
  252. package/api/discover/_catalog-view.test.mjs +0 -128
  253. package/api/discover/detail/item/item.d.mts +0 -26
  254. package/api/discover/detail/item/item.mjs +0 -78
  255. package/api/discover/detail/item/item.test.mjs +0 -73
  256. package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
  257. package/api/theme/add/add.rollback.test.mjs +0 -158
  258. package/api/theme/build/build.rollback.test.mjs +0 -148
  259. package/api/upgrade/run/files-changed.test.mjs +0 -111
  260. package/assets/codemods/file-count.test.mjs +0 -163
  261. package/assets/docs/tree/add-a-component.doc.mjs +0 -75
  262. package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
  263. package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
  264. package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
  265. package/assets/docs/tree/block-template.doc.mjs +0 -130
  266. package/assets/docs/tree/build-the-template.doc.mjs +0 -28
  267. package/assets/docs/tree/building-blocks.doc.mjs +0 -46
  268. package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
  269. package/assets/docs/tree/checks.doc.mjs +0 -119
  270. package/assets/docs/tree/codemods.doc.mjs +0 -147
  271. package/assets/docs/tree/component-family.doc.mjs +0 -113
  272. package/assets/docs/tree/component-imports.doc.mjs +0 -69
  273. package/assets/docs/tree/component-lookups.doc.mjs +0 -149
  274. package/assets/docs/tree/components.doc.mjs +0 -23
  275. package/assets/docs/tree/configuration.doc.mjs +0 -23
  276. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
  277. package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
  278. package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
  279. package/assets/docs/tree/docs.doc.mjs +0 -21
  280. package/assets/docs/tree/document-the-template.doc.mjs +0 -28
  281. package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
  282. package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
  283. package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
  284. package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
  285. package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
  286. package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
  287. package/assets/docs/tree/help.doc.mjs +0 -16
  288. package/assets/docs/tree/links.doc.mjs +0 -98
  289. package/assets/docs/tree/package-and-test.doc.mjs +0 -32
  290. package/assets/docs/tree/page-template.doc.mjs +0 -71
  291. package/assets/docs/tree/publishing.doc.mjs +0 -111
  292. package/assets/docs/tree/quick-start.doc.mjs +0 -272
  293. package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
  294. package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
  295. package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
  296. package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
  297. package/assets/docs/tree/ship.doc.mjs +0 -16
  298. package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
  299. package/assets/docs/tree/single-component.doc.mjs +0 -165
  300. package/assets/docs/tree/start-a-template.doc.mjs +0 -143
  301. package/assets/docs/tree/subcomponent.doc.mjs +0 -115
  302. package/assets/docs/tree/template-assets.doc.mjs +0 -64
  303. package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
  304. package/assets/docs/tree/template-fonts.doc.mjs +0 -102
  305. package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
  306. package/assets/docs/tree/template-icons.doc.mjs +0 -97
  307. package/assets/docs/tree/template-images-media.doc.mjs +0 -127
  308. package/assets/docs/tree/template-styles.doc.mjs +0 -93
  309. package/assets/docs/tree/templates.doc.mjs +0 -34
  310. package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
  311. package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
  312. package/assets/docs/tree/themes.doc.mjs +0 -39
  313. package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
  314. package/assets/docs/tree/upgrading.doc.mjs +0 -103
  315. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
  316. package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
  317. package/assets/docs/tree/versioning.doc.mjs +0 -161
  318. package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
  319. package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
  320. package/authoring/discover/discover.doc.d.mts +0 -13
  321. package/authoring/discover/discover.doc.mjs +0 -138
  322. package/authoring/discover/parse.d.mts +0 -24
  323. package/authoring/discover/parse.mjs +0 -128
  324. package/authoring/discover/parse.test.mjs +0 -124
  325. package/authoring/discover/type.ts +0 -87
  326. package/clients/cli/commands/component-batch.test.mjs +0 -341
  327. package/clients/cli/commands/discover.sources.test.mjs +0 -267
  328. package/clients/cli/commands/integration-verify.doc.mjs +0 -22
  329. package/clients/cli/lib/parse-error-format.test.mjs +0 -81
  330. package/foundation/response/batch.type.d.mts +0 -33
  331. package/foundation/response/batch.type.mjs +0 -34
@@ -1,76 +1,44 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file discover.search leaf — free-text search across installed packages and,
5
- * when the project has discover sources, everything it could add.
4
+ * @file discover.search leaf — free-text search across external packages.
6
5
  *
7
- * A free-text query always answers with a list, so its response type depends
8
- * on the form of the query and never on what the project has:
9
- * 1. any matches -> discover.search
10
- * 2. fuzzy hits (distance <= 3) -> throw ERR_NOT_FOUND with suggestions
11
- * 3. otherwise -> throw ERR_NOT_FOUND
12
- * Matches are installed components, the project's other installed items,
13
- * packages, and every item a source lists for a package the project could add.
14
- * A caller opens one item by its package path, which ../detail answers.
6
+ * Resolution order (matching the flat command exactly):
7
+ * 1. exact component name -> discover.detail.doc
8
+ * 2. single substring hit -> discover.detail.doc
9
+ * 3. multiple substring hits -> discover.search
10
+ * 4. fuzzy hits (distance <= 3) -> throw ERR_NOT_FOUND with suggestions
11
+ * 5. otherwise -> throw ERR_NOT_FOUND
15
12
  *
16
- * @position api/discover/search — pure ranking over the installed component
17
- * names and ../_catalog-view's search items.
13
+ * @position api/discover/search — projection over ../_adapter's resolver;
14
+ * delegates the single-component cases to ../detail/doc.
18
15
  */
19
16
 
17
+ import {findComponent} from '../_adapter.mjs';
18
+ import {docFromResult} from '../detail/doc/doc.mjs';
20
19
  import {levenshteinDistance} from '../../../foundation/text/string-utils.mjs';
21
20
  import {AstryxError} from '../../error.mjs';
22
21
  import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
23
- import {DISCOVER_KINDS} from '../../../authoring/discover/parse.mjs';
24
22
 
25
23
  /**
26
24
  * @typedef {import('../_package-scanner.mjs').ScannedPackage} ScannedPackage
27
- * @typedef {import('../_catalog-view.mjs').SearchItem} SearchItem
28
25
  */
29
26
 
30
- const KIND_ORDER = ['package', ...DISCOVER_KINDS];
31
-
32
- /**
33
- * How well an item matches: 0 exact name, 1 name prefix, 2 name substring,
34
- * 3 title, summary, keyword, or description; null for no match.
35
- * @param {SearchItem} item
36
- * @param {string} lower
37
- * @returns {number | null}
38
- */
39
- function rank(item, lower) {
40
- const name = item.name.toLowerCase();
41
- if (name === lower) return 0;
42
- if (name.startsWith(lower)) return 1;
43
- if (name.includes(lower)) return 2;
44
- const text = [
45
- item.title,
46
- item.summary,
47
- item.description,
48
- ...(item.keywords ?? []),
49
- ]
50
- .filter(Boolean)
51
- .join('\n')
52
- .toLowerCase();
53
- return text.includes(lower) ? 3 : null;
54
- }
55
-
56
27
  /**
57
28
  * Search all packages for `query` (a free-text term that never starts with
58
- * `@`). Resolves to a search response when anything matches, even a single
59
- * item or an exact component name, or throws AstryxError (ERR_NOT_FOUND) —
60
- * with fuzzy suggestions when any exist.
29
+ * `@`). Resolves to a single component's docs when unambiguous, a search
30
+ * response when several match, or throws AstryxError (ERR_NOT_FOUND) — with
31
+ * fuzzy suggestions when any exist.
61
32
  *
62
- * @param {ScannedPackage[]} packages installed packages
33
+ * @param {ScannedPackage[]} packages
63
34
  * @param {string} query
64
- * @param {{
65
- * items?: SearchItem[],
66
- * type?: import('../../../authoring/discover/type').DiscoverKind,
67
- * only?: 'installed' | 'available',
68
- * limit?: number,
69
- * }} opts
70
- * @returns {Promise<import('../discover.type.mjs').DiscoverSearchResponse>}
35
+ * @param {{lang?: string | null, zh?: boolean}} opts
36
+ * @returns {Promise<
37
+ * import('../discover.type.mjs').DiscoverDetailDocResponse |
38
+ * import('../discover.type.mjs').DiscoverSearchResponse
39
+ * >}
71
40
  */
72
- export async function search(packages, query, opts) {
73
- const {items = [], type, only, limit} = opts;
41
+ export async function search(packages, query, {lang, zh}) {
74
42
  // An empty query must error, not match every component via `.includes('')`
75
43
  // (parity with the api/search leaf). The discover() dispatcher already routes
76
44
  // an empty query to list, but the leaf must be safe on its own.
@@ -83,64 +51,50 @@ export async function search(packages, query, opts) {
83
51
  }
84
52
  const lower = query.toLowerCase();
85
53
 
86
- /** @type {SearchItem[]} */
87
- const installedComponents = packages.flatMap(pkg =>
88
- pkg.components.map(name => ({
89
- package: pkg.name,
90
- kind: /** @type {const} */ ('component'),
91
- name,
92
- installed: true,
93
- })),
94
- );
54
+ const exact = findComponent(packages, query);
55
+ if (exact) return await docFromResult(exact, {lang, zh});
95
56
 
96
- const ranked = [...installedComponents, ...items]
97
- .filter(item => (type == null ? true : item.kind === type))
98
- .filter(item =>
99
- only === 'installed'
100
- ? item.installed
101
- : only === 'available'
102
- ? !item.installed
103
- : true,
104
- )
105
- .map(item => ({item, score: rank(item, lower)}))
106
- .filter(
107
- /** @returns {m is {item: SearchItem, score: number}} */
108
- m => m.score != null,
109
- )
110
- .sort(
111
- (a, b) =>
112
- a.score - b.score ||
113
- Number(b.item.installed) - Number(a.item.installed) ||
114
- KIND_ORDER.indexOf(a.item.kind) - KIND_ORDER.indexOf(b.item.kind) ||
115
- a.item.package.localeCompare(b.item.package) ||
116
- a.item.name.localeCompare(b.item.name),
117
- );
57
+ const substringMatches =
58
+ /** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
59
+ for (const pkg of packages) {
60
+ for (const comp of pkg.components) {
61
+ if (comp.toLowerCase().includes(lower)) {
62
+ substringMatches.push({pkg, comp});
63
+ }
64
+ }
65
+ }
118
66
 
119
- if (ranked.length > 0) {
120
- const matches = ranked.map(({item}) => ({
121
- package: item.package,
122
- component: item.name,
123
- kind: item.kind,
124
- installed: item.installed,
125
- ...(item.title ? {title: item.title} : {}),
126
- ...(item.summary ? {summary: item.summary} : {}),
127
- }));
128
- const shown = limit == null ? matches : matches.slice(0, limit);
67
+ if (substringMatches.length === 1) {
68
+ const match = substringMatches[0];
69
+ const result = findComponent([match.pkg], match.comp);
70
+ if (result) return await docFromResult(result, {lang, zh});
71
+ }
72
+
73
+ if (substringMatches.length > 1) {
129
74
  return {
130
75
  type: 'discover.search',
131
76
  data: {
132
77
  query,
133
- matches: shown,
134
- ...(shown.length < matches.length ? {total: matches.length} : {}),
78
+ matches: substringMatches.map(m => ({
79
+ package: m.pkg.name,
80
+ component: m.comp,
81
+ })),
135
82
  },
136
83
  };
137
84
  }
138
85
 
139
- // Fuzzy fallback over installed components.
140
- const fuzzyMatches = installedComponents
141
- .map(entry => ({
142
- ...entry,
143
- distance: levenshteinDistance(lower, entry.name.toLowerCase()),
86
+ // Fuzzy fallback
87
+ const allComponents =
88
+ /** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
89
+ for (const pkg of packages) {
90
+ for (const comp of pkg.components) {
91
+ allComponents.push({pkg, comp});
92
+ }
93
+ }
94
+ const fuzzyMatches = allComponents
95
+ .map(item => ({
96
+ ...item,
97
+ distance: levenshteinDistance(lower, item.comp.toLowerCase()),
144
98
  }))
145
99
  .filter(m => m.distance <= 3)
146
100
  .sort((a, b) => a.distance - b.distance)
@@ -150,7 +104,7 @@ export async function search(packages, query, opts) {
150
104
  throw new AstryxError(
151
105
  `"${query}" not found`,
152
106
  fuzzyMatches.map(m => ({
153
- name: m.package + '/' + m.name,
107
+ name: m.pkg.name + '/' + m.comp,
154
108
  reason: 'similar name',
155
109
  })),
156
110
  ERROR_CODES.ERR_NOT_FOUND,
@@ -1,8 +1,8 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file Colocated tests for the discover.search leaf, over a small temp docs
5
- * directory shaped like a scanned package.
4
+ * @file Colocated tests for the discover.search leaf. Exact/single matches load
5
+ * a real `.doc.mjs`, so these drive a small temp docs directory.
6
6
  */
7
7
 
8
8
  import {describe, it, expect, beforeAll, afterAll} from 'vitest';
@@ -47,31 +47,16 @@ afterAll(() => {
47
47
  });
48
48
 
49
49
  describe('discover.search leaf', () => {
50
- it('lists an exact component name first, with every other match', async () => {
50
+ it('an exact component name resolves to its docs', async () => {
51
51
  const res = await search(packages, 'Alpha', {});
52
- expect(res.type).toBe('discover.search');
53
- expect(res.data.matches.map(m => m.component)).toEqual([
54
- 'Alpha',
55
- 'AlphaCard',
56
- ]);
52
+ expect(res.type).toBe('discover.detail.doc');
53
+ expect(res.data.name).toBe('Alpha');
57
54
  });
58
55
 
59
- it('lists a single match too, so the response type never depends on the data', async () => {
56
+ it('a single substring match resolves to its docs', async () => {
60
57
  const res = await search(packages, 'card', {});
61
- expect(res).toEqual({
62
- type: 'discover.search',
63
- data: {
64
- query: 'card',
65
- matches: [
66
- {
67
- package: '@acme/widgets',
68
- component: 'AlphaCard',
69
- kind: 'component',
70
- installed: true,
71
- },
72
- ],
73
- },
74
- });
58
+ expect(res.type).toBe('discover.detail.doc');
59
+ expect(res.data.name).toBe('AlphaCard');
75
60
  });
76
61
 
77
62
  it('multiple substring matches return a search response', async () => {
@@ -81,18 +66,8 @@ describe('discover.search leaf', () => {
81
66
  data: {
82
67
  query: 'alph',
83
68
  matches: [
84
- {
85
- package: '@acme/widgets',
86
- component: 'Alpha',
87
- kind: 'component',
88
- installed: true,
89
- },
90
- {
91
- package: '@acme/widgets',
92
- component: 'AlphaCard',
93
- kind: 'component',
94
- installed: true,
95
- },
69
+ {package: '@acme/widgets', component: 'Alpha'},
70
+ {package: '@acme/widgets', component: 'AlphaCard'},
96
71
  ],
97
72
  },
98
73
  });
@@ -141,112 +116,3 @@ describe('discover.search leaf — empty query (parity with api/search)', () =>
141
116
  });
142
117
  });
143
118
  });
144
-
145
- describe('discover.search leaf across every kind and source', () => {
146
- /** @type {any[]} */
147
- const items = [
148
- {
149
- package: '@acme/widgets',
150
- kind: 'template',
151
- name: 'pages/AlphaHome',
152
- installed: true,
153
- },
154
- {
155
- package: '@acme/charts',
156
- kind: 'package',
157
- name: '@acme/charts',
158
- installed: false,
159
- description: 'Charts for alpha dashboards',
160
- },
161
- {
162
- package: '@acme/charts',
163
- kind: 'component',
164
- name: 'AlphaChart',
165
- installed: false,
166
- },
167
- {
168
- package: '@acme/charts',
169
- kind: 'doc',
170
- name: 'guide',
171
- installed: false,
172
- summary: 'How to chart',
173
- },
174
- ];
175
-
176
- it('ranks every match by how closely its name matches, installed first among equals', async () => {
177
- const res = await search(packages, 'alph', {items});
178
- expect(res.type).toBe('discover.search');
179
- expect(
180
- res.data.matches.map(m => [m.kind, m.component, m.installed]),
181
- ).toEqual([
182
- ['component', 'Alpha', true],
183
- ['component', 'AlphaCard', true],
184
- ['component', 'AlphaChart', false],
185
- ['template', 'pages/AlphaHome', true],
186
- ['package', '@acme/charts', false],
187
- ]);
188
- });
189
-
190
- it('lists an exact installed component name with the matches from every source', async () => {
191
- const res = await search(packages, 'Alpha', {items});
192
- expect(res.type).toBe('discover.search');
193
- expect(res.data.matches[0]).toEqual({
194
- package: '@acme/widgets',
195
- component: 'Alpha',
196
- kind: 'component',
197
- installed: true,
198
- });
199
- expect(res.data.matches.map(m => m.component)).toContain('AlphaChart');
200
- });
201
-
202
- it('lists a single partial component match when other items match too', async () => {
203
- const res = await search(packages, 'card', {
204
- items: [
205
- ...items,
206
- {
207
- package: '@acme/charts',
208
- kind: 'template',
209
- name: 'pages/CardGrid',
210
- installed: false,
211
- },
212
- ],
213
- });
214
- expect(res.type).toBe('discover.search');
215
- expect(res.data.matches.map(m => m.component)).toEqual([
216
- 'AlphaCard',
217
- 'pages/CardGrid',
218
- ]);
219
- });
220
-
221
- it('lists one installed component when nothing else matches', async () => {
222
- const res = await search(packages, 'card', {items});
223
- expect(res.type).toBe('discover.search');
224
- expect(res.data.matches.map(m => m.component)).toEqual(['AlphaCard']);
225
- });
226
-
227
- it('keeps one kind with type, and one side with only', async () => {
228
- const templates = await search(packages, 'alph', {items, type: 'template'});
229
- expect(templates.data.matches.map(m => m.component)).toEqual([
230
- 'pages/AlphaHome',
231
- ]);
232
- const available = await search(packages, 'alph', {
233
- items,
234
- only: 'available',
235
- });
236
- expect(available.data.matches.map(m => m.component)).toEqual([
237
- 'AlphaChart',
238
- '@acme/charts',
239
- ]);
240
- });
241
-
242
- it('caps the list at limit and reports the total', async () => {
243
- const res = await search(packages, 'alph', {items, limit: 2});
244
- expect(res.data.matches).toHaveLength(2);
245
- expect(res.data.total).toBe(5);
246
- });
247
-
248
- it('matches titles, summaries, keywords, and descriptions too', async () => {
249
- const res = await search(packages, 'how to chart', {items});
250
- expect(res.data.matches.map(m => m.component)).toEqual(['guide']);
251
- });
252
- });
@@ -77,12 +77,10 @@ export function docsLinkProblems(catalog: DocsCatalog, tree: DocsTree, { owner,
77
77
  /**
78
78
  * What \`astryx doctor integration docs\` checks in one integration's docs: the
79
79
  * docs tree they build beside the CLI's (namespaces, placements, routes) and
80
- * every link in them (spec:AST-046, spec:AST-047). A tree problem hides a doc,
81
- * so it is an error; a link that names no doc prints as written, so it is a
82
- * warning.
80
+ * every link in them (spec:AST-046, spec:AST-047).
83
81
  * @param {{name: string}} integration
84
82
  * @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[]}} discovered
85
- * @returns {Promise<Array<{severity: 'error' | 'warning', message: string}>>}
83
+ * @returns {Promise<string[]>}
86
84
  */
87
85
  export function packageDocsProblems(integration: {
88
86
  name: string;
@@ -90,10 +88,7 @@ export function packageDocsProblems(integration: {
90
88
  records: import("../../foundation/discovery/docs-discovery.mjs").DocsTopicRecord[];
91
89
  namespaces: import("../../foundation/doc-compiler/tree.mjs").TreeNamespaceInput[];
92
90
  guides: import("../../foundation/doc-compiler/tree.mjs").TreeDocInput[];
93
- }): Promise<Array<{
94
- severity: "error" | "warning";
95
- message: string;
96
- }>>;
91
+ }): Promise<string[]>;
97
92
  /**
98
93
  * How a token reference finds its target: the topic it names in `catalog`,
99
94
  * lowered for the same language.
@@ -667,12 +667,10 @@ export async function docsLinkProblems(
667
667
  /**
668
668
  * What \`astryx doctor integration docs\` checks in one integration's docs: the
669
669
  * docs tree they build beside the CLI's (namespaces, placements, routes) and
670
- * every link in them (spec:AST-046, spec:AST-047). A tree problem hides a doc,
671
- * so it is an error; a link that names no doc prints as written, so it is a
672
- * warning.
670
+ * every link in them (spec:AST-046, spec:AST-047).
673
671
  * @param {{name: string}} integration
674
672
  * @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[]}} discovered
675
- * @returns {Promise<Array<{severity: 'error' | 'warning', message: string}>>}
673
+ * @returns {Promise<string[]>}
676
674
  */
677
675
  export async function packageDocsProblems(integration, discovered) {
678
676
  const catalog = DocsCatalog.fromBuiltins();
@@ -682,18 +680,12 @@ export async function packageDocsProblems(integration, discovered) {
682
680
  guides: discovered.guides.map(input => ({...input, rank: 1})),
683
681
  });
684
682
  const tree = await projectTree(catalog);
685
- /** @type {Array<{severity: 'error' | 'warning', message: string}>} */
686
683
  const problems = tree.diagnostics
687
684
  .filter(d => d.severity === 'error' && d.provider === integration.name)
688
- .map(d => ({
689
- severity: /** @type {const} */ ('error'),
690
- message: `${d.source ?? integration.name}: ${d.message}`,
691
- }));
692
- for (const message of await docsLinkProblems(catalog, tree, {
693
- owner: integration.name,
694
- })) {
695
- problems.push({severity: 'warning', message});
696
- }
685
+ .map(d => `${d.source ?? integration.name}: ${d.message}`);
686
+ problems.push(
687
+ ...(await docsLinkProblems(catalog, tree, {owner: integration.name})),
688
+ );
697
689
  return problems;
698
690
  }
699
691
 
@@ -76,32 +76,6 @@ describe('reference doc overlays (#2182)', () => {
76
76
  ).toEqual([]);
77
77
  });
78
78
 
79
- it(`${topic} --${variant}: every content override lands on a block of its own type`, async () => {
80
- // Blocks are matched by index and type, and a mismatch is dropped with
81
- // no warning: a prose override aimed at a code block leaves the base
82
- // text in place, so the reader gets a translated title over an English
83
- // body. Pad with null to reach the block you mean.
84
- const base = await load(basePath);
85
- const overlayMod = await load(overlayPath);
86
- const overlay = overlayMod.docsDense || overlayMod.docsZh;
87
- const byTitle = new Map(base.docs.sections.map(s => [s.title, s]));
88
- const dropped = [];
89
- for (const entry of overlay.sections || []) {
90
- const section = byTitle.get(entry.section);
91
- if (!section) continue;
92
- (entry.content || []).forEach((block, i) => {
93
- if (block == null) return;
94
- const target = section.content[i];
95
- if (target?.type !== block.type) {
96
- dropped.push(
97
- `${entry.section} block ${i}: ${block.type} over ${target?.type ?? 'nothing'}`,
98
- );
99
- }
100
- });
101
- }
102
- expect(dropped, `${topic}.doc.${variant}.mjs overrides that never apply`).toEqual([]);
103
- });
104
-
105
79
  it(`${topic} --${variant}: no base section is overridden twice`, async () => {
106
80
  const overlayMod = await load(overlayPath);
107
81
  const overlay = overlayMod.docsDense || overlayMod.docsZh;
@@ -153,7 +127,7 @@ describe('the reported defect: docs tokens --dense (#2182)', () => {
153
127
  const zh = await docs('theme', null, {zh: true});
154
128
  const titles = zh.data.sections.map(s => s.title);
155
129
  // Every section the overlay translates must appear once, in Chinese only.
156
- expect(titles).not.toContain('Dark mode');
130
+ expect(titles).not.toContain('Light/Dark Mode');
157
131
  expect(titles).toContain('亮/暗模式');
158
132
  });
159
133
  });
@@ -27,7 +27,7 @@ export const doc = {
27
27
  'A route opens a node of the docs tree instead: a namespace such as ' +
28
28
  "`cli/api` returns its children one level down, a typed doc such as " +
29
29
  "`cli/api/functions/search` returns its content, and a guide the tree " +
30
- 'places (`cli/integrations/quick-start`) reads like any topic. ' +
30
+ 'places (`cli/integrations`) reads like any topic. ' +
31
31
  'Every read but the list carries `links`, the commands that move from it: ' +
32
32
  '`up` to the level it sits in, `previous` and `next` to its neighbors, and, ' +
33
33
  'for a typed doc, `related` to the docs it names (its command or function, ' +
@@ -137,7 +137,7 @@ export const doc = {
137
137
  {label: 'One API function', code: "await docs('cli/api/functions/search');"},
138
138
  {
139
139
  label: 'A whole guide from the docs tree',
140
- code: "await docs('cli/integrations/quick-start');",
140
+ code: "await docs('cli/integrations');",
141
141
  },
142
142
  {label: 'One section by key', code: "await docs('tokens', 'spacing');"},
143
143
  ],