@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
@@ -88,6 +88,8 @@
88
88
  * | 'ERR_LAYOUT_INVALID'
89
89
  * | 'ERR_UNCLASSIFIED_EXIT'
90
90
  * | 'ERR_SIGNAL_TERMINATED'
91
+ * | 'ERR_VERSIONS_UNAVAILABLE'
92
+ * | 'ERR_PROJECT_REQUIRED'
91
93
  * )} ErrorCode
92
94
  */
93
95
 
@@ -236,6 +238,21 @@ export const ERROR_CODES = Object.freeze({
236
238
  * command never reached a terminal path of its own.
237
239
  */
238
240
  ERR_SIGNAL_TERMINATED: 'ERR_SIGNAL_TERMINATED',
241
+
242
+ // ── Global mode (which release answers) ──────────────────────────
243
+ /**
244
+ * The CLI release a run needs could not run: the release that matches the
245
+ * project's Core is not installed and could not be fetched (offline, or the
246
+ * registry lacks it), the project's own CLI could not be started, or a copy
247
+ * that carries no Core could not install its release's Core outside a
248
+ * project. Nothing was written.
249
+ */
250
+ ERR_VERSIONS_UNAVAILABLE: 'ERR_VERSIONS_UNAVAILABLE',
251
+ /**
252
+ * The command needs a project (an app with Astryx installed, or an
253
+ * integration package) and was run outside one. Nothing was written.
254
+ */
255
+ ERR_PROJECT_REQUIRED: 'ERR_PROJECT_REQUIRED',
239
256
  });
240
257
 
241
258
  /**
@@ -113,6 +113,7 @@ describe('error codes: shipped set', () => {
113
113
  'ERR_NO_SOURCE',
114
114
  'ERR_PALETTE_GENERATION',
115
115
  'ERR_PATH_TRAVERSAL',
116
+ 'ERR_PROJECT_REQUIRED',
116
117
  'ERR_SIGNAL_TERMINATED',
117
118
  'ERR_THEME_INVALID',
118
119
  'ERR_THEME_LOAD',
@@ -133,6 +134,7 @@ describe('error codes: shipped set', () => {
133
134
  'ERR_UNKNOWN_THEME',
134
135
  'ERR_UNKNOWN_TOPIC',
135
136
  'ERR_VERSION_DETECT',
137
+ 'ERR_VERSIONS_UNAVAILABLE',
136
138
  'ERR_WRITE_FAILED',
137
139
  ];
138
140
 
@@ -70,13 +70,18 @@ describe('json envelope shape', () => {
70
70
  expect(env.apiVersion).toBe(API_VERSION);
71
71
  expect(env.type).toBe('docs.list');
72
72
  expect(env.data).toEqual([{name: 'Button'}]);
73
- expect('meta' in env).toBe(false);
73
+ // The only meta every result carries names who answered (AST-081 FR5).
74
+ expect(Object.keys(env.meta)).toEqual(['answeredBy']);
75
+ const {cli, core, copy} = env.meta.answeredBy;
76
+ expect(typeof cli).toBe('string');
77
+ expect(core === null || typeof core === 'string').toBe(true);
78
+ expect(['project', 'matched', 'carried']).toContain(copy);
74
79
  });
75
80
 
76
81
  it('jsonOut attaches optional meta as a sibling of data', () => {
77
82
  jsonOut({type: 'discover.list', data: [], meta: {configured: false}});
78
83
  const env = JSON.parse(logs[0]);
79
- expect(env.meta).toEqual({configured: false});
84
+ expect(env.meta).toEqual({configured: false, answeredBy: expect.any(Object)});
80
85
  expect(env.data).toEqual([]);
81
86
  });
82
87
 
@@ -30,6 +30,7 @@
30
30
  */
31
31
  import {ERROR_CODES, isErrorCode} from './error-codes.mjs';
32
32
  import {recordEnvelope, setOutcome} from '../debug/index.mjs';
33
+ import {answeredBy} from '../release/run-context.mjs';
33
34
 
