@astryxdesign/cli 0.7.2 → 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 (373) hide show
  1. package/README.md +104 -71
  2. package/api/build/_adapter.d.mts +58 -0
  3. package/api/build/_adapter.mjs +127 -3
  4. package/api/build/blocks/blocks.d.mts +92 -0
  5. package/api/build/blocks/blocks.mjs +528 -0
  6. package/api/build/blocks/blocks.test.mjs +238 -0
  7. package/api/build/blocks/blocks.weights.json +1 -0
  8. package/api/build/build.mjs +25 -6
  9. package/api/build/build.type.mjs +1 -1
  10. package/api/build/kit/answer.d.mts +18 -0
  11. package/api/build/kit/answer.mjs +195 -0
  12. package/api/build/kit/answer.test.mjs +108 -0
  13. package/api/build/kit/kind.d.mts +25 -0
  14. package/api/build/kit/kind.mjs +170 -0
  15. package/api/build/kit/kit.d.mts +2 -4
  16. package/api/build/kit/kit.mjs +8 -398
  17. package/api/build/kit/rank.d.mts +3 -32
  18. package/api/build/kit/rank.mjs +25 -342
  19. package/api/build/kit/rank.test.mjs +2 -1
  20. package/api/build/kit/signals.d.mts +79 -0
  21. package/api/build/kit/signals.mjs +295 -0
  22. package/api/build/kit/start.d.mts +32 -0
  23. package/api/build/kit/start.mjs +163 -0
  24. package/api/build/kit/words.d.mts +72 -0
  25. package/api/build/kit/words.mjs +202 -0
  26. package/api/build/tree.d.mts +20 -0
  27. package/api/build/tree.mjs +53 -0
  28. package/api/build/tree.test.mjs +185 -0
  29. package/api/build/tree.weights.json +1 -0
  30. package/api/component/_adapter.mjs +39 -5
  31. package/api/component/component-replacement.test.mjs +1 -0
  32. package/api/component/component.mjs +17 -3
  33. package/api/component/component.test.mjs +15 -0
  34. package/api/component/doc-links.test.mjs +2 -2
  35. package/api/discover/_adapter.d.mts +1 -2
  36. package/api/discover/_adapter.mjs +42 -17
  37. package/api/discover/_adapter.test.mjs +42 -0
  38. package/api/discover/discover.mjs +0 -1
  39. package/api/docs/_adapter.d.mts +2 -2
  40. package/api/docs/_adapter.mjs +82 -23
  41. package/api/docs/docs-homes.test.mjs +127 -0
  42. package/api/docs/docs.doc.mjs +3 -3
  43. package/api/docs/docs.test.mjs +35 -19
  44. package/api/docs/integration-tree.test.mjs +20 -20
  45. package/api/docs/integrationDocs.test.mjs +1 -1
  46. package/api/docs/namespace-section.test.mjs +6 -6
  47. package/api/docs/reference-blocks.test.mjs +2 -2
  48. package/api/doctor/_adapter.d.mts +33 -13
  49. package/api/doctor/_adapter.mjs +55 -25
  50. package/api/doctor/doctor.d.mts +23 -5
  51. package/api/doctor/doctor.mjs +183 -40
  52. package/api/doctor/doctor.test.mjs +95 -12
  53. package/api/hook/hook.mjs +1 -1
  54. package/api/init/init.doc.mjs +20 -6
  55. package/api/init/init.test.mjs +18 -2
  56. package/api/init/init.type.d.mts +3 -3
  57. package/api/init/init.type.mjs +3 -3
  58. package/api/init/remove/remove.mjs +17 -4
  59. package/api/init/remove/remove.test.mjs +114 -2
  60. package/api/init/run/run.mjs +69 -6
  61. package/api/integration/_adapter.d.mts +8 -0
  62. package/api/integration/_adapter.mjs +21 -1
  63. package/api/integration/authoring-checks.mjs +83 -9
  64. package/api/integration/authoring-checks.test.mjs +220 -0
  65. package/api/integration/pack-check.mjs +123 -4
  66. package/api/integration/pack-check.test.mjs +87 -0
  67. package/api/integration/validate-integration-case-disk.test.mjs +111 -0
  68. package/api/integration/validate-integration-fixes.test.mjs +6 -5
  69. package/api/integration/validate-integration-gaps.test.mjs +1975 -0
  70. package/api/integration/validate-integration.d.mts +15 -2
  71. package/api/integration/validate-integration.mjs +298 -39
  72. package/api/integration/validate-integration.type.d.mts +90 -1
  73. package/api/integration/validate-integration.type.mjs +67 -2
  74. package/api/integration/validateIntegration.doc.mjs +1 -1
  75. package/api/search/ORDERING.md +28 -0
  76. package/api/search/_adapter.d.mts +82 -2
  77. package/api/search/_adapter.mjs +157 -10
  78. package/api/search/_adapter.test.mjs +173 -0
  79. package/api/search/_candidate-score.d.mts +40 -0
  80. package/api/search/_candidate-score.mjs +238 -0
  81. package/api/search/_cards.json +6098 -0
  82. package/api/search/_compound.d.mts +50 -0
  83. package/api/search/_compound.mjs +170 -0
  84. package/api/search/_doc-searcher.d.mts +4 -0
  85. package/api/search/_doc-searcher.mjs +23 -0
  86. package/api/search/_doc-searcher.test.mjs +36 -0
  87. package/api/search/_doc-searcher.weights.json +1 -0
  88. package/api/search/_doc-text.d.mts +30 -0
  89. package/api/search/_doc-text.mjs +87 -0
  90. package/api/search/_entries.d.mts +63 -0
  91. package/api/search/_entries.mjs +232 -0
  92. package/api/search/_entries.test.mjs +48 -0
  93. package/api/search/_features.d.mts +35 -0
  94. package/api/search/_features.mjs +155 -0
  95. package/api/search/_gather-components.d.mts +26 -0
  96. package/api/search/_gather-components.mjs +284 -0
  97. package/api/search/_gather-docs.d.mts +20 -0
  98. package/api/search/_gather-docs.mjs +254 -0
  99. package/api/search/_gather-hooks.d.mts +12 -0
  100. package/api/search/_gather-hooks.mjs +52 -0
  101. package/api/search/_gather-templates.d.mts +25 -0
  102. package/api/search/_gather-templates.mjs +107 -0
  103. package/api/search/_lexical.d.mts +135 -0
  104. package/api/search/_lexical.mjs +351 -0
  105. package/api/search/_main-searcher.d.mts +19 -0
  106. package/api/search/_main-searcher.mjs +115 -0
  107. package/api/search/_main-searcher.test.mjs +106 -0
  108. package/api/search/_main-searcher.weights.json +1 -0
  109. package/api/search/_module-doc.d.mts +32 -0
  110. package/api/search/_module-doc.mjs +78 -0
  111. package/api/search/_order.d.mts +32 -0
  112. package/api/search/_order.mjs +162 -0
  113. package/api/search/_order.test.mjs +72 -0
  114. package/api/search/_priority.d.mts +50 -0
  115. package/api/search/_priority.mjs +139 -0
  116. package/api/search/_query-words.d.mts +25 -0
  117. package/api/search/_query-words.mjs +92 -0
  118. package/api/search/_query.d.mts +65 -0
  119. package/api/search/_query.mjs +176 -0
  120. package/api/search/_result.d.mts +97 -0
  121. package/api/search/_result.mjs +150 -0
  122. package/api/search/_score.d.mts +60 -0
  123. package/api/search/_score.mjs +283 -0
  124. package/api/search/_synonyms.d.mts +21 -0
  125. package/api/search/_synonyms.mjs +67 -0
  126. package/api/search/_template-searcher.d.mts +4 -0
  127. package/api/search/_template-searcher.mjs +23 -0
  128. package/api/search/_template-searcher.test.mjs +40 -0
  129. package/api/search/_template-searcher.weights.json +1 -0
  130. package/api/search/_titles.d.mts +33 -0
  131. package/api/search/_titles.mjs +65 -0
  132. package/api/search/_words.d.mts +64 -0
  133. package/api/search/_words.mjs +157 -0
  134. package/api/search/search.d.mts +22 -305
  135. package/api/search/search.doc.mjs +8 -6
  136. package/api/search/search.mjs +56 -2482
  137. package/api/search/search.test.mjs +14 -14
  138. package/api/search/search.type.d.mts +6 -1
  139. package/api/search/search.type.mjs +6 -1
  140. package/api/search/tree.d.mts +15 -0
  141. package/api/search/tree.mjs +40 -0
  142. package/api/search/tree.test.mjs +66 -0
  143. package/api/search/tree.weights.json +1 -0
  144. package/api/template/template.mjs +5 -1
  145. package/api/theme/build/build.packed-old-core.test.mjs +1 -0
  146. package/api/upgrade/_adapter.d.mts +57 -9
  147. package/api/upgrade/_adapter.mjs +198 -28
  148. package/api/upgrade/registry/registry.d.mts +10 -4
  149. package/api/upgrade/registry/registry.mjs +33 -16
  150. package/api/upgrade/registry/registry.test.mjs +85 -0
  151. package/api/upgrade/run/run.d.mts +4 -2
  152. package/api/upgrade/run/run.mjs +13 -2
  153. package/api/upgrade/run/run.test.mjs +417 -3
  154. package/api/upgrade/upgrade.doc.mjs +10 -5
  155. package/api/upgrade/upgrade.mjs +13 -2
  156. package/api/upgrade/upgrade.test.mjs +194 -0
  157. package/api/upgrade/upgrade.type.d.mts +5 -3
  158. package/api/upgrade/upgrade.type.mjs +8 -6
  159. package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
  160. package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
  161. package/assets/docs/author-a-theme.doc.mjs +2 -2
  162. package/assets/docs/is-my-code-good.doc.mjs +287 -0
  163. package/assets/docs/tree/add-a-component.doc.mjs +1 -1
  164. package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
  165. package/assets/docs/tree/add-a-topic.doc.mjs +2 -2
  166. package/assets/docs/tree/agent-guidance.doc.mjs +1 -1
  167. package/assets/docs/tree/api.doc.mjs +6 -0
  168. package/assets/docs/tree/{integrations.doc.mjs → authoring.doc.mjs} +15 -6
  169. package/assets/docs/tree/block-template.doc.mjs +1 -1
  170. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  171. package/assets/docs/tree/building-blocks.doc.mjs +2 -2
  172. package/assets/docs/tree/check-the-props.doc.mjs +1 -1
  173. package/assets/docs/tree/check-your-docs.doc.mjs +2 -2
  174. package/assets/docs/tree/checks.doc.mjs +3 -3
  175. package/assets/docs/tree/ci-and-containers.doc.mjs +13 -0
  176. package/assets/docs/tree/cli-command.doc.mjs +1 -1
  177. package/assets/docs/tree/cli.doc.mjs +1 -1
  178. package/assets/docs/tree/codemods.doc.mjs +1 -1
  179. package/assets/docs/tree/component-family.doc.mjs +1 -1
  180. package/assets/docs/tree/component-imports.doc.mjs +1 -1
  181. package/assets/docs/tree/components.doc.mjs +1 -1
  182. package/assets/docs/tree/configuration.doc.mjs +1 -1
  183. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +1 -1
  184. package/assets/docs/tree/define-the-theme.doc.mjs +1 -1
  185. package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
  186. package/assets/docs/tree/docs.doc.mjs +1 -1
  187. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  188. package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
  189. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  190. package/assets/docs/tree/extend-or-replace.doc.mjs +1 -1
  191. package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
  192. package/assets/docs/tree/fonts-and-assets.doc.mjs +1 -1
  193. package/assets/docs/tree/generate-a-palette.doc.mjs +1 -1
  194. package/assets/docs/tree/global-integrations.doc.mjs +2 -2
  195. package/assets/docs/tree/grade-template-with-agent.doc.mjs +4 -4
  196. package/assets/docs/tree/help.doc.mjs +2 -2
  197. package/assets/docs/tree/host-entry.doc.mjs +128 -0
  198. package/assets/docs/tree/links.doc.mjs +1 -1
  199. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  200. package/assets/docs/tree/page-template.doc.mjs +1 -1
  201. package/assets/docs/tree/publishing.doc.mjs +1 -1
  202. package/assets/docs/tree/quick-start.doc.mjs +1 -1
  203. package/assets/docs/tree/replace-a-core-component.doc.mjs +1 -1
  204. package/assets/docs/tree/replace-a-core-template.doc.mjs +1 -1
  205. package/assets/docs/tree/sections-and-placement.doc.mjs +1 -1
  206. package/assets/docs/tree/see-it-in-an-app.doc.mjs +1 -1
  207. package/assets/docs/tree/ship.doc.mjs +2 -2
  208. package/assets/docs/tree/short-and-findable.doc.mjs +1 -1
  209. package/assets/docs/tree/single-component.doc.mjs +1 -1
  210. package/assets/docs/tree/start-a-template.doc.mjs +1 -1
  211. package/assets/docs/tree/subcomponent.doc.mjs +1 -1
  212. package/assets/docs/tree/template-assets.doc.mjs +1 -1
  213. package/assets/docs/tree/template-doc-overview.doc.mjs +2 -2
  214. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  215. package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
  216. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  217. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  218. package/assets/docs/tree/template-styles.doc.mjs +1 -1
  219. package/assets/docs/tree/templates.doc.mjs +1 -1
  220. package/assets/docs/tree/test-in-an-app.doc.mjs +1 -1
  221. package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
  222. package/assets/docs/tree/themes.doc.mjs +1 -1
  223. package/assets/docs/tree/tokens-data.doc.mjs +2 -2
  224. package/assets/docs/tree/troubleshooting.doc.mjs +1 -1
  225. package/assets/docs/tree/upgrading.doc.mjs +1 -1
  226. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +1 -1
  227. package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
  228. package/assets/docs/tree/versioning.doc.mjs +5 -1
  229. package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
  230. package/assets/docs/tree/write-the-template-file.doc.mjs +1 -1
  231. package/assets/docs/use-integrations.doc.mjs +120 -0
  232. package/assets/docs/working-with-ai.doc.mjs +6 -2
  233. package/assets/templates/themes/butter/butterTheme.ts +4 -2
  234. package/assets/templates/themes/stone/stoneTheme.ts +4 -2
  235. package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
  236. package/authoring/debug/parse.d.mts +1 -1
  237. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  238. package/authoring/integration/integration.doc.mjs +1 -1
  239. package/authoring/integration/type.ts +1 -1
  240. package/clients/cli/bin/astryx.mjs +7 -78
  241. package/clients/cli/command-result-coverage.test.mjs +6 -5
  242. package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
  243. package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
  244. package/clients/cli/commands/component.test.mjs +6 -6
  245. package/clients/cli/commands/docs.doc.mjs +2 -2
  246. package/clients/cli/commands/docs.mjs +1 -1
  247. package/clients/cli/commands/docs.test.mjs +14 -14
  248. package/clients/cli/commands/doctor-integration.test.mjs +49 -1
  249. package/clients/cli/commands/doctor.doc.mjs +1 -1
  250. package/clients/cli/commands/doctor.mjs +40 -0
  251. package/clients/cli/commands/doctor.test.mjs +65 -0
  252. package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
  253. package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
  254. package/clients/cli/commands/init.behavior.test.mjs +230 -1
  255. package/clients/cli/commands/init.doc.mjs +28 -9
  256. package/clients/cli/commands/init.flag-help.test.mjs +1 -0
  257. package/clients/cli/commands/init.mjs +2 -2
  258. package/clients/cli/commands/integration-check.test.mjs +48 -0
  259. package/clients/cli/commands/integration.doc.mjs +1 -1
  260. package/clients/cli/commands/manifest.doc.mjs +1 -1
  261. package/clients/cli/commands/manifest.mjs +67 -0
  262. package/clients/cli/commands/outside-project.test.mjs +101 -1
  263. package/clients/cli/commands/postinstall.doc.mjs +23 -0
  264. package/clients/cli/commands/postinstall.mjs +31 -0
  265. package/clients/cli/commands/setup-nudge.test.mjs +78 -0
  266. package/clients/cli/commands/{build-theme.mjs → theme.mjs} +1 -1
  267. package/clients/cli/commands/upgrade.doc.mjs +4 -2
  268. package/clients/cli/commands/upgrade.mjs +9 -2
  269. package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
  270. package/clients/cli/index.mjs +54 -94
  271. package/clients/cli/lib/component-format.mjs +1 -1
  272. package/clients/cli/lib/define-command.mjs +12 -7
  273. package/clients/cli/lib/exit-codes.test.mjs +5 -0
  274. package/clients/cli/lib/manifest.test.mjs +12 -0
  275. package/clients/cli/lib/welcome-box.mjs +50 -0
  276. package/clients/cli/run.mjs +108 -0
  277. package/foundation/agent-docs/agent-doc-state.d.mts +32 -7
  278. package/foundation/agent-docs/agent-doc-state.mjs +58 -9
  279. package/foundation/agent-docs/agent-docs.d.mts +100 -12
  280. package/foundation/agent-docs/agent-docs.mjs +1017 -105
  281. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
  282. package/foundation/agent-docs/agent-docs.test.mjs +683 -39
  283. package/foundation/agent-docs/computer-agent-text.d.mts +39 -2
  284. package/foundation/agent-docs/computer-agent-text.mjs +135 -8
  285. package/foundation/agent-docs/computer-agent-text.test.mjs +99 -2
  286. package/foundation/config/project.mjs +20 -22
  287. package/foundation/config/project.test.mjs +56 -0
  288. package/foundation/discovery/authoring-self-docs.d.mts +7 -0
  289. package/foundation/discovery/authoring-self-docs.mjs +16 -4
  290. package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
  291. package/foundation/discovery/authoring-surface.d.mts +1 -1
  292. package/foundation/discovery/authoring-surface.mjs +2 -2
  293. package/foundation/discovery/authoring-surface.test.mjs +1 -1
  294. package/foundation/discovery/cli-self-docs.d.mts +2 -1
  295. package/foundation/discovery/cli-self-docs.mjs +4 -3
  296. package/foundation/discovery/cli-self-docs.test.mjs +2 -2
  297. package/foundation/discovery/component-discovery.d.mts +37 -0
  298. package/foundation/discovery/component-discovery.mjs +80 -5
  299. package/foundation/discovery/component-loader.d.mts +1 -1
  300. package/foundation/discovery/docs-discovery.mjs +14 -1
  301. package/foundation/discovery/module-exports.d.mts +41 -0
  302. package/foundation/discovery/module-exports.mjs +253 -0
  303. package/foundation/discovery/runner-allowlist.d.mts +2 -4
  304. package/foundation/discovery/runner-allowlist.mjs +2 -4
  305. package/foundation/discovery/runner-commands.d.mts +77 -0
  306. package/foundation/discovery/runner-commands.mjs +294 -0
  307. package/foundation/discovery/runner-commands.test.mjs +128 -0
  308. package/foundation/discovery/stray-pointers.test.mjs +1 -1
  309. package/foundation/discovery/template-adapter.mjs +18 -1
  310. package/foundation/discovery/template-needs.mjs +1 -44
  311. package/foundation/discovery/theme-discovery.mjs +147 -3
  312. package/foundation/doc-compiler/doc-loads.test.mjs +33 -9
  313. package/foundation/doc-compiler/read.mjs +59 -1
  314. package/foundation/doc-compiler/read.test.mjs +11 -2
  315. package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
  316. package/foundation/doc-compiler/tree.d.mts +32 -6
  317. package/foundation/doc-compiler/tree.mjs +77 -43
  318. package/foundation/doc-compiler/tree.test.mjs +7 -7
  319. package/foundation/fs/paths.d.mts +70 -8
  320. package/foundation/fs/paths.mjs +556 -38
  321. package/foundation/fs/paths.test.mjs +430 -54
  322. package/foundation/fs/read-record.d.mts +18 -0
  323. package/foundation/fs/read-record.mjs +131 -0
  324. package/foundation/fs/read-record.test.mjs +77 -0
  325. package/foundation/integrations/autolink.d.mts +2 -1
  326. package/foundation/integrations/autolink.mjs +4 -13
  327. package/foundation/integrations/cli-peer-version.d.mts +36 -0
  328. package/foundation/integrations/cli-peer-version.mjs +132 -0
  329. package/foundation/integrations/cli-peer-version.test.mjs +354 -0
  330. package/foundation/integrations/computer-integrations.d.mts +6 -3
  331. package/foundation/integrations/computer-integrations.mjs +38 -9
  332. package/foundation/integrations/contribution-inventory.d.mts +15 -20
  333. package/foundation/integrations/contribution-inventory.mjs +41 -5
  334. package/foundation/integrations/exports-subpaths.d.mts +57 -0
  335. package/foundation/integrations/exports-subpaths.mjs +113 -0
  336. package/foundation/integrations/integrations.d.mts +27 -1
  337. package/foundation/integrations/integrations.mjs +61 -2
  338. package/foundation/integrations/public-imports.d.mts +118 -0
  339. package/foundation/integrations/public-imports.mjs +1769 -0
  340. package/foundation/integrations/public-imports.test.mjs +1793 -0
  341. package/foundation/integrations/validate-contributions.d.mts +115 -0
  342. package/foundation/integrations/validate-contributions.mjs +1168 -13
  343. package/foundation/release/cache.test.mjs +24 -21
  344. package/foundation/release/global-state.d.mts +8 -4
  345. package/foundation/release/global-state.mjs +4 -2
  346. package/foundation/release/handoff.d.mts +23 -4
  347. package/foundation/release/handoff.mjs +175 -8
  348. package/foundation/release/notices.d.mts +62 -8
  349. package/foundation/release/notices.mjs +136 -25
  350. package/foundation/release/notices.test.mjs +21 -0
  351. package/foundation/release/run-context.mjs +14 -0
  352. package/foundation/response/response-types.doc.mjs +1 -1
  353. package/foundation/route/route.d.mts +285 -0
  354. package/foundation/route/route.mjs +324 -0
  355. package/foundation/route/route.test.mjs +153 -0
  356. package/foundation/runtime/hosted-runtime.test.mjs +403 -0
  357. package/foundation/runtime/locked-versions.d.mts +32 -0
  358. package/foundation/runtime/locked-versions.mjs +65 -0
  359. package/foundation/runtime/package-root.d.mts +91 -0
  360. package/foundation/runtime/package-root.mjs +174 -0
  361. package/foundation/runtime/package-set.d.mts +62 -0
  362. package/foundation/runtime/package-set.mjs +130 -0
  363. package/foundation/runtime/package-set.test.mjs +432 -0
  364. package/foundation/text/string-utils.d.mts +2 -1
  365. package/foundation/text/string-utils.mjs +16 -5
  366. package/foundation/text/suggest-order.d.mts +72 -0
  367. package/foundation/text/suggest-order.mjs +363 -0
  368. package/foundation/text/suggest-order.test.mjs +259 -0
  369. package/host/door-conformance.test.mjs +274 -0
  370. package/host/index.d.ts +116 -0
  371. package/host/index.mjs +295 -0
  372. package/host/index.test.mjs +302 -0
  373. package/package.json +14 -9
