@astryxdesign/cli 0.7.2-canary.fdd384f → 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 (450) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +169 -149
  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/kit/kit.mjs +3 -11
  7. package/api/component/_adapter.d.mts +31 -0
  8. package/api/component/_adapter.mjs +119 -11
  9. package/api/component/component.doc.mjs +6 -1
  10. package/api/component/component.mjs +60 -10
  11. package/api/component/doc-links.test.mjs +386 -0
  12. package/api/discover/_adapter.d.mts +132 -12
  13. package/api/discover/_adapter.mjs +488 -27
  14. package/api/discover/_adapter.test.mjs +599 -17
  15. package/api/discover/_catalog-view.d.mts +16 -5
  16. package/api/discover/_catalog-view.mjs +32 -8
  17. package/api/discover/detail/doc/doc.mjs +9 -1
  18. package/api/discover/discover.d.mts +11 -0
  19. package/api/discover/discover.doc.mjs +9 -7
  20. package/api/discover/discover.mjs +121 -19
  21. package/api/discover/discover.type.d.mts +20 -7
  22. package/api/discover/discover.type.mjs +17 -7
  23. package/api/discover/list/list.d.mts +4 -3
  24. package/api/discover/list/list.mjs +17 -10
  25. package/api/docs/_adapter.d.mts +63 -0
  26. package/api/docs/_adapter.mjs +312 -18
  27. package/api/docs/docs.doc.mjs +2 -1
  28. package/api/docs/docs.mjs +2 -1
  29. package/api/docs/docs.test.mjs +5 -2
  30. package/api/docs/integration-tree.test.mjs +22 -0
  31. package/api/docs/list/list.mjs +12 -2
  32. package/api/docs/reference-blocks.test.mjs +1 -3
  33. package/api/doctor/_adapter.d.mts +108 -0
  34. package/api/doctor/_adapter.mjs +223 -4
  35. package/api/doctor/doctor.d.mts +199 -0
  36. package/api/doctor/doctor.doc.mjs +3 -2
  37. package/api/doctor/doctor.mjs +530 -34
  38. package/api/doctor/doctor.test.mjs +180 -14
  39. package/api/doctor/release-checks.test.mjs +156 -0
  40. package/api/doctor/theme-checks.mjs +16 -3
  41. package/api/doctor/theme-checks.test.mjs +223 -7
  42. package/api/error.d.mts +10 -0
  43. package/api/error.mjs +25 -0
  44. package/api/gap-report/gap-report.d.mts +3 -0
  45. package/api/gap-report/gap-report.doc.mjs +11 -3
  46. package/api/gap-report/gap-report.mjs +152 -48
  47. package/api/gap-report/gap-report.test.mjs +233 -0
  48. package/api/gap-report/gap-report.type.d.mts +41 -0
  49. package/api/gap-report/gap-report.type.mjs +18 -0
  50. package/api/hook/_adapter.mjs +3 -11
  51. package/api/hook/hook.doc.mjs +4 -0
  52. package/api/hook/list/list.d.mts +1 -1
  53. package/api/init/_adapter.d.mts +22 -0
  54. package/api/init/_adapter.mjs +59 -0
  55. package/api/init/init.d.mts +7 -5
  56. package/api/init/init.doc.mjs +28 -7
  57. package/api/init/init.mjs +28 -4
  58. package/api/init/init.type.d.mts +48 -3
  59. package/api/init/init.type.mjs +37 -3
  60. package/api/init/run/run.d.mts +1 -1
  61. package/api/init/run/run.mjs +15 -4
  62. package/api/init/user/user.d.mts +14 -0
  63. package/api/init/user/user.mjs +87 -0
  64. package/api/init/user/user.test.mjs +232 -0
  65. package/api/integration/_adapter.d.mts +33 -0
  66. package/api/integration/_adapter.mjs +58 -0
  67. package/api/integration/authoring-checks.mjs +100 -5
  68. package/api/integration/authoring-checks.test.mjs +769 -0
  69. package/api/integration/authoring-checks.type.d.mts +134 -0
  70. package/api/integration/authoring-checks.type.mjs +60 -1
  71. package/api/integration/integrationCheck.doc.mjs +1 -1
  72. package/api/integration/integrationComponentConflicts.doc.mjs +11 -3
  73. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  74. package/api/integration/pack-check.mjs +303 -13
  75. package/api/integration/pack-check.test.mjs +371 -10
  76. package/api/integration/validate-integration-fixes.test.mjs +67 -0
  77. package/api/integration/validate-integration.d.mts +8 -0
  78. package/api/integration/validate-integration.mjs +55 -9
  79. package/api/integration/validate-integration.test.mjs +77 -8
  80. package/api/integration/validate-integration.type.d.mts +8 -0
  81. package/api/integration/validate-integration.type.mjs +3 -1
  82. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  83. package/api/integration/validateIntegration.doc.mjs +4 -2
  84. package/api/search/_adapter.d.mts +11 -0
  85. package/api/search/_adapter.mjs +25 -0
  86. package/api/search/search.d.mts +73 -13
  87. package/api/search/search.doc.mjs +8 -3
  88. package/api/search/search.domain-priority.test.mjs +108 -18
  89. package/api/search/search.mjs +541 -52
  90. package/api/search/search.test.mjs +143 -1
  91. package/api/search/search.type.d.mts +14 -1
  92. package/api/search/search.type.mjs +6 -1
  93. package/api/swizzle/_adapter.mjs +2 -2
  94. package/api/swizzle/copy/copy.mjs +1 -1
  95. package/api/template/template-integration.test.mjs +1 -1
  96. package/api/theme/_adapter.d.mts +16 -0
  97. package/api/theme/_adapter.mjs +32 -5
  98. package/api/theme/build/build.d.mts +2 -1
  99. package/api/theme/build/build.mjs +70 -14
  100. package/api/theme/build/build.packed-old-core.test.mjs +20 -3
  101. package/api/theme/build/font-warning.mjs +5 -3
  102. package/api/theme/build/font-warning.test.mjs +2 -1
  103. package/api/theme/remove/remove.test.mjs +2 -2
  104. package/api/theme/targets/targets.mjs +3 -10
  105. package/api/theme/themeTargets.doc.mjs +4 -0
  106. package/api/theme/use/use.test.mjs +1 -1
  107. package/api/upgrade/_adapter.d.mts +40 -2
  108. package/api/upgrade/_adapter.mjs +118 -5
  109. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  110. package/api/upgrade/run/run.mjs +35 -2
  111. package/api/upgrade/status/status.d.mts +21 -5
  112. package/api/upgrade/status/status.mjs +45 -8
  113. package/api/upgrade/upgrade.doc.mjs +6 -3
  114. package/api/upgrade/upgrade.mjs +5 -1
  115. package/api/upgrade/upgrade.type.d.mts +23 -0
  116. package/api/upgrade/upgrade.type.mjs +16 -1
  117. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  118. package/assets/codemods/registry.mjs +1 -0
  119. package/assets/codemods/runner.mjs +7 -1
  120. package/assets/codemods/transforms/next/index.mjs +1 -11
  121. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  122. package/assets/discover/official-packages.json +367 -0
  123. package/assets/docs/author-a-theme.doc.mjs +2 -2
  124. package/assets/docs/browser-support.doc.mjs +1 -1
  125. package/assets/docs/getting-started.doc.mjs +23 -3
  126. package/assets/docs/styling-overview.doc.mjs +1 -1
  127. package/assets/docs/theme.doc.mjs +1 -1
  128. package/assets/docs/tree/add-a-component.doc.mjs +12 -2
  129. package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
  130. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  131. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  132. package/assets/docs/tree/block-template.doc.mjs +6 -18
  133. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  134. package/assets/docs/tree/building-blocks.doc.mjs +4 -0
  135. package/assets/docs/tree/check-the-props.doc.mjs +8 -3
  136. package/assets/docs/tree/check-your-docs.doc.mjs +30 -13
  137. package/assets/docs/tree/checks.doc.mjs +17 -17
  138. package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
  139. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  140. package/assets/docs/tree/cli.doc.mjs +6 -0
  141. package/assets/docs/tree/codemods.doc.mjs +17 -7
  142. package/assets/docs/tree/commands.doc.mjs +7 -1
  143. package/assets/docs/tree/component-family.doc.mjs +3 -5
  144. package/assets/docs/tree/component-imports.doc.mjs +13 -3
  145. package/assets/docs/tree/components.doc.mjs +7 -1
  146. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  147. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  148. package/assets/docs/tree/configuration.doc.mjs +7 -3
  149. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  150. package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
  151. package/assets/docs/tree/describe-the-component.doc.mjs +2 -2
  152. package/assets/docs/tree/docs.doc.mjs +9 -3
  153. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  154. package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
  155. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  156. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  157. package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
  158. package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
  159. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  160. package/assets/docs/tree/global.doc.mjs +131 -0
  161. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  162. package/assets/docs/tree/install-once.doc.mjs +105 -0
  163. package/assets/docs/tree/integrations.doc.mjs +13 -1
  164. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  165. package/assets/docs/tree/layout.doc.mjs +6 -6
  166. package/assets/docs/tree/links.doc.mjs +6 -5
  167. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  168. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  169. package/assets/docs/tree/migration.doc.mjs +0 -1
  170. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  171. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  172. package/assets/docs/tree/page-template.doc.mjs +3 -7
  173. package/assets/docs/tree/problems.doc.mjs +205 -0
  174. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  175. package/assets/docs/tree/publishing.doc.mjs +6 -6
  176. package/assets/docs/tree/quick-start.doc.mjs +52 -26
  177. package/assets/docs/tree/reference.doc.mjs +192 -0
  178. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  179. package/assets/docs/tree/replace-a-core-template.doc.mjs +9 -11
  180. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  181. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  182. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  183. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  184. package/assets/docs/tree/single-component.doc.mjs +14 -6
  185. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  186. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  187. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  188. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  189. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  190. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  191. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  192. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  193. package/assets/docs/tree/templates.doc.mjs +7 -1
  194. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  195. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  196. package/assets/docs/tree/themes.doc.mjs +4 -0
  197. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  198. package/assets/docs/tree/troubleshooting.doc.mjs +22 -14
  199. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  200. package/assets/docs/tree/updates.doc.mjs +92 -0
  201. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  202. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
  203. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  204. package/assets/docs/tree/versioning.doc.mjs +9 -9
  205. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  206. package/assets/docs/tree/write-the-template-file.doc.mjs +5 -5
  207. package/assets/docs/working-with-ai.doc.mjs +23 -9
  208. package/authoring/codemod/codemod.doc.mjs +7 -3
  209. package/authoring/config/config.doc.mjs +9 -6
  210. package/authoring/config/type.ts +4 -2
  211. package/authoring/debug/parse.d.mts +5 -5
  212. package/authoring/discover/discover.doc.mjs +7 -1
  213. package/authoring/doctypes/_schema.d.mts +8 -3
  214. package/authoring/doctypes/_schema.mjs +1 -0
  215. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  216. package/authoring/doctypes/command/command.doc.mjs +20 -12
  217. package/authoring/doctypes/command/type.ts +14 -0
  218. package/authoring/doctypes/component/component.doc.mjs +29 -26
  219. package/authoring/doctypes/component/type.ts +15 -5
  220. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  221. package/authoring/doctypes/function/function.doc.mjs +9 -8
  222. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  223. package/authoring/doctypes/hook/type.ts +4 -0
  224. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  225. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  226. package/authoring/doctypes/schema/schema.doc.mjs +9 -9
  227. package/authoring/doctypes/template/template.doc.mjs +2 -2
  228. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  229. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  230. package/authoring/identity/identity.doc.mjs +3 -3
  231. package/authoring/index.d.ts +1 -0
  232. package/authoring/integration/integration.doc.mjs +22 -5
  233. package/authoring/integration/parse.test.mjs +11 -0
  234. package/authoring/integration/schema.d.mts +14 -3
  235. package/authoring/integration/schema.mjs +33 -2
  236. package/authoring/integration/type.ts +8 -0
  237. package/clients/cli/bin/astryx.mjs +20 -3
  238. package/clients/cli/cli-command.test.mjs +166 -0
  239. package/clients/cli/commands/blog.doc.mjs +1 -0
  240. package/clients/cli/commands/build-theme.batch-report.test.mjs +14 -2
  241. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  242. package/clients/cli/commands/build-theme.mjs +25 -12
  243. package/clients/cli/commands/build.doc.mjs +1 -0
  244. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  245. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  246. package/clients/cli/commands/component.doc.mjs +1 -0
  247. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  248. package/clients/cli/commands/discover.doc.mjs +9 -1
  249. package/clients/cli/commands/discover.mjs +144 -93
  250. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  251. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  252. package/clients/cli/commands/docs.doc.mjs +1 -0
  253. package/clients/cli/commands/docs.mjs +49 -19
  254. package/clients/cli/commands/docs.test.mjs +2 -2
  255. package/clients/cli/commands/doctor-integration-components.doc.mjs +7 -3
  256. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  257. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  258. package/clients/cli/commands/doctor-integration-validate.doc.mjs +13 -2
  259. package/clients/cli/commands/doctor-integration.test.mjs +52 -4
  260. package/clients/cli/commands/doctor.doc.mjs +12 -2
  261. package/clients/cli/commands/doctor.mjs +102 -7
  262. package/clients/cli/commands/doctor.test.mjs +10 -4
  263. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  264. package/clients/cli/commands/gap-report.mjs +24 -2
  265. package/clients/cli/commands/gap-report.test.mjs +79 -0
  266. package/clients/cli/commands/hook.doc.mjs +1 -0
  267. package/clients/cli/commands/init.behavior.test.mjs +5 -0
  268. package/clients/cli/commands/init.doc.mjs +29 -3
  269. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  270. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  271. package/clients/cli/commands/integration-check.doc.mjs +10 -2
  272. package/clients/cli/commands/integration-check.test.mjs +175 -1
  273. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  274. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  275. package/clients/cli/commands/integration.mjs +15 -9
  276. package/clients/cli/commands/json-contract.test.mjs +11 -2
  277. package/clients/cli/commands/manifest.doc.mjs +1 -0
  278. package/clients/cli/commands/outside-project.test.mjs +774 -0
  279. package/clients/cli/commands/search.doc.mjs +1 -0
  280. package/clients/cli/commands/search.mjs +16 -11
  281. package/clients/cli/commands/search.test.mjs +429 -296
  282. package/clients/cli/commands/setup-nudge.test.mjs +102 -2
  283. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  284. package/clients/cli/commands/swizzle.mjs +5 -3
  285. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  286. package/clients/cli/commands/template.doc.mjs +1 -0
  287. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  288. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  289. package/clients/cli/commands/theme-build.doc.mjs +1 -0
  290. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  291. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  292. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  293. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  294. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  295. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  296. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  297. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  298. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  299. package/clients/cli/commands/upgrade.doc.mjs +22 -1
  300. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  301. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  302. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  303. package/clients/cli/index.mjs +111 -16
  304. package/clients/cli/lib/cli-error.mjs +4 -1
  305. package/clients/cli/lib/component-format.test.mjs +1 -1
  306. package/clients/cli/lib/define-command.mjs +2 -2
  307. package/clients/cli/lib/json-shim.mjs +3 -1
  308. package/clients/cli/lib/manifest.d.ts +9 -0
  309. package/clients/cli/lib/manifest.mjs +17 -1
  310. package/clients/cli/lib/manifest.test.mjs +25 -0
  311. package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
  312. package/foundation/agent-docs/agent-doc-state.mjs +66 -6
  313. package/foundation/agent-docs/agent-docs.d.mts +4 -3
  314. package/foundation/agent-docs/agent-docs.mjs +11 -9
  315. package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
  316. package/foundation/agent-docs/computer-agent-text.mjs +623 -0
  317. package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
  318. package/foundation/config/project.d.mts +35 -3
  319. package/foundation/config/project.mjs +145 -8
  320. package/foundation/config/project.test.mjs +66 -0
  321. package/foundation/config/theme-state.mjs +5 -4
  322. package/foundation/discovery/authoring-self-docs.mjs +1 -1
  323. package/foundation/discovery/cli-self-docs.mjs +20 -3
  324. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  325. package/foundation/discovery/component-replacement.mjs +2 -1
  326. package/foundation/discovery/copied-passages.d.mts +216 -0
  327. package/foundation/discovery/copied-passages.mjs +720 -0
  328. package/foundation/discovery/copied-passages.test.mjs +124 -0
  329. package/foundation/discovery/doc-consistency.d.mts +34 -0
  330. package/foundation/discovery/doc-consistency.mjs +513 -0
  331. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  332. package/foundation/discovery/doc-fluff.d.mts +112 -0
  333. package/foundation/discovery/doc-fluff.mjs +328 -0
  334. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  335. package/foundation/discovery/doc-types.d.mts +1 -1
  336. package/foundation/discovery/doc-types.mjs +15 -8
  337. package/foundation/discovery/doc-types.test.mjs +94 -2
  338. package/foundation/discovery/docs-discovery.d.mts +7 -0
  339. package/foundation/discovery/docs-discovery.mjs +26 -2
  340. package/foundation/discovery/project-typescript.d.mts +11 -2
  341. package/foundation/discovery/project-typescript.mjs +32 -4
  342. package/foundation/discovery/prop-drift.d.mts +26 -7
  343. package/foundation/discovery/prop-drift.mjs +173 -8
  344. package/foundation/discovery/prop-drift.test.mjs +120 -2
  345. package/foundation/discovery/runner-allowlist.d.mts +40 -0
  346. package/foundation/discovery/runner-allowlist.mjs +53 -0
  347. package/foundation/discovery/stray-pointers.d.mts +52 -0
  348. package/foundation/discovery/stray-pointers.mjs +293 -0
  349. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  350. package/foundation/discovery/template-needs.mjs +5 -2
  351. package/foundation/discovery/theme-imports.mjs +8 -4
  352. package/foundation/discovery/theme-imports.test.mjs +1 -1
  353. package/foundation/discovery/type-text.mjs +1 -1
  354. package/foundation/discovery/type-text.test.mjs +1 -1
  355. package/foundation/doc-compiler/doc-loads.test.mjs +42 -2
  356. package/foundation/doc-compiler/inputs.mjs +4 -1
  357. package/foundation/doc-compiler/links.d.mts +32 -0
  358. package/foundation/doc-compiler/links.mjs +163 -26
  359. package/foundation/doc-compiler/links.test.mjs +97 -4
  360. package/foundation/doc-compiler/read.d.mts +1 -1
  361. package/foundation/doc-compiler/tree.mjs +30 -1
  362. package/foundation/doc-compiler/tree.test.mjs +8 -1
  363. package/foundation/env/cli-command.d.mts +83 -0
  364. package/foundation/env/cli-command.mjs +152 -0
  365. package/foundation/env/cli-command.test.mjs +129 -0
  366. package/foundation/env/node-version.test.mjs +15 -3
  367. package/foundation/env/package-manager.d.mts +93 -9
  368. package/foundation/env/package-manager.global.test.mjs +66 -0
  369. package/foundation/env/package-manager.mjs +184 -13
  370. package/foundation/env/package-manager.test.mjs +341 -15
  371. package/foundation/env/project-scope.d.mts +9 -0
  372. package/foundation/env/project-scope.mjs +33 -0
  373. package/foundation/env/search-path.d.mts +42 -0
  374. package/foundation/env/search-path.mjs +205 -0
  375. package/foundation/env/search-path.test.mjs +122 -0
  376. package/foundation/env/user-dirs.d.mts +39 -0
  377. package/foundation/env/user-dirs.mjs +93 -0
  378. package/foundation/env/user-dirs.test.mjs +72 -0
  379. package/foundation/env/user-settings.d.mts +46 -0
  380. package/foundation/env/user-settings.mjs +106 -0
  381. package/foundation/env/user-settings.test.mjs +64 -0
  382. package/foundation/fs/file-protection.mjs +15 -1
  383. package/foundation/fs/module-loader.d.mts +2 -1
  384. package/foundation/fs/module-loader.mjs +60 -4
  385. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  386. package/foundation/fs/module-loader.test.mjs +194 -0
  387. package/foundation/fs/path-compare.d.mts +33 -0
  388. package/foundation/fs/path-compare.mjs +73 -0
  389. package/foundation/fs/paths.d.mts +57 -1
  390. package/foundation/fs/paths.mjs +131 -3
  391. package/foundation/fs/paths.test.mjs +10 -1
  392. package/foundation/integrations/computer-integrations.d.mts +78 -0
  393. package/foundation/integrations/computer-integrations.mjs +316 -0
  394. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  395. package/foundation/integrations/contribution-inventory.d.mts +11 -0
  396. package/foundation/integrations/contribution-inventory.mjs +50 -2
  397. package/foundation/integrations/integration-warnings.mjs +3 -2
  398. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  399. package/foundation/integrations/integrations.d.mts +25 -1
  400. package/foundation/integrations/integrations.mjs +46 -3
  401. package/foundation/integrations/issue.ts +6 -0
  402. package/foundation/integrations/validate-contributions.d.mts +2 -0
  403. package/foundation/integrations/validate-contributions.mjs +41 -1
  404. package/foundation/release/agent-text-worker.d.mts +4 -0
  405. package/foundation/release/agent-text-worker.mjs +52 -0
  406. package/foundation/release/cache.d.mts +310 -0
  407. package/foundation/release/cache.mjs +1216 -0
  408. package/foundation/release/cache.test.mjs +920 -0
  409. package/foundation/release/choose.d.mts +207 -0
  410. package/foundation/release/choose.mjs +677 -0
  411. package/foundation/release/choose.test.mjs +427 -0
  412. package/foundation/release/core-worker.d.mts +4 -0
  413. package/foundation/release/core-worker.mjs +38 -0
  414. package/foundation/release/global-state.d.mts +259 -0
  415. package/foundation/release/global-state.mjs +472 -0
  416. package/foundation/release/global-state.test.mjs +381 -0
  417. package/foundation/release/handoff.d.mts +60 -0
  418. package/foundation/release/handoff.e2e.test.mjs +278 -0
  419. package/foundation/release/handoff.mjs +357 -0
  420. package/foundation/release/lock-lease.d.mts +23 -0
  421. package/foundation/release/lock-lease.mjs +80 -0
  422. package/foundation/release/notices.d.mts +253 -0
  423. package/foundation/release/notices.mjs +596 -0
  424. package/foundation/release/notices.test.mjs +565 -0
  425. package/foundation/release/npm-guard.d.mts +4 -0
  426. package/foundation/release/npm-guard.mjs +126 -0
  427. package/foundation/release/project.d.mts +141 -0
  428. package/foundation/release/project.mjs +466 -0
  429. package/foundation/release/project.test.mjs +288 -0
  430. package/foundation/release/refresh-worker.d.mts +4 -0
  431. package/foundation/release/refresh-worker.mjs +27 -0
  432. package/foundation/release/run-context.d.mts +47 -0
  433. package/foundation/release/run-context.mjs +149 -0
  434. package/foundation/release/update-notice-env.d.mts +28 -0
  435. package/foundation/release/update-notice-env.mjs +39 -0
  436. package/foundation/response/base.d.ts +26 -3
  437. package/foundation/response/error-codes.d.mts +3 -1
  438. package/foundation/response/error-codes.doc.mjs +12 -0
  439. package/foundation/response/error-codes.mjs +17 -0
  440. package/foundation/response/error-codes.test.mjs +2 -0
  441. package/foundation/response/json-contract.test.mjs +7 -2
  442. package/foundation/response/json.mjs +4 -1
  443. package/foundation/response/response-types.doc.mjs +17 -11
  444. package/foundation/response/response-types.doc.test.mjs +46 -0
  445. package/foundation/response/response.doc.mjs +3 -3
  446. package/foundation/xle/browser-imports.test.mjs +74 -0
  447. package/package.json +11 -11
  448. package/scripts/postinstall.mjs +24 -5
  449. /package/assets/codemods/transforms/{next → v0.7.2}/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +0 -0
  450. /package/assets/codemods/transforms/{next → v0.7.2}/migrate-list-edge-compensation-to-edge.mjs +0 -0
