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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (694) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +216 -162
  3. package/api/build/_adapter.d.mts +66 -0
  4. package/api/build/_adapter.mjs +139 -4
  5. package/api/build/blocks/blocks.d.mts +92 -0
  6. package/api/build/blocks/blocks.mjs +528 -0
  7. package/api/build/blocks/blocks.test.mjs +238 -0
  8. package/api/build/blocks/blocks.weights.json +1 -0
  9. package/api/build/build.doc.mjs +4 -0
  10. package/api/build/build.mjs +25 -6
  11. package/api/build/build.type.mjs +1 -1
  12. package/api/build/help/help.mjs +1 -1
  13. package/api/build/kit/answer.d.mts +18 -0
  14. package/api/build/kit/answer.mjs +195 -0
  15. package/api/build/kit/answer.test.mjs +108 -0
  16. package/api/build/kit/kind.d.mts +25 -0
  17. package/api/build/kit/kind.mjs +170 -0
  18. package/api/build/kit/kit.d.mts +2 -4
  19. package/api/build/kit/kit.mjs +8 -406
  20. package/api/build/kit/rank.d.mts +3 -32
  21. package/api/build/kit/rank.mjs +25 -342
  22. package/api/build/kit/rank.test.mjs +2 -1
  23. package/api/build/kit/signals.d.mts +79 -0
  24. package/api/build/kit/signals.mjs +295 -0
  25. package/api/build/kit/start.d.mts +32 -0
  26. package/api/build/kit/start.mjs +163 -0
  27. package/api/build/kit/words.d.mts +72 -0
  28. package/api/build/kit/words.mjs +202 -0
  29. package/api/build/tree.d.mts +20 -0
  30. package/api/build/tree.mjs +53 -0
  31. package/api/build/tree.test.mjs +185 -0
  32. package/api/build/tree.weights.json +1 -0
  33. package/api/component/_adapter.d.mts +72 -1
  34. package/api/component/_adapter.mjs +251 -23
  35. package/api/component/component-replacement.test.mjs +1 -0
  36. package/api/component/component.doc.mjs +6 -1
  37. package/api/component/component.mjs +97 -16
  38. package/api/component/component.test.mjs +95 -0
  39. package/api/component/doc-links.test.mjs +386 -0
  40. package/api/component/integration-export-name.test.mjs +644 -0
  41. package/api/component/list/list.mjs +42 -4
  42. package/api/discover/_adapter.d.mts +131 -12
  43. package/api/discover/_adapter.mjs +520 -34
  44. package/api/discover/_adapter.test.mjs +641 -17
  45. package/api/discover/_catalog-view.d.mts +16 -5
  46. package/api/discover/_catalog-view.mjs +32 -8
  47. package/api/discover/detail/doc/doc.mjs +9 -1
  48. package/api/discover/discover.d.mts +11 -0
  49. package/api/discover/discover.doc.mjs +9 -7
  50. package/api/discover/discover.mjs +120 -19
  51. package/api/discover/discover.type.d.mts +20 -7
  52. package/api/discover/discover.type.mjs +17 -7
  53. package/api/discover/list/list.d.mts +4 -3
  54. package/api/discover/list/list.mjs +17 -10
  55. package/api/docs/_adapter.d.mts +76 -2
  56. package/api/docs/_adapter.mjs +630 -34
  57. package/api/docs/docs-homes.test.mjs +127 -0
  58. package/api/docs/docs.doc.mjs +5 -4
  59. package/api/docs/docs.mjs +2 -1
  60. package/api/docs/docs.test.mjs +39 -20
  61. package/api/docs/integration-tree.test.mjs +42 -20
  62. package/api/docs/integrationDocs.test.mjs +125 -1
  63. package/api/docs/list/list.mjs +12 -2
  64. package/api/docs/namespace-section.test.mjs +6 -6
  65. package/api/docs/reference-blocks.test.mjs +3 -5
  66. package/api/doctor/_adapter.d.mts +128 -0
  67. package/api/doctor/_adapter.mjs +253 -4
  68. package/api/doctor/doctor.d.mts +217 -0
  69. package/api/doctor/doctor.doc.mjs +3 -2
  70. package/api/doctor/doctor.mjs +691 -52
  71. package/api/doctor/doctor.test.mjs +267 -18
  72. package/api/doctor/release-checks.test.mjs +156 -0
  73. package/api/doctor/theme-checks.mjs +17 -4
  74. package/api/doctor/theme-checks.test.mjs +223 -7
  75. package/api/error.d.mts +10 -0
  76. package/api/error.mjs +25 -0
  77. package/api/gap-report/gap-report.d.mts +3 -0
  78. package/api/gap-report/gap-report.doc.mjs +11 -3
  79. package/api/gap-report/gap-report.mjs +219 -52
  80. package/api/gap-report/gap-report.test.mjs +233 -0
  81. package/api/gap-report/gap-report.type.d.mts +41 -0
  82. package/api/gap-report/gap-report.type.mjs +18 -0
  83. package/api/hook/_adapter.mjs +3 -11
  84. package/api/hook/hook.doc.mjs +4 -0
  85. package/api/hook/hook.mjs +1 -1
  86. package/api/hook/list/list.d.mts +1 -1
  87. package/api/index.d.mts +2 -0
  88. package/api/index.mjs +2 -0
  89. package/api/init/_adapter.d.mts +22 -0
  90. package/api/init/_adapter.mjs +59 -0
  91. package/api/init/init.d.mts +7 -5
  92. package/api/init/init.doc.mjs +45 -10
  93. package/api/init/init.mjs +28 -4
  94. package/api/init/init.test.mjs +18 -2
  95. package/api/init/init.type.d.mts +50 -5
  96. package/api/init/init.type.mjs +39 -5
  97. package/api/init/remove/remove.mjs +17 -4
  98. package/api/init/remove/remove.test.mjs +114 -2
  99. package/api/init/run/run.d.mts +1 -1
  100. package/api/init/run/run.mjs +86 -12
  101. package/api/init/user/user.d.mts +14 -0
  102. package/api/init/user/user.mjs +87 -0
  103. package/api/init/user/user.test.mjs +232 -0
  104. package/api/integration/_adapter.d.mts +53 -0
  105. package/api/integration/_adapter.mjs +132 -0
  106. package/api/integration/add-contribution.component-names.test.mjs +66 -0
  107. package/api/integration/add-contribution.mjs +8 -4
  108. package/api/integration/add-contribution.test.mjs +4 -2
  109. package/api/integration/authoring-checks.mjs +192 -14
  110. package/api/integration/authoring-checks.test.mjs +1028 -0
  111. package/api/integration/authoring-checks.type.d.mts +143 -0
  112. package/api/integration/authoring-checks.type.mjs +74 -2
  113. package/api/integration/check/check.d.mts +96 -0
  114. package/api/integration/check/check.mjs +357 -0
  115. package/api/integration/check/check.test.mjs +489 -0
  116. package/api/integration/integration-check.type.d.mts +118 -0
  117. package/api/integration/integration-check.type.mjs +84 -0
  118. package/api/integration/integrationCheck.doc.d.mts +10 -0
  119. package/api/integration/integrationCheck.doc.mjs +73 -0
  120. package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
  121. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  122. package/api/integration/pack-check.mjs +486 -123
  123. package/api/integration/pack-check.test.mjs +817 -10
  124. package/api/integration/validate-integration-case-disk.test.mjs +111 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +73 -5
  126. package/api/integration/validate-integration-gaps.test.mjs +1975 -0
  127. package/api/integration/validate-integration.d.mts +23 -2
  128. package/api/integration/validate-integration.mjs +358 -45
  129. package/api/integration/validate-integration.test.mjs +88 -8
  130. package/api/integration/validate-integration.type.d.mts +105 -0
  131. package/api/integration/validate-integration.type.mjs +79 -1
  132. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  133. package/api/integration/validateIntegration.doc.mjs +19 -3
  134. package/api/search/ORDERING.md +28 -0
  135. package/api/search/_adapter.d.mts +91 -0
  136. package/api/search/_adapter.mjs +172 -0
  137. package/api/search/_adapter.test.mjs +173 -0
  138. package/api/search/_candidate-score.d.mts +40 -0
  139. package/api/search/_candidate-score.mjs +238 -0
  140. package/api/search/_cards.json +6098 -0
  141. package/api/search/_compound.d.mts +50 -0
  142. package/api/search/_compound.mjs +170 -0
  143. package/api/search/_doc-searcher.d.mts +4 -0
  144. package/api/search/_doc-searcher.mjs +23 -0
  145. package/api/search/_doc-searcher.test.mjs +36 -0
  146. package/api/search/_doc-searcher.weights.json +1 -0
  147. package/api/search/_doc-text.d.mts +30 -0
  148. package/api/search/_doc-text.mjs +87 -0
  149. package/api/search/_entries.d.mts +63 -0
  150. package/api/search/_entries.mjs +232 -0
  151. package/api/search/_entries.test.mjs +48 -0
  152. package/api/search/_features.d.mts +35 -0
  153. package/api/search/_features.mjs +155 -0
  154. package/api/search/_gather-components.d.mts +26 -0
  155. package/api/search/_gather-components.mjs +284 -0
  156. package/api/search/_gather-docs.d.mts +20 -0
  157. package/api/search/_gather-docs.mjs +254 -0
  158. package/api/search/_gather-hooks.d.mts +12 -0
  159. package/api/search/_gather-hooks.mjs +52 -0
  160. package/api/search/_gather-templates.d.mts +25 -0
  161. package/api/search/_gather-templates.mjs +107 -0
  162. package/api/search/_lexical.d.mts +135 -0
  163. package/api/search/_lexical.mjs +351 -0
  164. package/api/search/_main-searcher.d.mts +19 -0
  165. package/api/search/_main-searcher.mjs +115 -0
  166. package/api/search/_main-searcher.test.mjs +106 -0
  167. package/api/search/_main-searcher.weights.json +1 -0
  168. package/api/search/_module-doc.d.mts +32 -0
  169. package/api/search/_module-doc.mjs +78 -0
  170. package/api/search/_order.d.mts +32 -0
  171. package/api/search/_order.mjs +162 -0
  172. package/api/search/_order.test.mjs +72 -0
  173. package/api/search/_priority.d.mts +50 -0
  174. package/api/search/_priority.mjs +139 -0
  175. package/api/search/_query-words.d.mts +25 -0
  176. package/api/search/_query-words.mjs +92 -0
  177. package/api/search/_query.d.mts +65 -0
  178. package/api/search/_query.mjs +176 -0
  179. package/api/search/_result.d.mts +97 -0
  180. package/api/search/_result.mjs +150 -0
  181. package/api/search/_score.d.mts +60 -0
  182. package/api/search/_score.mjs +283 -0
  183. package/api/search/_synonyms.d.mts +21 -0
  184. package/api/search/_synonyms.mjs +67 -0
  185. package/api/search/_template-searcher.d.mts +4 -0
  186. package/api/search/_template-searcher.mjs +23 -0
  187. package/api/search/_template-searcher.test.mjs +40 -0
  188. package/api/search/_template-searcher.weights.json +1 -0
  189. package/api/search/_titles.d.mts +33 -0
  190. package/api/search/_titles.mjs +65 -0
  191. package/api/search/_words.d.mts +64 -0
  192. package/api/search/_words.mjs +157 -0
  193. package/api/search/search.d.mts +22 -236
  194. package/api/search/search.doc.mjs +14 -7
  195. package/api/search/search.domain-priority.test.mjs +108 -18
  196. package/api/search/search.integration-check.test.mjs +24 -0
  197. package/api/search/search.mjs +59 -1904
  198. package/api/search/search.test.mjs +193 -15
  199. package/api/search/search.type.d.mts +20 -2
  200. package/api/search/search.type.mjs +12 -2
  201. package/api/search/tree.d.mts +15 -0
  202. package/api/search/tree.mjs +40 -0
  203. package/api/search/tree.test.mjs +66 -0
  204. package/api/search/tree.weights.json +1 -0
  205. package/api/swizzle/_adapter.mjs +2 -2
  206. package/api/swizzle/copy/copy.mjs +29 -15
  207. package/api/template/template-integration.test.mjs +1 -1
  208. package/api/template/template.mjs +5 -1
  209. package/api/template/template.test.mjs +120 -3
  210. package/api/theme/_adapter.d.mts +16 -0
  211. package/api/theme/_adapter.mjs +32 -5
  212. package/api/theme/build/build.d.mts +2 -1
  213. package/api/theme/build/build.family.test.mjs +64 -0
  214. package/api/theme/build/build.mjs +250 -38
  215. package/api/theme/build/build.packed-old-core.test.mjs +21 -3
  216. package/api/theme/build/font-warning.mjs +5 -3
  217. package/api/theme/build/font-warning.test.mjs +2 -1
  218. package/api/theme/remove/remove.test.mjs +2 -2
  219. package/api/theme/targets/targets.mjs +3 -10
  220. package/api/theme/themeBuild.doc.mjs +4 -4
  221. package/api/theme/themeTargets.doc.mjs +4 -0
  222. package/api/theme/use/use.test.mjs +1 -1
  223. package/api/upgrade/_adapter.d.mts +97 -11
  224. package/api/upgrade/_adapter.mjs +315 -32
  225. package/api/upgrade/registry/registry.d.mts +10 -4
  226. package/api/upgrade/registry/registry.mjs +33 -16
  227. package/api/upgrade/registry/registry.test.mjs +85 -0
  228. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  229. package/api/upgrade/run/run.d.mts +4 -2
  230. package/api/upgrade/run/run.mjs +48 -4
  231. package/api/upgrade/run/run.test.mjs +417 -3
  232. package/api/upgrade/status/status.d.mts +21 -5
  233. package/api/upgrade/status/status.mjs +45 -8
  234. package/api/upgrade/upgrade.doc.mjs +16 -8
  235. package/api/upgrade/upgrade.mjs +18 -3
  236. package/api/upgrade/upgrade.test.mjs +194 -0
  237. package/api/upgrade/upgrade.type.d.mts +28 -3
  238. package/api/upgrade/upgrade.type.mjs +24 -7
  239. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  240. package/assets/codemods/registry.mjs +1 -0
  241. package/assets/codemods/runner.mjs +7 -1
  242. package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
  243. package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
  244. package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
  245. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  246. package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
  247. package/assets/discover/official-packages.json +367 -0
  248. package/assets/docs/README.md +10 -0
  249. package/assets/docs/author-a-theme.doc.mjs +5 -5
  250. package/assets/docs/browser-support.doc.mjs +1 -1
  251. package/assets/docs/getting-started.doc.mjs +26 -6
  252. package/assets/docs/is-my-code-good.doc.mjs +287 -0
  253. package/assets/docs/styling-overview.doc.mjs +1 -1
  254. package/assets/docs/theme.doc.dense.mjs +1 -1
  255. package/assets/docs/theme.doc.mjs +2 -2
  256. package/assets/docs/theme.doc.zh.mjs +1 -1
  257. package/assets/docs/tree/add-a-component.doc.mjs +22 -2
  258. package/assets/docs/tree/add-a-theme.doc.mjs +14 -4
  259. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  260. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  261. package/assets/docs/tree/api.doc.mjs +6 -0
  262. package/assets/docs/tree/authoring.doc.mjs +61 -0
  263. package/assets/docs/tree/block-template.doc.mjs +8 -20
  264. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  265. package/assets/docs/tree/building-blocks.doc.mjs +6 -2
  266. package/assets/docs/tree/check-the-props.doc.mjs +201 -0
  267. package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
  268. package/assets/docs/tree/checks.doc.mjs +32 -24
  269. package/assets/docs/tree/ci-and-containers.doc.mjs +101 -0
  270. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  271. package/assets/docs/tree/cli.doc.mjs +7 -1
  272. package/assets/docs/tree/codemods.doc.mjs +17 -7
  273. package/assets/docs/tree/commands.doc.mjs +7 -1
  274. package/assets/docs/tree/component-family.doc.mjs +8 -6
  275. package/assets/docs/tree/component-imports.doc.mjs +21 -3
  276. package/assets/docs/tree/components.doc.mjs +7 -1
  277. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  278. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  279. package/assets/docs/tree/configuration.doc.mjs +8 -4
  280. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  281. package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
  282. package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
  283. package/assets/docs/tree/docs.doc.mjs +9 -3
  284. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  285. package/assets/docs/tree/document-the-theme.doc.mjs +4 -4
  286. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  287. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  288. package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
  291. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  292. package/assets/docs/tree/global.doc.mjs +131 -0
  293. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  294. package/assets/docs/tree/help.doc.mjs +2 -2
  295. package/assets/docs/tree/host-entry.doc.mjs +128 -0
  296. package/assets/docs/tree/install-once.doc.mjs +105 -0
  297. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  298. package/assets/docs/tree/layout.doc.mjs +6 -6
  299. package/assets/docs/tree/links.doc.mjs +7 -6
  300. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  301. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  302. package/assets/docs/tree/migration.doc.mjs +0 -1
  303. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  304. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  305. package/assets/docs/tree/page-template.doc.mjs +4 -8
  306. package/assets/docs/tree/problems.doc.mjs +205 -0
  307. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  308. package/assets/docs/tree/publishing.doc.mjs +6 -6
  309. package/assets/docs/tree/quick-start.doc.mjs +54 -28
  310. package/assets/docs/tree/reference.doc.mjs +192 -0
  311. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  312. package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
  313. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  314. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  315. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  316. package/assets/docs/tree/ship.doc.mjs +2 -2
  317. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  318. package/assets/docs/tree/single-component.doc.mjs +15 -6
  319. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  320. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  321. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  322. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  323. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  324. package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
  325. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  326. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  327. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  328. package/assets/docs/tree/templates.doc.mjs +7 -1
  329. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  330. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  331. package/assets/docs/tree/themes.doc.mjs +5 -1
  332. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  333. package/assets/docs/tree/tokens-data.doc.mjs +2 -2
  334. package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
  335. package/assets/docs/tree/type-scale.doc.mjs +3 -3
  336. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  337. package/assets/docs/tree/updates.doc.mjs +92 -0
  338. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  339. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +15 -3
  340. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  341. package/assets/docs/tree/versioning.doc.mjs +14 -9
  342. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  343. package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
  344. package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
  345. package/assets/docs/use-a-theme.doc.mjs +2 -2
  346. package/assets/docs/use-integrations.doc.mjs +120 -0
  347. package/assets/docs/working-with-ai.doc.mjs +70 -13
  348. package/assets/templates/themes/butter/butterTheme.ts +4 -2
  349. package/assets/templates/themes/stone/stoneTheme.ts +4 -2
  350. package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
  351. package/assets/theme.template.ts +1 -1
  352. package/authoring/codemod/codemod.doc.mjs +7 -3
  353. package/authoring/config/config.doc.mjs +9 -6
  354. package/authoring/config/type.ts +4 -2
  355. package/authoring/debug/parse.d.mts +5 -5
  356. package/authoring/discover/discover.doc.mjs +7 -1
  357. package/authoring/doctypes/_schema.d.mts +8 -3
  358. package/authoring/doctypes/_schema.mjs +1 -0
  359. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  360. package/authoring/doctypes/command/command.doc.mjs +20 -12
  361. package/authoring/doctypes/command/type.ts +14 -0
  362. package/authoring/doctypes/component/component.doc.mjs +30 -27
  363. package/authoring/doctypes/component/type.ts +21 -8
  364. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  365. package/authoring/doctypes/function/function.doc.mjs +9 -8
  366. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  367. package/authoring/doctypes/hook/type.ts +4 -0
  368. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  369. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  370. package/authoring/doctypes/schema/schema.doc.mjs +10 -10
  371. package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
  372. package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
  373. package/authoring/doctypes/template/parse.d.mts +6 -2
  374. package/authoring/doctypes/template/parse.mjs +3 -1
  375. package/authoring/doctypes/template/template.doc.mjs +3 -3
  376. package/authoring/doctypes/template/type.ts +22 -0
  377. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  378. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  379. package/authoring/identity/identity.doc.mjs +3 -3
  380. package/authoring/index.d.ts +2 -0
  381. package/authoring/integration/integration.doc.mjs +30 -6
  382. package/authoring/integration/parse.test.mjs +21 -0
  383. package/authoring/integration/schema.d.mts +16 -3
  384. package/authoring/integration/schema.mjs +34 -2
  385. package/authoring/integration/type.ts +13 -1
  386. package/clients/cli/bin/astryx.mjs +11 -65
  387. package/clients/cli/cli-command.test.mjs +166 -0
  388. package/clients/cli/command-result-coverage.test.mjs +6 -5
  389. package/clients/cli/commands/blog.doc.mjs +1 -0
  390. package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
  391. package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
  392. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  393. package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
  394. package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
  395. package/clients/cli/commands/build.doc.mjs +1 -0
  396. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  397. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  398. package/clients/cli/commands/component.doc.mjs +1 -0
  399. package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
  400. package/clients/cli/commands/component.test.mjs +6 -6
  401. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  402. package/clients/cli/commands/discover.doc.mjs +9 -1
  403. package/clients/cli/commands/discover.mjs +144 -93
  404. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  405. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  406. package/clients/cli/commands/docs.doc.mjs +3 -2
  407. package/clients/cli/commands/docs.mjs +50 -20
  408. package/clients/cli/commands/docs.test.mjs +16 -16
  409. package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
  410. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  411. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  412. package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
  413. package/clients/cli/commands/doctor-integration.test.mjs +936 -3
  414. package/clients/cli/commands/doctor.doc.mjs +12 -2
  415. package/clients/cli/commands/doctor.mjs +332 -7
  416. package/clients/cli/commands/doctor.test.mjs +75 -4
  417. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  418. package/clients/cli/commands/gap-report.mjs +24 -2
  419. package/clients/cli/commands/gap-report.test.mjs +79 -0
  420. package/clients/cli/commands/hook.doc.mjs +1 -0
  421. package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
  422. package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
  423. package/clients/cli/commands/init.behavior.test.mjs +235 -1
  424. package/clients/cli/commands/init.doc.mjs +55 -10
  425. package/clients/cli/commands/init.flag-help.test.mjs +1 -0
  426. package/clients/cli/commands/init.mjs +2 -2
  427. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  428. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  429. package/clients/cli/commands/integration-check.doc.mjs +93 -0
  430. package/clients/cli/commands/integration-check.test.mjs +489 -0
  431. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  432. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  433. package/clients/cli/commands/integration.doc.mjs +6 -2
  434. package/clients/cli/commands/integration.mjs +119 -7
  435. package/clients/cli/commands/json-contract.test.mjs +11 -2
  436. package/clients/cli/commands/manifest.doc.mjs +2 -1
  437. package/clients/cli/commands/manifest.mjs +67 -0
  438. package/clients/cli/commands/outside-project.test.mjs +874 -0
  439. package/clients/cli/commands/postinstall.doc.mjs +23 -0
  440. package/clients/cli/commands/postinstall.mjs +31 -0
  441. package/clients/cli/commands/search.doc.mjs +1 -0
  442. package/clients/cli/commands/search.mjs +16 -11
  443. package/clients/cli/commands/search.test.mjs +429 -296
  444. package/clients/cli/commands/setup-nudge.test.mjs +180 -2
  445. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  446. package/clients/cli/commands/swizzle.mjs +5 -3
  447. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  448. package/clients/cli/commands/template.doc.mjs +1 -0
  449. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  450. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  451. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  452. package/clients/cli/commands/theme-build.doc.mjs +3 -2
  453. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  454. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  455. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  456. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  457. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  458. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  459. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  460. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  461. package/clients/cli/commands/{build-theme.mjs → theme.mjs} +27 -14
  462. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  463. package/clients/cli/commands/upgrade.doc.mjs +26 -3
  464. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  465. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  466. package/clients/cli/commands/upgrade.mjs +9 -2
  467. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  468. package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
  469. package/clients/cli/index.mjs +156 -100
  470. package/clients/cli/lib/cli-error.mjs +4 -1
  471. package/clients/cli/lib/component-format.mjs +1 -1
  472. package/clients/cli/lib/component-format.test.mjs +1 -1
  473. package/clients/cli/lib/define-command.mjs +14 -9
  474. package/clients/cli/lib/exit-codes.test.mjs +5 -0
  475. package/clients/cli/lib/json-shim.mjs +3 -1
  476. package/clients/cli/lib/manifest.d.ts +9 -0
  477. package/clients/cli/lib/manifest.mjs +17 -1
  478. package/clients/cli/lib/manifest.test.mjs +37 -0
  479. package/clients/cli/lib/welcome-box.mjs +50 -0
  480. package/clients/cli/run.mjs +108 -0
  481. package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
  482. package/foundation/agent-docs/agent-doc-state.mjs +123 -14
  483. package/foundation/agent-docs/agent-docs.d.mts +104 -15
  484. package/foundation/agent-docs/agent-docs.mjs +1028 -114
  485. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
  486. package/foundation/agent-docs/agent-docs.test.mjs +683 -39
  487. package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
  488. package/foundation/agent-docs/computer-agent-text.mjs +750 -0
  489. package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
  490. package/foundation/config/project.d.mts +35 -3
  491. package/foundation/config/project.mjs +243 -26
  492. package/foundation/config/project.test.mjs +122 -0
  493. package/foundation/config/theme-state.mjs +5 -4
  494. package/foundation/discovery/authoring-self-docs.d.mts +7 -0
  495. package/foundation/discovery/authoring-self-docs.mjs +17 -4
  496. package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
  497. package/foundation/discovery/authoring-surface.d.mts +1 -1
  498. package/foundation/discovery/authoring-surface.mjs +2 -2
  499. package/foundation/discovery/authoring-surface.test.mjs +1 -1
  500. package/foundation/discovery/cli-self-docs.d.mts +2 -1
  501. package/foundation/discovery/cli-self-docs.mjs +22 -4
  502. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  503. package/foundation/discovery/component-discovery.d.mts +227 -10
  504. package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
  505. package/foundation/discovery/component-discovery.mjs +940 -57
  506. package/foundation/discovery/component-discovery.test.mjs +96 -0
  507. package/foundation/discovery/component-loader.d.mts +1 -1
  508. package/foundation/discovery/component-replacement.mjs +20 -1
  509. package/foundation/discovery/component-replacement.test.mjs +40 -0
  510. package/foundation/discovery/copied-passages.d.mts +216 -0
  511. package/foundation/discovery/copied-passages.mjs +720 -0
  512. package/foundation/discovery/copied-passages.test.mjs +124 -0
  513. package/foundation/discovery/doc-consistency.d.mts +34 -0
  514. package/foundation/discovery/doc-consistency.mjs +513 -0
  515. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  516. package/foundation/discovery/doc-fluff.d.mts +112 -0
  517. package/foundation/discovery/doc-fluff.mjs +328 -0
  518. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  519. package/foundation/discovery/doc-types.d.mts +157 -0
  520. package/foundation/discovery/doc-types.mjs +1231 -0
  521. package/foundation/discovery/doc-types.test.mjs +744 -0
  522. package/foundation/discovery/docs-discovery.d.mts +88 -0
  523. package/foundation/discovery/docs-discovery.mjs +97 -3
  524. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  525. package/foundation/discovery/integration-doc-files.mjs +231 -0
  526. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  527. package/foundation/discovery/module-exports.d.mts +68 -0
  528. package/foundation/discovery/module-exports.mjs +609 -31
  529. package/foundation/discovery/module-exports.test.mjs +172 -0
  530. package/foundation/discovery/package-tsconfig.d.mts +14 -0
  531. package/foundation/discovery/package-tsconfig.mjs +228 -0
  532. package/foundation/discovery/package-tsconfig.test.mjs +210 -0
  533. package/foundation/discovery/project-typescript.d.mts +32 -0
  534. package/foundation/discovery/project-typescript.mjs +89 -0
  535. package/foundation/discovery/prop-drift.d.mts +297 -0
  536. package/foundation/discovery/prop-drift.mjs +2428 -0
  537. package/foundation/discovery/prop-drift.test.mjs +2337 -0
  538. package/foundation/discovery/runner-allowlist.d.mts +38 -0
  539. package/foundation/discovery/runner-allowlist.mjs +51 -0
  540. package/foundation/discovery/runner-commands.d.mts +77 -0
  541. package/foundation/discovery/runner-commands.mjs +294 -0
  542. package/foundation/discovery/runner-commands.test.mjs +128 -0
  543. package/foundation/discovery/stray-pointers.d.mts +52 -0
  544. package/foundation/discovery/stray-pointers.mjs +293 -0
  545. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  546. package/foundation/discovery/template-adapter.mjs +92 -6
  547. package/foundation/discovery/template-needs.mjs +6 -46
  548. package/foundation/discovery/theme-discovery.mjs +147 -3
  549. package/foundation/discovery/theme-imports.mjs +8 -4
  550. package/foundation/discovery/theme-imports.test.mjs +1 -1
  551. package/foundation/discovery/type-match.d.mts +53 -0
  552. package/foundation/discovery/type-match.mjs +660 -0
  553. package/foundation/discovery/type-match.test.mjs +169 -0
  554. package/foundation/discovery/type-text.d.mts +68 -0
  555. package/foundation/discovery/type-text.mjs +658 -0
  556. package/foundation/discovery/type-text.test.mjs +196 -0
  557. package/foundation/discovery/unresolved-references.d.mts +62 -0
  558. package/foundation/discovery/unresolved-references.mjs +790 -0
  559. package/foundation/discovery/unresolved-references.test.mjs +567 -0
  560. package/foundation/doc-compiler/doc-loads.test.mjs +84 -10
  561. package/foundation/doc-compiler/inputs.mjs +27 -1
  562. package/foundation/doc-compiler/inputs.test.mjs +0 -1
  563. package/foundation/doc-compiler/links.d.mts +41 -5
  564. package/foundation/doc-compiler/links.mjs +167 -28
  565. package/foundation/doc-compiler/links.test.mjs +97 -4
  566. package/foundation/doc-compiler/read.d.mts +1 -1
  567. package/foundation/doc-compiler/read.mjs +59 -1
  568. package/foundation/doc-compiler/read.test.mjs +11 -2
  569. package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
  570. package/foundation/doc-compiler/tree.d.mts +32 -6
  571. package/foundation/doc-compiler/tree.mjs +107 -44
  572. package/foundation/doc-compiler/tree.test.mjs +14 -7
  573. package/foundation/env/cli-command.d.mts +83 -0
  574. package/foundation/env/cli-command.mjs +152 -0
  575. package/foundation/env/cli-command.test.mjs +129 -0
  576. package/foundation/env/node-version.test.mjs +15 -3
  577. package/foundation/env/package-manager.d.mts +93 -9
  578. package/foundation/env/package-manager.global.test.mjs +66 -0
  579. package/foundation/env/package-manager.mjs +184 -13
  580. package/foundation/env/package-manager.test.mjs +341 -15
  581. package/foundation/env/project-scope.d.mts +9 -0
  582. package/foundation/env/project-scope.mjs +33 -0
  583. package/foundation/env/search-path.d.mts +42 -0
  584. package/foundation/env/search-path.mjs +205 -0
  585. package/foundation/env/search-path.test.mjs +122 -0
  586. package/foundation/env/user-dirs.d.mts +39 -0
  587. package/foundation/env/user-dirs.mjs +93 -0
  588. package/foundation/env/user-dirs.test.mjs +72 -0
  589. package/foundation/env/user-settings.d.mts +46 -0
  590. package/foundation/env/user-settings.mjs +106 -0
  591. package/foundation/env/user-settings.test.mjs +64 -0
  592. package/foundation/fs/file-protection.mjs +15 -1
  593. package/foundation/fs/module-loader.d.mts +2 -1
  594. package/foundation/fs/module-loader.mjs +60 -4
  595. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  596. package/foundation/fs/module-loader.test.mjs +194 -0
  597. package/foundation/fs/path-compare.d.mts +33 -0
  598. package/foundation/fs/path-compare.mjs +73 -0
  599. package/foundation/fs/paths.d.mts +122 -4
  600. package/foundation/fs/paths.mjs +675 -29
  601. package/foundation/fs/paths.test.mjs +439 -54
  602. package/foundation/fs/read-record.d.mts +18 -0
  603. package/foundation/fs/read-record.mjs +131 -0
  604. package/foundation/fs/read-record.test.mjs +77 -0
  605. package/foundation/integrations/autolink.d.mts +2 -1
  606. package/foundation/integrations/autolink.mjs +4 -13
  607. package/foundation/integrations/cli-peer-version.d.mts +36 -0
  608. package/foundation/integrations/cli-peer-version.mjs +132 -0
  609. package/foundation/integrations/cli-peer-version.test.mjs +354 -0
  610. package/foundation/integrations/computer-integrations.d.mts +81 -0
  611. package/foundation/integrations/computer-integrations.mjs +345 -0
  612. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  613. package/foundation/integrations/contribution-inventory.d.mts +26 -20
  614. package/foundation/integrations/contribution-inventory.mjs +97 -8
  615. package/foundation/integrations/exports-subpaths.d.mts +57 -0
  616. package/foundation/integrations/exports-subpaths.mjs +113 -0
  617. package/foundation/integrations/integration-warnings.mjs +3 -2
  618. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  619. package/foundation/integrations/integrations.d.mts +51 -1
  620. package/foundation/integrations/integrations.mjs +106 -4
  621. package/foundation/integrations/issue.ts +6 -0
  622. package/foundation/integrations/public-imports.d.mts +118 -0
  623. package/foundation/integrations/public-imports.mjs +1769 -0
  624. package/foundation/integrations/public-imports.test.mjs +1793 -0
  625. package/foundation/integrations/validate-contributions.d.mts +117 -0
  626. package/foundation/integrations/validate-contributions.mjs +1209 -14
  627. package/foundation/release/agent-text-worker.d.mts +4 -0
  628. package/foundation/release/agent-text-worker.mjs +52 -0
  629. package/foundation/release/cache.d.mts +310 -0
  630. package/foundation/release/cache.mjs +1216 -0
  631. package/foundation/release/cache.test.mjs +923 -0
  632. package/foundation/release/choose.d.mts +207 -0
  633. package/foundation/release/choose.mjs +677 -0
  634. package/foundation/release/choose.test.mjs +427 -0
  635. package/foundation/release/core-worker.d.mts +4 -0
  636. package/foundation/release/core-worker.mjs +38 -0
  637. package/foundation/release/global-state.d.mts +263 -0
  638. package/foundation/release/global-state.mjs +474 -0
  639. package/foundation/release/global-state.test.mjs +381 -0
  640. package/foundation/release/handoff.d.mts +79 -0
  641. package/foundation/release/handoff.e2e.test.mjs +278 -0
  642. package/foundation/release/handoff.mjs +524 -0
  643. package/foundation/release/lock-lease.d.mts +23 -0
  644. package/foundation/release/lock-lease.mjs +80 -0
  645. package/foundation/release/notices.d.mts +307 -0
  646. package/foundation/release/notices.mjs +707 -0
  647. package/foundation/release/notices.test.mjs +586 -0
  648. package/foundation/release/npm-guard.d.mts +4 -0
  649. package/foundation/release/npm-guard.mjs +126 -0
  650. package/foundation/release/project.d.mts +141 -0
  651. package/foundation/release/project.mjs +466 -0
  652. package/foundation/release/project.test.mjs +288 -0
  653. package/foundation/release/refresh-worker.d.mts +4 -0
  654. package/foundation/release/refresh-worker.mjs +27 -0
  655. package/foundation/release/run-context.d.mts +47 -0
  656. package/foundation/release/run-context.mjs +163 -0
  657. package/foundation/release/update-notice-env.d.mts +28 -0
  658. package/foundation/release/update-notice-env.mjs +39 -0
  659. package/foundation/response/base.d.ts +26 -3
  660. package/foundation/response/error-codes.d.mts +3 -1
  661. package/foundation/response/error-codes.doc.mjs +12 -0
  662. package/foundation/response/error-codes.mjs +17 -0
  663. package/foundation/response/error-codes.test.mjs +2 -0
  664. package/foundation/response/json-contract.test.mjs +7 -2
  665. package/foundation/response/json.mjs +4 -1
  666. package/foundation/response/response-types.doc.mjs +22 -11
  667. package/foundation/response/response-types.doc.test.mjs +46 -0
  668. package/foundation/response/response.doc.mjs +3 -3
  669. package/foundation/route/route.d.mts +285 -0
  670. package/foundation/route/route.mjs +324 -0
  671. package/foundation/route/route.test.mjs +153 -0
  672. package/foundation/runtime/hosted-runtime.test.mjs +403 -0
  673. package/foundation/runtime/locked-versions.d.mts +32 -0
  674. package/foundation/runtime/locked-versions.mjs +65 -0
  675. package/foundation/runtime/package-root.d.mts +91 -0
  676. package/foundation/runtime/package-root.mjs +174 -0
  677. package/foundation/runtime/package-set.d.mts +62 -0
  678. package/foundation/runtime/package-set.mjs +130 -0
  679. package/foundation/runtime/package-set.test.mjs +432 -0
  680. package/foundation/text/string-utils.d.mts +2 -1
  681. package/foundation/text/string-utils.mjs +16 -5
  682. package/foundation/text/suggest-order.d.mts +72 -0
  683. package/foundation/text/suggest-order.mjs +363 -0
  684. package/foundation/text/suggest-order.test.mjs +259 -0
  685. package/foundation/xle/browser-imports.test.mjs +74 -0
  686. package/foundation/xle/registry.mjs +4 -0
  687. package/foundation/xle/registry.test.mjs +28 -0
  688. package/host/door-conformance.test.mjs +274 -0
  689. package/host/index.d.ts +116 -0
  690. package/host/index.mjs +295 -0
  691. package/host/index.test.mjs +302 -0
  692. package/package.json +16 -11
  693. package/scripts/postinstall.mjs +24 -5
  694. package/assets/docs/tree/integrations.doc.mjs +0 -40
