@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
@@ -23,7 +23,55 @@
23
23
  * @property {boolean} [registry]
24
24
  */
25
25
  /**
26
- * Detect the installed target version from node_modules.
26
+ * Where an upgrade runs: the root of the Astryx project `cwd` belongs to, the
27
+ * nearest folder at or above it whose package.json declares an Astryx
28
+ * package or that an Astryx workspace lists as a member, so a run from any
29
+ * folder inside a project upgrades that project exactly as a run from its
30
+ * root does. Its source, config, agent docs and
31
+ * protection declarations all live there. The search stops at a repository
32
+ * root and ends at the home folder without counting it (see
33
+ * `findAstryxProject`). A `path` the caller names, in any spelling (`./src`,
34
+ * `src`, `src/`), is read from `cwd`, where they typed it. With no `path`,
35
+ * the upgrade scans `./src` at the project root. With no Astryx project, the
36
+ * upgrade runs in `cwd` as released versions did.
37
+ * @param {UpgradeOptions} options
38
+ * @param {string} cwd
39
+ * @returns {{options: UpgradeOptions, cwd: string, origin?: string}} `origin`
40
+ * is the folder the command ran in, when the project root is above it
41
+ */
42
+ export function scopeToProject(options: UpgradeOptions, cwd: string): {
43
+ options: UpgradeOptions;
44
+ cwd: string;
45
+ origin?: string;
46
+ };
47
+ /**
48
+ * The result of an upgrade that ran at a project root above the folder the
49
+ * command ran in, with its file paths made relative to that folder, so each
50
+ * resolves from where the command ran: `modifiedFiles`, `agentDocs.files`, and
51
+ * the `file` of each `protectedFiles`, `declinedCandidates` and `errors`
52
+ * entry. The registry step names copied-composition paths from that folder
53
+ * itself (see `reconcileRegistryCompositions`), so they pass through. A
54
+ * result of a run at the project root is returned as it is.
55
+ * @template {{type: string, data: object}} T
56
+ * @param {T} result
57
+ * @param {{cwd: string, origin?: string}} scope from `scopeToProject`
58
+ * @returns {T}
59
+ */
60
+ export function relativeToOrigin<T extends {
61
+ type: string;
62
+ data: object;
63
+ }>(result: T, { cwd: root, origin }: {
64
+ cwd: string;
65
+ origin?: string;
66
+ }): T;
67
+ /**
68
+ * Detect the installed target version: the Core the Astryx project of `cwd`
69
+ * installed, in its own node_modules or, for a member its workspace lists, in
70
+ * a folder up to the workspace root. The nearest folder wins, the current
71
+ * name before the legacy one, then Yarn Plug'n'Play. A Core above a project
72
+ * no workspace lists does not count, so a nested project that has not
73
+ * installed its own reports nothing installed. With no Astryx project, only
74
+ * the node_modules of `cwd` itself is read, as released versions did.
27
75
  * @param {string} cwd
28
76
  * @returns {{version: string, packageName: string}|null}
29
77
  */
@@ -31,6 +79,43 @@ export function detectInstalledTargetVersion(cwd: string): {
31
79
  version: string;
32
80
  packageName: string;
33
81
  } | null;
