@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.3-canary.02f5fe4

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 (694) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/README.md +216 -162
  3. package/api/build/_adapter.d.mts +66 -0
  4. package/api/build/_adapter.mjs +139 -4
  5. package/api/build/blocks/blocks.d.mts +92 -0
  6. package/api/build/blocks/blocks.mjs +528 -0
  7. package/api/build/blocks/blocks.test.mjs +238 -0
  8. package/api/build/blocks/blocks.weights.json +1 -0
  9. package/api/build/build.doc.mjs +4 -0
  10. package/api/build/build.mjs +25 -6
  11. package/api/build/build.type.mjs +1 -1
  12. package/api/build/help/help.mjs +1 -1
  13. package/api/build/kit/answer.d.mts +18 -0
  14. package/api/build/kit/answer.mjs +195 -0
  15. package/api/build/kit/answer.test.mjs +108 -0
  16. package/api/build/kit/kind.d.mts +25 -0
  17. package/api/build/kit/kind.mjs +170 -0
  18. package/api/build/kit/kit.d.mts +2 -4
  19. package/api/build/kit/kit.mjs +8 -406
  20. package/api/build/kit/rank.d.mts +3 -32
  21. package/api/build/kit/rank.mjs +25 -342
  22. package/api/build/kit/rank.test.mjs +2 -1
  23. package/api/build/kit/signals.d.mts +79 -0
  24. package/api/build/kit/signals.mjs +295 -0
  25. package/api/build/kit/start.d.mts +32 -0
  26. package/api/build/kit/start.mjs +163 -0
  27. package/api/build/kit/words.d.mts +72 -0
  28. package/api/build/kit/words.mjs +202 -0
  29. package/api/build/tree.d.mts +20 -0
  30. package/api/build/tree.mjs +53 -0
  31. package/api/build/tree.test.mjs +185 -0
  32. package/api/build/tree.weights.json +1 -0
  33. package/api/component/_adapter.d.mts +72 -1
  34. package/api/component/_adapter.mjs +251 -23
  35. package/api/component/component-replacement.test.mjs +1 -0
  36. package/api/component/component.doc.mjs +6 -1
  37. package/api/component/component.mjs +97 -16
  38. package/api/component/component.test.mjs +95 -0
  39. package/api/component/doc-links.test.mjs +386 -0
  40. package/api/component/integration-export-name.test.mjs +644 -0
  41. package/api/component/list/list.mjs +42 -4
  42. package/api/discover/_adapter.d.mts +131 -12
  43. package/api/discover/_adapter.mjs +520 -34
  44. package/api/discover/_adapter.test.mjs +641 -17
  45. package/api/discover/_catalog-view.d.mts +16 -5
  46. package/api/discover/_catalog-view.mjs +32 -8
  47. package/api/discover/detail/doc/doc.mjs +9 -1
  48. package/api/discover/discover.d.mts +11 -0
  49. package/api/discover/discover.doc.mjs +9 -7
  50. package/api/discover/discover.mjs +120 -19
  51. package/api/discover/discover.type.d.mts +20 -7
  52. package/api/discover/discover.type.mjs +17 -7
  53. package/api/discover/list/list.d.mts +4 -3
  54. package/api/discover/list/list.mjs +17 -10
  55. package/api/docs/_adapter.d.mts +76 -2
  56. package/api/docs/_adapter.mjs +630 -34
  57. package/api/docs/docs-homes.test.mjs +127 -0
  58. package/api/docs/docs.doc.mjs +5 -4
  59. package/api/docs/docs.mjs +2 -1
  60. package/api/docs/docs.test.mjs +39 -20
  61. package/api/docs/integration-tree.test.mjs +42 -20
  62. package/api/docs/integrationDocs.test.mjs +125 -1
  63. package/api/docs/list/list.mjs +12 -2
  64. package/api/docs/namespace-section.test.mjs +6 -6
  65. package/api/docs/reference-blocks.test.mjs +3 -5
  66. package/api/doctor/_adapter.d.mts +128 -0
  67. package/api/doctor/_adapter.mjs +253 -4
  68. package/api/doctor/doctor.d.mts +217 -0
  69. package/api/doctor/doctor.doc.mjs +3 -2
  70. package/api/doctor/doctor.mjs +691 -52
  71. package/api/doctor/doctor.test.mjs +267 -18
  72. package/api/doctor/release-checks.test.mjs +156 -0
  73. package/api/doctor/theme-checks.mjs +17 -4
  74. package/api/doctor/theme-checks.test.mjs +223 -7
  75. package/api/error.d.mts +10 -0
  76. package/api/error.mjs +25 -0
  77. package/api/gap-report/gap-report.d.mts +3 -0
  78. package/api/gap-report/gap-report.doc.mjs +11 -3
  79. package/api/gap-report/gap-report.mjs +219 -52
  80. package/api/gap-report/gap-report.test.mjs +233 -0
  81. package/api/gap-report/gap-report.type.d.mts +41 -0
  82. package/api/gap-report/gap-report.type.mjs +18 -0
  83. package/api/hook/_adapter.mjs +3 -11
  84. package/api/hook/hook.doc.mjs +4 -0
  85. package/api/hook/hook.mjs +1 -1
  86. package/api/hook/list/list.d.mts +1 -1
  87. package/api/index.d.mts +2 -0
  88. package/api/index.mjs +2 -0
  89. package/api/init/_adapter.d.mts +22 -0
  90. package/api/init/_adapter.mjs +59 -0
  91. package/api/init/init.d.mts +7 -5
  92. package/api/init/init.doc.mjs +45 -10
  93. package/api/init/init.mjs +28 -4
  94. package/api/init/init.test.mjs +18 -2
  95. package/api/init/init.type.d.mts +50 -5
  96. package/api/init/init.type.mjs +39 -5
  97. package/api/init/remove/remove.mjs +17 -4
  98. package/api/init/remove/remove.test.mjs +114 -2
  99. package/api/init/run/run.d.mts +1 -1
  100. package/api/init/run/run.mjs +86 -12
  101. package/api/init/user/user.d.mts +14 -0
  102. package/api/init/user/user.mjs +87 -0
  103. package/api/init/user/user.test.mjs +232 -0
  104. package/api/integration/_adapter.d.mts +53 -0
  105. package/api/integration/_adapter.mjs +132 -0
  106. package/api/integration/add-contribution.component-names.test.mjs +66 -0
  107. package/api/integration/add-contribution.mjs +8 -4
  108. package/api/integration/add-contribution.test.mjs +4 -2
  109. package/api/integration/authoring-checks.mjs +192 -14
  110. package/api/integration/authoring-checks.test.mjs +1028 -0
  111. package/api/integration/authoring-checks.type.d.mts +143 -0
  112. package/api/integration/authoring-checks.type.mjs +74 -2
  113. package/api/integration/check/check.d.mts +96 -0
  114. package/api/integration/check/check.mjs +357 -0
  115. package/api/integration/check/check.test.mjs +489 -0
  116. package/api/integration/integration-check.type.d.mts +118 -0
  117. package/api/integration/integration-check.type.mjs +84 -0
  118. package/api/integration/integrationCheck.doc.d.mts +10 -0
  119. package/api/integration/integrationCheck.doc.mjs +73 -0
  120. package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
  121. package/api/integration/integrationDocConflicts.doc.mjs +22 -5
  122. package/api/integration/pack-check.mjs +486 -123
  123. package/api/integration/pack-check.test.mjs +817 -10
  124. package/api/integration/validate-integration-case-disk.test.mjs +111 -0
  125. package/api/integration/validate-integration-fixes.test.mjs +73 -5
  126. package/api/integration/validate-integration-gaps.test.mjs +1975 -0
  127. package/api/integration/validate-integration.d.mts +23 -2
  128. package/api/integration/validate-integration.mjs +358 -45
  129. package/api/integration/validate-integration.test.mjs +88 -8
  130. package/api/integration/validate-integration.type.d.mts +105 -0
  131. package/api/integration/validate-integration.type.mjs +79 -1
  132. package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
  133. package/api/integration/validateIntegration.doc.mjs +19 -3
  134. package/api/search/ORDERING.md +28 -0
  135. package/api/search/_adapter.d.mts +91 -0
  136. package/api/search/_adapter.mjs +172 -0
  137. package/api/search/_adapter.test.mjs +173 -0
  138. package/api/search/_candidate-score.d.mts +40 -0
  139. package/api/search/_candidate-score.mjs +238 -0
  140. package/api/search/_cards.json +6098 -0
  141. package/api/search/_compound.d.mts +50 -0
  142. package/api/search/_compound.mjs +170 -0
  143. package/api/search/_doc-searcher.d.mts +4 -0
  144. package/api/search/_doc-searcher.mjs +23 -0
  145. package/api/search/_doc-searcher.test.mjs +36 -0
  146. package/api/search/_doc-searcher.weights.json +1 -0
  147. package/api/search/_doc-text.d.mts +30 -0
  148. package/api/search/_doc-text.mjs +87 -0
  149. package/api/search/_entries.d.mts +63 -0
  150. package/api/search/_entries.mjs +232 -0
  151. package/api/search/_entries.test.mjs +48 -0
  152. package/api/search/_features.d.mts +35 -0
  153. package/api/search/_features.mjs +155 -0
  154. package/api/search/_gather-components.d.mts +26 -0
  155. package/api/search/_gather-components.mjs +284 -0
  156. package/api/search/_gather-docs.d.mts +20 -0
  157. package/api/search/_gather-docs.mjs +254 -0
  158. package/api/search/_gather-hooks.d.mts +12 -0
  159. package/api/search/_gather-hooks.mjs +52 -0
  160. package/api/search/_gather-templates.d.mts +25 -0
  161. package/api/search/_gather-templates.mjs +107 -0
  162. package/api/search/_lexical.d.mts +135 -0
  163. package/api/search/_lexical.mjs +351 -0
  164. package/api/search/_main-searcher.d.mts +19 -0
  165. package/api/search/_main-searcher.mjs +115 -0
  166. package/api/search/_main-searcher.test.mjs +106 -0
  167. package/api/search/_main-searcher.weights.json +1 -0
  168. package/api/search/_module-doc.d.mts +32 -0
  169. package/api/search/_module-doc.mjs +78 -0
  170. package/api/search/_order.d.mts +32 -0
  171. package/api/search/_order.mjs +162 -0
  172. package/api/search/_order.test.mjs +72 -0
  173. package/api/search/_priority.d.mts +50 -0
  174. package/api/search/_priority.mjs +139 -0
  175. package/api/search/_query-words.d.mts +25 -0
  176. package/api/search/_query-words.mjs +92 -0
  177. package/api/search/_query.d.mts +65 -0
  178. package/api/search/_query.mjs +176 -0
  179. package/api/search/_result.d.mts +97 -0
  180. package/api/search/_result.mjs +150 -0
  181. package/api/search/_score.d.mts +60 -0
  182. package/api/search/_score.mjs +283 -0
  183. package/api/search/_synonyms.d.mts +21 -0
  184. package/api/search/_synonyms.mjs +67 -0
  185. package/api/search/_template-searcher.d.mts +4 -0
  186. package/api/search/_template-searcher.mjs +23 -0
  187. package/api/search/_template-searcher.test.mjs +40 -0
  188. package/api/search/_template-searcher.weights.json +1 -0
  189. package/api/search/_titles.d.mts +33 -0
  190. package/api/search/_titles.mjs +65 -0
  191. package/api/search/_words.d.mts +64 -0
  192. package/api/search/_words.mjs +157 -0
  193. package/api/search/search.d.mts +22 -236
  194. package/api/search/search.doc.mjs +14 -7
  195. package/api/search/search.domain-priority.test.mjs +108 -18
  196. package/api/search/search.integration-check.test.mjs +24 -0
  197. package/api/search/search.mjs +59 -1904
  198. package/api/search/search.test.mjs +193 -15
  199. package/api/search/search.type.d.mts +20 -2
  200. package/api/search/search.type.mjs +12 -2
  201. package/api/search/tree.d.mts +15 -0
  202. package/api/search/tree.mjs +40 -0
  203. package/api/search/tree.test.mjs +66 -0
  204. package/api/search/tree.weights.json +1 -0
  205. package/api/swizzle/_adapter.mjs +2 -2
  206. package/api/swizzle/copy/copy.mjs +29 -15
  207. package/api/template/template-integration.test.mjs +1 -1
  208. package/api/template/template.mjs +5 -1
  209. package/api/template/template.test.mjs +120 -3
  210. package/api/theme/_adapter.d.mts +16 -0
  211. package/api/theme/_adapter.mjs +32 -5
  212. package/api/theme/build/build.d.mts +2 -1
  213. package/api/theme/build/build.family.test.mjs +64 -0
  214. package/api/theme/build/build.mjs +250 -38
  215. package/api/theme/build/build.packed-old-core.test.mjs +21 -3
  216. package/api/theme/build/font-warning.mjs +5 -3
  217. package/api/theme/build/font-warning.test.mjs +2 -1
  218. package/api/theme/remove/remove.test.mjs +2 -2
  219. package/api/theme/targets/targets.mjs +3 -10
  220. package/api/theme/themeBuild.doc.mjs +4 -4
  221. package/api/theme/themeTargets.doc.mjs +4 -0
  222. package/api/theme/use/use.test.mjs +1 -1
  223. package/api/upgrade/_adapter.d.mts +97 -11
  224. package/api/upgrade/_adapter.mjs +315 -32
  225. package/api/upgrade/registry/registry.d.mts +10 -4
  226. package/api/upgrade/registry/registry.mjs +33 -16
  227. package/api/upgrade/registry/registry.test.mjs +85 -0
  228. package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
  229. package/api/upgrade/run/run.d.mts +4 -2
  230. package/api/upgrade/run/run.mjs +48 -4
  231. package/api/upgrade/run/run.test.mjs +417 -3
  232. package/api/upgrade/status/status.d.mts +21 -5
  233. package/api/upgrade/status/status.mjs +45 -8
  234. package/api/upgrade/upgrade.doc.mjs +16 -8
  235. package/api/upgrade/upgrade.mjs +18 -3
  236. package/api/upgrade/upgrade.test.mjs +194 -0
  237. package/api/upgrade/upgrade.type.d.mts +28 -3
  238. package/api/upgrade/upgrade.type.mjs +24 -7
  239. package/assets/codemods/__tests__/registry.test.mjs +1 -0
  240. package/assets/codemods/registry.mjs +1 -0
  241. package/assets/codemods/runner.mjs +7 -1
  242. package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
  243. package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
  244. package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
  245. package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
  246. package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
  247. package/assets/discover/official-packages.json +367 -0
  248. package/assets/docs/README.md +10 -0
  249. package/assets/docs/author-a-theme.doc.mjs +5 -5
  250. package/assets/docs/browser-support.doc.mjs +1 -1
  251. package/assets/docs/getting-started.doc.mjs +26 -6
  252. package/assets/docs/is-my-code-good.doc.mjs +287 -0
  253. package/assets/docs/styling-overview.doc.mjs +1 -1
  254. package/assets/docs/theme.doc.dense.mjs +1 -1
  255. package/assets/docs/theme.doc.mjs +2 -2
  256. package/assets/docs/theme.doc.zh.mjs +1 -1
  257. package/assets/docs/tree/add-a-component.doc.mjs +22 -2
  258. package/assets/docs/tree/add-a-theme.doc.mjs +14 -4
  259. package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
  260. package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
  261. package/assets/docs/tree/api.doc.mjs +6 -0
  262. package/assets/docs/tree/authoring.doc.mjs +61 -0
  263. package/assets/docs/tree/block-template.doc.mjs +8 -20
  264. package/assets/docs/tree/build-the-template.doc.mjs +1 -1
  265. package/assets/docs/tree/building-blocks.doc.mjs +6 -2
  266. package/assets/docs/tree/check-the-props.doc.mjs +201 -0
  267. package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
  268. package/assets/docs/tree/checks.doc.mjs +32 -24
  269. package/assets/docs/tree/ci-and-containers.doc.mjs +101 -0
  270. package/assets/docs/tree/cli-command.doc.mjs +142 -0
  271. package/assets/docs/tree/cli.doc.mjs +7 -1
  272. package/assets/docs/tree/codemods.doc.mjs +17 -7
  273. package/assets/docs/tree/commands.doc.mjs +7 -1
  274. package/assets/docs/tree/component-family.doc.mjs +8 -6
  275. package/assets/docs/tree/component-imports.doc.mjs +21 -3
  276. package/assets/docs/tree/components.doc.mjs +7 -1
  277. package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
  278. package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
  279. package/assets/docs/tree/configuration.doc.mjs +8 -4
  280. package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
  281. package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
  282. package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
  283. package/assets/docs/tree/docs.doc.mjs +9 -3
  284. package/assets/docs/tree/document-the-template.doc.mjs +1 -1
  285. package/assets/docs/tree/document-the-theme.doc.mjs +4 -4
  286. package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
  287. package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
  288. package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
  289. package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
  290. package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
  291. package/assets/docs/tree/global-integrations.doc.mjs +124 -0
  292. package/assets/docs/tree/global.doc.mjs +131 -0
  293. package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
  294. package/assets/docs/tree/help.doc.mjs +2 -2
  295. package/assets/docs/tree/host-entry.doc.mjs +128 -0
  296. package/assets/docs/tree/install-once.doc.mjs +105 -0
  297. package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
  298. package/assets/docs/tree/layout.doc.mjs +6 -6
  299. package/assets/docs/tree/links.doc.mjs +7 -6
  300. package/assets/docs/tree/migration-setup.doc.mjs +3 -2
  301. package/assets/docs/tree/migration-verification.doc.mjs +0 -1
  302. package/assets/docs/tree/migration.doc.mjs +0 -1
  303. package/assets/docs/tree/monorepos.doc.mjs +84 -0
  304. package/assets/docs/tree/package-and-test.doc.mjs +1 -1
  305. package/assets/docs/tree/page-template.doc.mjs +4 -8
  306. package/assets/docs/tree/problems.doc.mjs +205 -0
  307. package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
  308. package/assets/docs/tree/publishing.doc.mjs +6 -6
  309. package/assets/docs/tree/quick-start.doc.mjs +54 -28
  310. package/assets/docs/tree/reference.doc.mjs +192 -0
  311. package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
  312. package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
  313. package/assets/docs/tree/scaffold.doc.mjs +1 -1
  314. package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
  315. package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
  316. package/assets/docs/tree/ship.doc.mjs +2 -2
  317. package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
  318. package/assets/docs/tree/single-component.doc.mjs +15 -6
  319. package/assets/docs/tree/start-a-template.doc.mjs +18 -8
  320. package/assets/docs/tree/subcomponent.doc.mjs +6 -6
  321. package/assets/docs/tree/template-assets.doc.mjs +2 -2
  322. package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
  323. package/assets/docs/tree/template-fonts.doc.mjs +1 -1
  324. package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
  325. package/assets/docs/tree/template-icons.doc.mjs +1 -1
  326. package/assets/docs/tree/template-images-media.doc.mjs +1 -1
  327. package/assets/docs/tree/template-styles.doc.mjs +2 -2
  328. package/assets/docs/tree/templates.doc.mjs +7 -1
  329. package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
  330. package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
  331. package/assets/docs/tree/themes.doc.mjs +5 -1
  332. package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
  333. package/assets/docs/tree/tokens-data.doc.mjs +2 -2
  334. package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
  335. package/assets/docs/tree/type-scale.doc.mjs +3 -3
  336. package/assets/docs/tree/uninstall.doc.mjs +109 -0
  337. package/assets/docs/tree/updates.doc.mjs +92 -0
  338. package/assets/docs/tree/upgrading.doc.mjs +6 -6
  339. package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +15 -3
  340. package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
  341. package/assets/docs/tree/versioning.doc.mjs +14 -9
  342. package/assets/docs/tree/who-answers.doc.mjs +119 -0
  343. package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
  344. package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
  345. package/assets/docs/use-a-theme.doc.mjs +2 -2
  346. package/assets/docs/use-integrations.doc.mjs +120 -0
  347. package/assets/docs/working-with-ai.doc.mjs +70 -13
  348. package/assets/templates/themes/butter/butterTheme.ts +4 -2
  349. package/assets/templates/themes/stone/stoneTheme.ts +4 -2
  350. package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
  351. package/assets/theme.template.ts +1 -1
  352. package/authoring/codemod/codemod.doc.mjs +7 -3
  353. package/authoring/config/config.doc.mjs +9 -6
  354. package/authoring/config/type.ts +4 -2
  355. package/authoring/debug/parse.d.mts +5 -5
  356. package/authoring/discover/discover.doc.mjs +7 -1
  357. package/authoring/doctypes/_schema.d.mts +8 -3
  358. package/authoring/doctypes/_schema.mjs +1 -0
  359. package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
  360. package/authoring/doctypes/command/command.doc.mjs +20 -12
  361. package/authoring/doctypes/command/type.ts +14 -0
  362. package/authoring/doctypes/component/component.doc.mjs +30 -27
  363. package/authoring/doctypes/component/type.ts +21 -8
  364. package/authoring/doctypes/enum/enum.doc.mjs +7 -4
  365. package/authoring/doctypes/function/function.doc.mjs +9 -8
  366. package/authoring/doctypes/hook/hook.doc.mjs +5 -4
  367. package/authoring/doctypes/hook/type.ts +4 -0
  368. package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
  369. package/authoring/doctypes/reference/reference.doc.mjs +12 -11
  370. package/authoring/doctypes/schema/schema.doc.mjs +10 -10
  371. package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
  372. package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
  373. package/authoring/doctypes/template/parse.d.mts +6 -2
  374. package/authoring/doctypes/template/parse.mjs +3 -1
  375. package/authoring/doctypes/template/template.doc.mjs +3 -3
  376. package/authoring/doctypes/template/type.ts +22 -0
  377. package/authoring/doctypes/theme/theme.doc.mjs +2 -2
  378. package/authoring/gap-report/gap-report.doc.mjs +2 -2
  379. package/authoring/identity/identity.doc.mjs +3 -3
  380. package/authoring/index.d.ts +2 -0
  381. package/authoring/integration/integration.doc.mjs +30 -6
  382. package/authoring/integration/parse.test.mjs +21 -0
  383. package/authoring/integration/schema.d.mts +16 -3
  384. package/authoring/integration/schema.mjs +34 -2
  385. package/authoring/integration/type.ts +13 -1
  386. package/clients/cli/bin/astryx.mjs +11 -65
  387. package/clients/cli/cli-command.test.mjs +166 -0
  388. package/clients/cli/command-result-coverage.test.mjs +6 -5
  389. package/clients/cli/commands/blog.doc.mjs +1 -0
  390. package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
  391. package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
  392. package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
  393. package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
  394. package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
  395. package/clients/cli/commands/build.doc.mjs +1 -0
  396. package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
  397. package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
  398. package/clients/cli/commands/component.doc.mjs +1 -0
  399. package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
  400. package/clients/cli/commands/component.test.mjs +6 -6
  401. package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
  402. package/clients/cli/commands/discover.doc.mjs +9 -1
  403. package/clients/cli/commands/discover.mjs +144 -93
  404. package/clients/cli/commands/discover.no-source.test.mjs +448 -33
  405. package/clients/cli/commands/discover.sources.test.mjs +20 -1
  406. package/clients/cli/commands/docs.doc.mjs +3 -2
  407. package/clients/cli/commands/docs.mjs +50 -20
  408. package/clients/cli/commands/docs.test.mjs +16 -16
  409. package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
  410. package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
  411. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
  412. package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
  413. package/clients/cli/commands/doctor-integration.test.mjs +936 -3
  414. package/clients/cli/commands/doctor.doc.mjs +12 -2
  415. package/clients/cli/commands/doctor.mjs +332 -7
  416. package/clients/cli/commands/doctor.test.mjs +75 -4
  417. package/clients/cli/commands/gap-report.doc.mjs +15 -2
  418. package/clients/cli/commands/gap-report.mjs +24 -2
  419. package/clients/cli/commands/gap-report.test.mjs +79 -0
  420. package/clients/cli/commands/hook.doc.mjs +1 -0
  421. package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
  422. package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
  423. package/clients/cli/commands/init.behavior.test.mjs +235 -1
  424. package/clients/cli/commands/init.doc.mjs +55 -10
  425. package/clients/cli/commands/init.flag-help.test.mjs +1 -0
  426. package/clients/cli/commands/init.mjs +2 -2
  427. package/clients/cli/commands/integration-add.doc.mjs +7 -0
  428. package/clients/cli/commands/integration-authoring.test.mjs +49 -3
  429. package/clients/cli/commands/integration-check.doc.mjs +93 -0
  430. package/clients/cli/commands/integration-check.test.mjs +489 -0
  431. package/clients/cli/commands/integration-pack.doc.mjs +8 -1
  432. package/clients/cli/commands/integration-verify.doc.mjs +8 -1
  433. package/clients/cli/commands/integration.doc.mjs +6 -2
  434. package/clients/cli/commands/integration.mjs +119 -7
  435. package/clients/cli/commands/json-contract.test.mjs +11 -2
  436. package/clients/cli/commands/manifest.doc.mjs +2 -1
  437. package/clients/cli/commands/manifest.mjs +67 -0
  438. package/clients/cli/commands/outside-project.test.mjs +874 -0
  439. package/clients/cli/commands/postinstall.doc.mjs +23 -0
  440. package/clients/cli/commands/postinstall.mjs +31 -0
  441. package/clients/cli/commands/search.doc.mjs +1 -0
  442. package/clients/cli/commands/search.mjs +16 -11
  443. package/clients/cli/commands/search.test.mjs +429 -296
  444. package/clients/cli/commands/setup-nudge.test.mjs +180 -2
  445. package/clients/cli/commands/swizzle.doc.mjs +7 -0
  446. package/clients/cli/commands/swizzle.mjs +5 -3
  447. package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
  448. package/clients/cli/commands/template.doc.mjs +1 -0
  449. package/clients/cli/commands/text-json-parity.test.mjs +5 -0
  450. package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
  451. package/clients/cli/commands/theme-add.doc.mjs +8 -1
  452. package/clients/cli/commands/theme-build.doc.mjs +3 -2
  453. package/clients/cli/commands/theme-eject.doc.mjs +1 -0
  454. package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
  455. package/clients/cli/commands/theme-list.doc.mjs +1 -0
  456. package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
  457. package/clients/cli/commands/theme-remove.doc.mjs +7 -0
  458. package/clients/cli/commands/theme-targets.doc.mjs +1 -0
  459. package/clients/cli/commands/theme-template.doc.mjs +1 -0
  460. package/clients/cli/commands/theme-use.doc.mjs +7 -0
  461. package/clients/cli/commands/{build-theme.mjs → theme.mjs} +27 -14
  462. package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
  463. package/clients/cli/commands/upgrade.doc.mjs +26 -3
  464. package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
  465. package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
  466. package/clients/cli/commands/upgrade.mjs +9 -2
  467. package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
  468. package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
  469. package/clients/cli/index.mjs +156 -100
  470. package/clients/cli/lib/cli-error.mjs +4 -1
  471. package/clients/cli/lib/component-format.mjs +1 -1
  472. package/clients/cli/lib/component-format.test.mjs +1 -1
  473. package/clients/cli/lib/define-command.mjs +14 -9
  474. package/clients/cli/lib/exit-codes.test.mjs +5 -0
  475. package/clients/cli/lib/json-shim.mjs +3 -1
  476. package/clients/cli/lib/manifest.d.ts +9 -0
  477. package/clients/cli/lib/manifest.mjs +17 -1
  478. package/clients/cli/lib/manifest.test.mjs +37 -0
  479. package/clients/cli/lib/welcome-box.mjs +50 -0
  480. package/clients/cli/run.mjs +108 -0
  481. package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
  482. package/foundation/agent-docs/agent-doc-state.mjs +123 -14
  483. package/foundation/agent-docs/agent-docs.d.mts +104 -15
  484. package/foundation/agent-docs/agent-docs.mjs +1028 -114
  485. package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
  486. package/foundation/agent-docs/agent-docs.test.mjs +683 -39
  487. package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
  488. package/foundation/agent-docs/computer-agent-text.mjs +750 -0
  489. package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
  490. package/foundation/config/project.d.mts +35 -3
  491. package/foundation/config/project.mjs +243 -26
  492. package/foundation/config/project.test.mjs +122 -0
  493. package/foundation/config/theme-state.mjs +5 -4
  494. package/foundation/discovery/authoring-self-docs.d.mts +7 -0
  495. package/foundation/discovery/authoring-self-docs.mjs +17 -4
  496. package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
  497. package/foundation/discovery/authoring-surface.d.mts +1 -1
  498. package/foundation/discovery/authoring-surface.mjs +2 -2
  499. package/foundation/discovery/authoring-surface.test.mjs +1 -1
  500. package/foundation/discovery/cli-self-docs.d.mts +2 -1
  501. package/foundation/discovery/cli-self-docs.mjs +22 -4
  502. package/foundation/discovery/cli-self-docs.test.mjs +3 -2
  503. package/foundation/discovery/component-discovery.d.mts +227 -10
  504. package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
  505. package/foundation/discovery/component-discovery.mjs +940 -57
  506. package/foundation/discovery/component-discovery.test.mjs +96 -0
  507. package/foundation/discovery/component-loader.d.mts +1 -1
  508. package/foundation/discovery/component-replacement.mjs +20 -1
  509. package/foundation/discovery/component-replacement.test.mjs +40 -0
  510. package/foundation/discovery/copied-passages.d.mts +216 -0
  511. package/foundation/discovery/copied-passages.mjs +720 -0
  512. package/foundation/discovery/copied-passages.test.mjs +124 -0
  513. package/foundation/discovery/doc-consistency.d.mts +34 -0
  514. package/foundation/discovery/doc-consistency.mjs +513 -0
  515. package/foundation/discovery/doc-consistency.test.mjs +347 -0
  516. package/foundation/discovery/doc-fluff.d.mts +112 -0
  517. package/foundation/discovery/doc-fluff.mjs +328 -0
  518. package/foundation/discovery/doc-fluff.test.mjs +142 -0
  519. package/foundation/discovery/doc-types.d.mts +157 -0
  520. package/foundation/discovery/doc-types.mjs +1231 -0
  521. package/foundation/discovery/doc-types.test.mjs +744 -0
  522. package/foundation/discovery/docs-discovery.d.mts +88 -0
  523. package/foundation/discovery/docs-discovery.mjs +97 -3
  524. package/foundation/discovery/integration-doc-files.d.mts +22 -0
  525. package/foundation/discovery/integration-doc-files.mjs +231 -0
  526. package/foundation/discovery/integration-doc-files.test.mjs +246 -0
  527. package/foundation/discovery/module-exports.d.mts +68 -0
  528. package/foundation/discovery/module-exports.mjs +609 -31
  529. package/foundation/discovery/module-exports.test.mjs +172 -0
  530. package/foundation/discovery/package-tsconfig.d.mts +14 -0
  531. package/foundation/discovery/package-tsconfig.mjs +228 -0
  532. package/foundation/discovery/package-tsconfig.test.mjs +210 -0
  533. package/foundation/discovery/project-typescript.d.mts +32 -0
  534. package/foundation/discovery/project-typescript.mjs +89 -0
  535. package/foundation/discovery/prop-drift.d.mts +297 -0
  536. package/foundation/discovery/prop-drift.mjs +2428 -0
  537. package/foundation/discovery/prop-drift.test.mjs +2337 -0
  538. package/foundation/discovery/runner-allowlist.d.mts +38 -0
  539. package/foundation/discovery/runner-allowlist.mjs +51 -0
  540. package/foundation/discovery/runner-commands.d.mts +77 -0
  541. package/foundation/discovery/runner-commands.mjs +294 -0
  542. package/foundation/discovery/runner-commands.test.mjs +128 -0
  543. package/foundation/discovery/stray-pointers.d.mts +52 -0
  544. package/foundation/discovery/stray-pointers.mjs +293 -0
  545. package/foundation/discovery/stray-pointers.test.mjs +86 -0
  546. package/foundation/discovery/template-adapter.mjs +92 -6
  547. package/foundation/discovery/template-needs.mjs +6 -46
  548. package/foundation/discovery/theme-discovery.mjs +147 -3
  549. package/foundation/discovery/theme-imports.mjs +8 -4
  550. package/foundation/discovery/theme-imports.test.mjs +1 -1
  551. package/foundation/discovery/type-match.d.mts +53 -0
  552. package/foundation/discovery/type-match.mjs +660 -0
  553. package/foundation/discovery/type-match.test.mjs +169 -0
  554. package/foundation/discovery/type-text.d.mts +68 -0
  555. package/foundation/discovery/type-text.mjs +658 -0
  556. package/foundation/discovery/type-text.test.mjs +196 -0
  557. package/foundation/discovery/unresolved-references.d.mts +62 -0
  558. package/foundation/discovery/unresolved-references.mjs +790 -0
  559. package/foundation/discovery/unresolved-references.test.mjs +567 -0
  560. package/foundation/doc-compiler/doc-loads.test.mjs +84 -10
  561. package/foundation/doc-compiler/inputs.mjs +27 -1
  562. package/foundation/doc-compiler/inputs.test.mjs +0 -1
  563. package/foundation/doc-compiler/links.d.mts +41 -5
  564. package/foundation/doc-compiler/links.mjs +167 -28
  565. package/foundation/doc-compiler/links.test.mjs +97 -4
  566. package/foundation/doc-compiler/read.d.mts +1 -1
  567. package/foundation/doc-compiler/read.mjs +59 -1
  568. package/foundation/doc-compiler/read.test.mjs +11 -2
  569. package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
  570. package/foundation/doc-compiler/tree.d.mts +32 -6
  571. package/foundation/doc-compiler/tree.mjs +107 -44
  572. package/foundation/doc-compiler/tree.test.mjs +14 -7
  573. package/foundation/env/cli-command.d.mts +83 -0
  574. package/foundation/env/cli-command.mjs +152 -0
  575. package/foundation/env/cli-command.test.mjs +129 -0
  576. package/foundation/env/node-version.test.mjs +15 -3
  577. package/foundation/env/package-manager.d.mts +93 -9
  578. package/foundation/env/package-manager.global.test.mjs +66 -0
  579. package/foundation/env/package-manager.mjs +184 -13
  580. package/foundation/env/package-manager.test.mjs +341 -15
  581. package/foundation/env/project-scope.d.mts +9 -0
  582. package/foundation/env/project-scope.mjs +33 -0
  583. package/foundation/env/search-path.d.mts +42 -0
  584. package/foundation/env/search-path.mjs +205 -0
  585. package/foundation/env/search-path.test.mjs +122 -0
  586. package/foundation/env/user-dirs.d.mts +39 -0
  587. package/foundation/env/user-dirs.mjs +93 -0
  588. package/foundation/env/user-dirs.test.mjs +72 -0
  589. package/foundation/env/user-settings.d.mts +46 -0
  590. package/foundation/env/user-settings.mjs +106 -0
  591. package/foundation/env/user-settings.test.mjs +64 -0
  592. package/foundation/fs/file-protection.mjs +15 -1
  593. package/foundation/fs/module-loader.d.mts +2 -1
  594. package/foundation/fs/module-loader.mjs +60 -4
  595. package/foundation/fs/module-loader.stdout.test.mjs +3 -2
  596. package/foundation/fs/module-loader.test.mjs +194 -0
  597. package/foundation/fs/path-compare.d.mts +33 -0
  598. package/foundation/fs/path-compare.mjs +73 -0
  599. package/foundation/fs/paths.d.mts +122 -4
  600. package/foundation/fs/paths.mjs +675 -29
  601. package/foundation/fs/paths.test.mjs +439 -54
  602. package/foundation/fs/read-record.d.mts +18 -0
  603. package/foundation/fs/read-record.mjs +131 -0
  604. package/foundation/fs/read-record.test.mjs +77 -0
  605. package/foundation/integrations/autolink.d.mts +2 -1
  606. package/foundation/integrations/autolink.mjs +4 -13
  607. package/foundation/integrations/cli-peer-version.d.mts +36 -0
  608. package/foundation/integrations/cli-peer-version.mjs +132 -0
  609. package/foundation/integrations/cli-peer-version.test.mjs +354 -0
  610. package/foundation/integrations/computer-integrations.d.mts +81 -0
  611. package/foundation/integrations/computer-integrations.mjs +345 -0
  612. package/foundation/integrations/computer-integrations.test.mjs +292 -0
  613. package/foundation/integrations/contribution-inventory.d.mts +26 -20
  614. package/foundation/integrations/contribution-inventory.mjs +97 -8
  615. package/foundation/integrations/exports-subpaths.d.mts +57 -0
  616. package/foundation/integrations/exports-subpaths.mjs +113 -0
  617. package/foundation/integrations/integration-warnings.mjs +3 -2
  618. package/foundation/integrations/integration-warnings.test.mjs +8 -9
  619. package/foundation/integrations/integrations.d.mts +51 -1
  620. package/foundation/integrations/integrations.mjs +106 -4
  621. package/foundation/integrations/issue.ts +6 -0
  622. package/foundation/integrations/public-imports.d.mts +118 -0
  623. package/foundation/integrations/public-imports.mjs +1769 -0
  624. package/foundation/integrations/public-imports.test.mjs +1793 -0
  625. package/foundation/integrations/validate-contributions.d.mts +117 -0
  626. package/foundation/integrations/validate-contributions.mjs +1209 -14
  627. package/foundation/release/agent-text-worker.d.mts +4 -0
  628. package/foundation/release/agent-text-worker.mjs +52 -0
  629. package/foundation/release/cache.d.mts +310 -0
  630. package/foundation/release/cache.mjs +1216 -0
  631. package/foundation/release/cache.test.mjs +923 -0
  632. package/foundation/release/choose.d.mts +207 -0
  633. package/foundation/release/choose.mjs +677 -0
  634. package/foundation/release/choose.test.mjs +427 -0
  635. package/foundation/release/core-worker.d.mts +4 -0
  636. package/foundation/release/core-worker.mjs +38 -0
  637. package/foundation/release/global-state.d.mts +263 -0
  638. package/foundation/release/global-state.mjs +474 -0
  639. package/foundation/release/global-state.test.mjs +381 -0
  640. package/foundation/release/handoff.d.mts +79 -0
  641. package/foundation/release/handoff.e2e.test.mjs +278 -0
  642. package/foundation/release/handoff.mjs +524 -0
  643. package/foundation/release/lock-lease.d.mts +23 -0
  644. package/foundation/release/lock-lease.mjs +80 -0
  645. package/foundation/release/notices.d.mts +307 -0
  646. package/foundation/release/notices.mjs +707 -0
  647. package/foundation/release/notices.test.mjs +586 -0
  648. package/foundation/release/npm-guard.d.mts +4 -0
  649. package/foundation/release/npm-guard.mjs +126 -0
  650. package/foundation/release/project.d.mts +141 -0
  651. package/foundation/release/project.mjs +466 -0
  652. package/foundation/release/project.test.mjs +288 -0
  653. package/foundation/release/refresh-worker.d.mts +4 -0
  654. package/foundation/release/refresh-worker.mjs +27 -0
  655. package/foundation/release/run-context.d.mts +47 -0
  656. package/foundation/release/run-context.mjs +163 -0
  657. package/foundation/release/update-notice-env.d.mts +28 -0
  658. package/foundation/release/update-notice-env.mjs +39 -0
  659. package/foundation/response/base.d.ts +26 -3
  660. package/foundation/response/error-codes.d.mts +3 -1
  661. package/foundation/response/error-codes.doc.mjs +12 -0
  662. package/foundation/response/error-codes.mjs +17 -0
  663. package/foundation/response/error-codes.test.mjs +2 -0
  664. package/foundation/response/json-contract.test.mjs +7 -2
  665. package/foundation/response/json.mjs +4 -1
  666. package/foundation/response/response-types.doc.mjs +22 -11
  667. package/foundation/response/response-types.doc.test.mjs +46 -0
  668. package/foundation/response/response.doc.mjs +3 -3
  669. package/foundation/route/route.d.mts +285 -0
  670. package/foundation/route/route.mjs +324 -0
  671. package/foundation/route/route.test.mjs +153 -0
  672. package/foundation/runtime/hosted-runtime.test.mjs +403 -0
  673. package/foundation/runtime/locked-versions.d.mts +32 -0
  674. package/foundation/runtime/locked-versions.mjs +65 -0
  675. package/foundation/runtime/package-root.d.mts +91 -0
  676. package/foundation/runtime/package-root.mjs +174 -0
  677. package/foundation/runtime/package-set.d.mts +62 -0
  678. package/foundation/runtime/package-set.mjs +130 -0
  679. package/foundation/runtime/package-set.test.mjs +432 -0
  680. package/foundation/text/string-utils.d.mts +2 -1
  681. package/foundation/text/string-utils.mjs +16 -5
  682. package/foundation/text/suggest-order.d.mts +72 -0
  683. package/foundation/text/suggest-order.mjs +363 -0
  684. package/foundation/text/suggest-order.test.mjs +259 -0
  685. package/foundation/xle/browser-imports.test.mjs +74 -0
  686. package/foundation/xle/registry.mjs +4 -0
  687. package/foundation/xle/registry.test.mjs +28 -0
  688. package/host/door-conformance.test.mjs +274 -0
  689. package/host/index.d.ts +116 -0
  690. package/host/index.mjs +295 -0
  691. package/host/index.test.mjs +302 -0
  692. package/package.json +16 -11
  693. package/scripts/postinstall.mjs +24 -5
  694. package/assets/docs/tree/integrations.doc.mjs +0 -40
