@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4

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 (331) hide show
  1. package/README.md +96 -99
  2. package/api/build/build.doc.mjs +1 -6
  3. package/api/build/build.test.mjs +0 -22
  4. package/api/build/kit/kit.mjs +5 -44
  5. package/api/component/_adapter.d.mts +0 -25
  6. package/api/component/_adapter.mjs +5 -59
  7. package/api/component/component.d.mts +3 -6
  8. package/api/component/component.doc.mjs +17 -37
  9. package/api/component/component.mjs +9 -249
  10. package/api/component/component.type.d.mts +0 -25
  11. package/api/component/component.type.mjs +0 -44
  12. package/api/discover/_adapter.d.mts +6 -114
  13. package/api/discover/_adapter.mjs +17 -372
  14. package/api/discover/detail/detail.d.mts +6 -18
  15. package/api/discover/detail/detail.mjs +13 -67
  16. package/api/discover/detail/detail.test.mjs +0 -85
  17. package/api/discover/discover.d.mts +9 -3
  18. package/api/discover/discover.doc.mjs +18 -61
  19. package/api/discover/discover.mjs +36 -220
  20. package/api/discover/discover.test.mjs +2 -11
  21. package/api/discover/discover.type.d.mts +8 -147
  22. package/api/discover/discover.type.mjs +12 -102
  23. package/api/discover/list/list.d.mts +6 -20
  24. package/api/discover/list/list.mjs +12 -45
  25. package/api/discover/list/list.test.mjs +0 -46
  26. package/api/discover/search/search.d.mts +16 -18
  27. package/api/discover/search/search.mjs +56 -102
  28. package/api/discover/search/search.test.mjs +10 -144
  29. package/api/docs/_adapter.d.mts +3 -8
  30. package/api/docs/_adapter.mjs +6 -14
  31. package/api/docs/docOverlays.test.mjs +1 -27
  32. package/api/docs/docs.doc.mjs +2 -2
  33. package/api/docs/docs.test.mjs +243 -0
  34. package/api/docs/integration-tree.test.mjs +555 -0
  35. package/api/docs/integrationDocs.test.mjs +314 -0
  36. package/api/doctor/doctor.d.mts +3 -8
  37. package/api/doctor/doctor.doc.mjs +8 -17
  38. package/api/doctor/doctor.mjs +9 -90
  39. package/api/doctor/doctor.test.mjs +10 -122
  40. package/api/doctor/doctor.type.d.mts +1 -1
  41. package/api/doctor/doctor.type.mjs +1 -1
  42. package/api/gap-report/gap-report.doc.mjs +10 -19
  43. package/api/hook/hook.doc.mjs +3 -6
  44. package/api/index.d.mts +2 -1
  45. package/api/index.mjs +5 -5
  46. package/api/init/init.doc.mjs +12 -17
  47. package/api/integration/add-helpers.d.mts +2 -5
  48. package/api/integration/add-helpers.mjs +9 -36
  49. package/api/integration/add-theme.mjs +1 -22
  50. package/api/integration/add-theme.test.mjs +0 -34
  51. package/api/integration/authoring-checks.mjs +2 -2
  52. package/api/integration/integrationPackCheck.doc.mjs +3 -3
  53. package/api/integration/pack-check.mjs +9 -82
  54. package/api/integration/pack-check.test.mjs +0 -90
  55. package/api/integration/pack-check.type.mjs +1 -1
  56. package/api/json/assertResponse.doc.mjs +1 -1
  57. package/api/json/index.ts +1 -0
  58. package/api/json/isError.doc.mjs +1 -1
  59. package/api/layout/_adapter.d.mts +34 -0
  60. package/api/layout/_adapter.mjs +148 -0
  61. package/api/layout/check/check.d.mts +16 -0
  62. package/api/layout/check/check.mjs +40 -0
  63. package/api/layout/expand/expand.d.mts +22 -0
  64. package/api/layout/expand/expand.mjs +155 -0
  65. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  66. package/api/layout/grammar/grammar.d.mts +13 -0
  67. package/api/layout/grammar/grammar.mjs +87 -0
  68. package/api/layout/layout.d.mts +6 -0
  69. package/api/layout/layout.mjs +17 -0
  70. package/api/layout/layout.test.mjs +297 -0
  71. package/api/layout/layout.type.d.mts +89 -0
  72. package/api/layout/layout.type.mjs +103 -0
  73. package/api/layout/layoutCheck.doc.d.mts +11 -0
  74. package/api/layout/layoutCheck.doc.mjs +85 -0
  75. package/api/layout/layoutExpand.doc.d.mts +11 -0
  76. package/api/layout/layoutExpand.doc.mjs +107 -0
  77. package/api/layout/layoutGrammar.doc.d.mts +11 -0
  78. package/api/layout/layoutGrammar.doc.mjs +57 -0
  79. package/api/search/search.d.mts +1 -27
  80. package/api/search/search.doc.mjs +2 -2
  81. package/api/search/search.mjs +16 -228
  82. package/api/search/search.test.mjs +512 -0
  83. package/api/swizzle/swizzle.doc.mjs +5 -7
  84. package/api/template/copy/copy.mjs +1 -1
  85. package/api/template/copy/copy.test.mjs +0 -9
  86. package/api/template/template-integration.test.mjs +65 -1
  87. package/api/template/template.doc.mjs +1 -2
  88. package/api/template/template.mjs +1 -1
  89. package/api/theme/add/add.mjs +25 -17
  90. package/api/theme/add/add.staging.test.mjs +23 -40
  91. package/api/theme/build/build.family.test.mjs +12 -7
  92. package/api/theme/build/build.mjs +18 -8
  93. package/api/theme/generateTonalPalette.doc.mjs +2 -1
  94. package/api/theme/listThemes.doc.mjs +1 -1
  95. package/api/theme/themeAdd.doc.mjs +10 -9
  96. package/api/theme/themeBuild.doc.mjs +13 -13
  97. package/api/theme/themeList.doc.mjs +1 -1
  98. package/api/theme/themeListAvailable.doc.mjs +1 -2
  99. package/api/theme/themePaletteGenerate.doc.mjs +8 -15
  100. package/api/theme/themeTargets.doc.mjs +2 -3
  101. package/api/theme/themeTemplate.doc.mjs +1 -2
  102. package/api/upgrade/run/run.mjs +4 -6
  103. package/api/upgrade/upgrade.doc.mjs +22 -24
  104. package/api/upgrade/upgrade.type.mjs +2 -2
  105. package/assets/codemods/__tests__/runner.test.mjs +1 -3
  106. package/assets/codemods/integration-runner.mjs +3 -3
  107. package/assets/codemods/runner.mjs +4 -5
  108. package/assets/docs/README.md +2 -4
  109. package/assets/docs/browser-support.doc.mjs +11 -11
  110. package/assets/docs/color.doc.mjs +2 -8
  111. package/assets/docs/elevation.doc.mjs +4 -6
  112. package/assets/docs/getting-started.doc.mjs +16 -5
  113. package/assets/docs/icons.doc.mjs +21 -2
  114. package/assets/docs/illustrations.doc.mjs +15 -7
  115. package/assets/docs/internationalization.doc.mjs +5 -7
  116. package/assets/docs/layout.doc.dense.mjs +82 -130
  117. package/assets/docs/layout.doc.mjs +77 -133
  118. package/assets/docs/migration.doc.mjs +21 -19
  119. package/assets/docs/motion.doc.mjs +3 -16
  120. package/assets/docs/principles.doc.dense.mjs +5 -5
  121. package/assets/docs/principles.doc.mjs +0 -8
  122. package/assets/docs/principles.doc.zh.mjs +6 -6
  123. package/assets/docs/shape.doc.mjs +3 -8
  124. package/assets/docs/spacing.doc.mjs +2 -7
  125. package/assets/docs/styling-libraries.doc.mjs +2 -6
  126. package/assets/docs/styling.doc.mjs +23 -19
  127. package/assets/docs/theme.doc.dense.mjs +18 -58
  128. package/assets/docs/theme.doc.mjs +46 -56
  129. package/assets/docs/theme.doc.zh.mjs +8 -9
  130. package/assets/docs/tokens.doc.dense.mjs +2 -2
  131. package/assets/docs/tokens.doc.mjs +8 -389
  132. package/assets/docs/tokens.doc.zh.mjs +2 -2
  133. package/assets/docs/tree/integrations.doc.mjs +451 -25
  134. package/assets/docs/tree/integrations.test.mjs +62 -0
  135. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  136. package/assets/docs/typography.doc.mjs +4 -24
  137. package/assets/docs/working-with-ai.doc.mjs +22 -30
  138. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  139. package/authoring/config/config.doc.mjs +2 -10
  140. package/authoring/config/parse.d.mts +0 -2
  141. package/authoring/config/parse.mjs +0 -19
  142. package/authoring/config/parse.test.mjs +0 -8
  143. package/authoring/config/type.ts +2 -13
  144. package/authoring/doctypes/_schema.d.mts +2 -3
  145. package/authoring/doctypes/_schema.mjs +0 -6
  146. package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
  147. package/authoring/doctypes/base/type.ts +2 -4
  148. package/authoring/doctypes/command/command.doc.mjs +1 -1
  149. package/authoring/doctypes/command/type.ts +1 -1
  150. package/authoring/doctypes/component/component.doc.mjs +0 -6
  151. package/authoring/doctypes/component/type.ts +0 -8
  152. package/authoring/doctypes/reference/reference.doc.mjs +0 -7
  153. package/authoring/doctypes/reference/type.ts +0 -5
  154. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  155. package/authoring/doctypes/template/template.doc.mjs +1 -1
  156. package/authoring/doctypes/template/type.ts +2 -2
  157. package/authoring/index.d.mts +0 -1
  158. package/authoring/index.d.ts +0 -10
  159. package/authoring/index.mjs +0 -1
  160. package/authoring/integration/integration.doc.mjs +10 -12
  161. package/clients/cli/command-result-coverage.test.mjs +7 -7
  162. package/clients/cli/commands/component/index.mjs +55 -152
  163. package/clients/cli/commands/component-ownership.test.mjs +0 -89
  164. package/clients/cli/commands/component.doc.mjs +9 -27
  165. package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
  166. package/clients/cli/commands/discover.doc.mjs +9 -53
  167. package/clients/cli/commands/discover.mjs +118 -393
  168. package/clients/cli/commands/docs.doc.mjs +1 -1
  169. package/clients/cli/commands/docs.mjs +17 -60
  170. package/clients/cli/commands/docs.test.mjs +294 -0
  171. package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
  172. package/clients/cli/commands/doctor-integration.test.mjs +0 -53
  173. package/clients/cli/commands/doctor.doc.mjs +1 -3
  174. package/clients/cli/commands/doctor.mjs +5 -49
  175. package/clients/cli/commands/gap-report.doc.mjs +9 -10
  176. package/clients/cli/commands/init.doc.mjs +6 -9
  177. package/clients/cli/commands/integration-add.doc.mjs +9 -9
  178. package/clients/cli/commands/integration-authoring.test.mjs +10 -61
  179. package/clients/cli/commands/integration-pack.doc.mjs +9 -5
  180. package/clients/cli/commands/integration-real-world.test.mjs +1 -1
  181. package/clients/cli/commands/integration.doc.mjs +4 -4
  182. package/clients/cli/commands/integration.mjs +43 -74
  183. package/clients/cli/commands/layout-check.doc.mjs +65 -0
  184. package/clients/cli/commands/layout-expand.doc.mjs +83 -0
  185. package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
  186. package/clients/cli/commands/layout.doc.mjs +34 -0
  187. package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
  188. package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
  189. package/clients/cli/commands/layout.mjs +275 -0
  190. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  191. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  192. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  193. package/clients/cli/commands/manifest.doc.mjs +1 -1
  194. package/clients/cli/commands/search.doc.mjs +3 -10
  195. package/clients/cli/commands/search.mjs +2 -21
  196. package/clients/cli/commands/search.test.mjs +4 -21
  197. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  198. package/clients/cli/commands/template.doc.mjs +1 -1
  199. package/clients/cli/commands/text-json-parity.test.mjs +16 -5
  200. package/clients/cli/commands/theme-add.doc.mjs +1 -1
  201. package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
  202. package/clients/cli/commands/theme-palette.doc.mjs +2 -1
  203. package/clients/cli/commands/theme-targets.doc.mjs +2 -2
  204. package/clients/cli/commands/theme.doc.mjs +1 -2
  205. package/clients/cli/commands/upgrade.doc.mjs +3 -62
  206. package/clients/cli/index.mjs +10 -28
  207. package/clients/cli/lib/define-command.mjs +4 -28
  208. package/clients/cli/lib/define-command.test.mjs +0 -54
  209. package/clients/cli/lib/exit-codes.test.mjs +9 -18
  210. package/clients/cli/lib/json-shim.mjs +14 -24
  211. package/clients/cli/lib/json-shim.test.mjs +20 -6
  212. package/clients/cli/lib/manifest.mjs +13 -18
  213. package/clients/cli/lib/manifest.test.mjs +2 -5
  214. package/foundation/agent-docs/agent-docs.mjs +1 -1
  215. package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
  216. package/foundation/discovery/authoring-self-docs.mjs +0 -1
  217. package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
  218. package/foundation/discovery/cli-self-docs.mjs +2 -16
  219. package/foundation/discovery/cli-self-docs.test.mjs +0 -20
  220. package/foundation/discovery/docs-discovery.mjs +1 -5
  221. package/foundation/discovery/docs-discovery.test.mjs +0 -21
  222. package/foundation/discovery/docs-section-key.d.mts +1 -1
  223. package/foundation/discovery/docs-section-key.mjs +1 -1
  224. package/foundation/discovery/template-adapter.mjs +1 -1
  225. package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
  226. package/foundation/doc-compiler/tree.d.mts +0 -4
  227. package/foundation/doc-compiler/tree.mjs +1 -6
  228. package/foundation/doc-compiler/tree.test.mjs +598 -0
  229. package/foundation/integrations/cli-requirement.d.mts +6 -26
  230. package/foundation/integrations/cli-requirement.mjs +11 -46
  231. package/foundation/integrations/cli-requirement.test.mjs +2 -7
  232. package/foundation/integrations/contribution-inventory.mjs +1 -1
  233. package/foundation/integrations/integrations.d.mts +1 -14
  234. package/foundation/integrations/integrations.mjs +1 -41
  235. package/foundation/integrations/integrations.test.mjs +0 -31
  236. package/foundation/response/error-codes.doc.mjs +8 -6
  237. package/foundation/response/error-codes.test.mjs +5 -30
  238. package/foundation/response/response-types.doc.d.mts +3 -4
  239. package/foundation/response/response-types.doc.mjs +27 -40
  240. package/foundation/response/response-types.doc.test.mjs +0 -23
  241. package/foundation/response/response.doc.mjs +10 -11
  242. package/foundation/xle/browser.d.mts +3 -3
  243. package/foundation/xle/browser.mjs +3 -3
  244. package/foundation/xle/expand.mjs +2 -2
  245. package/foundation/xle/parse.mjs +1 -1
  246. package/foundation/xle/print.mjs +2 -2
  247. package/foundation/xle/splice.mjs +1 -1
  248. package/package.json +9 -9
  249. package/api/discover/_adapter.test.mjs +0 -215
  250. package/api/discover/_catalog-view.d.mts +0 -115
  251. package/api/discover/_catalog-view.mjs +0 -203
  252. package/api/discover/_catalog-view.test.mjs +0 -128
  253. package/api/discover/detail/item/item.d.mts +0 -26
  254. package/api/discover/detail/item/item.mjs +0 -78
  255. package/api/discover/detail/item/item.test.mjs +0 -73
  256. package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
  257. package/api/theme/add/add.rollback.test.mjs +0 -158
  258. package/api/theme/build/build.rollback.test.mjs +0 -148
  259. package/api/upgrade/run/files-changed.test.mjs +0 -111
  260. package/assets/codemods/file-count.test.mjs +0 -163
  261. package/assets/docs/tree/add-a-component.doc.mjs +0 -75
  262. package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
  263. package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
  264. package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
  265. package/assets/docs/tree/block-template.doc.mjs +0 -130
  266. package/assets/docs/tree/build-the-template.doc.mjs +0 -28
  267. package/assets/docs/tree/building-blocks.doc.mjs +0 -46
  268. package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
  269. package/assets/docs/tree/checks.doc.mjs +0 -119
  270. package/assets/docs/tree/codemods.doc.mjs +0 -147
  271. package/assets/docs/tree/component-family.doc.mjs +0 -113
  272. package/assets/docs/tree/component-imports.doc.mjs +0 -69
  273. package/assets/docs/tree/component-lookups.doc.mjs +0 -149
  274. package/assets/docs/tree/components.doc.mjs +0 -23
  275. package/assets/docs/tree/configuration.doc.mjs +0 -23
  276. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
  277. package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
  278. package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
  279. package/assets/docs/tree/docs.doc.mjs +0 -21
  280. package/assets/docs/tree/document-the-template.doc.mjs +0 -28
  281. package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
  282. package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
  283. package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
  284. package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
  285. package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
  286. package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
  287. package/assets/docs/tree/help.doc.mjs +0 -16
  288. package/assets/docs/tree/links.doc.mjs +0 -98
  289. package/assets/docs/tree/package-and-test.doc.mjs +0 -32
  290. package/assets/docs/tree/page-template.doc.mjs +0 -71
  291. package/assets/docs/tree/publishing.doc.mjs +0 -111
  292. package/assets/docs/tree/quick-start.doc.mjs +0 -272
  293. package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
  294. package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
  295. package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
  296. package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
  297. package/assets/docs/tree/ship.doc.mjs +0 -16
  298. package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
  299. package/assets/docs/tree/single-component.doc.mjs +0 -165
  300. package/assets/docs/tree/start-a-template.doc.mjs +0 -143
  301. package/assets/docs/tree/subcomponent.doc.mjs +0 -115
  302. package/assets/docs/tree/template-assets.doc.mjs +0 -64
  303. package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
  304. package/assets/docs/tree/template-fonts.doc.mjs +0 -102
  305. package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
  306. package/assets/docs/tree/template-icons.doc.mjs +0 -97
  307. package/assets/docs/tree/template-images-media.doc.mjs +0 -127
  308. package/assets/docs/tree/template-styles.doc.mjs +0 -93
  309. package/assets/docs/tree/templates.doc.mjs +0 -34
  310. package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
  311. package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
  312. package/assets/docs/tree/themes.doc.mjs +0 -39
  313. package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
  314. package/assets/docs/tree/upgrading.doc.mjs +0 -103
  315. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
  316. package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
  317. package/assets/docs/tree/versioning.doc.mjs +0 -161
  318. package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
  319. package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
  320. package/authoring/discover/discover.doc.d.mts +0 -13
  321. package/authoring/discover/discover.doc.mjs +0 -138
  322. package/authoring/discover/parse.d.mts +0 -24
  323. package/authoring/discover/parse.mjs +0 -128
  324. package/authoring/discover/parse.test.mjs +0 -124
  325. package/authoring/discover/type.ts +0 -87
  326. package/clients/cli/commands/component-batch.test.mjs +0 -341
  327. package/clients/cli/commands/discover.sources.test.mjs +0 -267
  328. package/clients/cli/commands/integration-verify.doc.mjs +0 -22
  329. package/clients/cli/lib/parse-error-format.test.mjs +0 -81
  330. package/foundation/response/batch.type.d.mts +0 -33
  331. package/foundation/response/batch.type.mjs +0 -34