@@ -14,7 +14,7 @@
14
14
  // unsupported runtimes this guard protects against.
15
15
  //
16
16
  // Sibling package modules (e.g. `cli/`, `lib/`) are resolved by this bin's REAL
17
- // path. When the CLI is installed as a package, `npx astryx` runs this file
17
+ // path. When the CLI is installed as a package, the package manager runs this file
18
18
  // through the `node_modules/.bin/astryx` symlink, and some Node versions resolve
19
19
  // relative specifiers from the symlink's directory rather than the real package
20
20
  // — breaking bare `../…` imports with a cryptic ERR_MODULE_NOT_FOUND.
@@ -53,10 +53,24 @@ if (!isNodeVersionSupported(process.versions.node)) {
53
53
  process.exit(1);
54
54
  }
55
55
 
56
+ // Global mode: choose the release that answers this folder and, when it is
57
+ // not this copy, hand the run to it before anything the project provides (its
58
+ // astryx.config, integrations, or Core) is loaded. Returns only when this copy
59
+ // answers. See foundation/release/handoff.mjs and spec AST-081 FR2 and FR9.
60
+ const {startRun} = await importSrc('../../foundation/release/handoff.mjs');
61
+ await startRun({
62
+ cliRoot: join(binDir, '..', '..', '..'),
63
+ argv: process.argv.slice(2),
64
+ });
65
+
56
66
  // Imports that transitively load `styleText` must happen AFTER the gate above,
