@astryxdesign/cli 0.6.3 → 0.6.4-canary.10dd683

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 (643) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/README.md +117 -78
  3. package/api/blog/blog.doc.mjs +1 -0
  4. package/api/build/_adapter.d.mts +50 -0
  5. package/api/build/_adapter.mjs +60 -0
  6. package/api/build/build.doc.mjs +16 -9
  7. package/api/build/build.test.mjs +197 -8
  8. package/api/build/build.type.d.mts +91 -2
  9. package/api/build/build.type.mjs +52 -8
  10. package/api/build/help/help.d.mts +12 -5
  11. package/api/build/help/help.mjs +69 -6
  12. package/api/build/kit/kit.d.mts +4 -1
  13. package/api/build/kit/kit.mjs +165 -49
  14. package/api/build/kit/rank.d.mts +44 -0
  15. package/api/build/kit/rank.mjs +432 -0
  16. package/api/build/kit/rank.test.mjs +196 -0
  17. package/api/component/_adapter.d.mts +6 -12
  18. package/api/component/_adapter.mjs +20 -10
  19. package/api/component/component.doc.mjs +13 -3
  20. package/api/component/component.mjs +91 -14
  21. package/api/component/component.test.mjs +38 -0
  22. package/api/component/component.type.d.mts +22 -11
  23. package/api/component/component.type.mjs +32 -24
  24. package/api/component/detail/blocks/blocks.d.mts +2 -1
  25. package/api/component/detail/blocks/blocks.mjs +4 -3
  26. package/api/component/list/list.d.mts +0 -5
  27. package/api/component/list/list.mjs +40 -11
  28. package/api/discover/_adapter.d.mts +114 -6
  29. package/api/discover/_adapter.mjs +372 -17
  30. package/api/discover/_adapter.test.mjs +215 -0
  31. package/api/discover/_catalog-view.d.mts +115 -0
  32. package/api/discover/_catalog-view.mjs +203 -0
  33. package/api/discover/_catalog-view.test.mjs +128 -0
  34. package/api/discover/detail/detail.d.mts +18 -6
  35. package/api/discover/detail/detail.mjs +67 -13
  36. package/api/discover/detail/detail.test.mjs +85 -0
  37. package/api/discover/detail/item/item.d.mts +26 -0
  38. package/api/discover/detail/item/item.mjs +78 -0
  39. package/api/discover/detail/item/item.test.mjs +73 -0
  40. package/api/discover/discover.d.mts +3 -9
  41. package/api/discover/discover.doc.mjs +62 -18
  42. package/api/discover/discover.mjs +220 -36
  43. package/api/discover/discover.test.mjs +11 -2
  44. package/api/discover/discover.type.d.mts +150 -11
  45. package/api/discover/discover.type.mjs +107 -17
  46. package/api/discover/list/list.d.mts +20 -6
  47. package/api/discover/list/list.mjs +45 -12
  48. package/api/discover/list/list.test.mjs +46 -0
  49. package/api/discover/search/search.d.mts +18 -16
  50. package/api/discover/search/search.mjs +102 -56
  51. package/api/discover/search/search.test.mjs +144 -10
  52. package/api/docs/_adapter.d.mts +272 -41
  53. package/api/docs/_adapter.mjs +985 -108
  54. package/api/docs/compiled-topics.test.mjs +78 -0
  55. package/api/docs/detail/detail.mjs +22 -63
  56. package/api/docs/detail/section/section.d.mts +1 -1
  57. package/api/docs/detail/section/section.mjs +54 -19
  58. package/api/docs/detail/section/section.test.mjs +50 -0
  59. package/api/docs/docs.d.mts +10 -3
  60. package/api/docs/docs.doc.mjs +55 -16
  61. package/api/docs/docs.mjs +53 -10
  62. package/api/docs/docs.test.mjs +164 -4
  63. package/api/docs/docs.type.d.mts +221 -5
  64. package/api/docs/docs.type.mjs +153 -11
  65. package/api/docs/index/index.d.mts +18 -0
  66. package/api/docs/index/index.mjs +40 -0
  67. package/api/docs/index/index.test.mjs +62 -0
  68. package/api/docs/integration-tree.test.mjs +555 -0
  69. package/api/docs/integrationDocs.test.mjs +114 -8
  70. package/api/docs/list/list.mjs +28 -12
  71. package/api/docs/node/node.d.mts +43 -0
  72. package/api/docs/node/node.mjs +192 -0
  73. package/api/docs/reference-blocks.test.mjs +406 -0
  74. package/api/doctor/doctor.d.mts +99 -1
  75. package/api/doctor/doctor.doc.mjs +1 -0
  76. package/api/doctor/doctor.mjs +548 -1
  77. package/api/doctor/doctor.test.mjs +610 -1
  78. package/api/gap-report/gap-report.doc.mjs +8 -4
  79. package/api/hook/_adapter.mjs +19 -5
  80. package/api/hook/hook.doc.mjs +1 -0
  81. package/api/hook/hook.type.d.mts +3 -3
  82. package/api/hook/hook.type.mjs +11 -11
  83. package/api/hook/list/list.d.mts +2 -2
  84. package/api/hook/list/list.mjs +69 -17
  85. package/api/index.d.mts +1 -1
  86. package/api/index.mjs +1 -0
  87. package/api/init/init.doc.mjs +6 -1
  88. package/api/init/init.test.mjs +41 -1
  89. package/api/init/remove/remove.mjs +1 -1
  90. package/api/init/run/run.mjs +20 -10
  91. package/api/integration/add-contribution.component-names.test.mjs +120 -0
  92. package/api/integration/add-contribution.d.mts +2 -1
  93. package/api/integration/add-contribution.mjs +130 -15
  94. package/api/integration/add-contribution.test.mjs +258 -7
  95. package/api/integration/add-helpers.d.mts +5 -2
  96. package/api/integration/add-helpers.mjs +36 -9
  97. package/api/integration/add-theme.mjs +34 -64
  98. package/api/integration/add-theme.test.mjs +105 -21
  99. package/api/integration/authoring-checks.mjs +138 -28
  100. package/api/integration/authoring-checks.test.mjs +179 -7
  101. package/api/integration/authoring-checks.type.mjs +6 -1
  102. package/api/integration/integration-authoring.type.d.mts +3 -1
  103. package/api/integration/integration-authoring.type.mjs +2 -0
  104. package/api/integration/integration-block-exports.test.mjs +10 -6
  105. package/api/integration/integrationAdd.doc.mjs +14 -4
  106. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  107. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  108. package/api/integration/integrationAddComponent.doc.mjs +2 -1
  109. package/api/integration/integrationAddDoc.doc.mjs +8 -1
  110. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  111. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  112. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  113. package/api/integration/integrationDocConflicts.doc.mjs +2 -1
  114. package/api/integration/integrationPackCheck.doc.mjs +2 -1
  115. package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
  116. package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
  117. package/api/integration/pack-check.mjs +83 -7
  118. package/api/integration/pack-check.test.mjs +387 -47
  119. package/api/integration/pack-check.type.d.mts +26 -2
  120. package/api/integration/pack-check.type.mjs +14 -1
  121. package/api/integration/summarizeIssues.doc.mjs +1 -0
  122. package/api/integration/template-conflict-compatibility.test.mjs +73 -0
  123. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  124. package/api/integration/validate-integration.mjs +52 -102
  125. package/api/integration/validate-integration.test.mjs +179 -26
  126. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  127. package/api/integration/validateIntegration.doc.mjs +3 -2
  128. package/api/json/assertResponse.doc.mjs +1 -0
  129. package/api/json/envelope-types.test.mjs +76 -0
  130. package/api/json/index.ts +2 -0
  131. package/api/json/isError.doc.mjs +1 -0
  132. package/api/json/parseResponse.doc.mjs +3 -2
  133. package/api/layout/_adapter.mjs +20 -5
  134. package/api/layout/expand/expand.mjs +7 -5
  135. package/api/layout/expand/expand.path-safety.test.mjs +53 -0
  136. package/api/layout/grammar/grammar.mjs +2 -1
  137. package/api/layout/layoutCheck.doc.mjs +1 -0
  138. package/api/layout/layoutExpand.doc.mjs +2 -1
  139. package/api/layout/layoutGrammar.doc.mjs +1 -0
  140. package/api/search/search-return-type.test.mjs +54 -0
  141. package/api/search/search.d.mts +62 -11
  142. package/api/search/search.doc.mjs +8 -2
  143. package/api/search/search.mjs +471 -83
  144. package/api/search/search.test.mjs +124 -1
  145. package/api/search/search.type.d.mts +15 -3
  146. package/api/search/search.type.mjs +5 -2
  147. package/api/swizzle/copy/copy.mjs +28 -11
  148. package/api/swizzle/swizzle.doc.mjs +2 -1
  149. package/api/swizzle/swizzle.type.d.mts +2 -2
  150. package/api/swizzle/swizzle.type.mjs +2 -2
  151. package/api/template/copy/copy.mjs +17 -23
  152. package/api/template/copy/copy.test.mjs +17 -0
  153. package/api/template/list/list.mjs +1 -0
  154. package/api/template/table-floating-bulk-actions.test.mjs +66 -0
  155. package/api/template/template-integration.test.mjs +1072 -3
  156. package/api/template/template-suffix.test.mjs +41 -21
  157. package/api/template/template.d.mts +1 -1
  158. package/api/template/template.doc.mjs +30 -8
  159. package/api/template/template.mjs +45 -8
  160. package/api/template/template.type.d.mts +12 -14
  161. package/api/template/template.type.mjs +15 -14
  162. package/api/theme/_adapter.d.mts +2 -3
  163. package/api/theme/_adapter.mjs +4 -5
  164. package/api/theme/add/add.binary.test.mjs +84 -0
  165. package/api/theme/add/add.mjs +31 -22
  166. package/api/theme/add/add.rollback.test.mjs +158 -0
  167. package/api/theme/add/add.staging.test.mjs +83 -0
  168. package/api/theme/add/add.test.mjs +14 -1
  169. package/api/theme/build/build.family.test.mjs +7 -12
  170. package/api/theme/build/build.mjs +140 -59
  171. package/api/theme/build/build.public-component-vars.test.mjs +1 -1
  172. package/api/theme/build/build.receipt-doc.test.mjs +111 -0
  173. package/api/theme/build/build.rollback.test.mjs +148 -0
  174. package/api/theme/build/build.test.mjs +127 -0
  175. package/api/theme/build/font-warning.mjs +3 -3
  176. package/api/theme/build/font-warning.test.mjs +5 -2
  177. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  178. package/api/theme/integration-themes.test.mjs +39 -28
  179. package/api/theme/list/list.test.mjs +19 -20
  180. package/api/theme/listThemes.doc.mjs +6 -5
  181. package/api/theme/palette/generate/generate.mjs +8 -3
  182. package/api/theme/palette/generate/generate.test.mjs +96 -0
  183. package/api/theme/palette/generate/generator.d.mts +10 -13
  184. package/api/theme/palette/generate/generator.mjs +15 -4
  185. package/api/theme/palette/generate/generator.test.mjs +10 -0
  186. package/api/theme/template/template.mjs +11 -2
  187. package/api/theme/template/template.test.mjs +20 -0
  188. package/api/theme/theme.type.d.mts +170 -11
  189. package/api/theme/theme.type.mjs +94 -27
  190. package/api/theme/themeAdd.doc.mjs +4 -3
  191. package/api/theme/themeBuild.doc.mjs +8 -4
  192. package/api/theme/themeList.doc.mjs +6 -3
  193. package/api/theme/themeListAvailable.doc.mjs +5 -3
  194. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  195. package/api/theme/themeTargets.doc.mjs +1 -0
  196. package/api/theme/themeTemplate.doc.mjs +6 -2
  197. package/api/upgrade/_adapter.d.mts +32 -5
  198. package/api/upgrade/_adapter.mjs +139 -22
  199. package/api/upgrade/list/list.mjs +2 -1
  200. package/api/upgrade/list/list.test.mjs +73 -0
  201. package/api/upgrade/project-context.test.mjs +272 -0
  202. package/api/upgrade/provider-agreement.test.mjs +152 -0
  203. package/api/upgrade/run/run.mjs +356 -59
  204. package/api/upgrade/status/status.mjs +2 -2
  205. package/api/upgrade/upgrade.doc.mjs +12 -5
  206. package/api/upgrade/upgrade.type.d.mts +43 -5
  207. package/api/upgrade/upgrade.type.mjs +27 -11
  208. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  209. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  210. package/assets/codemods/integration-discovery.mjs +48 -4
  211. package/assets/codemods/integration-discovery.test.mjs +73 -0
  212. package/assets/codemods/integration-runner.mjs +56 -4
  213. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  214. package/assets/codemods/registry.mjs +1 -0
  215. package/assets/codemods/run-codemod.mjs +177 -34
  216. package/assets/codemods/runner.mjs +350 -102
  217. package/assets/codemods/term-log.mjs +32 -8
  218. package/assets/codemods/term-log.test.mjs +19 -1
  219. package/assets/codemods/transform-prop.mjs +109 -0
  220. package/assets/codemods/transform-prop.test.mjs +95 -0
  221. package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
  222. package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
  223. package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
  224. package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
  225. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
  226. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
  227. package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
  228. package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
  229. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  230. package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  231. package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
  232. package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
  233. package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
  234. package/assets/docs/README.md +9 -0
  235. package/assets/docs/authoring.doc.mjs +14 -0
  236. package/assets/docs/getting-started.doc.mjs +2 -2
  237. package/assets/docs/internationalization.doc.mjs +7 -5
  238. package/assets/docs/layout.doc.dense.mjs +2 -2
  239. package/assets/docs/layout.doc.mjs +1 -1
  240. package/assets/docs/principles.doc.mjs +6 -6
  241. package/assets/docs/styling-libraries.doc.mjs +4 -4
  242. package/assets/docs/styling.doc.mjs +4 -4
  243. package/assets/docs/theme.doc.mjs +5 -5
  244. package/assets/docs/tokens.doc.mjs +1 -1
  245. package/assets/docs/tree/api.doc.mjs +30 -0
  246. package/assets/docs/tree/cli.doc.mjs +23 -0
  247. package/assets/docs/tree/commands.doc.mjs +25 -0
  248. package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +144 -26
  249. package/assets/docs/tree/integrations.test.mjs +62 -0
  250. package/assets/docs/tree/writing-docs.doc.mjs +286 -0
  251. package/assets/docs/working-with-ai.doc.mjs +4 -4
  252. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
  253. package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
  254. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  255. package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
  256. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  257. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  258. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
  259. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
  260. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
  261. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
  262. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
  263. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
  264. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
  265. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
  266. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
  267. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
  268. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
  269. package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
  270. package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
  271. package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
  272. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
  273. package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
  274. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  275. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
  276. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
  277. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
  278. package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
  279. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
  280. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
  281. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
  282. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
  283. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
  284. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
  285. package/assets/templates/pages/table-tree/page.tsx +1704 -0
  286. package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
  287. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  288. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  289. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  290. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  291. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  292. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  293. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  294. package/authoring/_shared/contract.ts +22 -0
  295. package/authoring/codemod/codemod.doc.mjs +7 -2
  296. package/authoring/codemod/parse.d.mts +8 -8
  297. package/authoring/codemod/parse.mjs +8 -6
  298. package/authoring/codemod/type.ts +12 -0
  299. package/authoring/config/config.doc.mjs +10 -2
  300. package/authoring/config/debug-composition.test.mjs +92 -0
  301. package/authoring/config/parse.d.mts +15 -13
  302. package/authoring/config/parse.mjs +27 -8
  303. package/authoring/config/parse.test.mjs +8 -0
  304. package/authoring/config/type.ts +29 -6
  305. package/authoring/debug/debug.doc.d.mts +11 -0
  306. package/authoring/debug/debug.doc.mjs +182 -0
  307. package/authoring/debug/parse.d.mts +8 -8
  308. package/authoring/debug/parse.mjs +3 -3
  309. package/authoring/discover/discover.doc.d.mts +13 -0
  310. package/authoring/discover/discover.doc.mjs +138 -0
  311. package/authoring/discover/parse.d.mts +24 -0
  312. package/authoring/discover/parse.mjs +128 -0
  313. package/authoring/discover/parse.test.mjs +124 -0
  314. package/authoring/discover/type.ts +87 -0
  315. package/authoring/doctypes/_schema.d.mts +790 -23
  316. package/authoring/doctypes/_schema.mjs +543 -39
  317. package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
  318. package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
  319. package/authoring/doctypes/base/type.ts +41 -0
  320. package/authoring/doctypes/command/command.doc.mjs +4 -3
  321. package/authoring/doctypes/command/parse.d.mts +2 -2
  322. package/authoring/doctypes/command/parse.mjs +1 -1
  323. package/authoring/doctypes/command/type.ts +5 -4
  324. package/authoring/doctypes/component/component.doc.mjs +6 -3
  325. package/authoring/doctypes/component/parse.d.mts +2 -2
  326. package/authoring/doctypes/component/parse.mjs +1 -1
  327. package/authoring/doctypes/component/type.ts +6 -5
  328. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  329. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  330. package/authoring/doctypes/enum/parse.d.mts +2 -2
  331. package/authoring/doctypes/enum/parse.mjs +1 -1
  332. package/authoring/doctypes/enum/type.ts +4 -2
  333. package/authoring/doctypes/function/function.doc.mjs +7 -2
  334. package/authoring/doctypes/function/parse.d.mts +2 -2
  335. package/authoring/doctypes/function/parse.mjs +1 -1
  336. package/authoring/doctypes/function/type.ts +9 -4
  337. package/authoring/doctypes/hook/hook.doc.mjs +4 -0
  338. package/authoring/doctypes/hook/parse.d.mts +2 -2
  339. package/authoring/doctypes/hook/parse.mjs +1 -1
  340. package/authoring/doctypes/hook/type.ts +5 -4
  341. package/authoring/doctypes/legacy.d.mts +8 -6
  342. package/authoring/doctypes/legacy.mjs +5 -4
  343. package/authoring/doctypes/load-contract.test.mjs +233 -0
  344. package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
  345. package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
  346. package/authoring/doctypes/namespace/parse.d.mts +12 -0
  347. package/authoring/doctypes/namespace/parse.mjs +25 -0
  348. package/authoring/doctypes/namespace/parse.test.mjs +163 -0
  349. package/authoring/doctypes/namespace/type.ts +74 -0
  350. package/authoring/doctypes/parse.d.mts +22 -18
  351. package/authoring/doctypes/parse.mjs +22 -11
  352. package/authoring/doctypes/parse.test.mjs +77 -3
  353. package/authoring/doctypes/reference/parse.d.mts +2 -2
  354. package/authoring/doctypes/reference/parse.mjs +8 -5
  355. package/authoring/doctypes/reference/reference.doc.mjs +48 -6
  356. package/authoring/doctypes/reference/type.ts +70 -7
  357. package/authoring/doctypes/schema/parse.d.mts +2 -2
  358. package/authoring/doctypes/schema/parse.mjs +1 -1
  359. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  360. package/authoring/doctypes/schema/type.ts +4 -4
  361. package/authoring/doctypes/template/parse.d.mts +94 -1
  362. package/authoring/doctypes/template/parse.mjs +40 -2
  363. package/authoring/doctypes/template/parse.test.mjs +26 -2
  364. package/authoring/doctypes/template/template.doc.mjs +13 -3
  365. package/authoring/doctypes/template/type.ts +13 -2
  366. package/authoring/doctypes/theme/parse.d.mts +35 -0
  367. package/authoring/doctypes/theme/parse.mjs +76 -0
  368. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  369. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  370. package/authoring/doctypes/theme/type.ts +42 -0
  371. package/authoring/doctypes/types.ts +12 -10
  372. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  373. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  374. package/authoring/gap-report/parse.d.mts +10 -10
  375. package/authoring/gap-report/parse.mjs +6 -6
  376. package/authoring/gap-report/type.ts +1 -1
  377. package/authoring/identity/identity.doc.d.mts +9 -0
  378. package/authoring/identity/identity.doc.mjs +61 -0
  379. package/authoring/identity/type.ts +132 -0
  380. package/authoring/index.d.mts +3 -0
  381. package/authoring/index.d.ts +62 -17
  382. package/authoring/index.mjs +4 -1
  383. package/authoring/integration/integration.doc.mjs +15 -8
  384. package/authoring/integration/parse.d.mts +2 -2
  385. package/authoring/integration/parse.mjs +1 -1
  386. package/authoring/integration/parse.test.mjs +10 -1
  387. package/authoring/integration/schema.d.mts +6 -4
  388. package/authoring/integration/schema.mjs +9 -3
  389. package/authoring/integration/type.ts +19 -8
  390. package/authoring/shadcn/receipt.d.mts +6 -6
  391. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  392. package/clients/cli/command-load-failure.test.mjs +83 -0
  393. package/clients/cli/commands/blog.doc.mjs +1 -1
  394. package/clients/cli/commands/blog.mjs +23 -8
  395. package/clients/cli/commands/blog.test.mjs +42 -1
  396. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  397. package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
  398. package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
  399. package/clients/cli/commands/build-theme.mjs +16 -50
  400. package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
  401. package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
  402. package/clients/cli/commands/build.doc.mjs +16 -8
  403. package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
  404. package/clients/cli/commands/build.mjs +137 -114
  405. package/clients/cli/commands/build.playbook.test.mjs +75 -0
  406. package/clients/cli/commands/build.text-fields.test.mjs +81 -0
  407. package/clients/cli/commands/component/index.mjs +3 -8
  408. package/clients/cli/commands/component-ownership.test.mjs +3 -3
  409. package/clients/cli/commands/component-package.test.mjs +46 -0
  410. package/clients/cli/commands/component-resolution.test.mjs +21 -0
  411. package/clients/cli/commands/component.doc.mjs +1 -1
  412. package/clients/cli/commands/component.test.mjs +19 -0
  413. package/clients/cli/commands/detail-levels.test.mjs +2 -2
  414. package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
  415. package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
  416. package/clients/cli/commands/discover.doc.mjs +55 -9
  417. package/clients/cli/commands/discover.mjs +393 -118
  418. package/clients/cli/commands/discover.sources.test.mjs +267 -0
  419. package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
  420. package/clients/cli/commands/docs.doc.mjs +28 -6
  421. package/clients/cli/commands/docs.mjs +240 -26
  422. package/clients/cli/commands/docs.test.mjs +193 -1
  423. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  424. package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
  425. package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
  426. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  427. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  428. package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
  429. package/clients/cli/commands/doctor-integration.test.mjs +90 -8
  430. package/clients/cli/commands/doctor.doc.mjs +1 -1
  431. package/clients/cli/commands/doctor.mjs +59 -32
  432. package/clients/cli/commands/doctor.test.mjs +42 -0
  433. package/clients/cli/commands/gap-report.doc.mjs +17 -6
  434. package/clients/cli/commands/gap-report.test.mjs +72 -0
  435. package/clients/cli/commands/hook/index.mjs +7 -17
  436. package/clients/cli/commands/hook.doc.mjs +1 -1
  437. package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
  438. package/clients/cli/commands/init.doc.mjs +20 -9
  439. package/clients/cli/commands/init.flag-help.test.mjs +153 -0
  440. package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
  441. package/clients/cli/commands/integration-add.doc.mjs +32 -6
  442. package/clients/cli/commands/integration-authoring.test.mjs +13 -9
  443. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  444. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  445. package/clients/cli/commands/integration.doc.mjs +1 -1
  446. package/clients/cli/commands/integration.mjs +1 -0
  447. package/clients/cli/commands/interactive-guard.test.mjs +101 -24
  448. package/clients/cli/commands/json-contract.test.mjs +33 -0
  449. package/clients/cli/commands/layout-check.doc.mjs +15 -4
  450. package/clients/cli/commands/layout-expand.doc.mjs +22 -5
  451. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  452. package/clients/cli/commands/layout.doc.mjs +3 -3
  453. package/clients/cli/commands/layout.mjs +21 -9
  454. package/clients/cli/commands/layout.path-help.test.mjs +33 -0
  455. package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
  456. package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
  457. package/clients/cli/commands/manifest.doc.mjs +1 -1
  458. package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
  459. package/clients/cli/commands/search.doc.mjs +7 -4
  460. package/clients/cli/commands/search.mjs +28 -9
  461. package/clients/cli/commands/search.test.mjs +75 -0
  462. package/clients/cli/commands/setup-nudge.test.mjs +6 -0
  463. package/clients/cli/commands/swizzle.doc.mjs +3 -2
  464. package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
  465. package/clients/cli/commands/template.doc.mjs +52 -13
  466. package/clients/cli/commands/template.flag-help.test.mjs +117 -0
  467. package/clients/cli/commands/template.mjs +4 -91
  468. package/clients/cli/commands/template.path-help.test.mjs +40 -0
  469. package/clients/cli/commands/text-json-parity.test.mjs +719 -0
  470. package/clients/cli/commands/theme-add.doc.mjs +4 -3
  471. package/clients/cli/commands/theme-build.doc.mjs +8 -7
  472. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  473. package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
  474. package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
  475. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  476. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  477. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  478. package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
  479. package/clients/cli/commands/theme-template.doc.mjs +2 -2
  480. package/clients/cli/commands/theme.doc.mjs +1 -1
  481. package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
  482. package/clients/cli/commands/upgrade.doc.mjs +22 -10
  483. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  484. package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
  485. package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
  486. package/clients/cli/commands/upgrade.mjs +29 -7
  487. package/clients/cli/formatters/index.mjs +164 -1
  488. package/clients/cli/formatters/index.test.mjs +97 -0
  489. package/clients/cli/index.mjs +21 -30
  490. package/clients/cli/latest-version-env.test.mjs +50 -0
  491. package/clients/cli/lib/cli-error.test.mjs +7 -0
  492. package/clients/cli/lib/component-format.mjs +9 -9
  493. package/clients/cli/lib/component-format.test.mjs +1 -1
  494. package/clients/cli/lib/define-command.mjs +32 -6
  495. package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
  496. package/clients/cli/lib/exit-codes.test.mjs +97 -0
  497. package/clients/cli/lib/hook-format.mjs +19 -10
  498. package/clients/cli/lib/json-shim.mjs +38 -2
  499. package/clients/cli/lib/json-shim.test.mjs +83 -0
  500. package/clients/cli/lib/manifest.d.ts +2 -0
  501. package/clients/cli/lib/manifest.mjs +37 -2
  502. package/clients/cli/lib/manifest.test.mjs +17 -0
  503. package/foundation/agent-docs/agent-docs.d.mts +7 -2
  504. package/foundation/agent-docs/agent-docs.mjs +82 -12
  505. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
  506. package/foundation/agent-docs/agent-docs.test.mjs +19 -1
  507. package/foundation/config/integration-debug.test.mjs +28 -3
  508. package/foundation/config/project-themes.test.mjs +11 -19
  509. package/foundation/config/project.d.mts +20 -11
  510. package/foundation/config/project.mjs +263 -91
  511. package/foundation/config/project.test.mjs +270 -21
  512. package/foundation/discovery/authoring-self-docs.d.mts +87 -0
  513. package/foundation/discovery/authoring-self-docs.mjs +237 -0
  514. package/foundation/discovery/authoring-self-docs.test.mjs +170 -0
  515. package/foundation/discovery/authoring-surface.d.mts +74 -0
  516. package/foundation/discovery/authoring-surface.mjs +525 -0
  517. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  518. package/foundation/discovery/cli-self-docs.d.mts +119 -0
  519. package/foundation/discovery/cli-self-docs.mjs +490 -0
  520. package/foundation/discovery/cli-self-docs.test.mjs +375 -0
  521. package/foundation/discovery/component-discovery.d.mts +39 -1
  522. package/foundation/discovery/component-discovery.mjs +50 -1
  523. package/foundation/discovery/component-loader.d.mts +35 -38
  524. package/foundation/discovery/component-loader.mjs +53 -222
  525. package/foundation/discovery/docs-discovery.d.mts +119 -11
  526. package/foundation/discovery/docs-discovery.mjs +423 -108
  527. package/foundation/discovery/docs-discovery.test.mjs +365 -20
  528. package/foundation/discovery/docs-output-budget.d.mts +28 -0
  529. package/foundation/discovery/docs-output-budget.mjs +50 -0
  530. package/foundation/discovery/docs-section-key.d.mts +116 -0
  531. package/foundation/discovery/docs-section-key.mjs +322 -0
  532. package/foundation/discovery/docs-section-key.test.mjs +246 -0
  533. package/foundation/discovery/template-adapter.d.mts +113 -11
  534. package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
  535. package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
  536. package/foundation/discovery/template-adapter.mjs +774 -83
  537. package/foundation/discovery/template-adapter.test.mjs +57 -0
  538. package/foundation/discovery/template-conflict-release.d.mts +13 -0
  539. package/foundation/discovery/template-conflict-release.mjs +40 -0
  540. package/foundation/discovery/template-conflict-release.test.mjs +40 -0
  541. package/foundation/discovery/theme-discovery.d.mts +67 -7
  542. package/foundation/discovery/theme-discovery.mjs +916 -186
  543. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  544. package/foundation/discovery/theming-targets.test.mjs +4 -0
  545. package/foundation/doc-compiler/bundle.d.mts +47 -0
  546. package/foundation/doc-compiler/bundle.mjs +278 -0
  547. package/foundation/doc-compiler/bundle.test.mjs +266 -0
  548. package/foundation/doc-compiler/compile.d.mts +343 -0
  549. package/foundation/doc-compiler/compile.mjs +558 -0
  550. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  551. package/foundation/doc-compiler/diagnostics.mjs +305 -0
  552. package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
  553. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  554. package/foundation/doc-compiler/import.d.mts +24 -0
  555. package/foundation/doc-compiler/import.mjs +59 -0
  556. package/foundation/doc-compiler/inputs.d.mts +102 -0
  557. package/foundation/doc-compiler/inputs.mjs +291 -0
  558. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  559. package/foundation/doc-compiler/ir.d.mts +22 -0
  560. package/foundation/doc-compiler/ir.mjs +471 -0
  561. package/foundation/doc-compiler/lenses.d.mts +36 -0
  562. package/foundation/doc-compiler/lenses.mjs +173 -0
  563. package/foundation/doc-compiler/links.d.mts +162 -0
  564. package/foundation/doc-compiler/links.mjs +294 -0
  565. package/foundation/doc-compiler/links.test.mjs +192 -0
  566. package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
  567. package/foundation/doc-compiler/overlays.d.mts +37 -0
  568. package/foundation/doc-compiler/overlays.mjs +206 -0
  569. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  570. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  571. package/foundation/doc-compiler/read.d.mts +127 -0
  572. package/foundation/doc-compiler/read.mjs +325 -0
  573. package/foundation/doc-compiler/read.test.mjs +313 -0
  574. package/foundation/doc-compiler/source.d.mts +33 -0
  575. package/foundation/doc-compiler/source.mjs +128 -0
  576. package/foundation/doc-compiler/tree.d.mts +288 -0
  577. package/foundation/doc-compiler/tree.mjs +876 -0
  578. package/foundation/doc-compiler/tree.test.mjs +598 -0
  579. package/foundation/fs/file-protection.d.mts +33 -0
  580. package/foundation/fs/file-protection.mjs +825 -0
  581. package/foundation/fs/file-protection.test.mjs +250 -0
  582. package/foundation/fs/module-loader.d.mts +1 -0
  583. package/foundation/fs/module-loader.mjs +50 -1
  584. package/foundation/fs/module-loader.stdout.test.mjs +332 -0
  585. package/foundation/fs/path-safety.d.mts +3 -2
  586. package/foundation/fs/path-safety.mjs +49 -19
  587. package/foundation/fs/path-safety.test.mjs +50 -0
  588. package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
  589. package/foundation/identity/provider-identity.d.mts +90 -0
  590. package/foundation/identity/provider-identity.mjs +320 -0
  591. package/foundation/identity/provider-identity.test.mjs +254 -0
  592. package/foundation/identity/providers.d.mts +7 -0
  593. package/foundation/identity/providers.mjs +16 -0
  594. package/foundation/integrations/autolink.d.mts +58 -1
  595. package/foundation/integrations/autolink.mjs +143 -45
  596. package/foundation/integrations/autolink.test.mjs +1 -1
  597. package/foundation/integrations/cli-requirement.d.mts +45 -0
  598. package/foundation/integrations/cli-requirement.mjs +154 -0
  599. package/foundation/integrations/cli-requirement.test.mjs +84 -0
  600. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  601. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  602. package/foundation/integrations/contribution-inventory.d.mts +3 -2
  603. package/foundation/integrations/contribution-inventory.mjs +27 -24
  604. package/foundation/integrations/contribution-inventory.test.mjs +86 -27
  605. package/foundation/integrations/integration-warnings.d.mts +9 -2
  606. package/foundation/integrations/integration-warnings.mjs +52 -21
  607. package/foundation/integrations/integration-warnings.test.mjs +74 -1
  608. package/foundation/integrations/integrations.d.mts +63 -3
  609. package/foundation/integrations/integrations.mjs +122 -9
  610. package/foundation/integrations/integrations.test.mjs +415 -1
  611. package/foundation/integrations/provider-conflicts.test.mjs +125 -0
  612. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  613. package/foundation/integrations/provider-resolution.d.mts +152 -0
  614. package/foundation/integrations/provider-resolution.mjs +576 -0
  615. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  616. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  617. package/foundation/integrations/theme-descriptor.mjs +44 -0
  618. package/foundation/integrations/validate-contributions.d.mts +2 -0
  619. package/foundation/integrations/validate-contributions.mjs +131 -29
  620. package/foundation/response/base.d.ts +8 -4
  621. package/foundation/response/error-codes.d.mts +3 -1
  622. package/foundation/response/error-codes.d.ts +2 -0
  623. package/foundation/response/error-codes.doc.mjs +13 -4
  624. package/foundation/response/error-codes.mjs +8 -2
  625. package/foundation/response/error-codes.test.mjs +137 -10
  626. package/foundation/response/json-contract.test.mjs +57 -17
  627. package/foundation/response/json.d.mts +4 -2
  628. package/foundation/response/json.mjs +8 -10
  629. package/foundation/response/response-types.doc.d.mts +5 -1
  630. package/foundation/response/response-types.doc.mjs +41 -21
  631. package/foundation/response/response-types.doc.test.mjs +158 -0
  632. package/foundation/response/response.doc.mjs +1 -1
  633. package/foundation/text/string-utils.d.mts +8 -0
  634. package/foundation/text/string-utils.mjs +40 -10
  635. package/foundation/xle/expand.d.mts +2 -0
  636. package/foundation/xle/expand.mjs +4 -3
  637. package/foundation/xle/expand.test.mjs +54 -0
  638. package/foundation/xle/xle.test.mjs +13 -0
  639. package/package.json +10 -11
  640. package/assets/templates/themes/manifest.json +0 -95
  641. package/clients/cli/lib/update-check.mjs +0 -83
  642. package/clients/cli/lib/update-check.test.mjs +0 -137
  643. package/clients/cli/update-hint-commands.test.mjs +0 -54