@@ -354,31 +354,16 @@ describe('checkImplicitIntegrations', () => {
354
354
  });
355
355
 
356
356
  it('names the package, the field, and what it contributes', () => {
357
- // Roots count only when they exist, so this one gives them real folders.
358
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-implicit-'));
359
- try {
360
- const dir = name => {
361
- fs.mkdirSync(path.join(root, name));
362
- return path.join(root, name);
363
- };
364
- const c = checkImplicitIntegrations({
365
- integrations: [
366
- autolinked({
367
- components: dir('components'),
368
- templates: dir('templates'),
369
- themes: dir('themes'),
370
- }),
371
- ],
372
- });
373
- expect(c.message).toContain('@acme/widgets@1.0.0');
374
- expect(c.message).toContain('from dependencies');
375
- expect(c.message).toContain(
376
- 'contributing components, templates, themes',
377
- );
378
- expect(c.message).not.toContain('missing on disk');
379
- } finally {
380
- fs.rmSync(root, {recursive: true, force: true});
381
- }
357
+ const c = checkImplicitIntegrations({
358
+ integrations: [
359
+ autolinked({templates: '/abs/templates', themes: '/abs/themes'}),
360
+ ],
361
+ });
362
+ expect(c.message).toContain('@acme/widgets@1.0.0');
363
+ expect(c.message).toContain('from dependencies');
364
+ expect(c.message).toContain(
365
+ 'contributing components, templates, themes',
366
+ );
382
367
  });