57
67
  // so they are dynamically imported here rather than at the top of the module.
58
- const {program, loadProjectDebugHandler, handleVersionJsonPreflight} =
59
- await importSrc('index.mjs');
68
+ const {
69
+ program,
70
+ loadProjectDebugHandler,
71
+ loadProjectForHelp,
72
+ handleVersionJsonPreflight,
73
+ } = await importSrc('index.mjs');
60
74
  const {isJsonMode, toErrorEnvelope} = await importSrc('../../foundation/response/json.mjs');
61
75
  const {handleCommanderError} = await importSrc('lib/json-shim.mjs');
62
76
  const {setOutcome} = await importSrc('../../foundation/debug/index.mjs');
@@ -107,6 +121,9 @@ process.on('uncaughtException', handleFatal);
107
121
  // Pick up the project's `debug` function before parsing, so parse errors and
108
122
  // `--help` — which short-circuit before any hook runs — are reported too.
109
123
  await loadProjectDebugHandler();
124
+ // Help prints its commands while Commander parses, so a help run reads the
125
+ // project's declared `cliCommand` here.
126
+ await loadProjectForHelp();
110
127
 
111
128
  // `--version --json` answers and exits without Commander, so it runs here —
112
129
  // after the handler exists, or the run would go unrecorded.
