@astryxdesign/cli 0.6.3-canary.db4e378 → 0.6.3-canary.db52d98

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 (397) hide show
  1. package/README.md +38 -15
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/_adapter.d.mts +50 -0
  4. package/api/build/_adapter.mjs +60 -0
  5. package/api/build/build.doc.mjs +14 -7
  6. package/api/build/build.test.mjs +184 -6
  7. package/api/build/build.type.d.mts +57 -2
  8. package/api/build/build.type.mjs +30 -7
  9. package/api/build/help/help.d.mts +4 -0
  10. package/api/build/help/help.mjs +24 -11
  11. package/api/build/kit/kit.d.mts +4 -1
  12. package/api/build/kit/kit.mjs +165 -49
  13. package/api/build/kit/rank.d.mts +44 -0
  14. package/api/build/kit/rank.mjs +432 -0
  15. package/api/build/kit/rank.test.mjs +196 -0
  16. package/api/component/_adapter.d.mts +6 -12
  17. package/api/component/_adapter.mjs +20 -10
  18. package/api/component/component.doc.mjs +1 -0
  19. package/api/component/component.mjs +60 -12
  20. package/api/component/list/list.mjs +3 -2
  21. package/api/discover/discover.doc.mjs +1 -0
  22. package/api/docs/_adapter.d.mts +252 -34
  23. package/api/docs/_adapter.mjs +923 -132
  24. package/api/docs/detail/detail.mjs +11 -3
  25. package/api/docs/detail/section/section.mjs +24 -13
  26. package/api/docs/detail/section/section.test.mjs +15 -6
  27. package/api/docs/docs.d.mts +5 -3
  28. package/api/docs/docs.doc.mjs +39 -17
  29. package/api/docs/docs.mjs +44 -8
  30. package/api/docs/docs.test.mjs +158 -4
  31. package/api/docs/docs.type.d.mts +181 -2
  32. package/api/docs/docs.type.mjs +117 -3
  33. package/api/docs/index/index.mjs +11 -3
  34. package/api/docs/index/index.test.mjs +1 -1
  35. package/api/docs/integration-tree.test.mjs +555 -0
  36. package/api/docs/integrationDocs.test.mjs +14 -14
  37. package/api/docs/list/list.mjs +28 -12
  38. package/api/docs/node/node.d.mts +43 -0
  39. package/api/docs/node/node.mjs +192 -0
  40. package/api/docs/reference-blocks.test.mjs +406 -0
  41. package/api/doctor/doctor.d.mts +54 -4
  42. package/api/doctor/doctor.doc.mjs +1 -0
  43. package/api/doctor/doctor.mjs +331 -16
  44. package/api/doctor/doctor.test.mjs +420 -7
  45. package/api/gap-report/gap-report.doc.mjs +1 -0
  46. package/api/hook/_adapter.mjs +19 -5
  47. package/api/hook/hook.doc.mjs +1 -0
  48. package/api/hook/list/list.d.mts +1 -1
  49. package/api/hook/list/list.mjs +69 -17
  50. package/api/index.d.mts +1 -1
  51. package/api/index.mjs +1 -0
  52. package/api/init/init.doc.mjs +2 -1
  53. package/api/integration/add-contribution.d.mts +2 -1
  54. package/api/integration/add-contribution.mjs +114 -12
  55. package/api/integration/add-contribution.test.mjs +174 -3
  56. package/api/integration/add-theme.mjs +34 -64
  57. package/api/integration/add-theme.test.mjs +105 -21
  58. package/api/integration/authoring-checks.mjs +138 -28
  59. package/api/integration/authoring-checks.test.mjs +179 -7
  60. package/api/integration/authoring-checks.type.mjs +6 -1
  61. package/api/integration/integration-authoring.type.d.mts +2 -0
  62. package/api/integration/integration-authoring.type.mjs +2 -0
  63. package/api/integration/integration-block-exports.test.mjs +10 -6
  64. package/api/integration/integrationAdd.doc.mjs +7 -0
  65. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  66. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  67. package/api/integration/integrationAddComponent.doc.mjs +1 -0
  68. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  69. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  70. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  71. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  72. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  73. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  74. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  75. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  76. package/api/integration/pack-check.mjs +34 -0
  77. package/api/integration/pack-check.test.mjs +138 -47
  78. package/api/integration/pack-check.type.d.mts +26 -2
  79. package/api/integration/pack-check.type.mjs +14 -1
  80. package/api/integration/summarizeIssues.doc.mjs +1 -0
  81. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  82. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  83. package/api/integration/validate-integration.mjs +50 -102
  84. package/api/integration/validate-integration.test.mjs +88 -26
  85. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  86. package/api/integration/validateIntegration.doc.mjs +2 -1
  87. package/api/json/assertResponse.doc.mjs +1 -0
  88. package/api/json/index.ts +2 -0
  89. package/api/json/isError.doc.mjs +1 -0
  90. package/api/json/parseResponse.doc.mjs +1 -0
  91. package/api/layout/_adapter.mjs +20 -5
  92. package/api/layout/layoutCheck.doc.mjs +1 -0
  93. package/api/layout/layoutExpand.doc.mjs +1 -0
  94. package/api/layout/layoutGrammar.doc.mjs +1 -0
  95. package/api/search/search.d.mts +59 -1
  96. package/api/search/search.doc.mjs +5 -3
  97. package/api/search/search.mjs +458 -77
  98. package/api/search/search.test.mjs +91 -2
  99. package/api/search/search.type.d.mts +13 -1
  100. package/api/search/search.type.mjs +4 -1
  101. package/api/swizzle/swizzle.doc.mjs +1 -0
  102. package/api/template/list/list.mjs +1 -0
  103. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  104. package/api/template/template-integration.test.mjs +1072 -3
  105. package/api/template/template-suffix.test.mjs +41 -21
  106. package/api/template/template.doc.mjs +28 -7
  107. package/api/template/template.mjs +45 -8
  108. package/api/template/template.type.d.mts +6 -8
  109. package/api/template/template.type.mjs +3 -2
  110. package/api/theme/_adapter.d.mts +2 -3
  111. package/api/theme/_adapter.mjs +4 -5
  112. package/api/theme/add/add.binary.test.mjs +10 -17
  113. package/api/theme/add/add.test.mjs +14 -1
  114. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  115. package/api/theme/integration-themes.test.mjs +39 -28
  116. package/api/theme/list/list.test.mjs +19 -20
  117. package/api/theme/listThemes.doc.mjs +6 -5
  118. package/api/theme/template/template.test.mjs +5 -0
  119. package/api/theme/themeAdd.doc.mjs +4 -3
  120. package/api/theme/themeBuild.doc.mjs +1 -0
  121. package/api/theme/themeList.doc.mjs +6 -3
  122. package/api/theme/themeListAvailable.doc.mjs +5 -3
  123. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  124. package/api/theme/themeTargets.doc.mjs +1 -0
  125. package/api/theme/themeTemplate.doc.mjs +2 -1
  126. package/api/upgrade/_adapter.d.mts +32 -5
  127. package/api/upgrade/_adapter.mjs +97 -69
  128. package/api/upgrade/provider-agreement.test.mjs +152 -0
  129. package/api/upgrade/run/run.mjs +356 -59
  130. package/api/upgrade/upgrade.doc.mjs +6 -1
  131. package/api/upgrade/upgrade.type.d.mts +34 -0
  132. package/api/upgrade/upgrade.type.mjs +15 -0
  133. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  134. package/assets/codemods/integration-discovery.mjs +8 -2
  135. package/assets/codemods/integration-discovery.test.mjs +15 -0
  136. package/assets/codemods/integration-runner.mjs +56 -4
  137. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  138. package/assets/codemods/run-codemod.mjs +177 -34
  139. package/assets/codemods/runner.mjs +350 -102
  140. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  141. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  142. package/assets/codemods/transforms/next/index.mjs +19 -1
  143. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  144. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  145. package/assets/docs/getting-started.doc.mjs +2 -2
  146. package/assets/docs/layout.doc.dense.mjs +2 -2
  147. package/assets/docs/layout.doc.mjs +1 -1
  148. package/assets/docs/principles.doc.mjs +6 -6
  149. package/assets/docs/styling-libraries.doc.mjs +3 -3
  150. package/assets/docs/styling.doc.mjs +4 -4
  151. package/assets/docs/theme.doc.mjs +5 -5
  152. package/assets/docs/tokens.doc.mjs +1 -1
  153. package/assets/docs/tree/api.doc.mjs +30 -0
  154. package/assets/docs/tree/cli.doc.mjs +23 -0
  155. package/assets/docs/tree/commands.doc.mjs +25 -0
  156. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +66 -38
  157. package/assets/docs/tree/integrations.test.mjs +62 -0
  158. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  159. package/assets/docs/working-with-ai.doc.mjs +3 -3
  160. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  161. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  162. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  163. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  164. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  165. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  166. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  167. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  168. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  169. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  170. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  171. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  172. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  173. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  174. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  175. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  176. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  177. package/authoring/codemod/codemod.doc.mjs +1 -1
  178. package/authoring/codemod/type.ts +12 -0
  179. package/authoring/config/config.doc.mjs +1 -1
  180. package/authoring/debug/debug.doc.d.mts +11 -0
  181. package/authoring/debug/debug.doc.mjs +182 -0
  182. package/authoring/debug/parse.d.mts +3 -3
  183. package/authoring/doctypes/_schema.d.mts +119 -117
  184. package/authoring/doctypes/_schema.mjs +54 -3
  185. package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
  186. package/authoring/doctypes/base/type.ts +6 -5
  187. package/authoring/doctypes/command/command.doc.mjs +1 -1
  188. package/authoring/doctypes/command/type.ts +2 -2
  189. package/authoring/doctypes/component/type.ts +2 -2
  190. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  191. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  192. package/authoring/doctypes/enum/type.ts +1 -1
  193. package/authoring/doctypes/function/function.doc.mjs +3 -2
  194. package/authoring/doctypes/function/type.ts +3 -2
  195. package/authoring/doctypes/hook/type.ts +2 -2
  196. package/authoring/doctypes/load-contract.test.mjs +28 -2
  197. package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
  198. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  199. package/authoring/doctypes/namespace/type.ts +5 -2
  200. package/authoring/doctypes/parse.d.mts +4 -2
  201. package/authoring/doctypes/parse.mjs +10 -5
  202. package/authoring/doctypes/reference/reference.doc.mjs +35 -6
  203. package/authoring/doctypes/reference/type.ts +30 -13
  204. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  205. package/authoring/doctypes/schema/type.ts +1 -2
  206. package/authoring/doctypes/template/parse.d.mts +2 -0
  207. package/authoring/doctypes/template/parse.mjs +4 -0
  208. package/authoring/doctypes/template/parse.test.mjs +18 -0
  209. package/authoring/doctypes/template/template.doc.mjs +9 -3
  210. package/authoring/doctypes/template/type.ts +8 -0
  211. package/authoring/doctypes/theme/parse.d.mts +35 -0
  212. package/authoring/doctypes/theme/parse.mjs +76 -0
  213. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  214. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  215. package/authoring/doctypes/theme/type.ts +42 -0
  216. package/authoring/doctypes/types.ts +2 -1
  217. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  218. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  219. package/authoring/identity/identity.doc.mjs +2 -2
  220. package/authoring/index.d.mts +1 -0
  221. package/authoring/index.d.ts +7 -4
  222. package/authoring/index.mjs +2 -1
  223. package/authoring/integration/integration.doc.mjs +2 -2
  224. package/authoring/integration/type.ts +4 -10
  225. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  226. package/clients/cli/commands/blog.doc.mjs +1 -1
  227. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  228. package/clients/cli/commands/build-theme.mjs +11 -45
  229. package/clients/cli/commands/build.doc.mjs +12 -7
  230. package/clients/cli/commands/build.mjs +105 -67
  231. package/clients/cli/commands/build.text-fields.test.mjs +41 -0
  232. package/clients/cli/commands/component/index.mjs +1 -1
  233. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  234. package/clients/cli/commands/component.doc.mjs +1 -1
  235. package/clients/cli/commands/discover.broken-integration.test.mjs +7 -8
  236. package/clients/cli/commands/discover.doc.mjs +1 -1
  237. package/clients/cli/commands/discover.mjs +1 -1
  238. package/clients/cli/commands/docs.doc.mjs +21 -9
  239. package/clients/cli/commands/docs.mjs +184 -70
  240. package/clients/cli/commands/docs.test.mjs +120 -16
  241. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  242. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  243. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  244. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  245. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  246. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  247. package/clients/cli/commands/doctor.doc.mjs +1 -1
  248. package/clients/cli/commands/doctor.mjs +53 -16
  249. package/clients/cli/commands/gap-report.doc.mjs +1 -1
  250. package/clients/cli/commands/hook.doc.mjs +1 -1
  251. package/clients/cli/commands/init.doc.mjs +1 -1
  252. package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
  253. package/clients/cli/commands/integration-add.doc.mjs +11 -1
  254. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  255. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  256. package/clients/cli/commands/integration.doc.mjs +1 -1
  257. package/clients/cli/commands/integration.mjs +1 -0
  258. package/clients/cli/commands/layout-check.doc.mjs +1 -1
  259. package/clients/cli/commands/layout-expand.doc.mjs +1 -1
  260. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  261. package/clients/cli/commands/layout.doc.mjs +1 -1
  262. package/clients/cli/commands/manifest.doc.mjs +1 -1
  263. package/clients/cli/commands/search.doc.mjs +1 -1
  264. package/clients/cli/commands/search.mjs +11 -2
  265. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  266. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  267. package/clients/cli/commands/template.doc.mjs +24 -7
  268. package/clients/cli/commands/template.mjs +4 -91
  269. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  270. package/clients/cli/commands/theme-add.doc.mjs +2 -2
  271. package/clients/cli/commands/theme-build.doc.mjs +1 -1
  272. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  273. package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
  274. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  275. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  276. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  277. package/clients/cli/commands/theme-template.doc.mjs +1 -1
  278. package/clients/cli/commands/theme.doc.mjs +1 -1
  279. package/clients/cli/commands/upgrade.doc.mjs +3 -2
  280. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  281. package/clients/cli/commands/upgrade.mjs +29 -7
  282. package/clients/cli/formatters/index.mjs +2 -0
  283. package/clients/cli/formatters/index.test.mjs +6 -0
  284. package/clients/cli/index.mjs +8 -0
  285. package/clients/cli/lib/hook-format.mjs +14 -5
  286. package/clients/cli/lib/manifest.mjs +9 -2
  287. package/foundation/agent-docs/agent-docs.d.mts +3 -2
  288. package/foundation/agent-docs/agent-docs.mjs +13 -9
  289. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  290. package/foundation/config/project-themes.test.mjs +11 -19
  291. package/foundation/config/project.d.mts +20 -11
  292. package/foundation/config/project.mjs +123 -80
  293. package/foundation/config/project.test.mjs +144 -21
  294. package/foundation/discovery/authoring-self-docs.d.mts +18 -0
  295. package/foundation/discovery/authoring-self-docs.mjs +37 -15
  296. package/foundation/discovery/authoring-self-docs.test.mjs +25 -9
  297. package/foundation/discovery/authoring-surface.d.mts +74 -0
  298. package/foundation/discovery/authoring-surface.mjs +525 -0
  299. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  300. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  301. package/foundation/discovery/cli-self-docs.mjs +490 -0
  302. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  303. package/foundation/discovery/component-discovery.d.mts +38 -0
  304. package/foundation/discovery/component-discovery.mjs +48 -0
  305. package/foundation/discovery/component-loader.d.mts +35 -38
  306. package/foundation/discovery/component-loader.mjs +53 -222
  307. package/foundation/discovery/docs-discovery.d.mts +112 -11
  308. package/foundation/discovery/docs-discovery.mjs +231 -36
  309. package/foundation/discovery/docs-discovery.test.mjs +111 -32
  310. package/foundation/discovery/docs-output-budget.d.mts +2 -2
  311. package/foundation/discovery/docs-output-budget.mjs +1 -1
  312. package/foundation/discovery/docs-section-key.d.mts +28 -10
  313. package/foundation/discovery/docs-section-key.mjs +134 -33
  314. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  315. package/foundation/discovery/template-adapter.d.mts +99 -6
  316. package/foundation/discovery/template-adapter.mjs +480 -57
  317. package/foundation/discovery/template-adapter.test.mjs +57 -0
  318. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  319. package/foundation/discovery/template-conflict-release.mjs +40 -0
  320. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  321. package/foundation/discovery/theme-discovery.d.mts +67 -7
  322. package/foundation/discovery/theme-discovery.mjs +916 -186
  323. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  324. package/foundation/doc-compiler/bundle.d.mts +47 -0
  325. package/foundation/doc-compiler/bundle.mjs +278 -0
  326. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  327. package/foundation/doc-compiler/compile.d.mts +220 -39
  328. package/foundation/doc-compiler/compile.mjs +311 -15
  329. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  330. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  331. package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
  332. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  333. package/foundation/doc-compiler/import.d.mts +24 -0
  334. package/foundation/doc-compiler/import.mjs +59 -0
  335. package/foundation/doc-compiler/inputs.d.mts +102 -0
  336. package/foundation/doc-compiler/inputs.mjs +291 -0
  337. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  338. package/foundation/doc-compiler/ir.d.mts +13 -0
  339. package/foundation/doc-compiler/ir.mjs +196 -12
  340. package/foundation/doc-compiler/lenses.d.mts +8 -5
  341. package/foundation/doc-compiler/lenses.mjs +50 -4
  342. package/foundation/doc-compiler/links.d.mts +162 -0
  343. package/foundation/doc-compiler/links.mjs +294 -0
  344. package/foundation/doc-compiler/links.test.mjs +192 -0
  345. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  346. package/foundation/doc-compiler/overlays.d.mts +37 -0
  347. package/foundation/doc-compiler/overlays.mjs +206 -0
  348. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  349. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  350. package/foundation/doc-compiler/read.d.mts +127 -0
  351. package/foundation/doc-compiler/read.mjs +325 -0
  352. package/foundation/doc-compiler/read.test.mjs +313 -0
  353. package/foundation/doc-compiler/source.d.mts +33 -0
  354. package/foundation/doc-compiler/source.mjs +128 -0
  355. package/foundation/doc-compiler/tree.d.mts +288 -0
  356. package/foundation/doc-compiler/tree.mjs +876 -0
  357. package/foundation/doc-compiler/tree.test.mjs +598 -0
  358. package/foundation/fs/file-protection.d.mts +33 -0
  359. package/foundation/fs/file-protection.mjs +825 -0
  360. package/foundation/fs/file-protection.test.mjs +250 -0
  361. package/foundation/integrations/autolink.d.mts +58 -1
  362. package/foundation/integrations/autolink.mjs +143 -57
  363. package/foundation/integrations/autolink.test.mjs +1 -1
  364. package/foundation/integrations/cli-requirement.d.mts +45 -0
  365. package/foundation/integrations/cli-requirement.mjs +154 -0
  366. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  367. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  368. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  369. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  370. package/foundation/integrations/contribution-inventory.mjs +27 -24
  371. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  372. package/foundation/integrations/integration-warnings.d.mts +9 -2
  373. package/foundation/integrations/integration-warnings.mjs +51 -26
  374. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  375. package/foundation/integrations/integrations.d.mts +3 -0
  376. package/foundation/integrations/integrations.mjs +11 -97
  377. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  378. package/foundation/integrations/provider-resolution.d.mts +152 -0
  379. package/foundation/integrations/provider-resolution.mjs +576 -0
  380. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  381. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  382. package/foundation/integrations/theme-descriptor.mjs +44 -0
  383. package/foundation/integrations/validate-contributions.mjs +121 -29
  384. package/foundation/response/error-codes.d.mts +3 -1
  385. package/foundation/response/error-codes.d.ts +2 -0
  386. package/foundation/response/error-codes.doc.mjs +12 -2
  387. package/foundation/response/error-codes.mjs +7 -1
  388. package/foundation/response/error-codes.test.mjs +55 -11
  389. package/foundation/response/response-types.doc.d.mts +5 -1
  390. package/foundation/response/response-types.doc.mjs +20 -11
  391. package/foundation/response/response.doc.mjs +1 -1
  392. package/foundation/text/string-utils.d.mts +8 -0
  393. package/foundation/text/string-utils.mjs +40 -10
  394. package/foundation/xle/expand.mjs +1 -1
  395. package/foundation/xle/xle.test.mjs +13 -0
  396. package/package.json +10 -9
  397. package/assets/templates/themes/manifest.json +0 -95