82
+ /**
83
+ * Whether the installed Core is newer than this CLI, so part of the requested
84
+ * range has no codemods here.
85
+ *
86
+ * Core codemods ship inside the CLI. A CLI older than the installed
87
+ * `@astryxdesign/core` has none for the releases after its own version, so it
88
+ * can find no codemods, or stop partway, while the code still needs those
89
+ * releases' migrations. The returned command repeats this upgrade with the CLI
90
+ * release that matches the installed Core.
91
+ *
92
+ * Where an upgrade runs decides what it finds: the installed Core is read
93
+ * from that folder, and `--path` must stay inside it. So the command first
94
+ * changes to `cwd`, the folder this run used, then names `sourcePath`, the
95
+ * directory this run scanned, as an absolute `--path`. Both are named by their
96
+ * physical paths, with every symbolic link resolved: a shell's `cd` follows a
97
+ * link, but the CLI it starts reads its folder with every link resolved and
98
+ * checks `--path` against that. Pasted from any folder, the command finds the
99
+ * same Core and scans the same directory, even after a package runner moved
100
+ * this run (Yarn 1 runs `yarn astryx` at the project root). It is written for
101
+ * a POSIX shell, or for PowerShell on Windows (cmd.exe is not a target), with
102
+ * every argument quoted for that shell.
103
+ *
104
+ * Returns null when the CLI covers the whole range (`to` is not newer than
105
+ * both the CLI and `from`), when the CLI's own version cannot be read, or when
106
+ * the target is legacy `@xds/core`, which no CLI release shares a version with.
107
+ *
108
+ * @param {{from: string, to: string, packageName: string, options: UpgradeOptions, cwd: string, sourcePath: string}} input
109
+ * @returns {import('./upgrade.type.mjs').CliBehindCore | null}
110
+ */
111
+ export function detectCliBehindCore({ from, to, packageName, options, cwd, sourcePath, }: {
112
+ from: string;
113
+ to: string;
114
+ packageName: string;
115
+ options: UpgradeOptions;
116
+ cwd: string;
117
+ sourcePath: string;
118
+ }): import("./upgrade.type.mjs").CliBehindCore | null;
34
119
  /**
35
120
  * @param {(string | null | undefined | false)[] | undefined} files
36
121
  * @returns {string[]}
@@ -47,25 +132,20 @@ export function runPostCodemodHooks(hooks: import("../../authoring/config/type")
47
132
  files: string[];
48
133
  apply: boolean;
49
134
  }): Promise<void>;
50
- /**
51
- * @typedef {object} AgentDocsRefreshPlan
52
- * @property {string} cwd
53
- * @property {string|null} renderedBlock
54
- * @property {import('./upgrade.type.mjs').AgentDocsSummary} summary
55
- */
56
135
  /**
57
136
  * Compute the expected managed block and report staleness without writing.
58
137
  * Apply-mode callers commit the prepared bytes only after codemods and hooks
59
138
  * succeed.
60
139
  *
61
- * @param {{cwd: string, installedVersion: string, apply: boolean, fresh?: boolean}} ctx
140
+ * @param {{cwd: string, installedVersion: string, apply: boolean, fresh?: boolean, origin?: string}} ctx
62
141
  * @returns {Promise<AgentDocsRefreshPlan>}
63
142
  */