@@ -0,0 +1,166 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * Every printed command starts with the project's CLI command: the door a host
5
+ * sets, or the `cliCommand` a loaded integration declares. JSON keeps commands
6
+ * bare.
7
+ */
8
+
9
+ import {afterEach, beforeEach, describe, expect, it} from 'vitest';
10
+ import {spawnSync} from 'node:child_process';
11
+ import * as fs from 'node:fs';
12
+ import * as os from 'node:os';
13
+ import * as path from 'node:path';
14
+ import {runCli} from '../../test-utils/run-cli.mjs';
15
+ import {
16
+ hasRecordedProject,
17
+ runWithCliDoor,
18
+ } from '../../foundation/env/cli-command.mjs';
19
+ import {getCliInvocation} from '../../foundation/env/package-manager.mjs';
20
+ import {loadProjectForHelp} from './index.mjs';
21
+
22
+ const BIN = path.resolve(import.meta.dirname, 'bin', 'astryx.mjs');
23
+
24
+ /** @type {string} */
25
+ let tmpDir;
26
+
27
+ beforeEach(() => {
28
+ // Repo-local, so Vite permits importing the integration manifest.
29
+ tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-cli-command-'));
30
+ });
31
+
32
+ afterEach(() => {
33
+ fs.rmSync(tmpDir, {recursive: true, force: true});
34
+ });
35
+
36
+ /**
37
+ * An app that installs one integration declaring `cliCommand`, with no
38
+ * astryx.config: the integration is autolinked.
39
+ * @param {string} cliCommand
40
+ */
41
+ function appWithIntegration(cliCommand) {
42
+ fs.writeFileSync(
43
+ path.join(tmpDir, 'package.json'),
44
+ JSON.stringify({name: 'app', dependencies: {'@acme/x': '1.0.0'}}),
45
+ );
46
+ fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), '<!-- ASTRYX:START -->\n');
47
+ const pkg = path.join(tmpDir, 'node_modules', '@acme', 'x');
48
+ fs.mkdirSync(pkg, {recursive: true});
49
+ fs.writeFileSync(
50
+ path.join(pkg, 'package.json'),
51
+ JSON.stringify({name: '@acme/x', version: '1.0.0'}),
52
+ );
53
+ fs.writeFileSync(
54
+ path.join(pkg, 'astryx.integration.mjs'),
55
+ `export default ${JSON.stringify({cliCommand})};\n`,
56
+ );
57
+ }
58
+
59
+ describe("an integration's cliCommand", () => {
60
+ it('starts the hints of a command that never loads the project itself', async () => {
61
+ appWithIntegration('acme astryx');
62
+ const {status, stderr} = await runCli(['theme', 'remove', 'nope'], tmpDir);
63
+ expect(status).toBe(1);
64
+ expect(stderr).toContain('`acme astryx theme add nope`');
65
+ });
66
+ });
67
+
68
+ describe('the setup nudge in a project with no CLI of its own', () => {
69
+ it('names the declared cliCommand for the step after installing the CLI (spec AST-081 FR5)', async () => {
70
+ // Outside this repository: the nudge stays quiet in the CLI's own checkout.
71
+ const app = fs.mkdtempSync(
72
+ path.join(os.tmpdir(), 'astryx-cli-command-nudge-'),
73
+ );
74
+ try {
75
+ // Only Core, of another release than the CLI that answers, an
76
+ // integration declaring cliCommand, and no agent docs yet.
77
+ fs.writeFileSync(
78
+ path.join(app, 'package.json'),
79
+ JSON.stringify({
80
+ name: 'app',
81
+ dependencies: {'@acme/x': '1.0.0', '@astryxdesign/core': '0.0.1'},
82
+ }),
83
+ );
84
+ fs.writeFileSync(path.join(app, 'package-lock.json'), '{}');
85
+ for (const [name, version, extra] of [
86
+ ['@acme/x', '1.0.0', 'acme astryx'],
87
+ ['@astryxdesign/core', '0.0.1', null],
88
+ ]) {
89
+ const dir = path.join(app, 'node_modules', ...name.split('/'));
90
+ fs.mkdirSync(dir, {recursive: true});
91
+ fs.writeFileSync(
92
+ path.join(dir, 'package.json'),
93
+ JSON.stringify({name, version}),
94
+ );
95
+ if (extra) {
96
+ fs.writeFileSync(
97
+ path.join(dir, 'astryx.integration.mjs'),
98
+ `export default ${JSON.stringify({cliCommand: extra})};\n`,
99
+ );
100
+ }
101
+ }
102
+
103
+ const {stderr} = await runCli(['docs', 'tokens'], app);
104
+ expect(stderr).toContain(
105
+ 'Next step: run `npm install @astryxdesign/cli@0.0.1`, then `acme astryx init`',
106
+ );
107
+ } finally {
108
+ fs.rmSync(app, {recursive: true, force: true});
109
+ }
110
+ });
111
+ });
112
+
113
+ describe('help', () => {
114
+ it('loads the project for a help run, and only for one', async () => {
115
+ appWithIntegration('acme astryx');
116
+ const cwd = process.cwd();
117
+ process.chdir(tmpDir);
118
+ try {
119
+ await loadProjectForHelp(['docs', 'theme']);
120
+ expect(hasRecordedProject(tmpDir)).toBe(false);
121
+ await loadProjectForHelp(['component', '--help']);
122
+ expect(getCliInvocation(tmpDir)).toBe('acme astryx');
123
+ } finally {
124
+ process.chdir(cwd);
125
+ }
126
+ });
127
+
128
+ it("prints the integration's command in `--help`", () => {
129
+ appWithIntegration('acme astryx');
130
+ const result = spawnSync(process.execPath, [BIN, '--help'], {
131
+ cwd: tmpDir,
132
+ encoding: 'utf-8',
133
+ });
134
+ expect(result.status).toBe(0);
135
+ expect(result.stdout).toContain('acme astryx search button');
136
+ });
137
+ });
138
+
139
+ describe("a host's door", () => {
140
+ it('prefixes doc commands in text and leaves them bare in JSON', async () => {
141
+ const text = await runWithCliDoor('acme astryx', () =>
142
+ runCli(['docs', 'getting-started', '--full']),
143
+ );
144
+ expect(text.stdout).toContain('acme astryx init');
145
+
146
+ const json = await runWithCliDoor('acme astryx', () =>
147
+ runCli(['docs', 'getting-started', '--json']),
148
+ );
149
+ expect(json.stdout).toContain('astryx init');
150
+ expect(json.stdout).not.toContain('acme astryx');
151
+ });
152
+
153
+ it('prefixes suggested commands in text and leaves them bare in JSON', async () => {
154
+ const text = await runWithCliDoor('acme astryx', () =>
155
+ runCli(['search', '']),
156
+ );
157
+ expect(text.stderr).toContain('acme astryx search button');
158
+
159
+ const json = await runWithCliDoor('acme astryx', () =>
160
+ runCli(['search', '', '--json']),
161
+ );
162
+ expect(JSON.parse(json.stdout).suggestions[0].name).toBe(
163
+ 'astryx search button',
164
+ );
165
+ });
166
+ });
@@ -24,6 +24,7 @@ export const doc = {
24
24
  {label: 'List posts', cli: 'astryx blog'},
25
25
  {label: 'Read one post', cli: 'astryx blog introducing-astryx --json'},
26
26
  ],