@@ -30,7 +30,7 @@ export const docs = {
30
30
  },
31
31
  {
32
32
  type: 'prose',
33
- text: 'All approaches resolve to the same design tokens, so theming and dark mode work regardless of which you choose. For external styling libraries, run `astryx docs styling-libraries`; it covers Tailwind, StyleX, Panda, Chakra, MUI, CSS-in-JS, CSS Modules, Sass, and `useTheme()` for non-CSS processing.',
33
+ text: 'All approaches resolve to the same design tokens, so theming and dark mode work regardless of which you choose. For external styling libraries, run {@link generic:styling-libraries}; it covers Tailwind, StyleX, Panda, Chakra, MUI, CSS-in-JS, CSS Modules, Sass, and `useTheme()` for non-CSS processing.',
34
34
  },
35
35
  ],
36
36
  },
@@ -118,7 +118,7 @@ const overrides = stylex.create({
118
118
  },
119
119
  {
120
120
  type: 'prose',
121
- text: 'The bridge is pure CSS with zero JS. Theme changes (dark mode, custom themes) apply automatically because the utilities reference the same CSS custom properties that components use. This is the paved Tailwind path; for other styling libraries that follow the same aliasing pattern, run `astryx docs styling-libraries`.',
121
+ text: 'The bridge is pure CSS with zero JS. Theme changes (dark mode, custom themes) apply automatically because the utilities reference the same CSS custom properties that components use. This is the paved Tailwind path; for other styling libraries that follow the same aliasing pattern, run {@link generic:styling-libraries}.',
122
122
  },
123
123
  ],