34
35
  export const API_VERSION = 1;
35
36
 
@@ -101,7 +102,9 @@ export function jsonOut(response) {
101
102
  const envelope = {apiVersion: API_VERSION, type: response.type};
102
103
  if (response.package !== undefined) envelope.package = response.package;
103
104
  envelope.data = response.data;
104
- if (response.meta !== undefined) envelope.meta = response.meta;
105
+ // Every successful result names the release that answered (spec AST-081
106
+ // FR5): the CLI, the Core it paired with, and which copy it was.
107
+ envelope.meta = {...(response.meta ?? {}), answeredBy: answeredBy()};
105
108
  // Serialize BEFORE marking handled. If JSON.stringify throws (a circular
106
109
  // reference or a BigInt in `data` — an author bug in a command's return
107
110
  // value), the `__xdsJsonHandled` flag must stay unset so the bin error
@@ -32,6 +32,11 @@ export const doc = {
32
32
  description:
33
33
  'The removal receipt — returned when --remove-agents is set: `data.removed` is true when a managed agent-docs block was found and removed, and false when there was none to remove.',
34
34
  },
35
+ {
36
+ value: 'init.user',
37
+ description:
38
+ 'The computer-level agent text receipt — returned when --user is set: `data.files`, one `{path, action, reason?}` per path acted on, the skill file first and then each link to its folder (action `written` | `linked` | `unchanged` | `removed` | `absent` | `kept`; `reason` only on `kept`: `edited` when a person changed the text, `not-astryx` when Astryx did not write it), `data.command` (the command the text names), and `data.warnings`.',
39
+ },
35
40
  // component
36
41
  {
37
42
  value: 'component.list',
@@ -112,7 +117,7 @@ export const doc = {
112
117
  {
113
118
  value: 'discover.list',
114
119
  description:
115
- 'The integrations the project loads (name, category, components, version, a list per other kind they add, and latest when a source knows it); with a discover source, meta.available lists what the project could add and meta.sources reports each source; when empty it carries meta.configured to tell "nothing configured" from "nothing discovered".',
120
+ 'What the project has, the integrations it loads and the official packages it declares, official packages first (name, category, components, version, a list per other kind they add, and latest when a source knows it); meta.available lists what the project could add, the official packages first, each with the command that adds it, and meta.sources reports each source, the official list last; when it lists no integration it carries meta.configured to tell "nothing configured" from "nothing discovered".',
116
121
  },
117
122
  {
118
123
  value: 'discover.detail',
@@ -139,7 +144,7 @@ export const doc = {
139
144
  {
140
145
  value: 'search',
141
146
  description:
142
- 'The echoed query, `matchCount` (total matches, before `limit`), and results, a ranked SearchResultEntry[] bounded by `limit`: each {domain, name, package, score, reason, description, command} (package is the npm package that owns the result), plus import (components, hooks), title, parent (the command that opens the level above), and, for a hit on one section, section (docs), or displayName and kind (templates).',
147
+ 'The echoed query, `matchCount` (total matches, before `limit`), and results, a ranked SearchResultEntry[] bounded by `limit`: each {domain, name, package, score, reason, description, command} (package is the npm package that owns the result), plus import (components, hooks), title, parent (the command that opens the level above), and, for a hit on one section, section (docs), or displayName and kind (templates). When a search with no `type` could not obtain @astryxdesign/core, `meta.partial` is {skipped, reason}: the domains it skipped (component, hook, template) and why.',
143
148
  },
144
149
 
145
150
  // build
@@ -169,12 +174,13 @@ export const doc = {
169
174
  // gap reports
170
175
  {
171
176
  value: 'gap-report.categories',
172
- description: 'The fixed gap category values and human-readable labels.',
177
+ description:
178
+ 'The fixed gap category values and human-readable labels; when a loaded integration names its own issues URL, meta.destinations lists every destination ({to, default, issuesUrl}) and meta.ask tells an agent to ask the person.',
173
179
  },
174
180
  {
175
181
  value: 'gap-report.file',
176
182
  description:
177
- 'An aggregate receipt: overall status, the selected package, issuesUrl (or null), deliveries in handler order, each {handlerType: project | integration | fallback, handler, audience, status, url, message}, and filedCount/routedOnlyCount totals.',
183
+ 'An aggregate receipt: overall status, the selected package, issuesUrl (or null), deliveries in handler order, each {handlerType: project | integration | fallback, handler, audience, status, url, message}, and filedCount/routedOnlyCount totals; without --to, when a loaded integration names its own issues URL, destinations and ask as on gap-report.categories.',
178
184
  },
179
185
 
180
186
  // template
@@ -283,19 +289,19 @@ export const doc = {
283
289
  {
284
290
  value: 'upgrade.status',
285
291
  description:
286
- 'A short-circuit outcome with no codemods run (up_to_date, no_codemods, or config_fixable), each carrying the agent-docs summary.',
292
+ 'A short-circuit outcome with no codemods run (up_to_date, no_codemods, or config_fixable), each carrying the agent-docs summary. no_codemods and config_fixable carry cliBehindCore ({cliVersion, command}) when the installed Core is newer than the CLI, which then has no codemods for the releases after its own version.',
287
293
  },
288
294
  {
289
295
  value: 'upgrade.run',
290
296
  description:
291
- 'The run receipt: from/to versions, codemod count, integrations processed, the agent-docs summary, sourcePathFound (false when the resolved source directory does not exist, so no source file was read), and (apply mode) filesChanged, transformsApplied, and per-codemod errors.',
297
+ 'The run receipt: from/to versions, codemod count, integrations processed, the agent-docs summary, sourcePathFound (false when the resolved source directory does not exist, so no source file was read), and (apply mode) filesChanged, transformsApplied, and per-codemod errors. When the installed Core is newer than the CLI, it also carries cliBehindCore ({cliVersion, command}): codemods for the releases after cliVersion did not run.',
292
298
  },
293
299
 
294
300
  // manifest
295
301
  {
296
302
  value: 'manifest',
297
303
  description:
298
- 'The CLI capability manifest: name, version, apiVersion, description, globalOptions, commands (each name, description, arguments, options, json, aliases?, responseTypes?, examples?, exitCodes? as [{code, when}], subcommands?), jsonSupported, and the flat responseTypes index.',
304
+ "The CLI capability manifest: name, version, apiVersion, description, globalOptions, commands (each name, description, arguments, options, json, aliases?, responseTypes?, examples?, exitCodes? as [{code, when}], outsideProject? (same, refuse, or own; absent on a group), subcommands?), jsonSupported, globalMode ({docs, summary}: what a run may do beyond its command, such as the hand-off to the project's own CLI, the daily update check, and the agent skill file, and the docs topic that explains it), and the flat responseTypes index.",
299
305
  },
300
306
 
301
307
  // help and version, which no single command owns
@@ -327,12 +333,12 @@ export const doc = {
327
333
  {
328
334
  value: 'integration.pack-check',
329
335
  description:
330
- 'The packed-package check: name, version, packable, tarball {filename, fileCount, size, unpackedSize} or null, inventory {manifest, roots [{kind, path, expectedFiles, missingFiles, complete}], expectedFiles, packedFiles}, contributions {local, packed}, each null or {themes [{slug, exportName}], components, templates [{id, type, name}], codemods [{version, id}], docs, agentDocsAppend}, and issues [{code, severity, message}].',
336
+ 'The packed-package check: name, version, packable, tarball {filename, fileCount, size, unpackedSize} or null, inventory {manifest, roots [{kind, path, expectedFiles, missingFiles, complete}], expectedFiles, packedFiles}, contributions {local, packed}, each null or {themes [{slug, exportName}], components, templates [{id, type, name}], codemods [{version, id}], docs, agentDocsAppend}, and issues [{code, severity, message, fix?, file?, line?}] (the issues validation finds in the source and, prefixed packed_, in the packed tree, with the fix and the place when the check knows them).',
331
337
  },
332
338
  {
333
339
  value: 'integration.validate',
334
340
  description:
335
- 'The validation result: validated (false when nothing was validated: with no package.json the issues list carries one no_package error so the command exits 1, and with a package.json but no integration manifest the issues list is empty and proves nothing), the package name and version (both null when validated is false) plus issues, an AstryxIntegrationIssue[] of {code, severity: warning | error, message}.',
341
+ 'The validation result: validated (false when nothing was validated: with no package.json the issues list carries one no_package error so the command exits 1, and with a package.json but no integration manifest the issues list is empty and proves nothing), the package name and version (both null when validated is false) plus issues, an AstryxIntegrationIssue[] of {code, severity: warning | error, message, fix?, file?, line?} (fix: the change that resolves it; file and line: where, relative to the package), and notes when there are any: {code, message} information that fails nothing, such as invalid_cli_command for a malformed cliCommand. When the manifest loads, docTypes checks each doc against its published authoring type: status (checked | skipped), reason, typescript, docs, findings (all warnings, each naming the field and a fix), unchecked, and fixtures (test fixture docs not checked).',
336
342
  },
337
343
  {
338
344
  value: 'integration.template-conflicts',
@@ -342,12 +348,17 @@ export const doc = {
342
348
  {
343
349
  value: 'integration.component-conflicts',
344
350
  description:
345
- 'validated (false when no integration manifest was found, so nothing was inspected), the integration identity, structural issues, and non-blocking conflicts where an integration component name is also owned by Core; each conflict includes the exact package-qualified command.',
351
+ 'validated (false when no integration manifest was found, so nothing was inspected), the integration identity, structural issues, and non-blocking conflicts where an integration component name is also owned by Core; each conflict includes the exact package-qualified command. When the manifest loads and declares a components root, propDrift compares documented props with the TypeScript props: status (checked | skipped), reason, typescript, components, typesCompared, typesSkipped, findings (all warnings; a default_mismatch carries docDefault, codeDefault, and a fix), unchecked, typesNotCompared, and propsNotChecked.',
346
352
  },
347
353
  {
348
354
  value: 'integration.doc-conflicts',
349
355
  description:
350
- 'validated (false when no integration manifest was found, so nothing was inspected), the integration identity, structural issues, and Core doc overlaps. Each finding includes `severity` (`info` | `error`) and `relationship` (`replaces` | `extends` | `accidental`).',
356
+ 'validated (false when no integration manifest was found, so nothing was inspected), the integration identity, structural issues, and Core doc overlaps. Each finding includes `severity` (`info` | `error`) and `relationship` (`replaces` | `extends` | `accidental`). copiedPassages lists each pair of topics that repeat 10 or more words of prose word for word: topic, section, otherTopic, otherOwner (package | core), words, passages, owner (the topic that should keep the text), text (the passage as the topic writes it), line (where the copy starts in the topic to change, or null), and message (the exact replacement); each is also a copied_passage warning in issues. fluff lists padding phrases and low-density topics: topic, kind (phrase | density), phrase, section, file (relative to the package root), line, density, and message (what to cut or write instead); each is also a doc_fluff warning in issues. strayPointers lists each code span that is exactly `astryx docs <name>` for a doc that exists, in the prose, description or summary of a topic or the text fields of a component doc: topic (the topic or component doc), kind (topic | component), section, field (the field outside any section, such as description or usage.bestPractices[0].description, else null), file (relative to the package root), line, pointer (the written command), link (the {@link} that replaces it), and message; each is also a stray_doc_pointer warning in issues.',
357
+ },
358
+ {
359
+ value: 'integration.check',
360
+ description:
361
+ 'Every source check of an integration package in one result: validated (false when no integration manifest was found, so nothing was checked), the package name and version, strict, and checks, one entry per check (validate, components, templates, docs), each with check, errors, warnings, skipped, failed, and response, the envelope that check returns on its own. The totals are errors, warnings, and skipped; unchecked counts what the checks could not compare. With --strict, failures lists each warning and each piece of skipped work again as an error, in the issue format the checks use; it is empty without --strict. failed decides the exit code.',
351
362
  },
352
363
  ],
353
364
  };
@@ -12,6 +12,7 @@ import * as path from 'node:path';
12
12
  import {describe, it, expect} from 'vitest';
13
13
  import {doc} from './response-types.doc.mjs';
14
14
  import {runCli} from '../../test-utils/run-cli.mjs';
15
+ import {linkThisCliAsProjectCli} from '../../test-utils/release-fixtures.mjs';
15
16
 
16
17
  /** @param {string} type */
17
18
  const describedAs = type =>
@@ -112,6 +113,51 @@ describe('response-types EnumDoc names every field', () => {
112
113
  );
113
114
  });
114
115
 
116
+ it('search, including meta.partial when Core cannot be obtained', async () => {
117
+ const empty = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-rt-partial-'));
118
+ // The project's own CLI answers and no Core is installed: an open search
119
+ // answers from docs and themes and says what it skipped.
120
+ linkThisCliAsProjectCli(empty);
121
+ try {
122
+ const res = await data(['search', 'button'], empty);
123
+ expect(res.meta.partial).toBeDefined();
124
+ expectNamed('search', ['meta', 'partial', ...fieldsOf(res.meta.partial)]);
125
+ for (const domain of res.meta.partial.skipped) {
126
+ expectNamed('search', [domain]);
127
+ }
128
+ } finally {
129
+ fs.rmSync(empty, {recursive: true, force: true});
130
+ }
131
+ });
132
+
133
+ it('init.user: every row field, action, and kept reason the receipt type declares', () => {
134
+ const types = fs.readFileSync(
135
+ new URL('../../api/init/init.type.mjs', import.meta.url),
136
+ 'utf8',
137
+ );
138
+ /** The quoted members of the union a typedef or property declares. */
139
+ const union = (/** @type {RegExp} */ re) =>
140
+ [...(types.match(re)?.[1] ?? '').matchAll(/'([^']+)'/gu)].map(m => m[1]);
141
+ const actions = union(/@typedef \{([^}]*)\} InitUserAction/u);
142
+ const reasons = union(/@property \{([^}]*)\} \[reason\]/u);
143
+ expect(actions).toContain('linked');
144
+ expect(reasons.length).toBeGreaterThan(0);
145
+ const rowFields = [
146
+ ...types
147
+ .split('@typedef {object} InitUserFile')[1]
148
+ .split('*/')[0]
149
+ .matchAll(/@property \{[^}]*\} \[?(\w+)/gu),
150
+ ].map(m => m[1]);
151
+ expectNamed('init.user', [
152
+ 'files',
153
+ 'command',
154
+ 'warnings',
155
+ ...rowFields,
156
+ ...actions,
157
+ ...reasons,
158
+ ]);
159
+ });
160
+
115
161
  it('build.kit, including the hint a thin kit carries', async () => {
116
162
  const res = await data(['build', 'zzqx-nothing-matches']);
117
163
  expect(res.type).toBe('build.kit');
@@ -21,11 +21,11 @@ export const doc = {
21
21
  fields: [
22
22
  {
23
23
  name: 'Success envelope',
24
- type: '{ apiVersion: number; type: string; package?: string; data: unknown; meta?: Record<string, unknown> }',
24
+ type: '{ apiVersion: number; type: string; package?: string; data: unknown; meta?: { answeredBy?: { cli: string; core: string | null; copy: "project" | "starting" | "matched" | "carried" | "fallback" } } & Record<string, unknown> }',
25
25
  description:
26
26
  'Emitted for every successful command in --json mode: a type ' +
27
27
  'discriminator, the package that owns what the response is about, ' +
28
- 'its data payload, and an optional meta sidecar.',
28
+ 'its data payload, and an optional meta object beside data.',
29
29
  fields: [
30
30
  {
31
31
  name: 'apiVersion',
@@ -65,7 +65,7 @@ export const doc = {
65
65
  name: 'meta',
66
66
  type: 'Record<string, unknown>',
67
67
  description:
68
- 'Optional sidecar, emitted as a sibling of data (never merged in). A `deprecations` field is an array of `{id, replacements}` entries; each stable lifecycle id names the replacement commands without changing the command data.',
68
+ "Optional, emitted as a sibling of data (never merged in). `answeredBy` is on every successful result of a release that has it: `{cli, core, copy}`, the answering CLI version, the Core it pairs with (or null), and which copy answered: `project` (the project's own CLI), `starting` (the copy that started the run, in a project with no CLI of its own), `matched` (the release equal to the project's Core, when the project's own CLI cannot start), `carried` (outside a project), or `fallback` (the matched release could not be obtained, so the starting copy answered). A `deprecations` field is an array of `{id, replacements}` entries; each stable lifecycle id names the replacement commands without changing the command data. Other fields may be added (spec:AST-017 FR13).",
69
69
  },
70
70
  ],
71
71
  },
@@ -0,0 +1,74 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * `@astryxdesign/cli/xle` (browser.mjs) runs in browsers: nothing it imports,
5
+ * directly or through other modules, may load a Node built-in.
6
+ */
7
+
8
+ import {describe, expect, it} from 'vitest';
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+
12
+ const ENTRY = path.join(import.meta.dirname, 'browser.mjs');
13
+
14
+ /** Every module specifier a file imports or re-exports, static or dynamic. */
15
+ const SPECIFIER =
16
+ /(?:\bimport\s*(?:[\w*{}\s,$]+\s*from\s*)?|\bexport\s*[\w*{}\s,$]+\s*from\s*|\bimport\s*\(\s*)['"]([^'"]+)['"]/gu;
17
+
18
+ /**
19
+ * The files `entry` reaches through relative imports, with the bare and
20
+ * `node:` specifiers each one names.
21
+ * @param {string} entry
22
+ * @returns {Map<string, string[]>}
23
+ */
24
+ function importGraph(entry) {
25
+ /** @type {Map<string, string[]>} */
26
+ const graph = new Map();
27
+ const queue = [entry];
28
+ while (queue.length > 0) {
29
+ const file = /** @type {string} */ (queue.pop());
30
+ if (graph.has(file)) continue;
31
+ // Comments hold JSDoc type imports (`import('./x').T`), which load nothing.
32
+ const source = fs
33
+ .readFileSync(file, 'utf8')
34
+ .replace(/\/\*[\s\S]*?\*\//gu, '')
35
+ .replace(/^\s*\/\/.*$/gmu, '');
36
+ /** @type {string[]} */
37
+ const external = [];
38
+ for (const [, spec] of source.matchAll(SPECIFIER)) {
39
+ if (spec.startsWith('.')) {
40
+ queue.push(path.resolve(path.dirname(file), spec));
41
+ } else {
42
+ external.push(spec);
43
+ }
44
+ }
45
+ graph.set(file, external);
46
+ }
47
+ return graph;
48
+ }
49
+
50
+ describe('the xle browser export', () => {
51
+ it('reaches no Node built-in and no AsyncLocalStorage', () => {
52
+ const graph = importGraph(ENTRY);
53
+ // The walk reaches the parser, validator and expander.
54
+ expect(graph.size).toBeGreaterThan(3);
55
+ const builtins = [...graph].flatMap(([file, specs]) =>
56
+ specs
57
+ .filter(
58
+ spec =>
59
+ spec.startsWith('node:') ||
60
+ /^(?:fs|path|os|child_process|async_hooks|url)$/u.test(spec),
61
+ )
62
+ .map(
63
+ spec => `${path.relative(import.meta.dirname, file)} imports ${spec}`,
64
+ ),
65
+ );
66
+ expect(builtins).toEqual([]);
67
+ const storage = [...graph.keys()]
68
+ .filter(file =>
69
+ fs.readFileSync(file, 'utf8').includes('AsyncLocalStorage'),
70
+ )
71
+ .map(file => path.relative(import.meta.dirname, file));
72
+ expect(storage).toEqual([]);
73
+ });
74
+ });
@@ -20,6 +20,7 @@ import path from 'node:path';
20
20
  import {findCoreDir} from '../fs/paths.mjs';
21
21
  import {
22
22
  discoverComponents,
23
+ familyMember,
23
24
  findComponentReadme,
24
25
  resolveImportPath,
25
26
  } from '../discovery/component-discovery.mjs';
@@ -126,6 +127,9 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
126
127
  } catch {
127
128
  continue; // a malformed doc must not take down the whole language
128
129
  }
130
+ // A member documented in its family's doc (VStack in Stack's doc) is
131
+ // registered by the family's own folder, with every other member.
132
+ if (familyMember(docs, dirName)) continue;
129
133
  const importPath = resolveImportPath(coreDir, dirName);
130
134
 
131
135
  const register = (/** @type {string} */ rawName, /** @type {import('./xle-ast').DocProp[]} */ props) => {
@@ -0,0 +1,28 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file The layout-language registry over the real @astryxdesign/core tree:
5
+ * the import path it emits for each component.
6
+ */
7
+
8
+ import {describe, it, expect} from 'vitest';
9
+ import * as path from 'node:path';
10
+ import {fileURLToPath} from 'node:url';
11
+ import {buildRegistry} from './registry.mjs';
12
+
13
+ const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
14
+
15
+ describe('buildRegistry import paths', () => {
16
+ it('keeps the Stack family on the paths it registers from Stack\'s folder', async () => {
17
+ // HStack and VStack are listed components whose docs live in Stack's doc.
18
+ // Listing them must not let their folders re-register the family under
19
+ // their own paths: a member's folder registers nothing, Stack's does.
20
+ const {components} = await buildRegistry({cwd: REPO});
21
+ const importOf = (/** @type {string} */ name) => components.get(name)?.importPath;
22
+ for (const name of ['Stack', 'StackItem', 'HStack', 'VStack']) {
23
+ expect(importOf(name), name).toBe('@astryxdesign/core/Stack');
24
+ }
25
+ expect(importOf('Heading')).toBe('@astryxdesign/core/Heading');
26
+ expect(importOf('Text')).toBe('@astryxdesign/core/Text');
27
+ }, 120_000);
28
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.7.2-canary.fe2c655",
3
+ "version": "0.7.2",
4
4
  "displayName": "CLI",
5
5
  "description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
6
6
  "author": "Meta Open Source",
@@ -101,10 +101,10 @@
101
101
  "zod": "^4.4.3"
102
102
  },
103
103
  "peerDependencies": {
104
- "@astryxdesign/charts": "0.7.2-canary.fe2c655",
105
- "@astryxdesign/core": "0.7.2-canary.fe2c655",
106
- "@astryxdesign/lab": "0.7.2-canary.fe2c655",
107
- "@astryxdesign/theme-neutral": "0.7.2-canary.fe2c655"
104
+ "@astryxdesign/charts": "*",
105
+ "@astryxdesign/core": "*",
106
+ "@astryxdesign/lab": "*",
107
+ "@astryxdesign/theme-neutral": "*"
108
108
  },
109
109
  "peerDependenciesMeta": {
110
110
  "@astryxdesign/charts": {
@@ -121,10 +121,10 @@
121
121
  }
122
122
  },
123
123
  "devDependencies": {
124
- "@astryxdesign/charts": "0.7.2-canary.fe2c655",
125
- "@astryxdesign/core": "0.7.2-canary.fe2c655",
126
- "@astryxdesign/lab": "0.7.2-canary.fe2c655",
127
- "@astryxdesign/theme-neutral": "0.7.2-canary.fe2c655",
124
+ "@astryxdesign/charts": "*",
125
+ "@astryxdesign/core": "*",
126
+ "@astryxdesign/lab": "*",
127
+ "@astryxdesign/theme-neutral": "*",
128
128
  "@heroicons/react": "^2.2.0",
129
129
  "@stylexjs/stylex": "^0.19.0",
130
130
  "@types/babel__core": "^7.20.5",
@@ -134,8 +134,8 @@
134
134
  "scripts": {
135
135
  "astryx": "node clients/cli/bin/astryx.mjs",
136
136
  "postinstall": "node scripts/postinstall.mjs",
137
- "test": "vitest run --root ../.. packages/cli",
138
- "test:watch": "vitest --root ../.. packages/cli",
137
+ "test": "cd ../.. && vitest run packages/cli",
138
+ "test:watch": "cd ../.. && vitest packages/cli",
139
139
  "typecheck:template-docs": "tsc --project tsconfig.template-docs.json",
140
140
  "typecheck:json-api": "tsc --project tsconfig.json-api.json",
141
141
  "typecheck:strict": "tsc --project tsconfig.strict.json",
@@ -7,7 +7,7 @@
7
7
  * installed as a project dependency and the project hasn't run init yet, print a
8
8
  * one-line next-step so agents/humans discover it.
9
9
  *
10
- * Reuses the ONE setup check (isAstryxInitialized) from the dependency-free leaf
10
+ * Reuses the ONE setup check (isAstryxPromptInReach) from the dependency-free leaf
11
11
  * ../foundation/agent-docs/agent-doc-state.mjs — node builtins only, so it is
12
12
  * genuinely safe to load at install time (importing agent-docs.mjs would drag in
13
13
  * the full CLI module graph). Non-interactive, never fails the install, and
@@ -24,7 +24,7 @@ import {fileURLToPath, pathToFileURL} from 'node:url';
24
24
  // is safe to load at install time.
25
25
  import {
26
26
  shouldNudge,
27
- SETUP_NUDGE,
27
+ setupNudge,
28
28
  } from '../foundation/agent-docs/agent-doc-state.mjs';
29
29
 
30
30
  const HERE = fileURLToPath(import.meta.url);
@@ -41,15 +41,34 @@ async function projectIsSetUp(root) {
41
41
  // Dep-free leaf (node builtins only) — safe to load mid-install. NOT
42
42
  // agent-docs.mjs, whose static graph (component discovery, package-manager
43
43
  // detection, …) isn't guaranteed importable yet during this postinstall.
44
- const {isAstryxInitialized} = await import(
44
+ const {isAstryxPromptInReach} = await import(
45
45
  '../foundation/agent-docs/agent-doc-state.mjs'
46
46
  );
47
- return isAstryxInitialized(root);
47
+ return isAstryxPromptInReach(root);
48
48
  } catch {
49
49
  return false; // best-effort — if the check can't load, fall through and nudge
50
50
  }
51
51
  }
52
52
 
53
+ /**
54
+ * The stem the CLI's picker prints for this project. At install time no
55
+ * integration is loaded, so this is the package-manager guess. Falls back to
56
+ * the contract's scoped form when the picker cannot load.
57
+ * @param {string} root
58
+ * @returns {Promise<string | undefined>}
59
+ */
60
+ export async function cliInvocation(root) {
61
+ try {
62
+ // Node builtins only, like the contract.
63
+ const {getCliInvocation} = await import(
64
+ '../foundation/env/package-manager.mjs'
65
+ );
66
+ return getCliInvocation(root);
67
+ } catch {
68
+ return undefined;
69
+ }
70
+ }
71
+
53
72
  async function main() {
54
73
  const root = process.env.INIT_CWD || process.cwd();
55
74
  const nudge = shouldNudge({
@@ -58,7 +77,7 @@ async function main() {
58
77
  isSetUp: await projectIsSetUp(root),
59
78
  });
60
79
  if (nudge) {
61
- process.stdout.write(SETUP_NUDGE);
80
+ process.stdout.write(setupNudge(await cliInvocation(root)));
62
81
  }
63
82
  }
64
83