27
+ outsideProject: 'same',
27
28
  exitCodes: [
28
29
  {code: 0, when: 'success'},
29
30
  {code: 1, when: 'unknown slug, or the feed or a post cannot be fetched'},
@@ -91,12 +91,24 @@ function count(text, pattern) {
91
91
 
92
92
  /** @param {string} stdout */
93
93
  function lines(stdout) {
94
- return stdout.split('\n').filter(Boolean);
94
+ return bareRecipe(stdout).split('\n').filter(Boolean);
95
+ }
96
+
97
+ /**
98
+ * The font recipe names `docs typography` with the project's CLI invocation,
99
+ * which depends on where the test runs; compare it as bare `astryx`.
100
+ * @param {string} stdout
101
+ */
102
+ function bareRecipe(stdout) {
103
+ return stdout.replace(
104
+ /(recipe: |guidance: )\S.*? docs typography/g,
105
+ '$1astryx docs typography',
106
+ );
95
107
  }
96
108
 
97
109
  /** @param {string} stdout The sizes follow Core's CSS, so goldens keep the shape. */
98
110
  function normalized(stdout) {
99
- return stdout.replace(/\d+(\.\d+)? KB/g, '<size> KB');
111
+ return bareRecipe(stdout).replace(/\d+(\.\d+)? KB/g, '<size> KB');
100
112
  }
101
113
 
102
114
  /** Bytes of the full report printed by one invocation per theme. */
@@ -75,7 +75,7 @@ describe('theme build font-loading warning', () => {
75
75
  expect(result.stdout).toContain('display=swap');
76
76
  expect(result.stdout).toContain('@font-face');
77
77
  expect(result.stdout).toContain('font-display: swap');
78
- expect(result.stdout).toContain('astryx docs typography');
78
+ expect(result.stdout).toContain(' docs typography');
79
79
  // The one-line summaries follow the CLI's stream contract. These are
80
80
  // NOTICES about a correct theme, not warnings, so they go to stdout with
81
81
  // the rest of the build's progress — stderr stays for the defects an
@@ -105,8 +105,8 @@ describe('theme build font-loading warning', () => {
105
105
  );
106
106
 
107
107
  expect(result.code).toBe(0);
108
- expect(result.stdout).toContain(
109
- '[note] Fonts named but not loaded: "Space Grotesk", "JetBrains Mono". Load them in your app (recipe: astryx docs typography).\n',
108
+ expect(result.stdout).toMatch(
109
+ /\[note\] Fonts named but not loaded: "Space Grotesk", "JetBrains Mono"\. Load them in your app \(recipe: .+ docs typography\)\.\n/,
110
110
  );
111
111
  expect(result.stdout).not.toContain('fonts.googleapis.com');
112
112
  expect(result.stdout).not.toContain('@font-face');
@@ -34,6 +34,7 @@ import * as path from 'node:path';
34
34
  import {fileURLToPath} from 'node:url';
35
35
  import {spawn} from 'node:child_process';
36
36
  import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
37
+ import {isOutsideProject} from '../../../foundation/env/project-scope.mjs';
37
38
  import {jsonOut} from '../../../foundation/response/json.mjs';
38
39
  import {
39
40
  emit,
@@ -224,10 +225,13 @@ async function runThemeBuildWatch(entries, options) {
224
225
  emit(text(watchingLine));
225
226
 
226
227
  await new Promise((/** @type {(value?: void) => void} */ resolve) => {
228
+ let stopping = false;
227
229
  /** @param {NodeJS.Signals} signal */
228
230
  const stop = async signal => {
229
- process.removeListener('SIGINT', stop);
230
- process.removeListener('SIGTERM', stop);
231
+ // A second interrupt while stopping (a terminal's Ctrl-C and the same
232
+ // signal passed on by the copy that started the run) changes nothing.
233
+ if (stopping) return;
234
+ stopping = true;
231
235
  stopped = true;
232
236
  queued.clear();
233
237
  for (const d of debounces.values()) clearTimeout(d);
@@ -237,10 +241,12 @@ async function runThemeBuildWatch(entries, options) {
237
241
  rebuildChild?.kill(signal);
238
242
  await rebuildDone;
239
243
  emit(text('\nStopped watching.'));
244
+ process.removeListener('SIGINT', stop);
245
+ process.removeListener('SIGTERM', stop);
240
246
  resolve();
241
247
  };
242
- process.once('SIGINT', stop);
243
- process.once('SIGTERM', stop);
248
+ process.on('SIGINT', stop);
249
+ process.on('SIGTERM', stop);
244
250
  });
245
251
  }
246
252
 
@@ -283,14 +289,24 @@ function printThemeAddList(themes) {
283
289
  return theme.description ? [head, theme.description] : head;
284
290
  }),
285
291
  ),
286
- text(
287
- `Import one: ${run} theme add <slug> [--package <package>]\n` +
288
- `Fork source: ${run} theme eject <slug> [target-path]`,
289
- ),
292
+ text(themeNextSteps(run)),
290
293
  more,
291
294
  );
292
295
  }
293
296
 
297
+ /**
298
+ * What to do with a listed theme. Outside a project there is no app to add one
299
+ * to, so only the fork step is named (spec AST-081 FR3).
300
+ * @param {string} run the CLI invocation
301
+ * @returns {string}
302
+ */
303
+ function themeNextSteps(run) {
304
+ const fork = `Fork source: ${run} theme eject <slug> [target-path]`;
305
+ return isOutsideProject()
306
+ ? fork
307
+ : `Import one: ${run} theme add <slug> [--package <package>]\n${fork}`;
308
+ }
309
+
294
310
  /**
295
311
  * Print every field in the `theme.list` entries. Duplicate slugs stay separate
296
312
  * because each record names its owner.
@@ -325,10 +341,7 @@ function printThemeList(themes, unmigratedCopies = []) {
325
341
  default: (/** @type {boolean} */ value) => (value ? 'yes' : 'no'),
326
342
  },
327
343
  }),
