@astryxdesign/cli 0.6.3 → 0.6.4-canary.078fd25

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
@@ -120,39 +120,94 @@ describe('integration authoring CLI', () => {
120
120
  );
121
121
  });
122
122
 
123
- it('packs the generated contribution and proves the consumer inventory', async () => {
123
+ it('pack-check rejects a generated component without an exports map (no-map false green)', async () => {
124
124
  const added = await runCli(
125
125
  ['integration', 'add', 'component', 'AcmeWidget', '--json'],
126
126
  tmpDir,
127
127
  );
128
128
  expect(added.status).toBe(0);
129
129
 
130
- const checked = await runCli(
131
- ['integration', 'pack', '--check', '--json'],
132
- tmpDir,
133
- );
134
- expect(checked.status).toBe(0);
135
- expect(parseEnvelope(checked.stdout)).toMatchObject({
130
+ const checked = await runCli(['integration', 'verify', '--json'], tmpDir);
131
+ // Without an exports map, the extensionless import cannot resolve —
132
+ // pack-check must fail, not false-green.
133
+ expect(checked.status).not.toBe(0);
134
+ const envelope = parseEnvelope(checked.stdout);
135
+ expect(envelope).toMatchObject({
136
136
  type: 'integration.pack-check',
137
137
  data: {
138
138
  name: '@acme/widgets',
139
- version: '1.0.0',
140
- packable: true,
141
- contributions: {
142
- local: {components: ['AcmeWidget']},
143
- packed: {components: ['AcmeWidget']},
144
- },
139
+ packable: false,
145
140
  },
146
141
  });
142
+ expect(envelope.data.issues).toContainEqual(
143
+ expect.objectContaining({
144
+ severity: 'error',
145
+ message: expect.stringContaining('AcmeWidget'),
146
+ }),
147
+ );
147
148
  });
148
149
 
149
- it('requires the explicit --check gate on pack', async () => {
150
- const result = await runCli(['integration', 'pack', '--json'], tmpDir);
151
- expect(result.status).not.toBe(0);
152
- expect(parseEnvelope(result.stdout)).toMatchObject({
153
- code: 'ERR_INVALID_ARGUMENT',
154
- error: 'Pass --check to verify the integration tarball.',
150
+ it('keeps `integration pack --check` as a deprecated alias of `integration verify`', async () => {
151
+ // The old spelling runs the same check: the same JSON, the same exit code.
152
+ const verify = await runCli(['integration', 'verify', '--json'], tmpDir);
153
+ const old = await runCli(
154
+ ['integration', 'pack', '--check', '--json'],
155
+ tmpDir,
156
+ );
157
+ expect(old.status).toBe(verify.status);
158
+ const verifyEnvelope = parseEnvelope(verify.stdout);
159
+ const oldEnvelope = parseEnvelope(old.stdout);
160
+ expect(oldEnvelope.type).toBe('integration.pack-check');
161
+ expect(oldEnvelope.type).toBe(verifyEnvelope.type);
162
+ expect(oldEnvelope.data.packable).toBe(verifyEnvelope.data.packable);
163
+ expect(oldEnvelope.data.issues).toEqual(verifyEnvelope.data.issues);
164
+ // The global flag may come first, as agents usually write it.
165
+ const lead = await runCli(
166
+ ['--json', 'integration', 'pack', '--check'],
167
+ tmpDir,
168
+ );
169
+ expect(parseEnvelope(lead.stdout).type).toBe('integration.pack-check');
170
+ // In text, it says to use the new name, on stderr, so stdout is the same.
171
+ const text = await runCli(['integration', 'pack', '--check'], tmpDir);
172
+ const verifyText = await runCli(['integration', 'verify'], tmpDir);
173
+ expect(text.status).toBe(verifyText.status);
174
+ expect(text.stdout).toBe(verifyText.stdout);
175
+ expect(text.stderr).toContain('`integration pack --check` is deprecated');
176
+ expect(text.stderr).toContain('astryx integration verify');
177
+ // Without --check it fails, as it did, and names both spellings.
178
+ const bare = await runCli(['integration', 'pack'], tmpDir);
179
+ expect(bare.status).not.toBe(0);
180
+ expect(bare.stderr).toContain('--check');
181
+ expect(bare.stderr).toContain('astryx integration verify');
182
+ // Help lists it, marked deprecated: nothing is hidden.
183
+ const help = await runCli(['integration', '--help'], tmpDir);
184
+ expect(help.stdout).toMatch(
185
+ /pack .*Deprecated: the old name of `integration verify`/,
186
+ );
187
+ // `verify` itself takes no --check.
188
+ const flag = await runCli(['integration', 'verify', '--check'], tmpDir);
189
+ expect(flag.status).not.toBe(0);
190
+ expect(flag.stderr).toContain("unknown option '--check'");
191
+ // An unknown subcommand with a flag names the subcommand, in text and JSON.
192
+ const unknown = await runCli(['integration', 'bogus', '--check'], tmpDir);
193
+ expect(unknown.status).not.toBe(0);
194
+ expect(unknown.stderr).toContain("unknown subcommand 'integration bogus'");
195
+ expect(unknown.stderr).toMatch(/verify\s+\(available subcommand\)/);
196
+ const unknownJson = await runCli(
197
+ ['integration', 'bogus', '--check', '--json'],
198
+ tmpDir,
199
+ );
200
+ expect(parseEnvelope(unknownJson.stdout)).toMatchObject({
201
+ code: 'ERR_UNKNOWN_SUBCOMMAND',
202
+ error: "unknown subcommand 'integration bogus'",
203
+ suggestions: expect.arrayContaining([
204
+ expect.objectContaining({name: 'verify'}),
205
+ ]),
155
206
  });
207
+ // A flag alone is an unknown option, not an unknown subcommand.
208
+ const flagOnly = await runCli(['integration', '--bogus'], tmpDir);
209
+ expect(flagOnly.status).not.toBe(0);
210
+ expect(flagOnly.stderr).toContain("unknown option '--bogus'");
156
211
  });
157
212
 
158
213
  it('refuses kind-specific options on another kind', async () => {
@@ -5,23 +5,19 @@ export const doc = {
5
5
  type: 'command',
6
6
  name: 'integration pack',
7
7
  displayName: 'astryx integration pack',
8
- namespace: 'cli',
9
- summary: 'Prove the packed integration is what consumers receive',
8
+ namespace: 'cli/commands',
9
+ summary: 'Deprecated: the old name of `integration verify`',
10
10
  description:
11
- 'Runs the package lifecycle, packs with npm, checks every required contribution file against the real tarball, extracts it into a scratch consumer, and compares the local and packed contribution inventories through one shared contract.',
11
+ '`astryx integration pack --check` is the name this check had before {@link command:integration verify}. It still runs the same check, with the same output, JSON, and exit codes, and prints a note that names `integration verify`. It will be removed in a later release.',
12
12
  fn: 'integrationPackCheck',
13
13
  options: [
14
14
  {
15
15
  flag: '--check',
16
- description: 'Run the packed-package verification gate',
16
+ description: 'Run the check. Required, as before.',
17
17
  },
18
18
  ],
19
19
  examples: [
20
- {label: 'Verify before publishing', cli: 'astryx integration pack --check'},
21
- {
22
- label: 'Machine-readable result',
23
- cli: 'astryx integration pack --check --json',
24
- },
20
+ {label: 'The old spelling', cli: 'astryx integration pack --check'},
25
21
  ],
26
22
  exitCodes: [
27
23
  {code: 0, when: 'the packed package exposes the same valid contributions'},
@@ -30,5 +26,5 @@ export const doc = {
30
26
  when: '--check is omitted or the tarball is incomplete or invalid',
31
27
  },
32
28
  ],
33
- related: ['integration add', 'doctor integration validate'],
29
+ related: ['integration verify'],
34
30
  };
@@ -201,13 +201,6 @@ export const oceanTheme = defineTheme({
201
201
  });
202
202
  `,
203
203
  );
204
- const catalogFile = path.join(providerDir, 'themes', 'manifest.json');
205
- const catalog = JSON.parse(fs.readFileSync(catalogFile, 'utf-8'));
206
- catalog.themes[0].files.push(
207
- 'tokens/ocean.palette.ts',
208
- 'tokens/ocean.palette.receipt.json',
209
- );
210
- writeJson(catalogFile, catalog);
211
204
 
212
205
  const providerPackage = JSON.parse(
213
206
  fs.readFileSync(path.join(providerDir, 'package.json'), 'utf-8'),
@@ -221,7 +214,7 @@ export const oceanTheme = defineTheme({
221
214
  ]);
222
215
 
223
216
  const checked = await runCli(
224
- ['integration', 'pack', '--check', '--json'],
217
+ ['integration', 'verify', '--json'],
225
218
  providerDir,
226
219
  );
227
220
  expect(checked.status, checked.stderr).toBe(0);
@@ -464,8 +457,9 @@ export const oceanTheme = defineTheme({
464
457
  outputDir: target,
465
458
  files: [
466
459
  'oceanTheme.ts',
467
- 'tokens/ocean.palette.ts',
460
+ 'oceanTheme.doc.mjs',
468
461
  'tokens/ocean.palette.receipt.json',
462
+ 'tokens/ocean.palette.ts',
469
463
  ],
470
464
  },
471
465
  });
@@ -612,7 +606,7 @@ export const oceanTheme = defineTheme({
612
606
  expect(corruptedInstall.status).not.toBe(0);
613
607
  expect(parseEnvelope(corruptedInstall.stdout)).toMatchObject({
614
608
  code: 'ERR_THEME_INVALID',
615
- error: expect.stringContaining('ocean.palette.ts'),
609
+ error: expect.stringContaining('./tokens/ocean.palette'),
616
610
  });
617
611
  }, 120_000);
618
612
  });
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').CommandDoc} */
4
+ export const doc = {
5
+ type: 'command',
6
+ name: 'integration verify',
7
+ displayName: 'astryx integration verify',
8
+ namespace: 'cli/commands',
9
+ summary: 'Check the package the way npm will publish it, before you publish',
10
+ description:
11
+ 'Packs the package with npm, unpacks the tarball into a temporary app without installing its dependencies, and checks that the app sees the same components, templates, themes, docs, and codemods as the package, that every public import resolves, and that the package declares a CLI new enough to read it. It publishes nothing and leaves no tarball behind. It runs the package\'s own pack lifecycle scripts, as `npm pack` does.',
12
+ fn: 'integrationPackCheck',
13
+ examples: [
14
+ {label: 'Check before publishing', cli: 'astryx integration verify'},
15
+ {label: 'Machine-readable result', cli: 'astryx integration verify --json'},
16
+ ],
17
+ exitCodes: [
18
+ {code: 0, when: 'the packed package exposes the same valid contributions'},
19
+ {code: 1, when: 'the tarball is incomplete or invalid'},
20
+ ],
21
+ related: ['integration add', 'doctor integration validate'],
22
+ };
@@ -5,19 +5,19 @@ export const doc = {
5
5
  type: 'command',
6
6
  name: 'integration',
7
7
  displayName: 'astryx integration',
8
- namespace: 'cli',
8
+ namespace: 'cli/commands',
9
9
  summary: 'Author and verify an Astryx integration package',
10
10
  description:
11
- 'Add contributions that are valid on arrival, then prove the packed package exposes the same contributions a consumer will receive.',
12
- subcommands: ['add', 'pack'],
11
+ 'Add contributions to your package, then check the packed package the way an app receives it. The guides start at {@link namespace:integrations}.',
12
+ subcommands: ['add', 'verify', 'pack'],
13
13
  examples: [
14
14
  {
15
15
  label: 'Add a component',
16
16
  cli: 'astryx integration add component AcmeWidget',
17
17
  },
18
18
  {
19
- label: 'Check the package tarball',
20
- cli: 'astryx integration pack --check',
19
+ label: 'Check the package before publishing',
20
+ cli: 'astryx integration verify',
21
21
  },
22
22
  ],
23
23
  exitCodes: [
@@ -12,6 +12,7 @@ import {cliError} from '../lib/cli-error.mjs';
12
12
  import {defineCommand} from '../lib/define-command.mjs';
13
13
  import {doc as integrationGroup} from './integration.doc.mjs';
14
14
  import {doc as integrationAddCommand} from './integration-add.doc.mjs';
15
+ import {doc as integrationVerifyCommand} from './integration-verify.doc.mjs';
15
16
  import {doc as integrationPackCommand} from './integration-pack.doc.mjs';
16
17
  import {doc as integrationAddFn} from '../../../api/integration/integrationAdd.doc.mjs';
17
18
  import {doc as integrationPackCheckFn} from '../../../api/integration/integrationPackCheck.doc.mjs';
@@ -24,8 +25,16 @@ import {doc as integrationPackCheckFn} from '../../../api/integration/integratio
24
25
  */
25
26
  function showGroupOrUnknown(command, label, options, invoked) {
26
27
  const extras = invoked?.args ?? [];
27
- if (extras.length > 0) {
28
- return cliError(`unknown subcommand '${label} ${String(extras[0])}'`, {
28
+ // allowUnknownOption keeps an unknown flag among the args: a word there is
29
+ // an unknown subcommand, and a flag alone is an unknown option.
30
+ const word = extras.find(arg => !String(arg).startsWith('-'));
31
+ if (word == null && extras.length > 0) {
32
+ return cliError(`unknown option '${String(extras[0])}'`, {
33
+ code: ERROR_CODES.ERR_INVALID_OPTION,
34
+ });
35
+ }
36
+ if (word != null) {
37
+ return cliError(`unknown subcommand '${label} ${String(word)}'`, {
29
38
  suggestions: (command.commands ?? []).map(child => ({
30
39
  name: child.name(),
31
40
  reason: 'available subcommand',
@@ -37,6 +46,48 @@ function showGroupOrUnknown(command, label, options, invoked) {
37
46
  return NO_RESULT_SET;
38
47
  }
39
48
 
49
+ /**
50
+ * Run `integration verify` and print its result, as text or JSON.
51
+ * @param {import('commander').Command} program
52
+ */
53
+ async function verifyPackage(program) {
54
+ const result = await integrationPackCheck({cwd: process.cwd()});
55
+ if (program.opts().json) {
56
+ jsonOut(result);
57
+ } else {
58
+ const {name, version, packable, tarball, inventory, issues} = result.data;
59
+ const identity = [name, version].filter(Boolean).join('@');
60
+ const blocks = [
61
+ section(
62
+ packable
63
+ ? 'Integration package ready'
64
+ : 'Integration package check failed',
65
+ ),
66
+ text(`${packable ? '[ok]' : '[fail]'} ${identity || 'local package'}`),
67
+ ];
68
+ if (tarball != null) {
69
+ blocks.push(
70
+ text(
71
+ `${tarball.fileCount} packed files; ${inventory.packedFiles}/${inventory.expectedFiles} required files present.`,
72
+ ),
73
+ );
74
+ }
75
+ if (issues.length > 0) {
76
+ blocks.push(
77
+ list(
78
+ issues.map(
79
+ issue =>
80
+ `[${issue.severity === 'error' ? 'fail' : 'warn'}] ${issue.message}`,
81
+ ),
82
+ ),
83
+ );
84
+ }
85
+ emit(...blocks);
86
+ }
87
+ if (!result.data.packable) process.exitCode = 1;
88
+ return NO_RESULT_SET;
89
+ }
90
+
40
91
  /** @param {import('commander').Command} program */
41
92
  export function registerIntegration(program) {
42
93
  /** @type {import('commander').Command} */
@@ -45,6 +96,10 @@ export function registerIntegration(program) {
45
96
  action: (options, command) =>
46
97
  showGroupOrUnknown(integration, 'integration', options, command),
47
98
  });
99
+ // An unknown subcommand given with a flag reports the unknown subcommand
100
+ // and lists the ones the group has, not the unknown option. Each subcommand
101
+ // still parses its own options.
102
+ integration.allowUnknownOption(true);
48
103
 
49
104
  defineCommand(integration, integrationAddCommand, {
50
105
  fn: integrationAddFn,
@@ -58,6 +113,7 @@ export function registerIntegration(program) {
58
113
  templateType: options.type,
59
114
  replaces: options.replaces,
60
115
  extends: options.extends,
116
+ parent: options.parent,
61
117
  to: options.to,
62
118
  });
63
119
  } catch (error) {
@@ -101,53 +157,29 @@ export function registerIntegration(program) {
101
157
  },
102
158
  });
103
159
 
160
+ defineCommand(integration, integrationVerifyCommand, {
161
+ fn: integrationPackCheckFn,
162
+ action: async () => verifyPackage(program),
163
+ });
164
+ // The name this check had before `integration verify`. It stays as a
165
+ // deprecated alias, listed as one in help, so scripts that call it keep
166
+ // working; it runs the same check with the same output and exit codes.
104
167
  defineCommand(integration, integrationPackCommand, {
105
168
  fn: integrationPackCheckFn,
106
169
  action: async options => {
107
170
  if (!options.check) {
108
- return cliError('Pass --check to verify the integration tarball.', {
109
- code: ERROR_CODES.ERR_INVALID_ARGUMENT,
110
- });
171
+ return cliError(
172
+ 'Pass --check to verify the integration tarball, or run `astryx integration verify`.',
173
+ {code: ERROR_CODES.ERR_INVALID_ARGUMENT},
174
+ );
111
175
  }
112
-
113
- const result = await integrationPackCheck({cwd: process.cwd()});
114
- if (program.opts().json) {
115
- jsonOut(result);
116
- } else {
117
- const {name, version, packable, tarball, inventory, issues} =
118
- result.data;
119
- const identity = [name, version].filter(Boolean).join('@');
120
- const blocks = [
121
- section(
122
- packable
123
- ? 'Integration package ready'
124
- : 'Integration package check failed',
125
- ),
126
- text(
127
- `${packable ? '[ok]' : '[fail]'} ${identity || 'local package'}`,
128
- ),
129
- ];
130
- if (tarball != null) {
131
- blocks.push(
132
- text(
133
- `${tarball.fileCount} packed files; ${inventory.packedFiles}/${inventory.expectedFiles} required files present.`,
134
- ),
135
- );
136
- }
137
- if (issues.length > 0) {
138
- blocks.push(
139
- list(
140
- issues.map(
141
- issue =>
142
- `[${issue.severity === 'error' ? 'fail' : 'warn'}] ${issue.message}`,
143
- ),
144
- ),
145
- );
146
- }
147
- emit(...blocks);
176
+ // stderr, and only in text: JSON callers get the same envelope as verify.
177
+ if (!program.opts().json) {
178
+ console.error(
179
+ 'Note: `integration pack --check` is deprecated. Run `astryx integration verify`: it runs the same check.',
180
+ );
148
181
  }
149
- if (!result.data.packable) process.exitCode = 1;
150
- return NO_RESULT_SET;
182
+ return verifyPackage(program);
151
183
  },
152
184
  });
153
185
  }
@@ -1,17 +1,19 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file Subprocess no-hang tests for `astryx init`.
4
+ * @file Subprocess no-hang tests: the CLI never waits on stdin (INV1).
5
5
  *
6
- * TTY was removed from the CLI: `init` is non-interactive by default and must
7
- * run cleanly (exit 0, writing the agent cheat sheet) instead of hanging on a
8
- * prompt. These tests spawn the CLI with stdin/stdout NOT a TTY (the CI / piped
9
- * / agent condition). A hang would show as signal SIGTERM + status null; we
10
- * assert `signal === null && status === 0` to prove it exits cleanly and works.
6
+ * Every run gets a stdin pipe that stays open and silent, the way an agent's
7
+ * harness holds it. A prompt or a stdin read for control flow then blocks until
8
+ * the deadline, and the run ends with signal SIGTERM and status null. With stdin
9
+ * ignored or closed, the same read would see EOF at once and pass.
10
+ *
11
+ * Every command and group in the manifest runs once, with a placeholder for
12
+ * each required argument so its action is reached, plus the bare `astryx`.
11
13
  */
12
14
 
13
15
  import {describe, it, expect, beforeEach, afterEach} from 'vitest';
14
- import {spawnSync} from 'node:child_process';
16
+ import {spawn, spawnSync} from 'node:child_process';
15
17
  import * as fs from 'node:fs';
16
18
  import * as path from 'node:path';
17
19
  import * as os from 'node:os';
@@ -19,37 +21,112 @@ import {fileURLToPath} from 'node:url';
19
21
 
20
22
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
23
  const CLI = path.resolve(__dirname, '..', 'bin', 'astryx.mjs');
24
+ const DEADLINE_MS = 20_000;
25
+ // Keeps every run offline: `blog` fetches its feed when run bare.
26
+ const OFFLINE = `data:text/javascript,${encodeURIComponent(
27
+ "globalThis.fetch = () => Promise.reject(new TypeError('fetch failed'));",
28
+ )}`;
29
+
30
+ /**
31
+ * Run `node <argv>` with a stdin pipe that is never written or ended.
32
+ * @param {string[]} argv
33
+ * @param {string} cwd
34
+ * @param {number} [deadline]
35
+ * @returns {Promise<{status: number | null, signal: NodeJS.Signals | null, output: string}>}
36
+ */
37
+ function runHeld(argv, cwd, deadline = DEADLINE_MS) {
38
+ return new Promise((resolve, reject) => {
39
+ const child = spawn(process.execPath, argv, {
40
+ cwd,
41
+ stdio: ['pipe', 'pipe', 'pipe'],
42
+ env: {...process.env, FORCE_COLOR: '0', CI: ''},
43
+ });
44
+ // Never written or ended; a late EPIPE after exit is not a result.
45
+ child.stdin.on('error', () => {});
46
+ let output = '';
47
+ child.stdout.setEncoding('utf8').on('data', chunk => (output += chunk));
48
+ child.stderr.setEncoding('utf8').on('data', chunk => (output += chunk));
49
+ const timer = setTimeout(() => child.kill('SIGTERM'), deadline);
50
+ child.on('error', error => {
51
+ clearTimeout(timer);
52
+ reject(error);
53
+ });
54
+ child.on('close', (status, signal) => {
55
+ clearTimeout(timer);
56
+ resolve({status, signal, output});
57
+ });
58
+ });
59
+ }
22
60
 
23
- let tmpDir;
61
+ /**
62
+ * @param {string[]} args
63
+ * @param {string} cwd
64
+ */
65
+ function runCli(args, cwd) {
66
+ return runHeld(['--import', OFFLINE, CLI, ...args], cwd);
67
+ }
24
68
 
25
- function runCli(args) {
26
- return spawnSync(process.execPath, [CLI, ...args], {
27
- cwd: tmpDir,
69
+ /** @returns {Array<[string, string[]]>} */
70
+ function manifestInvocations() {
71
+ const manifest = spawnSync(process.execPath, [CLI, 'manifest', '--json'], {
28
72
  encoding: 'utf8',
29
- timeout: 20_000,
30
- stdio: ['ignore', 'pipe', 'pipe'],
31
- env: {...process.env, FORCE_COLOR: '0', CI: ''},
32
73
  });
74
+ /** @type {string[][]} */
75
+ const invocations = [[]];
76
+ /** @param {any[]} commands */
77
+ const walk = commands => {
78
+ for (const command of commands) {
79
+ invocations.push([
80
+ ...command.name.split(' '),
81
+ ...command.arguments.filter((/** @type {any} */ a) => a.required).map(() => 'x'),
82
+ ]);
83
+ walk(command.subcommands ?? []);
84
+ }
85
+ };
86
+ walk(JSON.parse(manifest.stdout).data.commands);
87
+ return invocations.map(args => [['astryx', ...args].join(' '), args]);
33
88
  }
34
89
 
35
- beforeEach(() => {
36
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-interactive-guard-'));
90
+ describe('the harness holds stdin open', () => {
91
+ it('so a stdin read is reported as a hang', async () => {
92
+ const r = await runHeld(['-e', 'process.stdin.resume()'], os.tmpdir(), 1_000);
93
+ expect(r.signal).toBe('SIGTERM');
94
+ expect(r.status).toBeNull();
95
+ });
37
96
  });
38
97
 
39
- afterEach(() => {
40
- fs.rmSync(tmpDir, {recursive: true, force: true});
98
+ describe('every command exits without waiting on stdin', () => {
99
+ it.concurrent.for(manifestInvocations())('%s', async ([label, args], {expect}) => {
100
+ const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-interactive-guard-'));
101
+ try {
102
+ const r = await runCli(args, cwd);
103
+ expect(r.signal, `${label} waited on stdin:\n${r.output.slice(-500)}`).toBeNull();
104
+ } finally {
105
+ fs.rmSync(cwd, {recursive: true, force: true});
106
+ }
107
+ });
41
108
  });
42
109
 
43
110
  describe('init is non-interactive by default (no TTY needed)', () => {
44
- it('runs cleanly (exit 0, no hang) and writes agent docs', () => {
45
- const r = runCli(['init']);
111
+ let tmpDir;
112
+
113
+ beforeEach(() => {
114
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-interactive-guard-'));
115
+ });
116
+
117
+ afterEach(() => {
118
+ fs.rmSync(tmpDir, {recursive: true, force: true});
119
+ });
120
+
121
+ it('runs cleanly (exit 0, no hang) and writes agent docs', async () => {
122
+ const r = await runCli(['init'], tmpDir);
46
123
  expect(r.signal).toBeNull(); // did not hang
47
124
  expect(r.status).toBe(0); // succeeded without a TTY
48
125
  expect(fs.readdirSync(tmpDir).length).toBeGreaterThan(0); // wrote the cheat sheet
49
126
  });
50
127
 
51
- it('writes an agent-doc file containing the ASTRYX cheat-sheet marker', () => {
52
- runCli(['init']);
128
+ it('writes an agent-doc file containing the ASTRYX cheat-sheet marker', async () => {
129
+ await runCli(['init'], tmpDir);
53
130
  // init injects into existing agent-doc files if present, else creates AGENTS.md
54
131
  const candidates = ['AGENTS.md', 'CLAUDE.md', '.cursorrules', path.join('.claude', 'CLAUDE.md')];
55
132
  const doc = candidates.find(f => fs.existsSync(path.join(tmpDir, f)));
@@ -57,8 +134,8 @@ describe('init is non-interactive by default (no TTY needed)', () => {
57
134
  expect(fs.readFileSync(path.join(tmpDir, doc), 'utf8')).toMatch(/ASTRYX:START/);
58
135
  });
59
136
 
60
- it('still runs --features agents non-interactively', () => {
61
- const r = runCli(['init', '--features', 'agents']);
137
+ it('still runs --features agents non-interactively', async () => {
138
+ const r = await runCli(['init', '--features', 'agents'], tmpDir);
62
139
  expect(r.signal).toBeNull();
63
140
  expect(r.status).toBe(0);
64
141
  expect(fs.readdirSync(tmpDir).length).toBeGreaterThan(0);
@@ -172,3 +172,36 @@ describe('--json contract: supported commands emit valid envelopes', () => {
172
172
  expect(parsed.data.summary.fail).toBeGreaterThan(0);
173
173
  });
174
174
  });
175
+
176
+ describe('--json contract: the flag describes the envelopes it emits', () => {
177
+ /** @param {string} shape e.g. ` apiVersion, error, code, suggestions? ` */
178
+ const fields = shape => shape.split(',').map(f => f.trim().replace(/\?$/, ''));
179
+
180
+ it('names every field of the success and error envelopes', async () => {
181
+ const manifest = parseJson((await runCli(['manifest', '--json'], {cwd: tmpDir})).stdout);
182
+ const {description} = manifest.data.globalOptions.find(o => o.flag === '--json');
183
+ const match = /Success envelope: \{([^}]*)\}.*Error envelope: \{([^}]*)\}/.exec(description);
184
+ expect(match, description).not.toBeNull();
185
+ const [, success, error] = /** @type {RegExpExecArray} */ (match);
186
+
187
+ for (const key of Object.keys(manifest)) expect(fields(success)).toContain(key);
188
+ expect(fields(success)).toContain('meta');
189
+
190
+ // An unknown command's envelope carries every error field, suggestions included.
191
+ const failure = parseJson((await runCli(['bogus-cmd', '--json'], {cwd: tmpDir})).stdout);
192
+ expect(Object.keys(failure)).toContain('suggestions');
193
+ for (const key of Object.keys(failure)) expect(fields(error)).toContain(key);
194
+ });
195
+
196
+ it('the CLI README describes the same envelopes', () => {
197
+ const readme = fs.readFileSync(new URL('../../../README.md', import.meta.url), 'utf8');
198
+ const line = readme
199
+ .split('\n')
200
+ .find(l => l.startsWith('- `--json`: Output as typed JSON envelope:'));
201
+ expect(line, 'README global --json line').toBeDefined();
202
+ const [success, error] = [...String(line).matchAll(/`\{([^}]*)\}`/g)].map(m => fields(m[1]));
203
+ expect(success).toEqual(expect.arrayContaining(['apiVersion', 'type', 'data', 'meta']));
204
+ expect(error).toEqual(expect.arrayContaining(['apiVersion', 'error', 'code', 'suggestions']));
205
+ expect(readme).toContain('{"apiVersion": 1, "type": "component.detail"');
206
+ });
207
+ });
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'layout check',
15
15
  displayName: 'astryx layout check',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary:
18
18
  'Validate a layout expression and echo canonical compact/outline forms',
19
19
  description:
@@ -21,9 +21,20 @@ export const doc = {
21
21
  'echoes it back in both canonical surfaces (compact and outline). An invalid but ' +
22
22
  'parseable expression is reported with line/col and suggestions, and exits non-zero.',
23
23
  fn: 'layoutCheck',
24
- args: [{name: 'expression', param: 'expression', required: false}],
24
+ args: [
25
+ {
26
+ name: 'expression',
27
+ param: 'expression',
28
+ required: false,
29
+ description:
30
+ 'The XLE/XLO expression. Pass - to read it from stdin; --file reads it from a file instead.',
31
+ },
32
+ ],
25
33
  options: [
26
- {flag: '--file <file>', description: 'Read the expression from a file'},
34
+ {
35
+ flag: '--file <file>',
36
+ description: 'Read the expression from a file (used instead of the argument when both are given)',
37
+ },
27
38
  {
28
39
  flag: '--form <form>',
29
40
  param: 'options.form',
@@ -47,7 +58,7 @@ export const doc = {
47
58
  {code: 0, when: 'the expression is valid'},
48
59
  {
49
60
  code: 1,
50
- when: 'the expression is invalid or empty, has a syntax error, or a bad --form',
61
+ when: 'the expression is invalid, empty or over 5 MB (from stdin or --file), has a syntax error, or a bad --form',
51
62
  },
52
63
  ],
53
64
  related: ['layout expand', 'layout grammar'],