@@ -0,0 +1,524 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The first thing every run does: choose the release that answers and,
5
+ * when it is not this copy, hand the run to it (spec AST-081 FR2, FR6, FR9).
6
+ *
7
+ * Runs in the bin right after the Node version gate, before the CLI loads
8
+ * the folder's `astryx.config`, its integrations, or its Core. A hand-off
9
+ * starts the chosen CLI with exactly this run's arguments, working folder, and
10
+ * standard streams, adds nothing to its environment, options, or
11
+ * configuration, and ends this process with that CLI's exit status. The
12
+ * chosen copy makes the same choice and finds itself, so a run is handed off
13
+ * at most once.
14
+ *
15
+ * In text mode a run that a copy other than the project's own CLI answers
16
+ * prints one line on standard error naming the CLI and Core that answered; a
17
+ * run with `--json` prints none and carries `meta.answeredBy` instead. After a
18
+ * successful command, the copy that started the run prints any update notice
19
+ * (notices.mjs); a global copy also starts the daily update check, which
20
+ * installs nothing (global-state.mjs).
21
+ *
22
+ * A programmatic host that found the project's own CLI and did not run it
23
+ * passes the reason (spec AST-081 FR1, FR2). That run is never handed to the
24
+ * project's CLI: this copy answers in its place when it is that CLI's release,
25
+ * saying so in a line of its own; a package set of the host's whose CLI is
26
+ * that release answers through its own host entry; and otherwise this copy
27
+ * answers as for a release that cannot be obtained, with the warning naming
28
+ * the reason.
29
+ *
30
+ * A hosted run installs nothing (architecture:cli-surface INV30): a release
31
+ * other than this copy comes only from the first of the host's package sets
32
+ * that qualifies. When that CLI ships a host entry, the entry runs in this
33
+ * process with the same inputs, discover sources included, and the host's
34
+ * call settles with its result; otherwise its bin takes the run. With no such
35
+ * set, this copy answers, announced.
36
+ *
37
+ * @input the running copy, argv, the working folder, and a host's
38
+ * declined-project-CLI reason
39
+ * @output returns when this copy answers, or with another release's result
40
+ * when its host entry answered; never returns after a hand-off to a bin
41
+ * @position foundation/release — called once per run by clients/cli/run.mjs.
42
+ */
43
+
44
+ import {spawn} from 'node:child_process';
45
+ import {writeSync} from 'node:fs';
46
+ import {
47
+ chooseRelease,
48
+ isComputerLevel,
49
+ isGlobalCopy,
50
+ namesWhoAnswered,
51
+ packageRootOf,
52
+ projectRootOf,
53
+ runningCopy,
54
+ } from './choose.mjs';
55
+ import {readReleaseFacts} from './project.mjs';
56
+ import {ensureRelease, userCacheDir} from './cache.mjs';
57
+ import {
58
+ maybeFetchCore,
59
+ maybeKeepAgentText,
60
+ maybeStartCheck,
61
+ } from './global-state.mjs';
62
+ import {recordRunChoice} from './run-context.mjs';
63
+ import {noticeLines} from './notices.mjs';
64
+ import {cliDoor, runWithCliDoor} from '../env/cli-command.mjs';
65
+ import {hostedRun} from '../runtime/package-root.mjs';
66
+ import {qualifyingRoot} from '../runtime/package-set.mjs';
67
+
68
+ /** Where each release's notes are published. */
69
+
70
+ /**
71
+ * The who-answered line for a run a copy other than the project's own CLI
72
+ * answers.
73
+ * @param {import('./choose.mjs').ReleaseChoice} choice
74
+ * @param {boolean} [computer] the command acts on the computer, not the folder
75
+ * @returns {string}
76
+ */
77
+ export function whoAnsweredLine(choice, computer = false) {
78
+ const core = choice.coreVersion ?? choice.version;
79
+ if (computer) {
80
+ return `astryx: answered by CLI ${choice.version} with Core ${core}, for this computer`;
81
+ }
82
+ return choice.copy === 'matched'
83
+ ? `astryx: answered by CLI ${choice.version} with Core ${core}, the release that matches this project's Core`
84
+ : `astryx: answered by CLI ${choice.version} with Core ${core}, outside a project`;
85
+ }
86
+
87
+ /**
88
+ * The line for a run this copy answers in place of the project's own CLI,
89
+ * which a host declined, when this copy is that CLI's release (FR2).
90
+ * @param {string} version
91
+ * @param {string} reason the reason, as {@link declinedReasonText} words it
92
+ * @returns {string}
93
+ */
94
+ export function inPlaceOfProjectLine(version, reason) {
95
+ return `astryx: answered by CLI ${version}, the release of this project's CLI, in its place (${reason})`;
96
+ }
97
+
98
+ /**
99
+ * The line for a run handed to the project's own CLI.
100
+ * @param {string} projectVersion
101
+ * @param {string} startedIn the version of the copy the run started in
102
+ * @returns {string}
103
+ */
104
+ export function handedToProjectLine(projectVersion, startedIn) {
105
+ return `astryx: answered by this project's CLI ${projectVersion}, handed over from CLI ${startedIn}`;
106
+ }
107
+
108
+ /**
109
+ * One line on standard error while a release installs, so a slow download
110
+ * never looks like a hang. Text mode only.
111
+ * @param {'install' | 'wait'} event
112
+ * @param {string} version
113
+ */
114
+ export function progressLine(event, version) {
115
+ console.error(progressText(event, version));
116
+ }
117
+
118
+ /**
119
+ * The text of {@link progressLine}.
120
+ * @param {'install' | 'wait'} event
121
+ * @param {string} version
122
+ * @returns {string}
123
+ */
124
+ export function progressText(event, version) {
125
+ return event === 'install'
126
+ ? `astryx: installing CLI release ${version} into the per-user cache (once)...`
127
+ : `astryx: waiting for another run to finish installing CLI release ${version}...`;
128
+ }
129
+
130
+ /**
131
+ * The warning a run prints, in text mode, when the release that matches the
132
+ * project's Core cannot be obtained and the copy that answered before global
133
+ * mode answers instead (spec AST-081 FR2).
134
+ * @param {string} wanted the matched release, or the range it was read from
135
+ * @param {string} reason why it cannot be obtained
136
+ * @param {string} answering the version that answers instead
137
+ * @returns {string}
138
+ */
139
+ export function fallbackLine(wanted, reason, answering) {
140
+ return `astryx: could not get Astryx ${wanted} to match this project's Core (${reason}); answering with CLI ${answering} instead`;
141
+ }
142
+
143
+ /**
144
+ * Fail the run before any command starts, in the shape every command fails
145
+ * in: the JSON error envelope on stdout with `--json`, else `Error: …` on
146
+ * standard error. Exit status 1.
147
+ * @param {string} message
148
+ * @param {boolean} json
149
+ * @returns {never}
150
+ */
151
+ function failUnavailable(message, json) {
152
+ if (json) {
153
+ process.stdout.write(
154
+ `${JSON.stringify(
155
+ {apiVersion: 1, error: message, code: 'ERR_VERSIONS_UNAVAILABLE'},
156
+ null,
157
+ 2,
158
+ )}\n`,
159
+ );
160
+ } else {
161
+ console.error(`Error: ${message}`);
162
+ }
163
+ process.exit(1);
164
+ }
165
+
166
+ /**
167
+ * The fallback warning's reason for a project CLI a host declined.
168
+ * @param {string} reason the host's own words
169
+ * @returns {string}
170
+ */
171
+ export function declinedReasonText(reason) {
172
+ return `project CLI skipped: ${reason}`;
173
+ }
174
+
175
+ /**
176
+ * Choose who answers and hand off when it is not this copy.
177
+ * @param {{cliRoot: string, argv: string[], declinedProjectCli?: string}} input
178
+ * argv after `node astryx`; the reason a programmatic host declined the
179
+ * project's own CLI, when it did
180
+ * @returns {Promise<import('../../host/index.js').HostedCliResult | undefined>}
181
+ * resolves with nothing when this copy answers, and with that release's
182
+ * result when another package set's host entry answered a hosted run
183
+ */
184
+ export async function startRun({cliRoot, argv, declinedProjectCli}) {
185
+ const json = argv.includes('--json');
186
+ const self = runningCopy(cliRoot);
187
+ const cacheDir = userCacheDir();
188
+ // A host carries its own CLI and keeps it current itself: a hosted copy
189
+ // runs none of the global copy's background work, and installs nothing.
190
+ const hosted = hostedRun();
191
+ const global = !hosted && isGlobalCopy(cliRoot, cacheDir);
192
+ if (global) {
193
+ try {
194
+ maybeStartCheck();
195
+ } catch {
196
+ // A check that cannot start never fails a run.
197
+ }
198
+ try {
199
+ // The global copy keeps the computer-level agent text on its own
200
+ // release's text, so it follows each upgrade of the copy (FR8).
201
+ maybeKeepAgentText({release: self});
202
+ } catch {
203
+ // Nor does the agent text.
204
+ }
205
+ // And its own Core, so component reads work offline outside a project
206
+ // after one online run (FR3). Started as the run ends, so it never takes
207
+ // the install lock from this run's own Core read, nor holds anything the
208
+ // command's caller waits on while the command runs.
209
+ process.once('exit', () => {
210
+ try {
211
+ maybeFetchCore({release: self, cacheDir});
212
+ } catch {
213
+ // Nor does the Core download.
214
+ }
215
+ });
216
+ }
217
+
218
+ const computer = isComputerLevel(argv);
219
+ /** @type {import('./choose.mjs').ReleaseChoice} */
220
+ let choice;
221
+ try {
222
+ choice = chooseRelease({
223
+ cwd: process.cwd(),
224
+ self,
225
+ cacheDir,
226
+ computer,
227
+ });
228
+ } catch {
229
+ choice = {
230
+ copy: 'carried',
231
+ answer: 'self',
232
+ version: self.version,
233
+ bin: null,
234
+ coreVersion: null,
235
+ inProject: false,
236
+ unavailable: null,
237
+ };
238
+ }
239
+
240
+ // A host declined the project's own CLI (FR2): the run is never handed to
241
+ // it. The release equal to that CLI's version answers in its place when
242
+ // this copy is that release, or when a package set of the host's holds it
243
+ // with a host entry; otherwise this copy answers, announced as for a release
244
+ // that cannot be obtained, naming the reason.
245
+ let declined = null;
246
+ /** Set when this copy answers in place of the declined CLI, its release. */
247
+ let inPlace = null;
248
+ if (
249
+ declinedProjectCli &&
250
+ choice.copy === 'project' &&
251
+ choice.answer !== 'self'
252
+ ) {
253
+ if (choice.version === self.version) {
254
+ // Still the project CLI's release (`copy` stays `project`), never the
255
+ // release matched to the project's Core, which can be another.
256
+ choice = {...choice, answer: 'self', bin: null, unavailable: null};
257
+ inPlace = declinedReasonText(declinedProjectCli);
258
+ } else {
259
+ const served = hosted
260
+ ? qualifyingRoot({
261
+ release: choice.version,
262
+ projectDir: projectDirOf(process.cwd()),
263
+ roots: hosted.roots,
264
+ needsHostEntry: true,
265
+ })
266
+ : null;
267
+ if (served && 'root' in served && served.hostEntry) {
268
+ const answered = await answerInPackageSet(
269
+ served.hostEntry,
270
+ served.root,
271
+ {argv, declinedProjectCli},
272
+ );
273
+ if (answered) return answered;
274
+ }
275
+ declined = declinedReasonText(declinedProjectCli);
276
+ }
277
+ }
278
+
279
+ if (!declined && choice.unavailable && choice.copy === 'project') {
280
+ failUnavailable(
281
+ `This project's CLI ${choice.version} could not be started: ${choice.unavailable}. Reinstall the project's dependencies.`,
282
+ json,
283
+ );
284
+ }
285
+
286
+ // A host's door holds only inside the call that set it; notices print as
287
+ // the process exits, outside it, so the door this run started under is
288
+ // kept and set again for them (FR5).
289
+ const door = cliDoor();
290
+ /** FR10: after a successful command, at most once a day per notice. */
291
+ const notify = () => {
292
+ const print = () => {
293
+ for (const line of noticeLines({
294
+ cwd: process.cwd(),
295
+ self,
296
+ choice: computer ? {...choice, inProject: false} : choice,
297
+ json,
298
+ cacheDir,
299
+ })) {
300
+ // Synchronous: the process is exiting.
301
+ writeSync(2, `${line}\n`);
302
+ }
303
+ };
304
+ try {
305
+ if (door) runWithCliDoor(door, print);
306
+ else print();
307
+ } catch {
308
+ // A notice never fails a run.
309
+ }
310
+ };
311
+ /**
312
+ * The matched release cannot be obtained: the copy that started the run
313
+ * answers instead, as before global mode, announced (FR2).
314
+ * @param {string} reason
315
+ * @returns {Promise<void>}
316
+ */
317
+ const fallBack = async reason => {
318
+ recordRunChoice({
319
+ ...choice,
320
+ copy: 'fallback',
321
+ answer: 'self',
322
+ version: self.version,
323
+ bin: null,
324
+ coreVersion: null,
325
+ unavailable: null,
326
+ });
327
+ if (!json) {
328
+ console.error(fallbackLine(choice.version, reason, self.version));
329
+ }
330
+ process.once('exit', code => {
331
+ if (code === 0) notify();
332
+ });
333
+ };
334
+
335
+ if (declined) {
336
+ await fallBack(declined);
337
+ return;
338
+ }
339
+
340
+ if (choice.unavailable) {
341
+ await fallBack(choice.unavailable);
342
+ return;
343
+ }
344
+
345
+ if (choice.answer === 'self') {
346
+ recordRunChoice(choice);
347
+ // A project with no CLI of its own is answered as released, with no
348
+ // line; a hint after the command, once a day, says how to match it.
349
+ if (!json && (choice.copy === 'matched' || choice.copy === 'carried'))
350
+ console.error(whoAnsweredLine(choice, computer));
351
+ else if (!json && inPlace)
352
+ console.error(inPlaceOfProjectLine(choice.version, inPlace));
353
+ process.once('exit', code => {
354
+ if (code === 0) notify();
355
+ });
356
+ return;
357
+ }
358
+
359
+ let bin = choice.bin;
360
+ if (!bin && hosted) {
361
+ const served = qualifyingRoot({
362
+ release: choice.version,
363
+ projectDir: projectDirOf(process.cwd()),
364
+ roots: hosted.roots,
365
+ });
366
+ if (!('root' in served)) {
367
+ await fallBack(served.reason);
368
+ return;
369
+ }
370
+ if (served.hostEntry) {
371
+ const answered = await answerInPackageSet(served.hostEntry, served.root, {
372
+ argv,
373
+ });
374
+ if (answered) return answered;
375
+ }
376
+ // A hosted run installs nothing (INV30): a set whose CLI starts through
377
+ // neither its host entry nor a bin leaves this copy to answer.
378
+ if (!served.bin) {
379
+ await fallBack(
380
+ `the CLI ${choice.version} in the package set at ${served.root} could not be started`,
381
+ );
382
+ return;
383
+ }
384
+ bin = served.bin;
385
+ }
386
+ if (!bin) {
387
+ const release = ensureRelease(choice.version, {
388
+ cacheDir,
389
+ onProgress: json ? undefined : progressLine,
390
+ });
391
+ if (!('bin' in release)) {
392
+ await fallBack(release.reason);
393
+ return;
394
+ }
395
+ bin = release.bin;
396
+ }
397
+
398
+ if (!json) {
399
+ if (choice.copy === 'project') {
400
+ console.error(handedToProjectLine(choice.version, self.version));
401
+ } else if (!namesWhoAnswered(packageRootOf(bin))) {
402
+ console.error(whoAnsweredLine(choice, computer));
403
+ }
404
+ }
405
+
406
+ await handOff(bin, argv, choice, json, notify);
407
+ }
408
+
409
+ /**
410
+ * How long a hand-off waits after an interrupt before passing it on to a CLI
411
+ * that is still running. An interrupt sent to the whole process group (a
412
+ * terminal's Ctrl-C, a process manager) already reached that CLI, and one that
413
+ * stops within this time is never interrupted twice; one sent to this process
414
+ * alone (an agent's `kill('SIGINT')`) stops the run once it is passed on.
415
+ */
416
+ export const INTERRUPT_GRACE_MS = 5000;
417
+
418
+ /**
419
+ * The project folder a run in `cwd` belongs to, or null outside a project.
420
+ * @param {string} cwd
421
+ * @returns {string | null}
422
+ */
423
+ function projectDirOf(cwd) {
424
+ try {
425
+ return projectRootOf(readReleaseFacts(cwd));
426
+ } catch {
427
+ return null;
428
+ }
429
+ }
430
+
431
+ /**
432
+ * Hand a hosted run over to the CLI of one of the host's package sets,
433
+ * through that CLI's own host entry, in this process, with the inputs this run
434
+ * got: the arguments, the folder, the command name, the approved integrations,
435
+ * the discover sources, and the reason the host declined the project's CLI.
436
+ * Its roots are that package set alone. That CLI prints its own who-answered
437
+ * line and notices, and the host's call settles with its result.
438
+ * @param {string} hostEntry the package set's `host/index.mjs`
439
+ * @param {string} root the package set
440
+ * @param {{argv: string[], declinedProjectCli?: string}} run
441
+ * @returns {Promise<import('../../host/index.js').HostedCliResult | null>} null
442
+ * when the entry cannot be loaded, before anything ran
443
+ */
444
+ async function answerInPackageSet(hostEntry, root, {argv, declinedProjectCli}) {
445
+ const hosted = hostedRun();
446
+ if (!hosted?.loadHostEntry) return null;
447
+ let answer;
448
+ try {
449
+ answer = await hosted.loadHostEntry(hostEntry);
450
+ } catch {
451
+ return null;
452
+ }
453
+ const door = cliDoor();
454
+ return answer({
455
+ argv,
456
+ cwd: process.cwd(),
457
+ roots: [root],
458
+ integrations: [...hosted.integrations],
459
+ discoverSources: [...hosted.discoverSources],
460
+ ...(door ? {cliCommand: door} : {}),
461
+ ...(declinedProjectCli ? {declinedProjectCli} : {}),
462
+ });
463
+ }
464
+
465
+ /**
466
+ * Run `bin` as this run and end with its exit status.
467
+ * @param {string} bin
468
+ * @param {string[]} argv
469
+ * @param {import('./choose.mjs').ReleaseChoice} choice
470
+ * @param {boolean} json
471
+ * @param {() => void} [notify] prints update notices after a successful run
472
+ * @returns {Promise<never>}
473
+ */
474
+ function handOff(bin, argv, choice, json, notify = () => {}) {
475
+ return new Promise(() => {
476
+ const child = spawn(process.execPath, [bin, ...argv], {
477
+ stdio: 'inherit',
478
+ windowsHide: false,
479
+ });
480
+ /** @param {NodeJS.Signals} signal */
481
+ const forward = signal => {
482
+ try {
483
+ child.kill(signal);
484
+ } catch {
485
+ // The child is already gone.
486
+ }
487
+ };
488
+ const running = () => child.exitCode === null && child.signalCode === null;
489
+ // An interrupt is passed on only to a CLI still running after the grace
490
+ // (see INTERRUPT_GRACE_MS): one sent to this process alone then stops the
491
+ // run, and one the whole process group got is not delivered twice to a CLI
492
+ // that stops in time. On Windows, Ctrl-C reaches every process in the
493
+ // console and a forwarded SIGINT would end the child abruptly, so this
494
+ // process only outlives it.
495
+ const onInterrupt = () => {
496
+ if (process.platform === 'win32' || !running()) return;
497
+ setTimeout(() => {
498
+ if (running()) forward('SIGINT');
499
+ }, INTERRUPT_GRACE_MS).unref();
500
+ };
501
+ process.on('SIGINT', onInterrupt);
502
+ process.on('SIGTERM', forward);
503
+ process.on('SIGHUP', forward);
504
+ child.on('error', error => {
505
+ failUnavailable(
506
+ choice.copy === 'project'
507
+ ? `This project's CLI ${choice.version} could not be started: ${error.message}. Reinstall the project's dependencies.`
508
+ : `CLI release ${choice.version} could not be started: ${error.message}.`,
509
+ json,
510
+ );
511
+ });
512
+ child.on('exit', (code, signal) => {
513
+ process.off('SIGINT', onInterrupt);
514
+ process.off('SIGTERM', forward);
515
+ process.off('SIGHUP', forward);
516
+ if (signal) {
517
+ process.kill(process.pid, signal);
518
+ return;
519
+ }
520
+ if (code === 0) notify();
521
+ process.exit(code ?? 1);
522
+ });
523
+ });
524
+ }
@@ -0,0 +1,23 @@
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
+ * Renew the holder's record: the same process and computer, with a counter
6
+ * that changes on every renewal. Never throws.
7
+ * @param {string} lockDir
8
+ */
9
+ export function renewLock(lockDir: string): void;
10
+ /**
11
+ * Whether a lock held from another computer has gone silent: its record has
12
+ * not changed for `LEASE_SILENCE_MS` of this process's own observation.
13
+ * @param {string} lockDir
14
+ * @param {number} [now]
15
+ * @returns {boolean}
16
+ */
17
+ export function foreignLockIsSilent(lockDir: string, now?: number): boolean;
18
+ /** Forget what this process observed (tests). */
19
+ export function forgetObservedLocks(): void;
20
+ /** How often the holder renews its record while the package manager works. */
21
+ export const LEASE_RENEW_MS: 10000;
22
+ /** How long a record from another computer may go unrenewed, as observed. */
23
+ export const LEASE_SILENCE_MS: 60000;
@@ -0,0 +1,80 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The lease on a release install's lock in the per-user cache (spec
5
+ * AST-081 FR11).
6
+ *
7
+ * A lock folder records its holder in `owner.json`: the process id and the
8
+ * computer's name. On the same computer a waiting run checks whether that
9
+ * process still runs. A cache shared between computers cannot check another
10
+ * computer's processes, so the holder renews its record every
11
+ * `LEASE_RENEW_MS` while the package manager works, and a waiting run takes
12
+ * a lock from another computer over once it has seen the record go unrenewed
13
+ * for `LEASE_SILENCE_MS`. The waiting run judges by change it observes, never
14
+ * by comparing clocks, so computers whose clocks differ agree.
15
+ *
16
+ * @input the lock folder
17
+ * @output the renewed record, and whether a foreign record has gone silent
18
+ * @position foundation/release — renewed by npm-guard.mjs, read by cache.mjs.
19
+ */
20
+
21
+ import * as fs from 'node:fs';
22
+ import * as path from 'node:path';
23
+
24
+ /** How often the holder renews its record while the package manager works. */
25
+ export const LEASE_RENEW_MS = 10_000;
26
+
27
+ /** How long a record from another computer may go unrenewed, as observed. */
28
+ export const LEASE_SILENCE_MS = 60_000;
29
+
30
+ /**
31
+ * Renew the holder's record: the same process and computer, with a counter
32
+ * that changes on every renewal. Never throws.
33
+ * @param {string} lockDir
34
+ */
35
+ export function renewLock(lockDir) {
36
+ const file = path.join(lockDir, 'owner.json');
37
+ try {
38
+ const owner = JSON.parse(fs.readFileSync(file, 'utf-8'));
39
+ const next = {...owner, beat: (Number(owner.beat) || 0) + 1};
40
+ const tmp = `${file}.${process.pid}.tmp`;
41
+ fs.writeFileSync(tmp, JSON.stringify(next));
42
+ fs.renameSync(tmp, file);
43
+ } catch {
44
+ // A lock that was taken over or removed has no record to renew.
45
+ }
46
+ }
47
+
48
+ /**
49
+ * What this process last saw of each foreign lock: the record's text and
50
+ * when that text was first seen.
51
+ * @type {Map<string, {text: string, since: number}>}
52
+ */
53
+ const observed = new Map();
54
+
55
+ /**
56
+ * Whether a lock held from another computer has gone silent: its record has
57
+ * not changed for `LEASE_SILENCE_MS` of this process's own observation.
58
+ * @param {string} lockDir
59
+ * @param {number} [now]
60
+ * @returns {boolean}
61
+ */
62
+ export function foreignLockIsSilent(lockDir, now = Date.now()) {
63
+ let text;
64
+ try {
65
+ text = fs.readFileSync(path.join(lockDir, 'owner.json'), 'utf-8');
66
+ } catch {
67
+ text = '';
68
+ }
69
+ const seen = observed.get(lockDir);
70
+ if (!seen || seen.text !== text) {
71
+ observed.set(lockDir, {text, since: now});
72
+ return false;
73
+ }
74
+ return now - seen.since >= LEASE_SILENCE_MS;
75
+ }
76
+
77
+ /** Forget what this process observed (tests). */
78
+ export function forgetObservedLocks() {
79
+ observed.clear();
80
+ }