@astryxdesign/cli 0.6.4-canary.06c8fa3 → 0.6.4-canary.0e1fbdb
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.
- package/README.md +49 -40
- package/api/build/build.doc.mjs +6 -1
- package/api/build/build.test.mjs +22 -0
- package/api/build/kit/kit.mjs +44 -5
- package/api/component/component.doc.mjs +14 -7
- package/api/docs/_adapter.d.mts +8 -3
- package/api/docs/_adapter.mjs +14 -6
- package/api/docs/docOverlays.test.mjs +27 -1
- package/api/docs/docs.doc.mjs +2 -2
- package/api/doctor/doctor.doc.mjs +17 -8
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/gap-report/gap-report.doc.mjs +19 -10
- package/api/hook/hook.doc.mjs +6 -3
- package/api/index.d.mts +2 -0
- package/api/index.mjs +3 -1
- package/api/init/init.doc.mjs +17 -12
- package/api/integration/add-theme.mjs +22 -1
- package/api/integration/add-theme.test.mjs +34 -0
- package/api/integration/authoring-checks.mjs +2 -2
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/pack-check.lifecycle-output.test.mjs +2 -0
- package/api/integration/pack-check.mjs +54 -6
- package/api/integration/pack-check.test.mjs +90 -0
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/index.ts +1 -0
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/_adapter.d.mts +34 -0
- package/api/layout/_adapter.mjs +148 -0
- package/api/layout/check/check.d.mts +16 -0
- package/api/layout/check/check.mjs +40 -0
- package/api/layout/expand/expand.d.mts +22 -0
- package/api/layout/expand/expand.mjs +155 -0
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.d.mts +13 -0
- package/api/layout/grammar/grammar.mjs +87 -0
- package/api/layout/layout.d.mts +6 -0
- package/api/layout/layout.mjs +17 -0
- package/api/layout/layout.test.mjs +297 -0
- package/api/layout/layout.type.d.mts +89 -0
- package/api/layout/layout.type.mjs +103 -0
- package/api/layout/layoutCheck.doc.d.mts +11 -0
- package/api/layout/layoutCheck.doc.mjs +85 -0
- package/api/layout/layoutExpand.doc.d.mts +11 -0
- package/api/layout/layoutExpand.doc.mjs +107 -0
- package/api/layout/layoutGrammar.doc.d.mts +11 -0
- package/api/layout/layoutGrammar.doc.mjs +57 -0
- package/api/search/search.d.mts +27 -1
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +228 -16
- package/api/swizzle/swizzle.doc.mjs +7 -5
- package/api/template/copy/copy.mjs +1 -1
- package/api/template/copy/copy.test.mjs +9 -0
- package/api/template/template-integration.test.mjs +65 -1
- package/api/template/template.doc.mjs +2 -1
- package/api/template/template.mjs +1 -1
- package/api/theme/generateTonalPalette.doc.mjs +1 -2
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +9 -10
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +2 -1
- package/api/theme/themePaletteGenerate.doc.mjs +15 -8
- package/api/theme/themeTargets.doc.mjs +3 -2
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/run/run.mjs +1 -1
- package/api/upgrade/upgrade.doc.mjs +24 -22
- package/assets/docs/README.md +4 -2
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +8 -2
- package/assets/docs/elevation.doc.mjs +6 -4
- package/assets/docs/getting-started.doc.mjs +5 -16
- package/assets/docs/icons.doc.mjs +2 -21
- package/assets/docs/illustrations.doc.mjs +7 -15
- package/assets/docs/layout.doc.dense.mjs +130 -82
- package/assets/docs/layout.doc.mjs +133 -77
- package/assets/docs/migration.doc.mjs +19 -21
- package/assets/docs/motion.doc.mjs +16 -3
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +8 -0
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +8 -3
- package/assets/docs/spacing.doc.mjs +7 -2
- package/assets/docs/styling-libraries.doc.mjs +6 -2
- package/assets/docs/styling.doc.mjs +19 -23
- package/assets/docs/theme.doc.dense.mjs +58 -18
- package/assets/docs/theme.doc.mjs +56 -46
- package/assets/docs/theme.doc.zh.mjs +9 -8
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +389 -8
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/add-a-component.doc.mjs +75 -0
- package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
- package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
- package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
- package/assets/docs/tree/block-template.doc.mjs +130 -0
- package/assets/docs/tree/build-the-template.doc.mjs +28 -0
- package/assets/docs/tree/building-blocks.doc.mjs +46 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
- package/assets/docs/tree/checks.doc.mjs +119 -0
- package/assets/docs/tree/codemods.doc.mjs +147 -0
- package/assets/docs/tree/component-family.doc.mjs +113 -0
- package/assets/docs/tree/component-imports.doc.mjs +69 -0
- package/assets/docs/tree/components.doc.mjs +23 -0
- package/assets/docs/tree/configuration.doc.mjs +23 -0
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
- package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
- package/assets/docs/tree/docs.doc.mjs +21 -0
- package/assets/docs/tree/document-the-template.doc.mjs +28 -0
- package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
- package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
- package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
- package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
- package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
- package/assets/docs/tree/help.doc.mjs +16 -0
- package/assets/docs/tree/integrations.doc.mjs +25 -470
- package/assets/docs/tree/links.doc.mjs +98 -0
- package/assets/docs/tree/package-and-test.doc.mjs +32 -0
- package/assets/docs/tree/page-template.doc.mjs +71 -0
- package/assets/docs/tree/publishing.doc.mjs +111 -0
- package/assets/docs/tree/quick-start.doc.mjs +272 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
- package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
- package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
- package/assets/docs/tree/ship.doc.mjs +16 -0
- package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
- package/assets/docs/tree/single-component.doc.mjs +165 -0
- package/assets/docs/tree/start-a-template.doc.mjs +143 -0
- package/assets/docs/tree/subcomponent.doc.mjs +115 -0
- package/assets/docs/tree/template-assets.doc.mjs +64 -0
- package/assets/docs/tree/template-doc-overview.doc.mjs +109 -0
- package/assets/docs/tree/template-fonts.doc.mjs +102 -0
- package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
- package/assets/docs/tree/template-icons.doc.mjs +97 -0
- package/assets/docs/tree/template-images-media.doc.mjs +127 -0
- package/assets/docs/tree/template-styles.doc.mjs +93 -0
- package/assets/docs/tree/templates.doc.mjs +34 -0
- package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
- package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
- package/assets/docs/tree/themes.doc.mjs +39 -0
- package/assets/docs/tree/troubleshooting.doc.mjs +149 -0
- package/assets/docs/tree/upgrading.doc.mjs +103 -0
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
- package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
- package/assets/docs/tree/versioning.doc.mjs +161 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
- package/assets/docs/typography.doc.mjs +24 -4
- package/assets/docs/working-with-ai.doc.mjs +30 -22
- package/authoring/config/config.doc.mjs +2 -2
- package/authoring/config/type.ts +2 -2
- package/authoring/doctypes/_schema.d.mts +3 -2
- package/authoring/doctypes/_schema.mjs +6 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +4 -2
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +1 -1
- package/authoring/doctypes/component/component.doc.mjs +6 -0
- package/authoring/doctypes/component/type.ts +8 -0
- package/authoring/doctypes/reference/reference.doc.mjs +7 -0
- package/authoring/doctypes/reference/type.ts +5 -0
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +2 -2
- package/authoring/integration/integration.doc.mjs +12 -10
- package/clients/cli/command-result-coverage.test.mjs +7 -7
- package/clients/cli/commands/component.doc.mjs +4 -3
- package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +60 -17
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -2
- package/clients/cli/commands/doctor-integration.test.mjs +53 -0
- package/clients/cli/commands/doctor.doc.mjs +3 -1
- package/clients/cli/commands/doctor.mjs +49 -5
- package/clients/cli/commands/gap-report.doc.mjs +10 -9
- package/clients/cli/commands/init.doc.mjs +9 -6
- package/clients/cli/commands/integration-add.doc.mjs +9 -9
- package/clients/cli/commands/integration-authoring.test.mjs +61 -10
- package/clients/cli/commands/integration-pack.doc.mjs +5 -9
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration-verify.doc.mjs +22 -0
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +74 -43
- package/clients/cli/commands/layout-check.doc.mjs +65 -0
- package/clients/cli/commands/layout-expand.doc.mjs +83 -0
- package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
- package/clients/cli/commands/layout.doc.mjs +34 -0
- package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
- package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
- package/clients/cli/commands/layout.mjs +275 -0
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +10 -3
- package/clients/cli/commands/search.mjs +21 -2
- package/clients/cli/commands/search.test.mjs +21 -4
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/text-json-parity.test.mjs +24 -1
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -2
- package/clients/cli/commands/theme-palette.doc.mjs +1 -2
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +62 -3
- package/clients/cli/index.mjs +32 -6
- package/clients/cli/lib/define-command.mjs +28 -4
- package/clients/cli/lib/define-command.test.mjs +54 -0
- package/clients/cli/lib/exit-codes.test.mjs +25 -2
- package/clients/cli/lib/json-shim.test.mjs +20 -6
- package/clients/cli/lib/manifest.mjs +23 -5
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/discovery/authoring-self-docs.test.mjs +6 -2
- package/foundation/discovery/cli-self-docs.mjs +16 -2
- package/foundation/discovery/cli-self-docs.test.mjs +20 -0
- package/foundation/discovery/docs-discovery.mjs +5 -1
- package/foundation/discovery/docs-discovery.test.mjs +21 -0
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +15 -2
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/tree.d.mts +4 -0
- package/foundation/doc-compiler/tree.mjs +6 -1
- package/foundation/integrations/cli-requirement.d.mts +26 -6
- package/foundation/integrations/cli-requirement.mjs +46 -11
- package/foundation/integrations/cli-requirement.test.mjs +7 -2
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/response/error-codes.doc.mjs +6 -8
- package/foundation/response/error-codes.test.mjs +30 -5
- package/foundation/response/response-types.doc.d.mts +4 -3
- package/foundation/response/response-types.doc.mjs +42 -6
- package/foundation/response/response.doc.mjs +11 -10
- package/foundation/xle/browser.d.mts +3 -3
- package/foundation/xle/browser.mjs +3 -3
- package/foundation/xle/expand.mjs +2 -2
- package/foundation/xle/parse.mjs +1 -1
- package/foundation/xle/print.mjs +2 -2
- package/foundation/xle/splice.mjs +1 -1
- package/package.json +9 -9
- package/api/docs/docs.test.mjs +0 -245
- package/api/docs/integration-tree.test.mjs +0 -555
- package/api/docs/integrationDocs.test.mjs +0 -314
- package/api/search/search.test.mjs +0 -530
- package/assets/docs/tree/integrations.test.mjs +0 -62
- package/assets/docs/tree/writing-docs.doc.mjs +0 -286
- package/clients/cli/commands/docs.test.mjs +0 -323
- package/foundation/agent-docs/agent-docs.test.mjs +0 -1159
- package/foundation/doc-compiler/tree.test.mjs +0 -606
package/README.md
CHANGED
|
@@ -30,7 +30,8 @@ The CLI documents itself, so these commands print what the installed version doe
|
|
|
30
30
|
`astryx.integration.*` manifest, codemods, and every doc type (`ComponentDoc`,
|
|
31
31
|
`TemplateDoc`, `ThemeDoc`, and the rest). Read one section with
|
|
32
32
|
`astryx docs authoring <section>`, for example `astryx docs authoring config`.
|
|
33
|
-
- `astryx docs cli/integrations`: the
|
|
33
|
+
- `astryx docs cli/integrations`: the guides to building an integration package,
|
|
34
|
+
from a quick start to publishing.
|
|
34
35
|
- `astryx docs`: every docs topic, including the design-system guides (for
|
|
35
36
|
example `tokens`, `theme`, and `layout`).
|
|
36
37
|
|
|
@@ -77,36 +78,37 @@ Options:
|
|
|
77
78
|
|
|
78
79
|
<!-- BEGIN GENERATED: commands -->
|
|
79
80
|
|
|
80
|
-
| Command | Description
|
|
81
|
-
| ------------- |
|
|
82
|
-
| `blog` | Read the Astryx blog from the published feed
|
|
83
|
-
| `build` | Build a page: the template to start from, or the workflow playbook (no query)
|
|
84
|
-
| `component` | List components or print component docs
|
|
85
|
-
| `discover` | Browse and search integrations: the ones you have and the ones you could add
|
|
86
|
-
| `docs` | Print reference docs
|
|
87
|
-
| `doctor` | Diagnose Astryx projects and integration packages
|
|
88
|
-
| `gap-report` |
|
|
89
|
-
| `hook` | List hooks or print hook docs
|
|
90
|
-
| `init` | Initialize the design system in your project
|
|
91
|
-
| `integration` | Author and verify an Astryx integration package
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
81
|
+
| Command | Description |
|
|
82
|
+
| ------------- | --------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `blog` | Read the Astryx blog from the published feed |
|
|
84
|
+
| `build` | Build a page: the template to start from, or the workflow playbook (no query) |
|
|
85
|
+
| `component` | List components or print component docs |
|
|
86
|
+
| `discover` | Browse and search integrations: the ones you have and the ones you could add |
|
|
87
|
+
| `docs` | Print reference docs |
|
|
88
|
+
| `doctor` | Diagnose Astryx projects and integration packages |
|
|
89
|
+
| `gap-report` | Report a missing component or feature to the package that owns it |
|
|
90
|
+
| `hook` | List hooks or print hook docs |
|
|
91
|
+
| `init` | Initialize the design system in your project |
|
|
92
|
+
| `integration` | Author and verify an Astryx integration package |
|
|
93
|
+
| `layout` | Generate XDS layouts from compressed expressions (XLE/XLO) |
|
|
94
|
+
| `search` | Search components, hooks, docs, and templates in one ranked list |
|
|
95
|
+
| `swizzle` | Copy component source for customization |
|
|
96
|
+
| `template` | List, show, or scaffold page and block templates |
|
|
97
|
+
| `theme` | Create and build themes: add a shipped one, compile to CSS, or list what a theme can override |
|
|
98
|
+
| `upgrade` | Update your code after upgrading Astryx, and refresh ShadCN-copied components |
|
|
97
99
|
|
|
98
100
|
<!-- END GENERATED: commands -->
|
|
99
101
|
<!-- Generated by scripts/generate-cli-readme.mjs from `astryx manifest`. Run `pnpm -F @astryxdesign/cli readme`. -->
|
|
100
102
|
|
|
101
103
|
### Global options
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
`--json` works with every command listed in `jsonSupported` (`astryx manifest --json`), which is every command except the bare groups such as `astryx theme`. The other four change only the reads named here; other commands ignore them:
|
|
104
106
|
|
|
105
107
|
- `--json`: Output as typed JSON envelope: `{ apiVersion, type, data, meta? }` (errors: `{ apiVersion, error, code, suggestions? }`)
|
|
106
|
-
- `--detail <level>`: Detail level for
|
|
107
|
-
- `--zh`:
|
|
108
|
-
- `--dense`:
|
|
109
|
-
- `--lang <locale>`: Language
|
|
108
|
+
- `--detail <level>`: Detail level for `component`, `hook`, and docs tree reads (such as `astryx docs cli/commands/build`), increasing in size: `brief` (names only, default for lists) < `compact` (names + 1-line descriptions) < `full` (full docs per entry). Single-item views default to `full`.
|
|
109
|
+
- `--zh`: Simplified Chinese for component reads and for docs topics that have a translation (English otherwise)
|
|
110
|
+
- `--dense`: Token-efficient dense text for `astryx component <Name>` and `astryx docs <topic>`
|
|
111
|
+
- `--lang <locale>`: Language or format for component and docs reads: `en` (default), `zh` (as `--zh`), or `dense` (as `--dense`)
|
|
110
112
|
|
|
111
113
|
## JSON API
|
|
112
114
|
|
|
@@ -163,9 +165,9 @@ if (isError(result)) {
|
|
|
163
165
|
| `ERR_UNKNOWN` | Fallback for any error without a more specific code. |
|
|
164
166
|
| `ERR_UNKNOWN_COMMAND` | A top-level command name was not recognized (e.g. `astryx bogus`). |
|
|
165
167
|
| `ERR_UNKNOWN_SUBCOMMAND` | A subcommand under a command group was not recognized (e.g. `astryx theme bogus`). |
|
|
166
|
-
| `ERR_INVALID_OPTION` | An unknown
|
|
167
|
-
| `ERR_INVALID_ARGUMENT` | An
|
|
168
|
-
| `ERR_MISSING_ARGUMENT` | A required
|
|
168
|
+
| `ERR_INVALID_OPTION` | An unknown option was passed, --json was given to a command without JSON output, or layout --form got a value other than compact, outline, or auto. |
|
|
169
|
+
| `ERR_INVALID_ARGUMENT` | An argument or option value is invalid: wrong type, out of range, an unknown choice, an extra argument, or a conflicting combination. |
|
|
170
|
+
| `ERR_MISSING_ARGUMENT` | A required argument or option value was omitted. |
|
|
169
171
|
| `ERR_INVALID_LANG` | `--lang` was given a value outside its choices (en, zh, dense). |
|
|
170
172
|
| `ERR_INVALID_DETAIL` | `--detail` was given a value outside its choices (full, compact, brief). |
|
|
171
173
|
| `ERR_NODE_VERSION` | The running Node.js version is below the supported minimum. |
|
|
@@ -183,8 +185,8 @@ if (isError(result)) {
|
|
|
183
185
|
| `ERR_UNKNOWN_THEME` | No theme matched the requested slug (theme add). |
|
|
184
186
|
| `ERR_INTEGRATION_ROOT_CONFLICT` | An integration manifest already declares a different path for the requested contribution root. |
|
|
185
187
|
| `ERR_INTEGRATION_EXPORT_CONFLICT` | A package export already maps a generated contribution subpath to a different target. |
|
|
186
|
-
| `ERR_UNKNOWN_PACKAGE` | No package matched the requested name
|
|
187
|
-
| `ERR_UNKNOWN_AGENT` | An unrecognized `--agent` value was passed to
|
|
188
|
+
| `ERR_UNKNOWN_PACKAGE` | No package matched the requested name. |
|
|
189
|
+
| `ERR_UNKNOWN_AGENT` | An unrecognized `--agent` value was passed to init. |
|
|
188
190
|
| `ERR_UNKNOWN_FEATURE` | An unrecognized `--features` value was passed to init. |
|
|
189
191
|
| `ERR_UNKNOWN_CODEMOD` | A `--codemod` value did not match any registered codemod (upgrade). |
|
|
190
192
|
| `ERR_CODEMOD_FAILED` | One or more codemods failed during an upgrade run. |
|
|
@@ -210,7 +212,7 @@ if (isError(result)) {
|
|
|
210
212
|
| `ERR_FETCH_FAILED` | A network fetch (RSS feed or post text) failed. |
|
|
211
213
|
| `ERR_LAYOUT_PARSE` | A layout expression failed to parse (syntax error, with line/col). |
|
|
212
214
|
| `ERR_LAYOUT_INVALID` | A layout expression parsed but failed validation (unknown component/prop/enum/block). |
|
|
213
|
-
| `ERR_UNCLASSIFIED_EXIT` | Recorded in the debug log, never printed: a command exited non-zero without
|
|
215
|
+
| `ERR_UNCLASSIFIED_EXIT` | Recorded in the debug log, never printed: a command exited non-zero without reporting an error code. |
|
|
214
216
|
| `ERR_SIGNAL_TERMINATED` | Recorded in the debug log, never printed: the process was ended by a signal (Ctrl-C, SIGTERM) before the command reached a terminal path. |
|
|
215
217
|
|
|
216
218
|
<!-- END GENERATED: error-codes -->
|
|
@@ -421,7 +423,7 @@ Every response has a `type` discriminant. The full set is below (generated from
|
|
|
421
423
|
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
422
424
|
| `init.run` | The install receipt: the `mode` (`default` \| `features`), the features run, agent-doc files written, any soft `docsError`, whether theme guidance was emitted, the template outcome (`workflow` \| `created` \| `skipped`) plus its path, and whether the next-steps were emitted. |
|
|
423
425
|
| `init.remove` | Confirmation that the managed agent-docs block was removed (`data.removed: true`) — returned when --remove-agents is set. |
|
|
424
|
-
| `component.list` | The component catalog grouped by
|
|
426
|
+
| `component.list` | The component catalog grouped by component group (each component's group field): `detail` (the level: names \| compact \| full) and `components`, the grouped map of names entries ({name, package, and optional canonical import for integrations}), brief entries, or a full ComponentDoc per entry. |
|
|
425
427
|
| `component.batch` | The component specialization of the shared `BatchResponse` and `BatchRow` types. An explicit programmatic selector array, or two or more CLI selectors, returns one ordered receipt: `count` plus `results`, one row per selector including duplicates. Every row carries `selector` and `status` (found \| not_found \| ambiguous \| error). A found row carries `result`, the same {type, data} response as one selector. An ambiguous row carries `code`, `error`, and `candidates` ({package, component, kind, installed}). Other failed rows carry `code`, `error`, and optional `suggestions` ({name, reason}). |
|
|
426
428
|
| `component.detail` | One component's authored ComponentDoc plus ownership fields (package, the owner; import, the specifier; sourceAvailable, whether source exists) and parentDoc (present when the component is documented inside another component's doc, naming that doc). |
|
|
427
429
|
| `component.detail.props` | Just one component's props table (ComponentPropDoc[]). |
|
|
@@ -444,7 +446,7 @@ Every response has a `type` discriminant. The full set is below (generated from
|
|
|
444
446
|
| `build.help` | The how-to-build-a-page playbook, emitted when no query is given: `playbook: true`, a title, the ordered steps (title, commands, optional returns), the on-system rules, and related lookups. Commands are bare subcommands for the caller to render with its own invocation. |
|
|
445
447
|
| `build.kit` | The template to start from and its kit: query, hasResults, matchCount (never a cap), directMatch, start {name, command, basis, reason, alternatives, ...}, pages (search's closest templates), blocks and domain as SearchResultEntry[], frame, foundation, and hint {reason, commands} when thin. |
|
|
446
448
|
| `swizzle.list` | The names of swizzlable components discoverable from cwd's @astryxdesign/core. |
|
|
447
|
-
| `swizzle.copy` | An eject receipt: component name, owning package, output directory, files-copied count, the written file names, whether any file uses StyleX, and an
|
|
449
|
+
| `swizzle.copy` | An eject receipt: component name, owning package, output directory, files-copied count, the written file names, whether any file uses StyleX, and, when the owner has an issues URL, feedback ({issuesUrl, ghCommand?}): where to report the gap that led to swizzling. |
|
|
448
450
|
| `gap-report.categories` | The fixed gap category values and human-readable labels. |
|
|
449
451
|
| `gap-report.file` | An aggregate receipt: overall status, the selected package, issuesUrl (or null), deliveries in handler order, each {handlerType: project \| integration \| fallback, handler, audience, status, url, message}, and filedCount/routedOnlyCount totals. |
|
|
450
452
|
| `template.list` | The effective discovered TemplateListEntry[] for pages and blocks. A winning replacement entry includes optional `replaces`, naming the Core id omitted from the default list. |
|
|
@@ -464,16 +466,22 @@ Every response has a `type` discriminant. The full set is below (generated from
|
|
|
464
466
|
| `theme.targets` | The whole themeable surface: the echoed filter, componentCount, and targets, one per theming target — {key, className, component, props, states, deprecatedFor?}, where props and states are its legal override keys and deprecatedFor names the canonical replacement key. |
|
|
465
467
|
| `theme.palette.generate` | An author-reviewable OKLCH palette candidate, its reproducibility receipt, summary counts, and optional candidate/receipt file-write result. |
|
|
466
468
|
| `upgrade.list` | Every available codemod, oldest→newest, as {name, title, version, optional}; returned for --list without running anything. |
|
|
469
|
+
| `upgrade.registry` | The copied-composition receipt for --registry: applied, ok, the counts (found, current, wouldUpdate, updated, wouldMerge, merged, wouldRefreshReceipt, receiptsRefreshed, conflicts, missing, invalid, failed), and items. |
|
|
467
470
|
| `upgrade.status` | A short-circuit outcome with no codemods run (up_to_date, no_codemods, or config_fixable), each carrying the agent-docs summary. |
|
|
468
471
|
| `upgrade.run` | The run receipt: from/to versions, codemod count, integrations processed, the agent-docs summary, and (apply mode) filesChanged, transformsApplied, and per-codemod errors. |
|
|
469
472
|
| `manifest` | The CLI capability manifest: name, version, apiVersion, description, globalOptions, commands (each name, description, arguments, options, json, aliases?, responseTypes?, examples?, exitCodes? as [{code, when}], subcommands?), jsonSupported, and the flat responseTypes index. |
|
|
470
|
-
| `
|
|
473
|
+
| `help` | Help, in one of two shapes. A bare `astryx --json` returns the root manifest: name, version, commands (the command names), jsonSupported, and manifest (the full payload `astryx manifest --json` returns). `--help --json` on any command, or `astryx help [command] --json`, returns that command's help: command, description, usage, options (each flags, description, and defaultValue and choices when set), and subcommands (each name and description). data.manifest marks the first shape; data.usage marks the second. |
|
|
474
|
+
| `version` | The CLI version, for `astryx --version --json`: {version}. |
|
|
475
|
+
| `doctor` | The health-check report: `checks` (each with id, label, status: pass \| warn \| fail \| info, a message, and an optional fix, always present on warn and fail) plus a `summary` of counts per status. |
|
|
471
476
|
| `integration.add` | A contribution-writer receipt: kind, name, optional root {path, created}, integration-manifest path, every affected project-relative path, written, and dryRun. |
|
|
472
477
|
| `integration.pack-check` | The packed-package check: name, version, packable, tarball {filename, fileCount, size, unpackedSize} or null, inventory {manifest, roots [{kind, path, expectedFiles, missingFiles, complete}], expectedFiles, packedFiles}, contributions {local, packed}, each null or {themes [{slug, exportName}], components, templates [{id, type, name}], codemods [{version, id}], docs, agentDocsAppend}, and issues [{code, severity, message}]. |
|
|
473
478
|
| `integration.validate` | The validation result: the package name and version (both null when no local manifest is found) plus issues, an AstryxIntegrationIssue[] of {code, severity: warning \| error, message}. |
|
|
474
479
|
| `integration.template-conflicts` | The integration identity, structural issues, and non-blocking Core template-id conflicts as {id, severity: warning, integrationPackage, integrationType, integrationName, coreMatches, message, command}. |
|
|
475
480
|
| `integration.component-conflicts` | The integration identity, structural issues, and non-blocking conflicts where an integration component name is also owned by Core; each conflict includes the exact package-qualified command. |
|
|
476
481
|
| `integration.doc-conflicts` | The integration identity, structural issues, and Core doc overlaps. Each finding includes `severity` (`info` \| `error`) and `relationship` (`replaces` \| `extends` \| `accidental`). |
|
|
482
|
+
| `layout.expand` | The expansion: parsed form, generated TSX code, componentsUsed, states (count of useState hooks scaffolded), todos, blocksReferenced (each {name, mode}), warnings, and written (the output path, or null when nothing was written). |
|
|
483
|
+
| `layout.check` | The validation result: a valid flag, the detected form, errors (each with line/col, message, formatted text, and suggestions), warnings, and the expression re-printed in both canonical surfaces (compact and outline). |
|
|
484
|
+
| `layout.grammar` | The XLE/XLO grammar cheatsheet: a text field with the full reference plus an aliases map (short name → canonical component) generated from this install's registry. |
|
|
477
485
|
|
|
478
486
|
<!-- END GENERATED: response-types -->
|
|
479
487
|
<!-- Generated by scripts/generate-cli-readme.mjs from the response-types EnumDoc. Run `pnpm -F @astryxdesign/cli readme`. -->
|
|
@@ -574,12 +582,12 @@ There is no factory: write a plain object. For editor autocomplete and
|
|
|
574
582
|
type-checking, annotate it with the `AstryxConfig` type exported from
|
|
575
583
|
`@astryxdesign/cli/authoring`.
|
|
576
584
|
|
|
577
|
-
| Field | Type | Purpose
|
|
578
|
-
| ----------------------------- | ------------------------------ |
|
|
579
|
-
| `integrations` | `string[]` | Integration package names to load (see [Integrations](#integrations)).
|
|
580
|
-
| `issuesUrl` | `string` | Where "report an issue" links point for your project. Defaults to the core issue tracker.
|
|
581
|
-
| `hooks.postCodemod` | `PostCodemodHook[]` | Commands to run after `astryx upgrade` applies codemods (e.g. reinstall, rebuild, reformat).
|
|
582
|
-
| `experimental.xle.components` | `Record<string, XleComponent>` |
|
|
585
|
+
| Field | Type | Purpose |
|
|
586
|
+
| ----------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------- |
|
|
587
|
+
| `integrations` | `string[]` | Integration package names to load (see [Integrations](#integrations)). |
|
|
588
|
+
| `issuesUrl` | `string` | Where "report an issue" links point for your project. Defaults to the core issue tracker. |
|
|
589
|
+
| `hooks.postCodemod` | `PostCodemodHook[]` | Commands to run after `astryx upgrade` applies codemods (e.g. reinstall, rebuild, reformat). |
|
|
590
|
+
| `experimental.xle.components` | `Record<string, XleComponent>` | Register app-local components so layout (XLE) expressions can reference them by name. Unstable. |
|
|
583
591
|
|
|
584
592
|
The config is validated against a strict schema when the CLI loads it, so an
|
|
585
593
|
unknown field is a hard error rather than a silent no-op. `astryx doctor`
|
|
@@ -675,9 +683,10 @@ Warnings go to stderr and never corrupt a `--json` envelope. To inspect problems
|
|
|
675
683
|
Core identity overlaps before publishing. Bare `astryx doctor` checks overall
|
|
676
684
|
project health.
|
|
677
685
|
|
|
678
|
-
For the full
|
|
679
|
-
|
|
686
|
+
For the full walkthrough, from an empty folder to a published package, see the
|
|
687
|
+
guides:
|
|
680
688
|
|
|
681
689
|
```bash
|
|
682
690
|
astryx docs cli/integrations
|
|
691
|
+
astryx docs cli/integrations/quick-start
|
|
683
692
|
```
|
package/api/build/build.doc.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export const doc = {
|
|
|
40
40
|
type: 'string',
|
|
41
41
|
description:
|
|
42
42
|
'Directory to resolve @astryxdesign/core and templates from.',
|
|
43
|
+
default: 'process.cwd()',
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
46
|
name: 'options.type',
|
|
@@ -69,7 +70,11 @@ export const doc = {
|
|
|
69
70
|
throws: [
|
|
70
71
|
{
|
|
71
72
|
code: 'ERR_INVALID_ARGUMENT',
|
|
72
|
-
when: 'options.type is not a known domain, or options.limit is not a positive integer',
|
|
73
|
+
when: 'a query is given and options.type is not a known domain, or options.limit is not a positive integer',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: 'ERR_CORE_NOT_FOUND',
|
|
77
|
+
when: 'a query is given and @astryxdesign/core cannot be found from cwd',
|
|
73
78
|
},
|
|
74
79
|
],
|
|
75
80
|
examples: [
|
package/api/build/build.test.mjs
CHANGED
|
@@ -179,6 +179,28 @@ describe('build kit — coverage gates the pages group', () => {
|
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
+
it('does not call a page that only mentions every word a direct match', async () => {
|
|
183
|
+
// `empty state` and `command palette` name components. A page whose text
|
|
184
|
+
// mentions both words, or that renders the component, is a layout
|
|
185
|
+
// reference, not the page the reader asked for.
|
|
186
|
+
for (const query of ['empty state', 'command palette']) {
|
|
187
|
+
const r = await build(query, {cwd: REPO});
|
|
188
|
+
if (r.type !== 'build.kit') throw new Error('expected build.kit');
|
|
189
|
+
expect(r.data.directMatch, query).toBe(false);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('keeps the page and component a query names first', async () => {
|
|
194
|
+
const pageOf = async (/** @type {string} */ query) => {
|
|
195
|
+
const r = await build(query, {cwd: REPO});
|
|
196
|
+
if (r.type !== 'build.kit') throw new Error('expected build.kit');
|
|
197
|
+
return r.data;
|
|
198
|
+
};
|
|
199
|
+
expect((await pageOf('checkout flow')).pages[0]).toMatchObject({name: 'checkout-wizard'});
|
|
200
|
+
expect((await pageOf('sign in with sso')).pages[0]).toMatchObject({name: 'login-sso'});
|
|
201
|
+
expect((await pageOf('search results')).domain.map(e => e.name)).toContain('PowerSearch');
|
|
202
|
+
});
|
|
203
|
+
|
|
182
204
|
it('leaves single-concept queries alone (nothing to cover)', async () => {
|
|
183
205
|
const r = await build('dashboard', {cwd: REPO});
|
|
184
206
|
expect(r.type).toBe('build.kit');
|
package/api/build/kit/kit.mjs
CHANGED
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import {search} from '../../search/search.mjs';
|
|
31
|
+
import {findCoreDir} from '../../../foundation/fs/paths.mjs';
|
|
32
|
+
import {AstryxError} from '../../error.mjs';
|
|
33
|
+
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
31
34
|
import {getResultCoverage} from '../../search/coverage.mjs';
|
|
32
35
|
import {loadPageTemplates} from '../_adapter.mjs';
|
|
33
36
|
import {pickAlternatives, pickStart, rankPages} from './rank.mjs';
|
|
@@ -188,12 +191,30 @@ function chooseStart(ranked, pages, directMatch, catalog) {
|
|
|
188
191
|
*/
|
|
189
192
|
export async function buildKit(query, options = {}) {
|
|
190
193
|
const {cwd = process.cwd(), type, limit = 60} = options;
|
|
194
|
+
// A kit is built from Core's components, hooks, and templates. An open
|
|
195
|
+
// search without core covers the docs alone, so the kit asks for core here.
|
|
196
|
+
if (type !== 'doc' && !findCoreDir(cwd)) {
|
|
197
|
+
throw new AstryxError(
|
|
198
|
+
'Could not find @astryxdesign/core package',
|
|
199
|
+
undefined,
|
|
200
|
+
ERROR_CODES.ERR_CORE_NOT_FOUND,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
191
203
|
// search()'s JSDoc @returns widens results to object[]; the SearchResponse
|
|
192
204
|
// shape is the contract (api/search/search.type.mjs). Cast locally rather than
|
|
193
205
|
// tightening the search @returns (a separate follow-up).
|
|
194
206
|
const result =
|
|
195
207
|
/** @type {import('../../search/search.type.mjs').SearchResponse} */ (
|
|
196
|
-
await search(query, {
|
|
208
|
+
await search(query, {
|
|
209
|
+
cwd,
|
|
210
|
+
type,
|
|
211
|
+
// Search wider than the surfaced kit so a flood of doc matches cannot
|
|
212
|
+
// bury the page templates past the cutoff; the caller's `limit` still
|
|
213
|
+
// caps the kit below. A non-positive or non-integer limit is passed
|
|
214
|
+
// through unchanged so search rejects it (ERR_INVALID_ARGUMENT).
|
|
215
|
+
limit:
|
|
216
|
+
Number.isInteger(limit) && limit > 0 ? Math.max(limit, 200) : limit,
|
|
217
|
+
})
|
|
197
218
|
);
|
|
198
219
|
const results = result.data.results;
|
|
199
220
|
// The TOTAL number of matches, not the number that survived `limit`. The kit
|
|
@@ -257,6 +278,24 @@ export async function buildKit(query, options = {}) {
|
|
|
257
278
|
command: `${page.command} --skeleton`,
|
|
258
279
|
}));
|
|
259
280
|
|
|
281
|
+
// The caller's `limit` caps the surfaced kit, even though the search above
|
|
282
|
+
// ran wider to find templates that a flood of doc matches would otherwise
|
|
283
|
+
// bury past the cutoff. Keep pages first, then blocks, then components.
|
|
284
|
+
let budget = limit;
|
|
285
|
+
/**
|
|
286
|
+
* @template T
|
|
287
|
+
* @param {T[]} arr
|
|
288
|
+
* @returns {T[]}
|
|
289
|
+
*/
|
|
290
|
+
const toLimit = arr => {
|
|
291
|
+
const out = arr.slice(0, Math.max(0, budget));
|
|
292
|
+
budget -= out.length;
|
|
293
|
+
return out;
|
|
294
|
+
};
|
|
295
|
+
const pagesKept = toLimit(pages);
|
|
296
|
+
const blocksKept = toLimit(blocks);
|
|
297
|
+
const domainKept = toLimit(domain);
|
|
298
|
+
|
|
260
299
|
// A kit narrowed to components or hooks has no page to start from; every
|
|
261
300
|
// other kit does, so the reader is never left to compose a page from scratch.
|
|
262
301
|
const wantsPages = !type || type === 'template';
|
|
@@ -288,7 +327,7 @@ export async function buildKit(query, options = {}) {
|
|
|
288
327
|
// not resolve — the same defect `getCliInvocation` exists to prevent, and
|
|
289
328
|
// the renderer applies it. A JSON caller gets the parts, not a sentence.
|
|
290
329
|
const hint =
|
|
291
|
-
|
|
330
|
+
pagesKept.length + blocksKept.length + domainKept.length < THIN_KIT
|
|
292
331
|
? {
|
|
293
332
|
reason:
|
|
294
333
|
'Few matches. This is keyword search, not semantic — try other wordings.',
|
|
@@ -306,9 +345,9 @@ export async function buildKit(query, options = {}) {
|
|
|
306
345
|
matchCount,
|
|
307
346
|
directMatch,
|
|
308
347
|
start,
|
|
309
|
-
pages,
|
|
310
|
-
blocks,
|
|
311
|
-
domain,
|
|
348
|
+
pages: pagesKept,
|
|
349
|
+
blocks: blocksKept,
|
|
350
|
+
domain: domainKept,
|
|
312
351
|
frame: FRAME,
|
|
313
352
|
foundation: FOUNDATION,
|
|
314
353
|
hint,
|
|
@@ -45,6 +45,7 @@ export const doc = {
|
|
|
45
45
|
name: 'options.cwd',
|
|
46
46
|
type: 'string',
|
|
47
47
|
description: 'Directory to resolve @astryxdesign/core from.',
|
|
48
|
+
default: 'process.cwd()',
|
|
48
49
|
},
|
|
49
50
|
{
|
|
50
51
|
name: 'options.list',
|
|
@@ -54,13 +55,14 @@ export const doc = {
|
|
|
54
55
|
{
|
|
55
56
|
name: 'options.category',
|
|
56
57
|
type: 'string',
|
|
57
|
-
description:
|
|
58
|
+
description:
|
|
59
|
+
"List only the components in this group: a key of the unfiltered list (each component's group field), such as 'Layout' or 'Button'. It is not the category field of a component detail.",
|
|
58
60
|
},
|
|
59
61
|
{
|
|
60
62
|
name: 'options.package',
|
|
61
63
|
type: 'string',
|
|
62
64
|
description:
|
|
63
|
-
"Scope lookup to a specific external package (e.g. '@acme/
|
|
65
|
+
"Scope lookup to a specific external package (e.g. '@acme/widgets').",
|
|
64
66
|
},
|
|
65
67
|
{
|
|
66
68
|
name: 'options.props',
|
|
@@ -87,7 +89,8 @@ export const doc = {
|
|
|
87
89
|
name: 'options.detail',
|
|
88
90
|
type: "'full' | 'compact' | 'brief'",
|
|
89
91
|
description: 'Detail level for list views.',
|
|
90
|
-
default:
|
|
92
|
+
default:
|
|
93
|
+
"'full' for a named component; 'brief' for lists (returned as data.detail: 'names')",
|
|
91
94
|
},
|
|
92
95
|
{
|
|
93
96
|
name: 'options.lang',
|
|
@@ -110,7 +113,7 @@ export const doc = {
|
|
|
110
113
|
{
|
|
111
114
|
type: 'component.list',
|
|
112
115
|
description:
|
|
113
|
-
"The catalog grouped by
|
|
116
|
+
"The catalog grouped by component group. data.detail is the level ('names' | 'compact' | 'full') and data.components is the grouped map: names entries with name, package, and an optional canonical import for integration and legacy package components; brief entries; or full ComponentDoc entries.",
|
|
114
117
|
},
|
|
115
118
|
{
|
|
116
119
|
type: 'component.batch',
|
|
@@ -160,7 +163,7 @@ export const doc = {
|
|
|
160
163
|
},
|
|
161
164
|
{
|
|
162
165
|
code: 'ERR_UNKNOWN_CATEGORY',
|
|
163
|
-
when: 'options.category is not a string or matches no
|
|
166
|
+
when: 'options.category is not a string or matches no component group',
|
|
164
167
|
},
|
|
165
168
|
{
|
|
166
169
|
code: 'ERR_UNKNOWN_COMPONENT',
|
|
@@ -174,6 +177,10 @@ export const doc = {
|
|
|
174
177
|
code: 'ERR_NO_DOC',
|
|
175
178
|
when: 'the resolved component has no .doc.mjs typed doc file',
|
|
176
179
|
},
|
|
180
|
+
{
|
|
181
|
+
code: 'ERR_INVALID_DOC',
|
|
182
|
+
when: "the resolved component's .doc.mjs fails to load or validate",
|
|
183
|
+
},
|
|
177
184
|
{
|
|
178
185
|
code: 'ERR_NO_SOURCE',
|
|
179
186
|
when: 'options.source is set but the component has no source file',
|
|
@@ -194,8 +201,8 @@ export const doc = {
|
|
|
194
201
|
},
|
|
195
202
|
{label: 'Props only', code: "await component('Button', {props: true});"},
|
|
196
203
|
{
|
|
197
|
-
label: 'Browse
|
|
198
|
-
code: "await component(undefined, {category: '
|
|
204
|
+
label: 'Browse one group',
|
|
205
|
+
code: "await component(undefined, {category: 'Layout', detail: 'compact'});",
|
|
199
206
|
},
|
|
200
207
|
],
|
|
201
208
|
command: 'component',
|
package/api/docs/_adapter.d.mts
CHANGED
|
@@ -77,10 +77,12 @@ export function docsLinkProblems(catalog: DocsCatalog, tree: DocsTree, { owner,
|
|
|
77
77
|
/**
|
|
78
78
|
* What \`astryx doctor integration docs\` checks in one integration's docs: the
|
|
79
79
|
* docs tree they build beside the CLI's (namespaces, placements, routes) and
|
|
80
|
-
* every link in them (spec:AST-046, spec:AST-047).
|
|
80
|
+
* every link in them (spec:AST-046, spec:AST-047). A tree problem hides a doc,
|
|
81
|
+
* so it is an error; a link that names no doc prints as written, so it is a
|
|
82
|
+
* warning.
|
|
81
83
|
* @param {{name: string}} integration
|
|
82
84
|
* @param {{records: import('../../foundation/discovery/docs-discovery.mjs').DocsTopicRecord[], namespaces: import('../../foundation/doc-compiler/tree.mjs').TreeNamespaceInput[], guides: import('../../foundation/doc-compiler/tree.mjs').TreeDocInput[]}} discovered
|
|
83
|
-
* @returns {Promise<string
|
|
85
|
+
* @returns {Promise<Array<{severity: 'error' | 'warning', message: string}>>}
|
|
84
86
|
*/
|
|
85
87
|
export function packageDocsProblems(integration: {
|
|
86
88
|
name: string;
|
|
@@ -88,7 +90,10 @@ export function packageDocsProblems(integration: {
|
|
|
88
90
|
records: import("../../foundation/discovery/docs-discovery.mjs").DocsTopicRecord[];
|
|
89
91
|
namespaces: import("../../foundation/doc-compiler/tree.mjs").TreeNamespaceInput[];
|
|
90
92
|
guides: import("../../foundation/doc-compiler/tree.mjs").TreeDocInput[];
|
|
91
|
-
}): Promise<
|
|
93
|
+
}): Promise<Array<{
|
|
94
|
+
severity: "error" | "warning";
|
|
95
|
+
message: string;
|
|
96
|
+
}>>;
|
|
92
97
|
/**
|
|
93
98
|
* How a token reference finds its target: the topic it names in `catalog`,
|
|
94
99
|
* lowered for the same language.
|
package/api/docs/_adapter.mjs
CHANGED
|
@@ -667,10 +667,12 @@ export async function docsLinkProblems(
|
|
|
667
667
|
/**
|
|
668
668
|
* What \`astryx doctor integration docs\` checks in one integration's docs: the
|
|
669
669
|
* docs tree they build beside the CLI's (namespaces, placements, routes) and
|
|
670
|
-
* every link in them (spec:AST-046, spec:AST-047).
|
|
670
|
+
* every link in them (spec:AST-046, spec:AST-047). A tree problem hides a doc,
|
|
671
|
+
* so it is an error; a link that names no doc prints as written, so it is a
|
|
672
|
+
* warning.
|
|
671
673
|
* @param {{name: string}} integration
|
|
672
674
|
* @param {{records: import('../../foundation/discovery/docs-discovery.mjs').DocsTopicRecord[], namespaces: import('../../foundation/doc-compiler/tree.mjs').TreeNamespaceInput[], guides: import('../../foundation/doc-compiler/tree.mjs').TreeDocInput[]}} discovered
|
|
673
|
-
* @returns {Promise<string
|
|
675
|
+
* @returns {Promise<Array<{severity: 'error' | 'warning', message: string}>>}
|
|
674
676
|
*/
|
|
675
677
|
export async function packageDocsProblems(integration, discovered) {
|
|
676
678
|
const catalog = DocsCatalog.fromBuiltins();
|
|
@@ -680,12 +682,18 @@ export async function packageDocsProblems(integration, discovered) {
|
|
|
680
682
|
guides: discovered.guides.map(input => ({...input, rank: 1})),
|
|
681
683
|
});
|
|
682
684
|
const tree = await projectTree(catalog);
|
|
685
|
+
/** @type {Array<{severity: 'error' | 'warning', message: string}>} */
|
|
683
686
|
const problems = tree.diagnostics
|
|
684
687
|
.filter(d => d.severity === 'error' && d.provider === integration.name)
|
|
685
|
-
.map(d =>
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
688
|
+
.map(d => ({
|
|
689
|
+
severity: /** @type {const} */ ('error'),
|
|
690
|
+
message: `${d.source ?? integration.name}: ${d.message}`,
|
|
691
|
+
}));
|
|
692
|
+
for (const message of await docsLinkProblems(catalog, tree, {
|
|
693
|
+
owner: integration.name,
|
|
694
|
+
})) {
|
|
695
|
+
problems.push({severity: 'warning', message});
|
|
696
|
+
}
|
|
689
697
|
return problems;
|
|
690
698
|
}
|
|
691
699
|
|
|
@@ -76,6 +76,32 @@ describe('reference doc overlays (#2182)', () => {
|
|
|
76
76
|
).toEqual([]);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
+
it(`${topic} --${variant}: every content override lands on a block of its own type`, async () => {
|
|
80
|
+
// Blocks are matched by index and type, and a mismatch is dropped with
|
|
81
|
+
// no warning: a prose override aimed at a code block leaves the base
|
|
82
|
+
// text in place, so the reader gets a translated title over an English
|
|
83
|
+
// body. Pad with null to reach the block you mean.
|
|
84
|
+
const base = await load(basePath);
|
|
85
|
+
const overlayMod = await load(overlayPath);
|
|
86
|
+
const overlay = overlayMod.docsDense || overlayMod.docsZh;
|
|
87
|
+
const byTitle = new Map(base.docs.sections.map(s => [s.title, s]));
|
|
88
|
+
const dropped = [];
|
|
89
|
+
for (const entry of overlay.sections || []) {
|
|
90
|
+
const section = byTitle.get(entry.section);
|
|
91
|
+
if (!section) continue;
|
|
92
|
+
(entry.content || []).forEach((block, i) => {
|
|
93
|
+
if (block == null) return;
|
|
94
|
+
const target = section.content[i];
|
|
95
|
+
if (target?.type !== block.type) {
|
|
96
|
+
dropped.push(
|
|
97
|
+
`${entry.section} block ${i}: ${block.type} over ${target?.type ?? 'nothing'}`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
expect(dropped, `${topic}.doc.${variant}.mjs overrides that never apply`).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
|
|
79
105
|
it(`${topic} --${variant}: no base section is overridden twice`, async () => {
|
|
80
106
|
const overlayMod = await load(overlayPath);
|
|
81
107
|
const overlay = overlayMod.docsDense || overlayMod.docsZh;
|
|
@@ -127,7 +153,7 @@ describe('the reported defect: docs tokens --dense (#2182)', () => {
|
|
|
127
153
|
const zh = await docs('theme', null, {zh: true});
|
|
128
154
|
const titles = zh.data.sections.map(s => s.title);
|
|
129
155
|
// Every section the overlay translates must appear once, in Chinese only.
|
|
130
|
-
expect(titles).not.toContain('
|
|
156
|
+
expect(titles).not.toContain('Dark mode');
|
|
131
157
|
expect(titles).toContain('亮/暗模式');
|
|
132
158
|
});
|
|
133
159
|
});
|
package/api/docs/docs.doc.mjs
CHANGED
|
@@ -27,7 +27,7 @@ export const doc = {
|
|
|
27
27
|
'A route opens a node of the docs tree instead: a namespace such as ' +
|
|
28
28
|
"`cli/api` returns its children one level down, a typed doc such as " +
|
|
29
29
|
"`cli/api/functions/search` returns its content, and a guide the tree " +
|
|
30
|
-
'places (`cli/integrations`) reads like any topic. ' +
|
|
30
|
+
'places (`cli/integrations/quick-start`) reads like any topic. ' +
|
|
31
31
|
'Every read but the list carries `links`, the commands that move from it: ' +
|
|
32
32
|
'`up` to the level it sits in, `previous` and `next` to its neighbors, and, ' +
|
|
33
33
|
'for a typed doc, `related` to the docs it names (its command or function, ' +
|
|
@@ -137,7 +137,7 @@ export const doc = {
|
|
|
137
137
|
{label: 'One API function', code: "await docs('cli/api/functions/search');"},
|
|
138
138
|
{
|
|
139
139
|
label: 'A whole guide from the docs tree',
|
|
140
|
-
code: "await docs('cli/integrations');",
|
|
140
|
+
code: "await docs('cli/integrations/quick-start');",
|
|
141
141
|
},
|
|
142
142
|
{label: 'One section by key', code: "await docs('tokens', 'spacing');"},
|
|
143
143
|
],
|
|
@@ -13,14 +13,18 @@ export const doc = {
|
|
|
13
13
|
name: 'doctor',
|
|
14
14
|
namespace: 'cli/api',
|
|
15
15
|
displayName: 'doctor()',
|
|
16
|
-
summary:
|
|
16
|
+
summary:
|
|
17
|
+
"Check a project's Astryx setup and get a pass/warn/fail report per check. Use it as a CI gate or before debugging a broken install.",
|
|
17
18
|
description:
|
|
18
|
-
'Runs a series of
|
|
19
|
+
'Runs a series of diagnostics: Node version, ' +
|
|
19
20
|
'@astryxdesign/core install and version alignment with the CLI, installed ' +
|
|
20
21
|
'themes and wiring, astryx.config validity, integrations linked from ' +
|
|
21
|
-
'package.json without a config entry,
|
|
22
|
-
'
|
|
23
|
-
'
|
|
22
|
+
'package.json without a config entry, core peer dependencies, ' +
|
|
23
|
+
'integration provider identity and contribution issues, agent docs, the ' +
|
|
24
|
+
'detected package manager, and the health of the docs the CLI reads (authoring ' +
|
|
25
|
+
'and CLI docs, the docs tree, doc size), and returns a structured ' +
|
|
26
|
+
'report. It only reads (never installs, writes, or mutates), apart from ' +
|
|
27
|
+
"importing astryx.config, which runs that file's top-level code, so it is safe " +
|
|
24
28
|
'as a CI gate and for agents to invoke.',
|
|
25
29
|
importPath: '@astryxdesign/cli/api',
|
|
26
30
|
signature: 'doctor(options?: DoctorOptions): Promise<DoctorResponse>',
|
|
@@ -29,18 +33,23 @@ export const doc = {
|
|
|
29
33
|
{
|
|
30
34
|
name: 'options.cwd',
|
|
31
35
|
type: 'string',
|
|
32
|
-
description:
|
|
36
|
+
description:
|
|
37
|
+
'Directory to diagnose. A missing directory is not an error; it shows up in the checks (e.g. core-installed: fail).',
|
|
38
|
+
default: 'process.cwd()',
|
|
33
39
|
},
|
|
34
40
|
],
|
|
35
41
|
returns: [
|
|
36
42
|
{
|
|
37
43
|
type: 'doctor',
|
|
38
44
|
description:
|
|
39
|
-
'The diagnostic report: `data.checks`, each with a stable id, label, `status` (`pass` | `warn` | `fail` | `info`), a one-line message, and
|
|
45
|
+
'The diagnostic report: `data.checks`, each with a stable id, label, `status` (`pass` | `warn` | `fail` | `info`), a one-line message, and an optional `fix` (always present on `warn` and `fail`; some `info` checks carry one too); plus `data.summary` with counts per status.',
|
|
40
46
|
},
|
|
41
47
|
],
|
|
42
48
|
examples: [
|
|
43
|
-
{
|
|
49
|
+
{
|
|
50
|
+
label: 'Fail a CI step on any failed check',
|
|
51
|
+
code: 'const r = await doctor();\nif (r.data.summary.fail > 0) process.exitCode = 1;',
|
|
52
|
+
},
|
|
44
53
|
{
|
|
45
54
|
label: 'Diagnose a directory',
|
|
46
55
|
code: "await doctor({cwd: '/path/to/app'});",
|