@astryxdesign/cli 0.6.3 → 0.6.4-canary.0e1fbdb

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 (728) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +152 -107
  3. package/api/blog/blog.doc.mjs +1 -0
  4. package/api/build/_adapter.d.mts +50 -0
  5. package/api/build/_adapter.mjs +60 -0
  6. package/api/build/build.doc.mjs +22 -10
  7. package/api/build/build.test.mjs +219 -8
  8. package/api/build/build.type.d.mts +91 -2
  9. package/api/build/build.type.mjs +52 -8
  10. package/api/build/help/help.d.mts +12 -5
  11. package/api/build/help/help.mjs +69 -6
  12. package/api/build/kit/kit.d.mts +4 -1
  13. package/api/build/kit/kit.mjs +208 -53
  14. package/api/build/kit/rank.d.mts +44 -0
  15. package/api/build/kit/rank.mjs +432 -0
  16. package/api/build/kit/rank.test.mjs +196 -0
  17. package/api/component/_adapter.d.mts +31 -12
  18. package/api/component/_adapter.mjs +79 -15
  19. package/api/component/component.d.mts +6 -3
  20. package/api/component/component.doc.mjs +49 -19
  21. package/api/component/component.mjs +339 -22
  22. package/api/component/component.test.mjs +38 -0
  23. package/api/component/component.type.d.mts +47 -11
  24. package/api/component/component.type.mjs +76 -24
  25. package/api/component/detail/blocks/blocks.d.mts +2 -1
  26. package/api/component/detail/blocks/blocks.mjs +4 -3
  27. package/api/component/list/list.d.mts +0 -5
  28. package/api/component/list/list.mjs +40 -11
  29. package/api/discover/_adapter.d.mts +114 -6
  30. package/api/discover/_adapter.mjs +372 -17
  31. package/api/discover/_adapter.test.mjs +215 -0
  32. package/api/discover/_catalog-view.d.mts +115 -0
  33. package/api/discover/_catalog-view.mjs +203 -0
  34. package/api/discover/_catalog-view.test.mjs +128 -0
  35. package/api/discover/detail/detail.d.mts +18 -6
  36. package/api/discover/detail/detail.mjs +67 -13
  37. package/api/discover/detail/detail.test.mjs +85 -0
  38. package/api/discover/detail/item/item.d.mts +26 -0
  39. package/api/discover/detail/item/item.mjs +78 -0
  40. package/api/discover/detail/item/item.test.mjs +73 -0
  41. package/api/discover/discover.d.mts +3 -9
  42. package/api/discover/discover.doc.mjs +62 -18
  43. package/api/discover/discover.mjs +220 -36
  44. package/api/discover/discover.test.mjs +11 -2
  45. package/api/discover/discover.type.d.mts +150 -11
  46. package/api/discover/discover.type.mjs +107 -17
  47. package/api/discover/list/list.d.mts +20 -6
  48. package/api/discover/list/list.mjs +45 -12
  49. package/api/discover/list/list.test.mjs +46 -0
  50. package/api/discover/search/search.d.mts +18 -16
  51. package/api/discover/search/search.mjs +102 -56
  52. package/api/discover/search/search.test.mjs +144 -10
  53. package/api/docs/_adapter.d.mts +277 -41
  54. package/api/docs/_adapter.mjs +993 -108
  55. package/api/docs/compiled-topics.test.mjs +78 -0
  56. package/api/docs/detail/detail.mjs +22 -63
  57. package/api/docs/detail/section/section.d.mts +1 -1
  58. package/api/docs/detail/section/section.mjs +54 -19
  59. package/api/docs/detail/section/section.test.mjs +50 -0
  60. package/api/docs/docOverlays.test.mjs +27 -1
  61. package/api/docs/docs.d.mts +10 -3
  62. package/api/docs/docs.doc.mjs +55 -16
  63. package/api/docs/docs.mjs +53 -10
  64. package/api/docs/docs.type.d.mts +221 -5
  65. package/api/docs/docs.type.mjs +153 -11
  66. package/api/docs/index/index.d.mts +18 -0
  67. package/api/docs/index/index.mjs +40 -0
  68. package/api/docs/index/index.test.mjs +62 -0
  69. package/api/docs/list/list.mjs +28 -12
  70. package/api/docs/node/node.d.mts +43 -0
  71. package/api/docs/node/node.mjs +192 -0
  72. package/api/docs/reference-blocks.test.mjs +406 -0
  73. package/api/doctor/doctor.d.mts +104 -1
  74. package/api/doctor/doctor.doc.mjs +18 -8
  75. package/api/doctor/doctor.mjs +635 -7
  76. package/api/doctor/doctor.test.mjs +732 -11
  77. package/api/doctor/doctor.type.d.mts +1 -1
  78. package/api/doctor/doctor.type.mjs +1 -1
  79. package/api/gap-report/gap-report.doc.mjs +27 -14
  80. package/api/hook/_adapter.mjs +19 -5
  81. package/api/hook/hook.doc.mjs +7 -3
  82. package/api/hook/hook.type.d.mts +3 -3
  83. package/api/hook/hook.type.mjs +11 -11
  84. package/api/hook/list/list.d.mts +2 -2
  85. package/api/hook/list/list.mjs +69 -17
  86. package/api/index.d.mts +2 -1
  87. package/api/index.mjs +6 -3
  88. package/api/init/init.doc.mjs +22 -12
  89. package/api/init/init.test.mjs +41 -1
  90. package/api/init/remove/remove.mjs +1 -1
  91. package/api/init/run/run.mjs +20 -10
  92. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  93. package/api/integration/add-contribution.d.mts +2 -1
  94. package/api/integration/add-contribution.mjs +130 -15
  95. package/api/integration/add-contribution.test.mjs +258 -7
  96. package/api/integration/add-helpers.d.mts +5 -2
  97. package/api/integration/add-helpers.mjs +36 -9
  98. package/api/integration/add-theme.mjs +56 -65
  99. package/api/integration/add-theme.test.mjs +139 -21
  100. package/api/integration/authoring-checks.mjs +138 -28
  101. package/api/integration/authoring-checks.test.mjs +179 -7
  102. package/api/integration/authoring-checks.type.mjs +6 -1
  103. package/api/integration/integration-authoring.type.d.mts +3 -1
  104. package/api/integration/integration-authoring.type.mjs +2 -0
  105. package/api/integration/integration-block-exports.test.mjs +10 -6
  106. package/api/integration/integrationAdd.doc.mjs +14 -4
  107. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  108. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  109. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  110. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  111. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  112. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  113. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  114. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  115. package/api/integration/integrationPackCheck.doc.mjs +5 -4
  116. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  117. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  118. package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
  119. package/api/integration/pack-check.mjs +160 -11
  120. package/api/integration/pack-check.test.mjs +477 -47
  121. package/api/integration/pack-check.type.d.mts +26 -2
  122. package/api/integration/pack-check.type.mjs +15 -2
  123. package/api/integration/summarizeIssues.doc.mjs +1 -0
  124. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  126. package/api/integration/validate-integration.mjs +52 -102
  127. package/api/integration/validate-integration.test.mjs +179 -26
  128. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  129. package/api/integration/validateIntegration.doc.mjs +3 -2
  130. package/api/json/assertResponse.doc.mjs +2 -1
  131. package/api/json/envelope-types.test.mjs +76 -0
  132. package/api/json/index.ts +2 -0
  133. package/api/json/isError.doc.mjs +2 -1
  134. package/api/json/parseResponse.doc.mjs +3 -2
  135. package/api/layout/_adapter.mjs +20 -5
  136. package/api/layout/expand/expand.mjs +7 -5
  137. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  138. package/api/layout/grammar/grammar.mjs +2 -1
  139. package/api/layout/layoutCheck.doc.mjs +1 -0
  140. package/api/layout/layoutExpand.doc.mjs +2 -1
  141. package/api/layout/layoutGrammar.doc.mjs +1 -0
  142. package/api/search/search-return-type.test.mjs +54 -0
  143. package/api/search/search.d.mts +89 -12
  144. package/api/search/search.doc.mjs +8 -2
  145. package/api/search/search.mjs +697 -97
  146. package/api/search/search.type.d.mts +15 -3
  147. package/api/search/search.type.mjs +5 -2
  148. package/api/swizzle/copy/copy.mjs +28 -11
  149. package/api/swizzle/swizzle.doc.mjs +8 -5
  150. package/api/swizzle/swizzle.type.d.mts +2 -2
  151. package/api/swizzle/swizzle.type.mjs +2 -2
  152. package/api/template/copy/copy.mjs +18 -24
  153. package/api/template/copy/copy.test.mjs +26 -0
  154. package/api/template/list/list.mjs +1 -0
  155. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  156. package/api/template/template-integration.test.mjs +1072 -3
  157. package/api/template/template-suffix.test.mjs +41 -21
  158. package/api/template/template.d.mts +1 -1
  159. package/api/template/template.doc.mjs +32 -9
  160. package/api/template/template.mjs +45 -8
  161. package/api/template/template.type.d.mts +12 -14
  162. package/api/template/template.type.mjs +15 -14
  163. package/api/theme/_adapter.d.mts +2 -3
  164. package/api/theme/_adapter.mjs +4 -5
  165. package/api/theme/add/add.binary.test.mjs +84 -0
  166. package/api/theme/add/add.mjs +31 -22
  167. package/api/theme/add/add.rollback.test.mjs +158 -0
  168. package/api/theme/add/add.staging.test.mjs +83 -0
  169. package/api/theme/add/add.test.mjs +14 -1
  170. package/api/theme/build/build.family.test.mjs +7 -12
  171. package/api/theme/build/build.mjs +140 -59
  172. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  173. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  174. package/api/theme/build/build.rollback.test.mjs +148 -0
  175. package/api/theme/build/build.test.mjs +127 -0
  176. package/api/theme/build/font-warning.mjs +3 -3
  177. package/api/theme/build/font-warning.test.mjs +5 -2
  178. package/api/theme/generateTonalPalette.doc.mjs +2 -2
  179. package/api/theme/integration-themes.test.mjs +39 -28
  180. package/api/theme/list/list.test.mjs +19 -20
  181. package/api/theme/listThemes.doc.mjs +6 -5
  182. package/api/theme/palette/generate/generate.mjs +8 -3
  183. package/api/theme/palette/generate/generate.test.mjs +96 -0
  184. package/api/theme/palette/generate/generator.d.mts +10 -13
  185. package/api/theme/palette/generate/generator.mjs +15 -4
  186. package/api/theme/palette/generate/generator.test.mjs +10 -0
  187. package/api/theme/template/template.mjs +11 -2
  188. package/api/theme/template/template.test.mjs +20 -0
  189. package/api/theme/theme.type.d.mts +170 -11
  190. package/api/theme/theme.type.mjs +94 -27
  191. package/api/theme/themeAdd.doc.mjs +12 -12
  192. package/api/theme/themeBuild.doc.mjs +21 -17
  193. package/api/theme/themeList.doc.mjs +6 -3
  194. package/api/theme/themeListAvailable.doc.mjs +6 -3
  195. package/api/theme/themePaletteGenerate.doc.mjs +16 -8
  196. package/api/theme/themeTargets.doc.mjs +4 -2
  197. package/api/theme/themeTemplate.doc.mjs +8 -3
  198. package/api/upgrade/_adapter.d.mts +32 -5
  199. package/api/upgrade/_adapter.mjs +139 -22
  200. package/api/upgrade/list/list.mjs +2 -1
  201. package/api/upgrade/list/list.test.mjs +73 -0
  202. package/api/upgrade/project-context.test.mjs +272 -0
  203. package/api/upgrade/provider-agreement.test.mjs +152 -0
  204. package/api/upgrade/run/files-changed.test.mjs +111 -0
  205. package/api/upgrade/run/run.mjs +358 -59
  206. package/api/upgrade/status/status.mjs +2 -2
  207. package/api/upgrade/upgrade.doc.mjs +32 -23
  208. package/api/upgrade/upgrade.type.d.mts +43 -5
  209. package/api/upgrade/upgrade.type.mjs +29 -13
  210. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  211. package/assets/codemods/__tests__/runner.test.mjs +332 -8
  212. package/assets/codemods/file-count.test.mjs +163 -0
  213. package/assets/codemods/integration-discovery.mjs +48 -4
  214. package/assets/codemods/integration-discovery.test.mjs +73 -0
  215. package/assets/codemods/integration-runner.mjs +59 -7
  216. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  217. package/assets/codemods/registry.mjs +1 -0
  218. package/assets/codemods/run-codemod.mjs +177 -34
  219. package/assets/codemods/runner.mjs +353 -104
  220. package/assets/codemods/term-log.mjs +32 -8
  221. package/assets/codemods/term-log.test.mjs +19 -1
  222. package/assets/codemods/transform-prop.mjs +109 -0
  223. package/assets/codemods/transform-prop.test.mjs +95 -0
  224. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  225. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  226. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  227. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  228. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  229. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  230. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  231. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  232. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  233. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  234. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  235. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  236. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  237. package/assets/docs/README.md +12 -1
  238. package/assets/docs/authoring.doc.mjs +14 -0
  239. package/assets/docs/browser-support.doc.mjs +11 -11
  240. package/assets/docs/color.doc.mjs +8 -2
  241. package/assets/docs/elevation.doc.mjs +6 -4
  242. package/assets/docs/getting-started.doc.mjs +6 -17
  243. package/assets/docs/icons.doc.mjs +2 -21
  244. package/assets/docs/illustrations.doc.mjs +7 -15
  245. package/assets/docs/internationalization.doc.mjs +7 -5
  246. package/assets/docs/layout.doc.dense.mjs +132 -84
  247. package/assets/docs/layout.doc.mjs +134 -78
  248. package/assets/docs/migration.doc.mjs +19 -21
  249. package/assets/docs/motion.doc.mjs +16 -3
  250. package/assets/docs/principles.doc.dense.mjs +5 -5
  251. package/assets/docs/principles.doc.mjs +14 -6
  252. package/assets/docs/principles.doc.zh.mjs +6 -6
  253. package/assets/docs/shape.doc.mjs +8 -3
  254. package/assets/docs/spacing.doc.mjs +7 -2
  255. package/assets/docs/styling-libraries.doc.mjs +10 -6
  256. package/assets/docs/styling.doc.mjs +22 -26
  257. package/assets/docs/theme.doc.dense.mjs +58 -18
  258. package/assets/docs/theme.doc.mjs +60 -50
  259. package/assets/docs/theme.doc.zh.mjs +9 -8
  260. package/assets/docs/tokens.doc.dense.mjs +2 -2
  261. package/assets/docs/tokens.doc.mjs +390 -9
  262. package/assets/docs/tokens.doc.zh.mjs +2 -2
  263. package/assets/docs/tree/add-a-component.doc.mjs +75 -0
  264. package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
  265. package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
  266. package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
  267. package/assets/docs/tree/api.doc.mjs +30 -0
  268. package/assets/docs/tree/block-template.doc.mjs +130 -0
  269. package/assets/docs/tree/build-the-template.doc.mjs +28 -0
  270. package/assets/docs/tree/building-blocks.doc.mjs +46 -0
  271. package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
  272. package/assets/docs/tree/checks.doc.mjs +119 -0
  273. package/assets/docs/tree/cli.doc.mjs +23 -0
  274. package/assets/docs/tree/codemods.doc.mjs +147 -0
  275. package/assets/docs/tree/commands.doc.mjs +25 -0
  276. package/assets/docs/tree/component-family.doc.mjs +113 -0
  277. package/assets/docs/tree/component-imports.doc.mjs +69 -0
  278. package/assets/docs/tree/component-lookups.doc.mjs +149 -0
  279. package/assets/docs/tree/components.doc.mjs +23 -0
  280. package/assets/docs/tree/configuration.doc.mjs +23 -0
  281. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
  282. package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
  283. package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
  284. package/assets/docs/tree/docs.doc.mjs +21 -0
  285. package/assets/docs/tree/document-the-template.doc.mjs +28 -0
  286. package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
  287. package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
  288. package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
  291. package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
  292. package/assets/docs/tree/help.doc.mjs +16 -0
  293. package/assets/docs/tree/integrations.doc.mjs +40 -0
  294. package/assets/docs/tree/links.doc.mjs +98 -0
  295. package/assets/docs/tree/package-and-test.doc.mjs +32 -0
  296. package/assets/docs/tree/page-template.doc.mjs +71 -0
  297. package/assets/docs/tree/publishing.doc.mjs +111 -0
  298. package/assets/docs/tree/quick-start.doc.mjs +272 -0
  299. package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
  300. package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
  301. package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
  302. package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
  303. package/assets/docs/tree/ship.doc.mjs +16 -0
  304. package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
  305. package/assets/docs/tree/single-component.doc.mjs +165 -0
  306. package/assets/docs/tree/start-a-template.doc.mjs +143 -0
  307. package/assets/docs/tree/subcomponent.doc.mjs +115 -0
  308. package/assets/docs/tree/template-assets.doc.mjs +64 -0
  309. package/assets/docs/tree/template-doc-overview.doc.mjs +109 -0
  310. package/assets/docs/tree/template-fonts.doc.mjs +102 -0
  311. package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
  312. package/assets/docs/tree/template-icons.doc.mjs +97 -0
  313. package/assets/docs/tree/template-images-media.doc.mjs +127 -0
  314. package/assets/docs/tree/template-styles.doc.mjs +93 -0
  315. package/assets/docs/tree/templates.doc.mjs +34 -0
  316. package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
  317. package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
  318. package/assets/docs/tree/themes.doc.mjs +39 -0
  319. package/assets/docs/tree/troubleshooting.doc.mjs +149 -0
  320. package/assets/docs/tree/upgrading.doc.mjs +103 -0
  321. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
  322. package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
  323. package/assets/docs/tree/versioning.doc.mjs +161 -0
  324. package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
  325. package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
  326. package/assets/docs/typography.doc.mjs +24 -4
  327. package/assets/docs/working-with-ai.doc.mjs +34 -26
  328. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  329. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  330. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  331. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  332. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  333. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  334. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  335. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  336. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  337. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  338. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  339. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  340. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  341. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  342. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  343. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  344. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  345. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  346. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  347. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  348. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  349. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  350. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  351. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  352. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  353. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  354. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  355. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  356. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  357. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  358. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  359. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  360. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  361. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  362. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  363. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  364. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  365. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  366. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  367. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  368. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  369. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  370. package/authoring/_shared/contract.ts +22 -0
  371. package/authoring/codemod/codemod.doc.mjs +7 -2
  372. package/authoring/codemod/parse.d.mts +8 -8
  373. package/authoring/codemod/parse.mjs +8 -6
  374. package/authoring/codemod/type.ts +12 -0
  375. package/authoring/config/config.doc.mjs +11 -3
  376. package/authoring/config/debug-composition.test.mjs +92 -0
  377. package/authoring/config/parse.d.mts +15 -13
  378. package/authoring/config/parse.mjs +27 -8
  379. package/authoring/config/parse.test.mjs +8 -0
  380. package/authoring/config/type.ts +29 -6
  381. package/authoring/debug/debug.doc.d.mts +11 -0
  382. package/authoring/debug/debug.doc.mjs +182 -0
  383. package/authoring/debug/parse.d.mts +8 -8
  384. package/authoring/debug/parse.mjs +3 -3
  385. package/authoring/discover/discover.doc.d.mts +13 -0
  386. package/authoring/discover/discover.doc.mjs +138 -0
  387. package/authoring/discover/parse.d.mts +24 -0
  388. package/authoring/discover/parse.mjs +128 -0
  389. package/authoring/discover/parse.test.mjs +124 -0
  390. package/authoring/discover/type.ts +87 -0
  391. package/authoring/doctypes/_schema.d.mts +792 -24
  392. package/authoring/doctypes/_schema.mjs +549 -39
  393. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  394. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  395. package/authoring/doctypes/base/type.ts +43 -0
  396. package/authoring/doctypes/command/command.doc.mjs +4 -3
  397. package/authoring/doctypes/command/parse.d.mts +2 -2
  398. package/authoring/doctypes/command/parse.mjs +1 -1
  399. package/authoring/doctypes/command/type.ts +5 -4
  400. package/authoring/doctypes/component/component.doc.mjs +12 -3
  401. package/authoring/doctypes/component/parse.d.mts +2 -2
  402. package/authoring/doctypes/component/parse.mjs +1 -1
  403. package/authoring/doctypes/component/type.ts +14 -5
  404. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  405. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  406. package/authoring/doctypes/enum/parse.d.mts +2 -2
  407. package/authoring/doctypes/enum/parse.mjs +1 -1
  408. package/authoring/doctypes/enum/type.ts +4 -2
  409. package/authoring/doctypes/function/function.doc.mjs +7 -2
  410. package/authoring/doctypes/function/parse.d.mts +2 -2
  411. package/authoring/doctypes/function/parse.mjs +1 -1
  412. package/authoring/doctypes/function/type.ts +9 -4
  413. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  414. package/authoring/doctypes/hook/parse.d.mts +2 -2
  415. package/authoring/doctypes/hook/parse.mjs +1 -1
  416. package/authoring/doctypes/hook/type.ts +5 -4
  417. package/authoring/doctypes/legacy.d.mts +8 -6
  418. package/authoring/doctypes/legacy.mjs +5 -4
  419. package/authoring/doctypes/load-contract.test.mjs +233 -0
  420. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  421. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  422. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  423. package/authoring/doctypes/namespace/parse.mjs +25 -0
  424. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  425. package/authoring/doctypes/namespace/type.ts +74 -0
  426. package/authoring/doctypes/parse.d.mts +22 -18
  427. package/authoring/doctypes/parse.mjs +22 -11
  428. package/authoring/doctypes/parse.test.mjs +77 -3
  429. package/authoring/doctypes/reference/parse.d.mts +2 -2
  430. package/authoring/doctypes/reference/parse.mjs +8 -5
  431. package/authoring/doctypes/reference/reference.doc.mjs +55 -6
  432. package/authoring/doctypes/reference/type.ts +75 -7
  433. package/authoring/doctypes/schema/parse.d.mts +2 -2
  434. package/authoring/doctypes/schema/parse.mjs +1 -1
  435. package/authoring/doctypes/schema/schema.doc.mjs +2 -2
  436. package/authoring/doctypes/schema/type.ts +4 -4
  437. package/authoring/doctypes/template/parse.d.mts +94 -1
  438. package/authoring/doctypes/template/parse.mjs +40 -2
  439. package/authoring/doctypes/template/parse.test.mjs +26 -2
  440. package/authoring/doctypes/template/template.doc.mjs +13 -3
  441. package/authoring/doctypes/template/type.ts +13 -2
  442. package/authoring/doctypes/theme/parse.d.mts +35 -0
  443. package/authoring/doctypes/theme/parse.mjs +76 -0
  444. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  445. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  446. package/authoring/doctypes/theme/type.ts +42 -0
  447. package/authoring/doctypes/types.ts +12 -10
  448. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  449. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  450. package/authoring/gap-report/parse.d.mts +10 -10
  451. package/authoring/gap-report/parse.mjs +6 -6
  452. package/authoring/gap-report/type.ts +1 -1
  453. package/authoring/identity/identity.doc.d.mts +9 -0
  454. package/authoring/identity/identity.doc.mjs +61 -0
  455. package/authoring/identity/type.ts +132 -0
  456. package/authoring/index.d.mts +3 -0
  457. package/authoring/index.d.ts +62 -17
  458. package/authoring/index.mjs +4 -1
  459. package/authoring/integration/integration.doc.mjs +22 -13
  460. package/authoring/integration/parse.d.mts +2 -2
  461. package/authoring/integration/parse.mjs +1 -1
  462. package/authoring/integration/parse.test.mjs +10 -1
  463. package/authoring/integration/schema.d.mts +6 -4
  464. package/authoring/integration/schema.mjs +9 -3
  465. package/authoring/integration/type.ts +19 -8
  466. package/authoring/shadcn/receipt.d.mts +6 -6
  467. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  468. package/clients/cli/command-load-failure.test.mjs +83 -0
  469. package/clients/cli/commands/blog.doc.mjs +1 -1
  470. package/clients/cli/commands/blog.mjs +23 -8
  471. package/clients/cli/commands/blog.test.mjs +42 -1
  472. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  473. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  474. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  475. package/clients/cli/commands/build-theme.mjs +16 -50
  476. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  477. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  478. package/clients/cli/commands/build.doc.mjs +16 -8
  479. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  480. package/clients/cli/commands/build.mjs +137 -114
  481. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  482. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  483. package/clients/cli/commands/component/index.mjs +153 -61
  484. package/clients/cli/commands/component-batch.test.mjs +341 -0
  485. package/clients/cli/commands/component-ownership.test.mjs +92 -3
  486. package/clients/cli/commands/component-package.test.mjs +46 -0
  487. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  488. package/clients/cli/commands/component.doc.mjs +28 -10
  489. package/clients/cli/commands/component.test.mjs +19 -0
  490. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  491. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  492. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  493. package/clients/cli/commands/discover.doc.mjs +55 -9
  494. package/clients/cli/commands/discover.mjs +393 -118
  495. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  496. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  497. package/clients/cli/commands/docs.doc.mjs +28 -6
  498. package/clients/cli/commands/docs.mjs +295 -38
  499. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  500. package/clients/cli/commands/doctor-integration-docs.doc.mjs +6 -5
  501. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  502. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  503. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  504. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  505. package/clients/cli/commands/doctor-integration.test.mjs +143 -8
  506. package/clients/cli/commands/doctor.doc.mjs +4 -2
  507. package/clients/cli/commands/doctor.mjs +108 -37
  508. package/clients/cli/commands/doctor.test.mjs +42 -0
  509. package/clients/cli/commands/gap-report.doc.mjs +27 -15
  510. package/clients/cli/commands/gap-report.test.mjs +72 -0
  511. package/clients/cli/commands/hook/index.mjs +7 -17
  512. package/clients/cli/commands/hook.doc.mjs +1 -1
  513. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  514. package/clients/cli/commands/init.doc.mjs +24 -10
  515. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  516. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  517. package/clients/cli/commands/integration-add.doc.mjs +39 -13
  518. package/clients/cli/commands/integration-authoring.test.mjs +74 -19
  519. package/clients/cli/commands/integration-pack.doc.mjs +6 -10
  520. package/clients/cli/commands/integration-real-world.test.mjs +4 -10
  521. package/clients/cli/commands/integration-verify.doc.mjs +22 -0
  522. package/clients/cli/commands/integration.doc.mjs +5 -5
  523. package/clients/cli/commands/integration.mjs +75 -43
  524. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  525. package/clients/cli/commands/json-contract.test.mjs +33 -0
  526. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  527. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  528. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  529. package/clients/cli/commands/layout.doc.mjs +3 -3
  530. package/clients/cli/commands/layout.mjs +21 -9
  531. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  532. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  533. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  534. package/clients/cli/commands/manifest.doc.mjs +2 -2
  535. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  536. package/clients/cli/commands/search.doc.mjs +16 -6
  537. package/clients/cli/commands/search.mjs +49 -11
  538. package/clients/cli/commands/search.test.mjs +92 -0
  539. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  540. package/clients/cli/commands/swizzle.doc.mjs +4 -3
  541. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  542. package/clients/cli/commands/template.doc.mjs +53 -14
  543. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  544. package/clients/cli/commands/template.mjs +4 -91
  545. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  546. package/clients/cli/commands/text-json-parity.test.mjs +725 -0
  547. package/clients/cli/commands/theme-add.doc.mjs +5 -4
  548. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  549. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  550. package/clients/cli/commands/theme-palette-generate.doc.mjs +12 -7
  551. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  552. package/clients/cli/commands/theme-palette.doc.mjs +2 -3
  553. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  554. package/clients/cli/commands/theme-targets.doc.mjs +3 -3
  555. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  556. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  557. package/clients/cli/commands/theme.doc.mjs +3 -2
  558. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  559. package/clients/cli/commands/upgrade.doc.mjs +83 -12
  560. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  561. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  562. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  563. package/clients/cli/commands/upgrade.mjs +29 -7
  564. package/clients/cli/formatters/index.mjs +164 -1
  565. package/clients/cli/formatters/index.test.mjs +97 -0
  566. package/clients/cli/index.mjs +47 -34
  567. package/clients/cli/latest-version-env.test.mjs +50 -0
  568. package/clients/cli/lib/cli-error.test.mjs +7 -0
  569. package/clients/cli/lib/component-format.mjs +9 -9
  570. package/clients/cli/lib/component-format.test.mjs +1 -1
  571. package/clients/cli/lib/define-command.mjs +56 -6
  572. package/clients/cli/lib/define-command.test.mjs +54 -0
  573. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  574. package/clients/cli/lib/exit-codes.test.mjs +113 -0
  575. package/clients/cli/lib/hook-format.mjs +19 -10
  576. package/clients/cli/lib/json-shim.mjs +62 -16
  577. package/clients/cli/lib/json-shim.test.mjs +83 -0
  578. package/clients/cli/lib/manifest.d.ts +2 -0
  579. package/clients/cli/lib/manifest.mjs +53 -6
  580. package/clients/cli/lib/manifest.test.mjs +22 -2
  581. package/clients/cli/lib/parse-error-format.test.mjs +81 -0
  582. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  583. package/foundation/agent-docs/agent-docs.mjs +83 -13
  584. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  585. package/foundation/config/integration-debug.test.mjs +28 -3
  586. package/foundation/config/project-themes.test.mjs +11 -19
  587. package/foundation/config/project.d.mts +20 -11
  588. package/foundation/config/project.mjs +263 -91
  589. package/foundation/config/project.test.mjs +270 -21
  590. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  591. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  592. package/foundation/discovery/authoring-self-docs.test.mjs +174 -0
  593. package/foundation/discovery/authoring-surface.d.mts +74 -0
  594. package/foundation/discovery/authoring-surface.mjs +525 -0
  595. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  596. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  597. package/foundation/discovery/cli-self-docs.mjs +504 -0
  598. package/foundation/discovery/cli-self-docs.test.mjs +395 -0
  599. package/foundation/discovery/component-discovery.d.mts +39 -1
  600. package/foundation/discovery/component-discovery.mjs +50 -1
  601. package/foundation/discovery/component-loader.d.mts +35 -38
  602. package/foundation/discovery/component-loader.mjs +53 -222
  603. package/foundation/discovery/docs-discovery.d.mts +119 -11
  604. package/foundation/discovery/docs-discovery.mjs +427 -108
  605. package/foundation/discovery/docs-discovery.test.mjs +386 -20
  606. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  607. package/foundation/discovery/docs-output-budget.mjs +50 -0
  608. package/foundation/discovery/docs-section-key.d.mts +116 -0
  609. package/foundation/discovery/docs-section-key.mjs +322 -0
  610. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  611. package/foundation/discovery/template-adapter.d.mts +113 -11
  612. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  613. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  614. package/foundation/discovery/template-adapter.mjs +774 -83
  615. package/foundation/discovery/template-adapter.test.mjs +57 -0
  616. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  617. package/foundation/discovery/template-conflict-release.mjs +40 -0
  618. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  619. package/foundation/discovery/theme-discovery.d.mts +67 -7
  620. package/foundation/discovery/theme-discovery.mjs +916 -186
  621. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  622. package/foundation/discovery/theming-targets.test.mjs +4 -0
  623. package/foundation/doc-compiler/bundle.d.mts +47 -0
  624. package/foundation/doc-compiler/bundle.mjs +278 -0
  625. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  626. package/foundation/doc-compiler/compile.d.mts +343 -0
  627. package/foundation/doc-compiler/compile.mjs +558 -0
  628. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  629. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  630. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  631. package/foundation/doc-compiler/doc-loads.test.mjs +1643 -0
  632. package/foundation/doc-compiler/import.d.mts +24 -0
  633. package/foundation/doc-compiler/import.mjs +59 -0
  634. package/foundation/doc-compiler/inputs.d.mts +102 -0
  635. package/foundation/doc-compiler/inputs.mjs +291 -0
  636. package/foundation/doc-compiler/inputs.test.mjs +298 -0
  637. package/foundation/doc-compiler/ir.d.mts +22 -0
  638. package/foundation/doc-compiler/ir.mjs +471 -0
  639. package/foundation/doc-compiler/lenses.d.mts +36 -0
  640. package/foundation/doc-compiler/lenses.mjs +173 -0
  641. package/foundation/doc-compiler/links.d.mts +162 -0
  642. package/foundation/doc-compiler/links.mjs +294 -0
  643. package/foundation/doc-compiler/links.test.mjs +192 -0
  644. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  645. package/foundation/doc-compiler/overlays.d.mts +37 -0
  646. package/foundation/doc-compiler/overlays.mjs +206 -0
  647. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  648. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  649. package/foundation/doc-compiler/read.d.mts +127 -0
  650. package/foundation/doc-compiler/read.mjs +325 -0
  651. package/foundation/doc-compiler/read.test.mjs +313 -0
  652. package/foundation/doc-compiler/source.d.mts +33 -0
  653. package/foundation/doc-compiler/source.mjs +128 -0
  654. package/foundation/doc-compiler/tree.d.mts +292 -0
  655. package/foundation/doc-compiler/tree.mjs +881 -0
  656. package/foundation/fs/file-protection.d.mts +33 -0
  657. package/foundation/fs/file-protection.mjs +825 -0
  658. package/foundation/fs/file-protection.test.mjs +250 -0
  659. package/foundation/fs/module-loader.d.mts +1 -0
  660. package/foundation/fs/module-loader.mjs +50 -1
  661. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  662. package/foundation/fs/path-safety.d.mts +3 -2
  663. package/foundation/fs/path-safety.mjs +49 -19
  664. package/foundation/fs/path-safety.test.mjs +50 -0
  665. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  666. package/foundation/identity/provider-identity.d.mts +90 -0
  667. package/foundation/identity/provider-identity.mjs +320 -0
  668. package/foundation/identity/provider-identity.test.mjs +254 -0
  669. package/foundation/identity/providers.d.mts +7 -0
  670. package/foundation/identity/providers.mjs +16 -0
  671. package/foundation/integrations/autolink.d.mts +58 -1
  672. package/foundation/integrations/autolink.mjs +143 -45
  673. package/foundation/integrations/autolink.test.mjs +1 -1
  674. package/foundation/integrations/cli-requirement.d.mts +65 -0
  675. package/foundation/integrations/cli-requirement.mjs +189 -0
  676. package/foundation/integrations/cli-requirement.test.mjs +89 -0
  677. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  678. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  679. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  680. package/foundation/integrations/contribution-inventory.mjs +28 -25
  681. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  682. package/foundation/integrations/integration-warnings.d.mts +9 -2
  683. package/foundation/integrations/integration-warnings.mjs +52 -21
  684. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  685. package/foundation/integrations/integrations.d.mts +63 -3
  686. package/foundation/integrations/integrations.mjs +122 -9
  687. package/foundation/integrations/integrations.test.mjs +415 -1
  688. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  689. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  690. package/foundation/integrations/provider-resolution.d.mts +152 -0
  691. package/foundation/integrations/provider-resolution.mjs +576 -0
  692. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  693. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  694. package/foundation/integrations/theme-descriptor.mjs +44 -0
  695. package/foundation/integrations/validate-contributions.d.mts +2 -0
  696. package/foundation/integrations/validate-contributions.mjs +131 -29
  697. package/foundation/response/base.d.ts +8 -4
  698. package/foundation/response/batch.type.d.mts +33 -0
  699. package/foundation/response/batch.type.mjs +34 -0
  700. package/foundation/response/error-codes.d.mts +3 -1
  701. package/foundation/response/error-codes.d.ts +2 -0
  702. package/foundation/response/error-codes.doc.mjs +19 -12
  703. package/foundation/response/error-codes.mjs +8 -2
  704. package/foundation/response/error-codes.test.mjs +166 -14
  705. package/foundation/response/json-contract.test.mjs +57 -17
  706. package/foundation/response/json.d.mts +4 -2
  707. package/foundation/response/json.mjs +8 -10
  708. package/foundation/response/response-types.doc.d.mts +7 -2
  709. package/foundation/response/response-types.doc.mjs +69 -25
  710. package/foundation/response/response-types.doc.test.mjs +181 -0
  711. package/foundation/response/response.doc.mjs +12 -11
  712. package/foundation/text/string-utils.d.mts +8 -0
  713. package/foundation/text/string-utils.mjs +40 -10
  714. package/foundation/xle/expand.d.mts +2 -0
  715. package/foundation/xle/expand.mjs +4 -3
  716. package/foundation/xle/expand.test.mjs +54 -0
  717. package/foundation/xle/xle.test.mjs +13 -0
  718. package/package.json +10 -11
  719. package/api/docs/docs.test.mjs +0 -83
  720. package/api/docs/integrationDocs.test.mjs +0 -208
  721. package/api/search/search.test.mjs +0 -389
  722. package/assets/docs/cli-integrations.doc.mjs +0 -367
  723. package/assets/templates/themes/manifest.json +0 -95
  724. package/clients/cli/commands/docs.test.mjs +0 -102
  725. package/clients/cli/lib/update-check.mjs +0 -83
  726. package/clients/cli/lib/update-check.test.mjs +0 -137
  727. package/clients/cli/update-hint-commands.test.mjs +0 -54
  728. package/foundation/agent-docs/agent-docs.test.mjs +0 -1141