@@ -1,22 +1,31 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
3
  /**
4
- * @file Path-safety regression tests for `--agent-docs-path`.
4
+ * @file Path-safety regression tests for agent-doc writes.
5
5
  *
6
6
  * `installAgentDocs(targetDir, {paths})` previously joined each path
7
7
  * onto `targetDir` with no validation, so:
8
8
  * - `../OUT.md` wrote outside `targetDir`
9
9
  * - `/tmp/x.md` was silently re-rooted under `targetDir`
10
10
  *
11
- * Both cases now throw PathSafetyError before any file is touched.
11
+ * Auto-detected and preset files were never checked at all, so a `CLAUDE.md`
12
+ * or `.claude/` symlinked out of the project had the block written through
13
+ * it. Every case now throws PathSafetyError before any file is touched.
14
+ *
15
+ * `removeAgentDocs` (`init --remove-agents`) stripped or deleted a block
16
+ * through the same kind of link and reported success. It now refuses with
17
+ * `ERR_PATH_TRAVERSAL` before any file is touched.
12
18
  */
13
19
 
14
- import {describe, it, expect, beforeEach, afterEach} from 'vitest';
20
+ import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
15
21
  import * as fs from 'node:fs';
16
22
  import * as path from 'node:path';
17
23
  import * as os from 'node:os';
