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

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 (276) hide show
  1. package/README.md +22 -1
  2. package/api/blog/blog.doc.mjs +1 -0
  3. package/api/build/build.doc.mjs +1 -0
  4. package/api/component/component.doc.mjs +1 -0
  5. package/api/discover/discover.doc.mjs +1 -0
  6. package/api/docs/_adapter.d.mts +3 -8
  7. package/api/docs/_adapter.mjs +13 -105
  8. package/api/docs/detail/section/section.mjs +9 -15
  9. package/api/docs/detail/section/section.test.mjs +15 -6
  10. package/api/docs/docs.doc.mjs +1 -0
  11. package/api/docs/list/list.mjs +3 -7
  12. package/api/doctor/doctor.d.mts +25 -3
  13. package/api/doctor/doctor.doc.mjs +1 -0
  14. package/api/doctor/doctor.mjs +186 -14
  15. package/api/doctor/doctor.test.mjs +332 -7
  16. package/api/gap-report/gap-report.doc.mjs +1 -0
  17. package/api/hook/_adapter.mjs +19 -5
  18. package/api/hook/hook.doc.mjs +1 -0
  19. package/api/hook/list/list.d.mts +1 -1
  20. package/api/hook/list/list.mjs +69 -17
  21. package/api/init/init.doc.mjs +1 -0
  22. package/api/integration/add-contribution.mjs +7 -7
  23. package/api/integration/add-contribution.test.mjs +37 -3
  24. package/api/integration/add-theme.mjs +34 -64
  25. package/api/integration/add-theme.test.mjs +105 -21
  26. package/api/integration/authoring-checks.test.mjs +8 -4
  27. package/api/integration/integration-block-exports.test.mjs +10 -6
  28. package/api/integration/integrationAdd.doc.mjs +1 -0
  29. package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
  30. package/api/integration/integrationAddCodemod.doc.mjs +1 -0
  31. package/api/integration/integrationAddComponent.doc.mjs +1 -0
  32. package/api/integration/integrationAddDoc.doc.mjs +1 -0
  33. package/api/integration/integrationAddTemplate.doc.mjs +1 -0
  34. package/api/integration/integrationAddTheme.doc.mjs +6 -5
  35. package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
  36. package/api/integration/integrationDocConflicts.doc.mjs +1 -0
  37. package/api/integration/integrationPackCheck.doc.mjs +1 -0
  38. package/api/integration/integrationTemplateConflicts.doc.mjs +1 -0
  39. package/api/integration/pack-check.test.mjs +17 -47
  40. package/api/integration/summarizeIssues.doc.mjs +1 -0
  41. package/api/integration/validate-integration-fixes.test.mjs +1389 -0
  42. package/api/integration/validate-integration.mjs +50 -102
  43. package/api/integration/validate-integration.test.mjs +85 -23
  44. package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
  45. package/api/integration/validateIntegration.doc.mjs +1 -0
  46. package/api/json/assertResponse.doc.mjs +1 -0
  47. package/api/json/isError.doc.mjs +1 -0
  48. package/api/json/parseResponse.doc.mjs +1 -0
  49. package/api/layout/layoutCheck.doc.mjs +1 -0
  50. package/api/layout/layoutExpand.doc.mjs +1 -0
  51. package/api/layout/layoutGrammar.doc.mjs +1 -0
  52. package/api/search/search.doc.mjs +1 -0
  53. package/api/search/search.mjs +16 -6
  54. package/api/swizzle/swizzle.doc.mjs +1 -0
  55. package/api/template/template-suffix.test.mjs +41 -21
  56. package/api/template/template.doc.mjs +1 -0
  57. package/api/theme/_adapter.d.mts +2 -3
  58. package/api/theme/_adapter.mjs +4 -5
  59. package/api/theme/add/add.binary.test.mjs +10 -17
  60. package/api/theme/add/add.test.mjs +14 -1
  61. package/api/theme/generateTonalPalette.doc.mjs +1 -0
  62. package/api/theme/integration-themes.test.mjs +39 -28
  63. package/api/theme/list/list.test.mjs +19 -20
  64. package/api/theme/listThemes.doc.mjs +6 -5
  65. package/api/theme/themeAdd.doc.mjs +4 -3
  66. package/api/theme/themeBuild.doc.mjs +1 -0
  67. package/api/theme/themeList.doc.mjs +6 -3
  68. package/api/theme/themeListAvailable.doc.mjs +5 -3
  69. package/api/theme/themePaletteGenerate.doc.mjs +1 -0
  70. package/api/theme/themeTargets.doc.mjs +1 -0
  71. package/api/theme/themeTemplate.doc.mjs +1 -0
  72. package/api/upgrade/_adapter.d.mts +32 -5
  73. package/api/upgrade/_adapter.mjs +97 -69
  74. package/api/upgrade/provider-agreement.test.mjs +152 -0
  75. package/api/upgrade/run/run.mjs +356 -59
  76. package/api/upgrade/upgrade.doc.mjs +6 -1
  77. package/api/upgrade/upgrade.type.d.mts +34 -0
  78. package/api/upgrade/upgrade.type.mjs +15 -0
  79. package/assets/codemods/__tests__/runner.test.mjs +330 -8
  80. package/assets/codemods/integration-discovery.mjs +8 -2
  81. package/assets/codemods/integration-discovery.test.mjs +15 -0
  82. package/assets/codemods/integration-runner.mjs +56 -4
  83. package/assets/codemods/integration-runner.protection.test.mjs +153 -0
  84. package/assets/codemods/run-codemod.mjs +177 -34
  85. package/assets/codemods/runner.mjs +350 -102
  86. package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
  87. package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
  88. package/assets/codemods/transforms/next/index.mjs +19 -1
  89. package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
  90. package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
  91. package/assets/docs/cli-integrations.doc.mjs +30 -30
  92. package/assets/docs/cli.doc.mjs +15 -0
  93. package/assets/docs/theme.doc.mjs +1 -1
  94. package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
  95. package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
  96. package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
  97. package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
  98. package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
  99. package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
  100. package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
  101. package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
  102. package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
  103. package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
  104. package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
  105. package/authoring/codemod/codemod.doc.mjs +1 -1
  106. package/authoring/codemod/type.ts +12 -0
  107. package/authoring/config/config.doc.mjs +1 -1
  108. package/authoring/debug/debug.doc.d.mts +11 -0
  109. package/authoring/debug/debug.doc.mjs +182 -0
  110. package/authoring/doctypes/_schema.d.mts +71 -141
  111. package/authoring/doctypes/_schema.mjs +29 -2
  112. package/authoring/doctypes/base/graph-fields.doc.mjs +1 -1
  113. package/authoring/doctypes/command/command.doc.mjs +1 -1
  114. package/authoring/doctypes/command/type.ts +1 -1
  115. package/authoring/doctypes/component/type.ts +2 -2
  116. package/authoring/doctypes/doctypes-new.test.mjs +48 -6
  117. package/authoring/doctypes/enum/enum.doc.mjs +1 -1
  118. package/authoring/doctypes/enum/type.ts +1 -1
  119. package/authoring/doctypes/function/function.doc.mjs +1 -1
  120. package/authoring/doctypes/function/type.ts +1 -1
  121. package/authoring/doctypes/hook/type.ts +2 -2
  122. package/authoring/doctypes/load-contract.test.mjs +3 -2
  123. package/authoring/doctypes/namespace/namespace.doc.mjs +2 -2
  124. package/authoring/doctypes/namespace/parse.test.mjs +23 -25
  125. package/authoring/doctypes/namespace/type.ts +5 -2
  126. package/authoring/doctypes/parse.d.mts +4 -2
  127. package/authoring/doctypes/parse.mjs +10 -5
  128. package/authoring/doctypes/reference/reference.doc.mjs +6 -4
  129. package/authoring/doctypes/reference/type.ts +9 -10
  130. package/authoring/doctypes/schema/schema.doc.mjs +1 -1
  131. package/authoring/doctypes/schema/type.ts +1 -2
  132. package/authoring/doctypes/template/template.doc.mjs +3 -3
  133. package/authoring/doctypes/theme/parse.d.mts +35 -0
  134. package/authoring/doctypes/theme/parse.mjs +76 -0
  135. package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
  136. package/authoring/doctypes/theme/theme.doc.mjs +79 -0
  137. package/authoring/doctypes/theme/type.ts +42 -0
  138. package/authoring/doctypes/types.ts +2 -1
  139. package/authoring/gap-report/gap-report.doc.d.mts +12 -0
  140. package/authoring/gap-report/gap-report.doc.mjs +183 -0
  141. package/authoring/index.d.mts +1 -0
  142. package/authoring/index.d.ts +7 -4
  143. package/authoring/index.mjs +2 -1
  144. package/authoring/integration/integration.doc.mjs +2 -2
  145. package/authoring/integration/type.ts +3 -9
  146. package/clients/cli/__tests__/cliManifest.test.ts +27 -29
  147. package/clients/cli/commands/blog.doc.mjs +1 -1
  148. package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
  149. package/clients/cli/commands/build-theme.mjs +10 -44
  150. package/clients/cli/commands/build.doc.mjs +1 -1
  151. package/clients/cli/commands/component.doc.mjs +1 -1
  152. package/clients/cli/commands/discover.doc.mjs +1 -1
  153. package/clients/cli/commands/docs.doc.mjs +1 -1
  154. package/clients/cli/commands/docs.mjs +15 -58
  155. package/clients/cli/commands/docs.test.mjs +11 -14
  156. package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
  157. package/clients/cli/commands/doctor-integration-docs.doc.mjs +1 -1
  158. package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -1
  159. package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
  160. package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
  161. package/clients/cli/commands/doctor-integration.test.mjs +15 -7
  162. package/clients/cli/commands/doctor.doc.mjs +1 -1
  163. package/clients/cli/commands/gap-report.doc.mjs +1 -1
  164. package/clients/cli/commands/hook.doc.mjs +1 -1
  165. package/clients/cli/commands/init.doc.mjs +1 -1
  166. package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
  167. package/clients/cli/commands/integration-add.doc.mjs +1 -1
  168. package/clients/cli/commands/integration-pack.doc.mjs +1 -1
  169. package/clients/cli/commands/integration-real-world.test.mjs +3 -9
  170. package/clients/cli/commands/integration.doc.mjs +1 -1
  171. package/clients/cli/commands/layout-check.doc.mjs +1 -1
  172. package/clients/cli/commands/layout-expand.doc.mjs +1 -1
  173. package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
  174. package/clients/cli/commands/layout.doc.mjs +1 -1
  175. package/clients/cli/commands/manifest.doc.mjs +1 -1
  176. package/clients/cli/commands/search.doc.mjs +1 -1
  177. package/clients/cli/commands/swizzle.doc.mjs +1 -1
  178. package/clients/cli/commands/template.doc.mjs +1 -1
  179. package/clients/cli/commands/text-json-parity.test.mjs +718 -0
  180. package/clients/cli/commands/theme-add.doc.mjs +2 -2
  181. package/clients/cli/commands/theme-build.doc.mjs +1 -1
  182. package/clients/cli/commands/theme-list.doc.mjs +2 -2
  183. package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
  184. package/clients/cli/commands/theme-palette.doc.mjs +1 -1
  185. package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
  186. package/clients/cli/commands/theme-targets.doc.mjs +1 -1
  187. package/clients/cli/commands/theme-template.doc.mjs +1 -1
  188. package/clients/cli/commands/theme.doc.mjs +1 -1
  189. package/clients/cli/commands/upgrade.doc.mjs +3 -2
  190. package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
  191. package/clients/cli/commands/upgrade.mjs +29 -7
  192. package/clients/cli/formatters/index.mjs +2 -0
  193. package/clients/cli/formatters/index.test.mjs +6 -0
  194. package/clients/cli/lib/hook-format.mjs +14 -5
  195. package/foundation/config/project-themes.test.mjs +11 -19
  196. package/foundation/config/project.d.mts +8 -0
  197. package/foundation/config/project.mjs +50 -21
  198. package/foundation/config/project.test.mjs +3 -16
  199. package/foundation/discovery/authoring-self-docs.d.mts +6 -0
  200. package/foundation/discovery/authoring-self-docs.mjs +17 -7
  201. package/foundation/discovery/authoring-self-docs.test.mjs +3 -2
  202. package/foundation/discovery/authoring-surface.d.mts +74 -0
  203. package/foundation/discovery/authoring-surface.mjs +525 -0
  204. package/foundation/discovery/authoring-surface.test.mjs +392 -0
  205. package/foundation/discovery/cli-self-docs.d.mts +113 -0
  206. package/foundation/discovery/cli-self-docs.mjs +514 -0
  207. package/foundation/discovery/cli-self-docs.test.mjs +437 -0
  208. package/foundation/discovery/component-loader.d.mts +35 -38
  209. package/foundation/discovery/component-loader.mjs +53 -222
  210. package/foundation/discovery/docs-discovery.d.mts +3 -2
  211. package/foundation/discovery/docs-discovery.mjs +14 -17
  212. package/foundation/discovery/docs-discovery.test.mjs +15 -15
  213. package/foundation/discovery/docs-section-key.d.mts +19 -8
  214. package/foundation/discovery/docs-section-key.mjs +119 -32
  215. package/foundation/discovery/docs-section-key.test.mjs +41 -19
  216. package/foundation/discovery/template-adapter.d.mts +7 -0
  217. package/foundation/discovery/template-adapter.mjs +27 -40
  218. package/foundation/discovery/template-adapter.test.mjs +15 -0
  219. package/foundation/discovery/theme-discovery.d.mts +67 -7
  220. package/foundation/discovery/theme-discovery.mjs +916 -186
  221. package/foundation/discovery/theme-discovery.test.mjs +613 -219
  222. package/foundation/doc-compiler/bundle.d.mts +47 -0
  223. package/foundation/doc-compiler/bundle.mjs +218 -0
  224. package/foundation/doc-compiler/bundle.test.mjs +255 -0
  225. package/foundation/doc-compiler/compile.d.mts +200 -0
  226. package/foundation/doc-compiler/compile.mjs +259 -9
  227. package/foundation/doc-compiler/diagnostics.d.mts +126 -0
  228. package/foundation/doc-compiler/diagnostics.mjs +277 -0
  229. package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
  230. package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
  231. package/foundation/doc-compiler/import.d.mts +24 -0
  232. package/foundation/doc-compiler/import.mjs +59 -0
  233. package/foundation/doc-compiler/inputs.d.mts +102 -0
  234. package/foundation/doc-compiler/inputs.mjs +286 -0
  235. package/foundation/doc-compiler/inputs.test.mjs +299 -0
  236. package/foundation/doc-compiler/ir.d.mts +13 -0
  237. package/foundation/doc-compiler/ir.mjs +189 -12
  238. package/foundation/doc-compiler/lower-doc.test.mjs +492 -0
  239. package/foundation/doc-compiler/overlays.d.mts +37 -0
  240. package/foundation/doc-compiler/overlays.mjs +206 -0
  241. package/foundation/doc-compiler/parse-readable.d.mts +9 -0
  242. package/foundation/doc-compiler/parse-readable.mjs +29 -0
  243. package/foundation/doc-compiler/read.d.mts +126 -0
  244. package/foundation/doc-compiler/read.mjs +320 -0
  245. package/foundation/doc-compiler/read.test.mjs +313 -0
  246. package/foundation/doc-compiler/source.d.mts +33 -0
  247. package/foundation/doc-compiler/source.mjs +128 -0
  248. package/foundation/fs/file-protection.d.mts +33 -0
  249. package/foundation/fs/file-protection.mjs +825 -0
  250. package/foundation/fs/file-protection.test.mjs +250 -0
  251. package/foundation/integrations/autolink.d.mts +58 -1
  252. package/foundation/integrations/autolink.mjs +143 -57
  253. package/foundation/integrations/contribution-fixes.d.mts +145 -0
  254. package/foundation/integrations/contribution-fixes.mjs +1284 -0
  255. package/foundation/integrations/contribution-inventory.d.mts +1 -1
  256. package/foundation/integrations/contribution-inventory.mjs +17 -20
  257. package/foundation/integrations/contribution-inventory.test.mjs +67 -27
  258. package/foundation/integrations/integrations.d.mts +3 -0
  259. package/foundation/integrations/integrations.mjs +11 -97
  260. package/foundation/integrations/provider-ledger.test.mjs +275 -0
  261. package/foundation/integrations/provider-resolution.d.mts +152 -0
  262. package/foundation/integrations/provider-resolution.mjs +576 -0
  263. package/foundation/integrations/provider-resolution.test.mjs +369 -0
  264. package/foundation/integrations/theme-descriptor.d.mts +8 -0
  265. package/foundation/integrations/theme-descriptor.mjs +44 -0
  266. package/foundation/integrations/validate-contributions.mjs +104 -10
  267. package/foundation/response/error-codes.d.mts +3 -1
  268. package/foundation/response/error-codes.d.ts +2 -0
  269. package/foundation/response/error-codes.doc.mjs +12 -2
  270. package/foundation/response/error-codes.mjs +7 -1
  271. package/foundation/response/error-codes.test.mjs +55 -11
  272. package/foundation/response/response-types.doc.mjs +1 -1
  273. package/foundation/response/response.doc.mjs +1 -1
  274. package/foundation/text/string-utils.mjs +22 -10
  275. package/package.json +10 -9
  276. package/assets/templates/themes/manifest.json +0 -95