124
124
  },
@@ -263,7 +263,7 @@ const overrides = stylex.create({
263
263
  },
264
264
  {
265
265
  type: 'prose',
266
- text: 'For systematic theming, use defineTheme component overrides instead of raw CSS selectors. defineTheme keeps the higher-level `prop:value` API (`variant:primary`, `size:sm`) and handles selector generation for you. Run `astryx docs theme` for the full theming guide.',
266
+ text: 'For systematic theming, use defineTheme component overrides instead of raw CSS selectors. defineTheme keeps the higher-level `prop:value` API (`variant:primary`, `size:sm`) and handles selector generation for you. Run {@link generic:theme} for the full theming guide.',
267
267
  },
268
268
  ],
269
269
  },
@@ -338,7 +338,7 @@ const styles = stylex.create({
338
338
  },
339
339
  {
340
340
  type: 'prose',
341
- text: 'See `astryx docs tokens` for the full token reference (all spacing, color, radius, shadow, and typography tokens with values). See `astryx docs theme` for how to override tokens via defineTheme.',
341
+ text: 'See {@link generic:tokens} for the full token reference (all spacing, color, radius, shadow, and typography tokens with values). See {@link generic:theme} for how to override tokens via defineTheme.',
342
342
  },
343
343
  ],
344
344
  },