@@ -11,53 +11,61 @@ export const doc = {
11
11
  type: 'schema',
12
12
  name: 'integration',
13
13
  displayName: 'Astryx Integration',
14
- namespace: 'cli',
14
+ namespace: 'authoring',
15
15
  description:
16
16
  'The astryx.integration.* manifest that sits beside an integration ' +
17
- "package's package.json. Points the CLI at the package's components, " +
18
- 'templates, codemods, doc topics, source themes, and managed agent guidance, ' +
19
- 'and where to file issues. Every field is optional.',
17
+ "package's package.json. It can preserve a stable provider identity across a package rename, " +
18
+ "and points the CLI at the package's components, templates, codemods, doc topics, " +
19
+ 'source themes, managed agent guidance, and issue tracker. Every field is optional.',
20
20
  appliesTo: 'astryx.integration.{ts,mjs,js}',
21
21
  fields: [
22
+ {
23
+ name: 'providerId',
24
+ type: 'string',
25
+ description:
26
+ 'The name that marks this package as the source of everything it contributes. Leave it out to use the package name from package.json. Set it to the old name only during a rename, so the IDs of what the package already contributed stay the same. If two packages use the same name here, the one you are working on wins; otherwise the one the CLI reads first wins, and the CLI warns about the other.',
27
+ example: "'@acme/widgets'",
28
+ },
22
29
  {
23
30
  name: 'components',
24
31
  type: 'string',
25
32
  description:
26
- 'Relative path to the components/docs root (resolved to absolute).',
33
+ 'The folder that holds your components and their docs, relative to package.json.',
27
34
  example: "'./src/components'",
28
35
  },
29
36
  {
30
37
  name: 'templates',
31
38
  type: 'string',
32
39
  description:
33
- 'Relative path to the templates root (resolved to absolute).',
40
+ 'The folder that holds your templates, relative to package.json.',
34
41
  example: "'./src/templates'",
35
42
  },
36
43
  {
37
44
  name: 'codemods',
38
45
  type: 'string',
39
- description: 'Relative path to the codemods root (resolved to absolute).',
46
+ description:
47
+ 'The folder that holds your codemods, relative to package.json.',
40
48
  example: "'./codemods'",
41
49
  },
42
50
  {
43
51
  name: 'docs',
44
52
  type: 'string',
45
53
  description:
46
- 'Relative path to the reference-docs (topics) root (resolved to absolute). Every {topic}.doc.{ts,mjs,js} under it is served by `astryx docs` beside the built-in topics; a topic may also declare `replaces` or `extends` to take the place of a built-in one or merge onto it.',
54
+ 'The folder that holds your doc topics, relative to package.json. Every {topic}.doc.{ts,mjs,js} in it shows up in `astryx docs` next to the built-in topics; a topic can also set `replaces` or `extends` to take over a built-in topic or add to it.',
47
55
  example: "'./docs'",
48
56
  },
49
57
  {
50
58
  name: 'themes',
51
59
  type: 'string',
52
60
  description:
53
- 'Relative path to a source-theme catalog root containing manifest.json plus one directory per theme slug. Installed themes appear in `astryx theme list` and can be copied with `astryx theme add`.',
61
+ 'The folder that holds your themes, relative to package.json, with one folder per theme. Each theme folder has the theme source and a matching .doc.mjs file with the same name. Installed themes show up in `astryx theme list` and can be copied with `astryx theme add`.',
54
62
  example: "'./themes'",
55
63
  },
56
64
  {
57
65
  name: 'agentDocs',
58
66
  type: '{ append?: readonly string[] }',
59
67
  description:
60
- 'Static package guidance appended to the end of the managed agent block. The CLI owns the section heading, package labels, bullets, target files, and writes.',
68
+ 'Lines of guidance your package adds to the end of the agent instructions the CLI manages. The CLI owns the heading, labels, bullets, and which files it writes.',
61
69
  example: "{ append: ['Run acme verify.'] }",
62
70
  },
63
71
  {
@@ -87,9 +95,10 @@ export const doc = {
87
95
  {
88
96
  type: 'prose',
89
97
  text:
90
- "Identity, the integration's name and version, comes from the " +
91
- "package's package.json, not from this manifest. The manifest only " +
92
- 'declares where the CLI finds each kind of artifact.',
98
+ 'The provider name defaults to the package name in package.json. ' +
99
+ 'During a rename, set `providerId` to the old package name so the IDs ' +
100
+ 'of what the package already contributed stay the same. The package ' +
101
+ 'version always comes from package.json.',
93
102
  },
94
103
  {
95
104
  type: 'prose',
@@ -1,7 +1,7 @@
1
1
  // @generated by scripts/sync-api-types.mjs from the JSDoc in authoring/**/*.mjs.
2
2
  // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
3
 
4
- /** @typedef {import('./type').AstryxIntegration} AstryxIntegration */
4
+ /** @typedef {import('./type.js').AstryxIntegration} AstryxIntegration */
5
5
  /**
6
6
  * Validate an unknown value as an Astryx integration manifest, or throw.
7
7
  *
@@ -14,4 +14,4 @@
14
14
  * @returns {AstryxIntegration}
15
15
  */
16
16
  export function parseIntegration(input: unknown, label?: string): AstryxIntegration;
17
- export type AstryxIntegration = import("./type").AstryxIntegration;
17
+ export type AstryxIntegration = import("./type.js").AstryxIntegration;
@@ -14,7 +14,7 @@
14
14
  import {formatZodError} from '../_shared/errors.mjs';
15
15
  import {integrationSchema} from './schema.mjs';
16
16
 
17
- /** @typedef {import('./type').AstryxIntegration} AstryxIntegration */
17
+ /** @typedef {import('./type.js').AstryxIntegration} AstryxIntegration */
18
18
 
19
19
  /**
20
20
  * Validate an unknown value as an Astryx integration manifest, or throw.
@@ -28,6 +28,9 @@ describe('parseIntegration (load boundary)', () => {
28
28
  components: './src',
29
29
  });
30
30
  expect(parseIntegration({docs: './docs'})).toEqual({docs: './docs'});
31
+ expect(parseIntegration({providerId: '@acme/legacy-widgets'})).toEqual({
32
+ providerId: '@acme/legacy-widgets',
33
+ });
31
34
  expect(parseIntegration({themes: './themes'})).toEqual({
32
35
  themes: './themes',
33
36
  });
@@ -66,7 +69,9 @@ describe('parseIntegration (load boundary)', () => {
66
69
  ? 'https://example.com/issues'
67
70
  : key === 'agentDocs'
68
71
  ? {}
69
- : './x',
72
+ : key === 'providerId'
73
+ ? '@acme/widgets'
74
+ : './x',
70
75
  ]),
71
76
  );
72
77
  expect(unknownIntegrationKeys(everyKnownKey)).toEqual([]);
@@ -82,6 +87,10 @@ describe('parseIntegration (load boundary)', () => {
82
87
  expect(reason({issuesUrl: 'nope'})).toContain('issuesUrl');
83
88
  });
84
89
 
90
+ it('rejects a noncanonical providerId', () => {
91
+ expect(reason({providerId: 'Acme Widgets'})).toContain('providerId');
92
+ });
93
+
85
94
  it('accepts an optional append array as manifest data', () => {
86
95
  expect(
87
96
  parseIntegration({
@@ -32,6 +32,7 @@ export const agentDocsSchema: z.ZodObject<{
32
32
  append: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
33
33
  }, z.core.$strip>;
34
34
  export const integrationBaseSchema: z.ZodObject<{
35
+ providerId: z.ZodOptional<z.ZodString>;
35
36
  components: z.ZodOptional<z.ZodString>;
36
37
  templates: z.ZodOptional<z.ZodString>;
37
38
  codemods: z.ZodOptional<z.ZodString>;
@@ -40,6 +41,7 @@ export const integrationBaseSchema: z.ZodObject<{
40
41
  issuesUrl: z.ZodOptional<z.ZodString>;
41
42
  }, z.core.$strip>;
42
43
  export const integrationSchema: z.ZodObject<{
44
+ providerId: z.ZodOptional<z.ZodString>;
43
45
  components: z.ZodOptional<z.ZodString>;
44
46
  templates: z.ZodOptional<z.ZodString>;
45
47
  codemods: z.ZodOptional<z.ZodString>;
@@ -53,8 +55,8 @@ export const integrationSchema: z.ZodObject<{
53
55
  /**
54
56
  * Compile-time drift-lock: sealed schema must infer exactly {@link AstryxIntegration}.
55
57
  *
56
- * @typedef {import('../_shared/contract').Expect<
57
- * import('../_shared/contract').Equal<z.infer<typeof integrationSchema>, AstryxIntegration>
58
+ * @typedef {import('../_shared/contract.js').Expect<
59
+ * import('../_shared/contract.js').Equal<z.infer<typeof integrationSchema>, AstryxIntegration>
58
60
  * >} _IntegrationDriftLock
59
61
  */
60
62
  /**
@@ -67,9 +69,9 @@ export const integrationSchema: z.ZodObject<{
67
69
  * @type {string[]}
68
70
  */
69
71
  export const KNOWN_INTEGRATION_KEYS: string[];
70
- export type AstryxIntegration = import("./type").AstryxIntegration;
72
+ export type AstryxIntegration = import("./type.js").AstryxIntegration;
71
73
  /**
72
74
  * Compile-time drift-lock: sealed schema must infer exactly {@link AstryxIntegration}.
73
75
  */
74
- export type _IntegrationDriftLock = import("../_shared/contract").Expect<import("../_shared/contract").Equal<z.infer<typeof integrationSchema>, AstryxIntegration>>;
76
+ export type _IntegrationDriftLock = import("../_shared/contract.js").Expect<import("../_shared/contract.js").Equal<z.infer<typeof integrationSchema>, AstryxIntegration>>;
75
77
  import { z } from 'zod';
@@ -16,11 +16,13 @@
16
16
  import {z} from 'zod';
17
17
  import {formatZodError} from '../_shared/errors.mjs';
18
18
 
19
- /** @typedef {import('./type').AstryxIntegration} AstryxIntegration */
19
+ /** @typedef {import('./type.js').AstryxIntegration} AstryxIntegration */
20
20
 
21
21
  const MAX_AGENT_DOC_LINES = 8;
22
22
  const MAX_AGENT_DOC_LINE_CODE_POINTS = 240;
23
23
  const MANAGED_MARKER_TEXT = /(?:ASTRYX|XDS):(START|END)/u;
24
+ const PROVIDER_ID_RE =
25
+ /^(?:@[a-z0-9][a-z0-9._~!*'()-]*\/)?[a-z0-9][a-z0-9._~!*'()-]*$/u;
24
26
 
25
27
  /**
26
28
  * @param {string} value
@@ -66,6 +68,10 @@ export const agentDocsSchema = z.object({
66
68
  });
67
69
 
68
70
  export const integrationBaseSchema = z.object({
71
+ providerId: z
72
+ .string()
73
+ .regex(PROVIDER_ID_RE, 'providerId must be a canonical npm package name')
74
+ .optional(),
69
75
  components: z.string().optional(),
70
76
  templates: z.string().optional(),
71
77
  codemods: z.string().optional(),
@@ -115,8 +121,8 @@ export function parseAgentDocsField(input, label) {
115
121
  /**
116
122
  * Compile-time drift-lock: sealed schema must infer exactly {@link AstryxIntegration}.
117
123
  *
118
- * @typedef {import('../_shared/contract').Expect<
119
- * import('../_shared/contract').Equal<z.infer<typeof integrationSchema>, AstryxIntegration>
124
+ * @typedef {import('../_shared/contract.js').Expect<
125
+ * import('../_shared/contract.js').Equal<z.infer<typeof integrationSchema>, AstryxIntegration>
120
126
  * >} _IntegrationDriftLock
121
127
  */
122
128
 
@@ -3,29 +3,40 @@
3
3
  /**
4
4
  * Public type surface for an Astryx integration manifest
5
5
  * (`astryx.integration.{ts,mjs,js}`, sibling to the integration package's
6
- * package.json). Identity (name/version) comes from package.json, not the
7
- * manifest. Authors write a plain object against {@link AstryxIntegration};
8
- * the CLI validates it via `parseIntegration` at the load boundary.
6
+ * package.json). Identity defaults to the package name, but `providerId` can keep
7
+ * a stable logical identity across an explicit package rename. Authors write a
8
+ * plain object against {@link AstryxIntegration}; the CLI validates it via
9
+ * `parseIntegration` at the load boundary.
9
10
  *
10
11
  * The manifest module may also carry `debug` and `gapReport` NAMED exports.
11
12
  * They are not fields here on purpose: a CLI released before a given manifest
12
13
  * field existed could reject it and lose every contribution, while an unknown
13
- * named export is simply not read. See the `cli-integrations` doc topic.
14
+ * named export is simply not read. See `astryx docs cli/integrations`.
14
15
  */
15
16
  export interface AstryxIntegration {
17
+ /** Stable logical provider ID. Omit to use package.json#name. Set this only
18
+ * when a package rename must preserve existing artifact IDs. */
19
+ providerId?: string;
16
20
  /** Relative path to the components/docs root (resolved to absolute). */
17
21
  components?: string;
18
22
  /** Relative path to the templates root (resolved to absolute). */
19
23
  templates?: string;
20
- /** Relative path to the codemods root (resolved to absolute). */
24
+ /** Relative path to the codemods root (resolved to absolute).
25
+ * The root uses a version-folder-first layout:
26
+ * `<codemodsRoot>/<version>/<id>.<ext>`, where `<version>` is an exact
27
+ * semver string (e.g. `0.2.0`, no `v` prefix) and `<id>` is a kebab-case
28
+ * module basename. Each module default-exports a codemod envelope stamped
29
+ * `type: 'code'` or `type: 'config'`. Codemod ids must be unique within
30
+ * a package across all versions. */
21
31
  codemods?: string;
22
32
  /** Relative path to the reference-docs (topics) root (resolved to
23
33
  * absolute). Every `{topic}.doc.{ts,mjs,js}` under it is a topic the CLI
24
34
  * serves from `astryx docs`, alongside the built-in ones. A topic may also
25
35
  * `replace` or `extend` a built-in topic; see the ReferenceDoc type. */
26
36
  docs?: string;
27
- /** Relative path to the source-theme catalog root (resolved to absolute).
28
- * The root contains `manifest.json` plus one directory per theme slug. */
37
+ /** Relative path to the source-theme root (resolved to absolute). Each
38
+ * lower-kebab theme directory contains a source module and mandatory
39
+ * same-stem, strongly typed `.doc.mjs` descriptor. */
29
40
  themes?: string;
30
41
  /** Static package guidance appended to the CLI-owned managed agent block. */
31
42
  agentDocs?: {
@@ -49,4 +60,4 @@ export type {
49
60
  GapReportCategory,
50
61
  GapReportTarget,
51
62
  GapReportHandlerReceipt,
52
- } from '../gap-report/type';
63
+ } from '../gap-report/type.js';
@@ -63,7 +63,7 @@ export function createRegistryReceipt(input: {
63
63
  name: string;
64
64
  path: string;
65
65
  aliases: string[];
66
- kind: "block" | "page" | "example" | "showcase";
66
+ kind: "page" | "block" | "example" | "showcase";
67
67
  };
68
68
  source: {
69
69
  package: "@astryxdesign/cli";
@@ -83,7 +83,7 @@ export function createRegistryReceipt(input: {
83
83
  name: string;
84
84
  path: string;
85
85
  aliases: string[];
86
- kind: "block" | "page" | "example" | "showcase";
86
+ kind: "page" | "block" | "example" | "showcase";
87
87
  };
88
88
  source: {
89
89
  package: "@astryxdesign/cli";
@@ -112,7 +112,7 @@ export function parseRegistryReceipt(input: unknown): {
112
112
  name: string;
113
113
  path: string;
114
114
  aliases: string[];
115
- kind: "block" | "page" | "example" | "showcase";
115
+ kind: "page" | "block" | "example" | "showcase";
116
116
  };
117
117
  source: {
118
118
  package: "@astryxdesign/cli";
@@ -132,7 +132,7 @@ export function parseRegistryReceipt(input: unknown): {
132
132
  name: string;
133
133
  path: string;
134
134
  aliases: string[];
135
- kind: "block" | "page" | "example" | "showcase";
135
+ kind: "page" | "block" | "example" | "showcase";
136
136
  };
137
137
  source: {
138
138
  package: "@astryxdesign/cli";
@@ -165,8 +165,8 @@ export const registryReceiptSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
165
165
  path: z.ZodString;
166
166
  aliases: z.ZodArray<z.ZodString>;
167
167
  kind: z.ZodEnum<{
168
- block: "block";
169
168
  page: "page";
169
+ block: "block";
170
170
  example: "example";
171
171
  showcase: "showcase";
172
172
  }>;
@@ -190,8 +190,8 @@ export const registryReceiptSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
190
190
  path: z.ZodString;
191
191
  aliases: z.ZodArray<z.ZodString>;
192
192
  kind: z.ZodEnum<{
193
- block: "block";
194
193
  page: "page";
194
+ block: "block";
195
195
  example: "example";
196
196
  showcase: "showcase";
197
197
  }>;
@@ -3,37 +3,35 @@
3
3
  import fs from 'fs';
4
4
  import path from 'path';
5
5
  import {describe, it, expect} from 'vitest';
6
-
7
- describe('@astryxdesign/cli Theme Manifest & Template Validation', () => {
8
- const manifestPath = path.resolve(
9
- 'packages/cli/assets/templates/themes/manifest.json',
10
- );
11
-
12
- it('validates theme manifest existence and structure', () => {
13
- expect(fs.existsSync(manifestPath)).toBe(true);
14
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
15
-
16
- expect(manifest.version).toBe(1);
17
- expect(Array.isArray(manifest.themes)).toBe(true);
18
- expect(manifest.themes.length).toBeGreaterThan(0);
19
- });
20
-
21
- it('verifies all referenced theme files exist', () => {
22
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
23
- const themesDir = path.dirname(manifestPath);
24
-
25
- for (const theme of manifest.themes) {
26
- expect(theme.slug).toBeDefined();
27
- expect(theme.displayName).toBeDefined();
28
- expect(theme.entry).toBeDefined();
29
-
30
- const entryPath = path.join(themesDir, theme.slug, theme.entry);
31
- expect(fs.existsSync(entryPath)).toBe(true);
32
-
6
+ import {discoverBundledThemes} from '../../../foundation/discovery/theme-discovery.mjs';
7
+
8
+ describe('@astryxdesign/cli bundled theme descriptor validation', () => {
9
+ it('discovers typed descriptors and their same-stem source files', () => {
10
+ const themes = discoverBundledThemes();
11
+ expect(themes.length).toBeGreaterThan(0);
12
+
13
+ for (const theme of themes) {
14
+ expect(theme.slug).toBeTruthy();
15
+ expect(theme.displayName).toBeTruthy();
16
+ expect(theme.docPath).toBe(
17
+ path.join(
18
+ theme.sourceDir,
19
+ `${path.basename(theme.entry, path.extname(theme.entry))}.doc.mjs`,
20
+ ),
21
+ );
22
+ expect(fs.existsSync(theme.docPath)).toBe(true);
23
+ expect(fs.existsSync(path.join(theme.sourceDir, theme.entry))).toBe(true);
33
24
  for (const file of theme.files) {
34
- const filePath = path.join(themesDir, theme.slug, file);
35
- expect(fs.existsSync(filePath)).toBe(true);
25
+ expect(fs.existsSync(path.join(theme.sourceDir, file))).toBe(true);
36
26
  }
37
27
  }
38
28
  });
29
+
30
+ it('does not ship the obsolete central theme catalog', () => {
31
+ expect(
32
+ fs.existsSync(
33
+ path.resolve('packages/cli/assets/templates/themes/manifest.json'),
34
+ ),
35
+ ).toBe(false);
36
+ });
39
37
  });
@@ -0,0 +1,83 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file A command whose module fails to import still answers: with --json, one
5
+ * error envelope on stdout; without it, the error on stderr. Exit 1 either way.
6
+ *
7
+ * The failure is injected with a module-load hook in a real subprocess, so the
8
+ * lazy command registry in index.mjs sees what a broken install would give it.
9
+ */
10
+
11
+ import {describe, it, expect, beforeAll, afterAll} from 'vitest';
12
+ import {spawnSync} from 'node:child_process';
13
+ import * as fs from 'node:fs';
14
+ import * as os from 'node:os';
15
+ import * as path from 'node:path';
16
+ import {fileURLToPath, pathToFileURL} from 'node:url';
17
+
18
+ const BIN = fileURLToPath(new URL('./bin/astryx.mjs', import.meta.url));
19
+
20
+ /** @type {string} */
21
+ let dir;
22
+ /** @type {string} */
23
+ let register;
24
+
25
+ beforeAll(() => {
26
+ dir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-load-failure-'));
27
+ const hooks = path.join(dir, 'hooks.mjs');
28
+ fs.writeFileSync(
29
+ hooks,
30
+ [
31
+ 'export async function load(url, context, nextLoad) {',
32
+ " if (url.endsWith('/clients/cli/commands/blog.mjs')) {",
33
+ " throw new Error('simulated load failure');",
34
+ ' }',
35
+ ' return nextLoad(url, context);',
36
+ '}',
37
+ '',
38
+ ].join('\n'),
39
+ );
40
+ register = path.join(dir, 'register.mjs');
41
+ fs.writeFileSync(
42
+ register,
43
+ `import {register} from 'node:module';\nregister(${JSON.stringify(pathToFileURL(hooks).href)});\n`,
44
+ );
45
+ });
46
+
47
+ afterAll(() => {
48
+ fs.rmSync(dir, {recursive: true, force: true});
49
+ });
50
+
51
+ /** @param {string[]} args */
52
+ function run(args) {
53
+ const res = spawnSync(
54
+ process.execPath,
55
+ ['--import', pathToFileURL(register).href, BIN, ...args],
56
+ {cwd: dir, encoding: 'utf-8', timeout: 20_000},
57
+ );
58
+ return {status: res.status, stdout: res.stdout, stderr: res.stderr};
59
+ }
60
+
61
+ describe('a command that fails to load', () => {
62
+ it('answers --json with one error envelope, exit 1', () => {
63
+ const {status, stdout, stderr} = run(['blog', '--json']);
64
+ expect(status).toBe(1);
65
+ expect(stderr).toBe('');
66
+ const envelope = JSON.parse(stdout);
67
+ expect(envelope).toMatchObject({apiVersion: 1, code: 'ERR_UNKNOWN'});
68
+ expect(envelope.error).toMatch(/blog.*simulated load failure/);
69
+ });
70
+
71
+ it('reports the failure on stderr without --json, exit 1', () => {
72
+ const {status, stdout, stderr} = run(['blog']);
73
+ expect(status).toBe(1);
74
+ expect(stdout).toBe('');
75
+ expect(stderr).toMatch(/blog.*failed to load.*simulated load failure/s);
76
+ });
77
+
78
+ it('leaves the other commands working', () => {
79
+ const {status, stdout} = run(['docs', '--json']);
80
+ expect(status).toBe(0);
81
+ expect(JSON.parse(stdout).type).toMatch(/^docs\./);
82
+ });
83
+ });
@@ -12,7 +12,7 @@ export const doc = {
12
12
  type: 'command',
13
13
  name: 'blog',
14
14
  displayName: 'astryx blog',
15
- namespace: 'cli',
15
+ namespace: 'cli/commands',
16
16
  summary: 'Read the Astryx blog from the published feed',
17
17
  description:
18
18
  'Reads the design-system blog over its published RSS feed (never the source ' +
@@ -24,6 +24,18 @@ import {resultSet} from '../../../foundation/debug/index.mjs';
24
24
  import {doc as blogCommand} from './blog.doc.mjs';
25
25
  import {doc as blogFn} from '../../../api/blog/blog.doc.mjs';
26
26
 
27
+ /** Every field of a post in the JSON, in order; record() skips empty ones. */
28
+ const POST_FIELDS = [
29
+ 'slug',
30
+ 'title',
31
+ 'description',
32
+ 'date',
33
+ 'type',
34
+ 'authors',
35
+ 'link',
36
+ 'textUrl',
37
+ ];
38
+
27
39
  /**
28
40
  * @param {import('commander').Command} program
29
41
  */
@@ -62,22 +74,25 @@ export function registerBlog(program) {
62
74
  const {feedUrl, posts} = result.data;
63
75
  if (posts.length === 0) {
64
76
  emit(
65
- section('Astryx blog', `feed: ${feedUrl}`),
77
+ section('Astryx blog'),
78
+ record({feedUrl}),
66
79
  text('No posts found in the feed.'),
67
80
  );
68
81
  return answered;
69
82
  }
70
- // One record per post — fields mirror the JSON post shape; empty
71
- // fields (type/textUrl) are skipped by record().
72
83
  emit(
73
- section('Astryx blog', `feed: ${feedUrl}`),
74
- records(posts, {fields: ['slug', 'title', 'type', 'textUrl']}),
84
+ section('Astryx blog'),
85
+ record({feedUrl}),
86
+ records(posts, {fields: POST_FIELDS}),
75
87
  text(`Read one: ${run} astryx blog <slug>`),
76
88
  );
77
89
  } else {
78
- // blog.detail — the feed URL, then the post body emitted verbatim
79
- // (code() so article typography/spacing isn't ASCII-normalized).
80
- emit(record({feed: result.data.feedUrl}), code(result.data.text));
90
+ // blog.detail — the post's fields and the feed URL, then the body
91
+ // verbatim (code() so article typography/spacing isn't ASCII-normalized).
92
+ emit(
93
+ record(result.data, {fields: [...POST_FIELDS, 'feedUrl']}),
94
+ code(result.data.text),
95
+ );
81
96
  }
82
97
  return answered;
83
98
  },
@@ -19,7 +19,10 @@ const FEED = `<?xml version="1.0" encoding="UTF-8"?>
19
19
  <item>
20
20
  <title>How Astryx works</title>
21
21
  <link>${SITE_URL}/blog/how-astryx-works</link>
22
+ <description>Under the hood &amp; more</description>
22
23
  <category>engineering</category>
24
+ <author>Ada</author>
25
+ <author>Grace</author>
23
26
  <pubDate>Mon, 29 Jun 2026 00:00:00 GMT</pubDate>
24
27
  <atom:link rel="alternate" type="text/plain" href="${SITE_URL}/blog/how-astryx-works.txt" />
25
28
  </item>
@@ -39,6 +42,23 @@ function stubFetch(routes) {
39
42
  });
40
43
  }
41
44
 
45
+ /**
46
+ * Every non-empty field prints as a `key: value` line under its JSON key.
47
+ * @param {string} stdout
48
+ * @param {Record<string, unknown>} fields
49
+ */
50
+ function expectFields(stdout, fields) {
51
+ const lines = stdout.split('\n');
52
+ for (const [key, value] of Object.entries(fields)) {
53
+ if (value == null || value === '' || (Array.isArray(value) && !value.length)) continue;
54
+ const shown = Array.isArray(value) ? value.join(', ') : String(value);
55
+ expect(
56
+ lines.some(line => line.startsWith(`${key}:`) && line.trimEnd().endsWith(shown)),
57
+ `${key}: ${shown}`,
58
+ ).toBe(true);
59
+ }
60
+ }
61
+
42
62
  beforeEach(() => {
43
63
  vi.stubGlobal(
44
64
  'fetch',
@@ -83,10 +103,31 @@ describe('blog CLI — json-enabled', () => {
83
103
  const {status, stdout} = await runCli(['blog']);
84
104
  expect(status).toBe(0);
85
105
  expect(stdout).toMatch(/Astryx blog/);
86
- expect(stdout).toMatch(/feed:/);
106
+ expect(stdout).toMatch(/^feedUrl:/m);
87
107
  expect(stdout).toMatch(/how-astryx-works/);
88
108
  });
89
109
 
110
+ it('the text list projects every JSON field under its JSON key', async () => {
111
+ const env = JSON.parse((await runCli(['blog', '--json'])).stdout);
112
+ const {status, stdout} = await runCli(['blog']);
113
+ expect(status).toBe(0);
114
+ expectFields(stdout, {feedUrl: env.data.feedUrl});
115
+ for (const post of env.data.posts) expectFields(stdout, post);
116
+ expect(stdout).not.toMatch(/^feed:/m);
117
+ });
118
+
119
+ it('the text detail projects every JSON field, then the post body', async () => {
120
+ const env = JSON.parse(
121
+ (await runCli(['blog', 'how-astryx-works', '--json'])).stdout,
122
+ );
123
+ const {status, stdout} = await runCli(['blog', 'how-astryx-works']);
124
+ expect(status).toBe(0);
125
+ const {text, ...fields} = env.data;
126
+ expectFields(stdout, fields);
127
+ expect(stdout).toContain(text);
128
+ expect(stdout).not.toMatch(/^feed:/m);
129
+ });
130
+
90
131
  it('surfaces the API error code and exits non-zero for an unknown slug (--json)', async () => {
91
132
  const {status, stdout} = await runCli(['blog', 'no-such-post', '--json']);
92
133
  expect(status).not.toBe(0);