@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
@@ -7,9 +7,11 @@
7
7
  * on failure. Progress is emitted through the shared `logger` (silent by default).
8
8
  *
9
9
  * @param {import('../_adapter.mjs').UpgradeOptions} [options]
10
- * @param {{cwd?: string}} [ctx]
10
+ * @param {{cwd?: string, origin?: string}} [ctx] `origin` is the folder the
11
+ * command ran in, when `cwd` is the project root above it
11
12
  * @returns {Promise<import('../upgrade.type.mjs').UpgradeStatusResponse | import('../upgrade.type.mjs').UpgradeRunResponse>}
12
13
  */
13
- export function run(options?: import("../_adapter.mjs").UpgradeOptions, { cwd }?: {
14
+ export function run(options?: import("../_adapter.mjs").UpgradeOptions, { cwd, origin }?: {
14
15
  cwd?: string;
16
+ origin?: string;
15
17
  }): Promise<import("../upgrade.type.mjs").UpgradeStatusResponse | import("../upgrade.type.mjs").UpgradeRunResponse>;
@@ -15,12 +15,18 @@
15
15
  * ShadCN-copied compositions → post-codemod hooks → render + refresh agent docs
16
16
  * from final post-upgrade state. Integration DISCOVERY errors skip that
17
17
  * integration; execution errors abort before the agent-doc write.
18
+ *
19
+ * Core codemods ship inside the CLI, so a CLI older than the installed Core
20
+ * has none for the releases after its own version. Every result past the
21
+ * up-to-date exit then carries `cliBehindCore`, and no human line says the
22
+ * upgrade finished; the warning names the same upgrade on the matching CLI.
18
23
  */
19
24
 
20
25
  import * as fs from 'node:fs';
21
26
  import * as path from 'node:path';
22
27
  import {
23
28
  detectInstalledTargetVersion,
29
+ detectCliBehindCore,
24
30
  prepareAgentDocsRefresh,
25
31
  applyAgentDocsRefresh,
26
32
  inspectAgentDocs,
@@ -42,9 +48,11 @@ import {
42
48
  statusUpToDate,
43
49
  statusNoCodemods,
44
50
  statusConfigFixable,
51
+ logCliBehindCore,
45
52
  } from '../status/status.mjs';
46
53
  import {semverGte} from '../../../foundation/env/semver.mjs';
47
54
  import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
55
+ import {isOutsideProject} from '../../../foundation/env/project-scope.mjs';
48
56
  import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
49
57
  import {AstryxError} from '../../error.mjs';
50
58
  import {logger} from '../../logger.mjs';
@@ -107,10 +115,11 @@ function loadFileProtection(cwd) {
107
115
  * on failure. Progress is emitted through the shared `logger` (silent by default).
108
116
  *
109
117
  * @param {import('../_adapter.mjs').UpgradeOptions} [options]
110
- * @param {{cwd?: string}} [ctx]
118
+ * @param {{cwd?: string, origin?: string}} [ctx] `origin` is the folder the
119
+ * command ran in, when `cwd` is the project root above it
111
120
  * @returns {Promise<import('../upgrade.type.mjs').UpgradeStatusResponse | import('../upgrade.type.mjs').UpgradeRunResponse>}
112
121
  */
113
- export async function run(options = {}, {cwd = process.cwd()} = {}) {
122
+ export async function run(options = {}, {cwd = process.cwd(), origin} = {}) {
114
123
  // Resolve the source dir against the API's cwd (not process.cwd()) so a
115
124
  // programmatic caller in another directory scans the right tree. Confine it to
116
125
  // cwd: --apply rewrites files in place, so a `..`-escaping or out-of-tree
@@ -144,9 +153,18 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
144
153
  const sourcePathFound = fs.existsSync(path_);
145
154
 
146
155
  const currentVersion = /** @type {string} */ (options.from);
156
+ // Named first, so a run that stops on the Core lookup below still says which
157
+ // folder it searched (spec:AST-040 FR12).
158
+ if (origin != null) {
159
+ logger.log(`Project root: ${path.relative(origin, cwd) || '.'}`);
160
+ logger.log(`Source folder: ${path.relative(origin, path_) || '.'}`);
161
+ }
147
162
  const installed = detectInstalledTargetVersion(cwd);
148
163
  if (!installed) {
149
- const msg = `Could not find installed @astryxdesign/core (or legacy @xds/core). Install the target version first, then rerun \`${getCliInvocation()} upgrade --from <old-version>\`.`;
164
+ // Outside a project there is no version to install (spec AST-081 FR3).
165
+ const msg = isOutsideProject(cwd)
166
+ ? 'Could not find installed @astryxdesign/core (or legacy @xds/core). This folder is outside a project; upgrade migrates the code of an app project that installs @astryxdesign/core.'
167
+ : `Could not find installed @astryxdesign/core (or legacy @xds/core). Install the target version first, then rerun \`${getCliInvocation()} upgrade --from <old-version>\`.`;
150
168
  logger.error(msg);
151
169
  logger.log('Aborted\n');
152
170
  throw new AstryxError(msg, undefined, ERROR_CODES.ERR_VERSION_DETECT);
@@ -159,6 +177,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
159
177
  {apply, path: path_},
160
178
  {
161
179
  cwd,
180
+ origin,
162
181
  expectedVersion:
163
182
  installed.packageName === '@astryxdesign/core'
164
183
  ? targetVersion
@@ -181,6 +200,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
181
200
  const registryResult = await reconcileCompositions();
182
201
  const agentDocsPlan = await prepareAgentDocsRefresh({
183
202
  cwd,
203
+ origin,
184
204
  installedVersion: targetVersion,
185
205
  apply,
186
206
  });
@@ -195,6 +215,17 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
195
215
  });
196
216
  }
197
217
 
218
+ // Past the up-to-date exit, codemods are needed through targetVersion. A
219
+ // CLI older than that has none for the releases after its own version.
220
+ const cliBehindCore = detectCliBehindCore({
221
+ from: currentVersion,
222
+ to: targetVersion,
223
+ packageName: installed.packageName,
224
+ options,
225
+ cwd,
226
+ sourcePath: path_,
227
+ });
228
+
198
229
  const versionManifests = await getCoreVersionManifests(
199
230
  currentVersion,
200
231
  targetVersion,
@@ -243,6 +274,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
243
274
  skipCodemods,
244
275
  root: cwd,
245
276
  protection,
277
+ coversTarget: !cliBehindCore,
246
278
  });
247
279
  const coreResult =
248
280
  codemodResult && 'totalFilesChanged' in codemodResult
@@ -271,6 +303,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
271
303
  for (const item of protectedFiles) {
272
304
  logger.error(` ${item.file} — ${item.declarations.join('; ')}`);
273
305
  }
306
+ if (cliBehindCore) logCliBehindCore(cliBehindCore, targetVersion);
274
307
  logger.log('Upgrade incomplete: protected changes remain\n');
275
308
  return {
276
309
  type: 'upgrade.run',
@@ -299,6 +332,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
299
332
  complete: false,
300
333
  errorCode: 'ERR_CODEMOD_PROTECTED',
301
334
  errors: coreResult?.errors ?? [],
335
+ ...(cliBehindCore ? {cliBehindCore} : {}),
302
336
  },
303
337
  };
304
338
  }
@@ -316,6 +350,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
316
350
  to: targetVersion,
317
351
  configError: configErr.message,
318
352
  configCodemods: coreConfigCodemodNames,
353
+ cliBehindCore,
319
354
  agentDocs:
320
355
  /** @type {import('../upgrade.type.mjs').AgentDocsSummary} */ ({
321
356
  status: inspection.status,
@@ -370,6 +405,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
370
405
  // No codemods in range — safe to render agent docs from current state.
371
406
  const agentDocsPlan = await prepareAgentDocsRefresh({
372
407
  cwd,
408
+ origin,
373
409
  installedVersion: targetVersion,
374
410
  apply,
375
411
  });
@@ -381,6 +417,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
381
417
  to: targetVersion,
382
418
  agentDocs,
383
419
  ...(registryResult ? {registryCompositions: registryResult.summary} : {}),
420
+ cliBehindCore,
384
421
  });
385
422
  }
386
423
 
@@ -620,6 +657,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
620
657
  }