18
- import {installAgentDocs} from './agent-docs.mjs';
24
+ import {installAgentDocs, removeAgentDocs} from './agent-docs.mjs';
19
25
  import {PathSafetyError} from '../fs/path-safety.mjs';
26
+ import {runCli} from '../../test-utils/run-cli.mjs';
27
+
28
+ const BLOCK = '<!-- ASTRYX:START -->\nmanaged\n<!-- ASTRYX:END -->';
20
29
 
21
30
  let tmpDir;
22
31
  beforeEach(() => {
@@ -26,6 +35,28 @@ afterEach(() => {
26
35
  fs.rmSync(tmpDir, {recursive: true, force: true});
27
36
  });
28
37
 
38
+ /** A project dir plus a sibling dir outside it. */
39
+ function layout() {
40
+ const project = path.join(tmpDir, 'project');
41
+ const outside = path.join(tmpDir, 'outside');
42
+ fs.mkdirSync(project, {recursive: true});
43
+ fs.mkdirSync(outside, {recursive: true});
44
+ return {project, outside};
45
+ }
46
+
47
+ /**
48
+ * @param {() => unknown} fn
49
+ * @returns {unknown} what `fn` threw
50
+ */
51
+ function thrownBy(fn) {
52
+ try {
53
+ fn();
54
+ } catch (err) {
55
+ return err;
56
+ }
57
+ throw new Error('expected a throw');
58
+ }
59
+
29
60
  describe('installAgentDocs path safety', () => {
30
61
  it('rejects --agent-docs-path that escapes the target directory', () => {
31
62
  const target = path.join(tmpDir, 'project');
@@ -64,3 +95,234 @@ describe('installAgentDocs path safety', () => {
64
95
  expect(fs.existsSync(path.join(tmpDir, 'escaped.md'))).toBe(false);
65
96
  });
66
97
  });
98
+
99
+ describe('installAgentDocs never writes through a symlink out of the project', () => {
100
+ it('refuses an auto-detected file that links outside', () => {
101
+ const {project, outside} = layout();
102
+ const shared = path.join(outside, 'CLAUDE.md');
103
+ fs.writeFileSync(shared, '# Shared\n');
104
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
105
+
106
+ expect(() => installAgentDocs(project, {renderedBlock: BLOCK})).toThrow(
107
+ /outside the project root/,
108
+ );
109
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('# Shared\n');
110
+ });
111
+
112
+ it('refuses a preset file reached through a symlinked directory', () => {
113
+ const {project, outside} = layout();
114
+ fs.symlinkSync(outside, path.join(project, '.claude'));
115
+
116
+ expect(() =>
117
+ installAgentDocs(project, {agent: 'claude', renderedBlock: BLOCK}),
118
+ ).toThrow(PathSafetyError);
119
+ expect(fs.readdirSync(outside)).toEqual([]);
120
+ });
121
+
122
+ it('refuses an existing preset file that links outside', () => {
123
+ const {project, outside} = layout();
124
+ const shared = path.join(outside, 'rules');
125
+ fs.writeFileSync(shared, 'rules\n');
126
+ fs.symlinkSync(shared, path.join(project, '.cursorrules'));
127
+
128
+ expect(() =>
129
+ installAgentDocs(project, {agent: 'cursor', renderedBlock: BLOCK}),
130
+ ).toThrow(PathSafetyError);
131
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('rules\n');
132
+ });
133
+
134
+ it('writes nothing when any file of the set escapes', () => {
135
+ const {project, outside} = layout();
136
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), '# Agents\n');
137
+ const shared = path.join(outside, 'CLAUDE.md');
138
+ fs.writeFileSync(shared, '# Shared\n');
139
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
140
+
141
+ expect(() => installAgentDocs(project, {renderedBlock: BLOCK})).toThrow(
142
+ PathSafetyError,
143
+ );
144
+ expect(fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8')).toBe(
145
+ '# Agents\n',
146
+ );
147
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('# Shared\n');
148
+ });
149
+
150
+ it('refuses to refresh a managed block that lives outside', () => {
151
+ const {project, outside} = layout();
152
+ const shared = path.join(outside, 'CLAUDE.md');
153
+ fs.writeFileSync(shared, `# Shared\n\n${BLOCK.replace('managed', 'old')}\n`);
154
+ const before = fs.readFileSync(shared, 'utf-8');
155
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
156
+
157
+ expect(() =>
158
+ installAgentDocs(project, {onlyReplace: true, renderedBlock: BLOCK}),
159
+ ).toThrow(PathSafetyError);
160
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(before);
161
+ });
162
+
163
+ it('refuses to strip a duplicate block from a wrapper that links outside', () => {
164
+ const {project, outside} = layout();
165
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), `# Agents\n\n${BLOCK}\n`);
166
+ const shared = path.join(outside, 'CLAUDE.md');
167
+ fs.writeFileSync(shared, `@AGENTS.md\n\n${BLOCK}\n`);
168
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
169
+
170
+ expect(() => installAgentDocs(project, {renderedBlock: BLOCK})).toThrow(
171
+ PathSafetyError,
172
+ );
173
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(`@AGENTS.md\n\n${BLOCK}\n`);
174
+ });
175
+
176
+ it('still refreshes in-project blocks beside an unmarked outside link it skips', () => {
177
+ const {project, outside} = layout();
178
+ fs.writeFileSync(
179
+ path.join(project, 'AGENTS.md'),
180
+ `# Agents\n\n${BLOCK.replace('managed', 'old')}\n`,
181
+ );
182
+ const shared = path.join(outside, 'rules');
183
+ fs.writeFileSync(shared, 'rules\n');
184
+ fs.symlinkSync(shared, path.join(project, '.cursorrules'));
185
+
186
+ expect(
187
+ installAgentDocs(project, {onlyReplace: true, renderedBlock: BLOCK}),
188
+ ).toEqual(['AGENTS.md']);
189
+ expect(fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8')).toContain(
190
+ 'managed',
191
+ );
192
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('rules\n');
193
+ });
194
+
195
+ it('writes through a symlink that stays inside the project', () => {
196
+ const {project} = layout();
197
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), '# Agents\n');
198
+ fs.symlinkSync('AGENTS.md', path.join(project, 'CLAUDE.md'));
199
+
200
+ expect(installAgentDocs(project, {renderedBlock: BLOCK})).toEqual([
201
+ 'AGENTS.md',
202
+ 'CLAUDE.md',
203
+ ]);
204
+ const content = fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8');
205
+ expect(content.split('<!-- ASTRYX:START -->')).toHaveLength(2);
206
+ });
207
+ });
208
+
209
+ describe('init --features agents with an agent doc linked outside the project', () => {
210
+ it('writes nothing outside, reports path-safety, and exits 1 in both modes', async () => {
211
+ const project = path.join(tmpDir, 'project');
212
+ const outside = path.join(tmpDir, 'outside');
213
+ fs.mkdirSync(project, {recursive: true});
214
+ fs.mkdirSync(outside, {recursive: true});
215
+ fs.writeFileSync(path.join(project, 'package.json'), '{"name":"app"}\n');
216
+ const shared = path.join(outside, 'CLAUDE.md');
217
+ fs.writeFileSync(shared, '# Shared\n');
218
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
219
+
220
+ const json = await runCli(['init', '--features', 'agents', '--json'], project);
221
+ expect(json.status).toBe(1);
222
+ const env = JSON.parse(json.stdout);
223
+ expect(env.type).toBe('init.run');
224
+ expect(env.data.docsError).toMatchObject({kind: 'path-safety'});
225
+
226
+ const text = await runCli(['init', '--features', 'agents'], project);
227
+ expect(text.status).toBe(1);
228
+
229
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('# Shared\n');
230
+ }, 30_000);
231
+ });
232
+
233
+ describe('removeAgentDocs never changes a file out of the project', () => {
234
+ beforeEach(() => {
235
+ vi.spyOn(console, 'log').mockImplementation(() => {});
236
+ });
237
+ afterEach(() => {
238
+ vi.restoreAllMocks();
239
+ });
240
+
241
+ it('refuses to strip a block from a file that links outside', () => {
242
+ const {project, outside} = layout();
243
+ const shared = path.join(outside, 'CLAUDE.md');
244
+ fs.writeFileSync(shared, `# Shared\n\n${BLOCK}\n`);
245
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
246
+
247
+ const err = thrownBy(() => removeAgentDocs(project));
248
+ expect(err).toBeInstanceOf(PathSafetyError);
249
+ expect(err).toMatchObject({code: 'ERR_PATH_TRAVERSAL'});
250
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(`# Shared\n\n${BLOCK}\n`);
251
+ });
252
+
253
+ it('refuses to delete a file reached through a symlinked directory', () => {
254
+ const {project, outside} = layout();
255
+ const shared = path.join(outside, 'CLAUDE.md');
256
+ const content = `# CLAUDE\n\nProject-specific guidance for AI coding agents.\n\n${BLOCK}\n`;
257
+ fs.writeFileSync(shared, content);
258
+ fs.symlinkSync(outside, path.join(project, '.claude'));
259
+
260
+ expect(thrownBy(() => removeAgentDocs(project))).toMatchObject({
261
+ code: 'ERR_PATH_TRAVERSAL',
262
+ });
263
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(content);
264
+ });
265
+
266
+ it('changes nothing when any file of the set escapes', () => {
267
+ const {project, outside} = layout();
268
+ const agents = `# Agents\n\nkeep\n\n${BLOCK}\n`;
269
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), agents);
270
+ const shared = path.join(outside, 'CLAUDE.md');
271
+ fs.writeFileSync(shared, `# Shared\n\n${BLOCK}\n`);
272
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
273
+
274
+ expect(thrownBy(() => removeAgentDocs(project))).toBeInstanceOf(PathSafetyError);
275
+ expect(fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8')).toBe(agents);
276
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(`# Shared\n\n${BLOCK}\n`);
277
+ });
278
+
279
+ it('still strips in-project blocks beside an unmarked outside link it skips', () => {
280
+ const {project, outside} = layout();
281
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), `# Agents\n\nkeep\n\n${BLOCK}\n`);
282
+ const shared = path.join(outside, 'rules');
283
+ fs.writeFileSync(shared, 'rules\n');
284
+ fs.symlinkSync(shared, path.join(project, '.cursorrules'));
285
+
286
+ removeAgentDocs(project);
287
+ expect(fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8')).toBe(
288
+ '# Agents\n\nkeep\n',
289
+ );
290
+ expect(fs.readFileSync(shared, 'utf-8')).toBe('rules\n');
291
+ });
292
+
293
+ it('strips through a symlink that stays inside the project', () => {
294
+ const {project} = layout();
295
+ fs.writeFileSync(path.join(project, 'AGENTS.md'), `# Agents\n\nkeep\n\n${BLOCK}\n`);
296
+ fs.symlinkSync('AGENTS.md', path.join(project, 'CLAUDE.md'));
297
+
298
+ removeAgentDocs(project);
299
+ expect(fs.readFileSync(path.join(project, 'AGENTS.md'), 'utf-8')).toBe(
300
+ '# Agents\n\nkeep\n',
301
+ );
302
+ });
303
+ });
304
+
305
+ describe('init --remove-agents with an agent doc linked outside the project', () => {
306
+ it('changes nothing outside, fails with ERR_PATH_TRAVERSAL, and exits 1 in both modes', async () => {
307
+ const {project, outside} = layout();
308
+ fs.writeFileSync(path.join(project, 'package.json'), '{"name":"app"}\n');
309
+ const shared = path.join(outside, 'CLAUDE.md');
310
+ const content = `# Shared\n\n${BLOCK}\n`;
311
+ fs.writeFileSync(shared, content);
312
+ fs.symlinkSync(shared, path.join(project, 'CLAUDE.md'));
313
+
314
+ const json = await runCli(['init', '--remove-agents', '--json'], project);
315
+ expect(json.status).toBe(1);
316
+ const env = JSON.parse(json.stdout);
317
+ expect(env).toMatchObject({apiVersion: 1, code: 'ERR_PATH_TRAVERSAL'});
318
+ expect(env.error).toMatch(/"CLAUDE\.md": resolves outside the project root/);
319
+ expect(env).not.toHaveProperty('data');
320
+
321
+ const text = await runCli(['init', '--remove-agents'], project);
322
+ expect(text.status).toBe(1);
323
+ expect(text.stderr).toMatch(/^Error: .*"CLAUDE\.md": resolves outside the project root/m);
324
+ expect(text.stdout).not.toMatch(/removed/i);
325
+
326
+ expect(fs.readFileSync(shared, 'utf-8')).toBe(content);
327
+ }, 30_000);
328
+ });
@@ -55,6 +55,15 @@ describe('generateCompressedIndex', () => {
55
55
  expect(frameRule).not.toMatch(/https?:/);
56
56
  });