64
- export function prepareAgentDocsRefresh({ cwd, installedVersion, apply, fresh, }: {
143
+ export function prepareAgentDocsRefresh({ cwd, installedVersion, apply, fresh, origin, }: {
65
144
  cwd: string;
66
145
  installedVersion: string;
67
146
  apply: boolean;
68
147
  fresh?: boolean;
148
+ origin?: string;
69
149
  }): Promise<AgentDocsRefreshPlan>;
70
150
  /**
71
151
  * Commit a prepared agent-doc refresh.
@@ -104,9 +184,9 @@ export function ensureCodemodDeps({ installDeps }?: {
104
184
  * Run the CORE registry codemods. Runs BEFORE the config is loaded so a core
105
185
  * CONFIG codemod can repair a config the strict loader would otherwise reject.
106
186
  * @param {CoreVersionManifest[]} versionManifests
107
- * @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean}} options
187
+ * @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean, coversTarget?: boolean}} options
108
188
  */
109
- export function runCoreCodemods(versionManifests: CoreVersionManifest[], { apply, path: srcPath, codemod, skipCodemods, root, protection, silent }: {
189
+ export function runCoreCodemods(versionManifests: CoreVersionManifest[], { apply, path: srcPath, codemod, skipCodemods, root, protection, silent, coversTarget, }: {
110
190
  apply: boolean;
111
191
  path: string;
112
192
  codemod?: string;
@@ -117,6 +197,7 @@ export function runCoreCodemods(versionManifests: CoreVersionManifest[], { apply
117
197
  classify: (file: string) => import("../../foundation/fs/file-protection.mjs").FileProtection[];
118
198
  };
119
199
  silent?: boolean;
200
+ coversTarget?: boolean;
120
201
  }): Promise<{
121
202
  totalFilesChanged: number;
122
203
  totalTransformsApplied: number;
@@ -250,6 +331,11 @@ export type UpgradeOptions = {
250
331
  };
251
332
  export type AgentDocsRefreshPlan = {
252
333
  cwd: string;
334
+ /**
335
+ * the folder the command ran in, when the upgrade
336
+ * runs at a project root above it
337
+ */
338
+ origin?: string | undefined;
253
339
  renderedBlock: string | null;
254
340
  summary: import("./upgrade.type.mjs").AgentDocsSummary;
255
341
  };
@@ -30,11 +30,25 @@ import {
30
30
  } from '../../assets/codemods/integration-discovery.mjs';
31
31
  import {runIntegrationCodemods} from '../../assets/codemods/integration-runner.mjs';
32
32
  import {
33
+ AgentDocsHomeError,
34
+ assertAgentDocsTarget,
33
35
  installAgentDocs,
34
36
  inspectAgentDocs,
35
37
  renderAgentDocsBlock,
36
38
  } from '../../foundation/agent-docs/agent-docs.mjs';
37
- import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
39
+ import {
40
+ CLI_PACKAGE,
41
+ commandInFolder,
42
+ formatCliCommand,
43
+ getDlxPrefix,
44
+ quoteCommandArgument,
45
+ } from '../../foundation/env/package-manager.mjs';
46
+ import {isValidSemver, semverGt} from '../../foundation/env/semver.mjs';
47
+ import {
48
+ CLI_ROOT,
49
+ findAstryxProject,
50
+ findProjectPackageOf,
51
+ } from '../../foundation/fs/paths.mjs';
38
52
  import {Project, providerLedgerOf} from '../../foundation/config/project.mjs';
39
53
  import {loadIntegrations} from '../../foundation/integrations/integrations.mjs';
40
54
  import {resolveProviders} from '../../foundation/integrations/provider-resolution.mjs';
@@ -74,26 +88,218 @@ const execFileAsync = promisify(execFile);
74
88
  */
75
89
 
76
90
  /**
77
- * Detect the installed target version from node_modules.
91
+ * Where an upgrade runs: the root of the Astryx project `cwd` belongs to, the
92
+ * nearest folder at or above it whose package.json declares an Astryx
93
+ * package or that an Astryx workspace lists as a member, so a run from any
94
+ * folder inside a project upgrades that project exactly as a run from its
95
+ * root does. Its source, config, agent docs and
96
+ * protection declarations all live there. The search stops at a repository
97
+ * root and ends at the home folder without counting it (see
98
+ * `findAstryxProject`). A `path` the caller names, in any spelling (`./src`,
99
+ * `src`, `src/`), is read from `cwd`, where they typed it. With no `path`,
100
+ * the upgrade scans `./src` at the project root. With no Astryx project, the
101
+ * upgrade runs in `cwd` as released versions did.
102
+ * @param {UpgradeOptions} options
103
+ * @param {string} cwd
104
+ * @returns {{options: UpgradeOptions, cwd: string, origin?: string}} `origin`
105
+ * is the folder the command ran in, when the project root is above it
106
+ */
107
+ export function scopeToProject(options, cwd) {
108
+ const here = path.resolve(cwd);
109
+ const root = findAstryxProject(here) ?? here;
110
+ if (root === here) return {options, cwd};
111
+ const namedPath =
112
+ options.path == null ? {} : {path: path.resolve(here, options.path)};
113
+ return {options: {...options, ...namedPath}, cwd: root, origin: here};
114
+ }
115
+
116
+ /**
117
+ * The result of an upgrade that ran at a project root above the folder the
118
+ * command ran in, with its file paths made relative to that folder, so each
119
+ * resolves from where the command ran: `modifiedFiles`, `agentDocs.files`, and
120
+ * the `file` of each `protectedFiles`, `declinedCandidates` and `errors`
121
+ * entry. The registry step names copied-composition paths from that folder
122
+ * itself (see `reconcileRegistryCompositions`), so they pass through. A
123
+ * result of a run at the project root is returned as it is.
124
+ * @template {{type: string, data: object}} T
125
+ * @param {T} result
126
+ * @param {{cwd: string, origin?: string}} scope from `scopeToProject`
127
+ * @returns {T}
128
+ */
129
+ export function relativeToOrigin(result, {cwd: root, origin}) {
130
+ if (origin == null) return result;
131
+ /** @param {string} file */
132
+ const rebase = file =>
133
+ path.relative(origin, path.resolve(root, file)).split(path.sep).join('/') ||
134
+ '.';
135
+ /** @type {Record<string, any>} */
136
+ const data = {...result.data};
137
+ if (data.agentDocs) {
138
+ data.agentDocs = {
139
+ ...data.agentDocs,
140
+ files: data.agentDocs.files.map(rebase),
141
+ };
142
+ }
143
+ if (data.modifiedFiles) data.modifiedFiles = data.modifiedFiles.map(rebase);
144
+ for (const key of ['protectedFiles', 'declinedCandidates', 'errors']) {
145
+ if (data[key]) {
146
+ data[key] = data[key].map(
147
+ (/** @type {{file: string, declarations?: string[]}} */ entry) => ({
148
+ ...entry,
149
+ file: rebase(entry.file),
150
+ ...(Array.isArray(entry.declarations)
151
+ ? {declarations: entry.declarations.map(rebaseDeclaration(rebase))}
152
+ : {}),
153
+ }),
154
+ );
155
+ }
156
+ }
157
+ return /** @type {T} */ ({...result, data});
158
+ }
159
+
160
+ /**
161
+ * The project-relative file a protection declaration names, and the text
162
+ * around it: the ignore or attributes file that protects a file (and its
163
+ * line), or the symbolic link on its path. Other declarations name no file.
164
+ */
165
+ const DECLARATION_PATHS = [
166
+ /^(excluded by )(.+?)(:\d+)?$/u,
167
+ /^(linguist-(?:generated|vendored) in )(.+?)(:\d+)$/u,
168
+ /^(symbolic link at )(.+)()$/u,
169
+ ];
170
+
171
+ /**
172
+ * A protection declaration with the file it names rebased, as `rebase` does
173
+ * for result paths.
174
+ * @param {(file: string) => string} rebase
175
+ * @returns {(declaration: string) => string}
176
+ */
177
+ function rebaseDeclaration(rebase) {
178
+ return declaration => {
179
+ for (const pattern of DECLARATION_PATHS) {
180
+ const match = pattern.exec(declaration);
181
+ if (match) return `${match[1]}${rebase(match[2])}${match[3] ?? ''}`;
182
+ }
183
+ return declaration;
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Detect the installed target version: the Core the Astryx project of `cwd`
189
+ * installed, in its own node_modules or, for a member its workspace lists, in
190
+ * a folder up to the workspace root. The nearest folder wins, the current
191
+ * name before the legacy one, then Yarn Plug'n'Play. A Core above a project
192
+ * no workspace lists does not count, so a nested project that has not
193
+ * installed its own reports nothing installed. With no Astryx project, only
194
+ * the node_modules of `cwd` itself is read, as released versions did.
78
195
  * @param {string} cwd
79
196
  * @returns {{version: string, packageName: string}|null}
80
197
  */
81
198
  export function detectInstalledTargetVersion(cwd) {
82
- for (const packageName of ['@astryxdesign/core', '@xds/core']) {
83
- const pkgPath = path.resolve(
84
- cwd,
85
- 'node_modules',
86
- ...packageName.split('/'),
87
- 'package.json',
199
+ const found = findProjectPackageOf(cwd, ['@astryxdesign/core', '@xds/core']);
200
+ if (!found) return null;
201
+ try {
202
+ const pkg = JSON.parse(
203
+ fs.readFileSync(path.join(found.packageDir, 'package.json'), 'utf-8'),
88
204
  );
89
- try {
90
- const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
91
- if (pkg.version) return {version: pkg.version, packageName};
92
- } catch {
93
- // Missing/unreadable — try the next supported package name.
94
- }
205
+ return pkg.version ? {version: pkg.version, packageName: found.name} : null;
206
+ } catch {
207
+ // Unreadable package.json: no version to target.
208
+ return null;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * The running CLI's own version, read from its package.json.
214
+ * @returns {string | null} null when it cannot be read or is not semver
215
+ */
216
+ function readRunningCliVersion() {
217
+ try {
218
+ const pkg = JSON.parse(
219
+ fs.readFileSync(path.join(CLI_ROOT, 'package.json'), 'utf-8'),
220
+ );
221
+ return isValidSemver(pkg.version) ? pkg.version : null;
222
+ } catch {
223
+ return null;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Whether the installed Core is newer than this CLI, so part of the requested
229
+ * range has no codemods here.
230
+ *
231
+ * Core codemods ship inside the CLI. A CLI older than the installed
232
+ * `@astryxdesign/core` has none for the releases after its own version, so it
233
+ * can find no codemods, or stop partway, while the code still needs those
234
+ * releases' migrations. The returned command repeats this upgrade with the CLI
235
+ * release that matches the installed Core.
236
+ *
237
+ * Where an upgrade runs decides what it finds: the installed Core is read
238
+ * from that folder, and `--path` must stay inside it. So the command first
239
+ * changes to `cwd`, the folder this run used, then names `sourcePath`, the
240
+ * directory this run scanned, as an absolute `--path`. Both are named by their
241
+ * physical paths, with every symbolic link resolved: a shell's `cd` follows a
242
+ * link, but the CLI it starts reads its folder with every link resolved and
243
+ * checks `--path` against that. Pasted from any folder, the command finds the
244
+ * same Core and scans the same directory, even after a package runner moved
245
+ * this run (Yarn 1 runs `yarn astryx` at the project root). It is written for
246
+ * a POSIX shell, or for PowerShell on Windows (cmd.exe is not a target), with
247
+ * every argument quoted for that shell.
248
+ *
249
+ * Returns null when the CLI covers the whole range (`to` is not newer than
250
+ * both the CLI and `from`), when the CLI's own version cannot be read, or when
251
+ * the target is legacy `@xds/core`, which no CLI release shares a version with.
252
+ *
253
+ * @param {{from: string, to: string, packageName: string, options: UpgradeOptions, cwd: string, sourcePath: string}} input
254
+ * @returns {import('./upgrade.type.mjs').CliBehindCore | null}
255
+ */
256
+ export function detectCliBehindCore({
257
+ from,
258
+ to,
259
+ packageName,
260
+ options,
261
+ cwd,
262
+ sourcePath,
263
+ }) {
264
+ if (packageName !== '@astryxdesign/core') return null;
265
+ const cliVersion = readRunningCliVersion();
266
+ if (!cliVersion || !semverGt(to, cliVersion) || !semverGt(to, from)) {
267
+ return null;
268
+ }
269
+ const runFolder = path.resolve(cwd);
270
+ const folder = physicalFolder(runFolder);
271
+ const scanned = path.join(folder, path.relative(runFolder, sourcePath));
272
+ const args = ['upgrade', '--from', from, '--path', scanned];
273
+ if (options.codemod) args.push('--codemod', options.codemod);
274
+ for (const name of options.skipCodemod ?? []) {
275
+ args.push('--skip-codemod', name);
276
+ }
277
+ for (const spec of options.integration ?? []) {
278
+ args.push('--integration', spec);
279
+ }
280
+ if (options.force) args.push('--force');
281
+ if (options.installDeps) args.push('--install-deps');
282
+ if (options.apply) args.push('--apply');
283
+ const upgrade = [
284
+ getDlxPrefix(cwd),
285
+ ...[`${CLI_PACKAGE}@${to}`, ...args].map(arg => quoteCommandArgument(arg)),
286
+ ].join(' ');
287
+ return {cliVersion, command: commandInFolder(folder, upgrade)};
288
+ }
289
+
290
+ /**
291
+ * A folder as the operating system reports it to a process that runs there,
292
+ * with every symbolic link on the way resolved. Falls back to the path as
293
+ * given when it cannot be resolved.
294
+ * @param {string} dir an absolute folder
295
+ * @returns {string}
296
+ */
297
+ function physicalFolder(dir) {
298
+ try {
299
+ return fs.realpathSync(dir);
300
+ } catch {
301
+ return dir;
95
302
  }
96
- return null;
97
303
  }
98
304
 
99
305
  /**
@@ -181,16 +387,47 @@ export async function runPostCodemodHooks(hooks, context) {
181
387
  /**
182
388
  * @typedef {object} AgentDocsRefreshPlan
183
389
  * @property {string} cwd
390
+ * @property {string} [origin] the folder the command ran in, when the upgrade
391
+ * runs at a project root above it
184
392
  * @property {string|null} renderedBlock
185
393
  * @property {import('./upgrade.type.mjs').AgentDocsSummary} summary
186
394
  */
187
395
 
396
+ /**
397
+ * The advice to run `init`, phrased for where the command ran: when the
398
+ * upgrade runs at a project root above that folder, it names the root, so the
399
+ * agent docs are installed beside the project's package.json.
400
+ * @param {string} cwd the folder the upgrade runs at
401
+ * @param {string} [origin] the folder the command ran in
402
+ * @returns {string}
403
+ */
404
+ function initAdvice(cwd, origin) {
405
+ const command = `\`${formatCliCommand('astryx init --features agents')}\``;
406
+ if (origin == null) return command;
407
+ return `${command} in ${path.relative(origin, cwd) || '.'} (the project root)`;
408
+ }
409
+
410
+ /**
411
+ * Why upgrade leaves the agent docs of a project at the home folder or the
412
+ * top of a settings folder, and what to do instead. init refuses the same
413
+ * folder, so the line never points at it.
414
+ * @param {AgentDocsHomeError} err
415
+ * @param {'stale' | 'missing'} [state] whether a block is there to refresh
416
+ * @returns {string}
417
+ */
418
+ function homeRefusalLine(err, state = 'stale') {
419
+ const where = `${err.dir} is the home folder or a settings folder in it, which every project's agents read.`;
420
+ return state === 'missing'
421
+ ? `Agent docs not installed: ${where} To have agent docs, move the project into a folder of its own, or add the Astryx block to its agent file by hand.`
422
+ : `Agent docs not refreshed: ${where} To keep agent docs, move the project into a folder of its own; otherwise update or remove the Astryx block there by hand.`;
423
+ }
424
+
188
425
  /**
189
426
  * Compute the expected managed block and report staleness without writing.
190
427
  * Apply-mode callers commit the prepared bytes only after codemods and hooks
191
428
  * succeed.
192
429
  *
193
- * @param {{cwd: string, installedVersion: string, apply: boolean, fresh?: boolean}} ctx
430
+ * @param {{cwd: string, installedVersion: string, apply: boolean, fresh?: boolean, origin?: string}} ctx
194
431
  * @returns {Promise<AgentDocsRefreshPlan>}
195
432
  */
196
433
  export async function prepareAgentDocsRefresh({
@@ -198,6 +435,7 @@ export async function prepareAgentDocsRefresh({
198
435
  installedVersion,
199
436
  apply,
200
437
  fresh = false,
438
+ origin,
201
439
  }) {
202
440
  const initial = inspectAgentDocs(cwd, installedVersion);
203
441
  /** @type {import('./upgrade.type.mjs').AgentDocsSummary} */
@@ -211,11 +449,21 @@ export async function prepareAgentDocsRefresh({
211
449
  };
212
450
 
213
451
  if (initial.status === 'missing') {
452
+ // init writes nothing in a project at the home folder or the top of a
453
+ // settings folder, so it is not the remedy there (INV31).
454
+ try {
455
+ assertAgentDocsTarget(cwd);
456
+ } catch (err) {
457
+ if (!(err instanceof AgentDocsHomeError)) throw err;
458
+ summary.action = 'error';
459
+ logger.warn(homeRefusalLine(err, 'missing'));
460
+ return {cwd, origin, renderedBlock: null, summary};
461
+ }
214
462
  summary.action = 'nudge-init';
215
463
  logger.warn(
216
- `No Astryx agent-docs block found - AI agents have no component index. Run \`${formatCliCommand('astryx init --features agents')}\` to install it.`,
464
+ `No Astryx agent-docs block found - AI agents have no component index. Run ${initAdvice(cwd, origin)} to install it.`,
217
465
  );
218
- return {cwd, renderedBlock: null, summary};
466
+ return {cwd, origin, renderedBlock: null, summary};
219
467
  }
220
468
 
221
469
  let renderedBlock;
@@ -228,16 +476,30 @@ export async function prepareAgentDocsRefresh({
228
476
  summary.action = 'error';
229
477
  summary.files = initial.files.map(file => file.path);
230
478
  logger.warn(
231
- `Could not render the expected agent docs. Run \`${formatCliCommand('astryx init --features agents')}\` to update them manually.`,
479
+ `Could not render the expected agent docs. Run ${initAdvice(cwd, origin)} to update them manually.`,
232
480
  );
233
- return {cwd, renderedBlock: null, summary};
481
+ return {cwd, origin, renderedBlock: null, summary};
234
482
  }
235
483
 
236
484
  const inspection = inspectAgentDocs(cwd, installedVersion, renderedBlock);
237
485
  summary.status = inspection.status;
238
486
  summary.fromVersions = inspection.blockVersions;
239
487
  summary.files = inspection.staleFiles;
240
- if (inspection.status === 'current') return {cwd, renderedBlock, summary};
488
+ if (inspection.status === 'current') {
489
+ return {cwd, origin, renderedBlock, summary};
490
+ }
491
+
492
+ // A project at the home folder or the top of a settings folder is never
493
+ // refreshed (INV31): the dry run says so, as --apply does, rather than
494
+ // offering a refresh that would be refused.
495
+ try {
496
+ assertAgentDocsTarget(cwd);
497
+ } catch (err) {
498
+ if (!(err instanceof AgentDocsHomeError)) throw err;
499
+ summary.action = 'error';
500
+ logger.warn(homeRefusalLine(err));
501
+ return {cwd, origin, renderedBlock: null, summary};
502
+ }
241
503
 
242
504
  summary.action = 'would-refresh';
243
505
  if (!apply) {
@@ -245,7 +507,7 @@ export async function prepareAgentDocsRefresh({
245
507
  `Agent docs differ from the installed Astryx and integration configuration. Re-run with --apply to refresh (${summary.files.join(', ')}).`,
246
508
  );
247
509
  }
248
- return {cwd, renderedBlock, summary};
510
+ return {cwd, origin, renderedBlock, summary};
249
511
  }
250
512
 
251
513
  /**
@@ -254,7 +516,7 @@ export async function prepareAgentDocsRefresh({
254
516
  * @returns {import('./upgrade.type.mjs').AgentDocsSummary}
255
517
  */
256
518
  export function applyAgentDocsRefresh(plan) {
257
- const {cwd, renderedBlock, summary} = plan;
519
+ const {cwd, origin, renderedBlock, summary} = plan;
258
520
  if (summary.action !== 'would-refresh' || renderedBlock == null)
259
521
  return summary;
260
522
 
@@ -262,6 +524,9 @@ export function applyAgentDocsRefresh(plan) {
262
524
  const written = installAgentDocs(cwd, {
263
525
  onlyReplace: true,
264
526
  renderedBlock,
527
+ // A GEMINI.md that resolves outside the project is left as it is.
528
+ onSkipped: (file, reason) =>
529
+ logger.warn(`Note: ${file} left as it is (${reason}).`),
265
530
  });
266
531
  summary.refreshed = written.length > 0;
267
532
  summary.files = written;
@@ -270,15 +535,21 @@ export function applyAgentDocsRefresh(plan) {
270
535
  logger.log(`[ok] Agent docs refreshed -> ${written.join(', ')}`);
271
536
  } else {
272
537
  logger.warn(
273
- `Agent docs look stale but couldn't be refreshed. Run \`${formatCliCommand('astryx init --features agents')}\` to reinstall the block.`,
538
+ `Agent docs look stale but couldn't be refreshed. Run ${initAdvice(cwd, origin)} to reinstall the block.`,
274
539
  );
275
540
  }
276
- } catch {
541
+ } catch (err) {
277
542
  summary.action = 'error';
278
543
  summary.refreshed = false;
279
- logger.warn(
280
- `Could not refresh agent docs. Run \`${formatCliCommand('astryx init --features agents')}\` to update them manually.`,
281
- );
544
+ if (err instanceof AgentDocsHomeError) {
545
+ // init refuses this folder too, so pointing at it would loop: say why,
546
+ // and what to do instead.
547
+ logger.warn(homeRefusalLine(err));
548
+ } else {
549
+ logger.warn(
550
+ `Could not refresh agent docs. Run ${initAdvice(cwd, origin)} to update them manually.`,
551
+ );
552
+ }
282
553
  }
283
554
  return summary;
284
555
  }
@@ -332,11 +603,20 @@ export async function ensureCodemodDeps({installDeps} = {}) {
332
603
  * Run the CORE registry codemods. Runs BEFORE the config is loaded so a core
333
604
  * CONFIG codemod can repair a config the strict loader would otherwise reject.
334
605
  * @param {CoreVersionManifest[]} versionManifests
335
- * @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean}} options
606
+ * @param {{apply: boolean, path: string, codemod?: string, skipCodemods: Set<string>, root?: string, protection?: {root: string, classify: (file: string) => import('../../foundation/fs/file-protection.mjs').FileProtection[]}, silent?: boolean, coversTarget?: boolean}} options
336
607
  */
337
608
  export async function runCoreCodemods(
338
609
  versionManifests,
339
- {apply, path: srcPath, codemod, skipCodemods, root, protection, silent},
610
+ {
611
+ apply,
612
+ path: srcPath,
613
+ codemod,
614
+ skipCodemods,
615
+ root,
616
+ protection,
617
+ silent,
618
+ coversTarget,
619
+ },
340
620
  ) {
341
621
  return runCodemods(versionManifests, {
342
622
  apply,
@@ -346,6 +626,7 @@ export async function runCoreCodemods(
346
626
  silent: silent ?? logger.silent,
347
627
  root,
348
628
  protection,
629
+ coversTarget,
349
630
  });
350
631
  }
351
632
 
@@ -367,7 +648,7 @@ export async function loadProjectContext(cwd, extraIntegrationSpecs = []) {
367
648
  // The CLI debug preflight may already have imported this config before core
368
649
  // CONFIG codemods run. Upgrade needs the bytes now on disk, not that module
369
650
  // cache entry; ordinary Project discovery remains cached by default.
370
- const project = await Project.load(cwd, {fresh: true});
651
+ const project = await Project.load(cwd, {fresh: true, core: 'project'});
371
652
  const postCodemodHooks = project.config.hooks?.postCodemod ?? [];
372
653
  const configuredSpecs = new Set(project.integrations ?? []);
373
654
  // Configured packages come from Project, which has already resolved provider
@@ -411,7 +692,9 @@ export async function loadProjectContext(cwd, extraIntegrationSpecs = []) {
411
692
  const extras =
412
693
  extraSpecs.length === 0
413
694
  ? []
414
- : await loadIntegrations(extraSpecs, {resolveProviders: false});
695
+ : // Resolved from the project, as --integration names a package it
696
+ // installed, not from whichever folder the process started in.
697
+ await loadIntegrations(extraSpecs, {cwd, resolveProviders: false});
415
698
  const {integrations, ledger} = resolveProviders(
416
699
  [
417
700
  ...candidates,
@@ -4,14 +4,18 @@
4
4
  /** @param {string} root */
5
5
  export function discoverRegistryReceipts(root: string): string[];
6
6
  /**
7
+ * Reported paths are relative to the scanned source folder, or, when `origin`
8
+ * names the folder the command ran in below the project root `cwd`, to that
9
+ * folder, so they resolve from where the command ran.
7
10
  * @param {{apply?: boolean, path?: string}} options
8
- * @param {{cwd?: string, fetchImpl?: typeof fetch, registryOrigin?: string, expectedVersion?: string, requireExpectedVersion?: boolean}} [ctx]
11
+ * @param {{cwd?: string, origin?: string, fetchImpl?: typeof fetch, registryOrigin?: string, expectedVersion?: string, requireExpectedVersion?: boolean}} [ctx]
9
12
  */
10
13
  export function reconcileRegistryCompositions(options?: {
11
14
  apply?: boolean;
12
15
  path?: string;
13
- }, { cwd, fetchImpl, registryOrigin, expectedVersion, requireExpectedVersion, }?: {
16
+ }, { cwd, origin, fetchImpl, registryOrigin, expectedVersion, requireExpectedVersion, }?: {
14
17
  cwd?: string;
18
+ origin?: string;
15
19
  fetchImpl?: typeof fetch;
16
20
  registryOrigin?: string;
17
21
  expectedVersion?: string;
@@ -23,9 +27,10 @@ export function reconcileRegistryCompositions(options?: {
23
27
  /** @param {import('../upgrade.type.mjs').RegistryCompositionSummary} summary */
24
28
  export function logRegistryCompositionSummary(summary: import("../upgrade.type.mjs").RegistryCompositionSummary): void;
25
29
  /**
26
- * Standalone `astryx upgrade --registry` leaf.
30
+ * Standalone `astryx upgrade --registry` leaf. `ctx.origin` is the folder the
31
+ * command ran in, when `ctx.cwd` is the project root above it.
27
32
  * @param {{apply?: boolean, path?: string}} options
28
- * @param {{cwd?: string, fetchImpl?: typeof fetch, registryOrigin?: string, expectedVersion?: string, requireExpectedVersion?: boolean}} [ctx]
33
+ * @param {{cwd?: string, origin?: string, fetchImpl?: typeof fetch, registryOrigin?: string, expectedVersion?: string, requireExpectedVersion?: boolean}} [ctx]
29
34
  * @returns {Promise<import('../upgrade.type.mjs').UpgradeRegistryResponse>}
30
35
  */
31
36
  export function registryUpgrade(options?: {
@@ -33,6 +38,7 @@ export function registryUpgrade(options?: {
33
38
  path?: string;
34
39
  }, ctx?: {
35
40
  cwd?: string;
41
+ origin?: string;
36
42
  fetchImpl?: typeof fetch;
37
43
  registryOrigin?: string;
38
44
  expectedVersion?: string;