383
368
 
384
369
  it('names the declared key too when an npm alias makes them differ', () => {
@@ -921,100 +906,3 @@ describe('checkDocsProgressiveDisclosure languages', () => {
921
906
  expect(c.message).not.toMatch(/deploying overview:/);
922
907
  });
923
908
  });
924
-
925
- describe('doctor says what it could not check', () => {
926
- const CORE = {
927
- 'node_modules/@astryxdesign/core/package.json': JSON.stringify({
928
- name: '@astryxdesign/core',
929
- version: '0.6.3',
930
- }),
931
- };
932
-
933
- /** Installed dependency whose manifest declares roots that do not exist. */
934
- const dangling = {
935
- 'node_modules/@acme/dangling/package.json': JSON.stringify({
936
- name: '@acme/dangling',
937
- version: '2.0.0',
938
- }),
939
- 'node_modules/@acme/dangling/astryx.integration.mjs':
940
- "export default {providerId: 'acme-dangling', components: './components', templates: './templates', docs: './docs'};\n",
941
- };
942
-
943
- /** Installed dependency whose manifest cannot be parsed at all. */
944
- const broken = {
945
- 'node_modules/@acme/broken/package.json': JSON.stringify({
946
- name: '@acme/broken',
947
- version: '1.0.0',
948
- }),
949
- 'node_modules/@acme/broken/astryx.integration.mjs':
950
- 'export default { this is not valid javascript ((\n',
951
- };
952
-
953
- /** @param {Record<string, string>} extra @param {string[]} deps */
954
- const project = (extra, deps) =>
955
- mkProject({
956
- 'package.json': JSON.stringify({
957
- name: 'consumer',
958
- version: '1.0.0',
959
- dependencies: Object.fromEntries(
960
- ['@astryxdesign/core', ...deps].map(d => [d, '1.0.0']),
961
- ),
962
- }),
963
- ...CORE,
964
- ...extra,
965
- });
966
-
967
- // An unparseable manifest is kept out of the loaded set on purpose, and
968
- // doctor used to report that no installed dependency ships a manifest.
969
- it('names an installed dependency whose manifest cannot be loaded', async () => {
970
- const report = (await doctor({cwd: project(broken, ['@acme/broken'])})).data;
971
- const check = report.checks.find(c => c.id === 'implicit-integrations');
972
-
973
- expect(check.status).toBe('info');
974
- expect(check.message).toContain('@acme/broken');
975
- expect(check.message).toContain('could not be loaded');
976
- expect(check.message).not.toContain('no installed dependency ships');
977
- expect(report.summary.fail).toBe(0);
978
- }, SLOW);
979
-
980
- it('does not claim contributions from roots that are missing on disk', async () => {
981
- const report = (await doctor({cwd: project(dangling, ['@acme/dangling'])}))
982
- .data;
983
- const implicit = report.checks.find(c => c.id === 'implicit-integrations');
984
- const issues = report.checks.find(c => c.id === 'integration-issues');
985
-
986
- expect(implicit.message).toContain('contributing nothing');
987
- expect(implicit.message).toContain('missing on disk');
988
- expect(implicit.message).not.toContain('contributing components');
989
- expect(issues.status).toBe('warn');
990
- expect(issues.message).toContain('@acme/dangling');
991
- }, SLOW);
992
-
993
- it('still says no dependency ships a manifest when none does', async () => {
994
- const report = (await doctor({cwd: project({}, [])})).data;
995
- const check = report.checks.find(c => c.id === 'implicit-integrations');
996
-
997
- expect(check.message).toBe(
998
- 'None — no installed dependency ships an astryx.integration.* manifest.',
999
- );
1000
- }, SLOW);
1001
-
1002
- it('says how many integrations could not be read, rather than counting silently', () => {
1003
- /** @type {any} */
1004
- const ctx = {
1005
- cwd: '/x',
1006
- nodeVersion: process.versions.node,
1007
- coreDir: null,
1008
- configPath: null,
1009
- configTheme: null,
1010
- integrations: [
1011
- {name: '@acme/ok', __spec: '@acme/ok', providerId: 'ok'},
1012
- {name: '@acme/bad', __spec: '@acme/bad', __loadError: 'boom'},
1013
- ],
1014
- };
1015
- const check = checkProviderIdentity(ctx);
1016
-
1017
- expect(check.message).toContain('1 loaded integration has its own provider ID.');
1018
- expect(check.message).toContain('could not be read');
1019
- });
1020
- });
@@ -23,7 +23,7 @@ export type DoctorCheck = {
23
23
  */
24
24
  message: string;
25
25
  /**
26
- * - Actionable remediation: always present on 'warn' and 'fail'; some 'info' checks carry one too.
26
+ * - Actionable remediation, present when status is not 'pass'.
27
27
  */
28
28
  fix?: string | undefined;
29
29
  };
