@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.2

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 (509) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +175 -154
  3. package/api/build/_adapter.d.mts +8 -0
  4. package/api/build/_adapter.mjs +12 -1
  5. package/api/build/build.doc.mjs +4 -0
  6. package/api/build/help/help.mjs +1 -1
  7. package/api/build/kit/kit.mjs +3 -11
  8. package/api/component/_adapter.d.mts +72 -1
  9. package/api/component/_adapter.mjs +212 -18
  10. package/api/component/component.doc.mjs +6 -1
  11. package/api/component/component.mjs +82 -15
  12. package/api/component/component.test.mjs +80 -0
  13. package/api/component/doc-links.test.mjs +386 -0
  14. package/api/component/integration-export-name.test.mjs +644 -0
  15. package/api/component/list/list.mjs +42 -4
  16. package/api/discover/_adapter.d.mts +132 -12
  17. package/api/discover/_adapter.mjs +488 -27
  18. package/api/discover/_adapter.test.mjs +599 -17
  19. package/api/discover/_catalog-view.d.mts +16 -5
  20. package/api/discover/_catalog-view.mjs +32 -8
  21. package/api/discover/detail/doc/doc.mjs +9 -1
  22. package/api/discover/discover.d.mts +11 -0
  23. package/api/discover/discover.doc.mjs +9 -7
  24. package/api/discover/discover.mjs +121 -19
  25. package/api/discover/discover.type.d.mts +20 -7
  26. package/api/discover/discover.type.mjs +17 -7
  27. package/api/discover/list/list.d.mts +4 -3
  28. package/api/discover/list/list.mjs +17 -10
  29. package/api/docs/_adapter.d.mts +74 -0
  30. package/api/docs/_adapter.mjs +553 -16
  31. package/api/docs/docs.doc.mjs +2 -1
  32. package/api/docs/docs.mjs +2 -1
  33. package/api/docs/docs.test.mjs +5 -2
  34. package/api/docs/integration-tree.test.mjs +22 -0
  35. package/api/docs/integrationDocs.test.mjs +124 -0
  36. package/api/docs/list/list.mjs +12 -2
  37. package/api/docs/reference-blocks.test.mjs +1 -3
  38. package/api/doctor/_adapter.d.mts +108 -0
  39. package/api/doctor/_adapter.mjs +223 -4
  40. package/api/doctor/doctor.d.mts +199 -0
  41. package/api/doctor/doctor.doc.mjs +3 -2
  42. package/api/doctor/doctor.mjs +530 -34
  43. package/api/doctor/doctor.test.mjs +180 -14
  44. package/api/doctor/release-checks.test.mjs +156 -0
  45. package/api/doctor/theme-checks.mjs +17 -4
  46. package/api/doctor/theme-checks.test.mjs +223 -7
  47. package/api/error.d.mts +10 -0
  48. package/api/error.mjs +25 -0
  49. package/api/gap-report/gap-report.d.mts +3 -0
  50. package/api/gap-report/gap-report.doc.mjs +11 -3
  51. package/api/gap-report/gap-report.mjs +219 -52
  52. package/api/gap-report/gap-report.test.mjs +233 -0
  53. package/api/gap-report/gap-report.type.d.mts +41 -0
  54. package/api/gap-report/gap-report.type.mjs +18 -0
  55. package/api/hook/_adapter.mjs +3 -11
  56. package/api/hook/hook.doc.mjs +4 -0
  57. package/api/hook/list/list.d.mts +1 -1
  58. package/api/index.d.mts +2 -0
  59. package/api/index.mjs +2 -0
  60. package/api/init/_adapter.d.mts +22 -0
  61. package/api/init/_adapter.mjs +59 -0
  62. package/api/init/init.d.mts +7 -5
  63. package/api/init/init.doc.mjs +28 -7
  64. package/api/init/init.mjs +28 -4
  65. package/api/init/init.type.d.mts +48 -3
  66. package/api/init/init.type.mjs +37 -3
  67. package/api/init/run/run.d.mts +1 -1
  68. package/api/init/run/run.mjs +17 -6
  69. package/api/init/user/user.d.mts +14 -0
  70. package/api/init/user/user.mjs +87 -0
  71. package/api/init/user/user.test.mjs +232 -0
  72. package/api/integration/_adapter.d.mts +45 -0
  73. package/api/integration/_adapter.mjs +112 -0
  74. package/api/integration/add-contribution.component-names.test.mjs +66 -0
  75. package/api/integration/add-contribution.mjs +8 -4
  76. package/api/integration/add-contribution.test.mjs +4 -2
  77. package/api/integration/authoring-checks.mjs +110 -6
  78. package/api/integration/authoring-checks.test.mjs +808 -0
  79. package/api/integration/authoring-checks.type.d.mts +143 -0
  80. package/api/integration/authoring-checks.type.mjs +74 -2
  81. package/api/integration/check/check.d.mts +96 -0
  82. package/api/integration/check/check.mjs +357 -0
  83. package/api/integration/check/check.test.mjs +489 -0
  84. package/api/integration/integration-check.type.d.mts +118 -0
  85. package/api/integration/integration-check.type.mjs +84 -0
  86. package/api/integration/integrationCheck.doc.d.mts +10 -0
  87. package/api/integration/integrationCheck.doc.mjs +73 -0
  88. package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
  89. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  90. package/api/integration/pack-check.mjs +364 -120
  91. package/api/integration/pack-check.test.mjs +730 -10
  92. package/api/integration/validate-integration-fixes.test.mjs +67 -0
  93. package/api/integration/validate-integration.d.mts +8 -0
  94. package/api/integration/validate-integration.mjs +63 -9
  95. package/api/integration/validate-integration.test.mjs +88 -8
  96. package/api/integration/validate-integration.type.d.mts +16 -0
  97. package/api/integration/validate-integration.type.mjs +14 -1
  98. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  99. package/api/integration/validateIntegration.doc.mjs +19 -3
  100. package/api/search/_adapter.d.mts +11 -0
  101. package/api/search/_adapter.mjs +25 -0
  102. package/api/search/search.d.mts +82 -13
  103. package/api/search/search.doc.mjs +8 -3
  104. package/api/search/search.domain-priority.test.mjs +108 -18
  105. package/api/search/search.integration-check.test.mjs +24 -0
  106. package/api/search/search.mjs +645 -64
  107. package/api/search/search.test.mjs +179 -1
  108. package/api/search/search.type.d.mts +14 -1
  109. package/api/search/search.type.mjs +6 -1
  110. package/api/swizzle/_adapter.mjs +2 -2
  111. package/api/swizzle/copy/copy.mjs +29 -15
  112. package/api/template/template-integration.test.mjs +1 -1
  113. package/api/template/template.test.mjs +120 -3
  114. package/api/theme/_adapter.d.mts +16 -0
  115. package/api/theme/_adapter.mjs +32 -5
  116. package/api/theme/build/build.d.mts +2 -1
  117. package/api/theme/build/build.family.test.mjs +64 -0
  118. package/api/theme/build/build.mjs +250 -38
  119. package/api/theme/build/build.packed-old-core.test.mjs +20 -3
  120. package/api/theme/build/font-warning.mjs +5 -3
  121. package/api/theme/build/font-warning.test.mjs +2 -1
  122. package/api/theme/remove/remove.test.mjs +2 -2
  123. package/api/theme/targets/targets.mjs +3 -10
  124. package/api/theme/themeBuild.doc.mjs +4 -4
  125. package/api/theme/themeTargets.doc.mjs +4 -0
  126. package/api/theme/use/use.test.mjs +1 -1
  127. package/api/upgrade/_adapter.d.mts +40 -2
  128. package/api/upgrade/_adapter.mjs +118 -5
  129. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  130. package/api/upgrade/run/run.mjs +35 -2
  131. package/api/upgrade/status/status.d.mts +21 -5
  132. package/api/upgrade/status/status.mjs +45 -8
  133. package/api/upgrade/upgrade.doc.mjs +6 -3
  134. package/api/upgrade/upgrade.mjs +5 -1
  135. package/api/upgrade/upgrade.type.d.mts +23 -0
  136. package/api/upgrade/upgrade.type.mjs +16 -1
  137. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  138. package/assets/codemods/registry.mjs +1 -0
  139. package/assets/codemods/runner.mjs +7 -1
  140. package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
  141. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  142. package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
  143. package/assets/discover/official-packages.json +367 -0
  144. package/assets/docs/README.md +10 -0
  145. package/assets/docs/author-a-theme.doc.mjs +3 -3
  146. package/assets/docs/browser-support.doc.mjs +1 -1
  147. package/assets/docs/getting-started.doc.mjs +26 -6
  148. package/assets/docs/styling-overview.doc.mjs +1 -1
  149. package/assets/docs/theme.doc.dense.mjs +1 -1
  150. package/assets/docs/theme.doc.mjs +2 -2
  151. package/assets/docs/theme.doc.zh.mjs +1 -1
  152. package/assets/docs/tree/add-a-component.doc.mjs +22 -2
  153. package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
  154. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  155. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  156. package/assets/docs/tree/block-template.doc.mjs +8 -20
  157. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  158. package/assets/docs/tree/building-blocks.doc.mjs +4 -0
  159. package/assets/docs/tree/check-the-props.doc.mjs +201 -0
  160. package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
  161. package/assets/docs/tree/checks.doc.mjs +32 -24
  162. package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
  163. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  164. package/assets/docs/tree/cli.doc.mjs +6 -0
  165. package/assets/docs/tree/codemods.doc.mjs +17 -7
  166. package/assets/docs/tree/commands.doc.mjs +7 -1
  167. package/assets/docs/tree/component-family.doc.mjs +8 -6
  168. package/assets/docs/tree/component-imports.doc.mjs +21 -3
  169. package/assets/docs/tree/components.doc.mjs +7 -1
  170. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  171. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  172. package/assets/docs/tree/configuration.doc.mjs +7 -3
  173. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  174. package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
  175. package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
  176. package/assets/docs/tree/docs.doc.mjs +9 -3
  177. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  178. package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
  179. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  180. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  181. package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
  182. package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
  183. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  184. package/assets/docs/tree/global.doc.mjs +131 -0
  185. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  186. package/assets/docs/tree/install-once.doc.mjs +105 -0
  187. package/assets/docs/tree/integrations.doc.mjs +13 -1
  188. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  189. package/assets/docs/tree/layout.doc.mjs +6 -6
  190. package/assets/docs/tree/links.doc.mjs +7 -6
  191. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  192. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  193. package/assets/docs/tree/migration.doc.mjs +0 -1
  194. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  195. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  196. package/assets/docs/tree/page-template.doc.mjs +4 -8
  197. package/assets/docs/tree/problems.doc.mjs +205 -0
  198. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  199. package/assets/docs/tree/publishing.doc.mjs +6 -6
  200. package/assets/docs/tree/quick-start.doc.mjs +53 -27
  201. package/assets/docs/tree/reference.doc.mjs +192 -0
  202. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  203. package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
  204. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  205. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  206. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  207. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  208. package/assets/docs/tree/single-component.doc.mjs +15 -6
  209. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  210. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  211. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  212. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  213. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  214. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  215. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  216. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  217. package/assets/docs/tree/templates.doc.mjs +7 -1
  218. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  219. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  220. package/assets/docs/tree/themes.doc.mjs +4 -0
  221. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  222. package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
  223. package/assets/docs/tree/type-scale.doc.mjs +3 -3
  224. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  225. package/assets/docs/tree/updates.doc.mjs +92 -0
  226. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  227. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
  228. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  229. package/assets/docs/tree/versioning.doc.mjs +10 -9
  230. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  231. package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
  232. package/assets/docs/use-a-theme.doc.mjs +2 -2
  233. package/assets/docs/working-with-ai.doc.mjs +66 -13
  234. package/assets/theme.template.ts +1 -1
  235. package/authoring/codemod/codemod.doc.mjs +7 -3
  236. package/authoring/config/config.doc.mjs +9 -6
  237. package/authoring/config/type.ts +4 -2
  238. package/authoring/debug/parse.d.mts +5 -5
  239. package/authoring/discover/discover.doc.mjs +7 -1
  240. package/authoring/doctypes/_schema.d.mts +8 -3
  241. package/authoring/doctypes/_schema.mjs +1 -0
  242. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  243. package/authoring/doctypes/command/command.doc.mjs +20 -12
  244. package/authoring/doctypes/command/type.ts +14 -0
  245. package/authoring/doctypes/component/component.doc.mjs +30 -27
  246. package/authoring/doctypes/component/type.ts +21 -8
  247. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  248. package/authoring/doctypes/function/function.doc.mjs +9 -8
  249. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  250. package/authoring/doctypes/hook/type.ts +4 -0
  251. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  252. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  253. package/authoring/doctypes/schema/schema.doc.mjs +9 -9
  254. package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
  255. package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
  256. package/authoring/doctypes/template/parse.d.mts +6 -2
  257. package/authoring/doctypes/template/parse.mjs +3 -1
  258. package/authoring/doctypes/template/template.doc.mjs +3 -3
  259. package/authoring/doctypes/template/type.ts +22 -0
  260. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  261. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  262. package/authoring/identity/identity.doc.mjs +3 -3
  263. package/authoring/index.d.ts +2 -0
  264. package/authoring/integration/integration.doc.mjs +30 -6
  265. package/authoring/integration/parse.test.mjs +21 -0
  266. package/authoring/integration/schema.d.mts +16 -3
  267. package/authoring/integration/schema.mjs +34 -2
  268. package/authoring/integration/type.ts +12 -0
  269. package/clients/cli/bin/astryx.mjs +20 -3
  270. package/clients/cli/cli-command.test.mjs +166 -0
  271. package/clients/cli/commands/blog.doc.mjs +1 -0
  272. package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
  273. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  274. package/clients/cli/commands/build-theme.mjs +26 -13
  275. package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
  276. package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
  277. package/clients/cli/commands/build.doc.mjs +1 -0
  278. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  279. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  280. package/clients/cli/commands/component.doc.mjs +1 -0
  281. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  282. package/clients/cli/commands/discover.doc.mjs +9 -1
  283. package/clients/cli/commands/discover.mjs +144 -93
  284. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  285. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  286. package/clients/cli/commands/docs.doc.mjs +1 -0
  287. package/clients/cli/commands/docs.mjs +49 -19
  288. package/clients/cli/commands/docs.test.mjs +2 -2
  289. package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
  290. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  291. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  292. package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
  293. package/clients/cli/commands/doctor-integration.test.mjs +888 -3
  294. package/clients/cli/commands/doctor.doc.mjs +12 -2
  295. package/clients/cli/commands/doctor.mjs +292 -7
  296. package/clients/cli/commands/doctor.test.mjs +10 -4
  297. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  298. package/clients/cli/commands/gap-report.mjs +24 -2
  299. package/clients/cli/commands/gap-report.test.mjs +79 -0
  300. package/clients/cli/commands/hook.doc.mjs +1 -0
  301. package/clients/cli/commands/init.behavior.test.mjs +5 -0
  302. package/clients/cli/commands/init.doc.mjs +29 -3
  303. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  304. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  305. package/clients/cli/commands/integration-check.doc.mjs +93 -0
  306. package/clients/cli/commands/integration-check.test.mjs +441 -0
  307. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  308. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  309. package/clients/cli/commands/integration.doc.mjs +6 -2
  310. package/clients/cli/commands/integration.mjs +119 -7
  311. package/clients/cli/commands/json-contract.test.mjs +11 -2
  312. package/clients/cli/commands/manifest.doc.mjs +1 -0
  313. package/clients/cli/commands/outside-project.test.mjs +774 -0
  314. package/clients/cli/commands/search.doc.mjs +1 -0
  315. package/clients/cli/commands/search.mjs +16 -11
  316. package/clients/cli/commands/search.test.mjs +429 -296
  317. package/clients/cli/commands/setup-nudge.test.mjs +102 -2
  318. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  319. package/clients/cli/commands/swizzle.mjs +5 -3
  320. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  321. package/clients/cli/commands/template.doc.mjs +1 -0
  322. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  323. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  324. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  325. package/clients/cli/commands/theme-build.doc.mjs +3 -2
  326. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  327. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  328. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  329. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  330. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  331. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  332. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  333. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  334. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  335. package/clients/cli/commands/upgrade.doc.mjs +22 -1
  336. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  337. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  338. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  339. package/clients/cli/index.mjs +112 -16
  340. package/clients/cli/lib/cli-error.mjs +4 -1
  341. package/clients/cli/lib/component-format.test.mjs +1 -1
  342. package/clients/cli/lib/define-command.mjs +2 -2
  343. package/clients/cli/lib/json-shim.mjs +3 -1
  344. package/clients/cli/lib/manifest.d.ts +9 -0
  345. package/clients/cli/lib/manifest.mjs +17 -1
  346. package/clients/cli/lib/manifest.test.mjs +25 -0
  347. package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
  348. package/foundation/agent-docs/agent-doc-state.mjs +66 -6
  349. package/foundation/agent-docs/agent-docs.d.mts +4 -3
  350. package/foundation/agent-docs/agent-docs.mjs +11 -9
  351. package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
  352. package/foundation/agent-docs/computer-agent-text.mjs +623 -0
  353. package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
  354. package/foundation/config/project.d.mts +35 -3
  355. package/foundation/config/project.mjs +226 -7
  356. package/foundation/config/project.test.mjs +66 -0
  357. package/foundation/config/theme-state.mjs +5 -4
  358. package/foundation/discovery/authoring-self-docs.mjs +2 -1
  359. package/foundation/discovery/cli-self-docs.mjs +20 -3
  360. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  361. package/foundation/discovery/component-discovery.d.mts +190 -10
  362. package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
  363. package/foundation/discovery/component-discovery.mjs +864 -56
  364. package/foundation/discovery/component-discovery.test.mjs +96 -0
  365. package/foundation/discovery/component-replacement.mjs +20 -1
  366. package/foundation/discovery/component-replacement.test.mjs +40 -0
  367. package/foundation/discovery/copied-passages.d.mts +216 -0
  368. package/foundation/discovery/copied-passages.mjs +720 -0
  369. package/foundation/discovery/copied-passages.test.mjs +124 -0
  370. package/foundation/discovery/doc-consistency.d.mts +34 -0
  371. package/foundation/discovery/doc-consistency.mjs +513 -0
  372. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  373. package/foundation/discovery/doc-fluff.d.mts +112 -0
  374. package/foundation/discovery/doc-fluff.mjs +328 -0
  375. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  376. package/foundation/discovery/doc-types.d.mts +157 -0
  377. package/foundation/discovery/doc-types.mjs +1231 -0
  378. package/foundation/discovery/doc-types.test.mjs +744 -0
  379. package/foundation/discovery/docs-discovery.d.mts +88 -0
  380. package/foundation/discovery/docs-discovery.mjs +83 -2
  381. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  382. package/foundation/discovery/integration-doc-files.mjs +231 -0
  383. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  384. package/foundation/discovery/module-exports.d.mts +27 -0
  385. package/foundation/discovery/module-exports.mjs +356 -31
  386. package/foundation/discovery/module-exports.test.mjs +172 -0
  387. package/foundation/discovery/package-tsconfig.d.mts +14 -0
  388. package/foundation/discovery/package-tsconfig.mjs +228 -0
  389. package/foundation/discovery/package-tsconfig.test.mjs +210 -0
  390. package/foundation/discovery/project-typescript.d.mts +32 -0
  391. package/foundation/discovery/project-typescript.mjs +89 -0
  392. package/foundation/discovery/prop-drift.d.mts +297 -0
  393. package/foundation/discovery/prop-drift.mjs +2428 -0
  394. package/foundation/discovery/prop-drift.test.mjs +2337 -0
  395. package/foundation/discovery/runner-allowlist.d.mts +40 -0
  396. package/foundation/discovery/runner-allowlist.mjs +53 -0
  397. package/foundation/discovery/stray-pointers.d.mts +52 -0
  398. package/foundation/discovery/stray-pointers.mjs +293 -0
  399. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  400. package/foundation/discovery/template-adapter.mjs +74 -5
  401. package/foundation/discovery/template-needs.mjs +5 -2
  402. package/foundation/discovery/theme-imports.mjs +8 -4
  403. package/foundation/discovery/theme-imports.test.mjs +1 -1
  404. package/foundation/discovery/type-match.d.mts +53 -0
  405. package/foundation/discovery/type-match.mjs +660 -0
  406. package/foundation/discovery/type-match.test.mjs +169 -0
  407. package/foundation/discovery/type-text.d.mts +68 -0
  408. package/foundation/discovery/type-text.mjs +658 -0
  409. package/foundation/discovery/type-text.test.mjs +196 -0
  410. package/foundation/discovery/unresolved-references.d.mts +62 -0
  411. package/foundation/discovery/unresolved-references.mjs +790 -0
  412. package/foundation/discovery/unresolved-references.test.mjs +567 -0
  413. package/foundation/doc-compiler/doc-loads.test.mjs +51 -1
  414. package/foundation/doc-compiler/inputs.mjs +27 -1
  415. package/foundation/doc-compiler/inputs.test.mjs +0 -1
  416. package/foundation/doc-compiler/links.d.mts +41 -5
  417. package/foundation/doc-compiler/links.mjs +167 -28
  418. package/foundation/doc-compiler/links.test.mjs +97 -4
  419. package/foundation/doc-compiler/read.d.mts +1 -1
  420. package/foundation/doc-compiler/tree.mjs +30 -1
  421. package/foundation/doc-compiler/tree.test.mjs +8 -1
  422. package/foundation/env/cli-command.d.mts +83 -0
  423. package/foundation/env/cli-command.mjs +152 -0
  424. package/foundation/env/cli-command.test.mjs +129 -0
  425. package/foundation/env/node-version.test.mjs +15 -3
  426. package/foundation/env/package-manager.d.mts +93 -9
  427. package/foundation/env/package-manager.global.test.mjs +66 -0
  428. package/foundation/env/package-manager.mjs +184 -13
  429. package/foundation/env/package-manager.test.mjs +341 -15
  430. package/foundation/env/project-scope.d.mts +9 -0
  431. package/foundation/env/project-scope.mjs +33 -0
  432. package/foundation/env/search-path.d.mts +42 -0
  433. package/foundation/env/search-path.mjs +205 -0
  434. package/foundation/env/search-path.test.mjs +122 -0
  435. package/foundation/env/user-dirs.d.mts +39 -0
  436. package/foundation/env/user-dirs.mjs +93 -0
  437. package/foundation/env/user-dirs.test.mjs +72 -0
  438. package/foundation/env/user-settings.d.mts +46 -0
  439. package/foundation/env/user-settings.mjs +106 -0
  440. package/foundation/env/user-settings.test.mjs +64 -0
  441. package/foundation/fs/file-protection.mjs +15 -1
  442. package/foundation/fs/module-loader.d.mts +2 -1
  443. package/foundation/fs/module-loader.mjs +60 -4
  444. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  445. package/foundation/fs/module-loader.test.mjs +194 -0
  446. package/foundation/fs/path-compare.d.mts +33 -0
  447. package/foundation/fs/path-compare.mjs +73 -0
  448. package/foundation/fs/paths.d.mts +57 -1
  449. package/foundation/fs/paths.mjs +131 -3
  450. package/foundation/fs/paths.test.mjs +10 -1
  451. package/foundation/integrations/computer-integrations.d.mts +78 -0
  452. package/foundation/integrations/computer-integrations.mjs +316 -0
  453. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  454. package/foundation/integrations/contribution-inventory.d.mts +11 -0
  455. package/foundation/integrations/contribution-inventory.mjs +56 -3
  456. package/foundation/integrations/integration-warnings.mjs +3 -2
  457. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  458. package/foundation/integrations/integrations.d.mts +25 -1
  459. package/foundation/integrations/integrations.mjs +46 -3
  460. package/foundation/integrations/issue.ts +6 -0
  461. package/foundation/integrations/validate-contributions.d.mts +2 -0
  462. package/foundation/integrations/validate-contributions.mjs +41 -1
  463. package/foundation/release/agent-text-worker.d.mts +4 -0
  464. package/foundation/release/agent-text-worker.mjs +52 -0
  465. package/foundation/release/cache.d.mts +310 -0
  466. package/foundation/release/cache.mjs +1216 -0
  467. package/foundation/release/cache.test.mjs +920 -0
  468. package/foundation/release/choose.d.mts +207 -0
  469. package/foundation/release/choose.mjs +677 -0
  470. package/foundation/release/choose.test.mjs +427 -0
  471. package/foundation/release/core-worker.d.mts +4 -0
  472. package/foundation/release/core-worker.mjs +38 -0
  473. package/foundation/release/global-state.d.mts +259 -0
  474. package/foundation/release/global-state.mjs +472 -0
  475. package/foundation/release/global-state.test.mjs +381 -0
  476. package/foundation/release/handoff.d.mts +60 -0
  477. package/foundation/release/handoff.e2e.test.mjs +278 -0
  478. package/foundation/release/handoff.mjs +357 -0
  479. package/foundation/release/lock-lease.d.mts +23 -0
  480. package/foundation/release/lock-lease.mjs +80 -0
  481. package/foundation/release/notices.d.mts +253 -0
  482. package/foundation/release/notices.mjs +596 -0
  483. package/foundation/release/notices.test.mjs +565 -0
  484. package/foundation/release/npm-guard.d.mts +4 -0
  485. package/foundation/release/npm-guard.mjs +126 -0
  486. package/foundation/release/project.d.mts +141 -0
  487. package/foundation/release/project.mjs +466 -0
  488. package/foundation/release/project.test.mjs +288 -0
  489. package/foundation/release/refresh-worker.d.mts +4 -0
  490. package/foundation/release/refresh-worker.mjs +27 -0
  491. package/foundation/release/run-context.d.mts +47 -0
  492. package/foundation/release/run-context.mjs +149 -0
  493. package/foundation/release/update-notice-env.d.mts +28 -0
  494. package/foundation/release/update-notice-env.mjs +39 -0
  495. package/foundation/response/base.d.ts +26 -3
  496. package/foundation/response/error-codes.d.mts +3 -1
  497. package/foundation/response/error-codes.doc.mjs +12 -0
  498. package/foundation/response/error-codes.mjs +17 -0
  499. package/foundation/response/error-codes.test.mjs +2 -0
  500. package/foundation/response/json-contract.test.mjs +7 -2
  501. package/foundation/response/json.mjs +4 -1
  502. package/foundation/response/response-types.doc.mjs +22 -11
  503. package/foundation/response/response-types.doc.test.mjs +46 -0
  504. package/foundation/response/response.doc.mjs +3 -3
  505. package/foundation/xle/browser-imports.test.mjs +74 -0
  506. package/foundation/xle/registry.mjs +4 -0
  507. package/foundation/xle/registry.test.mjs +28 -0
  508. package/package.json +11 -11
  509. package/scripts/postinstall.mjs +24 -5