@@ -76,7 +76,7 @@ function App() {
76
76
  [
77
77
  'Neutral',
78
78
  "import {neutralTheme} from '@astryxdesign/theme-neutral'",
79
- 'Muted, minimal aesthetic with system fonts. A good starting point.',
79
+ 'Muted, minimal aesthetic with Figtree typography. A good starting point.',
80
80
  ],
81
81
  [
82
82
  'Butter',
@@ -152,7 +152,7 @@ function App() {
152
152
  },
153
153
  {
154
154
  type: 'prose',
155
- text: 'The copy is editable project source, not a reference back into node_modules. Every file named by the theme catalog comes with it, including nested token or palette modules. A second add refuses to overwrite those files unless you pass `--overwrite`.',
155
+ text: 'The copy is editable project source, not a reference back into node_modules. The complete theme directory comes with it, including its typed `.doc.mjs`, nested token and palette modules, and receipts. A second add refuses to overwrite those files unless you pass `--overwrite`.',
156
156
  },
157
157
  ],
158
158
  },
@@ -391,7 +391,7 @@ const brandTheme = defineTheme({
391
391
  content: [
392
392
  {
393
393
  type: 'prose',
394
- text: 'The `components` field in defineTheme uses semantic component keys and style keys, not raw CSS selectors. Use `base` for all instances, `variant:value` or `stateName` for specific props/states, and let the theme pipeline choose the underlying selector. For raw external CSS escape hatches, prefer the data-attribute selector surface documented in `astryx docs styling`.',
394
+ text: 'The `components` field in defineTheme uses semantic component keys and style keys, not raw CSS selectors. Use `base` for all instances, `variant:value` or `stateName` for specific props/states, and let the theme pipeline choose the underlying selector. For raw external CSS escape hatches, prefer the data-attribute selector surface documented in {@link generic:styling}.',
395
395
  },
396
396
  {
397
397
  type: 'code',
@@ -572,7 +572,7 @@ import './themes/ocean.css';
572
572
  },
573
573
  {
574
574
  type: 'prose',
575
- text: "The build also warns when the theme names font families it does not load (webfonts like Fraunces) and prints the `<link>`/`@font-face` to add. The built CSS only sets font-family, so loading the font files stays the app's job. See `astryx docs typography` for the full recipe.",
575
+ text: "The build also warns when the theme names font families it does not load (webfonts like Fraunces) and prints the `<link>`/`@font-face` to add. The built CSS only sets font-family, so loading the font files stays the app's job. See {@link generic:typography} for the full recipe.",
576
576
  },
577
577
  ],
578
578
  },
@@ -811,7 +811,7 @@ function ChartConfig() {
811
811
  },
812
812
  {
813
813
  type: 'prose',
814
- text: 'See `astryx docs styling-libraries` for styling-library interop and `astryx docs tokens` for the full token reference.',
814
+ text: 'See {@link generic:styling-libraries} for styling-library interop and {@link generic:tokens} for the full token reference.',
815
815
  },
816
816
  ],
817
817
  },
@@ -1102,7 +1102,7 @@ export const docs = {
1102
1102
  },
1103
1103
  {
1104
1104
  "type": "prose",
1105
- "text": "See `astryx docs styling` for how to apply tokens via xstyle, className, and compound component patterns. See `astryx docs theme` for overriding tokens with defineTheme."
1105
+ "text": "See {@link generic:styling} for how to apply tokens via xstyle, className, and compound component patterns. See {@link generic:theme} for overriding tokens with defineTheme."
1106
1106
  }
1107
1107
  ]
1108
1108
  }
