@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
@@ -0,0 +1,441 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx integration check`: every source check in one command, the
5
+ * summary, exit codes with and without `--strict`, and the `--strict`
6
+ * failures, in text and JSON alike.
7
+ */
8
+
9
+ import {afterEach, beforeEach, describe, expect, it} from 'vitest';
10
+ import * as fs from 'node:fs';
11
+ import * as os from 'node:os';
12
+ import * as path from 'node:path';
13
+ import {runCli} from '../../../test-utils/run-cli.mjs';
14
+ import {discoverCoreTemplates} from '../../../foundation/discovery/template-adapter.mjs';
15
+
16
+ /** @type {string} */
17
+ let tmpDir;
18
+
19
+ beforeEach(() => {
20
+ // Under the repository, so the components check resolves Core.
21
+ tmpDir = fs.mkdtempSync(
22
+ path.join(process.cwd(), '.astryx-integration-check-cli-'),
23
+ );
24
+ });
25
+
26
+ afterEach(() => {
27
+ fs.rmSync(tmpDir, {recursive: true, force: true});
28
+ });
29
+
30
+ /**
31
+ * A package whose one page template takes a Core template's id: one warning
32
+ * (`templates` conflict). The doc matches TemplateDoc, so no other check
33
+ * warns about it.
34
+ * @param {{id: string, replaces?: string, extraManifest?: string, dir?: string}} options
35
+ */
36
+ function writePackage({id, replaces, extraManifest = '', dir = tmpDir}) {
37
+ fs.writeFileSync(
38
+ path.join(dir, 'package.json'),
39
+ JSON.stringify({name: '@acme/widgets', version: '1.2.3'}),
40
+ );
41
+ fs.writeFileSync(
42
+ path.join(dir, 'astryx.integration.mjs'),
43
+ `export default {templates: './templates'${extraManifest}};\n`,
44
+ );
45
+ fs.mkdirSync(path.join(dir, 'templates'), {recursive: true});
46
+ fs.writeFileSync(
47
+ path.join(dir, 'templates', `${id}.doc.mjs`),
48
+ `export default {type: 'page', name: 'Integration template', displayName: 'Integration template', description: 'fixture'${replaces == null ? '' : `, replaces: ${JSON.stringify(replaces)}`}};\n`,
49
+ );
50
+ fs.writeFileSync(
51
+ path.join(dir, 'templates', `${id}.tsx`),
52
+ 'export default function Fixture() { return null; }\n',
53
+ );
54
+ }
55
+
56
+ async function coreTemplateId() {
57
+ const core = (await discoverCoreTemplates()).find(
58
+ template => template.type === 'page',
59
+ );
60
+ expect(core).toBeDefined();
61
+ return /** @type {{dirName: string}} */ (core).dirName;
62
+ }
63
+
64
+ describe('astryx integration check', () => {
65
+ it('runs validate, components, templates, and docs in order, then a summary, and exits 0 on a warning', async () => {
66
+ writePackage({id: await coreTemplateId()});
67
+
68
+ const run = await runCli(['integration', 'check'], tmpDir);
69
+
70
+ const order = [
71
+ 'Validating integration: @acme/widgets@1.2.3',
72
+ 'Checking integration components: @acme/widgets@1.2.3',
73
+ 'Checking integration templates: @acme/widgets@1.2.3',
74
+ 'Checking integration docs: @acme/widgets@1.2.3',
75
+ 'Integration check: @acme/widgets@1.2.3',
76
+ ].map(line => run.stdout.indexOf(line));
77
+ expect(order.every(index => index >= 0)).toBe(true);
78
+ expect([...order].sort((a, b) => a - b)).toEqual(order);
79
+ expect(run.stdout).toContain('Consider renaming');
80
+ expect(run.stdout).not.toContain('Failing under --strict');
81
+ expect(run.stdout).toContain(
82
+ '[ok] 0 errors, 1 warning, 0 skipped. No check failed;',
83
+ );
84
+ // Each check's output stands apart from the next.
85
+ const lines = run.stdout.split('\n');
86
+ for (const header of [
87
+ 'Checking integration components:',
88
+ 'Checking integration templates:',
89
+ 'Checking integration docs:',
90
+ ]) {
91
+ expect(lines[lines.findIndex(line => line.includes(header)) - 1]).toBe(
92
+ '',
93
+ );
94
+ }
95
+ expect(run.status).toBe(0);
96
+ });
97
+
98
+ it('--strict lists the warning again as an error, after the checks, and exits 1', async () => {
99
+ const id = await coreTemplateId();
100
+ writePackage({id});
101
+
102
+ const run = await runCli(['integration', 'check', '--strict'], tmpDir);
103
+
104
+ expect(run.stdout).toContain(
105
+ 'Integration check: @acme/widgets@1.2.3 (strict)',
106
+ );
107
+ const block = run.stdout.indexOf('Failing under --strict');
108
+ expect(block).toBeGreaterThan(
109
+ run.stdout.indexOf('Checking integration docs:'),
110
+ );
111
+ expect(run.stdout.slice(block)).toMatch(
112
+ /severity: \[fail\]\ncheck: +templates\ncode: +template_id_conflict\n/,
113
+ );
114
+ expect(run.stdout).toContain(
115
+ '[fail] 0 errors, 1 warning, 0 skipped. --strict fails on every warning and on skipped work;',
116
+ );
117
+ expect(run.status).toBe(1);
118
+ });
119
+
120
+ it('--strict prints each finding once: its message above, its code in the failing list', async () => {
121
+ const id = await coreTemplateId();
122
+ writePackage({id});
123
+
124
+ const run = await runCli(['integration', 'check', '--strict'], tmpDir);
125
+ const json = await runCli(
126
+ ['integration', 'check', '--strict', '--json'],
127
+ tmpDir,
128
+ );
129
+ const [failure] = JSON.parse(json.stdout.trim()).data.failures;
130
+
131
+ expect(run.stdout.split(failure.message).length - 1).toBe(1);
132
+ expect(
133
+ run.stdout.slice(run.stdout.indexOf('Failing under --strict')),
134
+ ).toContain('template_id_conflict');
135
+ });
136
+
137
+ it('--json carries each check with its own envelope, the --strict failures, and exits as the text does', async () => {
138
+ const id = await coreTemplateId();
139
+ writePackage({id});
140
+
141
+ const run = await runCli(
142
+ ['integration', 'check', '--strict', '--json'],
143
+ tmpDir,
144
+ );
145
+
146
+ const parsed = JSON.parse(run.stdout.trim());
147
+ expect(parsed.type).toBe('integration.check');
148
+ expect(parsed.data).toMatchObject({
149
+ validated: true,
150
+ name: '@acme/widgets',
151
+ version: '1.2.3',
152
+ strict: true,
153
+ errors: 0,
154
+ warnings: 1,
155
+ skipped: [],
156
+ failed: true,
157
+ });
158
+ expect(parsed.data.checks.map(check => check.check)).toEqual([
159
+ 'validate',
160
+ 'components',
161
+ 'templates',
162
+ 'docs',
163
+ ]);
164
+ const templates = parsed.data.checks[2];
165
+ expect(templates).toMatchObject({
166
+ check: 'templates',
167
+ errors: 0,
168
+ warnings: 1,
169
+ skipped: [],
170
+ failed: false,
171
+ response: {
172
+ type: 'integration.template-conflicts',
173
+ data: {conflicts: [expect.objectContaining({id, severity: 'warning'})]},
174
+ },
175
+ });
176
+ expect(parsed.data.failures).toEqual([
177
+ {
178
+ check: 'templates',
179
+ severity: 'error',
180
+ code: 'template_id_conflict',
181
+ message: templates.response.data.conflicts[0].message,
182
+ },
183
+ ]);
184
+ expect(run.status).toBe(1);
185
+ });
186
+
187
+ it('exits 1 without --strict when one check fails on its own, and lists no failures', async () => {
188
+ writePackage({id: 'acme-app-shell', replaces: 'missing-core-shell'});
189
+
190
+ const text = await runCli(['integration', 'check'], tmpDir);
191
+ const json = await runCli(['integration', 'check', '--json'], tmpDir);
192
+
193
+ expect(text.stdout).toContain('missing_template_replacement_target');
194
+ expect(text.stdout).toMatch(
195
+ /\[fail\] [1-9]\d* errors?, .*Address the items marked \[fail\] above\./,
196
+ );
197
+ expect(text.stdout).not.toContain('Failing under --strict');
198
+ expect(JSON.parse(json.stdout.trim()).data).toMatchObject({
199
+ strict: false,
200
+ failures: [],
201
+ failed: true,
202
+ });
203
+ expect(text.status).toBe(1);
204
+ expect(json.status).toBe(1);
205
+ });
206
+
207
+ it('counts a package with no manifest as skipped work: exit 0, and 1 with --strict', async () => {
208
+ fs.writeFileSync(
209
+ path.join(tmpDir, 'package.json'),
210
+ JSON.stringify({name: '@acme/plain', version: '1.0.0'}),
211
+ );
212
+
213
+ const loose = await runCli(['integration', 'check'], tmpDir);
214
+ expect(loose.stdout).toContain(
215
+ "Nothing was checked: no astryx.integration.* found next to package.json. Run this command in an integration package's folder.",
216
+ );
217
+ // One cause, however many checks it stops: counted once.
218
+ expect(loose.stdout).toContain('[ok] 0 errors, 0 warnings, 1 skipped.');
219
+ expect(loose.status).toBe(0);
220
+
221
+ const strict = await runCli(
222
+ ['integration', 'check', '--strict', '--json'],
223
+ tmpDir,
224
+ );
225
+ const {data} = JSON.parse(strict.stdout.trim());
226
+ expect(data).toMatchObject({validated: false, errors: 0, failed: true});
227
+ // One cause, however many checks it stops: listed once.
228
+ expect(data.failures).toEqual([
229
+ {
230
+ check: 'validate',
231
+ severity: 'error',
232
+ code: 'missing_manifest',
233
+ message:
234
+ 'No astryx.integration.* found next to package.json, so nothing was checked.',
235
+ },
236
+ ]);
237
+ expect(strict.status).toBe(1);
238
+ });
239
+
240
+ it('exits 1 for no package.json, as validate does', async () => {
241
+ const empty = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-no-pkg-'));
242
+ try {
243
+ const run = await runCli(['integration', 'check'], empty);
244
+ expect(run.stdout).toContain(
245
+ 'Nothing was checked: no package.json found.',
246
+ );
247
+ expect(run.stdout).toContain('Integration check: (no package.json)');
248
+ expect(run.stdout).toContain(
249
+ '[fail] 1 error, 0 warnings, 0 skipped. No package.json was found here, so nothing was checked.',
250
+ );
251
+ expect(run.stdout).not.toContain('marked [fail] above');
252
+ expect(run.status).toBe(1);
253
+ } finally {
254
+ fs.rmSync(empty, {recursive: true, force: true});
255
+ }
256
+ });
257
+
258
+ it('states in its help that it is the CI check, the line to add, and what --strict promises', async () => {
259
+ const run = await runCli(['integration', 'check', '--help'], tmpDir);
260
+
261
+ expect(run.stdout).toContain(
262
+ "The CI check for an integration package's own build",
263
+ );
264
+ expect(run.stdout).toContain(
265
+ '"typecheck": "tsc --noEmit && astryx integration check --strict"',
266
+ );
267
+ expect(run.stdout).toContain(
268
+ 'A new check or failure code joins only in a minor release, named in the release notes; until then, a malformed `cliCommand` is reported as a note (`invalid_cli_command`) that fails nothing.',
269
+ );
270
+ expect(run.stdout).toContain('integration verify');
271
+ expect(run.stdout).toContain('against the package in the current folder');
272
+ expect(run.stdout).not.toContain('[package]');
273
+ });
274
+
275
+ it('reports a malformed cliCommand as a note beside the issues, which --strict does not fail', async () => {
276
+ // A unique template id, so nothing else warns.
277
+ writePackage({
278
+ id: 'acme-notes-only-fixture',
279
+ extraManifest: ", cliCommand: ' acme astryx\\n'",
280
+ });
281
+
282
+ const json = await runCli(
283
+ ['--json', 'integration', 'check', '--strict'],
284
+ tmpDir,
285
+ );
286
+ const envelope = JSON.parse(json.stdout);
287
+ const validate = envelope.data.checks[0].response.data;
288
+ expect(validate.issues.map((/** @type {any} */ i) => i.code)).not.toContain(
289
+ 'invalid_cli_command',
290
+ );
291
+ expect(validate.notes).toEqual([
292
+ {code: 'invalid_cli_command', message: expect.any(String)},
293
+ ]);
294
+ expect(envelope.data.failed).toBe(false);
295
+ expect(json.status).toBe(0);
296
+
297
+ const text = await runCli(['integration', 'check'], tmpDir);
298
+ expect(
299
+ text.stdout
300
+ .split('\n')
301
+ .filter(line => line.startsWith('note (invalid_cli_command): ')),
302
+ ).toHaveLength(1);
303
+ });
304
+
305
+ it('takes no package name: one passed is an error, not a check of the current folder', async () => {
306
+ writePackage({id: 'acme-page'});
307
+
308
+ const run = await runCli(['integration', 'check', '@acme/widgets'], tmpDir);
309
+
310
+ expect(run.stderr).toContain('too many arguments');
311
+ expect(run.stdout).not.toContain('Integration check:');
312
+ expect(run.status).toBe(1);
313
+ });
314
+ });
315
+
316
+ describe('a copied passage', () => {
317
+ const passage =
318
+ 'Themes cannot style the layer that holds a menu or a popover, so a menu ' +
319
+ 'keeps the default surface color until the next release adds a token for it.';
320
+
321
+ function writeCopiedDocs() {
322
+ fs.writeFileSync(
323
+ path.join(tmpDir, 'package.json'),
324
+ JSON.stringify({name: '@acme/widgets', version: '1.2.3'}),
325
+ );
326
+ fs.writeFileSync(
327
+ path.join(tmpDir, 'astryx.integration.mjs'),
328
+ `export default {docs: './docs'};\n`,
329
+ );
330
+ fs.mkdirSync(path.join(tmpDir, 'docs'));
331
+ for (const name of ['acme-setup', 'acme-menus']) {
332
+ const doc = {
333
+ type: 'generic',
334
+ name,
335
+ title: 'Fixture',
336
+ description: 'Fixture topic.',
337
+ sections: [
338
+ {title: 'Overview', content: [{type: 'prose', text: passage}]},
339
+ ],
340
+ };
341
+ fs.writeFileSync(
342
+ path.join(tmpDir, 'docs', `${name}.doc.mjs`),
343
+ `export default ${JSON.stringify(doc)};\n`,
344
+ );
345
+ }
346
+ }
347
+
348
+ it('keeps doctor integration docs at exit 0, and fails integration check --strict', async () => {
349
+ writeCopiedDocs();
350
+
351
+ const doctor = await runCli(['doctor', 'integration', 'docs'], tmpDir);
352
+ expect(doctor.status).toBe(0);
353
+ expect(doctor.stdout).toContain('1 copied passage(s)');
354
+
355
+ const loose = await runCli(['integration', 'check'], tmpDir);
356
+ expect(loose.status).toBe(0);
357
+
358
+ const strict = await runCli(['integration', 'check', '--strict'], tmpDir);
359
+ expect(strict.status).toBe(1);
360
+ expect(strict.stdout).toContain('copied_passage');
361
+ });
362
+ });
363
+
364
+ describe('a padding phrase', () => {
365
+ it('keeps doctor integration docs at exit 0, and fails integration check --strict', async () => {
366
+ fs.writeFileSync(
367
+ path.join(tmpDir, 'package.json'),
368
+ JSON.stringify({name: '@acme/widgets', version: '1.2.3'}),
369
+ );
370
+ fs.writeFileSync(
371
+ path.join(tmpDir, 'astryx.integration.mjs'),
372
+ `export default {docs: './docs'};\n`,
373
+ );
374
+ fs.mkdirSync(path.join(tmpDir, 'docs'));
375
+ const doc = {
376
+ type: 'generic',
377
+ name: 'acme-setup',
378
+ title: 'Fixture',
379
+ description: 'Fixture topic.',
380
+ sections: [
381
+ {
382
+ title: 'Overview',
383
+ content: [{type: 'prose', text: 'In order to start, run the setup.'}],
384
+ },
385
+ ],
386
+ };
387
+ fs.writeFileSync(
388
+ path.join(tmpDir, 'docs', 'acme-setup.doc.mjs'),
389
+ `export default ${JSON.stringify(doc)};\n`,
390
+ );
391
+
392
+ const doctor = await runCli(['doctor', 'integration', 'docs'], tmpDir);
393
+ expect(doctor.status).toBe(0);
394
+ expect(doctor.stdout).toContain('1 fluff finding(s)');
395
+
396
+ const strict = await runCli(['integration', 'check', '--strict'], tmpDir);
397
+ expect(strict.status).toBe(1);
398
+ expect(strict.stdout).toContain('doc_fluff');
399
+ });
400
+ });
401
+
402
+ describe('a stray doc pointer', () => {
403
+ it('keeps doctor integration docs at exit 0, and fails integration check --strict', async () => {
404
+ fs.writeFileSync(
405
+ path.join(tmpDir, 'package.json'),
406
+ JSON.stringify({name: '@acme/widgets', version: '1.2.3'}),
407
+ );
408
+ fs.writeFileSync(
409
+ path.join(tmpDir, 'astryx.integration.mjs'),
410
+ `export default {docs: './docs'};\n`,
411
+ );
412
+ fs.mkdirSync(path.join(tmpDir, 'docs'));
413
+ const doc = {
414
+ type: 'generic',
415
+ name: 'acme-setup',
416
+ title: 'Fixture',
417
+ description: 'Fixture topic.',
418
+ sections: [
419
+ {
420
+ title: 'Overview',
421
+ content: [
422
+ {type: 'prose', text: 'The theme is in `astryx docs theme`.'},
423
+ ],
424
+ },
425
+ ],
426
+ };
427
+ fs.writeFileSync(
428
+ path.join(tmpDir, 'docs', 'acme-setup.doc.mjs'),
429
+ `export default ${JSON.stringify(doc)};\n`,
430
+ );
431
+
432
+ const doctor = await runCli(['doctor', 'integration', 'docs'], tmpDir);
433
+ expect(doctor.status).toBe(0);
434
+ expect(doctor.stdout).toContain('1 stray doc pointer(s)');
435
+ expect(doctor.stdout).toContain('{@link @astryxdesign/cli:generic:theme}');
436
+
437
+ const strict = await runCli(['integration', 'check', '--strict'], tmpDir);
438
+ expect(strict.status).toBe(1);
439
+ expect(strict.stdout).toContain('stray_doc_pointer');
440
+ });
441
+ });
@@ -8,7 +8,7 @@ export const doc = {
8
8
  namespace: 'cli/commands',
9
9
  summary: 'Deprecated: the old name of `integration verify`',
10
10
  description:
11
- '`astryx integration pack --check` is the name this check had before {@link command:integration verify}. It still runs the same check, with the same output, JSON, and exit codes, and prints a note that names `integration verify`. It will be removed in a later release.',
11
+ '`astryx integration pack --check` is the name this check had before {@link command:integration verify}. It still runs the same check, with the same output, JSON, and exit codes, and prints a note that names `integration verify`. It will be removed in a later release. Outside a package it writes nothing and reports one failed check, no_package, naming the integration package it needs (exit 1).',
12
12
  fn: 'integrationPackCheck',
13
13
  options: [
14
14
  {
@@ -19,6 +19,7 @@ export const doc = {
19
19
  examples: [
20
20
  {label: 'The old spelling', cli: 'astryx integration pack --check'},
21
21
  ],
22
+ outsideProject: 'own',
22
23
  exitCodes: [
23
24
  {code: 0, when: 'the packed package exposes the same valid contributions'},
24
25
  {
@@ -27,4 +28,10 @@ export const doc = {
27
28
  },
28
29
  ],
29
30
  related: ['integration verify'],
31
+ notes: [
32
+ {
33
+ type: 'prose',
34
+ text: "In global mode: outside a package, `integration pack --check` writes nothing, reports one failed check, `no_package`, and exits 1. In a project, the project's version of Astryx runs it, whichever astryx command you start. See {@link namespace:global} and {@link generic:global-integrations}.",
35
+ },
36
+ ],
30
37
  };
@@ -8,15 +8,22 @@ export const doc = {
8
8
  namespace: 'cli/commands',
9
9
  summary: 'Check the package the way npm will publish it, before you publish',
10
10
  description:
11
- 'Packs the package with npm, unpacks the tarball into a temporary app without installing its dependencies, and checks that the app sees the same components, templates, themes, docs, and codemods as the package, that every public import resolves, and that the package declares a CLI new enough to read it. It publishes nothing and leaves no tarball behind. It runs the package\'s own pack lifecycle scripts, as `npm pack` does.',
11
+ 'Packs the package with npm, unpacks the tarball into a temporary app without installing its dependencies, and checks that the app sees the same components, templates, themes, docs, and codemods as the package, that every public import resolves, and that the package declares a CLI new enough to read it. It publishes nothing and leaves no tarball behind. It runs the package\'s own pack lifecycle scripts, as `npm pack` does. Outside a package it writes nothing and reports one failed check, no_package, naming the integration package it needs (exit 1).',
12
12
  fn: 'integrationPackCheck',
13
13
  examples: [
14
14
  {label: 'Check before publishing', cli: 'astryx integration verify'},
15
15
  {label: 'Machine-readable result', cli: 'astryx integration verify --json'},
16
16
  ],
17
+ outsideProject: 'own',
17
18
  exitCodes: [
18
19
  {code: 0, when: 'the packed package exposes the same valid contributions'},
19
20
  {code: 1, when: 'the tarball is incomplete or invalid'},
20
21
  ],
21
22
  related: ['integration add', 'doctor integration validate'],
23
+ notes: [
24
+ {
25
+ type: 'prose',
26
+ text: "In global mode: outside a package, it writes nothing, reports one failed check, `no_package`, and exits 1. In a project, the project's version of Astryx runs it, whichever astryx command you start. See {@link namespace:global} and {@link generic:global-integrations}.",
27
+ },
28
+ ],
22
29
  };
@@ -8,13 +8,17 @@ export const doc = {
8
8
  namespace: 'cli/commands',
9
9
  summary: 'Author and verify an Astryx integration package',
10
10
  description:
11
- 'Add contributions to your package, then check the packed package the way an app receives it. The guides start at {@link namespace:integrations}.',
12
- subcommands: ['add', 'verify', 'pack'],
11
+ 'Add contributions to your package, check them on every build with `integration check --strict`, then check the packed package the way an app receives it. The guides start at {@link namespace:integrations}.',
12
+ subcommands: ['add', 'check', 'verify', 'pack'],
13
13
  examples: [
14
14
  {
15
15
  label: 'Add a component',
16
16
  cli: 'astryx integration add component AcmeWidget',
17
17
  },
18
+ {
19
+ label: 'Check the package in CI, as part of its build',
20
+ cli: 'astryx integration check --strict',
21
+ },
18
22
  {
19
23
  label: 'Check the package before publishing',
20
24
  cli: 'astryx integration verify',