@@ -19,7 +19,7 @@
19
19
  * @property {string} label - Human-readable check name.
20
20
  * @property {DoctorStatus} status
21
21
  * @property {string} message - One-line result summary.
22
- * @property {string} [fix] - Actionable remediation: always present on 'warn' and 'fail'; some 'info' checks carry one too.
22
+ * @property {string} [fix] - Actionable remediation, present when status is not 'pass'.
23
23
  */
24
24
 
25
25
  /**
@@ -12,16 +12,12 @@ export const doc = {
12
12
  name: 'gapReport',
13
13
  namespace: 'cli/api',
14
14
  displayName: 'gapReport()',
15
- summary:
16
- 'Report a missing or hard-to-use design-system capability to the package that owns it.',
15
+ summary: 'Route a design-system gap through the fan-out handler composition.',
17
16
  description:
18
- 'Sends a gap report to every configured handler: the project config handler first, then each integration handler in config order. ' +
19
- 'Each handler has 30 s to finish, and its output goes to stderr. Public handlers run only with confirmPublic; internal handlers always run. ' +
20
- "With no handler, it files a GitHub issue for the owning package only with confirmPublic (without it nothing is sent), or returns the package's issues URL when that is not on GitHub. " +
21
- 'The report records whether an agent or a person ran it, and the response lists each handler outcome in order.',
17
+ 'Creates a normalized gap report and fans it out to every effective handler: the project config handler first, then each loaded integration handler in config order, deduplicated by handle function identity. Each handler receives a structuredClone of the report and an AbortSignal, then runs in its own worker with a 30 s timeout and stdout redirected to stderr. A timed-out worker is terminated before the next handler starts, so process.exit, process.exitCode, and late continuations cannot affect the CLI process. A public handler requires confirmPublic per handler; internal handlers always run. When no handlers exist, a built-in GitHub/routed-only fallback runs. The aggregate response carries ordered deliveries with per-handler outcomes.',
22
18
  importPath: '@astryxdesign/cli/api',
23
19
  signature:
24
- 'gapReport(component: string | undefined, options?: GapReportOptions): Promise<GapReportCategoriesResponse | GapReportReceiptResponse>',
20
+ 'gapReport(component?: string, options?: GapReportOptions): Promise<GapReportCategoriesResponse | GapReportReceiptResponse>',
25
21
  keywords: [
26
22
  'gap',
27
23
  'report',
@@ -60,13 +56,13 @@ export const doc = {
60
56
  name: 'options.package',
61
57
  type: 'string',
62
58
  description:
63
- 'Package that owns the gap: @astryxdesign/core, or a loaded integration by package name or config entry. Overrides automatic owner routing; required when more than one package provides the component.',
59
+ 'Explicit owning package when automatic routing is ambiguous.',
64
60
  },
65
61
  {
66
62
  name: 'options.confirmPublic',
67
63
  type: 'boolean',
68
64
  description:
69
- 'Allow public delivery: public handlers run, and with no handler a GitHub issue is filed through the gh CLI.',
65
+ 'Explicitly consent to invoking public handlers or creating a GitHub issue.',
70
66
  default: 'false',
71
67
  },
72
68
  {
@@ -81,7 +77,6 @@ export const doc = {
81
77
  type: 'string',
82
78
  description:
83
79
  'Directory used to load project config and component ownership.',
84
- default: 'process.cwd()',
85
80
  },
86
81
  ],
87
82
  returns: [
@@ -92,21 +87,17 @@ export const doc = {
92
87
  {
93
88
  type: 'gap-report.file',
94
89
  description:
95
- 'Receipt: status (filed, partial, failed, routed_only, consent_required, skipped), package, issuesUrl, ordered deliveries (handlerType, handler, audience, status, url, message), filedCount, and routedOnlyCount.',
90
+ 'An aggregate receipt with per-handler deliveries, filedCount/routedOnlyCount totals, and overall status.',
96
91
  },
97
92
  ],
98
93
  throws: [
99
- {
100
- code: 'ERR_MISSING_ARGUMENT',
101
- when: 'component, category, or reason is missing, blank, or not a string (unless listCategories is true)',
102
- },
103
94
  {
104
95
  code: 'ERR_UNKNOWN_CATEGORY',
105
96
  when: 'category is not one of the fixed gap-report values',
106
97
  },
107
98
  {
108
99
  code: 'ERR_INVALID_ARGUMENT',
109
- when: 'component is over 120 characters, category is over 80, reason is over 2000, or detail is not a string or is over 8000 characters',
100
+ when: 'a field value is invalid',
110
101
  },
111
102
  {
112
103
  code: 'ERR_AMBIGUOUS_COMPONENT',
@@ -118,7 +109,7 @@ export const doc = {
118
109
  },
119
110
  {
120
111
  code: 'ERR_NOT_FOUND',
121
- when: 'no report handler is configured and the owning package has no issues URL',
112
+ when: 'no handler and no issues URL available',
122
113
  },
123
114
  ],
124
115
  examples: [
@@ -131,8 +122,8 @@ export const doc = {
131
122
  code: "const receipt = await gapReport('Button', {category: 'missing_variant', reason: 'Need a compact size'});",
132
123
  },
133
124
  {
134
- label: 'Name the owning package',
135
- code: "const receipt = await gapReport('Button', {category: 'docs_gap', reason: 'Missing keyboard example', package: '@astryxdesign/core'});",
125
+ label: 'Confirm public filing',
126
+ code: "await gapReport('Button', {category: 'docs_gap', reason: 'Missing keyboard example', confirmPublic: true});",
136
127
  },
137
128
  ],
138
129
  command: 'gap-report',
@@ -34,7 +34,6 @@ export const doc = {
34
34
  name: 'options.cwd',
35
35
  type: 'string',
36
36
  description: 'Directory to resolve @astryxdesign/core from.',
37
- default: 'process.cwd()',
38
37
  },
39
38
  {
40
39
  name: 'options.list',
@@ -44,8 +43,7 @@ export const doc = {
44
43
  {
45
44
  name: 'options.category',
46
45
  type: 'string',
47
- description:
48
- "List only the hooks in this category, a key of the unfiltered list such as 'Media' or 'Focus'.",
46
+ description: 'List only hooks in this category.',
49
47
  },
50
48
  {
51
49
  name: 'options.params',
@@ -56,8 +54,7 @@ export const doc = {
56
54
  name: 'options.detail',
57
55
  type: "'full' | 'compact' | 'brief'",
58
56
  description: 'Detail level for list views.',
59
- default:
60
- "'full' for a named hook; 'brief' for lists (returned as data.detail: 'names')",
57
+ default: "'full' for a named hook, 'brief' for list views",
61
58
  },
62
59
  {
63
60
  name: 'options.lang',
@@ -107,7 +104,7 @@ export const doc = {
107
104
  },
108
105
  {
109
106
  label: 'Browse a category',
110
- code: "await hook(undefined, {category: 'Media', detail: 'compact'});",
107
+ code: "await hook(undefined, {category: 'State', detail: 'compact'});",
111
108
  },
112
109
  ],
113
110
  command: 'hook',
package/api/index.d.mts CHANGED
@@ -18,7 +18,6 @@ export { integrationAddTheme } from "./integration/add-theme.mjs";
18
18
  export { integrationPackCheck } from "./integration/pack-check.mjs";
19
19
  export { AstryxError } from "./error.mjs";
20
20
  export { logger } from "./logger.mjs";
21
- export * from "../foundation/response/batch.type.mjs";
22
21
  export * from "./component/component.type.mjs";
23
22
  export * from "./docs/docs.type.mjs";
24
23
  export * from "./blog/blog.type.mjs";
@@ -33,12 +32,14 @@ export * from "./gap-report/gap-report.type.mjs";
33
32
  export * from "./upgrade/upgrade.type.mjs";
34
33
  export * from "./init/init.type.mjs";
35
34
  export * from "./doctor/doctor.type.mjs";
35
+ export * from "./layout/layout.type.mjs";
36
36
  export * from "./integration/integration-authoring.type.mjs";
37
37
  export * from "./integration/pack-check.type.mjs";
38
38
  export * from "./integration/validate-integration.type.mjs";
39
39
  export * from "./integration/authoring-checks.type.mjs";
40
40
  export type Logger = import("./logger.mjs").Logger;
41
41
  export { themeBuild, themeAdd, themeTemplate, themeList, themeListAvailable, themeTargets, themePaletteGenerate, generateTonalPalette, listThemes } from "./theme/theme.mjs";
42
+ export { layoutExpand, layoutCheck, layoutGrammar } from "./layout/layout.mjs";
42
43
  export { integrationAdd, integrationAddAgentDoc, integrationAddCodemod, integrationAddComponent, integrationAddDoc, integrationAddTemplate } from "./integration/add-contribution.mjs";
43
44
  export { validateIntegration, summarizeIssues } from "./integration/validate-integration.mjs";
44
45
  export { integrationTemplateConflicts, integrationComponentConflicts, integrationDocConflicts } from "./integration/authoring-checks.mjs";
package/api/index.mjs CHANGED
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * @file Programmatic API for the Astryx CLI.
5
5
  *
6
- * Every function returns the same { type, data } envelope that `astryx --json` outputs.
6
+ * Every function returns the same { type, data } envelope that `xds --json` outputs.
7
7
  * Errors throw AstryxError (with optional .suggestions).
8
8
  *
9
9
  * @example
@@ -44,6 +44,7 @@ export {gapReport} from './gap-report/gap-report.mjs';
44
44
  export {upgrade} from './upgrade/upgrade.mjs';
45
45
  export {init} from './init/init.mjs';
46
46
  export {doctor} from './doctor/doctor.mjs';
47
+ export {layoutExpand, layoutCheck, layoutGrammar} from './layout/layout.mjs';
47
48
  export {
48
49
  integrationAdd,
49
50
  integrationAddAgentDoc,
@@ -72,12 +73,10 @@ export {logger} from './logger.mjs';
72
73
  * @typedef {import('./logger.mjs').Logger} Logger
73
74
  */