package/README.md CHANGED
@@ -15,6 +15,25 @@ npx @astryxdesign/cli template --list
15
15
 
16
16
  Once it's a project dependency (`npm install -D @astryxdesign/cli`), drop the scope and use the shorter `astryx` — e.g. `npx astryx component Button` or `pnpm exec astryx component Button`. Bare `astryx` resolves to an unrelated npm package until the CLI is installed, so prefer the scoped form above for first-run/one-off use.
17
17
 
18
+ ## Reading the CLI's own docs
19
+
20
+ The CLI documents itself, so these commands print what the installed version does:
21
+
22
+ - `astryx <command> --help`: one command's arguments and options.
23
+ - `astryx manifest --json`: every command, option, and response type, as JSON.
24
+ - `astryx docs cli --index`: one section for each command (`commands-<name>`)
25
+ and each API function, plus the JSON output envelope, error codes, and
26
+ response types (`api-<name>`). Read one with `astryx docs cli <key>`, for
27
+ example `astryx docs cli api-search`.
28
+ - `astryx docs authoring --index`: the authoring reference, with one section for
29
+ each file an author writes: the `astryx.config.*` file, the
30
+ `astryx.integration.*` manifest, codemods, and every doc type (`ComponentDoc`,
31
+ `TemplateDoc`, `ThemeDoc`, and the rest). Read one section with
32
+ `astryx docs authoring <section>`, for example `astryx docs authoring config`.
33
+ - `astryx docs cli-integrations`: the guide to building an integration package.
34
+ - `astryx docs`: every docs topic, including the design-system guides (for
35
+ example `tokens`, `theme`, and `layout`).
36
+
18
37
  ## Finding things: `astryx search`