@@ -34,7 +34,8 @@ export const doc = {
34
34
  'for a typed doc, `related` to the docs it names (its command or function, ' +
35
35
  'and its related docs); `previous` and `next` ' +
36
36
  'to the section or node before and after it. ' +
37
- 'Overlay options select localized or dense variants.',
37
+ 'Overlay options select localized or dense variants.' +
38
+ " In global mode: with `cwd` outside a project, doc topics from integrations installed next to this CLI package globally are listed too; inside a project, only the project's own integrations count. See {@link namespace:global} and {@link generic:computer-integrations}.",
38
39
  importPath: '@astryxdesign/cli/api',
39
40
  signature:
40
41
  'docs(topic?: string, section?: string, options?: DocsOptions): Promise<DocsListResponse | DocsIndexResponse | DocsDetailResponse | DocsDetailSectionResponse | DocsNodeResponse>',
package/api/docs/docs.mjs CHANGED
@@ -34,6 +34,7 @@ import {node as nodeLeaf, nodeView} from './node/node.mjs';
34
34
  import {resolveDocsArgument} from './_adapter.mjs';
35
35
  import {AstryxError} from '../error.mjs';
36
36
  import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
37
+ import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
37
38
 
38
39
  export {list, index, detail, sectionLeaf as section, nodeLeaf as node};
39
40
 
@@ -108,7 +109,7 @@ export async function docs(topic, section, options = {}) {
108
109
  return namespaceSection(found.tree, found.node, section, options);
109
110
  }
110
111
  throw new AstryxError(
111
- `"${found.node.route}" has no sections. Read it whole: astryx docs ${found.node.route}.`,
112
+ `"${found.node.route}" has no sections. Read it whole: ${formatCliCommand(`docs ${found.node.route}`)}.`,
112
113
  [{name: found.node.route, reason: found.node.summary}],
113
114
  ERROR_CODES.ERR_UNKNOWN_SECTION,
114
115
  );
@@ -11,6 +11,7 @@
11
11
  import {describe, it, expect} from 'vitest';
12
12
  import {docs} from './docs.mjs';
13
13
  import {AstryxError} from '../error.mjs';
14
+ import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
14
15
 
15
16
  const SLOW = 30_000;
16
17
 
@@ -92,7 +93,7 @@ describe('docs() dispatcher routing', () => {
92
93
 
93
94
  it("lists the docs tree's namespaces in meta, so every data entry reads as a topic", async () => {
94
95
  const res = await docs();
95
- expect(res.meta.namespaces.map(entry => entry.topic)).toEqual(['cli', 'internationalization', 'layout', 'migration', 'styling', 'styling-libraries', 'tokens', 'typography', 'unorganized']);
96
+ expect(res.meta.namespaces.map(entry => entry.topic)).toEqual(['cli', 'global', 'internationalization', 'layout', 'migration', 'styling', 'styling-libraries', 'tokens', 'typography', 'unorganized']);
96
97
  for (const entry of res.data) {
97
98
  expect((await docs(entry.topic)).type).toBe('docs.detail');
98
99
  }
@@ -107,7 +108,9 @@ describe('docs() dispatcher routing', () => {
107
108
  it('a section of a typed doc -> ERR_UNKNOWN_SECTION, suggesting the doc itself', async () => {
108
109
  const err = await docs('cli/api/functions/search', 'x').catch(e => e);
109
110
  expect(err.code).toBe('ERR_UNKNOWN_SECTION');
110
- expect(err.message).toContain('astryx docs cli/api/functions/search');
111
+ expect(err.message).toContain(
112
+ formatCliCommand('docs cli/api/functions/search'),
113
+ );
111
114
  expect(err.suggestions.map(s => s.name)).toEqual(['cli/api/functions/search']);
112
115
  }, SLOW);
113
116
 
@@ -569,4 +569,26 @@ describe('integration docs in the docs tree', () => {
569
569
  expect(check.status).toBe('warn');
570
570
  expect(check.message).toContain('both have the route "cli"');
571
571
  }, SLOW);
572
+
573
+ it('says what to write for a link that names a doc by its bare name, and when no doc has that name', async () => {
574
+ scaffold({
575
+ ...kit(),
576
+ 'bare.doc.mjs': guide('bare', {
577
+ sections: [
578
+ {
579
+ title: 'Overview',
580
+ content: [{type: 'prose', text: 'Read {@link deploy}, then {@link nosuchtopic}.'}],
581
+ },
582
+ ],
583
+ }),
584
+ });
585
+ const result = await integrationDocConflicts('@acme/kit', {cwd: tmpDir});
586
+ const graph = result.data.issues.filter(issue => issue.code === 'invalid_doc_graph').map(issue => issue.message);
587
+ expect(graph).toEqual(
588
+ expect.arrayContaining([
589
+ expect.stringContaining('"deploy" is a topic: write `{@link generic:deploy}`.'),
590
+ expect.stringContaining('no topic is named "nosuchtopic"'),
591
+ ]),
592
+ );
593
+ }, SLOW);
572
594
  });
@@ -22,6 +22,7 @@ import {docs} from './docs.mjs';
22
22
  import {search} from '../search/search.mjs';
23
23
  import {loadDocsCatalog} from './_adapter.mjs';
24
24
  import {AstryxError} from '../error.mjs';
25
+ import {discoverCoreTemplates} from '../../foundation/discovery/template-adapter.mjs';
25
26
 
26
27
  const SLOW = 30_000;
27
28
 
@@ -110,6 +111,129 @@ describe('integration-contributed topics', () => {
110
111
  expect(section.data.title).toBe('Overview');
111
112
  }, SLOW);
112
113
 
114
+ it('reads a link to a component or a template as the command that opens it', async () => {
115
+ scaffold({
116
+ 'using-widgets.doc.mjs': topic({
117
+ name: 'using-widgets',
118
+ title: 'Using widgets',
119
+ sections: [
120
+ {
121
+ title: 'Overview',
122
+ content: [
123
+ {
124
+ type: 'prose',
125
+ text: 'Start with {@link component:AcmeButton} or {@link block:acme-card}, built on {@link @astryxdesign/core:component:Button}.',
126
+ },
127
+ ],
128
+ },
129
+ ],
130
+ }),
131
+ });
132
+ const pkgDir = path.join(tmpDir, 'node_modules', '@acme', 'widgets');
133
+ fs.writeFileSync(
134
+ path.join(pkgDir, 'astryx.integration.mjs'),
135
+ "export default {components: './components', templates: './templates', docs: './docs'};\n",
136
+ );
137
+ fs.mkdirSync(path.join(pkgDir, 'components'));
138
+ fs.writeFileSync(
139
+ path.join(pkgDir, 'components', 'AcmeButton.doc.mjs'),
140
+ "export default {type: 'component', name: 'AcmeButton', displayName: 'Acme Button', description: 'A button.', props: []};\n",
141
+ );
142
+ fs.writeFileSync(
143
+ path.join(pkgDir, 'components', 'AcmeButton.tsx'),
144
+ 'export function AcmeButton() { return null; }\n',
145
+ );
146
+ fs.mkdirSync(path.join(pkgDir, 'templates'));
147
+ fs.writeFileSync(
148
+ path.join(pkgDir, 'templates', 'acme-card.doc.mjs'),
149
+ "export default {type: 'block', name: 'Acme card', description: 'A card.'};\n",
150
+ );
151
+ fs.writeFileSync(
152
+ path.join(pkgDir, 'templates', 'acme-card.tsx'),
153
+ 'export default function Fixture() { return null; }\n',
154
+ );
155
+
156
+ const detail = await docs('using-widgets', undefined, {cwd: tmpDir, full: true});
157
+
158
+ const prose = JSON.stringify(detail.data.sections);
159
+ expect(prose).toContain('`astryx component AcmeButton --package @acme/widgets`');
160
+ expect(prose).toContain(
161
+ '`astryx template acme-card --type block --package @acme/widgets`',
162
+ );
163
+ expect(prose).toContain('`astryx component Button`');
164
+ expect(prose).not.toContain('{@link');
165
+ }, SLOW);
166
+
167
+ it('selects Core in a link only where the bare name would open something else', async () => {
168
+ const core = await discoverCoreTemplates();
169
+ const page = core.find(template => template.type === 'page')?.dirName;
170
+ const block = core.find(template => template.type === 'block')?.dirName;
171
+ scaffold({
172
+ 'using-widgets.doc.mjs': topic({
173
+ name: 'using-widgets',
174
+ title: 'Using widgets',
175
+ sections: [
176
+ {
177
+ title: 'Overview',
178
+ content: [
179
+ {
180
+ type: 'prose',
181
+ text:
182
+ 'Core: {@link @astryxdesign/core:component:Button}, {@link @astryxdesign/core:component:Badge}, ' +
183
+ `{@link @astryxdesign/core:page:${page}}, {@link @astryxdesign/core:block:${block}}.`,
184
+ },
185
+ ],
186
+ },
187
+ ],
188
+ }),
189
+ });
190
+ const pkgDir = path.join(tmpDir, 'node_modules', '@acme', 'widgets');
191
+ // The CLI range that turns component replacement on.
192
+ fs.writeFileSync(
193
+ path.join(pkgDir, 'package.json'),
194
+ JSON.stringify({
195
+ name: '@acme/widgets',
196
+ version: '1.0.0',
197
+ peerDependencies: {'@astryxdesign/cli': '>=0.6.7'},
198
+ peerDependenciesMeta: {'@astryxdesign/cli': {optional: true}},
199
+ }),
200
+ );
201
+ fs.writeFileSync(
202
+ path.join(pkgDir, 'astryx.integration.mjs'),
203
+ "export default {components: './components', templates: './templates', docs: './docs'};\n",
204
+ );
205
+ fs.mkdirSync(path.join(pkgDir, 'components'));
206
+ // AcmeButton replaces Core's Button, so bare `Button` opens AcmeButton.
207
+ fs.writeFileSync(
208
+ path.join(pkgDir, 'components', 'AcmeButton.doc.mjs'),
209
+ "export default {type: 'component', name: 'AcmeButton', displayName: 'Acme Button', description: 'A button.', replaces: 'Button', props: []};\n",
210
+ );
211
+ fs.writeFileSync(
212
+ path.join(pkgDir, 'components', 'AcmeButton.tsx'),
213
+ 'export function AcmeButton() { return null; }\n',
214
+ );
215
+ // A page template with a Core page's id makes the bare id ambiguous.
216
+ fs.mkdirSync(path.join(pkgDir, 'templates'));
217
+ fs.writeFileSync(
218
+ path.join(pkgDir, 'templates', `${page}.doc.mjs`),
219
+ "export default {type: 'page', name: 'Acme page', displayName: 'Acme page', description: 'A page.'};\n",
220
+ );
221
+ fs.writeFileSync(
222
+ path.join(pkgDir, 'templates', `${page}.tsx`),
223
+ 'export default function Fixture() { return null; }\n',
224
+ );
225
+
226
+ const detail = await docs('using-widgets', undefined, {cwd: tmpDir, full: true});
227
+
228
+ const prose = JSON.stringify(detail.data.sections);
229
+ expect(prose).toContain('`astryx component Button --package @astryxdesign/core`');
230
+ expect(prose).toContain('`astryx component Badge`');
231
+ expect(prose).toContain(
232
+ `\`astryx template ${page} --type page --package @astryxdesign/core\``,
233
+ );
234
+ expect(prose).toContain(`\`astryx template ${block} --type block\``);
235
+ }, SLOW);
236
+
113
237
  it('is invisible to a project that does not configure the integration', async () => {
114
238
  scaffold({'deploying.doc.mjs': topic()}, {config: 'export default {};\n'});
115
239
  const listed = await docs(undefined, undefined, {cwd: tmpDir});
@@ -15,7 +15,12 @@
15
15
  */
16
16
 
17
17
  import {loadTopicFile} from '../../../foundation/doc-compiler/read.mjs';
18
- import {holdsOwnName, loadDocsCatalog, projectTree} from '../_adapter.mjs';
18
+ import {
19
+ holdsOwnName,
20
+ linkDocText,
21
+ loadDocsCatalog,
22
+ projectTree,
23
+ } from '../_adapter.mjs';
19
24
 
20
25
  /**
21
26
  * @param {object} [options]
@@ -39,7 +44,12 @@ export async function list({cwd} = {}) {
39
44
  /** @type {import('../docs.type.mjs').DocsListEntry} */
40
45
  const listed = {
41
46
  topic: entry.name,
42
- description,
47
+ // A link in the description reads as the command that opens its doc.
48
+ description: await linkDocText(
49
+ catalog,
50
+ entry.providerId ?? entry.package,
51
+ description,
52
+ ),
43
53
  package: entry.package,
44
54
  };
45
55
  if (entry.replaces != null) listed.replaces = entry.replaces;
@@ -276,9 +276,7 @@ describe('a reference block in a topic section', () => {
276
276
  expect(status).toBe(0);
277
277
  expect(stdout).toMatch(/^Field +\| Type +\| Required +\| Description/m);
278
278
  expect(stdout).toMatch(/^components +\| string +\| no +\| /m);
279
- expect(stdout).toContain(
280
- 'From Astryx Integration: `astryx docs authoring integration`',
281
- );
279
+ expect(stdout).toContain(' docs authoring integration`');
282
280
  },
283
281
  SLOW,
284
282
  );
@@ -43,8 +43,116 @@ export function findDoctorInstalledPackage(projectDir: string, packageName: stri
43
43
  export function listDoctorThemePackages(cwd: string): string[];
44
44
  /** @param {string} file */
45
45
  export function readPackageJson(file: string): any;
46
+ /**
47
+ * The integrations installed for the computer, and, outside a project, which
48
+ * of them the folder loads (spec AST-081 FR12): those it uses, and the names
49
+ * of the integrations the folder loads itself, whose copies win.
50
+ * @param {string} cwd
51
+ * @returns {Promise<{computerIntegrations: import('../../foundation/integrations/computer-integrations.mjs').ComputerIntegrationCandidate[], loadedComputerIntegrations: string[], folderIntegrations: string[]}>}
52
+ */
53
+ export function computerIntegrationsOutside(cwd: string): Promise<{
54
+ computerIntegrations: import("../../foundation/integrations/computer-integrations.mjs").ComputerIntegrationCandidate[];
55
+ loadedComputerIntegrations: string[];
56
+ folderIntegrations: string[];
57
+ }>;
58
+ /**
59
+ * Inside a project: the integrations installed for the computer it could add
60
+ * (spec AST-081 FR12), leaving out every package it loads or declares.
61
+ * @param {string} cwd
62
+ * @param {string[]} loadedNames the integrations the project loads
63
+ * @returns {Promise<import('../../foundation/integrations/computer-integrations.mjs').ComputerIntegrationCandidate[]>}
64
+ */
65
+ export function computerIntegrationsToAdd(cwd: string, loadedNames: string[]): Promise<import("../../foundation/integrations/computer-integrations.mjs").ComputerIntegrationCandidate[]>;
66
+ /**
67
+ * The computer-level agent text's setting and its state on disk.
68
+ * @returns {{settings: import('../../foundation/env/user-settings.mjs').ComputerAgentTextSettings, entries: Array<{path: string, state: import('../../foundation/agent-docs/computer-agent-text.mjs').ComputerAgentTextState, link?: true}>}}
69
+ */
70
+ export function computerAgentTextState(): {
71
+ settings: import("../../foundation/env/user-settings.mjs").ComputerAgentTextSettings;
72
+ entries: Array<{
73
+ path: string;
74
+ state: import("../../foundation/agent-docs/computer-agent-text.mjs").ComputerAgentTextState;
75
+ link?: true;
76
+ }>;
77
+ };
78
+ /**
79
+ * The release facts doctor reports, read here so the checks stay pure
80
+ * (spec AST-081 FR5, FR6, FR10; architecture:cli-surface INV21): who
81
+ * answered, the newest release the computer knows of, how far the global copy
82
+ * or the project is behind, and every `astryx` on the search path with the
83
+ * command that upgrades it.
84
+ * @param {string} cwd
85
+ * @param {{project: boolean}} options
86
+ * @returns {{answeredBy: {cli: string, core: string | null, copy: string}, latest: string | null, globalBehind: ReturnType<typeof globalBehind> | null, projectLag: ReturnType<typeof projectLag> | null, lastNoticeSkip: ReturnType<typeof lastNoticeSkip>, lastCheckFailure: ReturnType<typeof lastCheckFailure>, stateLock: ReturnType<typeof stateLockHolder>, searchPathCommands: Array<import('../../foundation/env/search-path.mjs').SearchPathCommand & {upgrade: string | null}>}}
87
+ */
88
+ export function releaseFacts(cwd: string, { project }: {
89
+ project: boolean;
90
+ }): {
91
+ answeredBy: {
92
+ cli: string;
93
+ core: string | null;
94
+ copy: string;
95
+ };
96
+ latest: string | null;
97
+ globalBehind: ReturnType<typeof globalBehind> | null;
98
+ projectLag: ReturnType<typeof projectLag> | null;
99
+ lastNoticeSkip: ReturnType<typeof lastNoticeSkip>;
100
+ lastCheckFailure: ReturnType<typeof lastCheckFailure>;
101
+ stateLock: ReturnType<typeof stateLockHolder>;
102
+ searchPathCommands: Array<import("../../foundation/env/search-path.mjs").SearchPathCommand & {
103
+ upgrade: string | null;
104
+ }>;
105
+ };
106
+ /** Whether `cwd` is outside every project. */
107
+ export function outsideProject(cwd: string): boolean;
108
+ /**
109
+ * The commands that bring a project's own CLI and Core to one release, with
110
+ * the project's package manager: Core up to the CLI, then its codemods, when
111
+ * the CLI is newer; else the CLI to the Core's release.
112
+ * @param {string} cwd
113
+ * @param {string} cli
114
+ * @param {string} core
115
+ * @returns {string}
116
+ */
117
+ export function alignCommand(cwd: string, cli: string, core: string): string;
118
+ /**
119
+ * The Core release the project at `cwd` names: installed, else locked, else
120
+ * declared; the version the daily hint and notice compare against (spec
121
+ * AST-081 FR2). Null outside a project or when it names none.
122
+ * @param {string} cwd
123
+ * @returns {string | null}
124
+ */
125
+ export function projectCoreVersion(cwd: string): string | null;
126
+ /**
127
+ * Whether the project at `cwd` installs its own CLI (spec AST-081 FR2).
128
+ * @param {string} cwd
129
+ * @returns {boolean}
130
+ */
131
+ export function projectHasOwnCli(cwd: string): boolean;
132
+ /**
133
+ * The command that adds the CLI at `version` with the project's package
134
+ * manager.
135
+ * @param {string} cwd
136
+ * @param {string} version
137
+ * @returns {string}
138
+ */
139
+ export function addCliCommandFor(cwd: string, version: string): string;
140
+ /**
141
+ * The command that adds a package with the folder's package manager, read
142
+ * from its lockfiles and `packageManager` field.
143
+ * @param {string} cwd
144
+ * @returns {(name: string) => string}
145
+ */
146
+ export function installCommandFor(cwd: string): (name: string) => string;
46
147
  export { resolveRecordedTheme } from "../theme/theme.mjs";
47
148
  export { collectUnloadedFonts } from "../theme/build/font-warning.mjs";
48
149
  export const SOURCE_EXTENSIONS: Set<string>;
150
+ export { displayHomePath };
151
+ import { globalBehind } from '../../foundation/release/notices.mjs';
152
+ import { projectLag } from '../../foundation/release/notices.mjs';
153
+ import { lastNoticeSkip } from '../../foundation/release/notices.mjs';
154
+ import { lastCheckFailure } from '../../foundation/release/global-state.mjs';
155
+ import { stateLockHolder } from '../../foundation/release/global-state.mjs';
156
+ import { displayHomePath } from '../../foundation/agent-docs/computer-agent-text.mjs';
49
157
  export { isLocalThemeOwner, planThemeAppWrite, readThemeState, resolveThemeModule } from "../../foundation/config/theme-state.mjs";
50
158
  export { themeBuild, validateThemePrivateInputs } from "../theme/build/build.mjs";
@@ -2,15 +2,52 @@
2
2
 
3
3
  /** @file Environment adapter for app-theme doctor evidence. */
4
4
 
5
+ import {isOutsideProject} from '../../foundation/env/project-scope.mjs';
6
+ import {answeredBy} from '../../foundation/release/run-context.mjs';
7
+ import {
8
+ knownLatestRelease,
9
+ lastCheckFailure,
10
+ stateLockHolder,
11
+ } from '../../foundation/release/global-state.mjs';
12
+ import {
13
+ addCliCommand,
14
+ alignCliAndCore,
15
+ globalBehind,
16
+ globalUpgradeCommand,
17
+ lastNoticeSkip,
18
+ projectLag,
19
+ } from '../../foundation/release/notices.mjs';
20
+ import {
21
+ coreVersionOf,
22
+ isGlobalCopy,
23
+ projectRootOf,
24
+ } from '../../foundation/release/choose.mjs';
25
+ import {readReleaseFacts} from '../../foundation/release/project.mjs';
26
+ import {detectPackageManager} from '../../foundation/env/package-manager.mjs';
27
+ import {astryxCommandsOnSearchPath} from '../../foundation/env/search-path.mjs';
28
+ import {readDeclaredDependencies} from '../../foundation/integrations/autolink.mjs';
29
+ import {
30
+ displayHomePath,
31
+ inspectComputerAgentText,
32
+ } from '../../foundation/agent-docs/computer-agent-text.mjs';
33
+ import {computerAgentTextSettings} from '../../foundation/env/user-settings.mjs';
5
34
  import * as fs from 'node:fs';
6
35
  import * as path from 'node:path';
7
- import {Project} from '../../foundation/config/project.mjs';
36
+ import {
37
+ Project,
38
+ availableComputerIntegrations,
39
+ computerIntegrationCandidates,
40
+ } from '../../foundation/config/project.mjs';
8
41
  import {
9
42
  discoverUnmigratedThemeCopies,
10
43
  themeImportPackage,
11
44
  } from '../../foundation/discovery/theme-discovery.mjs';
12
45
  import {resolveThemeImports} from '../../foundation/discovery/theme-imports.mjs';
13
- import {findCoreDir, findInstalledPackage} from '../../foundation/fs/paths.mjs';
46
+ import {
47
+ CLI_ROOT,
48
+ findProjectCoreDir,
49
+ findInstalledPackage,
50
+ } from '../../foundation/fs/paths.mjs';
14
51
  export {
15
52
  isLocalThemeOwner,
16
53
  planThemeAppWrite,
@@ -104,7 +141,7 @@ export function listProjectSourceFiles(root, generatedModule) {
104
141
 
105
142
  /** @param {string} projectDir */
106
143
  export async function discoverDoctorThemes(projectDir) {
107
- const project = await Project.load(projectDir);
144
+ const project = await Project.load(projectDir, {core: 'project'});
108
145
  return project.themes();
109
146
  }
110
147
 
@@ -124,7 +161,7 @@ export function discoverDoctorUnmigratedCopies(projectDir) {
124
161
 
125
162
  /** @param {string} projectDir */
126
163
  export function findDoctorCoreDir(projectDir) {
127
- return findCoreDir(projectDir);
164
+ return findProjectCoreDir(projectDir);
128
165
  }
129
166
 
130
167
  /** @param {string} projectDir @param {string} packageName */
@@ -188,3 +225,185 @@ export function readPackageJson(file) {
188
225
  return null;
189
226
  }
190
227
  }
228
+
229
+ /**
230
+ * The integrations installed for the computer, and, outside a project, which
231
+ * of them the folder loads (spec AST-081 FR12): those it uses, and the names
232
+ * of the integrations the folder loads itself, whose copies win.
233
+ * @param {string} cwd
234
+ * @returns {Promise<{computerIntegrations: import('../../foundation/integrations/computer-integrations.mjs').ComputerIntegrationCandidate[], loadedComputerIntegrations: string[], folderIntegrations: string[]}>}
235
+ */
236
+ export async function computerIntegrationsOutside(cwd) {
237
+ const computerIntegrations = computerIntegrationCandidates(cwd);
238
+ if (computerIntegrations.length === 0) {
239
+ return {
240
+ computerIntegrations,
241
+ loadedComputerIntegrations: [],
242
+ folderIntegrations: [],
243
+ };
244
+ }
245
+ try {
246
+ const project = await Project.load(cwd, {core: 'project'});
247
+ /** @type {Array<{name: string, __computer?: boolean, __loadError?: string}>} */
248
+ const loaded = project.loadedIntegrations;
249
+ return {
250
+ computerIntegrations,
251
+ loadedComputerIntegrations: loaded
252
+ .filter(i => i.__computer && !i.__loadError)
253
+ .map(i => i.name),
254
+ folderIntegrations: loaded.filter(i => !i.__computer).map(i => i.name),
255
+ };
256
+ } catch {
257
+ return {
258
+ computerIntegrations,
259
+ loadedComputerIntegrations: [],
260
+ folderIntegrations: [],
261
+ };
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Inside a project: the integrations installed for the computer it could add
267
+ * (spec AST-081 FR12), leaving out every package it loads or declares.
268
+ * @param {string} cwd
269
+ * @param {string[]} loadedNames the integrations the project loads
270
+ * @returns {Promise<import('../../foundation/integrations/computer-integrations.mjs').ComputerIntegrationCandidate[]>}
271
+ */
272
+ export async function computerIntegrationsToAdd(cwd, loadedNames) {
273
+ const installed = new Set([...loadedNames, ...declaredPackageNames(cwd)]);
274
+ return availableComputerIntegrations(cwd, installed);
275
+ }
276
+
277
+ /**
278
+ * The package names the folder's package.json declares, nearest first.
279
+ * @param {string} cwd
280
+ * @returns {string[]}
281
+ */
282
+ function declaredPackageNames(cwd) {
283
+ for (let dir = path.resolve(cwd); ;) {
284
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
285
+ return readDeclaredDependencies(dir).map(d => d.name);
286
+ }
287
+ const parent = path.dirname(dir);
288
+ if (parent === dir) return [];
289
+ dir = parent;
290
+ }
291
+ }
292
+
293
+ /**
294
+ * The computer-level agent text's setting and its state on disk.
295
+ * @returns {{settings: import('../../foundation/env/user-settings.mjs').ComputerAgentTextSettings, entries: Array<{path: string, state: import('../../foundation/agent-docs/computer-agent-text.mjs').ComputerAgentTextState, link?: true}>}}
296
+ */
297
+ export function computerAgentTextState() {
298
+ const settings = computerAgentTextSettings();
299
+ return {settings, entries: inspectComputerAgentText({links: settings.links})};
300
+ }
301
+
302
+ export {displayHomePath};
303
+
304
+ /**
305
+ * The release facts doctor reports, read here so the checks stay pure
306
+ * (spec AST-081 FR5, FR6, FR10; architecture:cli-surface INV21): who
307
+ * answered, the newest release the computer knows of, how far the global copy
308
+ * or the project is behind, and every `astryx` on the search path with the
309
+ * command that upgrades it.
310
+ * @param {string} cwd
311
+ * @param {{project: boolean}} options
312
+ * @returns {{answeredBy: {cli: string, core: string | null, copy: string}, latest: string | null, globalBehind: ReturnType<typeof globalBehind> | null, projectLag: ReturnType<typeof projectLag> | null, lastNoticeSkip: ReturnType<typeof lastNoticeSkip>, lastCheckFailure: ReturnType<typeof lastCheckFailure>, stateLock: ReturnType<typeof stateLockHolder>, searchPathCommands: Array<import('../../foundation/env/search-path.mjs').SearchPathCommand & {upgrade: string | null}>}}
313
+ */
314
+ export function releaseFacts(cwd, {project}) {
315
+ const answered = answeredBy(cwd);
316
+ return {
317
+ answeredBy: answered,
318
+ latest: knownLatestRelease(),
319
+ lastNoticeSkip: lastNoticeSkip(),
320
+ lastCheckFailure: lastCheckFailure(),
321
+ stateLock: stateLockHolder(),
322
+ globalBehind:
323
+ !project && isGlobalCopy(CLI_ROOT)
324
+ ? globalBehind({self: {version: answered.cli, root: CLI_ROOT}})
325
+ : null,
326
+ // The project's version is its own CLI's, or, with none, its Core's:
327
+ // installed, else locked, else declared, as the daily notice reads it.
328
+ projectLag: project
329
+ ? projectLag({
330
+ cwd,
331
+ current:
332
+ (answered.copy === 'starting' && projectCoreVersion(cwd)) ||
333
+ answered.cli,
334
+ })
335
+ : null,
336
+ searchPathCommands: astryxCommandsOnSearchPath().map(row => ({
337
+ ...row,
338
+ upgrade: row.cliRoot ? globalUpgradeCommand(row.cliRoot) : null,
339
+ })),
340
+ };
341
+ }
342
+
343
+ /** Whether `cwd` is outside every project. */
344
+ export function outsideProject(/** @type {string} */ cwd) {
345
+ return isOutsideProject(cwd);
346
+ }
347
+
348
+ /**
349
+ * The commands that bring a project's own CLI and Core to one release, with
350
+ * the project's package manager: Core up to the CLI, then its codemods, when
351
+ * the CLI is newer; else the CLI to the Core's release.
352
+ * @param {string} cwd
353
+ * @param {string} cli
354
+ * @param {string} core
355
+ * @returns {string}
356
+ */
357
+ export function alignCommand(cwd, cli, core) {
358
+ return alignCliAndCore({cwd, cli, core});
359
+ }
360
+
361
+ /**
362
+ * The Core release the project at `cwd` names: installed, else locked, else
363
+ * declared; the version the daily hint and notice compare against (spec
364
+ * AST-081 FR2). Null outside a project or when it names none.
365
+ * @param {string} cwd
366
+ * @returns {string | null}
367
+ */
368
+ export function projectCoreVersion(cwd) {
369
+ return coreVersionOf(readReleaseFacts(cwd));
370
+ }
371
+
372
+ /**
373
+ * Whether the project at `cwd` installs its own CLI (spec AST-081 FR2).
374
+ * @param {string} cwd
375
+ * @returns {boolean}
376
+ */
377
+ export function projectHasOwnCli(cwd) {
378
+ return Boolean(readReleaseFacts(cwd).cli);
379
+ }
380
+
381
+ /**
382
+ * The command that adds the CLI at `version` with the project's package
383
+ * manager.
384
+ * @param {string} cwd
385
+ * @param {string} version
386
+ * @returns {string}
387
+ */
388
+ export function addCliCommandFor(cwd, version) {
389
+ return addCliCommand(projectRootOf(readReleaseFacts(cwd)) ?? cwd, version);
390
+ }
391
+
392
+ /**
393
+ * The command that adds a package with the folder's package manager, read
394
+ * from its lockfiles and `packageManager` field.
395
+ * @param {string} cwd
396
+ * @returns {(name: string) => string}
397
+ */
398
+ export function installCommandFor(cwd) {
399
+ const pm = detectPackageManager(cwd);
400
+ const verb =
401
+ pm === 'pnpm'
402
+ ? 'pnpm add'
403
+ : pm === 'yarn'
404
+ ? 'yarn add'
405
+ : pm === 'bun'
406
+ ? 'bun add'
407
+ : 'npm install';
408
+ return name => `${verb} ${name}`;
409
+ }