@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
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'theme add',
15
15
  displayName: 'astryx theme add',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'Scaffold a theme into your project as editable source',
18
18
  description:
19
19
  "Copies a bundled or installed integration theme's source into your project so you own it. " +
@@ -49,7 +49,7 @@ export const doc = {
49
49
  {code: 0, when: 'success'},
50
50
  {
51
51
  code: 1,
52
- when: 'unknown or ambiguous theme, a path escape, a missing catalog file, or an existing file without --overwrite',
52
+ when: 'unknown or ambiguous theme, a path escape, a missing descriptor or source, or an existing file without --overwrite',
53
53
  },
54
54
  ],
55
55
  related: ['theme list', 'theme build'],
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'theme build',
15
15
  displayName: 'astryx theme build',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'Compile standalone themes or one keyed theme family',
18
18
  description:
19
19
  'Compiles defineTheme() sources through the same theme pipeline into scoped CSS, ' +
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'theme list',
15
15
  displayName: 'astryx theme list',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'List themes available to add',
18
18
  description:
19
19
  'Lists themes bundled with this CLI and source themes contributed by installed integrations, ' +
@@ -37,7 +37,7 @@ export const doc = {
37
37
  {code: 0, when: 'success'},
38
38
  {
39
39
  code: 1,
40
- when: 'the bundled-theme manifest or an installed theme catalog cannot be read',
40
+ when: 'a bundled or installed theme descriptor cannot be read',
41
41
  },
42
42
  ],
43
43
  related: ['theme add', 'theme build'],