@@ -0,0 +1,30 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx docs cli/api`: the programmatic API of `@astryxdesign/cli/api`.
5
+ *
6
+ * Adopts each function, schema, and enum doc whose `namespace` is `cli/api`,
7
+ * one generated level per kind: `cli/api/functions`, `cli/api/schemas`, and
8
+ * `cli/api/enums`.
9
+ */
10
+
11
+ /** @type {import('@astryxdesign/cli/authoring').NamespaceDoc} */
12
+ export const docs = {
13
+ type: 'namespace',
14
+ name: 'api',
15
+ title: 'API',
16
+ summary:
17
+ 'The programmatic API: functions, the JSON output envelope, error codes, and response types.',
18
+ keywords: ['api', 'functions', 'schemas', 'enums', 'json'],
19
+ placement: {parent: 'namespace:cli', slot: 'reference', order: 20},
20
+ slots: {
21
+ kinds: {title: 'Reference', accepts: {kinds: ['namespace']}},
22
+ },
23
+ adopts: [
24
+ {
25
+ source: {group: 'cli/api', kinds: ['function', 'schema', 'enum']},
26
+ into: 'kinds',
27
+ groupBy: 'kind',
28
+ },
29
+ ],
30
+ };
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx docs cli`: the top of the CLI's docs tree (spec:AST-046).
5
+ *
6
+ * A namespace declares a level and its slots. It never lists its children:
7
+ * a guide places itself here with `placement`, and the `commands` and `api`
8
+ * namespaces adopt the CLI's typed docs by the `namespace` group each declares.
9
+ */
10
+
11
+ /** @type {import('@astryxdesign/cli/authoring').NamespaceDoc} */
12
+ export const docs = {
13
+ type: 'namespace',
14
+ name: 'cli',
15
+ title: 'Astryx CLI',
16
+ summary:
17
+ 'Commands, programmatic APIs, integration authoring, and output contracts.',
18
+ keywords: ['cli', 'commands', 'api', 'reference'],
19
+ slots: {
20
+ guides: {title: 'Guides', accepts: {kinds: ['generic', 'namespace']}},
21
+ reference: {title: 'Reference', accepts: {kinds: ['namespace']}},
22
+ },
23
+ };
@@ -0,0 +1,25 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file `astryx docs cli/commands`: every command the CLI ships.
5
+ *
6
+ * Adopts each command doc whose `namespace` is `cli/commands`, so a new
7
+ * command appears here with no edit to this file.
8
+ */
9
+
10
+ /** @type {import('@astryxdesign/cli/authoring').NamespaceDoc} */
11
+ export const docs = {
12
+ type: 'namespace',
13
+ name: 'commands',
14
+ title: 'Commands',
15
+ summary:
16
+ 'Every command and subcommand: usage, options, examples, and exit codes.',
17
+ keywords: ['commands', 'usage', 'options', 'flags'],
18
+ placement: {parent: 'namespace:cli', slot: 'reference', order: 10},
19
+ slots: {
20
+ commands: {title: 'Commands', accepts: {kinds: ['command']}},
21
+ },
22
+ adopts: [
23
+ {source: {group: 'cli/commands', kinds: ['command']}, into: 'commands'},
24
+ ],
25
+ };
@@ -1,13 +1,20 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- /** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
3
+ /**
4
+ * @file `astryx docs cli/integrations`: the guide to building an integration
5
+ * package. It lives in the docs tree under the `cli` namespace (spec:AST-046),
6
+ * so its only route is `cli/integrations`.
7
+ */
4
8
 
9
+ /** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
5
10
  export const docs = {
6
- name: 'cli-integrations',
11
+ type: 'generic',
12
+ name: 'integrations',
13
+ placement: {parent: 'namespace:cli', slot: 'guides', order: 10},
7
14
  title: 'CLI Integrations',
8
15
  category: 'guide',
9
16
  description:
10
- 'Author an npm package that contributes components, templates, themes, docs, and upgrade codemods to Astryx.',
17
+ 'Build an Astryx integration: an npm package that contributes components, templates, themes, docs, and upgrade codemods.',
11
18
 
12
19
  sections: [
13
20
  {
@@ -20,11 +27,11 @@ export const docs = {
20
27
  },
21
28
  {
22
29
  type: 'prose',
23
- text: 'The authoring CLI owns the integration file. The first `astryx integration add` creates `astryx.integration.mjs`; each later add declares its root only after writing a valid contribution behind it. Identity (name and version) still comes from package.json. For the consumer side, run `astryx docs getting-started`.',
30
+ text: 'The authoring CLI owns the integration file. The first `astryx integration add` creates `astryx.integration.mjs`; each later add declares its root only after writing a valid contribution behind it. Identity (name and version) still comes from package.json. For the consumer side, run {@link generic:getting-started}.',
24
31
  },
25
32
  {
26
33
  type: 'prose',
27
- text: 'Every file an integration author writes is documented field by field in `npx astryx docs authoring`: the manifest, astryx.config, codemods, identity, and each doc type. `npx astryx docs authoring --index` lists them, and `npx astryx docs authoring <key>` reads one.',
34
+ text: 'Every file an integration author writes is documented field by field in {@link generic:authoring}: the manifest, astryx.config, codemods, identity, and each doc type. `npx astryx docs authoring --index` lists them, and `npx astryx docs authoring <key>` reads one.',
28
35
  },
29
36
  {
30
37
  type: 'prose',
@@ -84,7 +91,7 @@ export const docs = {
84
91
  content: [
85
92
  {
86
93
  type: 'prose',
87
- text: 'A useful theme package usually ships more than colors. Start with the source theme, author the palette request at `themes/ocean/palette.config.json`, then add the guides its consumers need. The `integration add` commands keep the package manifest in sync; add palette outputs to the theme catalog after generation.',
94
+ text: 'A useful theme package usually ships more than colors. Start with the source theme, author the palette request at `themes/ocean/palette.config.json`, then add the guides its consumers need. The `integration add` commands keep the package manifest in sync. Palette outputs live inside the theme directory, which ships as one unit, so there is nothing to register after generation.',
88
95
  },
89
96
  {
90
97
  type: 'code',
@@ -94,7 +101,7 @@ export const docs = {
94
101
  },
95
102
  {
96
103
  type: 'prose',
97
- text: "Edit the generated theme and guide files before publishing. The shown palette command writes `themes/ocean/tokens/ocean.palette.ts` and its sibling `themes/ocean/tokens/ocean.palette.receipt.json`. The TypeScript candidate directly exports `black`, `white`, and `palette`; import what the theme uses from `./tokens/ocean.palette`. Keep the request at `themes/ocean/palette.config.json`, and list the theme source, request, candidate, and receipt in the catalog entry's `files` array. Add any optional wrapper, refs, icon, or preview modules only when you author them, and list each one too. `integration pack --check` runs the real package lifecycle and compares local discovery with the npm tarball, so a missing source file or files allowlist entry fails before a consumer sees it.",
104
+ text: 'Edit the generated theme descriptor, source, and guide files before publishing. The shown palette command writes `themes/ocean/tokens/ocean.palette.ts` and its sibling `themes/ocean/tokens/ocean.palette.receipt.json`, a reproducibility receipt. The TypeScript candidate directly exports `black`, `white`, and `palette`; import what the theme uses from `./tokens/ocean.palette`. Keep the request at `themes/ocean/palette.config.json`. The whole theme directory is copied and packed as one unit, so an optional wrapper, refs, icon, or preview module you add inside it ships with the theme. `integration pack --check` runs the real package lifecycle and compares local discovery with the npm tarball, so a missing source or descriptor fails before a consumer sees it.',
98
105
  },
99
106
  {
100
107
  type: 'code',
@@ -104,7 +111,7 @@ export const docs = {
104
111
  },
105
112
  {
106
113
  type: 'prose',
107
- text: 'The package must be a direct dependency for automatic discovery. No `astryx.config` entry is needed unless the app must control integration order. `theme add` copies every file listed by the selected catalog entry, including nested token modules, and refuses to overwrite existing project files.',
114
+ text: "The package must be a direct dependency for automatic discovery. No `astryx.config` entry is needed unless the app must control integration order. `theme add` copies the selected theme's complete directory, including its typed `.doc.mjs`, nested token modules, and receipts, and refuses to overwrite existing project files.",
108
115
  },
109
116
  ],
110
117
  },
@@ -119,7 +126,7 @@ export const docs = {
119
126
  {
120
127
  type: 'code',
121
128
  lang: 'text',
122
- code: "Kind Metadata suffix type stamp Source file\n──────── ───────────────────────── ───────────── ──────────────────────\nComponent Name.doc.{ts,mjs,js} 'component' Name.tsx (same stem)\nTemplate Name.template.{ts,mjs,js} 'page'/'block' Name.tsx (same stem)\nDoc topic topic.doc.{ts,mjs,js} 'generic' (none — docs are prose)\nCodemod <version>/<id>.{ts,mjs,js} 'code'/'config' (the codemod IS the source)\nTheme manifest.json entry — <slug>/<entry>.ts",
129
+ code: "Kind Metadata file type stamp Source file\n──────── ───────────────────────── ───────────── ──────────────────────\nComponent Name.doc.mjs 'component' Name.tsx (same stem)\nTemplate Name.doc.mjs 'page'/'block' Name.tsx (same stem)\nDoc topic topic.doc.mjs 'generic' (none — docs are prose)\nCodemod <version>/<id>.{ts,mjs,js} 'code'/'config' (the codemod IS the source)\nTheme <slug>/nameTheme.doc.mjs 'theme' <slug>/nameTheme.ts (same stem)\n\nReleased .doc.js files, template .doc.ts files, and .template.{ts,mjs,js}\ntemplates still load. A component or topic .doc.ts loads only from a package\nlinked from outside node_modules; installed, it is listed but cannot be read.",
123
130
  },
124
131
  {
125
132
  type: 'prose',
@@ -152,7 +159,7 @@ export const docs = {
152
159
  content: [
153
160
  {
154
161
  type: 'prose',
155
- text: "Export your components from your library however you like, and consumers still import them from your package. For each component the CLI should document, ship a `.doc.{ts,mjs,js}` file with the same stem, for example `AcmeCarousel.tsx` alongside `AcmeCarousel.doc.ts`. The doc file must default-export an object with `type: 'component'` — not `'generic'` (that is for reference docs) and not `'page'`/`'block'` (those are for templates).",
162
+ text: "Export your components from your library however you like, and consumers still import them from your package. For each component the CLI should document, ship a strongly typed `.doc.mjs` file with the same stem, for example `AcmeCarousel.tsx` alongside `AcmeCarousel.doc.mjs`. The doc file must default-export an object with `type: 'component'` — not `'generic'` (that is for reference docs) and not `'page'`/`'block'` (those are for templates). Released `.doc.js` docs remain readable for compatibility. A `.doc.ts` component doc reads only when the package is linked from outside node_modules, not once it is installed. New authoring uses `.doc.mjs`.",
156
163
  },
157
164
  {
158
165
  type: 'prose',
@@ -161,7 +168,7 @@ export const docs = {
161
168
  {
162
169
  type: 'code',
163
170
  lang: 'typescript',
164
- code: "// AcmeCarousel.doc.ts\nexport default {\n type: 'component',\n name: 'AcmeCarousel',\n description: 'A carousel that cycles through slides.',\n // props, usage, examples, ...\n} satisfies import('@astryxdesign/cli/authoring').ComponentDoc;",
171
+ code: "// AcmeCarousel.doc.mjs\n/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */\nexport default {\n type: 'component',\n name: 'AcmeCarousel',\n displayName: 'Acme Carousel',\n usage: {description: 'A carousel that cycles through slides.'},\n props: [],\n};",
165
172
  },
