@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,50 @@
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
+ /** @typedef {import('./_lexical.mjs').Candidate} Candidate */
5
+ /**
6
+ * The strongest hit a run of two or more adjacent query words has when it is
7
+ * read as one joined word, and the query words it covers. Readers type a
8
+ * compound name as separate words (`table header cell` is TableHeaderCell,
9
+ * `number field` the keyword `numberfield`), and no single word of the run
10
+ * matches on its own.
11
+ *
12
+ * - 100: the run joins to a component, hook, or template name, or its plural
13
+ * (`table header cells` is TableHeaderCell), or a hook name without its
14
+ * `use` prefix (`table sticky columns` is useTableStickyColumns).
15
+ * - 90: the run joins to a one-word keyword (`number field` is
16
+ * `numberfield`).
17
+ * - 95: the run joins to most of a name, cut short (`dropdown menu radio` is
18
+ * DropdownMenuRadioItem); 92: it is a name's leading words, covering at least half
19
+ * of it (`top nav mega` is TopNavMegaMenu); 70: it is two or more adjacent
20
+ * words of a name that cover at least half of it (`header cell` in
21
+ * TableHeaderCell), the same coverage a word prefix needs. These three
22
+ * are for components and hooks only.
23
+ *
24
+ * A doc's name is a route or key, so docs are left out.
25
+ * @param {string[]} words - The query's words, stopwords included.
26
+ * @param {Candidate} candidate
27
+ * @returns {{score: number, reason: string, covered: Set<string>, alias?: 'partial' | 'keyword', aliasWords?: number} | null}
28
+ * `covered` holds the run's words and every stretch of them joined. `alias`
29
+ * marks a hit on part of a name or on a keyword, not on the whole name.
30
+ */
31
+ export function compoundHit(words: string[], candidate: Candidate): {
32
+ score: number;
33
+ reason: string;
34
+ covered: Set<string>;
35
+ alias?: "partial" | "keyword";
36
+ aliasWords?: number;
37
+ } | null;
38
+ /**
39
+ * The longest run of adjacent query words read as one name. Core's longest
40
+ * names run to six words; a longer run is a sentence, not a name, and reading
41
+ * every run of a long build idea costs time on every candidate.
42
+ */
43
+ export const MAX_RUN_WORDS: 6;
44
+ /**
45
+ * Each candidate's compound hit from its last scoreQuery, so domainPriority
46
+ * reads it without walking the query's runs again.
47
+ * @type {WeakMap<object, ReturnType<typeof compoundHit>>}
48
+ */
49
+ export const compoundOf: WeakMap<object, ReturnType<typeof compoundHit>>;
50
+ export type Candidate = import("./_lexical.mjs").Candidate;
@@ -0,0 +1,170 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Compound names: adjacent query words joined into a candidate's name
5
+ * or keyword (`icon button` and IconButton).
6
+ */
7
+
8
+ import {wordsOf, joined} from './_words.mjs';
9
+ import {pluralOf} from './_query.mjs';
10
+
11
+ /** @typedef {import('./_lexical.mjs').Candidate} Candidate */
12
+
13
+ /**
14
+ * The strongest hit a run of two or more adjacent query words has when it is
15
+ * read as one joined word, and the query words it covers. Readers type a
16
+ * compound name as separate words (`table header cell` is TableHeaderCell,
17
+ * `number field` the keyword `numberfield`), and no single word of the run
18
+ * matches on its own.
19
+ *
20
+ * - 100: the run joins to a component, hook, or template name, or its plural
21
+ * (`table header cells` is TableHeaderCell), or a hook name without its
22
+ * `use` prefix (`table sticky columns` is useTableStickyColumns).
23
+ * - 90: the run joins to a one-word keyword (`number field` is
24
+ * `numberfield`).
25
+ * - 95: the run joins to most of a name, cut short (`dropdown menu radio` is
26
+ * DropdownMenuRadioItem); 92: it is a name's leading words, covering at least half
27
+ * of it (`top nav mega` is TopNavMegaMenu); 70: it is two or more adjacent
28
+ * words of a name that cover at least half of it (`header cell` in
29
+ * TableHeaderCell), the same coverage a word prefix needs. These three
30
+ * are for components and hooks only.
31
+ *
32
+ * A doc's name is a route or key, so docs are left out.
33
+ * @param {string[]} words - The query's words, stopwords included.
34
+ * @param {Candidate} candidate
35
+ * @returns {{score: number, reason: string, covered: Set<string>, alias?: 'partial' | 'keyword', aliasWords?: number} | null}
36
+ * `covered` holds the run's words and every stretch of them joined. `alias`
37
+ * marks a hit on part of a name or on a keyword, not on the whole name.
38
+ */
39
+ export function compoundHit(words, candidate) {
40
+ if (candidate.domain === 'doc' || words.length < 2) return null;
41
+ const names = [candidate.name, ...(candidate.aliases ?? [])]
42
+ .filter(Boolean)
43
+ .map(name => ({name, nameJoined: joined(name), nameWords: wordsOf(name)}));
44
+ // Part of a name counts only for a component or hook. A template's name
45
+ // starts with the component it shows (`ProgressBarShowcase`), so part of it
46
+ // names the component, not the template.
47
+ const partial =
48
+ candidate.domain === 'component' || candidate.domain === 'hook';
49
+ // One-word lowercase keywords: a keyword an author declares for a reader
50
+ // to type, joined (`numberfield`). A capitalized one names another entry (a
51
+ // block's `componentsUsed`), which matches by its own name, and a keyword of
52
+ // several words is a phrase, matched as one.
53
+ const keywords = (candidate.keywords ?? []).filter(k =>
54
+ /^[a-z0-9]+$/.test(String(k)),
55
+ );
56
+ /** @type {{score: number, reason: string, covered: Set<string>, alias?: 'partial' | 'keyword', aliasWords?: number} | null} */
57
+ let best = null;
58
+ for (const {run, word} of queryRuns(words)) {
59
+ let score = 0;
60
+ let reason = '';
61
+ /** @type {'partial' | 'keyword' | null} */
62
+ let kind = null;
63
+ for (const {name, nameJoined, nameWords} of names) {
64
+ if (
65
+ nameJoined === word ||
66
+ pluralOf(word, nameJoined) ||
67
+ (candidate.domain === 'hook' && nameJoined === `use${word}`)
68
+ ) {
69
+ if (score < 100)
70
+ [score, reason, kind] = [100, `name ${name} spelled`, null];
71
+ } else if (!partial) {
72
+ continue;
73
+ } else if (
74
+ nameJoined.startsWith(word) &&
75
+ word.length / nameJoined.length >= 0.75
76
+ ) {
77
+ // Most of the name, cut short: `dropdown menu radio` is
78
+ // DropdownMenuRadioItem.
79
+ if (score < 95)
80
+ [score, reason, kind] = [95, `name ${name} spelled`, 'partial'];
81
+ } else if (
82
+ word.length / nameJoined.length >= 0.5 &&
83
+ run.every(
84
+ (w, j) => nameWords[j + (nameWords[0] === 'use' ? 1 : 0)] === w,
85
+ )
86
+ ) {
87
+ // The name's leading words: `top nav mega` is TopNavMegaMenu.
88
+ if (score < 92)
89
+ [score, reason, kind] = [
90
+ 92,
91
+ `name ${name} starts "${run.join(' ')}"`,
92
+ 'partial',
93
+ ];
94
+ } else if (
95
+ word.length / nameJoined.length >= 0.5 &&
96
+ nameWords.some((_, k) => run.every((w, j) => nameWords[k + j] === w))
97
+ ) {
98
+ if (score < 70)
99
+ [score, reason, kind] = [
100
+ 70,
101
+ `name ${name} holds "${run.join(' ')}"`,
102
+ 'partial',
103
+ ];
104
+ }
105
+ }
106
+ if (score < 90 && keywords.includes(word)) {
107
+ [score, reason, kind] = [
108
+ 90,
109
+ `keyword "${run.join(' ')}" spelled`,
110
+ 'keyword',
111
+ ];
112
+ }
113
+ if (score > (best?.score ?? 0)) {
114
+ // Each word of the run, and each identifier typed as several of its
115
+ // words joined (`dropdownMenu` in `dropdownMenu checkbox`).
116
+ const covered = new Set();
117
+ for (let a = 0; a < run.length; a++) {
118
+ for (let b = a + 1; b <= run.length; b++) {
119
+ covered.add(run.slice(a, b).join(''));
120
+ }
121
+ }
122
+ best = {
123
+ score,
124
+ reason,
125
+ covered,
126
+ ...(kind ? {alias: kind, aliasWords: run.length} : {}),
127
+ };
128
+ }
129
+ }
130
+ return best;
131
+ }
132
+
133
+ /**
134
+ * The longest run of adjacent query words read as one name. Core's longest
135
+ * names run to six words; a longer run is a sentence, not a name, and reading
136
+ * every run of a long build idea costs time on every candidate.
137
+ */
138
+ export const MAX_RUN_WORDS = 6;
139
+
140
+ /**
141
+ * Each run of two to {@link MAX_RUN_WORDS} adjacent query words, longest
142
+ * first, with the run joined into one word. Computed once per query.
143
+ * @type {WeakMap<string[], {run: string[], word: string}[]>}
144
+ */
145
+ const runsOf = new WeakMap();
146
+
147
+ /**
148
+ * @param {string[]} words
149
+ * @returns {{run: string[], word: string}[]}
150
+ */
151
+ function queryRuns(words) {
152
+ let runs = runsOf.get(words);
153
+ if (runs) return runs;
154
+ runs = [];
155
+ for (let len = Math.min(words.length, MAX_RUN_WORDS); len >= 2; len--) {
156
+ for (let i = 0; i + len <= words.length; i++) {
157
+ const run = words.slice(i, i + len);
158
+ runs.push({run, word: run.join('')});
159
+ }
160
+ }
161
+ runsOf.set(words, runs);
162
+ return runs;
163
+ }
164
+
165
+ /**
166
+ * Each candidate's compound hit from its last scoreQuery, so domainPriority
167
+ * reads it without walking the query's runs again.
168
+ * @type {WeakMap<object, ReturnType<typeof compoundHit>>}
169
+ */
170
+ export const compoundOf = new WeakMap();
@@ -0,0 +1,4 @@
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
+ export const doc: import("../../foundation/route/route.mjs").Searcher<import("./tree.mjs").SearchRequest, import("./_adapter.mjs").SearchCatalog, import("./search.type.mjs").SearchResponse>;
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The doc searcher: the main searcher's signals with its own weights,
5
+ * in _doc-searcher.weights.json.
6
+ * @input {query, options} and the gathered catalog with its static data
7
+ * @output the search response, the lexical response's shape and size
8
+ * @position api/search; a topic child of the root dispatcher in tree.mjs
9
+ */
10
+
11
+ import {routeKit} from '../../foundation/route/route.mjs';
12
+ import {asWeights, rankWith} from './_main-searcher.mjs';
13
+
14
+ /** @type {import('./tree.mjs').SearchKit} */
15
+ const {defineSearcher} = routeKit;
16
+
17
+ export const doc = defineSearcher({
18
+ id: 'doc',
19
+ summary:
20
+ 'Ranks entries for queries that ask for a doc, with weights of its own.',
21
+ run: (request, catalog, weights) =>
22
+ rankWith(request, catalog, asWeights(weights) ?? catalog.data.doc),
23
+ });
@@ -0,0 +1,36 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Tests for the doc searcher (_doc-searcher.mjs): with its own weights
5
+ * it ranks a doc first for a query that asks for one. Run against the real
6
+ * @astryxdesign/core.
7
+ */
8
+
9
+ import {describe, it, expect} from 'vitest';
10
+ import * as path from 'node:path';
11
+ import {fileURLToPath} from 'node:url';
12
+ import {gatherCandidates, loadSearchData} from './_adapter.mjs';
13
+ import {doc} from './_doc-searcher.mjs';
14
+
15
+ const REPO = path.resolve(
16
+ path.dirname(fileURLToPath(import.meta.url)),
17
+ '../../../..',
18
+ );
19
+
20
+ describe('doc searcher', () => {
21
+ it('ranks a doc first for a doc query', async () => {
22
+ const catalog = {
23
+ ...(await gatherCandidates({cwd: REPO})),
24
+ data: loadSearchData(),
25
+ };
26
+ const answer = /** @type {any} */ (
27
+ await doc.run(
28
+ {query: 'how do I install a theme', options: {cwd: REPO}},
29
+ catalog,
30
+ null,
31
+ )
32
+ );
33
+ expect(answer.data.results[0].domain).toBe('doc');
34
+ expect(answer.data.results.length).toBeLessThanOrEqual(20);
35
+ });
36
+ });
@@ -0,0 +1 @@
1
+ {"w":[0.255034,-0.032567,0.309242,0.050403,-0.358275,0.280939,0.461358,-0.613439,0.397626,0.070136,0.168831,0.032204,0.147137,-0.010509,-0.139086,0.247925,0.0,-0.013425,0.0,0.271127,-0.15666,0.161205,0.275391,-0.017229,-0.003888,0.018954,0.006559,0.010396,-0.003214,0.027251,-0.005917,0.093235,0.101059,0.006095,-0.013116,-0.036481,0.209443,0.12958,0.032606,0.036493,0.082651,0.0,0.0,0.0,0.067563,0.110925,0.145737,0.046132,-0.014063,0.127665,0.014997,0.180173,0.312727,0.079946,0.015853,-0.006495,0.009776,0.005509,0.006095],"mu":[0.122953,0.004932,0.176043,0.017021,0.147234,0.050213,0.178723,0.617872,0.005957,0.170087,0.638276,0.058177,0.049519,0.001321,0.051274,0.176439,0.061188,0.001341,0.0,0.009766,0.004823,0.073882,0.034193,0.000289,0.000827,0.000398,0.002652,0.001028,2.6e-05,0.008501,0.002364,0.111253,0.047342,0.000627,0.073136,0.02573,0.390793,0.145756,0.002861,0.044053,0.014124,0.0,0.0,0.0,0.007995,0.002104,0.029954,0.009344,0.000122,0.021697,0.001864,0.11116,0.041329,0.00039,0.000531,1e-06,0.000703,4.6e-05,6e-05],"sd":[0.272558,0.037015,0.37131,0.129352,0.35434,0.218385,0.383122,0.485909,0.076955,0.825557,1.798503,0.476936,0.124531,0.036157,0.2159,0.232289,1e-06,0.036574,1e-06,0.079222,0.057495,0.229243,0.146561,0.014114,0.017094,0.010761,0.028927,0.011091,0.003965,0.198705,0.104828,0.662804,0.448885,0.080939,0.547129,0.361981,1.544968,0.799909,0.170388,0.407639,0.250897,1e-06,1e-06,1e-06,0.048112,0.025129,0.109037,0.046651,0.006134,0.063975,0.011564,0.248543,0.049449,0.008334,0.023035,0.001195,0.026489,0.006758,0.007742]}
@@ -0,0 +1,30 @@
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 words one section says: its prose, headings, and list items.
6
+ * @param {any} section
7
+ * @returns {string[]}
8
+ */
9
+ export function sectionProse(section: any): string[];
10
+ /**
11
+ * The identifiers a doc part names in code ticks (`token-ref`,
12
+ * `ERR_UNKNOWN_SECTION`). Each is a keyword: a reader who types one exactly
13
+ * wants the part that defines or explains it.
14
+ * @param {any} part - a section, or `{content}` of a typed doc
15
+ * @returns {string[]}
16
+ */
17
+ export function codeTerms(part: any): string[];
18
+ /**
19
+ * The headings inside a section. Each names a subsection, so a query that
20
+ * names one should find the section as surely as one that names its title.
21
+ * @param {any} section
22
+ * @returns {string[]}
23
+ */
24
+ export function headings(section: any): string[];
25
+ /**
26
+ * A table cell as plain words, without its code ticks.
27
+ * @param {unknown} cell
28
+ * @returns {string}
29
+ */
30
+ export function plain(cell: unknown): string;
@@ -0,0 +1,87 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The text search reads from a doc section: its prose, code terms,
5
+ * headings, and table cells as plain words. Imported only by the adapter's
6
+ * gatherers.
7
+ */
8
+
9
+ import {unlinkText} from '../../foundation/doc-compiler/links.mjs';
10
+
11
+ /**
12
+ * The words one section says: its prose, headings, and list items.
13
+ * @param {any} section
14
+ * @returns {string[]}
15
+ */
16
+ export function sectionProse(section) {
17
+ /** @type {string[]} */
18
+ const prose = [];
19
+ if (section?.title) prose.push(section.title);
20
+ for (const block of section?.content || []) {
21
+ if ((block.type === 'prose' || block.type === 'heading') && block.text) {
22
+ prose.push(block.text);
23
+ } else if (block.type === 'list' && Array.isArray(block.items)) {
24
+ for (const item of block.items) {
25
+ const text = typeof item === 'string' ? item : item?.text;
26
+ if (typeof text === 'string') prose.push(text);
27
+ }
28
+ } else if (block.type === 'table' && Array.isArray(block.rows)) {
29
+ for (const row of block.rows) prose.push(row.map(plain).join(' '));
30
+ } else if (block.type === 'code' && typeof block.code === 'string') {
31
+ prose.push([block.label, block.code].filter(Boolean).join(' '));
32
+ }
33
+ }
34
+ return prose;
35
+ }
36
+
37
+ /**
38
+ * The identifiers a doc part names in code ticks (`token-ref`,
39
+ * `ERR_UNKNOWN_SECTION`). Each is a keyword: a reader who types one exactly
40
+ * wants the part that defines or explains it.
41
+ * @param {any} part - a section, or `{content}` of a typed doc
42
+ * @returns {string[]}
43
+ */
44
+ export function codeTerms(part) {
45
+ /** @type {Set<string>} */
46
+ const terms = new Set();
47
+ /** @param {unknown} text */
48
+ const scan = text => {
49
+ for (const m of String(text ?? '').matchAll(/`([^`\s]{2,40})`/g)) {
50
+ terms.add(m[1]);
51
+ }
52
+ };
53
+ for (const block of part?.content || []) {
54
+ if (block.type === 'prose') scan(block.text);
55
+ else if (block.type === 'list' && Array.isArray(block.items)) {
56
+ for (const item of block.items) {
57
+ scan(typeof item === 'string' ? item : item?.text);
58
+ }
59
+ } else if (block.type === 'table' && Array.isArray(block.rows)) {
60
+ for (const row of block.rows) for (const cell of row) scan(cell);
61
+ }
62
+ }
63
+ return [...terms];
64
+ }
65
+
66
+ /**
67
+ * The headings inside a section. Each names a subsection, so a query that
68
+ * names one should find the section as surely as one that names its title.
69
+ * @param {any} section
70
+ * @returns {string[]}
71
+ */
72
+ export function headings(section) {
73
+ return (section?.content || [])
74
+ .filter(
75
+ (/** @type {any} */ block) => block.type === 'heading' && block.text,
76
+ )
77
+ .map((/** @type {any} */ block) => String(block.text));
78
+ }
79
+
80
+ /**
81
+ * A table cell as plain words, without its code ticks.
82
+ * @param {unknown} cell
83
+ * @returns {string}
84
+ */
85
+ export function plain(cell) {
86
+ return unlinkText(String(cell ?? '')).replaceAll('`', '');
87
+ }
@@ -0,0 +1,63 @@
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 entries search can answer with and their text, by field. Each doc
6
+ * section is its own entry. Built once per gathered catalog.
7
+ * @param {any[]} all the gathered candidates
8
+ * @param {Record<string, {what?: string, synonyms?: string[], props?: string[]}>} cards
9
+ * @returns {EntryTable}
10
+ */
11
+ export function entryTable(all: any[], cards: Record<string, {
12
+ what?: string;
13
+ synonyms?: string[];
14
+ props?: string[];
15
+ }>): EntryTable;
16
+ /**
17
+ * @param {any[]} all
18
+ * @param {Record<string, {what?: string, synonyms?: string[], props?: string[]}>} cards
19
+ * @returns {EntryTable}
20
+ */
21
+ export function buildTable(all: any[], cards: Record<string, {
22
+ what?: string;
23
+ synonyms?: string[];
24
+ props?: string[];
25
+ }>): EntryTable;
26
+ export function entryOf(table: {
27
+ index: Map<string, number>;
28
+ }, res: {
29
+ domain: string;
30
+ name: string;
31
+ package?: string;
32
+ section?: string;
33
+ }): number | undefined;
34
+ export function entryId(c: any): string;
35
+ export const HASHED_FIELDS: readonly string[];
36
+ export type EntryTable = {
37
+ /**
38
+ * every returnable `<domain>:<name>`, in code-point order
39
+ */
40
+ ids: string[];
41
+ /**
42
+ * id -> position
43
+ */
44
+ index: Map<string, number>;
45
+ /**
46
+ * one candidate per id, for its result
47
+ */
48
+ candidate: any[];
49
+ /**
50
+ * domain index per id
51
+ */
52
+ domain: number[];
53
+ /**
54
+ * each id's name words
55
+ */
56
+ name: string[][];
57
+ fields: Record<"name" | "desc" | "card", {
58
+ post: Map<string, [number, number][]>;
59
+ idf: Map<string, number>;
60
+ len: number[];
61
+ avg: number;
62
+ }>;
63
+ };