@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,174 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The active hosted run (architecture:cli-surface INV30, spec AST-081
5
+ * FR1): the package sets, approved integrations, and discover sources a host
6
+ * passed through `@astryxdesign/cli/host`, the root that holds the copy that
7
+ * started the run, and the packages the run resolved.
8
+ *
9
+ * Only the host entry activates a hosted run, once per process. With none
10
+ * active, every lookup that consults it behaves as it does without a host.
11
+ *
12
+ * @input What the host entry passes to `activateHostedRun`.
13
+ * @output `hostedRun()` for the lookups that consult it; the resolved-package
14
+ * record the host entry returns.
15
+ * @position foundation/runtime — read by the release choice, Core lookups,
16
+ * computer-level integrations, and discover; written by host/index.mjs.
17
+ */
18
+
19
+ import * as fs from 'node:fs';
20
+ import {relativeWithin, samePath} from '../fs/path-compare.mjs';
21
+
22
+ /**
23
+ * @typedef {object} HostedRun
24
+ * @property {readonly string[]} roots the host's package sets, in its order
25
+ * @property {readonly string[]} integrations the integrations it approves for
26
+ * use outside a project
27
+ * @property {readonly Function[]} discoverSources its own discover sources
28
+ * @property {string | null} startingRoot the root that holds the copy that
29
+ * started the run
30
+ * @property {string | null} projectRoot the project the run works in, if any
31
+ * @property {((hostEntry: string) => Promise<(options: object) => Promise<{status: number, packages: Array<{name: string, version: string | null, source: 'project' | 'package-set'}>}>>) | null} loadHostEntry
32
+ * loads another release's host entry, from one of the package sets, to hand
33
+ * this run over to in this process
34
+ */
35
+
36
+ /** @type {HostedRun | null} */
37
+ let active = null;
38
+
39
+ /** @type {Map<string, {name: string, version: string | null, dir: string | null, source: 'project' | 'package-set' | undefined}>} */
40
+ const resolved = new Map();
41
+
42
+ /**
43
+ * @param {string} p
44
+ * @returns {string}
45
+ */
46
+ function real(p) {
47
+ try {
48
+ return fs.realpathSync(p);
49
+ } catch {
50
+ return p;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Start the hosted run of this process.
56
+ * @param {{roots?: readonly string[], integrations?: readonly string[], discoverSources?: readonly Function[], startingRoot?: string | null, projectRoot?: string | null, loadHostEntry?: HostedRun['loadHostEntry']}} inputs
57
+ * @returns {HostedRun}
58
+ */
59
+ export function activateHostedRun({
60
+ roots = [],
61
+ integrations = [],
62
+ discoverSources = [],
63
+ startingRoot = null,
64
+ projectRoot = null,
65
+ loadHostEntry = null,
66
+ }) {
67
+ if (active)
68
+ throw new Error('A hosted run is already active in this process.');
69
+ active = Object.freeze({
70
+ roots: Object.freeze([...roots]),
71
+ integrations: Object.freeze([...integrations]),
72
+ discoverSources: Object.freeze([...discoverSources]),
73
+ startingRoot,
74
+ projectRoot,
75
+ loadHostEntry,
76
+ });
77
+ return active;
78
+ }
79
+
80
+ /**
81
+ * The hosted run of this process, or null when no host started it.
82
+ * @returns {HostedRun | null}
83
+ */
84
+ export function hostedRun() {
85
+ return active;
86
+ }
87
+
88
+ /**
89
+ * Note one package the run resolved. The first record of a name stands. Does
90
+ * nothing outside a hosted run.
91
+ * @param {string} name
92
+ * @param {unknown} version
93
+ * @param {string | null | undefined} dir
94
+ * @param {'project' | 'package-set'} [source] where it came from, when the
95
+ * caller knows; otherwise the folder that holds `dir` says
96
+ */
97
+ export function recordResolved(name, version, dir, source) {
98
+ if (!active || typeof name !== 'string' || resolved.has(name)) return;
99
+ resolved.set(name, {
100
+ name,
101
+ version: typeof version === 'string' ? version : null,
102
+ dir: dir ?? null,
103
+ source,
104
+ });
105
+ }
106
+
107
+ /**
108
+ * Note every integration a project load resolved: one installed for the
109
+ * computer, an approved one included, comes from a package set; any other,
110
+ * from the project.
111
+ * @param {ReadonlyArray<{name: string, version?: string, __packageDir?: string, __computer?: boolean}>} integrations
112
+ */
113
+ export function recordResolvedIntegrations(integrations) {
114
+ if (!active) return;
115
+ for (const integration of integrations) {
116
+ recordResolved(
117
+ integration.name,
118
+ integration.version,
119
+ integration.__packageDir,
120
+ integration.__computer ? 'package-set' : 'project',
121
+ );
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Where a package in `dir` came from: the deepest of the project and the
127
+ * package sets (the root that holds the starting copy, and the roots the host
128
+ * passed) that holds it. A root that is the project itself, as when the
129
+ * host's CLI is installed in the project, counts as the project.
130
+ * @param {string | null} dir
131
+ * @returns {'project' | 'package-set'}
132
+ */
133
+ function sourceOf(dir) {
134
+ if (!active || !dir) return 'project';
135
+ const target = real(dir);
136
+ /** @type {Array<{base: string, source: 'project' | 'package-set'}>} */
137
+ const holders = [];
138
+ if (active.projectRoot) {
139
+ holders.push({base: real(active.projectRoot), source: 'project'});
140
+ }
141
+ for (const root of [active.startingRoot, ...active.roots]) {
142
+ if (root) holders.push({base: real(root), source: 'package-set'});
143
+ }
144
+ /** @type {{base: string, source: 'project' | 'package-set'} | null} */
145
+ let best = null;
146
+ for (const holder of holders) {
147
+ const holds =
148
+ samePath(holder.base, target) ||
149
+ relativeWithin(holder.base, target) != null;
150
+ // The project comes first, so it keeps a tie with a root that is itself.
151
+ if (holds && (!best || holder.base.length > best.base.length))
152
+ best = holder;
153
+ }
154
+ return best ? best.source : 'project';
155
+ }
156
+
157
+ /**
158
+ * Each package the run resolved: its name, version, and whether it came from
159
+ * the project or a package set (INV30).
160
+ * @returns {Array<{name: string, version: string | null, source: 'project' | 'package-set'}>}
161
+ */
162
+ export function resolvedPackages() {
163
+ return [...resolved.values()].map(({name, version, dir, source}) => ({
164
+ name,
165
+ version,
166
+ source: source ?? sourceOf(dir),
167
+ }));
168
+ }
169
+
170
+ /** Forget the hosted run. Tests only. */
171
+ export function _resetHostedRun() {
172
+ active = null;
173
+ resolved.clear();
174
+ }
@@ -0,0 +1,62 @@
1
+ // @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
2
+ // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
+
4
+ /**
5
+ * A root's own copy of `name`, read from its `node_modules` only: a root never
6
+ * reaches past itself.
7
+ * @param {string} root
8
+ * @param {string} name
9
+ * @returns {{dir: string, version: string | null} | null}
10
+ */
11
+ export function rootPackage(root: string, name: string): {
12
+ dir: string;
13
+ version: string | null;
14
+ } | null;
15
+ /**
16
+ * Whether `version` is one the project's install could bring in for `range`:
17
+ * a plain version range only, and a prerelease only when the range names a
18
+ * prerelease of the same version.
19
+ * @param {string | null} version
20
+ * @param {string} range
21
+ * @returns {boolean}
22
+ */
23
+ export function satisfiesInstall(version: string | null, range: string): boolean;
24
+ /**
25
+ * @typedef {object} ServingRoot
26
+ * @property {string} root
27
+ * @property {string} cliDir the root's CLI package
28
+ * @property {string | null} bin the root's `astryx` bin
29
+ * @property {string | null} hostEntry the root's `host/index.mjs`, when its
30
+ * CLI ships one
31
+ */
32
+ /**
33
+ * The first of `roots` that may serve a run in `projectDir` that CLI
34
+ * `release` answers.
35
+ * @param {{release: string, projectDir: string | null, roots: readonly string[], needsHostEntry?: boolean}} input
36
+ * `needsHostEntry` keeps out a root whose CLI has no host entry
37
+ * @returns {ServingRoot | {reason: string}}
38
+ */
39
+ export function qualifyingRoot({ release, projectDir, roots, needsHostEntry, }: {
40
+ release: string;
41
+ projectDir: string | null;
42
+ roots: readonly string[];
43
+ needsHostEntry?: boolean;
44
+ }): ServingRoot | {
45
+ reason: string;
46
+ };
47
+ export type ServingRoot = {
48
+ root: string;
49
+ /**
50
+ * the root's CLI package
51
+ */
52
+ cliDir: string;
53
+ /**
54
+ * the root's `astryx` bin
55
+ */
56
+ bin: string | null;
57
+ /**
58
+ * the root's `host/index.mjs`, when its
59
+ * CLI ships one
60
+ */
61
+ hostEntry: string | null;
62
+ };
@@ -0,0 +1,130 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Matching a project to a host's package sets (architecture:cli-surface
5
+ * INV30). A package set is a root whose `node_modules` holds a CLI, the Core
6
+ * equal to it, and the integrations installed with them; a run resolves from at
7
+ * most one root, and a hosted run installs nothing.
8
+ *
9
+ * Inside a project a root fills only the `@astryxdesign/*` packages the
10
+ * project leaves uninstalled whose copy in the root ships no integration
11
+ * manifest. For a run that a release other than the starting copy answers, the
12
+ * first root in the host's order qualifies when its CLI and Core are that
13
+ * release and it holds, for each package it may fill, the version the project
14
+ * would install: the lockfile's, else a published version in the declared
15
+ * range.
16
+ *
17
+ * @input A release, the project folder, and the host's roots.
18
+ * @output The root that serves the run, or why none can.
19
+ * @position foundation/runtime — read by the release choice (handoff.mjs) in a
20
+ * hosted run.
21
+ */
22
+
23
+ import * as fs from 'node:fs';
24
+ import * as path from 'node:path';
25
+ import {findManifestPaths} from '../integrations/integrations.mjs';
26
+ import {readJson} from '../release/project.mjs';
27
+ import {cliBinOf, isVersionRange} from '../release/cache.mjs';
28
+ import {isValidSemver, satisfiesRange} from '../env/semver.mjs';
29
+ import {projectAstryxPins} from './locked-versions.mjs';
30
+
31
+ const CLI = '@astryxdesign/cli';
32
+ const CORE = '@astryxdesign/core';
33
+
34
+ /**
35
+ * A root's own copy of `name`, read from its `node_modules` only: a root never
36
+ * reaches past itself.
37
+ * @param {string} root
38
+ * @param {string} name
39
+ * @returns {{dir: string, version: string | null} | null}
40
+ */
41
+ export function rootPackage(root, name) {
42
+ const dir = path.join(root, 'node_modules', ...name.split('/'));
43
+ const pkg = readJson(path.join(dir, 'package.json'));
44
+ if (!pkg || typeof pkg !== 'object' || pkg.name !== name) return null;
45
+ return {dir, version: typeof pkg.version === 'string' ? pkg.version : null};
46
+ }
47
+
48
+ /**
49
+ * Whether `version` is one the project's install could bring in for `range`:
50
+ * a plain version range only, and a prerelease only when the range names a
51
+ * prerelease of the same version.
52
+ * @param {string | null} version
53
+ * @param {string} range
54
+ * @returns {boolean}
55
+ */
56
+ export function satisfiesInstall(version, range) {
57
+ if (!version || !isValidSemver(version) || !isVersionRange(range)) {
58
+ return false;
59
+ }
60
+ const dash = version.indexOf('-');
61
+ if (dash !== -1 && !range.includes(`${version.slice(0, dash)}-`)) {
62
+ return false;
63
+ }
64
+ return satisfiesRange(version, range);
65
+ }
66
+
67
+ /**
68
+ * Whether `root` holds what the project would install for one pin it leaves
69
+ * uninstalled. A package the root holds as an integration, or does not hold at
70
+ * all, is one the root never fills, so it never keeps the root out.
71
+ * @param {string} root
72
+ * @param {import('./locked-versions.mjs').AstryxPin} pin
73
+ * @returns {boolean}
74
+ */
75
+ function holds(root, pin) {
76
+ if (pin.name === CLI) return true;
77
+ const copy = rootPackage(root, pin.name);
78
+ if (!copy) return pin.name !== CORE;
79
+ if (findManifestPaths(copy.dir).length > 0) return true;
80
+ if (pin.locked) return copy.version === pin.locked;
81
+ return satisfiesInstall(copy.version, pin.declared);
82
+ }
83
+
84
+ /**
85
+ * @typedef {object} ServingRoot
86
+ * @property {string} root
87
+ * @property {string} cliDir the root's CLI package
88
+ * @property {string | null} bin the root's `astryx` bin
89
+ * @property {string | null} hostEntry the root's `host/index.mjs`, when its
90
+ * CLI ships one
91
+ */
92
+
93
+ /**
94
+ * The first of `roots` that may serve a run in `projectDir` that CLI
95
+ * `release` answers.
96
+ * @param {{release: string, projectDir: string | null, roots: readonly string[], needsHostEntry?: boolean}} input
97
+ * `needsHostEntry` keeps out a root whose CLI has no host entry
98
+ * @returns {ServingRoot | {reason: string}}
99
+ */
100
+ export function qualifyingRoot({
101
+ release,
102
+ projectDir,
103
+ roots,
104
+ needsHostEntry = false,
105
+ }) {
106
+ const open = projectDir
107
+ ? projectAstryxPins(projectDir).filter(pin => pin.installed === null)
108
+ : [];
109
+ for (const root of roots) {
110
+ const cli = rootPackage(root, CLI);
111
+ if (!cli || cli.version !== release) continue;
112
+ const core = rootPackage(root, CORE);
113
+ if (!core || core.version !== release) continue;
114
+ const hostEntry = path.join(cli.dir, 'host', 'index.mjs');
115
+ const hasHostEntry = fs.existsSync(hostEntry);
116
+ if (needsHostEntry && !hasHostEntry) continue;
117
+ const bin = cliBinOf(cli.dir);
118
+ if (!bin && !hasHostEntry) continue;
119
+ if (!open.every(pin => holds(root, pin))) continue;
120
+ return {
121
+ root,
122
+ cliDir: cli.dir,
123
+ bin,
124
+ hostEntry: hasHostEntry ? hostEntry : null,
125
+ };
126
+ }
127
+ return {
128
+ reason: `no package set the host passed holds CLI ${release} with this project's packages`,
129
+ };
130
+ }