@@ -5,7 +5,7 @@ export const doc = {
5
5
  type: 'command',
6
6
  name: 'theme palette generate',
7
7
  displayName: 'astryx theme palette generate',
8
- namespace: 'cli',
8
+ namespace: 'cli/commands',
9
9
  summary: 'Generate an OKLCH palette candidate for human review',
10
10
  description:
11
11
  'Reads an explicit JSON request and runs the versioned astryx-oklch-v1 recipe. ' +
@@ -21,8 +21,8 @@ export const doc = {
21
21
  'JSON is also supported. Existing author-owned files are left untouched unless --overwrite is explicit. ' +
22
22
  'When used in a theme integration, keep the palette request under the theme slug, ' +
23
23
  'write the candidate and receipt under that same slug, import the candidate from the theme source, ' +
24
- "and list all three paths in the theme catalog entry's `files` array " +
25
- 'so `astryx theme add` copies them into the consumer project.',
24
+ 'and keep all three inside the theme directory: `astryx theme add` copies that whole ' +
25
+ 'directory into the consumer project, so nothing else has to list them.',
26
26
  fn: 'themePaletteGenerate',
27
27
  args: [{name: 'config', param: 'configPath', required: true}],
28
28
  options: [
@@ -5,7 +5,7 @@ export const doc = {
5
5
  type: 'command',
6
6
  name: 'theme palette',
7
7
  displayName: 'astryx theme palette',
8
- namespace: 'cli',
8
+ namespace: 'cli/commands',
9
9
  summary: 'Create and work with theme-owned color palettes',
10
10
  description:
11
11
  'Palette authoring tools. The initial generate command creates reviewable candidates. ' +
@@ -17,8 +17,9 @@ describe('astryx theme targets', () => {
17
17
  const {status, stdout} = await runCli(['theme', 'targets', 'Switch']);
18
18
 
19
19
  expect(status).toBe(0);
20
- expect(stdout).toMatch(/^switch\s+Switch\s+size\s+checked, disabled$/m);
21
- expect(stdout).toMatch(/^switch-thumb\s+Switch\s+size\s+checked$/m);
20
+ // Inline layout: key component - props - states - className
21
+ expect(stdout).toMatch(/^switch\s+Switch - size - checked, disabled - astryx-switch$/m);
22
+ expect(stdout).toMatch(/^switch-thumb\s+Switch - size - checked - astryx-switch-thumb$/m);
22
23
  expect(stdout).toMatch(/4 across 1 component/);
23
24
  });
24
25
 
@@ -28,7 +29,7 @@ describe('astryx theme targets', () => {
28
29
  expect(status).toBe(0);
29
30
  expect(stdout).toMatch(/^popover\s{2,}Popover/m);
30
31
  expect(stdout).toMatch(
31
- /^popover-surface \[deprecated; use popover\]\s{2,}Popover/m,
32
+ /^popover-surface\s{2,}Popover - astryx-popover-surface - deprecated; use popover$/m,
32
33
  );
33
34
  });
34
35
 
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'theme targets',
15
15
  displayName: 'astryx theme targets',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'List the component theming targets a theme can override',
18
18
  description:
19
19
  'Prints every `defineTheme` components key across the system: the stable class it paints, ' +
@@ -13,7 +13,7 @@ export const doc = {
13
13
  type: 'command',
14
14
  name: 'theme template',
15
15
  displayName: 'astryx theme template',
16
- namespace: 'cli',
16
+ namespace: 'cli/commands',
17
17
  summary: 'Write the annotated theme template into your project',
18
18
  description:
19
19
  'Writes theme.template.ts: the annotated reference for the whole theme surface, covering every ' +
@@ -12,7 +12,7 @@ export const doc = {
12
12
  type: 'command',
13
13
  name: 'theme',
14
14
  displayName: 'astryx theme',
15
- namespace: 'cli',
15
+ namespace: 'cli/commands',
16
16
  summary: 'Theme tools: build, export, and manage themes',
17
17
  description:
18
18
  'The theme command group. Running astryx theme with no subcommand prints the ' +
@@ -12,7 +12,7 @@ export const doc = {
12
12
  type: 'command',
13
13
  name: 'upgrade',
14
14
  displayName: 'astryx upgrade',
15
- namespace: 'cli',
15
+ namespace: 'cli/commands',
16
16
  summary: 'Migrate versions and update ShadCN-copied compositions',
17
17
  description:
18
18
  'Migrates project source from a previous Astryx version to the installed one by ' +
@@ -101,13 +101,14 @@ export const doc = {
101
101
  {label: 'Apply a migration', cli: 'astryx upgrade --from 0.1.0 --apply'},
102
102
  ],
103
103
  exitCodes: [
104
- {code: 0, when: 'success (including dry-run previews)'},
104
+ {code: 0, when: 'success, including complete dry-run previews'},
105
105
  {
106
106
  code: 1,
107
107
  when:
108
108
  'missing or invalid --from, --registry with --list or a migration flag, a --path escape, ' +
109
109
  'no installed @astryxdesign/core (or legacy @xds/core), jscodeshift missing and not installed by --install-deps, ' +
110
110
  'an astryx.config that fails validation and that no pending config codemod repairs, ' +
111
+ 'an unreadable or invalid protection declaration, a protected file that still requires a codemod change, ' +
111
112
  'an unknown codemod, a codemod or post-codemod hook failure, or unresolved registry items',
112
113
  },
113
114
  ],
@@ -0,0 +1,228 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file End-to-end protection and regeneration behavior for `astryx upgrade`.
5
+ */
6
+
7
+ import {afterEach, beforeEach, describe, expect, it} from 'vitest';
8
+ import {spawnSync} from 'node:child_process';
9
+ import * as fs from 'node:fs';
10
+ import * as os from 'node:os';
11
+ import * as path from 'node:path';
12
+ import {fileURLToPath} from 'node:url';
13
+
14
+ const CLI = path.resolve(
15
+ path.dirname(fileURLToPath(import.meta.url)),
16
+ '..',
17
+ 'bin',
18
+ 'astryx.mjs',
19
+ );
20
+ let root;
21
+
22
+ function write(relative, contents) {
23
+ const file = path.join(root, relative);
24
+ fs.mkdirSync(path.dirname(file), {recursive: true});
25
+ fs.writeFileSync(file, contents);
26
+ return file;
27
+ }
28
+
29
+ function run(args) {
30
+ const result = spawnSync(
31
+ process.execPath,
32
+ [CLI, '--json', 'upgrade', ...args],
33
+ {
34
+ cwd: root,
35
+ encoding: 'utf8',
36
+ timeout: 60_000,
37
+ env: {...process.env, FORCE_COLOR: '0', CI: ''},
38
+ },
39
+ );
40
+ return {...result, envelope: JSON.parse(result.stdout)};
41
+ }
42
+
43
+ function seed({hook = false} = {}) {
44
+ write('package.json', JSON.stringify({name: 'consumer', private: true}));
45
+ write(
46
+ 'node_modules/@astryxdesign/core/package.json',
47
+ JSON.stringify({name: '@astryxdesign/core', version: '0.6.0'}),
48
+ );
49
+ write('.gitattributes', 'generated/** linguist-generated=true\n');
50
+ const source =
51
+ "import {useResizable} from '@astryxdesign/core';\n" +
52
+ 'export const usePanel = () => useResizable({minSizePx: 200});\n';
53
+ write('src/owned.tsx', source);
54
+ write('generated/panel.tsx', `// @generated\n${source}`);
55
+ write(
56
+ 'astryx.config.mjs',
57
+ hook
58
+ ? `export default {hooks: {postCodemod: [{name: 'regenerate', buildCommand: () => ({command: process.execPath, args: ['-e', ${JSON.stringify("const fs=require('node:fs');const p='generated/panel.tsx';const s=fs.readFileSync(p,'utf8');fs.writeFileSync(p,s.replaceAll('minSizePx','minSize')); ")} ]})}]}};\n`
59
+ : 'export default {};\n',
60
+ );
61
+ }
62
+
63
+ beforeEach(() => {
64
+ root = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-protected-upgrade-'));
65
+ });
66
+
67
+ afterEach(() => {
68
+ fs.rmSync(root, {recursive: true, force: true});
69
+ });
70
+
71
+ const ARGS = [
72
+ '--from',
73
+ '0.5.0',
74
+ '--codemod',
75
+ 'rename-resizable-pixel-bounds',
76
+ '--path',
77
+ '.',
78
+ ];
79
+
80
+ describe('upgrade protected-file contract', () => {
81
+ it('reports the same protected candidate in dry-run and apply while retaining owned edits', () => {
82
+ seed();
83
+
84
+ const dry = run(ARGS);
85
+ expect(dry.status).toBe(1);
86
+ expect(dry.envelope).toMatchObject({
87
+ type: 'upgrade.run',
88
+ data: {
89
+ complete: false,
90
+ errorCode: 'ERR_CODEMOD_PROTECTED',
91
+ modifiedFiles: ['src/owned.tsx'],
92
+ protectedFiles: [
93
+ {
94
+ file: 'generated/panel.tsx',
95
+ reasons: ['generated'],
96
+ declarations: expect.arrayContaining([
97
+ 'linguist-generated in .gitattributes:1',
98
+ '@generated in the leading comment block',
99
+ ]),
100
+ },
101
+ ],
102
+ },
103
+ });
104
+ expect(fs.readFileSync(path.join(root, 'src/owned.tsx'), 'utf8')).toContain(
105
+ 'minSizePx',
106
+ );
107
+
108
+ const applied = run([...ARGS, '--apply']);
109
+ expect(applied.status).toBe(1);
110
+ expect(applied.envelope.data.protectedFiles).toEqual(
111
+ dry.envelope.data.protectedFiles,
112
+ );
113
+ expect(fs.readFileSync(path.join(root, 'src/owned.tsx'), 'utf8')).toContain(
114
+ 'minSize: 200',
115
+ );
116
+ expect(
117
+ fs.readFileSync(path.join(root, 'generated/panel.tsx'), 'utf8'),
118
+ ).toContain('minSizePx');
119
+ });
120
+
121
+ it('preserves a protected config migration when strict config loading fails', () => {
122
+ write('package.json', JSON.stringify({name: 'consumer', private: true}));
123
+ write(
124
+ 'node_modules/@astryxdesign/core/package.json',
125
+ JSON.stringify({name: '@astryxdesign/core', version: '0.1.3'}),
126
+ );
127
+ write(
128
+ 'astryx.config.mjs',
129
+ `// @generated\nexport default {layout: {components: {KpiCard: '@/KpiCard'}}};\n`,
130
+ );
131
+ write('src/index.ts', 'export {};\n');
132
+
133
+ const result = run([
134
+ '--from',
135
+ '0.1.2',
136
+ '--codemod',
137
+ 'migrate-layout-components-to-experimental',
138
+ '--path',
139
+ 'src',
140
+ '--apply',
141
+ ]);
142
+
143
+ expect(result.status).toBe(1);
144
+ expect(result.envelope).toMatchObject({
145
+ type: 'upgrade.run',
146
+ data: {
147
+ complete: false,
148
+ errorCode: 'ERR_CODEMOD_PROTECTED',
149
+ protectedFiles: [expect.objectContaining({file: 'astryx.config.mjs'})],
150
+ },
151
+ });
152
+ expect(
153
+ fs.readFileSync(path.join(root, 'astryx.config.mjs'), 'utf8'),
154
+ ).toContain('layout');
155
+ });
156
+
157
+ it('fails before writes when a protection declaration cannot be parsed', () => {
158
+ seed();
159
+ write('.hgignore', 'syntax: regexp\n[bad\n');
160
+
161
+ const result = run([...ARGS, '--apply']);
162
+
163
+ expect(result.status).toBe(1);
164
+ expect(result.envelope).toMatchObject({
165
+ code: 'ERR_CODEMOD_PROTECTION_SOURCE',
166
+ });
167
+ expect(result.envelope.error).toContain('.hgignore');
168
+ expect(fs.readFileSync(path.join(root, 'src/owned.tsx'), 'utf8')).toContain(
169
+ 'minSizePx',
170
+ );
171
+ });
172
+
173
+ it('preserves protected-file facts when regeneration fails', () => {
174
+ seed();
175
+ write(
176
+ 'astryx.config.mjs',
177
+ `export default {hooks: {postCodemod: [{name: 'regenerate', buildCommand: () => ({command: process.execPath, args: ['-e', 'process.exit(7)']})}]}};\n`,
178
+ );
179
+
180
+ const applied = run([...ARGS, '--apply']);
181
+
182
+ expect(applied.status).toBe(1);
183
+ expect(applied.envelope).toMatchObject({
184
+ type: 'upgrade.run',
185
+ data: {
186
+ complete: false,
187
+ errorCode: 'ERR_CODEMOD_PROTECTED',
188
+ protectedFiles: [
189
+ expect.objectContaining({file: 'generated/panel.tsx'}),
190
+ ],
191
+ errors: [
192
+ expect.objectContaining({
193
+ codemod: 'post-codemod-hook',
194
+ error: expect.stringContaining('Post-codemod hook failed'),
195
+ }),
196
+ ],
197
+ },
198
+ });
199
+ });
200
+
201
+ it('runs declared regeneration and clears a generated-file block after reevaluation', () => {
202
+ seed({hook: true});
203
+
204
+ const applied = run([...ARGS, '--apply']);
205
+
206
+ expect(applied.status, applied.stderr).toBe(0);
207
+ expect(applied.envelope).toMatchObject({
208
+ type: 'upgrade.run',
209
+ data: {
210
+ complete: true,
211
+ modifiedFiles: ['src/owned.tsx', 'generated/panel.tsx'],
212
+ protectedFiles: [],
213
+ declinedCandidates: [],
214
+ },
215
+ });
216
+ expect(fs.readFileSync(path.join(root, 'src/owned.tsx'), 'utf8')).toContain(
217
+ 'minSize: 200',
218
+ );
219
+ expect(
220
+ fs.readFileSync(path.join(root, 'generated/panel.tsx'), 'utf8'),
221
+ ).toContain('minSize: 200');
222
+
223
+ const second = run([...ARGS, '--apply']);
224
+ expect(second.status, second.stderr).toBe(0);
225
+ expect(second.envelope.data.complete).toBe(true);
226
+ expect(second.envelope.data.filesChanged).toBe(0);
227
+ });
228
+ });
@@ -13,6 +13,7 @@
13
13
  */
14
14
 
15
15
  import {jsonOut, jsonError} from '../../../foundation/response/json.mjs';
16
+ import {emit, section, records} from '../formatters/index.mjs';
16
17
  import {logger} from '../../../api/logger.mjs';
17
18
  import {AstryxError} from '../../../api/error.mjs';
18
19
  import {defineCommand} from '../lib/define-command.mjs';
@@ -33,27 +34,45 @@ export function registerUpgrade(program) {
33
34
  */
34
35
  async options => {
35
36
  const json = program.opts().json || false;
36
- logger.setSilent(json);
37
+ const isList = Boolean(options.list);
38
+ // Silence the logger for --list so the handler renders from the
39
+ // result (parity with --json), and for --json as before.
40
+ // Re-enable on error so handled failures still print.
41
+ logger.setSilent(json || isList);
37
42
 
38
43
  /** @type {import('../../../api/upgrade/upgrade.type.mjs').UpgradeListResponse | import('../../../api/upgrade/upgrade.type.mjs').UpgradeRegistryResponse | import('../../../api/upgrade/upgrade.type.mjs').UpgradeStatusResponse | import('../../../api/upgrade/upgrade.type.mjs').UpgradeRunResponse} */
39
44
  let result;
40
45
  try {
41
46
  result = await upgradeApi(options, {cwd: process.cwd()});
42
47
  } catch (e) {
43
- // Handled failures throw AstryxError: --json emits the structured
44
- // envelope (byte-identical to the old inline jsonError) + exits 1;
45
- // human mode already saw the error line + outro via the logger, so we
46
- // just set the exit code. Anything else is unexpected — let the
47
- // top-level boundary in bin/astryx.mjs format it as before.
48
+ // Re-enable the logger so the error is visible in text mode.
49
+ // For --list the logger was silent; for other modes the API
50
+ // already printed the error before throwing.
51
+ logger.setSilent(json);
48
52
  if (e instanceof AstryxError) {
49
53
  if (json) jsonError(e.message, undefined, e.code);
50
- else process.exitCode = 1;
54
+ else {
55
+ // The logger was silent only for --list; replay the error there.
56
+ // Non-list failures were already printed by the API.
57
+ if (isList) logger.error(e.message);
58
+ process.exitCode = 1;
59
+ }
51
60
  return NO_RESULT_SET;
52
61
  }
53
62
  throw e;
54
63
  }
55
64
 
56
65
  if (json) jsonOut(result);
66
+ else if (result.type === 'upgrade.list') {
67
+ // Render the list from the result, not the API logger, so the text
68
+ // carries the same fields the JSON does (name, title, version, optional).
69
+ emit(
70
+ section('Available codemods'),
71
+ records(result.data, {
72
+ fields: ['name', 'title', 'version', 'optional'],
73
+ }),
74
+ );
75
+ }
57
76
 
58
77
  const registrySummary =
59
78
  result.type === 'upgrade.registry'
@@ -65,6 +84,9 @@ export function registerUpgrade(program) {
65
84
  ? result.data.registryCompositions
66
85
  : undefined;
67
86
  if (registrySummary && !registrySummary.ok) process.exitCode = 1;
87
+ if (result.type === 'upgrade.run' && result.data.complete === false) {
88
+ process.exitCode = 1;
89
+ }
68
90
 
69
91
  // `--list` is the one lookup here: which migrations exist for the
70
92
  // range. Everything else migrates the project — an effect, reported by
@@ -152,6 +152,8 @@ function toAscii(s) {
152
152
  .replace(/[\u2018\u2019]/g, "'")
153
153
  .replace(/[\u201C\u201D]/g, '"')
154
154
  .replace(/\u2026/g, '...')
155
+ .replace(/\u2192/g, '->')
156
+ .replace(/\u2190/g, '<-')
155
157
  .replace(/\u00a0/g, ' ');
156
158
  }
157
159
 
@@ -117,6 +117,12 @@ describe('ASCII normalization', () => {
117
117
  expect(list(['Avatar \u2014 Group']).toString()).toBe('- Avatar - Group');
118
118
  });
119
119
 
120
+ it('converts Unicode arrows to ASCII arrows', () => {
121
+ expect(text('Rename items \u2192 options').toString()).toBe('Rename items -> options');
122
+ expect(text('options \u2190 items').toString()).toBe('options <- items');
123
+ expect(record({title: 'a \u2192 b'}).toString()).toBe('title: a -> b');
124
+ });
125
+
120
126
  it('leaves code verbatim (no normalization)', () => {
121
127
  expect(code('a \u2014 b').toString()).toBe('a \u2014 b');
122
128
  });
@@ -276,6 +276,12 @@ const commands = [
276
276
  ];
277
277
 
278
278
  const SETUP_NUDGE_EXEMPT = new Set(['init', 'agent-docs']);
279
+ /** An integration package's manifest: the package is not an app to set up. */
280
+ const INTEGRATION_MANIFEST_FILES = [
281
+ 'astryx.integration.ts',
282
+ 'astryx.integration.mjs',
283
+ 'astryx.integration.js',
284
+ ];
279
285
 
280
286
  /**
281
287
  * Build a fresh, fully-wired Astryx CLI program (root options, hooks, all
@@ -519,6 +525,8 @@ export async function createProgram() {
519
525
  if (SETUP_NUDGE_EXEMPT.has(actionCommand.name())) return;
520
526
  const cwd = process.cwd();
521
527
  if (!fs.existsSync(path.join(cwd, 'package.json'))) return; // not a project
528
+ // An integration package is not an app: `init` is not its next step.
529
+ if (INTEGRATION_MANIFEST_FILES.some(file => fs.existsSync(path.join(cwd, file)))) return;
522
530
  if (isAstryxInitialized(cwd)) return; // already set up — stay quiet
523
531
  // Same wording as the core/cli postinstall nudges. #4151's getCliInvocation()
524
532
  // renders the correct form for THIS project — scoped `npx @astryxdesign/cli`
@@ -9,7 +9,10 @@
9
9
  * - Brief: signature line with import hint, description, key params
10
10
  */
11
11
 
12
- import {discoverHooks, findHookDoc} from '../../../foundation/discovery/hook-discovery.mjs';
12
+ import {
13
+ discoverHooks,
14
+ findHookDoc,
15
+ } from '../../../foundation/discovery/hook-discovery.mjs';
13
16
  import {loadDocs} from '../../../foundation/discovery/component-loader.mjs';
14
17
  import {formatAccessibility, mdCell} from './component-format.mjs';
15
18
 
@@ -23,7 +26,9 @@ function buildSignature(docs) {
23
26
  const name = docs.name;
24
27
 
25
28
  // Build params string — only top-level params (skip options.foo nested params)
26
- const topParams = (docs.params || []).filter((/** @type {any} */ p) => !p.name.includes('.'));
29
+ const topParams = (docs.params || []).filter(
30
+ (/** @type {any} */ p) => !p.name.includes('.'),
31
+ );
27
32
  const paramStr = topParams
28
33
  .map((/** @type {any} */ p) => {
29
34
  const opt = p.required ? '' : '?';
@@ -150,7 +155,9 @@ export function formatHookCompact(docs, importPath) {
150
155
  const imp = importPath || docs.importPath;
151
156
  if (imp) {
152
157
  sections.push('## Import\n');
153
- sections.push(`\`\`\`tsx\nimport { ${docs.name} } from '${imp}';\n\`\`\`\n`);
158
+ sections.push(
159
+ `\`\`\`tsx\nimport { ${docs.name} } from '${imp}';\n\`\`\`\n`,
160
+ );
154
161
  }
155
162
 
156
163
  // Best Practices (matches component compact)
@@ -228,7 +235,9 @@ export function formatHookBrief(docs) {
228
235
  // Key params (matches component brief 'prop, prop' line)
229
236
  const paramNames = (docs.params || [])
230
237
  .filter((/** @type {any} */ p) => !p.name.includes('.'))
231
- .map((/** @type {any} */ p) => p.required ? `${p.name}: ${p.type.split('|')[0].trim()}` : p.name);
238
+ .map((/** @type {any} */ p) =>
239
+ p.required ? `${p.name}: ${p.type.split('|')[0].trim()}` : p.name,
240
+ );
232
241
  if (paramNames.length > 0) {
233
242
  output.push(` ${paramNames.join(', ')}`);
234
243
  }
@@ -253,7 +262,7 @@ export async function formatHookBriefAll(coreDir) {
253
262
  const docPath = findHookDoc(coreDir, hookName);
254
263
  if (docPath) {
255
264
  try {
256
- const docs = await loadDocs(docPath);
265
+ const docs = await loadDocs(docPath, {root: 'hooks'});
257
266
  output.push(formatHookBrief(docs));
258
267
  } catch {
259
268
  output.push(`${hookName}\n (no docs)\n`);
@@ -57,7 +57,13 @@ export const RESPONSE_TYPES = {
57
57
  'component.detail.showcase',
58
58
  'component.detail.blocks',
59
59
  ],
60
- docs: ['docs.list', 'docs.index', 'docs.detail', 'docs.detail.section'],
60
+ docs: [
61
+ 'docs.list',
62
+ 'docs.index',
63
+ 'docs.detail',
64
+ 'docs.detail.section',
65
+ 'docs.node',
66
+ ],
61
67
  blog: ['blog.list', 'blog.detail'],
62
68
  discover: [
63
69
  'discover.list',
@@ -110,8 +116,9 @@ const EXAMPLES = {
110
116
  docs: [
111
117
  'astryx docs',
112
118
  'astryx docs spacing --json',
113
- 'astryx docs theme --index',
119
+ 'astryx docs theme',
114
120
  'astryx docs theme quick-start',
121
+ 'astryx docs cli/integrations --full',
115
122
  ],
116
123
  discover: ['astryx discover --json'],
117
124
  search: [
@@ -78,8 +78,9 @@ export function detectStylingSystem(targetDir: string): "stylex" | "tailwind" |
78
78
  * Generate the agent cheat sheet from live CLI metadata.
79
79
  *
80
80
  * Structured as: workflow (behavioral) → rules (error prevention) → CLI reference.
81
- * Templates are positioned first in the workflow to teach agents the
82
- * "look at reference code" reflex before writing any UI.
81
+ * Templates lead the workflow: every page starts from a scaffolded template,
82
+ * because the template already carries the frame and spacing that an agent
83
+ * composing from components would have to re-derive, and usually gets wrong.
83
84
  *
84
85
  * `stylingSystem` tailors the custom-styling guidance to what the project has
85
86
  * configured (see {@link detectStylingSystem}) so the agent never reaches for a
@@ -354,8 +354,9 @@ export function detectStylingSystem(targetDir) {
354
354
  * Generate the agent cheat sheet from live CLI metadata.
355
355
  *
356
356
  * Structured as: workflow (behavioral) → rules (error prevention) → CLI reference.
357
- * Templates are positioned first in the workflow to teach agents the
358
- * "look at reference code" reflex before writing any UI.
357
+ * Templates lead the workflow: every page starts from a scaffolded template,
358
+ * because the template already carries the frame and spacing that an agent
359
+ * composing from components would have to re-derive, and usually gets wrong.
359
360
  *
360
361
  * `stylingSystem` tailors the custom-styling guidance to what the project has
361
362
  * configured (see {@link detectStylingSystem}) so the agent never reaches for a
@@ -428,17 +429,19 @@ export function generateCompressedIndex(
428
429
  lines.push(' import "@astryxdesign/core/astryx.css";');
429
430
  lines.push('');
430
431
 
431
- // Workflow — `build` is the front door; discover before writing UI.
432
- lines.push("WORKFLOW — discover, don't guess. Before writing UI:");
433
- lines.push('1. `astryx build "<idea>"` — START HERE: returns a kit (closest [page] + [block]s + [component]s). No args = full playbook.');
434
- lines.push('2. `astryx template <name> [--skeleton]` — scaffold the [page]/[block]s it named, or study their layout. Templates are reference code.');
435
- lines.push('3. `astryx component <Name>` — props + examples for every component you use.');
432
+ // Workflow — `build` is the front door, and every page starts from the
433
+ // template it names.
434
+ lines.push('WORKFLOW — start every page from a template. Never lay out a page from scratch:');
435
+ lines.push('1. `astryx build "<idea>"` — START HERE: names the [page] template to start from (always one: the closest match, or the app shell), two other templates, and the [block]s + [component]s for parts it lacks. No args = full playbook.');
436
+ lines.push('2. `astryx template <name> <path>` — scaffold that template into your project. Keep its frame, gap and padding; replace its data, copy and sections; delete sections you do not need.');
437
+ lines.push('3. `astryx template <Block>` for a part the template lacks; `astryx component <Name>` for props + examples before you use or change a component.');
438
+ lines.push('Changing a page you already have? Keep it: skip step 2 and add blocks and components inside its sections.');
436
439
  lines.push('');
437
440
 
438
441
  // Rules — the top error-preventers.
439
442
  lines.push('RULES:');
440
443
  lines.push('- No <div> — components do all layout/spacing, page frame included.');
441
- lines.push('- Frame first: read `astryx docs layout` before writing any page or screen — page frame, region widths, breakpoint behavior.');
444
+ lines.push('- Frame first: the template you scaffold sets the page frame. Read `astryx docs layout` before you change it — region widths, breakpoint behavior.');
442
445
  lines.push('- Dense data = rows (Table, List/Item), never Card-wrapped list items; Card is for standalone widgets. Status = StatusDot/Token; Badge = counts only.');
443
446
  // Styling guidance tailored to the project's configured system — never
444
447
  // recommend a path that isn't compiled here (xstyle needs the StyleX compiler;
@@ -463,7 +466,7 @@ export function generateCompressedIndex(
463
466
  css: 'replace any raw <div>/<span> layout, imported .css/@apply, or hardcoded value (#hex, 16px) with the component or a token (var(--color-*|--spacing-*|…))',
464
467
  };
465
468
  lines.push(
466
- `- SELF-CHECK before you finish: re-read the file and ${selfCheckFix[stylingSystem] ?? selfCheckFix.css}. If unsure a component/prop exists, run \`astryx component <Name>\` / \`astryx search "<thing>"\`; don't hand-roll CSS.`,
469
+ `- SELF-CHECK before you finish: re-read the file and ${selfCheckFix[stylingSystem] ?? selfCheckFix.css}. Confirm the page kept its template's frame, gap and padding. If unsure a component/prop exists, run \`astryx component <Name>\` / \`astryx search "<thing>"\`; don't hand-roll CSS.`,
467
470
  );
468
471
  lines.push('');
469
472
 
@@ -486,6 +489,7 @@ export function generateCompressedIndex(
486
489
  if (resolvedTopics.length > 0) {
487
490
  lines.push(` docs <topic> ${resolvedTopics.join(', ')}`);
488
491
  }
492
+ lines.push(' docs cli commands, API reference, integration authoring (one level at a time)');
489
493
  lines.push(' swizzle <Name> eject component source for deep customization');
490
494
  lines.push(' upgrade --apply run after any Astryx or integration dependency bump');
491
495
  const appendCount = agentDocs.reduce(