621
658
  receipt.errors = finalErrors;
622
659
  if (registryResult) receipt.registryCompositions = registryResult.summary;
660
+ if (cliBehindCore) receipt.cliBehindCore = cliBehindCore;
623
661
 
624
662
  if (protectedFiles.length > 0) {
625
663
  logger.error(
@@ -643,6 +681,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
643
681
  if (protectedFiles.length === 0) {
644
682
  const agentDocsPlan = await prepareAgentDocsRefresh({
645
683
  cwd,
684
+ origin,
646
685
  installedVersion: targetVersion,
647
686
  apply,
648
687
  fresh: true,
@@ -655,7 +694,12 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
655
694
  }
656
695
 
657
696
  const registryOk = receipt.registryCompositions?.ok ?? true;
658
- const done = apply ? 'Upgrade complete' : 'Dry run complete';
697
+ if (cliBehindCore) logCliBehindCore(cliBehindCore, targetVersion);
698
+ const done = cliBehindCore
699
+ ? 'Upgrade incomplete'
700
+ : apply
701
+ ? 'Upgrade complete'
702
+ : 'Dry run complete';
659
703
  logger.log(
660
704
  protectedFiles.length > 0
661
705
  ? 'Upgrade incomplete: protected changes remain\n'
@@ -3,18 +3,41 @@
3
3
  /**
4
4
  * @file Colocated tests for the upgrade.run leaf — the --path scan dir must be
5
5
  * confined to cwd (upgrade rewrites source in place with --apply, so an escaping
6
- * or out-of-tree path must be rejected), and the receipt must say whether that
7
- * dir existed at all.
6
+ * or out-of-tree path must be rejected), the receipt must say whether that
7
+ * dir existed at all, a run from any folder in a project upgrades that
8
+ * project (the nearest folder whose package.json declares Astryx, never the
9
+ * home folder) and names files relative to the folder it ran in, and the
10
+ * target Core is the project's own.
8
11
  */
9
12
 
10
- import {describe, it, expect, beforeEach, afterEach} from 'vitest';
13
+ import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
11
14
  import * as fs from 'node:fs';
12
15
  import * as os from 'node:os';
13
16
  import * as path from 'node:path';
14
17
  import {upgrade} from '../upgrade.mjs';
18
+ import {relativeToOrigin} from '../_adapter.mjs';
19
+ import {logger} from '../../logger.mjs';
20
+ import {generateCompressedIndex} from '../../../foundation/agent-docs/agent-docs.mjs';
15
21
 
16
22
  const SLOW = 30_000;
17
23
 
24
+ /**
25
+ * Run `fn` with `home` as the home folder.
26
+ * @template T
27
+ * @param {string} home @param {() => Promise<T>} fn
28
+ * @returns {Promise<T>}
29
+ */
30
+ async function withHome(home, fn) {
31
+ const previous = process.env.HOME;
32
+ process.env.HOME = home;
33
+ try {
34
+ return await fn();
35
+ } finally {
36
+ if (previous === undefined) delete process.env.HOME;
37
+ else process.env.HOME = previous;
38
+ }
39
+ }
40
+
18
41
  function seedProject(dir) {
19
42
  fs.writeFileSync(
20
43
  path.join(dir, 'package.json'),
@@ -95,3 +118,394 @@ describe('upgrade.run — sourcePathFound', () => {
95
118
  expect(res.data.sourcePathFound).toBe(true);
96
119
  }, SLOW);
97
120
  });
121
+
122
+ /** Core 0.7.0 renamed this prop; its codemod renames it on Typeahead. */
123
+ const OLD_PROP_SOURCE =
124
+ "import {Typeahead} from '@astryxdesign/core';\n" +
125
+ 'export const App = () => <Typeahead label="Fruit" emptySearchResultsText="None" />;\n';
126
+
127
+ /**
128
+ * A project with Core 0.7.0 installed and src/App.tsx using a prop that 0.7.0
129
+ * renamed.
130
+ * @param {string} dir
131
+ */
132
+ function seedOldPropProject(dir) {
133
+ fs.writeFileSync(
134
+ path.join(dir, 'package.json'),
135
+ JSON.stringify({name: 'app', dependencies: {'@astryxdesign/core': '0.7.0'}}),
136
+ );
137
+ const core = path.join(dir, 'node_modules', '@astryxdesign', 'core');
138
+ fs.mkdirSync(core, {recursive: true});
139
+ fs.writeFileSync(path.join(core, 'package.json'), JSON.stringify({name: '@astryxdesign/core', version: '0.7.0'}));
140
+ fs.mkdirSync(path.join(dir, 'src', 'l1', 'l2'), {recursive: true});
141
+ fs.writeFileSync(path.join(dir, 'src', 'App.tsx'), OLD_PROP_SOURCE);
142
+ }
143
+
144
+ describe('upgrade.run — a run from a subfolder upgrades the project', () => {
145
+ let dir;
146
+ beforeEach(() => {
147
+ dir = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-scope-'));
148
+ seedOldPropProject(dir);
149
+ });
150
+ afterEach(() => fs.rmSync(dir, {recursive: true, force: true}));
151
+
152
+ const appSource = () => fs.readFileSync(path.join(dir, 'src', 'App.tsx'), 'utf-8');
153
+
154
+ it.each([['src', 'App.tsx'], ['src/l1/l2', '../../App.tsx']])(
155
+ 'scans the project src by default when run from %s',
156
+ async (folder, reported) => {
157
+ const res = await upgrade({from: '0.6.8', apply: true}, {cwd: path.join(dir, folder)});
158
+
159
+ expect(res.type).toBe('upgrade.run');
160
+ expect(res.data.sourcePathFound).toBe(true);
161
+ expect(res.data.filesChanged).toBe(1);
162
+ expect(res.data.modifiedFiles).toEqual([reported]);
163
+ expect(appSource()).toContain('emptySearchText="None"');
164
+ },
165
+ SLOW,
166
+ );
167
+
168
+ it('reads a path you name relative to the folder you ran in', async () => {
169
+ const res = await upgrade({from: '0.6.8', path: '../..', apply: true}, {cwd: path.join(dir, 'src', 'l1', 'l2')});
170
+
171
+ expect(res.type).toBe('upgrade.run');
172
+ expect(res.data.filesChanged).toBe(1);
173
+ expect(appSource()).toContain('emptySearchText="None"');
174
+ }, SLOW);
175
+
176
+ it('still rejects a path outside the project', async () => {
177
+ await expect(
178
+ upgrade({from: '0.6.8', path: '../../..'}, {cwd: path.join(dir, 'src', 'l1')}),
179
+ ).rejects.toMatchObject({code: 'ERR_PATH_TRAVERSAL'});
180
+ expect(appSource()).toBe(OLD_PROP_SOURCE);
181
+ }, SLOW);
182
+
183
+ it("refreshes the agent docs at the project root, not the folder it ran in", async () => {
184
+ fs.writeFileSync(
185
+ path.join(dir, 'AGENTS.md'),
186
+ `# Agents\n\n${generateCompressedIndex('0.6.8')}\n`,
187
+ );
188
+
189
+ const res = await upgrade({from: '0.6.8', apply: true}, {cwd: path.join(dir, 'src', 'l1')});
190
+
191
+ expect(res.type).toBe('upgrade.run');
192
+ expect(res.data.agentDocs.action).toBe('refreshed');
193
+ expect(res.data.agentDocs.files).toEqual(['../../AGENTS.md']);
194
+ expect(fs.existsSync(path.join(dir, 'src', 'l1', 'AGENTS.md'))).toBe(false);
195
+ }, SLOW);
196
+ });
197
+
198
+ describe('upgrade.run — the result names files relative to the folder it ran in', () => {
199
+ let dir;
200
+ beforeEach(() => {
201
+ dir = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-receipt-'));
202
+ seedOldPropProject(dir);
203
+ fs.writeFileSync(path.join(dir, 'src', 'Generated.tsx'), `// @generated\n${OLD_PROP_SOURCE}`);
204
+ fs.writeFileSync(path.join(dir, 'src', 'Vendored.tsx'), OLD_PROP_SOURCE);
205
+ fs.writeFileSync(path.join(dir, '.gitattributes'), 'src/Vendored.tsx linguist-generated\n');
206
+ fs.writeFileSync(path.join(dir, 'AGENTS.md'), `# Agents\n\n${generateCompressedIndex('0.6.8')}\n`);
207
+ fs.mkdirSync(path.join(dir, 'frontend'), {recursive: true});
208
+ });
209
+ afterEach(() => fs.rmSync(dir, {recursive: true, force: true}));
210
+
211
+ it.each([
212
+ ['frontend', '../'],
213
+ ['.', ''],
214
+ ])('from %s, every file path resolves from that folder', async (folder, up) => {
215
+ const cwd = path.join(dir, folder);
216
+
217
+ const res = await upgrade({from: '0.6.8'}, {cwd});
218
+
219
+ expect(res.type).toBe('upgrade.run');
220
+ expect(res.data.modifiedFiles).toEqual([`${up}src/App.tsx`]);
221
+ expect(res.data.protectedFiles.map(item => item.file)).toEqual([
222
+ `${up}src/Generated.tsx`,
223
+ `${up}src/Vendored.tsx`,
224
+ ]);
225
+ for (const file of [...res.data.modifiedFiles, ...res.data.protectedFiles.map(item => item.file)]) {
226
+ expect(fs.existsSync(path.join(cwd, file))).toBe(true);
227
+ }
228
+ // The file a declaration names resolves from that folder too.
229
+ const vendored = res.data.protectedFiles.find(item => item.file.endsWith('Vendored.tsx'));
230
+ expect(vendored?.declarations).toEqual([`linguist-generated in ${up}.gitattributes:1`]);
231
+ expect(fs.existsSync(path.join(cwd, `${up}.gitattributes`))).toBe(true);
232
+ }, SLOW);
233
+
234
+ it('leaves a result from a run at the project root as it is', () => {
235
+ const result = {type: 'upgrade.run', data: {modifiedFiles: ['src/App.tsx']}};
236
+
237
+ expect(relativeToOrigin(result, {cwd: dir})).toBe(result);
238
+ });
239
+
240
+ it('rewrites every project-relative path and passes the copied-composition summary through', () => {
241
+ const registryCompositions = {items: [{item: 'example', path: 'components/Example.tsx', files: []}]};
242
+ const result = relativeToOrigin(
243
+ {
244
+ type: 'upgrade.run',
245
+ data: {
246
+ agentDocs: {status: 'stale', files: ['AGENTS.md']},
247
+ modifiedFiles: ['src/App.tsx'],
248
+ protectedFiles: [
249
+ {
250
+ file: 'src/Generated.tsx',
251
+ codemods: ['a'],
252
+ declarations: [
253
+ '@generated marker',
254
+ 'excluded by .gitignore',
255
+ 'excluded by src/.hgignore:3',
256
+ 'linguist-generated in .gitattributes:1',
257
+ 'symbolic link at src/linked',
258
+ 'installed dependency metadata node_modules/x',
259
+ ],
260
+ },
261
+ ],
262
+ declinedCandidates: [{file: 'src/Loose.tsx', reason: 'unproven'}],
263
+ errors: [{file: '.', codemod: 'post-codemod-hook', error: 'failed'}],
264
+ registryCompositions,
265
+ },
266
+ },
267
+ {cwd: dir, origin: path.join(dir, 'apps', 'web')},
268
+ );
269
+
270
+ expect(result.data).toEqual({
271
+ agentDocs: {status: 'stale', files: ['../../AGENTS.md']},
272
+ modifiedFiles: ['../../src/App.tsx'],
273
+ protectedFiles: [
274
+ {
275
+ file: '../../src/Generated.tsx',
276
+ codemods: ['a'],
277
+ declarations: [
278
+ '@generated marker',
279
+ 'excluded by ../../.gitignore',
280
+ 'excluded by ../../src/.hgignore:3',
281
+ 'linguist-generated in ../../.gitattributes:1',
282
+ 'symbolic link at ../../src/linked',
283
+ 'installed dependency metadata node_modules/x',
284
+ ],
285
+ },
286
+ ],
287
+ declinedCandidates: [{file: '../../src/Loose.tsx', reason: 'unproven'}],
288
+ errors: [{file: '../..', codemod: 'post-codemod-hook', error: 'failed'}],
289
+ registryCompositions,
290
+ });
291
+ });
292
+ });
293
+
294
+ describe("upgrade.run — the target Core is the project's own", () => {
295
+ let dir;
296
+ beforeEach(() => {
297
+ dir = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-own-core-'));
298
+ seedOldPropProject(dir);
299
+ });
300
+ afterEach(() => fs.rmSync(dir, {recursive: true, force: true}));
301
+
302
+ /**
303
+ * A project nested in `dir`, with src/App.tsx using the renamed prop.
304
+ * @param {Record<string, string>} dependencies
305
+ */
306
+ function nestedProject(dependencies) {
307
+ const nested = path.join(dir, 'apps', 'web');
308
+ fs.mkdirSync(path.join(nested, 'src'), {recursive: true});
309
+ fs.writeFileSync(path.join(nested, 'package.json'), JSON.stringify({name: 'web', dependencies}));
310
+ fs.writeFileSync(path.join(nested, 'src', 'App.tsx'), OLD_PROP_SOURCE);
311
+ return nested;
312
+ }
313
+
314
+ it.each([
315
+ ['declares no Astryx package', {}],
316
+ ['declares a Core it has not installed', {'@astryxdesign/core': '0.6.8'}],
317
+ ])(
318
+ 'does not upgrade a project that %s to the Core of the home folder above it',
319
+ async (_label, dependencies) => {
320
+ const nested = nestedProject(dependencies);
321
+
322
+ await withHome(dir, () =>
323
+ expect(
324
+ upgrade({from: '0.6.8', apply: true}, {cwd: nested}),
325
+ ).rejects.toMatchObject({code: 'ERR_VERSION_DETECT'}),
326
+ );
327
+ expect(fs.readFileSync(path.join(nested, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
328
+ expect(fs.readFileSync(path.join(dir, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
329
+ },
330
+ SLOW,
331
+ );
332
+
333
+ it('names the folder it searched before stopping on a missing Core, from a subfolder (AST-040 FR12)', async () => {
334
+ fs.rmSync(path.join(dir, 'node_modules'), {recursive: true, force: true});
335
+ const sub = path.join(dir, 'src', 'l1');
336
+ const log = vi.spyOn(logger, 'log');
337
+ try {
338
+ await expect(upgrade({from: '0.6.8'}, {cwd: sub})).rejects.toMatchObject({
339
+ code: 'ERR_VERSION_DETECT',
340
+ });
341
+ const lines = log.mock.calls.map(([line]) => String(line));
342
+ expect(lines).toContain('Project root: ../..');
343
+ expect(lines.indexOf('Project root: ../..')).toBeLessThan(
344
+ lines.indexOf('Aborted\n'),
345
+ );
346
+ } finally {
347
+ log.mockRestore();
348
+ }
349
+ }, SLOW);
350
+
351
+ it('does not upgrade a nested project that declares a Core it has not installed to the Core above it', async () => {
352
+ const nested = nestedProject({'@astryxdesign/core': '0.6.8'});
353
+
354
+ await expect(
355
+ upgrade({from: '0.6.8', apply: true}, {cwd: nested}),
356
+ ).rejects.toMatchObject({code: 'ERR_VERSION_DETECT'});
357
+ expect(fs.readFileSync(path.join(nested, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
358
+ }, SLOW);
359
+
360
+ it.each([
361
+ ['an override at the workspace root forces', {overrides: {'@astryxdesign/core': '0.7.0'}}, {'@astryxdesign/core': '~0.6.8'}],
362
+ ['a resolution at the workspace root forces', {resolutions: {'@astryxdesign/core': '0.7.0'}}, {'@astryxdesign/core': '0.6.8'}],
363
+ ['only a stale peer range names', {}, null],
364
+ ['the member declares another version of, not yet installed', {}, {'@astryxdesign/core': '0.9.0'}],
365
+ ])(
366
+ 'upgrades a workspace member to a hoisted Core that %s',
367
+ async (_label, rootFields, dependencies) => {
368
+ fs.writeFileSync(
369
+ path.join(dir, 'package.json'),
370
+ JSON.stringify({name: 'root', private: true, workspaces: ['apps/*'], ...rootFields}),
371
+ );
372
+ const member = dependencies
373
+ ? nestedProject(dependencies)
374
+ : nestedProject({});
375
+ if (!dependencies) {
376
+ fs.writeFileSync(
377
+ path.join(member, 'package.json'),
378
+ JSON.stringify({name: 'web', peerDependencies: {'@astryxdesign/core': '^0.6.8'}}),
379
+ );
380
+ }
381
+
382
+ const res = await upgrade({from: '0.6.8', apply: true}, {cwd: member});
383
+
384
+ expect(res.type).toBe('upgrade.run');
385
+ expect(res.data.to).toBe('0.7.0');
386
+ expect(res.data.modifiedFiles).toEqual(['src/App.tsx']);
387
+ expect(fs.readFileSync(path.join(member, 'src', 'App.tsx'), 'utf-8')).toContain('emptySearchText="None"');
388
+ },
389
+ SLOW,
390
+ );
391
+
392
+ it('does not upgrade a project its workspace does not list to the hoisted Core', async () => {
393
+ fs.writeFileSync(
394
+ path.join(dir, 'package.json'),
395
+ JSON.stringify({name: 'root', private: true, workspaces: ['packages/*']}),
396
+ );
397
+ const project = nestedProject({'@astryxdesign/core': '0.9.0'});
398
+
399
+ await expect(
400
+ upgrade({from: '0.6.8', apply: true}, {cwd: project}),
401
+ ).rejects.toMatchObject({code: 'ERR_VERSION_DETECT'});
402
+ expect(fs.readFileSync(path.join(project, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
403
+ }, SLOW);
404
+
405
+ it.each([[['apps/*']], [['{apps/*,tools/*}']]])('upgrades a member that declares no Astryx package, in its own src, when the workspace lists %j', async workspaces => {
406
+ fs.writeFileSync(
407
+ path.join(dir, 'package.json'),
408
+ JSON.stringify({name: 'root', private: true, workspaces, dependencies: {'@astryxdesign/core': '0.7.0'}}),
409
+ );
410
+ const member = nestedProject({});
411
+
412
+ const res = await upgrade({from: '0.6.8', apply: true}, {cwd: path.join(member, 'src')});
413
+
414
+ expect(res.type).toBe('upgrade.run');
415
+ expect(res.data.modifiedFiles).toEqual(['App.tsx']);
416
+ expect(fs.readFileSync(path.join(member, 'src', 'App.tsx'), 'utf-8')).toContain('emptySearchText="None"');
417
+ expect(fs.readFileSync(path.join(dir, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
418
+ }, SLOW);
419
+ });
420
+
421
+ describe('upgrade.run — the project is the nearest folder that declares Astryx', () => {
422
+ let home;
423
+ beforeEach(() => {
424
+ home = fs.mkdtempSync(path.join(os.tmpdir(), 'upg-home-'));
425
+ });
426
+ afterEach(() => fs.rmSync(home, {recursive: true, force: true}));
427
+
428
+ // Astryx installed in a home folder whose src holds loose files and another
429
+ // project, run from a folder with no package.json.
430
+ it('does not upgrade the home folder from a folder inside it', async () => {
431
+ seedOldPropProject(home);
432
+ fs.mkdirSync(path.join(home, 'src', 'repoA', 'src'), {recursive: true});
433
+ fs.writeFileSync(
434
+ path.join(home, 'src', 'repoA', 'package.json'),
435
+ JSON.stringify({name: 'repoA', dependencies: {'@astryxdesign/core': '0.6.8'}}),
436
+ );
437
+ fs.writeFileSync(path.join(home, 'src', 'repoA', 'src', 'a.tsx'), OLD_PROP_SOURCE);
438
+ const desktop = path.join(home, 'Desktop');
439
+ fs.mkdirSync(desktop, {recursive: true});
440
+
441
+ await withHome(home, () =>
442
+ expect(
443
+ upgrade({from: '0.6.8', apply: true}, {cwd: desktop}),
444
+ ).rejects.toMatchObject({code: 'ERR_VERSION_DETECT'}),
445
+ );
446
+ expect(fs.readFileSync(path.join(home, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
447
+ expect(fs.readFileSync(path.join(home, 'src', 'repoA', 'src', 'a.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
448
+ }, SLOW);
449
+
450
+ // Installing Core does not make a folder a project.
451
+ it('treats a folder that installs Core without declaring it as part of the project above it', async () => {
452
+ seedOldPropProject(home);
453
+ const tool = path.join(home, 'tools', 'codegen');
454
+ const core = path.join(tool, 'node_modules', '@astryxdesign', 'core');
455
+ fs.mkdirSync(core, {recursive: true});
456
+ fs.writeFileSync(path.join(tool, 'package.json'), JSON.stringify({name: 'codegen'}));
457
+ fs.writeFileSync(path.join(core, 'package.json'), JSON.stringify({name: '@astryxdesign/core', version: '0.9.0'}));
458
+
459
+ const res = await upgrade({from: '0.6.8', apply: true}, {cwd: tool});
460
+
461
+ expect(res.type).toBe('upgrade.run');
462
+ expect(res.data.to).toBe('0.7.0');
463
+ expect(res.data.modifiedFiles).toEqual(['../../src/App.tsx']);
464
+ }, SLOW);
465
+
466
+ it('names the project root and the folder it scans before a dry run in a folder that installs Core without declaring it', async () => {
467
+ seedOldPropProject(home);
468
+ const tool = path.join(home, 'tools', 'codegen');
469
+ const core = path.join(tool, 'node_modules', '@astryxdesign', 'core');
470
+ fs.mkdirSync(core, {recursive: true});
471
+ fs.writeFileSync(path.join(tool, 'package.json'), JSON.stringify({name: 'codegen'}));
472
+ fs.writeFileSync(path.join(core, 'package.json'), JSON.stringify({name: '@astryxdesign/core', version: '0.9.0'}));
473
+ const log = vi.spyOn(logger, 'log');
474
+ try {
475
+ const res = await upgrade({from: '0.6.8'}, {cwd: tool});
476
+
477
+ expect(res.type).toBe('upgrade.run');
478
+ const lines = log.mock.calls.map(([line]) => String(line));
479
+ expect(lines).toContain('Project root: ../..');
480
+ expect(lines).toContain(`Source folder: ${path.join('..', '..', 'src')}`);
481
+ expect(fs.readFileSync(path.join(home, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
482
+ } finally {
483
+ log.mockRestore();
484
+ }
485
+ }, SLOW);
486
+
487
+ it('upgrades the home folder as a folder outside any project, when run there', async () => {
488
+ seedOldPropProject(home);
489
+
490
+ const res = await withHome(home, () => upgrade({from: '0.6.8', apply: true}, {cwd: home}));
491
+
492
+ expect(res.type).toBe('upgrade.run');
493
+ expect(res.data.modifiedFiles).toEqual(['src/App.tsx']);
494
+ expect(fs.readFileSync(path.join(home, 'src', 'App.tsx'), 'utf-8')).toContain('emptySearchText="None"');
495
+ }, SLOW);
496
+
497
+ it('does not leave a repository for the project around it', async () => {
498
+ seedOldPropProject(home);
499
+ const repo = path.join(home, 'vendor', 'repo');
500
+ fs.mkdirSync(path.join(repo, '.git'), {recursive: true});
501
+ fs.mkdirSync(path.join(repo, 'src'), {recursive: true});
502
+ fs.writeFileSync(path.join(repo, 'package.json'), JSON.stringify({name: 'repo'}));
503
+ fs.writeFileSync(path.join(repo, 'src', 'App.tsx'), OLD_PROP_SOURCE);
504
+
505
+ await expect(
506
+ upgrade({from: '0.6.8', apply: true}, {cwd: repo}),
507
+ ).rejects.toMatchObject({code: 'ERR_VERSION_DETECT'});
508
+ expect(fs.readFileSync(path.join(repo, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
509
+ expect(fs.readFileSync(path.join(home, 'src', 'App.tsx'), 'utf-8')).toBe(OLD_PROP_SOURCE);
510
+ }, SLOW);
511
+ });
@@ -13,27 +13,43 @@ export function statusUpToDate({ from, to, agentDocs, registryCompositions }: {
13
13
  registryCompositions?: import("../upgrade.type.mjs").RegistryCompositionSummary;
14
14
  }): import("../upgrade.type.mjs").UpgradeStatusResponse;
15
15
  /**
16
- * No core or integration codemods apply to the requested version range.
17
- * @param {{from: string, to: string, agentDocs: import('../upgrade.type.mjs').AgentDocsSummary, registryCompositions?: import('../upgrade.type.mjs').RegistryCompositionSummary}} data
16
+ * The one warning for a CLI older than the installed Core: it has no codemods
17
+ * for the releases after its own version, and the pinned command does. The
18
+ * command gets a line of its own, so it copies exactly, whatever quotes or
19
+ * backticks its arguments carry. On Windows it is written for PowerShell, and
20
+ * the warning says so.
21
+ * @param {import('../upgrade.type.mjs').CliBehindCore} cliBehindCore
22
+ * @param {string} to the installed Core version
23
+ * @param {string} [platform] the `process.platform` the command was printed
24
+ * for, as `quoteCommandArgument` and `commandInFolder` take it
25
+ */
26
+ export function logCliBehindCore({ cliVersion, command }: import("../upgrade.type.mjs").CliBehindCore, to: string, platform?: string): void;
27
+ /**
28
+ * No core or integration codemods apply to the requested version range. When
29
+ * the CLI is older than the installed Core, that only means this CLI has none:
30
+ * the result carries `cliBehindCore` and the human lines say so.
31
+ * @param {{from: string, to: string, agentDocs: import('../upgrade.type.mjs').AgentDocsSummary, registryCompositions?: import('../upgrade.type.mjs').RegistryCompositionSummary, cliBehindCore?: import('../upgrade.type.mjs').CliBehindCore | null}} data
18
32
  * @returns {import('../upgrade.type.mjs').UpgradeStatusResponse}
19
33
  */
20
- export function statusNoCodemods({ from, to, agentDocs, registryCompositions }: {
34
+ export function statusNoCodemods({ from, to, agentDocs, registryCompositions, cliBehindCore }: {
21
35
  from: string;
22
36
  to: string;
23
37
  agentDocs: import("../upgrade.type.mjs").AgentDocsSummary;
24
38
  registryCompositions?: import("../upgrade.type.mjs").RegistryCompositionSummary;
39
+ cliBehindCore?: import("../upgrade.type.mjs").CliBehindCore | null;
25
40
  }): import("../upgrade.type.mjs").UpgradeStatusResponse;
26
41
  /**
27
42
  * DRY-RUN only: the consumer's astryx.config fails strict validation, but a
28
43
  * pending core CONFIG codemod previewed a change that would repair it. Preview
29
44
  * the fix + report the exact `--apply` command; integrations are skipped here.
30
- * @param {{from: string, to: string, configError: string, configCodemods: string[], agentDocs: import('../upgrade.type.mjs').AgentDocsSummary}} data
45
+ * @param {{from: string, to: string, configError: string, configCodemods: string[], agentDocs: import('../upgrade.type.mjs').AgentDocsSummary, cliBehindCore?: import('../upgrade.type.mjs').CliBehindCore | null}} data
31
46
  * @returns {import('../upgrade.type.mjs').UpgradeStatusResponse}
32
47
  */
33
- export function statusConfigFixable({ from, to, configError, configCodemods, agentDocs }: {
48
+ export function statusConfigFixable({ from, to, configError, configCodemods, agentDocs, cliBehindCore }: {
34
49
  from: string;
35
50
  to: string;
36
51
  configError: string;
37
52
  configCodemods: string[];
38
53
  agentDocs: import("../upgrade.type.mjs").AgentDocsSummary;
54
+ cliBehindCore?: import("../upgrade.type.mjs").CliBehindCore | null;
39
55
  }): import("../upgrade.type.mjs").UpgradeStatusResponse;