@@ -0,0 +1,33 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * The first title or heading that holds every word of the query, in order and
6
+ * side by side, or null.
7
+ * @param {string} term - Lowercased full query.
8
+ * @param {string[] | undefined} titles
9
+ * @returns {string | null}
10
+ */
11
+ export function headingWithPhrase(term: string, titles: string[] | undefined): string | null;
12
+ /**
13
+ * The first title or heading of two words or more that the query holds whole,
14
+ * in order and side by side, or null. A question such as "how do I add dark
15
+ * mode" names the "Dark mode" section outright, around words no title has.
16
+ * @param {string} term - Lowercased full query.
17
+ * @param {string[] | undefined} titles
18
+ * @returns {string | null}
19
+ */
20
+ export function titleInQuery(term: string, titles: string[] | undefined): string | null;
21
+ /**
22
+ * The score of a whole-query phrase inside a doc's title or heading: a keyword
23
+ * substring hit (70) promoted by the same 100 as the exact tier. Below an
24
+ * exact name or keyword (190-200), above the token-sum path (~151 at most).
25
+ */
26
+ export const TITLE_PHRASE_SCORE: 170;
27
+ /**
28
+ * The score of a whole title inside a longer query, before its coverage bonus:
29
+ * one step below {@link TITLE_PHRASE_SCORE}. The bonus (one per query term the
30
+ * candidate matches, at most 9) orders the sections that share a common title,
31
+ * so "best practices for spacing" puts Spacing's Best Practices first.
32
+ */
33
+ export const TITLE_IN_QUERY_SCORE: 160;
@@ -0,0 +1,65 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The title tier of a multi-word query: the whole query as a phrase in
5
+ * a doc's title or heading, or a whole title inside the query.
6
+ */
7
+
8
+ import {phraseWords, samePhraseWord} from './_query.mjs';
9
+
10
+ /**
11
+ * The score of a whole-query phrase inside a doc's title or heading: a keyword
12
+ * substring hit (70) promoted by the same 100 as the exact tier. Below an
13
+ * exact name or keyword (190-200), above the token-sum path (~151 at most).
14
+ */
15
+ export const TITLE_PHRASE_SCORE = 170;
16
+
17
+ /**
18
+ * The score of a whole title inside a longer query, before its coverage bonus:
19
+ * one step below {@link TITLE_PHRASE_SCORE}. The bonus (one per query term the
20
+ * candidate matches, at most 9) orders the sections that share a common title,
21
+ * so "best practices for spacing" puts Spacing's Best Practices first.
22
+ */
23
+ export const TITLE_IN_QUERY_SCORE = 160;
24
+
25
+ /**
26
+ * The first title or heading that holds every word of the query, in order and
27
+ * side by side, or null.
28
+ * @param {string} term - Lowercased full query.
29
+ * @param {string[] | undefined} titles
30
+ * @returns {string | null}
31
+ */
32
+ export function headingWithPhrase(term, titles) {
33
+ const query = phraseWords(term);
34
+ if (query.length < 2 || !titles) return null;
35
+ for (const title of titles) {
36
+ const words = phraseWords(String(title ?? ''));
37
+ for (let i = 0; i + query.length <= words.length; i++) {
38
+ if (query.every((word, j) => samePhraseWord(words[i + j], word)))
39
+ return title;
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+
45
+ /**
46
+ * The first title or heading of two words or more that the query holds whole,
47
+ * in order and side by side, or null. A question such as "how do I add dark
48
+ * mode" names the "Dark mode" section outright, around words no title has.
49
+ * @param {string} term - Lowercased full query.
50
+ * @param {string[] | undefined} titles
51
+ * @returns {string | null}
52
+ */
53
+ export function titleInQuery(term, titles) {
54
+ const query = phraseWords(term);
55
+ if (!titles) return null;
56
+ for (const title of titles) {
57
+ const words = phraseWords(String(title ?? ''));
58
+ if (words.length < 2 || words.length > query.length) continue;
59
+ for (let i = 0; i + words.length <= query.length; i++) {
60
+ if (words.every((word, j) => samePhraseWord(query[i + j], word)))
61
+ return title;
62
+ }
63
+ }
64
+ return null;
65
+ }
@@ -0,0 +1,64 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * @file Word matching for search: stems and word forms, word starts,
6
+ * identifier spelling, joined names, and typo tolerance.
7
+ */
8
+ /**
9
+ * Light stemmer: strips common English suffixes so "charts"/"charting" and
10
+ * "chart" share a root. Deliberately crude (no Porter) — good enough to bridge
11
+ * plural/gerund gaps without a dependency.
12
+ * @param {string} w
13
+ * @returns {string}
14
+ */
15
+ export function stem(w: string): string;
16
+ /**
17
+ * The forms of a word that count as the same word: itself, its stem, and its
18
+ * singular when it ends in a plural suffix — so "tables" is "table",
19
+ * "statuses" is "status", and "filtering" is "filter".
20
+ * @param {string} w - Lowercase word.
21
+ * @returns {Set<string>}
22
+ */
23
+ export function wordForms(w: string): Set<string>;
24
+ /**
25
+ * Whether two lowercase words are the same word, up to plural and stem form.
26
+ * @param {string} a
27
+ * @param {string} b
28
+ * @returns {boolean}
29
+ */
30
+ export function sameWord(a: string, b: string): boolean;
31
+ /**
32
+ * The lowercase words of a name or keyword: split at non-alphanumerics and at
33
+ * camelCase boundaries, so "TextInput" is ["text", "input"] and
34
+ * "Dashboard - Analytics" is ["dashboard", "analytics"].
35
+ * @param {string} text
36
+ * @returns {string[]}
37
+ */
38
+ export function wordsOf(text: string): string[];
39
+ /**
40
+ * Whether a term is found inside a name or keyword: it is one of its words, or
41
+ * the start of one (a truncation), and covers at least half of the whole
42
+ * string. Four letters minimum, so a short term never matches by accident.
43
+ * @param {string} term - Lowercase term.
44
+ * @param {string} text - The name or keyword as authored.
45
+ * @returns {boolean}
46
+ */
47
+ export function startsAWordOf(term: string, text: string): boolean;
48
+ /**
49
+ * A query with its camelCase and PascalCase identifiers spelled as words, so
50
+ * `SidebarToggle` reads "sidebar toggle" and `useTablePaginationState` "use
51
+ * table pagination state". Plain words, and identifiers joined with `_` or `-`, are
52
+ * unchanged: a joined token that matches nothing stays unmatched.
53
+ * @param {string} query - The query as typed, before lowercasing.
54
+ * @returns {string} Lowercased.
55
+ */
56
+ export function spellIdentifiers(query: string): string;
57
+ /**
58
+ * A name or keyword with its separators removed, lowercased: `Side Nav`,
59
+ * `side-nav`, and `SideNav` all join to `sidenav`.
60
+ * @param {string} text
61
+ * @returns {string}
62
+ */
63
+ export function joined(text: string): string;
64
+ export function isTypo(a: string, b: string, dist: number): boolean;
@@ -0,0 +1,157 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Word matching for search: stems and word forms, word starts,
5
+ * identifier spelling, joined names, and typo tolerance.
6
+ */
7
+
8
+ /**
9
+ * Light stemmer: strips common English suffixes so "charts"/"charting" and
10
+ * "chart" share a root. Deliberately crude (no Porter) — good enough to bridge
11
+ * plural/gerund gaps without a dependency.
12
+ * @param {string} w
13
+ * @returns {string}
14
+ */
15
+ export function stem(w) {
16
+ let s = w;
17
+ for (const suf of ['ing', 'ed', 'ies', 'es', 's']) {
18
+ if (s.length > suf.length + 2 && s.endsWith(suf)) {
19
+ s = suf === 'ies' ? s.slice(0, -3) + 'y' : s.slice(0, -suf.length);
20
+ break;
21
+ }
22
+ }
23
+ return s;
24
+ }
25
+
26
+ /**
27
+ * The forms of a word that count as the same word: itself, its stem, and its
28
+ * singular when it ends in a plural suffix — so "tables" is "table",
29
+ * "statuses" is "status", and "filtering" is "filter".
30
+ * @param {string} w - Lowercase word.
31
+ * @returns {Set<string>}
32
+ */
33
+ export function wordForms(w) {
34
+ const forms = new Set([w, stem(w)]);
35
+ if (w.length > 3 && w.endsWith('s')) forms.add(w.slice(0, -1));
36
+ if (w.length > 4 && w.endsWith('es')) forms.add(w.slice(0, -2));
37
+ if (w.length > 4 && w.endsWith('ies')) forms.add(w.slice(0, -3) + 'y');
38
+ // A gerund keeps its verb: "spacing" lost a final e ("space"), and
39
+ // "dragging" doubled a consonant ("drag"). A past participle does not: it
40
+ // usually describes a state ("archived notes"), not the action a catalog
41
+ // word names.
42
+ if (w.length >= 6 && w.endsWith('ing')) {
43
+ const base = w.slice(0, -3);
44
+ forms.add(base);
45
+ forms.add(`${base}e`);
46
+ if (/([b-df-hj-np-tv-z])\1$/.test(base)) forms.add(base.slice(0, -1));
47
+ }
48
+ return forms;
49
+ }
50
+
51
+ /**
52
+ * The singulars a lowercase word may have when it ends in a plural suffix:
53
+ * "tokens" is "token", "boxes" is "box", "entries" is "entry".
54
+ * @param {string} w
55
+ * @returns {string[]}
56
+ */
57
+ function singulars(w) {
58
+ /** @type {string[]} */
59
+ const out = [];
60
+ if (w.length > 3 && w.endsWith('s')) out.push(w.slice(0, -1));
61
+ if (w.length > 4 && w.endsWith('es')) out.push(w.slice(0, -2));
62
+ if (w.length > 4 && w.endsWith('ies')) out.push(w.slice(0, -3) + 'y');
63
+ return out;
64
+ }
65
+
66
+ /**
67
+ * Whether two lowercase words are the same word, up to plural and stem form.
68
+ * @param {string} a
69
+ * @param {string} b
70
+ * @returns {boolean}
71
+ */
72
+ export function sameWord(a, b) {
73
+ if (a === b) return true;
74
+ const forms = wordForms(a);
75
+ for (const f of wordForms(b)) if (forms.has(f)) return true;
76
+ return false;
77
+ }
78
+
79
+ /**
80
+ * The lowercase words of a name or keyword: split at non-alphanumerics and at
81
+ * camelCase boundaries, so "TextInput" is ["text", "input"] and
82
+ * "Dashboard - Analytics" is ["dashboard", "analytics"].
83
+ * @param {string} text
84
+ * @returns {string[]}
85
+ */
86
+ export function wordsOf(text) {
87
+ return String(text)
88
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
89
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
90
+ .toLowerCase()
91
+ .split(/[^a-z0-9]+/)
92
+ .filter(Boolean);
93
+ }
94
+
95
+ /**
96
+ * Whether a term is found inside a name or keyword: it is one of its words, or
97
+ * the start of one (a truncation), and covers at least half of the whole
98
+ * string. Four letters minimum, so a short term never matches by accident.
99
+ * @param {string} term - Lowercase term.
100
+ * @param {string} text - The name or keyword as authored.
101
+ * @returns {boolean}
102
+ */
103
+ export function startsAWordOf(term, text) {
104
+ if (term.length < 4) return false;
105
+ if (term.length / String(text).length < 0.5) return false;
106
+ // The term or its singular may start the word: "tokens" starts
107
+ // "tokenizer" through "token". A singular needs five letters, so "stats"
108
+ // does not start "status".
109
+ const starts = [term, ...singulars(term).filter(f => f.length >= 5)];
110
+ return wordsOf(text).some(
111
+ w => starts.some(f => w.startsWith(f)) || sameWord(term, w),
112
+ );
113
+ }
114
+
115
+ /**
116
+ * A query with its camelCase and PascalCase identifiers spelled as words, so
117
+ * `SidebarToggle` reads "sidebar toggle" and `useTablePaginationState` "use
118
+ * table pagination state". Plain words, and identifiers joined with `_` or `-`, are
119
+ * unchanged: a joined token that matches nothing stays unmatched.
120
+ * @param {string} query - The query as typed, before lowercasing.
121
+ * @returns {string} Lowercased.
122
+ */
123
+ export function spellIdentifiers(query) {
124
+ return String(query)
125
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
126
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
127
+ .toLowerCase();
128
+ }
129
+
130
+ /**
131
+ * A name or keyword with its separators removed, lowercased: `Side Nav`,
132
+ * `side-nav`, and `SideNav` all join to `sidenav`.
133
+ * @param {string} text
134
+ * @returns {string}
135
+ */
136
+ export function joined(text) {
137
+ return String(text)
138
+ .toLowerCase()
139
+ .replace(/[^a-z0-9]+/g, '');
140
+ }
141
+
142
+ /**
143
+ * The fewest letters both words need before an edit distance counts as a
144
+ * typo, by distance. Below them, one edit usually makes a different word.
145
+ */
146
+ const TYPO_MIN_LENGTH = {1: 5, 2: 8, 3: 11};
147
+
148
+ /**
149
+ * @param {string} a
150
+ * @param {string} b
151
+ * @param {number} dist
152
+ */
153
+ export const isTypo = (a, b, dist) =>
154
+ dist > 0 &&
155
+ dist <= 3 &&
156
+ Math.min(a.length, b.length) >=
157
+ TYPO_MIN_LENGTH[/** @type {1 | 2 | 3} */ (dist)];
@@ -1,219 +1,6 @@
1
1
  // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
- /**
5
- * Light stemmer: strips common English suffixes so "charts"/"charting" and
6
- * "chart" share a root. Deliberately crude (no Porter) — good enough to bridge
7
- * plural/gerund gaps without a dependency.
8
- * @param {string} w
9
- * @returns {string}
10
- */
11
- export function stem(w: string): string;
12
- /**
13
- * Whether two lowercase words are the same word, up to plural and stem form.
14
- * @param {string} a
15
- * @param {string} b
16
- * @returns {boolean}
17
- */
18
- export function sameWord(a: string, b: string): boolean;
19
- /**
20
- * A query with its camelCase and PascalCase identifiers spelled as words, so
21
- * `SidebarToggle` reads "sidebar toggle" and `useTablePaginationState` "use
22
- * table pagination state". Plain words, and identifiers joined with `_` or `-`, are
23
- * unchanged: a joined token that matches nothing stays unmatched.
24
- * @param {string} query - The query as typed, before lowercasing.
25
- * @returns {string} Lowercased.
26
- */
27
- export function spellIdentifiers(query: string): string;
28
- /**
29
- * The strongest hit a run of two or more adjacent query words has when it is
30
- * read as one joined word, and the query words it covers. Readers type a
31
- * compound name as separate words (`table header cell` is TableHeaderCell,
32
- * `number field` the keyword `numberfield`), and no single word of the run
33
- * matches on its own.
34
- *
35
- * - 100: the run joins to a component, hook, or template name, or its plural
36
- * (`table header cells` is TableHeaderCell), or a hook name without its
37
- * `use` prefix (`table sticky columns` is useTableStickyColumns).
38
- * - 90: the run joins to a one-word keyword (`number field` is
39
- * `numberfield`).
40
- * - 95: the run joins to most of a name, cut short (`dropdown menu radio` is
41
- * DropdownMenuRadioItem); 92: it is a name's leading words, covering at least half
42
- * of it (`top nav mega` is TopNavMegaMenu); 70: it is two or more adjacent
43
- * words of a name that cover at least half of it (`header cell` in
44
- * TableHeaderCell), the same coverage a word prefix needs. These three
45
- * are for components and hooks only.
46
- *
47
- * A doc's name is a route or key, so docs are left out.
48
- * @param {string[]} words - The query's words, stopwords included.
49
- * @param {Candidate} candidate
50
- * @returns {{score: number, reason: string, covered: Set<string>, alias?: 'partial' | 'keyword', aliasWords?: number} | null}
51
- * `covered` holds the run's words and every stretch of them joined. `alias`
52
- * marks a hit on part of a name or on a keyword, not on the whole name.
53
- */
54
- export function compoundHit(words: string[], candidate: Candidate): {
55
- score: number;
56
- reason: string;
57
- covered: Set<string>;
58
- alias?: "partial" | "keyword";
59
- aliasWords?: number;
60
- } | null;
61
- /**
62
- * Split a query into meaningful content tokens (lowercased, stopwords + very
63
- * short words removed). Empty for single-word queries (callers fall back to
64
- * whole-phrase scoring).
65
- * @param {string} term - Already-lowercased query.
66
- * @returns {string[]}
67
- */
68
- export function tokenizeQuery(term: string): string[];
69
- /**
70
- * A match's domain priority: 0 (none), 1, or 2 (a doc the whole query names).
71
- * A component, hook, template, or theme with priority ranks ahead of any doc
72
- * without it, whatever the two scores are. Docs among themselves rank by
73
- * priority, then score; everything else ranks among itself by score.
74
- *
75
- * A component, hook, template, or theme has priority (1) when one of the
76
- * query's words, or the whole query, hits its name or an authored keyword at
77
- * {@link STRONG_TOKEN_SCORE} or above, or when it matches every word.
78
- *
79
- * A doc has priority when the reader asked for that doc:
80
- * - 2: the whole query is the topic's name, its last route segment, or its
81
- * own title, as words and whatever the plural (`font setup` is
82
- * typography/font-setup, `side panel` is "Side panels");
83
- * - 1: a word of the query is the topic's name (`illustration` in a longer
84
- * question is the illustrations guide);
85
- * - 1: a query of two or more words is one of the topic's own declared
86
- * keywords, whatever the plural (`code review` on a guide that declares it);
87
- * - 1: the query holds one of the doc's titles whole (`resizable side panels`
88
- * names "Side panels"; `light dark mode button` names "Light/Dark Mode");
89
- * - 1: the doc matches every word of the query and one of them is a word of
90
- * its title (`switch to a dark theme` and "Use a theme").
91
- * A section answers to its topic's name.
92
- *
93
- * A doc that matched only by a heading holding the query, by one word, or by
94
- * words spread through its text has no priority. Docs are split into many
95
- * small topics, each with its own headings, so a common phrase such as
96
- * `font size` hits a heading exactly (170) while the component the reader is
97
- * after matches one word by keyword (`Text`, 98). Ranked on text alone, every
98
- * split adds another doc above the component. Broad reference pages match every word of many queries
99
- * in their text the same way. The score stays the text-match strength the
100
- * result reports, so callers that gate on it (`build`) see the same numbers.
101
- *
102
- * @param {string} term - Lowercased search term.
103
- * @param {string[]} tokens - Content tokens from tokenizeQuery(term).
104
- * @param {Candidate} candidate
105
- * @param {{score: number, matched: number, total: number}} hit - The
106
- * candidate's scoreQuery result.
107
- * @returns {0 | 1 | 2}
108
- */
109
- export function domainPriority(term: string, tokens: string[], candidate: Candidate, hit: {
110
- score: number;
111
- matched: number;
112
- total: number;
113
- }, queryWords?: string[]): 0 | 1 | 2;
114
- /**
115
- * The first title or heading that holds every word of the query, in order and
116
- * side by side, or null.
117
- * @param {string} term - Lowercased full query.
118
- * @param {string[] | undefined} titles
119
- * @returns {string | null}
120
- */
121
- export function headingWithPhrase(term: string, titles: string[] | undefined): string | null;
122
- /**
123
- * The first title or heading of two words or more that the query holds whole,
124
- * in order and side by side, or null. A question such as "how do I add dark
125
- * mode" names the "Dark mode" section outright, around words no title has.
126
- * @param {string} term - Lowercased full query.
127
- * @param {string[] | undefined} titles
128
- * @returns {string | null}
129
- */
130
- export function titleInQuery(term: string, titles: string[] | undefined): string | null;
131
- /**
132
- * @param {string} term - Lowercased full query.
133
- * @param {string[]} tokens - Content tokens from tokenizeQuery(term).
134
- * @param {Candidate} candidate
135
- * @param {string[]} [words] - The query's words for compound names (see
136
- * compoundHit); empty when the query names an entry outright.
137
- * @param {{plain?: boolean}} [opts] - `plain`: score without matches on part
138
- * of a name or a joined keyword.
139
- * @returns {{score: number, reason: string, matched: number, total: number, alias?: 'partial' | 'keyword', aliasWords?: number} | null}
140
- * `matched`/`total` are the query concepts this candidate answered, out of
141
- * the concepts the query had. Callers that must distinguish "matched one word
142
- * of three" from "matched all three" — `build`, which gates its pages group
143
- * on coverage — cannot recover that from the score, because a single strong
144
- * hit and a broad weak one land on the same number.
145
- */
146
- export function scoreQuery(term: string, tokens: string[], candidate: Candidate, words?: string[], { plain }?: {
147
- plain?: boolean;
148
- }): {
149
- score: number;
150
- reason: string;
151
- matched: number;
152
- total: number;
153
- alias?: "partial" | "keyword";
154
- aliasWords?: number;
155
- } | null;
156
- /**
157
- * Score a single candidate against the search term across name, keywords,
158
- * and prose signals. Returns the best (highest) score plus a human reason,
159
- * or null if nothing matched above the floor.
160
- *
161
- * @param {string} term - Lowercased search term.
162
- * @param {object} candidate
163
- * @param {string} candidate.name - Primary identifier (component/hook name, topic, template name).
164
- * @param {string[]} [candidate.aliases] - Other names, scored like the name (a theme's display name).
165
- * @param {string} [candidate.domain] - A component, hook, or template name
166
- * also matches typed as words: `command palette` is CommandPalette.
167
- * @param {string[]} [candidate.keywords] - Authored intent (componentsUsed, category words).
168
- * @param {string[]} [candidate.weakKeywords] - Derived signal (components a page renders).
169
- * @param {string} [candidate.description]
170
- * @param {string[]} [candidate.prose] - Extra free-text blobs (doc section text, best practices).
171
- * @param {string[]} [candidate.guidance] - Usage guidance (features, best practices) — scored a tier below description.
172
- * @param {{fuzzy?: boolean, joins?: boolean}} [opts] - `fuzzy`: allow edit-distance (typo) matches. Default true; multi-word queries pass false. `joins`: read a spaced query joined into a name or keyword (default true); off when the query names an entry outright.
173
- * @returns {{score: number, reason: string, alias?: 'partial' | 'keyword'} | null}
174
- * `alias` marks a hit that read the query's words joined.
175
- */
176
- export function scoreCandidate(term: string, { name, aliases, domain, keywords, weakKeywords, description, prose, guidance, }: {
177
- name: string;
178
- aliases?: string[] | undefined;
179
- domain?: string | undefined;
180
- keywords?: string[] | undefined;
181
- weakKeywords?: string[] | undefined;
182
- description?: string | undefined;
183
- prose?: string[] | undefined;
184
- guidance?: string[] | undefined;
185
- }, { fuzzy, joins }?: {
186
- fuzzy?: boolean;
187
- joins?: boolean;
188
- }): {
189
- score: number;
190
- reason: string;
191
- alias?: "partial" | "keyword";
192
- } | null;
193
- /**
194
- * The components (name and keywords) a search response was scored against, or
195
- * null when that search was narrowed away from components.
196
- * @param {object} response
197
- * @returns {{name: string, keywords: string[]}[] | null}
198
- */
199
- export function searchedComponents(response: object): {
200
- name: string;
201
- keywords: string[];
202
- }[] | null;
203
- /**
204
- * Every component the project can use, Core's and its integrations', with the
205
- * keywords its own doc declares: the discovery and doc reads search's own
206
- * candidates use, without the import paths and prose a result carries. `build`
207
- * reads it to tell a part of a page from a page when its search was narrowed
208
- * away from components.
209
- * @param {string} coreDir
210
- * @param {string} cwd
211
- * @returns {Promise<{name: string, keywords: string[]}[]>}
212
- */
213
- export function componentKeywords(coreDir: string, cwd: string): Promise<{
214
- name: string;
215
- keywords: string[];
216
- }[]>;
217
4
  /**
218
5
  * Unified ranked search across components, hooks, docs, templates, and themes.
219
6
  *
@@ -226,99 +13,29 @@ export function componentKeywords(coreDir: string, cwd: string): Promise<{
226
13
  */
227
14
  export function search(query: string, options?: {
228
15
  cwd?: string | undefined;
229
- type?: "component" | "hook" | "doc" | "template" | "theme" | undefined;
16
+ type?: "component" | "hook" | "theme" | "doc" | "template" | undefined;
230
17
  limit?: number | undefined;
231
18
  }): Promise<import("./search.type.mjs").SearchResponse>;
232
- export namespace SYNONYMS {
233
- let dashboard: string[];
234
- let login: string[];
235
- let signup: string[];
236
- let payment: string[];
237
- let pricing: string[];
238
- let chat: string[];
239
- let settings: string[];
240
- let calendar: string[];
241
- let table: string[];
242
- let gallery: string[];
243
- let hero: string[];
244
- let form: string[];
245
- let profile: string[];
246
- let documentation: string[];
247
- let navigation: string[];
248
- }
249
- /** Valid domain filters for `--type`. */
250
- export const SEARCH_DOMAINS: string[];
251
19
  /**
252
- * Filler words stripped from multi-word queries so natural-language phrasing
253
- * ("a page where you can see business stats") ranks on its content words.
254
- * Exported for `build`, whose page ranker strips the same words.
255
- */
256
- export const STOPWORDS: Set<string>;
257
- /**
258
- * A search candidate gathered from one content domain. Extra underscore-
259
- * prefixed fields carry domain-specific payload used only by {@link toResult}.
20
+ * The lexical ranker alone: keyword and fuzzy scoring of every candidate.
21
+ * `build` ranks from it.
22
+ *
23
+ * @param {string} query
24
+ * @param {{cwd?: string, type?: 'component'|'hook'|'doc'|'template'|'theme', limit?: number}} [options]
25
+ * @returns {Promise<import('./search.type.mjs').SearchResponse>}
260
26
  */
261
- export type Candidate = {
262
- domain: "component" | "hook" | "doc" | "template" | "theme";
263
- name: string;
264
- /**
265
- * - Other names the candidate answers to, scored
266
- * with the same name signals: a theme's display name.
267
- */
268
- aliases?: string[] | undefined;
269
- keywords?: string[] | undefined;
270
- /**
271
- * - A doc's own declared keywords: what its
272
- * author lists in `keywords`, without the code terms and table cells its
273
- * other keywords add.
274
- */
275
- _declared?: string[] | undefined;
276
- weakKeywords?: string[] | undefined;
277
- description?: string | undefined;
278
- prose?: string[] | undefined;
279
- guidance?: string[] | undefined;
280
- /**
281
- * - A doc's title and the headings inside it:
282
- * the lines a reader scans to pick it. The whole query standing in one of
283
- * them, or one of them standing whole in the query, is a top-tier match.
284
- */
285
- titles?: string[] | undefined;
286
- _import?: string | undefined;
287
- _title?: string | undefined;
288
- /**
289
- * - A doc result's topic or docs-tree route.
290
- */
291
- _topic?: string | undefined;
292
- /**
293
- * - A doc result's section key, when it is one section.
294
- */
295
- _section?: string | undefined;
296
- /**
297
- * - The command that reads exactly this doc part.
298
- */
299
- _command?: string | undefined;
300
- /**
301
- * - The command that opens the level above a doc
302
- * part: its topic's section list, or the docs-tree namespace it sits in.
303
- */
304
- _parent?: string | undefined;
305
- /**
306
- * - The npm package that owns the candidate:
307
- * Core's package for its components, hooks, and templates, the integration's
308
- * for what it contributed, and for a doc part the package that wrote it.
309
- */
310
- _package?: string | undefined;
311
- _displayName?: string | undefined;
312
- _kind?: "page" | "block" | undefined;
313
- _resultName?: string | undefined;
314
- _commandName?: string | undefined;
315
- /**
316
- * - How an integration component holds its
317
- * name, for the owner rule.
318
- */
319
- _hold?: "file" | "doc" | undefined;
320
- /**
321
- * - An integration component's doc.
322
- */
323
- _docPath?: string | undefined;
324
- };
27
+ export function searchCore(query: string, options?: {
28
+ cwd?: string;
29
+ type?: "component" | "hook" | "doc" | "template" | "theme";
30
+ limit?: number;
31
+ }): Promise<import("./search.type.mjs").SearchResponse>;
32
+ export { scoreCandidate } from "./_candidate-score.mjs";
33
+ export { scoreQuery } from "./_score.mjs";
34
+ export { domainPriority } from "./_priority.mjs";
35
+ export { compoundHit } from "./_compound.mjs";
36
+ export { SYNONYMS } from "./_synonyms.mjs";
37
+ export { searchedComponents } from "./_result.mjs";
38
+ export { componentKeywords } from "./_adapter.mjs";
39
+ export { SEARCH_DOMAINS, STOPWORDS, tokenizeQuery } from "./_query.mjs";
40
+ export { headingWithPhrase, titleInQuery } from "./_titles.mjs";
41
+ export { sameWord, spellIdentifiers, stem } from "./_words.mjs";