166
173
  ],
167
174
  },
@@ -171,20 +178,41 @@ export const docs = {
171
178
  content: [
172
179
  {
173
180
  type: 'prose',
174
- text: "Templates are usually not exported from the package directly. Instead, consumers browse them through the CLI and materialize them into their app. Define a template as a plain object with `type: 'page'` (full pages) or `type: 'block'` (smaller chunks) as its default export in a `.template.{ts,mjs,js}` file next to the source, for example `AcmeLandingPage.tsx` and `AcmeLandingPage.template.ts`. Do not use the `.doc.{ts,mjs,js}` suffix — that is for component docs and reference docs.",
181
+ text: "Templates are usually not exported from the package directly. Instead, consumers browse them through the CLI and materialize them into their app. Define a template as a strongly typed plain object stamped with `type: 'page'` (full pages) or `type: 'block'` (smaller chunks) in a same-stem `.doc.mjs`, for example `AcmeLandingPage.tsx` and `AcmeLandingPage.doc.mjs`. Released `.template.*` files remain readable for compatibility.",
175
182
  },
176
183
  {
177
184
  type: 'prose',
178
- text: 'A template id is its source-relative path with the metadata suffix removed; the display `name` is not its identity and may repeat. If an integration id matches a Core id, unqualified lookup fails closed instead of choosing one. Run `astryx doctor integration templates <package>` before publishing: it recommends renaming, but an intentional overlap is allowed when callers always pass `--package <package>`.',
185
+ text: "A template id is its exact source-relative path with the metadata suffix removed; the display `name` is not its identity and may repeat. Run `astryx --json template --list --package @astryxdesign/core` and copy the Core entry's `id` exactly. To replace one, generate the source/metadata pair with `integration add template`, then set `replaces` in that template's own metadata to the exact Core id. The declaration lives on the template, as `replaces` does on a doc topic; the manifest only points at the templates root.",
186
+ },
187
+ {
188
+ type: 'code',
189
+ lang: 'bash',
190
+ label: 'Create the integration template',
191
+ code: 'astryx integration add template acme-app-shell --type page',
192
+ },
193
+ {
194
+ type: 'code',
195
+ lang: 'typescript',
196
+ label: 'Declare the replacement',
197
+ code: "// templates/acme-app-shell.doc.mjs\n/** @type {import('@astryxdesign/cli/authoring').TemplateDoc} */\nexport default {\n type: 'page',\n name: 'acme-app-shell',\n displayName: 'Acme App Shell',\n description: 'An app shell with Acme navigation.',\n replaces: 'shell-side-nav',\n};",
179
198
  },
180
199
  {
181
200
  type: 'code',
182
201
  lang: 'typescript',
183
- code: "// AcmeLandingPage.template.ts\nexport default {\n type: 'page',\n // name, description, preview, ...\n};",
202
+ label: 'Use product navigation in the replacement source',
203
+ code: "// templates/acme-app-shell.tsx\nimport {AppShell} from '@astryxdesign/core/AppShell';\nimport {Card} from '@astryxdesign/core/Card';\nimport {AcmeSideNav, AcmeTopNav} from '@acme/navigation';\n\nexport default function AcmeAppShell() {\n return (\n <AppShell\n sideNav={<AcmeSideNav />}\n topNav={<AcmeTopNav />}>\n <Card>Product content</Card>\n </AppShell>\n );\n}",
204
+ },
205
+ {
206
+ type: 'prose',
207
+ text: 'With that declaration, `astryx template shell-side-nav` selects `acme-app-shell`; template listing, search, build suggestions, and block-layout lookup use the same effective identity. `astryx template shell-side-nav --package @astryxdesign/core` still selects the original, and `astryx template acme-app-shell --package @acme/navigation` explicitly selects the integration template. In the `template.list` JSON response, a winning replacement entry carries `replaces` naming the Core id it supersedes, and the Core entry is omitted from the default listing. A page can replace only a Core page, and a block can replace only a Core block. Missing Core targets, type mismatches, a declaration on a template that cannot be used, and more than one replacement from one package fail closed: Core stays the default and `astryx doctor integration templates <package>` reports the error. If multiple explicitly configured packages each replace the target, the package configured later wins with a warning. An explicitly configured replacement always wins over an autolinked one. If only autolinked packages conflict, the package listed later in package.json dependencies wins with a warning; add the intended package to `astryx.config` to make the choice explicit. Without `replaces`, valid template selection keeps the existing package-aware ambiguity behavior; contribution failure isolation still follows the rules below.',
208
+ },
209
+ {
210
+ type: 'prose',
211
+ text: "`replaces` is part of the strict template metadata object, so a CLI older than 0.7.0 rejects it: on those CLIs the package's templates and doc topics are withheld with one warning, while its components still load. Declare `@astryxdesign/cli >=0.7.0` when a package uses `replaces`.",
184
212
  },
185
213
  {
186
214
  type: 'prose',
187
- text: 'The CLI needs both files at consume time. `integration add` includes the templates root when package.json already has a files allowlist. It never creates an exports map, because doing that can make previously-open deep imports private; when a map already exists, it adds the generated source subpath without replacing author-owned entries. Use consumer-safe extensionless subpaths in the exports map (e.g. `"./templates/AcmeDashboard"` instead of `"./templates/AcmeDashboard.tsx"`), so consumers import without knowing the file extension. `integration pack --check` proves the source and metadata survive the tarball and verifies every component through the public import its metadata advertises.',
215
+ text: 'The CLI needs both files at consume time. `integration add` includes the templates root when package.json already has a files allowlist. It never creates an exports map, because doing that can make previously-open deep imports private; when a map already exists, it adds the generated source subpath without replacing author-owned entries. Use consumer-safe extensionless subpaths in the exports map (e.g. `"./templates/AcmeDashboard"` instead of `"./templates/AcmeDashboard.tsx"`), so consumers import without knowing the file extension. `integration pack --check` proves the source and metadata, including `replaces`, survive the tarball and verifies every component through the public import its metadata advertises.',
188
216
  },
189
217
  ],
190
218
  },