@@ -16,17 +16,27 @@ import {Command, Option} from 'commander';
16
16
  import {fileURLToPath} from 'node:url';
17
17
  import * as fs from 'node:fs';
18
18
  import * as path from 'node:path';
19
- import {getCliInvocation} from '../../foundation/env/package-manager.mjs';
19
+ import {formatCliCommand, getCliInvocation, quoteCommandArgument} from '../../foundation/env/package-manager.mjs';
20
+ import {hasRecordedProject} from '../../foundation/env/cli-command.mjs';
21
+ import {isOutsideProject} from '../../foundation/env/project-scope.mjs';
20
22
  import {API_VERSION, setJsonMode} from '../../foundation/response/json.mjs';
23
+ import {answeredBy, runChoice} from '../../foundation/release/run-context.mjs';
24
+ import {cliInstallAdvice, installFolder} from '../../foundation/release/notices.mjs';
21
25
  import {buildManifest} from './lib/manifest.mjs';
22
26
  import {cliError} from './lib/cli-error.mjs';
23
- import {emit, section, text, records} from './formatters/index.mjs';
27
+ import {section, text, records} from './formatters/index.mjs';
24
28
  import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
25
29
  import {levenshteinDistance} from '../../foundation/text/string-utils.mjs';
26
30
  import {installJsonShim} from './lib/json-shim.mjs';
27
- import {addDocHelp, markReportsResult} from './lib/define-command.mjs';
28
- import {doc as manifestDoc} from './commands/manifest.doc.mjs';
29
- import {isAstryxInitialized} from '../../foundation/agent-docs/agent-docs.mjs';
31
+ import {markReportsResult} from './lib/define-command.mjs';
32
+ import {
33
+ agentDocsTargetDir,
34
+ assertAgentDocsTarget,
35
+ isAstryxInitialized,
36
+ isAstryxPromptInReach,
37
+ } from '../../foundation/agent-docs/agent-docs.mjs';
38
+ import {CLI_ROOT} from '../../foundation/fs/paths.mjs';
39
+ import {setupNudge} from '../../foundation/agent-docs/agent-doc-state.mjs';
30
40
  import * as debug from '../../foundation/debug/index.mjs';
31
41
 
32
42
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -63,7 +73,7 @@ export function handleVersionJsonPreflight(argv = process.argv.slice(2)) {
63
73
  // reports the same shape Commander's own `--version` path does.
64
74
  debug.recordCommandResult(debug.NO_RESULT_SET);
65
75
  debug.setOutcome('ok', {exitCode: 0});
66
- console.log(JSON.stringify({apiVersion: API_VERSION, type: 'version', data: {version: pkg.version}}, null, 2));
76
+ console.log(JSON.stringify({apiVersion: API_VERSION, type: 'version', data: {version: pkg.version}, meta: {answeredBy: answeredBy()}}, null, 2));
67
77
  process.exit(0);
68
78
  }
69
79
 
@@ -98,6 +108,7 @@ export const JSON_SUPPORTED = new Set([
98
108
  'theme targets',
99
109
  'theme palette generate',
100
110
  'integration add',
111
+ 'integration check',
101
112
  'integration verify',
102
113
  'integration pack',
103
114
  'upgrade',
@@ -184,6 +195,31 @@ export async function loadProjectDebugHandler() {
184
195
  }
185
196
  }
186
197
 
198
+ /**
199
+ * Load the project's integrations before a help run, so help prints commands
200
+ * with the `cliCommand` they declare (spec:AST-081 FR5). Help is printed while
201
+ * Commander parses, before any hook, so the preAction load cannot reach it.
202
+ * `Project.load` reads astryx.config and each integration's manifest; it does
203
+ * no discovery. Skipped when the debug preload already loaded the project, and
204
+ * outside a package. Called from the bin before Commander parses.
205
+ *
206
+ * @param {string[]} [argv] arguments after the binary.
207
+ * @returns {Promise<void>}
208
+ */
209
+ export async function loadProjectForHelp(argv = process.argv.slice(2)) {
210
+ const help =
211
+ argv.includes('--help') || argv.includes('-h') || argv[0] === 'help';
212
+ if (!help) return;
213
+ try {
214
+ const cwd = process.cwd();
215
+ if (hasRecordedProject(cwd)) return;
216
+ const {Project} = await import('../../foundation/config/project.mjs');
217
+ await Project.load(cwd);
218
+ } catch {
219
+ // Help prints with the package-manager guess.
220
+ }
221
+ }
222
+
187
223
  /**
188
224
  * Hand the whole invocation to the debug recorder: which command ran, its
189
225
  * positional arguments by name, its options and where each value came from,
@@ -258,7 +294,7 @@ function captureInvocation(actionCommand, root) {
258
294
  */
259
295
  const commands = [
260
296
  {name: 'init', path: './commands/init.mjs', register: 'registerInit'},
261
- {name: 'component', path: './commands/component/index.mjs', register: 'registerComponent'},
297
+ {name: 'component', path: './commands/component.mjs', register: 'registerComponent'},
262
298
  {name: 'docs', path: './commands/docs.mjs', register: 'registerDocs'},
263
299
  {name: 'blog', path: './commands/blog.mjs', register: 'registerBlog'},
264
300
  {name: 'swizzle', path: './commands/swizzle.mjs', register: 'registerSwizzle'},
@@ -266,16 +302,40 @@ const commands = [
266
302
  // agent-docs folded into init — functions still importable from agent-docs.mjs
267
303
  {name: 'template', path: './commands/template.mjs', register: 'registerTemplate'},
268
304
  {name: 'upgrade', path: './commands/upgrade.mjs', register: 'registerUpgrade'},
269
- {name: 'theme', path: './commands/build-theme.mjs', register: 'registerTheme'},
305
+ {name: 'theme', path: './commands/theme.mjs', register: 'registerTheme'},
270
306
  {name: 'integration', path: './commands/integration.mjs', register: 'registerIntegration'},
271
- {name: 'hook', path: './commands/hook/index.mjs', register: 'registerHook'},
307
+ {name: 'hook', path: './commands/hook.mjs', register: 'registerHook'},
272
308
  {name: 'discover', path: './commands/discover.mjs', register: 'registerDiscover'},
273
309
  {name: 'search', path: './commands/search.mjs', register: 'registerSearch'},
274
310
  {name: 'build', path: './commands/build.mjs', register: 'registerBuild'},
275
311
  {name: 'doctor', path: './commands/doctor.mjs', register: 'registerDoctor'},
312
+ // Registered after every other command: the manifest lists the commands in
313
+ // registration order.
314
+ {name: 'manifest', path: './commands/manifest.mjs', register: 'registerManifest'},
315
+ {name: 'postinstall', path: './commands/postinstall.mjs', register: 'registerPostinstall'},
276
316
  ];
277
317
 
278
318
  const SETUP_NUDGE_EXEMPT = new Set(['init', 'agent-docs']);
319
+
320
+ /**
321
+ * Is `cwd` inside the CLI's own source checkout while the CLI runs from it?
322
+ * An installed CLI always lives under `node_modules`; a CLI running from source
323
+ * does not, and its checkout is the pnpm workspace that holds it. Developing
324
+ * Astryx is not an app to set up, so the setup nudge stays quiet there.
325
+ * @param {string} cwd
326
+ * @returns {boolean}
327
+ */
328
+ function inOwnSourceCheckout(cwd) {
329
+ if (CLI_ROOT.split(path.sep).includes('node_modules')) return false;
330
+ let checkout = CLI_ROOT;
331
+ while (!fs.existsSync(path.join(checkout, 'pnpm-workspace.yaml'))) {
332
+ const parent = path.dirname(checkout);
333
+ if (parent === checkout) return false;
334
+ checkout = parent;
335
+ }
336
+ const rel = path.relative(checkout, path.resolve(cwd));
337
+ return rel !== '..' && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel);
338
+ }
279
339
  /** An integration package's manifest: the package is not an app to set up. */
280
340
  const INTEGRATION_MANIFEST_FILES = [
281
341
  'astryx.integration.ts',
@@ -307,7 +367,8 @@ export async function createProgram() {
307
367
  // kit in clients/cli/formatters.
308
368
  program.addHelpText(
309
369
  'after',
310
- '\n' +
370
+ // A function, so the example names the invocation when help is printed.
371
+ () => '\n' +
311
372
  [
312
373
  section(
313
374
  'Output format',
@@ -330,9 +391,13 @@ export async function createProgram() {
330
391
  {fields: ['block', 'shape']},
331
392
  ),
332
393
  text(
333
- 'Grep a field across records, e.g. astryx search button | grep "^command:". ' +
394
+ `Grep a field across records, e.g. ${formatCliCommand('search button')} | grep "^command:". ` +
334
395
  'Errors/warnings go to stderr; use --json for structured parsing.',
335
396
  ),
397
+ text(
398
+ "Global mode: in a project, the project's own CLI answers (this copy hands the run to it); a copy installed for the computer checks for updates once a day and keeps an agent skill in your home folder. " +
399
+ `See ${formatCliCommand('docs global')}.`,
400
+ ),
336
401
  ]
337
402
  .map(block => block.toString())
338
403
  .join('\n\n'),
@@ -429,6 +494,7 @@ export async function createProgram() {
429
494
  // Enriched, self-describing surface (the full manifest payload).
430
495
  manifest,
431
496
  },
497
+ meta: {answeredBy: answeredBy()},
432
498
  }, null, 2));
433
499
  debug.recordCommandResult(
434
500
  debug.resultSet({
@@ -525,10 +591,29 @@ export async function createProgram() {
525
591
  process.exit(1);
526
592
  });
527
593
 
594
+ /**
595
+ * Load the project's integrations before any command runs, so every command
596
+ * it prints starts with the `cliCommand` they declare (the picker reads them
597
+ * synchronously; see foundation/env/cli-command.mjs). Skipped when this
598
+ * process already loaded the project, such as the bin's debug preload. A
599
+ * project that cannot load is the command's to report, never this hook's.
600
+ */
601
+ program.hook('preAction', async () => {
602
+ try {
603
+ const cwd = process.cwd();
604
+ if (hasRecordedProject(cwd)) return;
605
+ const {Project} = await import('../../foundation/config/project.mjs');
606
+ await Project.load(cwd);
607
+ } catch {
608
+ // Best-effort: the picker falls back to its package-manager guess.
609
+ }
610
+ });
611
+
528
612
  /**
529
613
  * Enforcement layer 3 — setup nudge. If this project hasn't run `astryx init`
530
- * yet (no Astryx marker in any agent-doc file — see isAstryxInitialized), remind
531
- * the user/agent that setup is missing.
614
+ * yet (no Astryx marker in any agent-doc file between the project and its
615
+ * repository root — see isAstryxPromptInReach), remind the user/agent that
616
+ * setup is missing.
532
617
  *
533
618
  * Uses `preAction` (not postAction) so it fires for EVERY valid command — even
534
619
  * ones whose action errors or calls process.exit (postAction is skipped then).
@@ -538,7 +623,9 @@ export async function createProgram() {
538
623
  * consumers parse stdout, not stderr — a stderr nudge would not reach them anyway.
539
624
  * The core/cli postinstall layers already nudge at install time regardless of
540
625
  * --json; a machine-readable nudge could later be an envelope field. Also skipped
541
- * for the installer commands themselves and outside a project (no package.json).
626
+ * for the installer commands themselves, outside a project (no package.json,
627
+ * or one that neither installs nor declares Astryx), and inside the CLI's own
628
+ * source checkout when it runs from there.
542
629
  */
543
630
  program.hook('preAction', (thisCommand, actionCommand) => {
544
631
  try {
@@ -546,15 +633,62 @@ export async function createProgram() {
546
633
  if (SETUP_NUDGE_EXEMPT.has(actionCommand.name())) return;
547
634
  const cwd = process.cwd();
548
635
  if (!fs.existsSync(path.join(cwd, 'package.json'))) return; // not a project
636
+ // A package.json that neither installs nor declares Astryx is outside a
637
+ // project: `init` would set up a project the folder does not have
638
+ // (spec AST-081 FR3).
639
+ if (isOutsideProject(cwd)) return;
549
640
  // An integration package is not an app: `init` is not its next step.
550
641
  if (INTEGRATION_MANIFEST_FILES.some(file => fs.existsSync(path.join(cwd, file)))) return;
551
- if (isAstryxInitialized(cwd)) return; // already set up — stay quiet
552
- // Same wording as the core/cli postinstall nudges. #4151's getCliInvocation()
553
- // renders the correct form for THIS project — scoped `npx @astryxdesign/cli`
554
- // one-off, or `<pm> astryx` when installed — never the bare `npx astryx` footgun.
555
- console.error(
556
- `\nNext step: run \`${getCliInvocation(cwd)} init\` to finish setup and install the Astryx agent prompt.`,
557
- );
642
+ if (inOwnSourceCheckout(cwd)) return; // developing Astryx itself, not an app
643
+ if (isAstryxPromptInReach(cwd)) return; // already set up — stay quiet
644
+ // Where init writes the docs, by init's own rule: the project root, which
645
+ // can sit above a nested package such as functions/. Inside a git
646
+ // repository the walk above already reaches it (the root never lies
647
+ // above the repository root), so this changes nothing there; outside a
648
+ // repository the walk checks only cwd, and this finds the root.
649
+ if (isAstryxInitialized(agentDocsTargetDir(cwd))) return;
650
+ // In the home folder, or at the top of a settings folder in it, init
651
+ // writes no agent docs, so naming it would repeat on every command.
652
+ try {
653
+ assertAgentDocsTarget(agentDocsTargetDir(cwd));
654
+ } catch {
655
+ return;
656
+ }
657
+ // Same wording as the core/cli postinstall nudges. getCliInvocation()
658
+ // renders the correct form for THIS project — an integration's cliCommand,
659
+ // scoped `npx @astryxdesign/cli` one-off, or `<pm> astryx` when installed —
660
+ // never npx with the unscoped name, which fetches an unrelated package.
661
+ // A project with no CLI of its own, answered by another release than its
662
+ // Core's: add the CLI at Core's version first, as the daily hint says,
663
+ // then run that CLI's init (spec AST-081 FR2).
664
+ // A folder that belongs to no project spec:AST-040 FR9 defines gets no
665
+ // reminder, as outside a project.
666
+ const target = installFolder(cwd);
667
+ if (target == null) return;
668
+ // From a folder inside the project whose package.json is not the
669
+ // project's, init runs from the project's folder. Only `cd` comes
670
+ // before it, so the command is the picker's for that folder, never the
671
+ // bare `astryx` name a package runner would fetch from the registry
672
+ // (spec AST-081 FR5).
673
+ if (target.moved) {
674
+ console.error(
675
+ setupNudge(getCliInvocation(target.dir), {before: `cd ${quoteCommandArgument(target.dir)}`}).trimEnd(),
676
+ );
677
+ return;
678
+ }
679
+ const choice = runChoice(cwd);
680
+ if (choice.copy === 'starting' && choice.coreVersion && choice.coreVersion !== choice.version) {
681
+ // The daily hint's comparison and command: add the CLI at Core's
682
+ // version, then run that CLI's init.
683
+ const add = cliInstallAdvice({cwd, core: choice.coreVersion});
684
+ if (add?.command) {
685
+ console.error(
686
+ setupNudge(getCliInvocation(add.root, {installed: true}), {before: add.command}).trimEnd(),
687
+ );
688
+ return;
689
+ }
690
+ }
691
+ console.error(setupNudge(getCliInvocation(cwd)).trimEnd());
558
692
  } catch {
559
693
  // Never let the nudge break a command.
560
694
  }
@@ -563,7 +697,7 @@ export async function createProgram() {
563
697
  for (const cmd of commands) {
564
698
  try {
565
699
  const mod = await import(cmd.path);
566
- mod[cmd.register](program);
700
+ mod[cmd.register](program, {jsonSupported: JSON_SUPPORTED, version: pkg.version});
567
701
  } catch (e) {
568
702
  // Command fails to load but CLI still works
569
703
  const reason = /** @type {any} */ (e).message;
@@ -583,84 +717,6 @@ export async function createProgram() {
583
717
  }
584
718
  }
585
719
 
586
- // Capability manifest — a single, self-describing view of the whole CLI so
587
- // agents can discover every command, argument, flag, and response type without
588
- // scraping `--help`. `astryx manifest --json` is the dedicated surface; the bare
589
- // `xds --json` embeds the same payload under data.manifest for convenience.
590
- // Intentionally CLI-special — no `api/manifest`. It introspects the live
591
- // Commander `program`, so extracting it to `api/` would create the `api → cli`
592
- // cycle from #4302. `buildManifest(program)` lives in lib/; see its header.
593
- const manifestCommand = program
594
- .command('manifest')
595
- .description('Print the full CLI capability manifest (use with --json)')
596
- .action(() => {
597
- const manifest = buildManifest(program, {
598
- jsonSupported: JSON_SUPPORTED,
599
- version: pkg.version,
600
- });
601
- // The manifest IS a result set: one entry per command the CLI ships.
602
- debug.recordCommandResult(
603
- debug.resultSet({
604
- count: manifest.commands.length,
605
- resultKind: 'command',
606
- }),
607
- );
608
- if (program.opts().json) {
609
- process.__xdsJsonHandled = true;
610
- console.log(JSON.stringify({apiVersion: API_VERSION, type: 'manifest', data: manifest}, null, 2));
611
- return;
612
- }
613
- // Human-readable summary as greppable records (agents should use --json).
614
- // One record per command: name, whether it supports --json, and the
615
- // description. Field names are the manifest entry's own keys.
616
- emit(
617
- section(`${manifest.name} v${manifest.version} (${manifest.commands.length} commands)`),
618
- records(
619
- manifest.commands.map(c => ({
620
- name: c.name,
621
- json: c.json ? 'yes' : '',
622
- description: c.description || '',
623
- })),
624
- {fields: ['name', 'json', 'description']},
625
- ),
626
- text(`Run \`${getCliInvocation()} manifest --json\` for the full structured manifest.`),
627
- );
628
- });
629
- addDocHelp(manifestCommand, manifestDoc);
630
- markReportsResult(manifestCommand);
631
-
632
- // Hidden command used by package.json postinstall scripts
633
- const postinstallCommand = program
634
- .command('postinstall', {hidden: true})
635
- .action(() => {
636
- // Prints the welcome box. Nothing is looked up.
637
- debug.recordCommandResult(debug.NO_RESULT_SET);
638
- const r = getCliInvocation();
639
- const pad = (/** @type {string} */ s, /** @type {number} */ len) => s + ' '.repeat(Math.max(0, len - s.length));
640
- const W = 49; // inner width of the box
641
- const line = (/** @type {string} */ s) => ` │ ${pad(s, W)}│`;
642
- console.log(`
643
- ╭${'─'.repeat(W + 2)}╮
644
- ${line('')}
645
- ${line(' Design system installed!')}
646
- ${line('')}
647
- ${line(' Get started:')}
648
- ${line(` ${r} init Setup + AI agent docs`)}
649
- ${line(` ${r} --help See all commands`)}
650
- ${line('')}
651
- ${line(' Or run directly:')}
652
- ${line(` ${r} init Setup + AI agent docs`)}
653
- ${line(` ${r} component Browse component docs`)}
654
- ${line(` ${r} hook Browse hook docs`)}
655
- ${line(` ${r} docs Design system reference`)}
656
- ${line(` ${r} swizzle Customize a component`)}
657
- ${line(` ${r} template Add a page template`)}
658
- ${line('')}
659
- ╰${'─'.repeat(W + 2)}╯
660
- `);
661
- });
662
- markReportsResult(postinstallCommand);
663
-
664
720
  // Install the JSON shim AFTER all commands are registered so we can
665
721
  // patch outputHelp on every command (root + subcommands). The shim
666
722
  // extends the --json contract to cover Commander's parse-time short
@@ -53,6 +53,7 @@
53
53
  import {isJsonMode, jsonError as _jsonError, humanWarn} from '../../../foundation/response/json.mjs';
54
54
  import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
55
55
  import {setOutcome} from '../../../foundation/debug/index.mjs';
56
+ import {formatCliCommand} from '../../../foundation/env/package-manager.mjs';
56
57
 
57
58
  /**
58
59
  * Suggestion object — matches the shape used by API errors and the JSON
@@ -122,7 +123,9 @@ export function cliError(message, options = {}) {
122
123
  if (suggestions?.length) {
123
124
  console.error('');
124
125
  for (const s of suggestions) {
125
- const tag = s.reason ? ` ${s.name} (${s.reason})` : ` ${s.name}`;
126
+ // A suggested command stays bare in JSON and is prefixed here.
127
+ const name = /^astryx(\s|$)/.test(s.name) ? formatCliCommand(s.name) : s.name;
128
+ const tag = s.reason ? ` ${name} (${s.reason})` : ` ${name}`;
126
129
  console.error(tag);
127
130
  }
128
131
  }
@@ -21,7 +21,7 @@ import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
21
21
  * (→ `.astryx-table-cell`), and `astryx-button` → key `button`.
22
22
  *
23
23
  * Keep the `astryx-` literal in sync with packages/core/src/naming.ts
24
- * (NAMESPACE / classPrefix), the same way build-theme.mjs mirrors it.
24
+ * (NAMESPACE / classPrefix), the same way commands/theme.mjs mirrors it.
25
25
  * <!-- SYNC: packages/core/src/naming.ts (namespace prefix source of truth) -->
26
26
  * @param {import('@astryxdesign/cli/authoring').ComponentThemingTarget} target
27
27
  * @returns {string}
@@ -67,7 +67,7 @@ describe('formatFull sub-component rendering', () => {
67
67
  expect(out).not.toContain('undefined');
68
68
  // Points the reader at the sub-component's own docs instead of a blank.
69
69
  expect(out).toMatch(
70
- /(?:astryx|@astryxdesign\/cli) component XDSRadioListItem/,
70
+ /(?:astryx|@astryxdesign\/cli(?:@\S+)?) component XDSRadioListItem/,
71
71
  );
72
72
  });
73
73
 
@@ -63,10 +63,10 @@ export function reportsResultVia(cmd) {
63
63
  /**
64
64
  * Mark a hand-registered command as reporting its result.
65
65
  *
66
- * For the handful of commands that cannot come from a CommandDoc — the root
67
- * program, `manifest` (it introspects the live program, so it cannot be
68
- * declared by one), `postinstall`, and the stub left behind when a command
69
- * module fails to load. They call {@link recordCommandResult} themselves; this
66
+ * For what does not come from a CommandDoc: the root program, and the stub
67
+ * left behind when a command module fails to load. Every command, `manifest`
68
+ * and the hidden `postinstall` hook included, registers through
69
+ * {@link defineCommand}. These call {@link recordCommandResult} themselves; this
70
70
  * says so, and the coverage test pins the set of commands allowed to, so the
71
71
  * mark cannot become a quiet way around the contract.
72
72
  *
@@ -105,10 +105,12 @@ export function commandDocsOf(cmd) {
105
105
  * fn?: import('@astryxdesign/cli/authoring').FunctionDoc,
106
106
  * action?: (...args: any[]) => import('../../../foundation/debug/command-result.mjs').CommandResult
107
107
  * | Promise<import('../../../foundation/debug/command-result.mjs').CommandResult>,
108
- * }} [impl]
108
+ * hidden?: boolean,
109
+ * }} [impl] `hidden` keeps the command out of help and the manifest (a
110
+ * package-script hook, not a command for people or agents).
109
111
  * @returns {import('commander').Command} the created command.
110
112
  */
111
- export function defineCommand(parent, doc, {fn, action} = {}) {
113
+ export function defineCommand(parent, doc, {fn, action, hidden} = {}) {
112
114
  // The command token is the last path segment ("theme build" -> "build"),
113
115
  // since subcommands are added to their group command, not the program.
114
116
  const token = doc.name.split(' ').pop() ?? doc.name;
@@ -119,7 +121,10 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
119
121
  })
120
122
  .join(' ');
121
123
 
122
- const cmd = parent.command(argSpec ? `${token} ${argSpec}` : token);
124
+ const cmd = parent.command(
125
+ argSpec ? `${token} ${argSpec}` : token,
126
+ hidden ? {hidden: true} : {},
127
+ );
123
128
  Object.defineProperty(cmd, COMMAND_DOCS, {value: {doc, fn}, configurable: true});
124
129
  if (doc.summary) cmd.description(doc.summary);
125
130
  if (doc.deprecated) {
@@ -180,8 +185,8 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
180
185
  */
181
186
  export function addDocHelp(cmd, doc) {
182
187
  addExitCodesHelp(cmd, doc.exitCodes);
183
- // Rendered when help is shown, so the run prefix (npx astryx, pnpm astryx,
184
- // ...) is looked up then, not on every start.
188
+ // Rendered when help is shown, so the run prefix (pnpm exec astryx, yarn
189
+ // astryx, ...) is looked up then, not on every start.
185
190
  cmd.addHelpText('after', () => {
186
191
  const examples = (doc.examples ?? []).flatMap(({label, cli}) => [
187
192
  ...(label ? [` # ${label}`] : []),
@@ -24,6 +24,10 @@ for (const file of fs.readdirSync(COMMANDS).sort()) {
24
24
  }
25
25
 
26
26
  const manifest = buildManifest(program, {jsonSupported: JSON_SUPPORTED, version: '0.0.0-test'});
27
+ /** Hidden commands (a package-script hook): documented, never in the manifest. */
28
+ const HIDDEN = new Set(
29
+ program.commands.filter((c) => /** @type {any} */ (c)._hidden).map((c) => c.name()),
30
+ );
27
31
  /** @type {Map<string, any>} */
28
32
  const entries = new Map();
29
33
  const walk = (/** @type {any} */ c) => {
@@ -98,6 +102,7 @@ describe('command exit codes', () => {
98
102
 
99
103
  it('the manifest carries every command exit code', () => {
100
104
  for (const doc of commandDocs) {
105
+ if (HIDDEN.has(doc.name)) continue;
101
106
  expect(entries.get(doc.name)?.exitCodes, doc.name).toEqual(
102
107
  doc.exitCodes.map(({code, when}) => ({code, when})),
103
108
  );
@@ -42,6 +42,7 @@
42
42
  */
43
43
 
44
44
  import {API_VERSION, isJsonMode, toErrorEnvelope} from '../../../foundation/response/json.mjs';
45
+ import {answeredBy} from '../../../foundation/release/run-context.mjs';
45
46
  import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
46
47
  import {setCommand, setOutcome, recordHelp} from '../../../foundation/debug/index.mjs';
47
48
 
@@ -84,7 +85,7 @@ function jsonActive() {
84
85
  * subcommand (e.g. `astryx component --help --json`).
85
86
  *
86
87
  * @param {import('commander').Command} cmd
87
- * @returns {{apiVersion: number, type: 'help', data: object}}
88
+ * @returns {{apiVersion: number, type: 'help', data: object, meta: {answeredBy: {cli: string, core: string | null, copy: 'project' | 'starting' | 'matched' | 'carried' | 'fallback'}}}}
88
89
  */
89
90
  export function buildHelpEnvelope(cmd) {
90
91
  // Reconstruct the fully-qualified command name (e.g. "astryx theme build").
@@ -119,6 +120,7 @@ export function buildHelpEnvelope(cmd) {
119
120
  options,
120
121
  subcommands,
121
122
  },
123
+ meta: {answeredBy: answeredBy()},
122
124
  };
123
125
  }
124
126
 
@@ -50,6 +50,13 @@ export interface ManifestCommand {
50
50
  examples?: string[];
51
51
  /** Documented exit codes: the process exit status and when it occurs. */
52
52
  exitCodes?: {code: number; when: string}[];
53
+ /**
54
+ * What the command does in a folder outside any project: `same` gives the
55
+ * answer it gives in a new project; `refuse` writes nothing and fails, naming
56
+ * the app project or integration package it needs; `own` does something
57
+ * else, which its docs state. Absent on a group that only holds subcommands.
58
+ */
59
+ outsideProject?: 'same' | 'refuse' | 'own';
53
60
  /** Nested subcommands (e.g. `theme build` under `theme`). */
54
61
  subcommands?: ManifestCommand[];
55
62
  }
@@ -64,6 +71,8 @@ export interface CLIManifest {
64
71
  commands: ManifestCommand[];
65
72
  /** Sorted list of fully-qualified command names that support `--json`. */
66
73
  jsonSupported: string[];
74
+ /** What a run may do beyond its command (the hand-off, the daily update check, the agent skill), and the docs topic that explains it. */
75
+ globalMode: {docs: string; summary: string};
67
76
  /** Flat index of response `type` discriminators keyed by command name. */
68
77
  responseTypes: Record<string, string[]>;
69
78
  }
@@ -9,7 +9,8 @@
9
9
  *
10
10
  * Its per-command facts come from the command's own definitions: names,
11
11
  * arguments and options from Commander metadata (program.commands, cmd.options,
12
- * cmd.registeredArguments, cmd.description()); examples from its CommandDoc;
12
+ * cmd.registeredArguments, cmd.description()); examples, exit codes, and what
13
+ * it does outside a project from its CommandDoc;
13
14
  * response `type` discriminators from the returns of the FunctionDoc it wraps
14
15
  * (both attached by `defineCommand`); `--json` support from the JSON_SUPPORTED
15
16
  * allowlist in index.mjs. The hand-kept lists are CLI_LAYER_RESPONSE_TYPES,
@@ -39,6 +40,16 @@ import {API_VERSION} from '../../../foundation/response/json.mjs';
39
40
  import {commandDocsOf} from './define-command.mjs';
40
41
  import {doc as manifestDoc} from '../commands/manifest.doc.mjs';
41
42
 
43
+ /**
44
+ * What a run may do beyond the command it was asked for (spec AST-081;
45
+ * `spec:AST-017` FR14), and where it is explained.
46
+ */
47
+ export const GLOBAL_MODE = Object.freeze({
48
+ docs: 'astryx docs global',
49
+ summary:
50
+ "In a folder that belongs to a project, the project's own CLI answers: this copy hands the run to it. In a project with no CLI of its own, and outside any project, this copy answers. A copy installed for the computer checks the registry for a newer release once a day in the background, and keeps one agent skill file in the home folder.",
51
+ });
52
+
42
53
  /**
43
54
  * Envelopes the CLI layer builds itself, so the wrapped FunctionDoc cannot
44
55
  * declare them: `manifest` wraps no API function, `theme build` batches several
@@ -194,6 +205,10 @@ function describeCommand(cmd, root, jsonSupported) {
194
205
  }));
195
206
  if (exitCodes.length > 0) entry.exitCodes = exitCodes;
196
207
 
208
+ // What the command does outside a project (spec AST-081 FR4). Every command
209
+ // declares it in its CommandDoc; a group that only holds subcommands does not.
210
+ if (docs?.doc.outsideProject) entry.outsideProject = docs.doc.outsideProject;
211
+
197
212
  // Sort subcommands by name for a stable, agent-facing contract — the same
198
213
  // guarantee the top-level command list makes. Otherwise Commander
199
214
  // registration order leaks into the manifest and a pure reorder of
@@ -265,6 +280,7 @@ export function buildManifest(program, opts = {}) {
265
280
  globalOptions: describeGlobalOptions(program),
266
281
  commands,
267
282
  jsonSupported: [...jsonSupported].sort(),
283
+ globalMode: GLOBAL_MODE,
268
284
  // Flat index of every response `type` discriminator the CLI can emit,
269
285
  // keyed by command — lets an agent know what to expect back per call.
270
286
  responseTypes: Object.fromEntries(
@@ -55,6 +55,10 @@ const CLI_LAYER_TYPES = {
55
55
  };
56
56
 
57
57
  const manifest = buildManifest(program, {jsonSupported: JSON_SUPPORTED, version: '0.0.0-test'});
58
+ /** Hidden commands (a package-script hook): documented, never in the manifest. */
59
+ const HIDDEN = new Set(
60
+ program.commands.filter((c) => /** @type {any} */ (c)._hidden).map((c) => c.name()),
61
+ );
58
62
 
59
63
  /** Flatten the manifest command tree into fully-qualified names. */
60
64
  function flatten(cmds, out = []) {
@@ -116,12 +120,19 @@ describe('manifest: drift guards', () => {
116
120
 
117
121
  it('takes every command example from its CommandDoc', () => {
118
122
  for (const [name, doc] of commandDocs) {
123
+ if (HIDDEN.has(name)) continue;
119
124
  const entry = allEntries.find((c) => c.name === name);
120
125
  expect(entry, `CommandDoc "${name}" has no manifest entry`).toBeDefined();
121
126
  expect(entry.examples ?? [], name).toEqual((doc.examples ?? []).map((e) => e.cli));
122
127
  }
123
128
  });
124
129
 
130
+ it('documents the hidden postinstall hook and keeps it out of the manifest', () => {
131
+ expect([...HIDDEN]).toEqual(['postinstall']);
132
+ expect(commandDocs.has('postinstall')).toBe(true);
133
+ expect(allNames.has('postinstall')).toBe(false);
134
+ });
135
+
125
136
  it('lists every response type the wrapped API function returns', () => {
126
137
  for (const [name, doc] of commandDocs) {
127
138
  if (!doc.fn) continue;
@@ -152,6 +163,7 @@ describe('manifest: drift guards', () => {
152
163
 
153
164
  it('takes response types from the wrapped FunctionDoc, plus CLI-layer envelopes', () => {
154
165
  for (const [name, doc] of commandDocs) {
166
+ if (HIDDEN.has(name)) continue;
155
167
  const entry = allEntries.find((c) => c.name === name);
156
168
  const returns = doc.fn ? functionDocs.get(doc.fn).returns.map((r) => r.type) : [];
157
169
  const expected = [...returns, ...(CLI_LAYER_TYPES[name] ?? [])];
@@ -307,3 +319,28 @@ describe('manifest: text projection', () => {
307
319
  for (const key of textKeys) expect(jsonKeys).toContain(key);
308
320
  });
309
321
  });
322
+
323
+ describe('global mode is discoverable (spec:AST-017 FR14)', () => {
324
+ it('the manifest names what a run may do beyond its command, and the docs topic that explains it', () => {
325
+ expect(manifest.globalMode.docs).toBe('astryx docs global');
326
+ for (const word of ['hands the run', 'once a day', 'agent skill']) {
327
+ expect(manifest.globalMode.summary).toContain(word);
328
+ }
329
+ });
330
+
331
+ it('--help carries one line pointing to the global mode docs', () => {
332
+ const help = program.helpInformation() + '';
333
+ let after = '';
334
+ program.emit('afterHelp', {
335
+ error: false,
336
+ write: (/** @type {string} */ s) => {
337
+ after += s;
338
+ },
339
+ });
340
+ const lines = `${help}${after}`
341
+ .split('\n')
342
+ .filter(line => line.startsWith('Global mode:'));
343
+ expect(lines).toHaveLength(1);
344
+ expect(lines[0]).toMatch(/docs global\.$/u);
345
+ });
346
+ });