74
75
 
75
- // ── Types (re-exported from the shared response foundation and each command's
76
- // colocated `.type.mjs`) ──────────────────────────────────────────────────
76
+ // ── Types (re-exported from each command's colocated `.type.mjs`) ─────
77
77
  // Runtime no-ops (the .type.mjs files are `export {}`); tsc carries these
78
78
  // through to the generated api/index.d.mts so the public type surface exposes
79
- // the shared receipt vocabulary and every command's Options + response types.
80
- export * from '../foundation/response/batch.type.mjs';
79
+ // every command's Options + response types by name.
81
80
  export * from './component/component.type.mjs';
82
81
  export * from './docs/docs.type.mjs';
83
82
  export * from './blog/blog.type.mjs';
@@ -92,6 +91,7 @@ export * from './gap-report/gap-report.type.mjs';
92
91
  export * from './upgrade/upgrade.type.mjs';
93
92
  export * from './init/init.type.mjs';
94
93
  export * from './doctor/doctor.type.mjs';
94
+ export * from './layout/layout.type.mjs';
95
95
  export * from './integration/integration-authoring.type.mjs';
96
96
  export * from './integration/pack-check.type.mjs';
97
97
  export * from './integration/validate-integration.type.mjs';
@@ -19,9 +19,10 @@ export const doc = {
19
19
  'Sets a project up with NO prompts, so it behaves identically for humans, ' +
20
20
  'agents, CI, and piped I/O. By default it installs the AGENTS.md/CLAUDE.md ' +
21
21
  'agent-docs cheat sheet, including guidance from configured integrations, and ' +
22
- "prints getting-started guidance; `features` / `all` print only the chosen features' " +
23
- 'guidance instead (the theme feature also writes the annotated theme template). ' +
24
- 'With `removeAgents` it removes the managed agent-docs block instead of installing.',
22
+ 'prints getting-started guidance; `features` / ' +
23
+ '`all` add theme and page-building guidance and can scaffold a starter ' +
24
+ 'template. With `removeAgents` it removes the managed agent-docs block ' +
25
+ 'instead of installing.',
25
26
  importPath: '@astryxdesign/cli/api',
26
27
  signature:
27
28
  'init(options?: InitOptions, ctx?: {cwd?: string}): Promise<InitRunResponse | InitRemoveResponse>',
@@ -31,7 +32,7 @@ export const doc = {
31
32
  name: 'options.features',
32
33
  type: 'string',
33
34
  description:
34
- 'Comma-separated features to install: agents (agent docs), theme (writes the annotated theme.template.ts), template (the page-building commands; writes a page only with templateName).',
35
+ 'Comma-separated features to install: agents (agent docs), theme (writes the annotated theme.template.ts), template (page-template guidance).',
35
36
  },
36
37
  {
37
38
  name: 'options.all',
@@ -46,8 +47,7 @@ export const doc = {
46
47
  {
47
48
  name: 'options.agent',
48
49
  type: 'string',
49
- description:
50
- 'Agent preset: claude, cursor, codex, hermes, muse, all. Used only when the agents feature runs.',
50
+ description: 'Agent preset: claude, cursor, codex, hermes, muse, all.',
51
51
  },
52
52
  {
53
53
  name: 'options.agentDocsPath',
@@ -58,14 +58,9 @@ export const doc = {
58
58
  name: 'options.templateName',
59
59
  type: 'string',
60
60
  description:
61
- 'Scaffold this page template to src/pages/<name>/page.tsx. Used only when the template feature runs (features includes template, or all); otherwise ignored. Programmatic only; the CLI never sets it.',
62
- },
63
- {
64
- name: 'ctx.cwd',
65
- type: 'string',
66
- description: 'Directory to set up.',
67
- default: 'process.cwd()',
61
+ 'Scaffold a named page template (programmatic only; the CLI never sets it).',
68
62
  },
63
+ {name: 'ctx.cwd', type: 'string', description: 'Directory to set up.'},
69
64
  ],
70
65
  returns: [
71
66
  {
@@ -76,13 +71,13 @@ export const doc = {
76
71
  {
77
72
  type: 'init.remove',
78
73
  description:
79
- 'Returned when `removeAgents` is set. `data.removed` is always true, even when no managed block was found.',
74
+ 'Confirmation that the managed agent-docs block was removed (`data.removed: true`), returned when `removeAgents` is set.',
80
75
  },
81
76
  ],
82
77
  throws: [
83
78
  {
84
79
  code: 'ERR_UNKNOWN_AGENT',
85
- when: 'the agents feature runs (default mode, features includes agents, or all) and `agent` is not one of claude, cursor, codex, hermes, muse, all',
80
+ when: '`agent` is not one of claude, cursor, codex, hermes, muse, all',
86
81
  },
87
82
  {
88
83
  code: 'ERR_UNKNOWN_FEATURE',
@@ -90,7 +85,7 @@ export const doc = {
90
85
  },
91
86
  {
92
87
  code: 'ERR_UNKNOWN_TEMPLATE',
93
- when: 'the template feature runs and `templateName` matches no bundled template',
88
+ when: '`templateName` matches no bundled template',
94
89
  },
95
90
  {
96
91
  code: 'ERR_FILE_EXISTS',
@@ -98,7 +93,7 @@ export const doc = {
98
93
  },
99
94
  {
100
95
  code: 'ERR_PATH_TRAVERSAL',
101
- when: 'the template output path resolves outside cwd (for example through a symlinked src directory), or, with removeAgents, a managed agent-docs file resolves outside cwd through a symlink',
96
+ when: 'the template output path resolves outside cwd, for example through a symlinked src directory',
102
97
  },
103
98
  ],
104
99
  examples: [
@@ -8,7 +8,7 @@ export function findPackageDir(startDir: string): string;
8
8
  /**
9
9
  * @typedef {object} WritePlan
10
10
  * @property {string} path
11
- * @property {string | Buffer} contents a Buffer is written byte for byte
11
+ * @property {string} contents
12
12
  * @property {boolean} createOnly
13
13
  * @property {Buffer} [expectedOriginal] bytes captured before validation;
14
14
  * a different current file is a concurrent edit and must never be overwritten
@@ -56,10 +56,7 @@ export function packageJsonUpdate(packageFile: string, rootPath: string, manifes
56
56
  export function applyWrites(plans: WritePlan[]): () => void;
57
57
  export type WritePlan = {
58
58
  path: string;
59
- /**
60
- * a Buffer is written byte for byte
61
- */
62
- contents: string | Buffer;
59
+ contents: string;
63
60
  createOnly: boolean;
64
61
  /**
65
62
  * bytes captured before validation;
@@ -5,8 +5,7 @@
5
5
  *
6
6
  * Hosts the atomic staged-write transaction, package.json files-array
7
7
  * maintenance, package-dir resolution, and project-path normalization that
8
- * every `integration add <kind>` command needs. `theme add` and `theme build`
9
- * write through the same transaction. Stateless and side-effect-free
8
+ * every `integration add <kind>` command needs. Stateless and side-effect-free
10
9
  * outside of {@link applyWrites}.
11
10
  */
12
11
 
@@ -41,7 +40,7 @@ export function findPackageDir(startDir) {
41
40
  /**
42
41
  * @typedef {object} WritePlan
43
42
  * @property {string} path
44
- * @property {string | Buffer} contents a Buffer is written byte for byte
43
+ * @property {string} contents
45
44
  * @property {boolean} createOnly
46
45
  * @property {Buffer} [expectedOriginal] bytes captured before validation;
47
46
  * a different current file is a concurrent edit and must never be overwritten
@@ -193,29 +192,21 @@ export function packageJsonUpdate(
193
192
 
194
193
  // ── Atomic staged-write transaction ─────────────────────────────────
195
194
 
196
- /**
197
- * @param {string} file
198
- * @returns {boolean} false when the file is still there
199
- */
195
+ /** @param {string} file */
200
196
  function removeTemporary(file) {
201
197
  try {
202
198
  fs.rmSync(file, {force: true});
203
- return true;
204
199
  } catch {
205
200
  // Best effort. The transaction error remains the actionable failure.
206
- return false;
207
201
  }
208
202
  }
209
203
 
210
204
  /**
211
205
  * Restore writes that already published. Best-effort so callers preserve
212
- * the original actionable error; returns every path it could not put back.
206
+ * the original actionable error.
213
207
  * @param {Array<WritePlan & {temporary: string, original: Buffer|null, mode: number}>} published
214
- * @returns {string[]}
215
208
  */
216
209
  function rollbackWrites(published) {
217
- /** @type {string[]} */
218
- const unrestored = [];
219
210
  for (const plan of [...published].reverse()) {
220
211
  let restore = null;
221
212
  try {
@@ -234,18 +225,12 @@ function rollbackWrites(published) {
234
225
  fs.renameSync(restore, plan.path);
235
226
  restore = null;
236
227
  }
237
- } catch (error) {
238
- // A created file that is already gone needs nothing. Any other failure
239
- // leaves this call's bytes, or no bytes, where the original was.
240
- const gone =
241
- error instanceof Error &&
242
- /** @type {NodeJS.ErrnoException} */ (error).code === 'ENOENT';
243
- if (!(gone && plan.original == null)) unrestored.push(plan.path);
228
+ } catch {
229
+ // Best effort. A concurrent edit belongs to its writer, not this rollback.
244
230
  } finally {
245
231
  if (restore != null) removeTemporary(restore);
246
232
  }
247
233
  }
248
- return unrestored;
249
234
  }
250
235
 
251
236
  /** @param {string} file */
@@ -340,22 +325,10 @@ export function applyWrites(plans) {
340
325
  }
341
326
  published.push(plan);
342
327
  }
343
- return () => {
344
- rollbackWrites(published);
345
- };
328
+ return () => rollbackWrites(published);
346
329
  } catch (error) {
347
- const leftovers = staged
348
- .filter(plan => !removeTemporary(plan.temporary))
349
- .map(plan => plan.temporary);
350
- const unrestored = rollbackWrites(published);
351
- if (error instanceof Error) {
352
- if (unrestored.length > 0) {
353
- error.message += ` Could not restore: ${unrestored.join(', ')}.`;
354
- }
355
- if (leftovers.length > 0) {
356
- error.message += ` Could not remove temporary files: ${leftovers.join(', ')}.`;
357
- }
358
- }
330
+ for (const plan of staged) removeTemporary(plan.temporary);
331
+ rollbackWrites(published);
359
332
  throw error;
360
333
  }
361
334
  }
@@ -24,10 +24,6 @@ import {
24
24
  import {loadManifestObject} from '../../foundation/integrations/integrations.mjs';
25
25
  import {themeDescriptorSource} from '../../foundation/integrations/theme-descriptor.mjs';
26
26
  import {assertContributionVisible} from '../../foundation/integrations/contribution-inventory.mjs';
27
- import {
28
- themesCliProblem,
29
- withDocsTreeCli,
30
- } from '../../foundation/integrations/cli-requirement.mjs';
31
27
  import {
32
28
  applyWrites,
33
29
  findPackageDir,
@@ -237,28 +233,11 @@ export async function integrationAddTheme(name, options = {}) {
237
233
  createOnly: true,
238
234
  },
239
235
  ];
240
- let packageUpdate = packageJsonUpdate(
236
+ const packageUpdate = packageJsonUpdate(
241
237
  packageFile,
242
238
  rootPath,
243
239
  path.basename(manifestFile),
244
240
  );
245
- // A CLI older than the one that reads typed theme descriptors rejects the
246
- // themes root and withholds the package's themes and docs. Declare the CLI
247
- // that reads them as a peer, so an older one is flagged at install instead.
248
- {
249
- const expectedOriginal =
250
- packageUpdate?.expectedOriginal ?? fs.readFileSync(packageFile);
251
- const text = packageUpdate?.contents ?? expectedOriginal.toString('utf-8');
252
- const current = JSON.parse(text);
253
- if (themesCliProblem(current) != null) {
254
- packageUpdate = {
255
- contents:
256
- JSON.stringify(withDocsTreeCli(current), null, 2) +
257
- (text.endsWith('\n') ? '\n' : ''),
258
- expectedOriginal,
259
- };
260
- }
261
- }
262
241
  if (packageUpdate != null) {
263
242
  plans.push({
264
243
  path: packageFile,
@@ -77,40 +77,6 @@ describe('integrationAddTheme', () => {
77
77
  expect((await validateLocalIntegration(tmpDir)).issues).toEqual([]);
78
78
  });
79
79
 
80
- it('declares the optional CLI peer that reads typed theme descriptors', async () => {
81
- setup({includeFiles: false});
82
- const result = await integrationAddTheme('ocean', {cwd: tmpDir});
83
- expect(result.data.files).toContain('package.json');
84
- const pkg = JSON.parse(
85
- fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8'),
86
- );
87
- expect(pkg.peerDependencies).toEqual({'@astryxdesign/cli': '>=0.7.0'});
88
- expect(pkg.peerDependenciesMeta).toEqual({
89
- '@astryxdesign/cli': {optional: true},
90
- });
91
- });
92
-
93
- it('keeps a CLI peer that already reads typed theme descriptors', async () => {
94
- const pkg = {
95
- name: '@acme/themes',
96
- version: '1.0.0',
97
- peerDependencies: {'@astryxdesign/cli': '^0.7.2'},
98
- };
99
- fs.writeFileSync(
100
- path.join(tmpDir, 'package.json'),
101
- `${JSON.stringify(pkg, null, 2)}\n`,
102
- );
103
- fs.writeFileSync(
104
- path.join(tmpDir, 'astryx.integration.mjs'),
105
- 'export default {};\n',
106
- );
107
- const result = await integrationAddTheme('ocean', {cwd: tmpDir});
108
- expect(result.data.files).not.toContain('package.json');
109
- expect(
110
- JSON.parse(fs.readFileSync(path.join(tmpDir, 'package.json'), 'utf-8')),
111
- ).toEqual(pkg);
112
- });
113
-
114
80
  it('dry-runs the identical receipt without writing anything', async () => {
115
81
  setup();
116
82
  const beforeManifest = fs.readFileSync(
@@ -368,11 +368,11 @@ export async function integrationDocConflicts(pkg, options = {}) {
368
368
  // and placed guides this package adds to the docs tree, and every link in
369
369
  // its docs (spec:AST-046, spec:AST-047).
370
370
  if (errors.length === 0) {
371
- for (const {severity, message} of await packageDocsProblems(
371
+ for (const message of await packageDocsProblems(
372
372
  /** @type {{name: string}} */ (resolved.integration),
373
373
  discovered,
374
374
  )) {
375
- issues.push({code: 'invalid_doc_graph', severity, message});
375
+ issues.push({code: 'invalid_doc_graph', severity: 'warning', message});
376
376
  }
377
377
 
378
378
  // A reference block includes content rather than linking to it, so one