@@ -194,12 +222,12 @@ export const docs = {
194
222
  content: [
195
223
  {
196
224
  type: 'prose',
197
- text: "Point the integration file's `docs` field at a directory of reference docs and every `{topic}.doc.{ts,mjs,js}` under it becomes a topic the CLI serves: `astryx docs` lists it, `astryx docs <topic>` prints it, `astryx search` indexes it, and `astryx init` names it in the agent block. A topic is a plain object with `type: 'generic'` as its default export — not `'component'` (that is for component docs with a same-stem source file). This is the same shape core's own topics use.",
225
+ text: "Point the integration file's `docs` field at a directory of reference docs and every strongly typed `{topic}.doc.mjs` under it becomes a topic the CLI serves: `astryx docs` lists it, `astryx docs <topic>` prints it, `astryx search` indexes it, and `astryx init` names it in the agent block. A topic is a plain object stamped `type: 'generic'` — not `'component'` (that is for component docs with a same-stem source file) — the same shape core's own topics use.",
198
226
  },
199
227
  {
200
228
  type: 'code',
201
229
  lang: 'typescript',
202
- code: "// docs/deploying.doc.ts\nexport default {\n type: 'generic',\n name: 'deploying',\n title: 'Deploying',\n description: 'Ship an app built with Acme widgets.',\n category: 'guide',\n sections: [\n {title: 'Overview', content: [{type: 'prose', text: '...'}]},\n ],\n};",
230
+ code: "// docs/deploying.doc.mjs\n/** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */\nexport default {\n type: 'generic',\n name: 'deploying',\n title: 'Deploying',\n description: 'Ship an app built with Acme widgets.',\n category: 'guide',\n sections: [\n {title: 'Overview', content: [{type: 'prose', text: '...'}]},\n ],\n};",
203
231
  },
204
232
  {
205
233
  type: 'prose',
@@ -212,7 +240,7 @@ export const docs = {
212
240
  },
213
241
  {
214
242
  type: 'prose',
215
- text: "`extends: 'x'` merges onto a topic instead of owning it: a section with the same key as one in the base (its `id`, or the key its title derives) or the same title replaces that section, and a section the base does not have is appended. Reach for it to correct or add to a topic you do not want to fork: a fork of someone else's guide stops receiving their fixes the day you write it.",
243
+ text: "`extends: 'x'` merges onto a topic instead of owning it: a section with the same key as one in the base (its `id`, or the key its title derives) or the same title replaces that section, and a section the base does not have is appended. The topic keeps its own title and description; only `replaces` renames it. Reach for it to correct or add to a topic you do not want to fork: a fork of someone else's guide stops receiving their fixes the day you write it.",
216
244
  },
217
245
  {
218
246
  type: 'list',
@@ -233,38 +261,25 @@ export const docs = {
233
261
  content: [
234
262
  {
235
263
  type: 'prose',
236
- text: "A theme contribution is editable `defineTheme` source, not compiled CSS. Add `themes: './themes'` to `astryx.integration.*`, place the source under one directory per slug, and list it in `themes/manifest.json`. If package.json has a `files` allowlist, include both the integration manifest and the themes root; packages with no allowlist already publish both. Do not add an `exports` map only for theme discovery.",
264
+ text: "A theme contribution is editable `defineTheme` source, not compiled CSS. Add `themes: './themes'` to `astryx.integration.*`. Give each lower-kebab slug its own directory containing a theme source and mandatory same-stem, strongly typed `.doc.mjs`. If package.json has a `files` allowlist, include both the integration manifest and the themes root; packages with no allowlist already publish both. Do not add an `exports` map only for theme discovery.",
237
265
  },
238
266
  {
239
267
  type: 'code',
240
268
  lang: 'text',
241
- code: 'themes/\n manifest.json\n ocean/\n oceanTheme.ts\n palette.config.json\n tokens/\n ocean.palette.ts\n ocean.palette.receipt.json',
269
+ code: 'themes/\n ocean/\n oceanTheme.ts\n oceanTheme.doc.mjs\n palette.config.json\n tokens/\n ocean.palette.ts\n ocean.palette.receipt.json',
242
270
  },
243
271
  {
244
272
  type: 'prose',
245
- text: 'The root catalog `manifest.json` must be `{ "version": 1, "themes": [...] }`. Each entry in the `themes` array requires every field shown below — omitting any one is a hard validation error:',
246
- },
247
- {
248
- type: 'list',
249
- style: 'unordered',
250
- items: [
251
- '`slug` — lowercase kebab-case starting with a letter (e.g. `"ocean"`). Must be unique within the catalog.',
252
- '`displayName` — human-readable label (e.g. `"Ocean"`).',
253
- '`description` — string description of the theme.',
254
- '`maintained` — boolean indicating active maintenance.',
255
- '`entry` — source file relative to `themes/<slug>/` (e.g. `"oceanTheme.ts"`).',
256
- '`exportName` — a valid JS identifier naming the runtime export in the entry file (e.g. `"oceanTheme"`). Astryx parses the source without executing it and rejects missing or type-only exports.',
257
- '`files` — non-empty array of filenames relative to `themes/<slug>/`. Must include the entry file and every local static import the entry source uses. Astryx validates that every listed file exists on disk and that every local import in the entry names a file in this list.',
258
- ],
273
+ text: '`ThemeDoc` owns `name` (the slug), `displayName`, `description`, and `maintained`. The descriptor/source stem supplies the source entry and required named runtime export. Astryx parses the source without executing it, confines every local static import and re-export to the theme directory, copies that complete directory, and rejects missing or type-only exports.',
259
274
  },
260
275
  {
261
276
  type: 'code',
262
- lang: 'json',
263
- code: '{\n "version": 1,\n "themes": [{\n "slug": "ocean",\n "displayName": "Ocean",\n "description": "Ocean theme with OKLCH palettes.",\n "maintained": true,\n "entry": "oceanTheme.ts",\n "exportName": "oceanTheme",\n "files": [\n "oceanTheme.ts",\n "palette.config.json",\n "tokens/ocean.palette.ts",\n "tokens/ocean.palette.receipt.json"\n ]\n }]\n}',
277
+ lang: 'javascript',
278
+ code: "/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */\nexport default {\n type: 'theme',\n name: 'ocean',\n displayName: 'Ocean',\n description: 'Ocean theme.',\n maintained: true,\n};",
264
279
  },
265
280
  {
266
281
  type: 'prose',
267
- text: 'The generated candidate is already importable: it exports `black`, `white`, `palette`, and a default palette value. Import it directly from `./tokens/ocean.palette`. A wrapper or palette-refs module is optional application code, not generator output; list it only if you create it.',
282
+ text: 'The generated palette candidate is already importable: it exports `black`, `white`, `palette`, and a default palette value. Import it directly from `./tokens/ocean.palette`. A wrapper or palette-refs module is optional application code, not generator output.',
268
283
  },
269
284
  {
270
285
  type: 'prose',
@@ -343,6 +358,19 @@ export const docs = {
343
358
  lang: 'bash',
344
359
  code: '# Preview what would change (dry-run, the default)\nastryx upgrade --from 0.1.0\n\n# Apply the migration\nastryx upgrade --from 0.1.0 --apply',
345
360
  },
361
+ {
362
+ type: 'prose',
363
+ text: 'Core and integration upgrade codemods do not edit existing consumer files that the working tree protects. Protection is VCS-neutral: Astryx reads nested `.gitattributes` rules for `linguist-generated` and `linguist-vendored`, leading `@generated` and `@partially-generated` comments, standard `Code generated … DO NOT EDIT.` comments, `.gitignore`, and `.hgignore` directly from disk. Later attribute rules, explicit false or unset values, and ignore negation keep their normal semantics. Installed dependencies, VCS metadata, paths outside the project, and symbolic links are also protected. Directory or file names such as `dist` and `generated` are not evidence by themselves.',
364
+ },
365
+ {
366
+ type: 'prose',
367
+ text: 'A protected file is transformed only in memory. If it would change, the upgrade applies eligible owned-source edits, runs `hooks.postCodemod` regeneration, and checks the protected file again. A remaining change makes the run incomplete and exits nonzero with `ERR_CODEMOD_PROTECTED`; JSON output lists `modifiedFiles` and `protectedFiles` with every effective declaration. Generated headers may include `Command: <exact command>` so the result can tell a consumer how to regenerate when no hook resolves the output. Dry-run uses the same classification without writing.',
368
+ },
369
+ {
370
+ type: 'code',
371
+ lang: 'text',
372
+ code: '# .gitattributes\ngenerated/** linguist-generated=true\nvendor/** linguist-vendored=true\n\n# A later rule can explicitly return an authored file to normal handling\ngenerated/hand-authored.ts linguist-generated=false',
373
+ },
346
374
  {
347
375
  type: 'prose',
348
376
  text: 'All authoring types are exported from `@astryxdesign/cli/authoring`: `ComponentDoc`, `HookDoc`, and `ReferenceDoc` for docs, `TemplateDoc` for templates, and `AstryxConfig`, `AstryxIntegration`, and `AstryxCodemod` for the project files. Consumers can also run their own post-codemod hooks, such as a reinstall or rebuild, via `hooks.postCodemod` in their `astryx.config`.',
@@ -426,7 +454,7 @@ export const docs = {
426
454
  },
427
455
  {
428
456
  type: 'prose',
429
- text: 'Discovery is resilient. A broken or misconfigured integration is skipped with a single non-blocking warning on stderr instead of crashing the CLI, and it never corrupts a `--json` stdout envelope. Everyday commands keep working with the remaining valid contributions.',
457
+ text: "Discovery is resilient. A manifest that fails to load is skipped because none of its roots are trustworthy. An error in one contribution kind is reported without hiding the integration's other valid kinds. Invalid template and component files are omitted without hiding valid siblings; other kinds keep their existing all-or-nothing behavior. Everyday commands keep working with the remaining valid contributions, warnings go to stderr, and `--json` stdout stays clean.",
430
458
  },
431
459
  {
432
460
  type: 'prose',
@@ -0,0 +1,62 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ import {describe, expect, it} from 'vitest';
4
+ import {docs as integrationGuide} from './integrations.doc.mjs';
5
+ import {doc as integrationSchema} from '../../../authoring/integration/integration.doc.mjs';
6
+ import {doc as templateSchema} from '../../../authoring/doctypes/template/template.doc.mjs';
7
+
8
+ function guideText() {
9
+ return integrationGuide.sections
10
+ .flatMap(section => section.content)
11
+ .flatMap(block => {
12
+ if (block.type === 'prose') return [block.text];
13
+ if (block.type === 'code') return [block.label ?? '', block.code];
14
+ if (block.type === 'list') return block.items;
15
+ return [];
16
+ })
17
+ .join('\n');
18
+ }
19
+
20
+ describe('integration template replacement docs', () => {
21
+ it('documents the complete author and consumer contract', () => {
22
+ const text = guideText();
23
+
24
+ for (const required of [
25
+ "replaces: 'shell-side-nav'",
26
+ 'acme-app-shell',
27
+ 'astryx --json template --list --package @astryxdesign/core',
28
+ 'astryx template shell-side-nav --package @astryxdesign/core',
29
+ 'astryx template acme-app-shell --package @acme/navigation',
30
+ 'templates/acme-app-shell.doc.mjs',
31
+ 'AcmeSideNav',
32
+ 'AcmeTopNav',
33
+ '<Card>Product content</Card>',
34
+ 'fail closed',
35
+ 'configured later wins',
36
+ 'wins over an autolinked one',
37
+ 'listed later in package.json dependencies',
38
+ 'valid siblings',
39
+ 'Without `replaces`',
40
+ '@astryxdesign/cli >=0.7.0',
41
+ 'templates and doc topics are withheld',
42
+ '`template.list` JSON response',
43
+ ]) {
44
+ expect(text, required).toContain(required);
45
+ }
46
+ });
47
+
48
+ it('declares a replacement on the template, never in the manifest', () => {
49
+ expect(guideText()).not.toContain('templateReplacements');
50
+ expect(
51
+ integrationSchema.fields.some(field => /replac/i.test(field.name)),
52
+ ).toBe(false);
53
+
54
+ const field = templateSchema.fields.find(
55
+ candidate => candidate.name === 'replaces',
56
+ );
57
+ expect(field).toMatchObject({type: 'string'});
58
+ expect(field.description).toContain('Integration templates only');
59
+ expect(field.description).toContain('--package @astryxdesign/core');
60
+ expect(field.description).toContain('0.7.0');
61
+ });
62
+ });