19
38
 
20
39
  When you don't know whether what you need is a component, a hook, a docs topic,
@@ -170,6 +189,8 @@ if (isError(result)) {
170
189
  | `ERR_UNKNOWN_FEATURE` | An unrecognized `--features` value was passed to init. |
171
190
  | `ERR_UNKNOWN_CODEMOD` | A `--codemod` value did not match any registered codemod (upgrade). |
172
191
  | `ERR_CODEMOD_FAILED` | One or more codemods failed during an upgrade run. |
192
+ | `ERR_CODEMOD_PROTECTED` | A required codemod change remains blocked by a protected consumer file. |
193
+ | `ERR_CODEMOD_PROTECTION_SOURCE` | A working-tree protection declaration could not be read or parsed. |
173
194
  | `ERR_NOT_FOUND` | A generic discover/lookup query matched nothing in any package. |
174
195
  | `ERR_NO_DOC` | A component exists but has no typed `.doc.mjs` file. |
175
196
  | `ERR_NO_SHOWCASE` | No showcase exists for the requested component. |
@@ -179,7 +200,7 @@ if (isError(result)) {
179
200
  | `ERR_FILE_EXISTS` | Refused to overwrite an existing file. |
180
201
  | `ERR_PATH_TRAVERSAL` | A path escaped its allowed root, or a name contained traversal markers. |
181
202
  | `ERR_WRITE_FAILED` | Writing output files failed (and was rolled back). |
182
- | `ERR_THEME_INVALID` | A theme definition or contributed theme catalog is invalid. |
203
+ | `ERR_THEME_INVALID` | A theme definition or contributed theme descriptor is invalid. |
183
204
  | `ERR_THEME_LOAD` | A theme file could not be loaded / parsed into a defineTheme result. |
184
205
  | `ERR_PALETTE_GENERATION` | A palette generation request or one of its constraints was invalid. |
185
206
  | `ERR_VERSION_DETECT` | The current `@astryxdesign/core` version could not be detected. |
@@ -11,6 +11,7 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'blog',
14
+ namespace: 'cli/api',
14
15
  displayName: 'blog()',
15
16
  summary: 'List blog posts, or read one, from the published RSS feed.',
16
17
  description:
@@ -11,6 +11,7 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'build',
14
+ namespace: 'cli/api',
14
15
  displayName: 'build()',
15
16
  summary:
16
17
  'Page-building assistant: the how-to-build playbook, or a composition kit for an idea.',
@@ -12,6 +12,7 @@ export const doc = {
12
12
  type: 'function',
13
13
  kind: 'api',
14
14
  name: 'component',
15
+ namespace: 'cli/api',
15
16
  displayName: 'component()',
16
17
  summary:
17
18
  'Resolve a component by name, or list the catalog, with optional focused slices (props, source, showcase, blocks).',
@@ -11,6 +11,7 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'discover',
14
+ namespace: 'cli/api',
14
15
  displayName: 'discover()',
15
16
  summary: 'Browse and search components from configured external packages.',
16
17
  description:
@@ -15,12 +15,6 @@
15
15
  * @returns {Promise<DocsCatalog>}
16
16
  */
17
17
  export function loadDocsCatalog(cwd?: string): Promise<DocsCatalog>;
18
- /**
19
- * The overlay languages a topic ships for its own file or any extension.
20
- * @param {import('../../foundation/discovery/docs-discovery.mjs').DocsTopicEntry} entry
21
- * @returns {string[]}
22
- */
23
- export function overlayLanguages(entry: import("../../foundation/discovery/docs-discovery.mjs").DocsTopicEntry): string[];
24
18
  /**
25
19
  * One topic, lowered for `lang`: overlaid, extensions merged, keys stamped.
26
20
  * Memoized per catalog, so a read that references a topic twice loads it once.
@@ -76,6 +70,7 @@ export function resolveTopicDocs(topic: string, options?: {
76
70
  node: import("../../foundation/doc-compiler/compile.mjs").CompiledReferenceNode;
77
71
  lang: string | null;
78
72
  }>;
79
- /** The localized overlays a docs read can apply. */
80
- export const OVERLAY_LANGUAGES: string[];
81
73
  import { DocsCatalog } from '../../foundation/discovery/docs-discovery.mjs';
74
+ import { OVERLAY_LANGUAGES } from '../../foundation/doc-compiler/read.mjs';
75
+ import { overlayLanguages } from '../../foundation/doc-compiler/read.mjs';
76
+ export { OVERLAY_LANGUAGES, overlayLanguages };
@@ -10,24 +10,29 @@
10
10
  * @output Catalog access, the compiler input for a topic, and the compiled
11
11
  * node for it: lowered (overlaid, extensions merged, keys stamped) or linked
12
12
  * (token references resolved too), memoized per catalog.
13
- * @position Sits beside docs.mjs (api/docs/). Loads authored files and hands
14
- * them to foundation/doc-compiler, so no leaf, doctor check or search loads,
15
- * merges, or resolves docs on its own. Discovery itself lives in
13
+ * @position Sits beside docs.mjs (api/docs/). Hands topics to
14
+ * foundation/doc-compiler (which loads their files) and memoizes the nodes
15
+ * per catalog, so no leaf, doctor check or search loads, merges, or resolves
16
+ * docs on its own. Discovery itself lives in
16
17
  * foundation/discovery/docs-discovery, which the catalog comes from.
17
18
  */
18
19
 
19
- import * as fs from 'node:fs';
20
- import * as path from 'node:path';
21
- import {pathToFileURL} from 'node:url';
22
20
  import {Project} from '../../foundation/config/project.mjs';
23
21
  import {DocsCatalog} from '../../foundation/discovery/docs-discovery.mjs';
24
22
  import {
25
23
  linkReferenceTopic,
26
24
  lowerReferenceTopic,
27
25
  } from '../../foundation/doc-compiler/compile.mjs';
26
+ import {
27
+ deepFreeze,
28
+ loadTopicInput,
29
+ OVERLAY_LANGUAGES,
30
+ overlayLanguages,
31
+ } from '../../foundation/doc-compiler/read.mjs';
28
32
  import {AstryxError} from '../error.mjs';
29
33
  import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
30
- import {parseDoc} from '../../authoring/doctypes/parse.mjs';
34
+
35
+ export {OVERLAY_LANGUAGES, overlayLanguages};
31
36
 
32
37
  /**
33
38
  * The project's topics: the built-in ones plus whatever the configured
@@ -51,34 +56,6 @@ export async function loadDocsCatalog(cwd = process.cwd()) {
51
56
  }
52
57
  }
53
58
 
54
- /** The localized overlays a docs read can apply. */
55
- export const OVERLAY_LANGUAGES = ['zh', 'dense'];
56
-
57
- /**
58
- * Where the `lang` overlay of a doc file lives: `{topic}.doc.{lang}.mjs`.
59
- * @param {string} docPath
60
- * @param {string} lang
61
- * @returns {string}
62
- */
63
- function overlayPath(docPath, lang) {
64
- return path.join(
65
- path.dirname(docPath),
66
- `${path.basename(docPath, '.doc.mjs')}.doc.${lang}.mjs`,
67
- );
68
- }
69
-
70
- /**
71
- * The overlay languages a topic ships for its own file or any extension.
72
- * @param {import('../../foundation/discovery/docs-discovery.mjs').DocsTopicEntry} entry
73
- * @returns {string[]}
74
- */
75
- export function overlayLanguages(entry) {
76
- const files = [entry.path, ...entry.extensions.map(ext => ext.path)];
77
- return OVERLAY_LANGUAGES.filter(lang =>
78
- files.some(file => fs.existsSync(overlayPath(file, lang))),
79
- );
80
- }
81
-
82
59
  /**
83
60
  * The overlay a read applies: none for the authored language.
84
61
  * @param {string | null | undefined} lang
@@ -88,61 +65,6 @@ function overlayLanguage(lang) {
88
65
  return lang && lang !== 'en' ? lang : null;
89
66
  }
90
67
 
91
- /**
92
- * Load one authored file and the overlay for `lang`. A failure is recorded on
93
- * the result, not thrown, so the compiler reports it in reading order.
94
- * @param {string} docPath
95
- * @param {string | null} lang
96
- * @returns {Promise<import('../../foundation/doc-compiler/compile.mjs').AuthoredFile>}
97
- */
98
- async function loadAuthoredFile(docPath, lang) {
99
- const file = path.basename(docPath);
100
- let doc;
101
- try {
102
- const mod = await import(pathToFileURL(docPath).href);
103
- doc = parseDoc(mod.docs ?? mod.default, file);
104
- } catch (error) {
105
- return {file, error};
106
- }
107
- if (!lang) return {file, doc};
108
- const translationPath = overlayPath(docPath, lang);
109
- if (!fs.existsSync(translationPath)) return {file, doc};
110
- try {
111
- const translationMod = await import(pathToFileURL(translationPath).href);
112
- return {
113
- file,
114
- doc,
115
- overlay: translationMod.docsZh || translationMod.docsDense || null,
116
- };
117
- } catch (overlayError) {
118
- return {file, doc, overlayError};
119
- }
120
- }
121
-
122
- /**
123
- * Everything the compiler needs for one topic, read from disk.
124
- * @param {import('../../foundation/discovery/docs-discovery.mjs').DocsTopicEntry} entry
125
- * @param {string | null} lang
126
- * @returns {Promise<import('../../foundation/doc-compiler/compile.mjs').ReferenceTopicInput>}
127
- */
128
- async function loadCompilerInput(entry, lang) {
129
- const extensions = [];
130
- for (const extension of entry.extensions) {
131
- extensions.push({
132
- ...(await loadAuthoredFile(extension.path, lang)),
133
- provider: extension.package,
134
- });
135
- }
136
- return {
137
- id: entry.name,
138
- provider: entry.package,
139
- replaces: entry.replaces ?? null,
140
- lang,
141
- base: await loadAuthoredFile(entry.path, lang),
142
- extensions,
143
- };
144
- }
145
-
146
68
  /** @type {WeakMap<DocsCatalog, Map<string, Promise<import('../../foundation/doc-compiler/compile.mjs').CompiledReferenceNode>>>} */
147
69
  const loweredByCatalog = new WeakMap();
148
70
 
@@ -166,7 +88,7 @@ export function lowerTopic(catalog, entry, lang = null) {
166
88
  const key = `${entry.name.toLowerCase()}\u0000${overlay ?? ''}`;
167
89
  let lowered = cache.get(key);
168
90
  if (!lowered) {
169
- lowered = loadCompilerInput(entry, overlay).then(input =>
91
+ lowered = loadTopicInput(entry, overlay).then(input =>
170
92
  deepFreeze(lowerReferenceTopic(input)),
171
93
  );
172
94
  cache.set(key, lowered);
@@ -174,20 +96,6 @@ export function lowerTopic(catalog, entry, lang = null) {
174
96
  return lowered;
175
97
  }
176
98
 
177
- /**
178
- * Freeze a value and everything in it.
179
- * @template T
180
- * @param {T} value
181
- * @returns {T}
182
- */
183
- function deepFreeze(value) {
184
- if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
185
- Object.freeze(value);
186
- for (const child of Object.values(value)) deepFreeze(child);
187
- }
188
- return value;
189
- }
190
-
191
99
  /**
192
100
  * How a token reference finds its target: the topic it names in `catalog`,
193
101
  * lowered for the same language.
@@ -4,9 +4,9 @@
4
4
  * @file docs.detail.section leaf — load a single section of a topic.
5
5
  *
6
6
  * @input A topic name, a section query, and optional {lang, zh, dense}. Resolves
7
- * the topic via the shared adapter, finds the section in its lowered compiled
8
- * node by its stable key, then by exact title, then by a title that contains
9
- * the query, and links only that section.
7
+ * the topic via the shared adapter, keeps the 0.6.x first title-substring
8
+ * match, then falls back to a stable key or normalized title key, and links
9
+ * only that section.
10
10
  * @output { type: 'docs.detail.section', data: ReferenceSection } with any
11
11
  * token-ref blocks inlined — matching `astryx --json docs <topic> <section>`.
12
12
  * Throws ERR_UNKNOWN_SECTION when nothing matches, or when the query matches
@@ -17,10 +17,7 @@
17
17
 
18
18
  import {AstryxError} from '../../../error.mjs';
19
19
  import {ERROR_CODES} from '../../../../foundation/response/error-codes.mjs';
20
- import {
21
- findDocSection,
22
- sectionKey,
23
- } from '../../../../foundation/discovery/docs-section-key.mjs';
20
+ import {findDocSection} from '../../../../foundation/discovery/docs-section-key.mjs';
24
21
  import {linkReferenceSection} from '../../../../foundation/doc-compiler/compile.mjs';
25
22
  import {
26
23
  readerSections,
@@ -52,16 +49,13 @@ export async function section(topic, sectionName, options = {}) {
52
49
 
53
50
  const {catalog, node, lang} = await resolveTopicDocs(topic, options);
54
51
  const sections = readerSections(node);
55
- const {section: match, candidates} = findDocSection(sections, sectionName);
52
+ const {section: match} = findDocSection(sections, sectionName);
56
53
  if (!match) {
57
- const ambiguous = candidates.length > 1;
58
54
  throw new AstryxError(
59
- ambiguous
60
- ? `Section "${sectionName}" matches ${candidates.length} sections in "${topic}". Read one by its key.`
61
- : `Section "${sectionName}" not found in "${topic}"`,
62
- (ambiguous ? candidates : sections).map(s => ({
63
- name: sectionKey(s),
64
- reason: s.title,
55
+ `Section "${sectionName}" not found in "${topic}"`,
56
+ sections.map(s => ({
57
+ name: s.title,
58
+ reason: 'available section',
65
59
  })),
66
60
  ERROR_CODES.ERR_UNKNOWN_SECTION,
67
61
  );
@@ -30,6 +30,17 @@ describe('docs.detail.section leaf', () => {
30
30
  }
31
31
  expect(err).toBeInstanceOf(AstryxError);
32
32
  expect(err.code).toBe('ERR_UNKNOWN_SECTION');
33
+ expect(err.suggestions).toEqual(
34
+ expect.arrayContaining([
35
+ expect.objectContaining({
36
+ name: expect.any(String),
37
+ reason: 'available section',
38
+ }),
39
+ ]),
40
+ );
41
+ expect(err.suggestions.some(suggestion => /\s/u.test(suggestion.name))).toBe(
42
+ true,
43
+ );
33
44
  }, SLOW);
34
45
 
35
46
  it('does not return the first section for an empty section name', async () => {
@@ -50,12 +61,10 @@ describe('docs.detail.section leaf', () => {
50
61
  expect(res.data.id).toBe(target.id);
51
62
  }, SLOW);
52
63
 
53
- it('refuses a query that matches more than one section', async () => {
54
- const err = await section('theme', 'e').catch(e => e);
55
- expect(err).toBeInstanceOf(AstryxError);
56
- expect(err.code).toBe('ERR_UNKNOWN_SECTION');
57
- expect(err.message).toMatch(/matches \d+ sections/);
58
- expect(err.suggestions.length).toBeGreaterThan(1);
64
+ it('keeps a previously accepted ambiguous query on its first match', async () => {
65
+ const res = await section('theme', 'e');
66
+ expect(res.type).toBe('docs.detail.section');
67
+ expect(res.data).toBeDefined();
59
68
  }, SLOW);
60
69
 
61
70
  it.each([null, 'zh', 'dense'])(
@@ -11,6 +11,7 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'docs',
14
+ namespace: 'cli/api',
14
15
  displayName: 'docs()',
15
16
  summary:
16
17
  'Read the reference docs: list every topic, one topic\'s sections, one section, or a whole topic.',
@@ -14,7 +14,7 @@
14
14
  * @position Leaf under api/docs. Sibling of detail; both share _adapter.mjs.
15
15
  */
16
16
 
17
- import {pathToFileURL} from 'node:url';
17
+ import {loadTopicFile} from '../../../foundation/doc-compiler/read.mjs';
18
18
  import {loadDocsCatalog} from '../_adapter.mjs';
19
19
 
20
20
  /**
@@ -29,12 +29,8 @@ export async function list({cwd} = {}) {
29
29
  for (const entry of catalog.entries()) {
30
30
  let description = entry.description ?? '';
31
31
  if (entry.description == null) {
32
- try {
33
- const mod = await import(pathToFileURL(entry.path).href);
34
- description = (mod.docs ?? mod.default)?.description ?? '';
35
- } catch {
36
- description = '';
37
- }
32
+ const file = await loadTopicFile(entry.path, null);
33
+ description = file.doc?.description ?? '';
38
34
  }
39
35
  /** @type {import('../docs.type.mjs').DocsListEntry} */
40
36
  const listed = {
@@ -100,12 +100,34 @@ export function checkPackageManager(ctx: DoctorContext): DoctorCheck;
100
100
  export function checkProviderIdentity(ctx: DoctorContext): DoctorCheck;
101
101
  /**
102
102
  * Every authoring self-doc is reachable from `astryx docs authoring`, loads,
103
- * and fits in one read. The audit is imported here, inside the try, so a
104
- * malformed self-doc is reported rather than taking Doctor down.
103
+ * and fits in one read, and every type `@astryxdesign/cli/authoring` exports
104
+ * has its doc there: the self-doc beside the module that declares it. The
105
+ * audits are imported here, inside the try, so a malformed self-doc is
106
+ * reported rather than taking Doctor down.
105
107
  * @param {DoctorContext} [_ctx]
108
+ * @param {{root?: string, sources?: string[], topicKeys?: Set<string> | null}} [options]
109
+ * Another authoring tree, list, or topic index to audit (for tests).
106
110
  * @returns {Promise<DoctorCheck>}
107
111
  */
108
- export function checkAuthoringDocs(_ctx?: DoctorContext): Promise<DoctorCheck>;
112
+ export function checkAuthoringDocs(_ctx?: DoctorContext, options?: {
113
+ root?: string;
114
+ sources?: string[];
115
+ topicKeys?: Set<string> | null;
116
+ }): Promise<DoctorCheck>;
117
+ /**
118
+ * Every command, API function, schema, and enum doc the CLI ships declares a
119
+ * namespace, and the topic that namespace names reads it: `astryx docs cli`
120
+ * for `cli/commands` and `cli/api`, `astryx docs authoring` for `authoring`.
121
+ * @param {DoctorContext | Partial<DoctorContext>} _ctx
122
+ * @param {{root?: string, sources?: string[], authoringSources?: string[]}} [options]
123
+ * test seams: the CLI root, the docs to audit, and the authoring topic's list
124
+ * @returns {Promise<DoctorCheck>}
125
+ */
126
+ export function checkCliDocs(_ctx: DoctorContext | Partial<DoctorContext>, options?: {
127
+ root?: string;
128
+ sources?: string[];
129
+ authoringSources?: string[];
130
+ }): Promise<DoctorCheck>;
109
131
  /**
110
132
  * Every topic reads progressively, in every language it ships: it loads, its
111
133
  * section index and each of its sections fit in one read, and no contributed
@@ -11,6 +11,7 @@ export const doc = {
11
11
  type: 'function',
12
12
  kind: 'api',
13
13
  name: 'doctor',
14
+ namespace: 'cli/api',
14
15
  displayName: 'doctor()',
15
16
  summary: 'Read-only project + environment health check.',
16
17
  description: