@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,6 +11,8 @@
11
11
  */
12
12
 
13
13
  import {describe, it, expect} from 'vitest';
14
+ import * as fs from 'node:fs';
15
+ import * as os from 'node:os';
14
16
  import * as path from 'node:path';
15
17
  import {fileURLToPath} from 'node:url';
16
18
  import {search, scoreCandidate, SEARCH_DOMAINS} from '../../../api/search/search.mjs';
@@ -28,6 +30,33 @@ const OPTS = {cwd: REPO_ROOT};
28
30
  // the vitest per-test timeout. Give both the same generous scan budget.
29
31
  const SCAN_TIMEOUT = 30_000;
30
32
 
33
+ /**
34
+ * A JSON value as the formatters print it (they normalize typography to ASCII).
35
+ * @param {unknown} value
36
+ */
37
+ function asText(value) {
38
+ return (Array.isArray(value) ? value.join(', ') : String(value))
39
+ .replace(/[\u2014\u2013]/g, '-')
40
+ .replace(/[\u2018\u2019]/g, "'")
41
+ .replace(/[\u201C\u201D]/g, '"')
42
+ .replace(/\u2026/g, '...')
43
+ .replace(/\u00a0/g, ' ')
44
+ .trimEnd();
45
+ }
46
+
47
+ /**
48
+ * Whether some text line prints `key:` with this value. The command field gains
49
+ * the caller's invocation prefix, so the value is matched as the line's end; a
50
+ * multi-line value is matched by its first line.
51
+ * @param {string[]} lines
52
+ * @param {string} key
53
+ * @param {unknown} value
54
+ */
55
+ function printsField(lines, key, value) {
56
+ const shown = asText(value).split('\n')[0].trimEnd();
57
+ return lines.some(line => line.startsWith(`${key}:`) && line.trimEnd().endsWith(shown));
58
+ }
59
+
31
60
  describe('search() API — ranking', () => {
32
61
  it('ranks an exact component name match first', async () => {
33
62
  const {data} = await search('button', OPTS);
@@ -162,6 +191,18 @@ describe('search CLI — exit codes + JSON contract', () => {
162
191
  expect(r.stdout).toContain('No results');
163
192
  });
164
193
 
194
+ it('takes every word after `search` as one query', async () => {
195
+ // Commander took only the first word, so `search dark mode` searched for
196
+ // "dark" and dropped "mode" without a word.
197
+ const json = await runCli(['--json', 'search', 'dark', 'mode', '--type', 'doc'], REPO_ROOT);
198
+ expect(json.status).toBe(0);
199
+ const env = JSON.parse(json.stdout);
200
+ expect(env.data.query).toBe('dark mode');
201
+ expect(env.data.results[0]).toMatchObject({name: 'theme', section: 'light-dark-mode'});
202
+ const text = await runCli(['search', 'dark', 'mode', '--type', 'doc'], REPO_ROOT);
203
+ expect(text.stdout).toContain('Results for "dark mode"');
204
+ }, SCAN_TIMEOUT);
205
+
165
206
  it('exits 1 for an invalid --type', async () => {
166
207
  const r = await runCli(['search', 'x', '--type', 'bogus'], REPO_ROOT);
167
208
  expect(r.status).toBe(1);
@@ -172,6 +213,20 @@ describe('search CLI — exit codes + JSON contract', () => {
172
213
  expect(r.status).toBe(1);
173
214
  });
174
215
 
216
+ it.each(['1.5', '5abc'])(
217
+ 'refuses --limit %s like search({limit}) does, in both modes',
218
+ async value => {
219
+ await expect(
220
+ search('x', {...OPTS, limit: Number(value)}),
221
+ ).rejects.toMatchObject({code: 'ERR_INVALID_ARGUMENT'});
222
+ const json = await runCli(['--json', 'search', 'x', '--limit', value], REPO_ROOT);
223
+ expect(json.status).toBe(1);
224
+ expect(JSON.parse(json.stdout)).toMatchObject({code: 'ERR_INVALID_ARGUMENT'});
225
+ const text = await runCli(['search', 'x', '--limit', value], REPO_ROOT);
226
+ expect(text.status).toBe(1);
227
+ },
228
+ );
229
+
175
230
  it('emits a valid --json envelope', async () => {
176
231
  const r = await runCli(['--json', 'search', 'button'], REPO_ROOT);
177
232
  expect(r.status).toBe(0);
@@ -223,6 +278,25 @@ describe('search CLI — exit codes + JSON contract', () => {
223
278
  expect(r.stdout).toContain('description:');
224
279
  });
225
280
 
281
+ it('prints every result field under its JSON key (score and reason with --verbose)', async () => {
282
+ // One query that reaches all four domains, so every per-domain field shows.
283
+ const args = ['search', 'theme', '--limit', '60'];
284
+ const env = JSON.parse((await runCli(['--json', ...args], REPO_ROOT)).stdout);
285
+ expect(new Set(env.data.results.map(r => r.domain))).toEqual(new Set(SEARCH_DOMAINS));
286
+ const plain = (await runCli(args, REPO_ROOT)).stdout.split('\n');
287
+ const verbose = (await runCli([...args, '--verbose'], REPO_ROOT)).stdout.split('\n');
288
+ for (const result of env.data.results) {
289
+ for (const [key, value] of Object.entries(result)) {
290
+ if (value == null || value === '') continue;
291
+ const label = `${result.domain} ${result.name}: ${key}`;
292
+ expect(printsField(verbose, key, value), label).toBe(true);
293
+ if (key !== 'score' && key !== 'reason') {
294
+ expect(printsField(plain, key, value), label).toBe(true);
295
+ }
296
+ }
297
+ }
298
+ }, 90_000);
299
+
226
300
  it('--verbose exits 0 and prints import/match detail', async () => {
227
301
  // Regression: the boolean verbose flag was named --detail, which collided
228
302
  // with the value-taking global `--detail <level>` — a bare `search
@@ -236,4 +310,22 @@ describe('search CLI — exit codes + JSON contract', () => {
236
310
  expect(r.stdout).toContain('score:');
237
311
  expect(r.stdout).toContain('reason:');
238
312
  });
313
+
314
+ it('searches the docs when no @astryxdesign/core is reachable, and exits 1 for --type component', async () => {
315
+ const empty = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-search-cli-no-core-'));
316
+ try {
317
+ const open = await runCli(['--json', 'search', 'make', 'an', 'integration'], empty);
318
+ expect(open.status).toBe(0);
319
+ expect(JSON.parse(open.stdout).data.results[0]).toMatchObject({domain: 'doc'});
320
+ // The text says the search covered the docs alone.
321
+ const text = await runCli(['search', 'button'], empty);
322
+ expect(text.status).toBe(0);
323
+ expect(text.stdout).toContain('only the docs were searched');
324
+ const json = await runCli(['--json', 'search', 'button', '--type', 'component'], empty);
325
+ expect(json.status).toBe(1);
326
+ expect(JSON.parse(json.stdout)).toMatchObject({code: 'ERR_CORE_NOT_FOUND'});
327
+ } finally {
328
+ fs.rmSync(empty, {recursive: true, force: true});
329
+ }
330
+ });
239
331
  }, SCAN_TIMEOUT);
@@ -89,6 +89,12 @@ describe('enforcement layer 3 — per-command setup nudge', () => {
89
89
  expect((await runCli(['docs', 'tokens'], tmp)).stderr).not.toMatch(NUDGE);
90
90
  });
91
91
 
92
+ it('is quiet in an integration package, which is not an app', async () => {
93
+ asProject();
94
+ write('astryx.integration.mjs', 'export default {};\n');
95
+ expect((await runCli(['docs', 'tokens'], tmp)).stderr).not.toMatch(NUDGE);
96
+ });
97
+
92
98
  it('does not nudge for the installer command itself', async () => {
93
99
  asProject();
94
100
  expect((await runCli(['init'], tmp)).stderr).not.toMatch(NUDGE);
@@ -12,7 +12,7 @@ export const doc = {
12
12
  type: 'command',
13
13
  name: 'swizzle',
14
14
  displayName: 'astryx swizzle',
15
- namespace: 'cli',
15
+ namespace: 'cli/commands',
16
16
  summary: 'Copy component source for customization',
17
17
  description:
18
18
  "Ejects a component's source from the resolved @astryxdesign/core (or its owning " +
@@ -40,12 +40,13 @@ export const doc = {
40
40
  {
41
41
  flag: '-f, --overwrite',
42
42
  param: 'options.overwrite',
43
- description: 'Overwrite existing files without prompting',
43
+ description:
44
+ 'Replace existing files. Without it, existing files fail the command with ERR_FILE_EXISTS and nothing is written',
44
45
  },
45
46
  ],
46
47
  examples: [
47
48
  {label: 'List swizzlable components', cli: 'astryx swizzle --list'},
48
- {label: 'Eject a component', cli: 'astryx swizzle XDSButton'},
49
+ {label: 'Eject a component', cli: 'astryx swizzle Button'},
49
50
  ],
50
51
  exitCodes: [
51
52
  {code: 0, when: 'success'},
@@ -74,6 +74,37 @@ describe('swizzle path safety', () => {
74
74
  expect(fs.existsSync(absTarget)).toBe(false);
75
75
  });
76
76
 
77
+ it('rejects a component directory that is a symlink out of the project', async () => {
78
+ const {project, outside} = buildFakeRepo(tmpDir);
79
+ const base = path.join(project, 'components', 'astryx');
80
+ fs.mkdirSync(base, {recursive: true});
81
+ fs.symlinkSync(outside, path.join(base, 'Button'));
82
+
83
+ const result = await runCli(['--json', 'swizzle', 'Button'], project);
84
+
85
+ expect(result.code).not.toBe(0);
86
+ expect(JSON.parse(result.stdout).code).toBe('ERR_PATH_TRAVERSAL');
87
+ expect(fs.readdirSync(outside)).toEqual([]);
88
+ });
89
+
90
+ it('rejects an existing file that is a symlink out of the project, even with --overwrite', async () => {
91
+ const {project, outside} = buildFakeRepo(tmpDir);
92
+ const outDir = path.join(project, 'components', 'astryx', 'Button');
93
+ fs.mkdirSync(outDir, {recursive: true});
94
+ const target = path.join(outside, 'kept.txt');
95
+ fs.writeFileSync(target, 'kept\n');
96
+ fs.symlinkSync(target, path.join(outDir, 'Button.tsx'));
97
+
98
+ const result = await runCli(
99
+ ['--json', 'swizzle', 'Button', '--overwrite'],
100
+ project,
101
+ );
102
+
103
+ expect(result.code).not.toBe(0);
104
+ expect(JSON.parse(result.stdout).code).toBe('ERR_PATH_TRAVERSAL');
105
+ expect(fs.readFileSync(target, 'utf-8')).toBe('kept\n');
106
+ });
107
+
77
108
  it('requires --overwrite in non-interactive mode when files already exist', async () => {
78
109
  const {project} = buildFakeRepo(tmpDir);
79
110
  const outDir = path.join(project, 'components', 'astryx', 'Button');
@@ -92,4 +123,15 @@ describe('swizzle path safety', () => {
92
123
  // Existing file unchanged
93
124
  expect(fs.readFileSync(existingPath, 'utf-8')).toBe('// my customizations\n');
94
125
  });
126
+
127
+ // The CLI never prompts: without --overwrite it refuses with a code, and the
128
+ // manifest agents read must say so.
129
+ it('describes --overwrite by its refusal, not a prompt', async () => {
130
+ const {project} = buildFakeRepo(tmpDir);
131
+ const result = await runCli(['--json', 'manifest'], project);
132
+ const swizzle = JSON.parse(result.stdout).data.commands.find(c => c.name === 'swizzle');
133
+ const overwrite = swizzle.options.find(o => o.flag.includes('--overwrite'));
134
+ expect(overwrite.description).not.toMatch(/prompt/i);
135
+ expect(overwrite.description).toContain('ERR_FILE_EXISTS');
136
+ });
95
137
  });
@@ -13,21 +13,41 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'template',
15
15
  displayName: 'astryx template',
16
- namespace: 'cli',
17
- summary: 'Inject a page or block template',
16
+ namespace: 'cli/commands',
17
+ summary: 'List, show, or scaffold page and block templates',
18
18
  description:
19
19
  'One entry point for the template family: with no name it lists the discovered ' +
20
20
  'templates; with a name it shows the source or a layout skeleton, or scaffolds it ' +
21
- 'into the project at a target path. Narrow an ambiguous name with --type and/or --package. ' +
22
- '--cdn writes the no-build-step CDN starter page, which ships as an asset rather than as ' +
23
- 'a discovered template.',
21
+ 'into the project at a target path. A configured integration replacement is the ' +
22
+ 'default for its Core id; use --package @astryxdesign/core for the original. ' +
23
+ 'Narrow other ambiguous names with --type and/or --package. --cdn writes the ' +
24
+ 'no-build-step CDN starter page, which ships as an asset rather than as a ' +
25
+ 'discovered template.',
24
26
  fn: 'template',
25
27
  args: [
26
- {name: 'name', param: 'name', required: false},
27
- {name: 'path', param: 'options.targetPath', required: false},
28
+ {
29
+ name: 'name',
30
+ param: 'name',
31
+ required: false,
32
+ description: 'Template id (see --list). Omit it to list the templates.',
33
+ },
34
+ {
35
+ name: 'path',
36
+ param: 'options.targetPath',
37
+ required: false,
38
+ description:
39
+ 'Where to scaffold the template, relative to the project root. A path that ends in .tsx, .ts, .jsx, .js, .mjs, .cjs, .css, .scss, .json, .md or .html is the file to write; ' +
40
+ "any other path is a directory, which receives page.tsx for a page template or the block's own file name for a block. " +
41
+ 'Omit it to print the source.',
42
+ },
28
43
  ],
29
44
  options: [
30
- {flag: '--list', param: 'options.list', description: 'List available templates'},
45
+ {
46
+ flag: '--list',
47
+ param: 'options.list',
48
+ description:
49
+ 'List available templates (narrow with --type and --package) and do nothing else: <name>, <path>, --skeleton and --overwrite are ignored',
50
+ },
31
51
  {
32
52
  flag: '--type <type>',
33
53
  param: 'options.type',
@@ -37,37 +57,56 @@ export const doc = {
37
57
  {
38
58
  flag: '--package <pkg>',
39
59
  param: 'options.package',
40
- description: 'Narrow to templates from a specific package',
60
+ description:
61
+ 'Narrow to templates from a specific package. Use @astryxdesign/core to select an original hidden by an integration replacement.',
41
62
  },
42
63
  {
43
64
  flag: '--skeleton',
44
65
  param: 'options.skeleton',
45
66
  description:
46
- 'Show layout skeleton with spatial annotations (padding, gap, nesting)',
67
+ 'Show layout skeleton with spatial annotations (padding, gap, nesting) instead of the source. Needs <name>. ' +
68
+ 'It writes nothing, so <path> and --overwrite are ignored; --list and --cdn take precedence',
47
69
  },
48
70
  {
49
71
  flag: '--cdn [path]',
50
72
  param: 'options.cdn',
51
73
  description:
52
- 'Write the no-build-step CDN starter page (default: cdn.template.html)',
74
+ 'Write the no-build-step CDN starter page and do nothing else: <name>, --list, --skeleton, --type and --package are ignored. ' +
75
+ 'The page goes to the --cdn value, else to <path>, else cdn.template.html, and that path is always the file itself. ' +
76
+ 'A value right after --cdn (anything not starting with -) is taken as that path',
53
77
  },
54
78
  {
55
79
  flag: '-f, --overwrite',
56
80
  param: 'options.overwrite',
57
- description: 'Overwrite existing files without prompting',
81
+ description:
82
+ 'Replace an existing target file. Without it an existing file is refused (ERR_FILE_EXISTS) and an existing CDN page is left as is',
58
83
  },
59
84
  ],
60
85
  examples: [
61
86
  {label: 'List templates', cli: 'astryx template --json'},
87
+ {
88
+ label: 'List exact Core ids',
89
+ cli: 'astryx --json template --list --package @astryxdesign/core',
90
+ },
62
91
  {
63
92
  label: 'Scaffold into the app',
64
93
  cli: 'astryx template dashboard ./src/app',
65
94
  },
95
+ {
96
+ label: 'Select a replaced Core original',
97
+ cli: 'astryx template shell-side-nav ./src/app --package @astryxdesign/core',
98
+ },
66
99
  {label: 'CDN starter page', cli: 'astryx template --cdn'},
67
- {label: 'CDN starter page, elsewhere', cli: 'astryx template --cdn public/demo.html'},
100
+ {
101
+ label: 'CDN starter page, elsewhere',
102
+ cli: 'astryx template --cdn public/demo.html',
103
+ },
68
104
  ],
69
105
  exitCodes: [
70
- {code: 0, when: 'success, including a CDN page left untouched because it already exists'},
106
+ {
107
+ code: 0,
108
+ when: 'success, including a CDN page left untouched because it already exists',
109
+ },
71
110
  {
72
111
  code: 1,
73
112
  when: 'unknown or ambiguous template, no source, a path escape, or an existing target without --overwrite',
@@ -0,0 +1,117 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx template` documents which of its flags win when they are
5
+ * combined, and behaves as documented. Option text is read from the generated
6
+ * manifest, the same strings `--help` prints.
7
+ */
8
+
9
+ import {describe, it, expect, beforeEach, afterEach} from 'vitest';
10
+ import * as fs from 'node:fs';
11
+ import * as os from 'node:os';
12
+ import * as path from 'node:path';
13
+ import {runCli} from '../../../test-utils/run-cli.mjs';
14
+
15
+ const SLOW = 30_000;
16
+
17
+ /** @type {string} */
18
+ let tmpDir;
19
+
20
+ beforeEach(() => {
21
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-template-flags-'));
22
+ fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({name: 'consumer'}));
23
+ });
24
+
25
+ afterEach(() => {
26
+ fs.rmSync(tmpDir, {recursive: true, force: true});
27
+ });
28
+
29
+ /** @param {string} rel */
30
+ const exists = rel => fs.existsSync(path.join(tmpDir, rel));
31
+
32
+ /** Files in the project, ignoring package.json. */
33
+ const written = () => fs.readdirSync(tmpDir).filter(f => f !== 'package.json');
34
+
35
+ /**
36
+ * template's option descriptions from the manifest, keyed by long flag.
37
+ * @returns {Promise<Record<string, string>>}
38
+ */
39
+ async function templateOptions() {
40
+ const {stdout} = await runCli(['--json', 'manifest'], tmpDir);
41
+ const template = JSON.parse(stdout).data.commands.find(
42
+ (/** @type {{name: string}} */ c) => c.name === 'template',
43
+ );
44
+ return Object.fromEntries(
45
+ template.options.map((/** @type {{flag: string, description: string}} */ o) => [
46
+ o.flag.match(/--[a-z-]+/)?.[0],
47
+ o.description,
48
+ ]),
49
+ );
50
+ }
51
+
52
+ /** @param {string[]} args */
53
+ async function templateJson(args) {
54
+ const result = await runCli(['--json', 'template', ...args], tmpDir);
55
+ return {status: result.status, envelope: JSON.parse(result.stdout)};
56
+ }
57
+
58
+ describe('astryx template flag precedence', () => {
59
+ it('--list: help says <name>, <path>, --skeleton and --overwrite are ignored, and they are', async () => {
60
+ const help = (await templateOptions())['--list'];
61
+ for (const ignored of ['<name>', '<path>', '--skeleton', '--overwrite']) {
62
+ expect(help).toContain(ignored);
63
+ }
64
+ expect(help).toMatch(/are ignored/);
65
+
66
+ const {status, envelope} = await templateJson([
67
+ 'dashboard',
68
+ './src/page.tsx',
69
+ '--list',
70
+ '--skeleton',
71
+ '--overwrite',
72
+ ]);
73
+ expect(status).toBe(0);
74
+ expect(envelope.type).toBe('template.list');
75
+ expect(written()).toEqual([]);
76
+ }, SLOW);
77
+
78
+ it('--skeleton: help says it needs <name> and writes nothing, and it does', async () => {
79
+ const help = (await templateOptions())['--skeleton'];
80
+ expect(help).toMatch(/Needs <name>/);
81
+ expect(help).toMatch(/writes nothing, so <path> and --overwrite are ignored/);
82
+ expect(help).toMatch(/--list and --cdn take precedence/);
83
+
84
+ const shown = await templateJson(['dashboard', './src/page.tsx', '--skeleton', '--overwrite']);
85
+ expect(shown.status).toBe(0);
86
+ expect(shown.envelope.type).toBe('template.skeleton');
87
+ expect(written()).toEqual([]);
88
+
89
+ const nameless = await templateJson(['--skeleton']);
90
+ expect(nameless.status).toBe(1);
91
+ expect(nameless.envelope.code).toBe('ERR_UNKNOWN_TEMPLATE');
92
+ }, SLOW);
93
+
94
+ it('--cdn: help says it overrides everything and where the page goes, and the CLI does that', async () => {
95
+ const help = (await templateOptions())['--cdn'];
96
+ for (const ignored of ['<name>', '--list', '--skeleton', '--type', '--package']) {
97
+ expect(help).toContain(ignored);
98
+ }
99
+ expect(help).toMatch(/--cdn value, else to <path>, else cdn\.template\.html/);
100
+ expect(help).toMatch(/always the file itself/);
101
+ expect(help).toMatch(/value right after --cdn/);
102
+
103
+ const everything = await templateJson(['dashboard', '--list', '--skeleton', '--type', 'bogus', '--cdn']);
104
+ expect(everything.envelope.type).toBe('template.cdn');
105
+ expect(everything.envelope.data.path).toBe('cdn.template.html');
106
+
107
+ // A bare --cdn writes to <path>, and a path with no extension is still the file.
108
+ const positional = await templateJson(['dashboard', 'demo', '--cdn']);
109
+ expect(positional.envelope.data.path).toBe('demo');
110
+ expect(fs.statSync(path.join(tmpDir, 'demo')).isFile()).toBe(true);
111
+
112
+ // The word after --cdn is its value, not the template name.
113
+ const value = await templateJson(['--cdn', 'dashboard']);
114
+ expect(value.envelope.data.path).toBe('dashboard');
115
+ expect(exists('dashboard')).toBe(true);
116
+ }, SLOW);
117
+ });
@@ -4,12 +4,9 @@
4
4
  * @file template command — thin CLI wrapper around api/template.mjs
5
5
  */
6
6
 
7
- import * as path from 'node:path';
8
- import * as fs from 'node:fs';
9
7
  import {jsonOut} from '../../../foundation/response/json.mjs';
10
8
  import {emit, section, text, records, code} from '../formatters/index.mjs';
11
9
  import {cliError} from '../lib/cli-error.mjs';
12
- import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
13
10
  import {template as templateApi} from '../../../api/template/template.mjs';
14
11
  import {Project} from '../../../foundation/config/project.mjs';
15
12
  import {warnOnIntegrationIssues} from '../../../foundation/integrations/integration-warnings.mjs';
@@ -21,18 +18,6 @@ import {doc as templateFn} from '../../../api/template/template.doc.mjs';
21
18
 
22
19
  export {discoverTemplates, listTemplates} from '../../../api/template/template.mjs';
23
20
 
24
- /**
25
- * A template entry as produced by the discover* helpers in api/template.mjs.
26
- * The api layer returns these as `object[]`; this local shape captures the
27
- * fields the command consumes. Remove once api/template.mjs exports a precise
28
- * type for its discovered templates.
29
- * @typedef {object} DiscoveredTemplate
30
- * @property {'page' | 'block'} type
31
- * @property {string} dirName
32
- * @property {string} name
33
- * @property {string} filePath
34
- */
35
-
36
21
  /**
37
22
  * The discriminated response returned by the template API. The api layer
38
23
  * currently declares `{type: string, data: unknown}`; narrow it here to the
@@ -89,36 +74,11 @@ export function registerTemplate(program) {
89
74
  // doctor integration validate. Best-effort; suppressed in --json mode.
90
75
  try {
91
76
  const project = await Project.load(process.cwd());
92
- await warnOnIntegrationIssues(
93
- /** @type {Array<import('../../../foundation/integrations/integrations.mjs').LoadedIntegration>} */ (
94
- project.loadedIntegrations
95
- ),
96
- {json},
97
- );
77
+ await warnOnIntegrationIssues(project, {json});
98
78
  } catch {
99
79
  // Never let the nudge break the command.
100
80
  }
101
81
 
102
- // Pre-flight overwrite check (only when we'd actually copy a file).
103
- // The API resolves the destination; we need to mirror its logic
104
- // narrowly enough to detect collisions before invoking it.
105
- if (
106
- name &&
107
- targetPath &&
108
- !options.list &&
109
- !options.skeleton &&
110
- !options.cdn
111
- ) {
112
- const collision = await detectTemplateCollision(name, targetPath);
113
- if (collision && !options.overwrite) {
114
- const rel = path.relative(process.cwd(), collision) || collision;
115
- const msg =
116
- `Refusing to overwrite existing file ${rel}. ` +
117
- `Re-run with --overwrite (or -f) to replace it.`;
118
- return cliError(msg, {code: ERROR_CODES.ERR_FILE_EXISTS});
119
- }
120
- }
121
-
122
82
  /** @type {TemplateResponse} */
123
83
  let result;
124
84
  try {
@@ -156,12 +116,14 @@ export function registerTemplate(program) {
156
116
  // isn't the built-in core package.
157
117
  /** @param {import('../../../api/template/template.type.mjs').TemplateListEntry} t */
158
118
  const toRow = t => ({
119
+ id: t.id,
159
120
  name: t.isReady ? t.name : `${t.name} (WIP)`,
160
121
  description: t.description,
161
122
  package:
162
123
  t.package && t.package !== '@astryxdesign/core' ? t.package : '',
124
+ replaces: t.replaces ?? '',
163
125
  });
164
- const fields = ['name', 'description', 'package'];
126
+ const fields = ['id', 'name', 'description', 'package', 'replaces'];
165
127
  emit(
166
128
  pages.length > 0 && section('Page Templates'),
167
129
  pages.length > 0 && records(pages.map(toRow), {fields}),
@@ -229,52 +191,3 @@ export function registerTemplate(program) {
229
191
  },
230
192
  });
231
193
  }
232
-
233
- /**
234
- * Mirror the destination-resolution logic in api/template.mjs so we can
235
- * detect a clobber before invoking the API.
236
- *
237
- * Returns the absolute destination file path if it already exists, or
238
- * `null` otherwise (template missing, no collision, or list/skeleton mode).
239
- *
240
- * Path-safety enforcement happens inside the API; here we only need
241
- * enough precision to check existence — a false negative just means the
242
- * API will catch the issue and abort.
243
- *
244
- * @param {string} name
245
- * @param {string} targetPath
246
- * @returns {Promise<string | null>}
247
- */
248
- async function detectTemplateCollision(name, targetPath) {
249
- const {discoverTemplates} = await import('../../../api/template/template.mjs');
250
- /** @type {DiscoveredTemplate[]} */
251
- let templates;
252
- try {
253
- templates = /** @type {DiscoveredTemplate[]} */ (
254
- await discoverTemplates(process.cwd())
255
- );
256
- } catch {
257
- return null;
258
- }
259
- const match = templates.find(t => t.dirName === name);
260
- if (!match) return null;
261
-
262
- // Resolve target as the API will. We can't call assertWithin here
263
- // because the API does it itself; we just need to know "is there a
264
- // file at the destination?".
265
- const resolved = path.resolve(process.cwd(), targetPath);
266
-
267
- // File-arg branch: targetPath looks like `./foo.tsx`.
268
- const {isFilePathArg} = await import('../../../foundation/fs/path-safety.mjs');
269
- let dest;
270
- if (isFilePathArg(targetPath)) {
271
- dest = resolved;
272
- } else {
273
- const fileName = match.type === 'block'
274
- ? path.basename(match.filePath)
275
- : 'page.tsx';
276
- dest = path.join(resolved, fileName);
277
- }
278
-
279
- return fs.existsSync(dest) ? dest : null;
280
- }
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `template <name> <path>` decides by extension whether <path> is the
5
+ * file to write or a directory to write into. Help and the manifest say so,
6
+ * and every extension they list is one the resolver treats as a file.
7
+ */
8
+
9
+ import {describe, it, expect} from 'vitest';
10
+ import {runCli} from '../../../test-utils/run-cli.mjs';
11
+ import {isFilePathArg} from '../../../foundation/fs/path-safety.mjs';
12
+
13
+ const SLOW = 30_000;
14
+
15
+ /** @param {string} text */
16
+ const listedExtensions = text =>
17
+ [...(text.match(/ends in ([.\w, ]+ or \.\w+)/)?.[1] ?? '').matchAll(/\.\w+/g)].map(m => m[0]);
18
+
19
+ describe('template path resolution is documented', () => {
20
+ it('help explains the file-or-directory rule and the default file names', async () => {
21
+ const {status, stdout} = await runCli(['template', '--help']);
22
+ expect(status).toBe(0);
23
+ expect(stdout).toMatch(/Arguments:/);
24
+ expect(stdout).toContain('page.tsx');
25
+ expect(stdout).toMatch(/block's own file name/);
26
+ }, SLOW);
27
+
28
+ it('the manifest carries the same description, and its extensions are the resolver\'s', async () => {
29
+ const {stdout} = await runCli(['manifest', '--json']);
30
+ const {data} = JSON.parse(stdout);
31
+ const template = data.commands.find((/** @type {any} */ c) => c.name === 'template');
32
+ const pathArg = template.arguments.find((/** @type {any} */ a) => a.name === 'path');
33
+ expect(pathArg.description).toContain('page.tsx');
34
+
35
+ const exts = listedExtensions(pathArg.description);
36
+ expect(exts.length).toBeGreaterThan(0);
37
+ for (const ext of exts) expect(isFilePathArg(`out/page${ext}`)).toBe(true);
38
+ expect(isFilePathArg('out/page')).toBe(false);
39
+ }, SLOW);
40
+ });