328
- text(
329
- `Import one: ${run} theme add <slug> [--package <package>]\n` +
330
- `Fork source: ${run} theme eject <slug> [target-path]`,
331
- ),
344
+ text(themeNextSteps(run)),
332
345
  more,
333
346
  );
334
347
  }
@@ -47,6 +47,7 @@ export const doc = {
47
47
  cli: 'astryx build "analytics dashboard" --json',
48
48
  },
49
49
  ],
50
+ outsideProject: 'same',
50
51
  exitCodes: [
51
52
  {code: 0, when: 'success (including zero matches)'},
52
53
  {
@@ -11,6 +11,7 @@ import * as os from 'node:os';
11
11
  import * as path from 'node:path';
12
12
  import {runCli} from '../../../test-utils/run-cli.mjs';
13
13
  import {doc as buildDoc} from './build.doc.mjs';
14
+ import {linkThisCliAsProjectCli} from '../../../test-utils/release-fixtures.mjs';
14
15
 
15
16
  const SLOW = 30_000;
16
17
 
@@ -20,6 +21,9 @@ let tmpDir;
20
21
  beforeEach(() => {
21
22
  tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-build-no-core-'));
22
23
  fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({name: 'consumer'}));
24
+ // A project whose own CLI answers and that installs no Core: outside a
25
+ // project a copy answers from the Core it carries instead (AST-081 FR3).
26
+ linkThisCliAsProjectCli(tmpDir);
23
27
  });
24
28
 
25
29
  afterEach(() => {
@@ -8,9 +8,16 @@
8
8
  * transient fetch (path _npx or npm_command=exec), and once set up.
9
9
  */
10
10
 
11
- import {describe, it, expect} from 'vitest';
11
+ import {describe, it, expect, beforeEach, afterEach} from 'vitest';
12
+ import {spawnSync} from 'node:child_process';
13
+ import * as fs from 'node:fs';
14
+ import * as os from 'node:os';
15
+ import * as path from 'node:path';
16
+ import {fileURLToPath} from 'node:url';
12
17
  import {shouldNudge} from '../../../scripts/postinstall.mjs';
13
18
 
19
+ const CLI = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../..');
20
+
14
21
  const DEP = '/proj/node_modules/@astryxdesign/cli/scripts/postinstall.mjs'; // real dep install
15
22
  const NPX = '/Users/x/.npm/_npx/a1b2/node_modules/@astryxdesign/cli/scripts/postinstall.mjs';
16
23
  const REPO = '/repo/packages/cli/scripts/postinstall.mjs'; // monorepo/source
@@ -40,3 +47,44 @@ describe('cli postinstall — shouldNudge', () => {
40
47
  expect(shouldNudge({})).toBe(false);
41
48
  });
42
49
  });
50
+
51
+ // Install time, end to end: the real script and the leaf it loads, installed
52
+ // under a monorepo's node_modules, run the way npm runs them for a package.
53
+ describe('cli postinstall — inside a monorepo package', () => {
54
+ let repo;
55
+ beforeEach(() => {
56
+ repo = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-cli-postinstall-'));
57
+ fs.mkdirSync(path.join(repo, '.git'));
58
+ fs.mkdirSync(path.join(repo, 'packages/app'), {recursive: true});
59
+ fs.writeFileSync(path.join(repo, 'packages/app/package.json'), '{"name":"app"}');
60
+ const installed = path.join(repo, 'node_modules/@astryxdesign/cli');
61
+ for (const rel of ['scripts/postinstall.mjs', 'foundation/agent-docs/agent-doc-state.mjs']) {
62
+ fs.mkdirSync(path.dirname(path.join(installed, rel)), {recursive: true});
63
+ fs.copyFileSync(path.join(CLI, rel), path.join(installed, rel));
64
+ }
65
+ });
66
+ afterEach(() => fs.rmSync(repo, {recursive: true, force: true}));
67
+
68
+ const install = () =>
69
+ spawnSync(
70
+ process.execPath,
71
+ [path.join(repo, 'node_modules/@astryxdesign/cli/scripts/postinstall.mjs')],
72
+ {
73
+ env: {...process.env, INIT_CWD: path.join(repo, 'packages/app'), npm_command: 'install'},
74
+ encoding: 'utf8',
75
+ },
76
+ );
77
+
78
+ it('stays quiet when init ran at the repository root', () => {
79
+ fs.writeFileSync(path.join(repo, 'AGENTS.md'), '<!-- ASTRYX:START -->\n');
80
+ const r = install();
81
+ expect(r.status).toBe(0);
82
+ expect(r.stdout).toBe('');
83
+ });
84
+
85
+ it('still nudges when no folder up to the repository root ran init', () => {
86
+ const r = install();
87
+ expect(r.status).toBe(0);
88
+ expect(r.stdout).toMatch(/finish setup and install the Astryx agent prompt/);
89
+ });
90
+ });
@@ -90,6 +90,7 @@ export const doc = {
90
90
  cli: 'astryx component SideNav --package @astryxdesign/core',
91
91
  },
92
92
  ],
93
+ outsideProject: 'same',
93
94
  exitCodes: [
94
95
  {code: 0, when: 'success'},
95
96
  {
@@ -68,8 +68,8 @@ describe('astryx discover with a manifest that fails to load', () => {
68
68
  const {status, stdout, stderr} = await runCli(['discover'], {cwd: project});
69
69
 
70
70
  expect(status).toBe(0);
71
- expect(stderr).toContain(
72
- 'Warning: @test/broken has 1 integration issue(s). Run: astryx doctor',
71
+ expect(stderr).toMatch(
72
+ /Warning: @test\/broken has 1 integration issue\(s\)\. Run: .+ doctor/,
73
73
  );
74
74
  expect(stdout).not.toContain('No integrations configured.');
75
75
  expect(stdout).toContain(
@@ -83,7 +83,11 @@ describe('astryx discover with a manifest that fails to load', () => {
83
83
  });
84
84
 
85
85
  expect(status).toBe(0);
86
- expect(JSON.parse(stdout).meta).toEqual({configured: true});
86
+ const {meta} = JSON.parse(stdout);
87
+ expect(meta.configured).toBe(true);
88
+ // The official list still answers; nothing else is claimed.
89
+ expect(meta.sources.map(s => s.name)).toEqual(['Astryx']);
90
+ expect(meta.answeredBy).toEqual(expect.any(Object));
87
91
  expect(stderr).not.toContain('integration issue');
88
92
  });
89
93
  });
@@ -129,8 +133,8 @@ describe('astryx discover with a configured package that is not installed', () =
129
133
  const {status, stderr} = await runCli(['discover'], {cwd: project});
130
134
 
131
135
  expect(status).toBe(0);
132
- expect(stderr).toContain(
133
- 'Warning: @test/missing has 1 integration issue(s). Run: astryx doctor\n',
136
+ expect(stderr).toMatch(
137
+ /Warning: @test\/missing has 1 integration issue\(s\)\. Run: .+ doctor\n/,
134
138
  );
135
139
  });
136
140
  });
@@ -148,8 +152,8 @@ describe('astryx search with a manifest that fails to load', () => {
148
152
  const {status, stderr} = await runCli(['search', 'button'], {cwd: project});
149
153
 
150
154
  expect(status).toBe(0);
151
- expect(stderr).toContain(
152
- 'Warning: @test/broken has 1 integration issue(s). Run: astryx doctor',
155
+ expect(stderr).toMatch(
156
+ /Warning: @test\/broken has 1 integration issue\(s\)\. Run: .+ doctor/,
153
157
  );
154
158
 
155
159
  const asJson = await runCli(['search', 'button', '--json'], {cwd: project});
@@ -17,7 +17,8 @@ export const doc = {
17
17
  summary:
18
18
  'Browse and search integrations: the ones you have and the ones you could add',
19
19
  description:
20
- 'Lists the integrations this project loads and, when it has a discover source, the ones it could add, with what each one adds. ' +
20
+ 'Lists what this project has, the integrations it loads and the official packages it declares, then what it could add: the official Astryx packages first, then whatever its discover sources list, with what each one adds. ' +
21
+ 'Inside a project, integrations installed for the computer, beside the CLI installed for it, are listed as ones the project could add, with its install command; outside one they load. ' +
21
22
  'A package query shows one package: what it adds, every version a source knows, and the command that adds it. ' +
22
23
  "An @scope/name/Component path prints an installed component's doc; any other item path shows that item. " +
23
24
  'Anything else, even an exact component name, searches every item and package and lists the matches. Discover only reads: your package manager installs, updates, and removes packages.',
@@ -78,6 +79,7 @@ export const doc = {
78
79
  cli: 'astryx discover dashboard --type template --available',
79
80
  },
80
81
  ],
82
+ outsideProject: 'same',
81
83
  exitCodes: [
82
84
  {code: 0, when: 'success'},
83
85
  {
@@ -86,4 +88,10 @@ export const doc = {
86
88
  },
87
89
  ],
88
90
  related: ['component', 'search', 'template'],
91
+ notes: [
92
+ {
93
+ type: 'prose',
94
+ text: "In global mode: outside a project, integrations installed next to your global install are listed as installed and their items show up; inside a project, only the project's integrations are, and the global ones the project could add are listed under available, with the project's install command. In a project, the project's version of Astryx runs it, whichever astryx command you start. See {@link namespace:global} and {@link generic:computer-integrations}.",
95
+ },
96
+ ],
89
97
  };