57
57
 
58
+ it('starts every page from a template before any component', () => {
59
+ const lines = generateCompressedIndex('1.0.0').split('\n');
60
+ const workflow = lines.findIndex(l => l.startsWith('WORKFLOW'));
61
+ expect(lines[workflow]).toMatch(/start every page from a template/);
62
+ expect(lines[workflow + 1]).toMatch(/^1\. `astryx build /);
63
+ expect(lines[workflow + 2]).toMatch(/^2\. `astryx template <name> <path>`/);
64
+ expect(lines.join('\n')).not.toMatch(/reference code/);
65
+ });
66
+
58
67
  it('includes the post-generation self-check rule', () => {
59
68
  const result = generateCompressedIndex('1.0.0');
60
69
  expect(result).toContain('SELF-CHECK before you finish');
@@ -134,7 +143,6 @@ describe('generateCompressedIndex', () => {
134
143
  const line = topicLine(generateCompressedIndex('1.0.0'));
135
144
  for (const topic of [
136
145
  'getting-started',
137
- 'cli-integrations',
138
146
  'browser-support',
139
147
  'styling-libraries',
140
148
  'working-with-ai',
@@ -143,6 +151,16 @@ describe('generateCompressedIndex', () => {
143
151
  }
144
152
  });
145
153
 
154
+ it('points to the CLI docs tree on a line of its own', () => {
155
+ // The integration guide lives in the docs tree now (cli/integrations), so
156
+ // the topic line no longer names it; the tree's entry point does.
157
+ const block = generateCompressedIndex('1.0.0');
158
+ expect(block).toContain(
159
+ ' docs cli commands, API reference, integration authoring (one level at a time)',
160
+ );
161
+ expect(topicLine(block)).not.toContain('cli-integrations');
162
+ });
163
+
146
164
  it('lists the topics it is given, so an integration’s reach the agent', () => {
147
165
  const line = topicLine(
148
166
  generateCompressedIndex('1.0.0', {topics: ['tokens', 'deploying']}),
@@ -63,11 +63,18 @@ function config(integrations, ownHandler = false) {
63
63
  );
64
64
  }
65
65
 
66
- /** @param {Record<string, unknown>} [astryx] */
67
- function packageJson(astryx) {
66
+ /**
67
+ * @param {Record<string, unknown>} [astryx]
68
+ * @param {Record<string, string>} [dependencies]
69
+ */
70
+ function packageJson(astryx, dependencies) {
68
71
  fs.writeFileSync(
69
72
  path.join(tmpDir, 'package.json'),
70
- JSON.stringify({name: 'consumer', ...(astryx ? {astryx} : {})}),
73
+ JSON.stringify({
74
+ name: 'consumer',
75
+ ...(dependencies ? {dependencies} : {}),
76
+ ...(astryx ? {astryx} : {}),
77
+ }),
71
78
  );
72
79
  }
73
80
 
@@ -172,6 +179,24 @@ describe('an app can refuse an inherited handler', () => {
172
179
 
173
180
  expect(fired()).toEqual(['reporting-integration']);
174
181
  });
182
+
183
+ it('keeps an autolinked handler in a project with no astryx.config', async () => {
184
+ packageJson(undefined, {'reporting-integration': '1.0.0'});
185
+ integration('reporting-integration');
186
+
187
+ await runOneCommand();
188
+
189
+ expect(fired()).toEqual(['reporting-integration']);
190
+ });
191
+
192
+ it('drops an autolinked handler under astryx.inheritDebug false with no astryx.config', async () => {
193
+ packageJson({inheritDebug: false}, {'reporting-integration': '1.0.0'});
194
+ integration('reporting-integration');
195
+
196
+ await runOneCommand();
197
+
198
+ expect(fired()).toEqual([]);
199
+ });
175
200
  });
176
201
 
177
202
  describe('loading the project twice delivers once', () => {
@@ -15,6 +15,7 @@ function installThemeIntegration(packageName, slug) {
15
15
  ...packageName.split('/'),
16
16
  );
17
17
  const themeDir = path.join(packageDir, 'themes', slug);
18
+ const stem = `${slug.replace(/-([a-z0-9])/gu, (_, character) => character.toUpperCase())}Theme`;
18
19
  fs.mkdirSync(themeDir, {recursive: true});
19
20
  fs.writeFileSync(
20
21
  path.join(packageDir, 'package.json'),
@@ -22,28 +23,19 @@ function installThemeIntegration(packageName, slug) {
22
23
  );
23
24
  fs.writeFileSync(
24
25
  path.join(packageDir, 'astryx.integration.mjs'),
25
- `export default {themes: './themes'};\n`,
26
+ `export default {themes: './themes'};
27
+ `,
26
28
  );
27
29
  fs.writeFileSync(
28
- path.join(packageDir, 'themes', 'manifest.json'),
29
- JSON.stringify({
30
- version: 1,
31
- themes: [
32
- {
33
- slug,
34
- displayName: 'Ocean',
35
- description: 'Blue and calm.',
36
- maintained: true,
37
- entry: 'oceanTheme.ts',
38
- exportName: 'oceanTheme',
39
- files: ['oceanTheme.ts'],
40
- },
41
- ],
42
- }),
30
+ path.join(themeDir, `${stem}.doc.mjs`),
31
+ `/** @type {import('@astryxdesign/cli/authoring').ThemeDoc} */
32
+ export default {type: 'theme', name: '${slug}', displayName: 'Ocean', description: 'Blue and calm.', maintained: true};
33
+ `,
43
34
  );
44
35
  fs.writeFileSync(
45
- path.join(themeDir, 'oceanTheme.ts'),
46
- `export const oceanTheme = {};\n`,
36
+ path.join(themeDir, `${stem}.ts`),
37
+ `export const ${stem} = {};
38
+ `,
47
39
  );
48
40
  }
49
41
 
@@ -99,7 +91,7 @@ describe('Project themes', () => {
99
91
  ]);
100
92
  });
101
93
 
102
- it('records an invalid integration theme catalog as an issue', async () => {
94
+ it('records an invalid integration theme descriptor as an issue', async () => {
103
95
  installThemeIntegration('@acme/themes', 'ocean');
104
96
  fs.rmSync(
105
97
  path.join(
@@ -9,6 +9,14 @@
9
9
  * @returns {string|null}
10
10
  */
11
11
  export function findConfigPath(startDir?: string): string | null;
12
+ /**
13
+ * The provider ledger a Project resolved at load: one outcome for every
14
+ * package directory configured, autolinked, or authored. Internal: upgrade
15
+ * resolves on top of it, and tests account for every candidate with it.
16
+ * @param {Project} project
17
+ * @returns {import('../integrations/provider-resolution.mjs').ProviderLedger}
18
+ */
19
+ export function providerLedgerOf(project: Project): import("../integrations/provider-resolution.mjs").ProviderLedger;
12
20
  /**
13
21
  * An integration issue tagged with the owner package. The base
14
22
  * {@link import('../integrations/issue').AstryxIntegrationIssue} fields plus the
@@ -87,9 +95,9 @@ export class Project {
87
95
  /**
88
96
  * Core + integration component ownership records. Wraps
89
97
  * discoverOwnedComponents for core and discoverIntegrationComponents (via
90
- * discoverOwnedComponents) for integrations, but applies the skip+warn
91
- * policy per integration: a broken integration's components are skipped and
92
- * its issues collected, never thrown. Memoized per instance.
98
+ * discoverOwnedComponents) for integrations. Invalid component records are
99
+ * omitted and reported; valid component siblings and other contribution kinds
100
+ * remain available. Memoized per instance.
93
101
  *
94
102
  * @returns {Promise<Array<{name: string, package: string, group: string|null, docPath: string|null, sourcePath: string|null, issuesUrl: string|undefined}>>}
95
103
  */
@@ -102,10 +110,11 @@ export class Project {
102
110
  issuesUrl: string | undefined;
103
111
  }>>;
104
112
  /**
105
- * Core + integration templates, type-tagged. Wraps discoverTemplates (core +
106
- * external blocks) and discoverIntegrationTemplatesForOne per integration so
107
- * a broken integration's templates are skipped and its issues collected.
108
- * Memoized per instance.
113
+ * Core + integration templates, type-tagged, with valid integration
114
+ * replacements projected over their Core targets. Wraps raw template discovery
115
+ * (Core + external blocks) and discoverIntegrationTemplatesForOne per integration
116
+ * so unusable template files are reported and omitted while valid siblings
117
+ * remain available. Memoized per instance.
109
118
  *
110
119
  * @returns {Promise<Array<object>>}
111
120
  */
@@ -113,8 +122,8 @@ export class Project {
113
122
  /**
114
123
  * Bundled source themes plus themes contributed by installed integrations.
115
124
  * Each record keeps its package owner and source directory so callers can
116
- * both list and copy it without reconstructing paths. A broken integration's
117
- * themes are skipped under the same issue policy as every other kind.
125
+ * both list and copy it without reconstructing paths. A broken theme
126
+ * contribution is reported without hiding the package's other valid kinds.
118
127
  *
119
128
  * @returns {Promise<import('../discovery/theme-discovery.mjs').DiscoveredTheme[]>}
120
129
  */
@@ -137,8 +146,8 @@ export class Project {
137
146
  /**
138
147
  * Core registry transforms + integration codemods for an upgrade range.
139
148
  * Wraps getTransformsBetween (core) and discoverIntegrationCodemods /
140
- * selectIntegrationCodemods (integrations). A broken integration's codemods
141
- * are skipped (issue collected) rather than failing the whole resolution.
149
+ * selectIntegrationCodemods (integrations). An invalid codemod contribution
150
+ * is reported and omitted without hiding other valid contribution kinds.
142
151
  * Memoized per (from, to) key.
143
152
  *
144
153
  * @param {string} fromVersion exclusive lower bound