@astryxdesign/cli 0.6.3 → 0.6.4-canary.10dd683
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/README.md +117 -78
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/_adapter.d.mts +50 -0
- package/api/build/_adapter.mjs +60 -0
- package/api/build/build.doc.mjs +16 -9
- package/api/build/build.test.mjs +197 -8
- package/api/build/build.type.d.mts +91 -2
- package/api/build/build.type.mjs +52 -8
- package/api/build/help/help.d.mts +12 -5
- package/api/build/help/help.mjs +69 -6
- package/api/build/kit/kit.d.mts +4 -1
- package/api/build/kit/kit.mjs +165 -49
- package/api/build/kit/rank.d.mts +44 -0
- package/api/build/kit/rank.mjs +432 -0
- package/api/build/kit/rank.test.mjs +196 -0
- package/api/component/_adapter.d.mts +6 -12
- package/api/component/_adapter.mjs +20 -10
- package/api/component/component.doc.mjs +13 -3
- package/api/component/component.mjs +91 -14
- package/api/component/component.test.mjs +38 -0
- package/api/component/component.type.d.mts +22 -11
- package/api/component/component.type.mjs +32 -24
- package/api/component/detail/blocks/blocks.d.mts +2 -1
- package/api/component/detail/blocks/blocks.mjs +4 -3
- package/api/component/list/list.d.mts +0 -5
- package/api/component/list/list.mjs +40 -11
- package/api/discover/_adapter.d.mts +114 -6
- package/api/discover/_adapter.mjs +372 -17
- package/api/discover/_adapter.test.mjs +215 -0
- package/api/discover/_catalog-view.d.mts +115 -0
- package/api/discover/_catalog-view.mjs +203 -0
- package/api/discover/_catalog-view.test.mjs +128 -0
- package/api/discover/detail/detail.d.mts +18 -6
- package/api/discover/detail/detail.mjs +67 -13
- package/api/discover/detail/detail.test.mjs +85 -0
- package/api/discover/detail/item/item.d.mts +26 -0
- package/api/discover/detail/item/item.mjs +78 -0
- package/api/discover/detail/item/item.test.mjs +73 -0
- package/api/discover/discover.d.mts +3 -9
- package/api/discover/discover.doc.mjs +62 -18
- package/api/discover/discover.mjs +220 -36
- package/api/discover/discover.test.mjs +11 -2
- package/api/discover/discover.type.d.mts +150 -11
- package/api/discover/discover.type.mjs +107 -17
- package/api/discover/list/list.d.mts +20 -6
- package/api/discover/list/list.mjs +45 -12
- package/api/discover/list/list.test.mjs +46 -0
- package/api/discover/search/search.d.mts +18 -16
- package/api/discover/search/search.mjs +102 -56
- package/api/discover/search/search.test.mjs +144 -10
- package/api/docs/_adapter.d.mts +272 -41
- package/api/docs/_adapter.mjs +985 -108
- package/api/docs/compiled-topics.test.mjs +78 -0
- package/api/docs/detail/detail.mjs +22 -63
- package/api/docs/detail/section/section.d.mts +1 -1
- package/api/docs/detail/section/section.mjs +54 -19
- package/api/docs/detail/section/section.test.mjs +50 -0
- package/api/docs/docs.d.mts +10 -3
- package/api/docs/docs.doc.mjs +55 -16
- package/api/docs/docs.mjs +53 -10
- package/api/docs/docs.test.mjs +164 -4
- package/api/docs/docs.type.d.mts +221 -5
- package/api/docs/docs.type.mjs +153 -11
- package/api/docs/index/index.d.mts +18 -0
- package/api/docs/index/index.mjs +40 -0
- package/api/docs/index/index.test.mjs +62 -0
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +114 -8
- package/api/docs/list/list.mjs +28 -12
- package/api/docs/node/node.d.mts +43 -0
- package/api/docs/node/node.mjs +192 -0
- package/api/docs/reference-blocks.test.mjs +406 -0
- package/api/doctor/doctor.d.mts +99 -1
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +548 -1
- package/api/doctor/doctor.test.mjs +610 -1
- package/api/gap-report/gap-report.doc.mjs +8 -4
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/hook.type.d.mts +3 -3
- package/api/hook/hook.type.mjs +11 -11
- package/api/hook/list/list.d.mts +2 -2
- package/api/hook/list/list.mjs +69 -17
- package/api/index.d.mts +1 -1
- package/api/index.mjs +1 -0
- package/api/init/init.doc.mjs +6 -1
- package/api/init/init.test.mjs +41 -1
- package/api/init/remove/remove.mjs +1 -1
- package/api/init/run/run.mjs +20 -10
- package/api/integration/add-contribution.component-names.test.mjs +120 -0
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +130 -15
- package/api/integration/add-contribution.test.mjs +258 -7
- package/api/integration/add-helpers.d.mts +5 -2
- package/api/integration/add-helpers.mjs +36 -9
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.mjs +138 -28
- package/api/integration/authoring-checks.test.mjs +179 -7
- package/api/integration/authoring-checks.type.mjs +6 -1
- package/api/integration/integration-authoring.type.d.mts +3 -1
- package/api/integration/integration-authoring.type.mjs +2 -0
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +14 -4
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +2 -1
- package/api/integration/integrationAddDoc.doc.mjs +8 -1
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +2 -1
- package/api/integration/integrationPackCheck.doc.mjs +2 -1
- package/api/integration/integrationTemplateConflicts.doc.d.mts +3 -0
- package/api/integration/integrationTemplateConflicts.doc.mjs +4 -0
- package/api/integration/pack-check.mjs +83 -7
- package/api/integration/pack-check.test.mjs +387 -47
- package/api/integration/pack-check.type.d.mts +26 -2
- package/api/integration/pack-check.type.mjs +14 -1
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/template-conflict-compatibility.test.mjs +73 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +52 -102
- package/api/integration/validate-integration.test.mjs +179 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +3 -2
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/envelope-types.test.mjs +76 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +3 -2
- package/api/layout/_adapter.mjs +20 -5
- package/api/layout/expand/expand.mjs +7 -5
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.mjs +2 -1
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +2 -1
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search-return-type.test.mjs +54 -0
- package/api/search/search.d.mts +62 -11
- package/api/search/search.doc.mjs +8 -2
- package/api/search/search.mjs +471 -83
- package/api/search/search.test.mjs +124 -1
- package/api/search/search.type.d.mts +15 -3
- package/api/search/search.type.mjs +5 -2
- package/api/swizzle/copy/copy.mjs +28 -11
- package/api/swizzle/swizzle.doc.mjs +2 -1
- package/api/swizzle/swizzle.type.d.mts +2 -2
- package/api/swizzle/swizzle.type.mjs +2 -2
- package/api/template/copy/copy.mjs +17 -23
- package/api/template/copy/copy.test.mjs +17 -0
- package/api/template/list/list.mjs +1 -0
- package/api/template/table-floating-bulk-actions.test.mjs +66 -0
- package/api/template/template-integration.test.mjs +1072 -3
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.d.mts +1 -1
- package/api/template/template.doc.mjs +30 -8
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +12 -14
- package/api/template/template.type.mjs +15 -14
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +84 -0
- package/api/theme/add/add.mjs +31 -22
- package/api/theme/add/add.rollback.test.mjs +158 -0
- package/api/theme/add/add.staging.test.mjs +83 -0
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/build/build.family.test.mjs +7 -12
- package/api/theme/build/build.mjs +140 -59
- package/api/theme/build/build.public-component-vars.test.mjs +1 -1
- package/api/theme/build/build.receipt-doc.test.mjs +111 -0
- package/api/theme/build/build.rollback.test.mjs +148 -0
- package/api/theme/build/build.test.mjs +127 -0
- package/api/theme/build/font-warning.mjs +3 -3
- package/api/theme/build/font-warning.test.mjs +5 -2
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/palette/generate/generate.mjs +8 -3
- package/api/theme/palette/generate/generate.test.mjs +96 -0
- package/api/theme/palette/generate/generator.d.mts +10 -13
- package/api/theme/palette/generate/generator.mjs +15 -4
- package/api/theme/palette/generate/generator.test.mjs +10 -0
- package/api/theme/template/template.mjs +11 -2
- package/api/theme/template/template.test.mjs +20 -0
- package/api/theme/theme.type.d.mts +170 -11
- package/api/theme/theme.type.mjs +94 -27
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +8 -4
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +6 -2
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +139 -22
- package/api/upgrade/list/list.mjs +2 -1
- package/api/upgrade/list/list.test.mjs +73 -0
- package/api/upgrade/project-context.test.mjs +272 -0
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/status/status.mjs +2 -2
- package/api/upgrade/upgrade.doc.mjs +12 -5
- package/api/upgrade/upgrade.type.d.mts +43 -5
- package/api/upgrade/upgrade.type.mjs +27 -11
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +48 -4
- package/assets/codemods/integration-discovery.test.mjs +73 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- package/assets/codemods/term-log.mjs +32 -8
- package/assets/codemods/term-log.test.mjs +19 -1
- package/assets/codemods/transform-prop.mjs +109 -0
- package/assets/codemods/transform-prop.test.mjs +95 -0
- package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
- package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
- package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
- package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +27 -5
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +20 -5
- package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
- package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
- package/assets/codemods/transforms/v0.6.4/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/v0.6.4/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/v0.6.4/index.mjs +31 -0
- package/assets/codemods/transforms/v0.6.4/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/v0.6.4/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/docs/README.md +9 -0
- package/assets/docs/authoring.doc.mjs +14 -0
- package/assets/docs/getting-started.doc.mjs +2 -2
- package/assets/docs/internationalization.doc.mjs +7 -5
- package/assets/docs/layout.doc.dense.mjs +2 -2
- package/assets/docs/layout.doc.mjs +1 -1
- package/assets/docs/principles.doc.mjs +6 -6
- package/assets/docs/styling-libraries.doc.mjs +4 -4
- package/assets/docs/styling.doc.mjs +4 -4
- package/assets/docs/theme.doc.mjs +5 -5
- package/assets/docs/tokens.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +30 -0
- package/assets/docs/tree/cli.doc.mjs +23 -0
- package/assets/docs/tree/commands.doc.mjs +25 -0
- package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +144 -26
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/working-with-ai.doc.mjs +4 -4
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.doc.mjs +1 -1
- package/assets/templates/blocks/components/CheckboxList/CheckboxListSelectAllPattern.tsx +1 -3
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.doc.mjs +14 -0
- package/assets/templates/blocks/components/Table/TableBulkActionsTable.tsx +71 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.doc.mjs +19 -0
- package/assets/templates/blocks/components/Table/TableFloatingBulkActionsTable.tsx +139 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerFormats.tsx +34 -0
- package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerInline.tsx +14 -0
- package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +13 -0
- package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +47 -0
- package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +14 -0
- package/assets/templates/blocks/components/Timer/TimerTypography.tsx +31 -0
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +19 -3
- package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +383 -65
- package/assets/templates/pages/table-tree/page.tsx +1704 -0
- package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/_shared/contract.ts +22 -0
- package/authoring/codemod/codemod.doc.mjs +7 -2
- package/authoring/codemod/parse.d.mts +8 -8
- package/authoring/codemod/parse.mjs +8 -6
- package/authoring/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +10 -2
- package/authoring/config/debug-composition.test.mjs +92 -0
- package/authoring/config/parse.d.mts +15 -13
- package/authoring/config/parse.mjs +27 -8
- package/authoring/config/parse.test.mjs +8 -0
- package/authoring/config/type.ts +29 -6
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +8 -8
- package/authoring/debug/parse.mjs +3 -3
- package/authoring/discover/discover.doc.d.mts +13 -0
- package/authoring/discover/discover.doc.mjs +138 -0
- package/authoring/discover/parse.d.mts +24 -0
- package/authoring/discover/parse.mjs +128 -0
- package/authoring/discover/parse.test.mjs +124 -0
- package/authoring/discover/type.ts +87 -0
- package/authoring/doctypes/_schema.d.mts +790 -23
- package/authoring/doctypes/_schema.mjs +543 -39
- package/authoring/doctypes/base/graph-fields.doc.d.mts +9 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +64 -0
- package/authoring/doctypes/base/type.ts +41 -0
- package/authoring/doctypes/command/command.doc.mjs +4 -3
- package/authoring/doctypes/command/parse.d.mts +2 -2
- package/authoring/doctypes/command/parse.mjs +1 -1
- package/authoring/doctypes/command/type.ts +5 -4
- package/authoring/doctypes/component/component.doc.mjs +6 -3
- package/authoring/doctypes/component/parse.d.mts +2 -2
- package/authoring/doctypes/component/parse.mjs +1 -1
- package/authoring/doctypes/component/type.ts +6 -5
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/parse.d.mts +2 -2
- package/authoring/doctypes/enum/parse.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +4 -2
- package/authoring/doctypes/function/function.doc.mjs +7 -2
- package/authoring/doctypes/function/parse.d.mts +2 -2
- package/authoring/doctypes/function/parse.mjs +1 -1
- package/authoring/doctypes/function/type.ts +9 -4
- package/authoring/doctypes/hook/hook.doc.mjs +4 -0
- package/authoring/doctypes/hook/parse.d.mts +2 -2
- package/authoring/doctypes/hook/parse.mjs +1 -1
- package/authoring/doctypes/hook/type.ts +5 -4
- package/authoring/doctypes/legacy.d.mts +8 -6
- package/authoring/doctypes/legacy.mjs +5 -4
- package/authoring/doctypes/load-contract.test.mjs +233 -0
- package/authoring/doctypes/namespace/namespace.doc.d.mts +9 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +128 -0
- package/authoring/doctypes/namespace/parse.d.mts +12 -0
- package/authoring/doctypes/namespace/parse.mjs +25 -0
- package/authoring/doctypes/namespace/parse.test.mjs +163 -0
- package/authoring/doctypes/namespace/type.ts +74 -0
- package/authoring/doctypes/parse.d.mts +22 -18
- package/authoring/doctypes/parse.mjs +22 -11
- package/authoring/doctypes/parse.test.mjs +77 -3
- package/authoring/doctypes/reference/parse.d.mts +2 -2
- package/authoring/doctypes/reference/parse.mjs +8 -5
- package/authoring/doctypes/reference/reference.doc.mjs +48 -6
- package/authoring/doctypes/reference/type.ts +70 -7
- package/authoring/doctypes/schema/parse.d.mts +2 -2
- package/authoring/doctypes/schema/parse.mjs +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +4 -4
- package/authoring/doctypes/template/parse.d.mts +94 -1
- package/authoring/doctypes/template/parse.mjs +40 -2
- package/authoring/doctypes/template/parse.test.mjs +26 -2
- package/authoring/doctypes/template/template.doc.mjs +13 -3
- package/authoring/doctypes/template/type.ts +13 -2
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +12 -10
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/gap-report/parse.d.mts +10 -10
- package/authoring/gap-report/parse.mjs +6 -6
- package/authoring/gap-report/type.ts +1 -1
- package/authoring/identity/identity.doc.d.mts +9 -0
- package/authoring/identity/identity.doc.mjs +61 -0
- package/authoring/identity/type.ts +132 -0
- package/authoring/index.d.mts +3 -0
- package/authoring/index.d.ts +62 -17
- package/authoring/index.mjs +4 -1
- package/authoring/integration/integration.doc.mjs +15 -8
- package/authoring/integration/parse.d.mts +2 -2
- package/authoring/integration/parse.mjs +1 -1
- package/authoring/integration/parse.test.mjs +10 -1
- package/authoring/integration/schema.d.mts +6 -4
- package/authoring/integration/schema.mjs +9 -3
- package/authoring/integration/type.ts +19 -8
- package/authoring/shadcn/receipt.d.mts +6 -6
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/command-load-failure.test.mjs +83 -0
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/blog.mjs +23 -8
- package/clients/cli/commands/blog.test.mjs +42 -1
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
- package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
- package/clients/cli/commands/build-theme.mjs +16 -50
- package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
- package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
- package/clients/cli/commands/build.doc.mjs +16 -8
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
- package/clients/cli/commands/build.mjs +137 -114
- package/clients/cli/commands/build.playbook.test.mjs +75 -0
- package/clients/cli/commands/build.text-fields.test.mjs +81 -0
- package/clients/cli/commands/component/index.mjs +3 -8
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- package/clients/cli/commands/component-package.test.mjs +46 -0
- package/clients/cli/commands/component-resolution.test.mjs +21 -0
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/component.test.mjs +19 -0
- package/clients/cli/commands/detail-levels.test.mjs +2 -2
- package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
- package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
- package/clients/cli/commands/discover.doc.mjs +55 -9
- package/clients/cli/commands/discover.mjs +393 -118
- package/clients/cli/commands/discover.sources.test.mjs +267 -0
- package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
- package/clients/cli/commands/docs.doc.mjs +28 -6
- package/clients/cli/commands/docs.mjs +240 -26
- package/clients/cli/commands/docs.test.mjs +193 -1
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
- package/clients/cli/commands/doctor-integration.test.mjs +90 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +59 -32
- package/clients/cli/commands/doctor.test.mjs +42 -0
- package/clients/cli/commands/gap-report.doc.mjs +17 -6
- package/clients/cli/commands/gap-report.test.mjs +72 -0
- package/clients/cli/commands/hook/index.mjs +7 -17
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
- package/clients/cli/commands/init.doc.mjs +20 -9
- package/clients/cli/commands/init.flag-help.test.mjs +153 -0
- package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
- package/clients/cli/commands/integration-add.doc.mjs +32 -6
- package/clients/cli/commands/integration-authoring.test.mjs +13 -9
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/integration.mjs +1 -0
- package/clients/cli/commands/interactive-guard.test.mjs +101 -24
- package/clients/cli/commands/json-contract.test.mjs +33 -0
- package/clients/cli/commands/layout-check.doc.mjs +15 -4
- package/clients/cli/commands/layout-expand.doc.mjs +22 -5
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +3 -3
- package/clients/cli/commands/layout.mjs +21 -9
- 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/no-prompt-wording.test.mjs +94 -0
- package/clients/cli/commands/search.doc.mjs +7 -4
- package/clients/cli/commands/search.mjs +28 -9
- package/clients/cli/commands/search.test.mjs +75 -0
- package/clients/cli/commands/setup-nudge.test.mjs +6 -0
- package/clients/cli/commands/swizzle.doc.mjs +3 -2
- package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
- package/clients/cli/commands/template.doc.mjs +52 -13
- package/clients/cli/commands/template.flag-help.test.mjs +117 -0
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/template.path-help.test.mjs +40 -0
- package/clients/cli/commands/text-json-parity.test.mjs +719 -0
- package/clients/cli/commands/theme-add.doc.mjs +4 -3
- package/clients/cli/commands/theme-build.doc.mjs +8 -7
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +9 -5
- package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
- package/clients/cli/commands/theme-template.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
- package/clients/cli/commands/upgrade.doc.mjs +22 -10
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
- package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +164 -1
- package/clients/cli/formatters/index.test.mjs +97 -0
- package/clients/cli/index.mjs +21 -30
- package/clients/cli/latest-version-env.test.mjs +50 -0
- package/clients/cli/lib/cli-error.test.mjs +7 -0
- package/clients/cli/lib/component-format.mjs +9 -9
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +32 -6
- package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
- package/clients/cli/lib/exit-codes.test.mjs +97 -0
- package/clients/cli/lib/hook-format.mjs +19 -10
- package/clients/cli/lib/json-shim.mjs +38 -2
- package/clients/cli/lib/json-shim.test.mjs +83 -0
- package/clients/cli/lib/manifest.d.ts +2 -0
- package/clients/cli/lib/manifest.mjs +37 -2
- package/clients/cli/lib/manifest.test.mjs +17 -0
- package/foundation/agent-docs/agent-docs.d.mts +7 -2
- package/foundation/agent-docs/agent-docs.mjs +82 -12
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
- package/foundation/agent-docs/agent-docs.test.mjs +19 -1
- package/foundation/config/integration-debug.test.mjs +28 -3
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +263 -91
- package/foundation/config/project.test.mjs +270 -21
- package/foundation/discovery/authoring-self-docs.d.mts +87 -0
- package/foundation/discovery/authoring-self-docs.mjs +237 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +170 -0
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +119 -0
- package/foundation/discovery/cli-self-docs.mjs +490 -0
- package/foundation/discovery/cli-self-docs.test.mjs +375 -0
- package/foundation/discovery/component-discovery.d.mts +39 -1
- package/foundation/discovery/component-discovery.mjs +50 -1
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +119 -11
- package/foundation/discovery/docs-discovery.mjs +423 -108
- package/foundation/discovery/docs-discovery.test.mjs +365 -20
- package/foundation/discovery/docs-output-budget.d.mts +28 -0
- package/foundation/discovery/docs-output-budget.mjs +50 -0
- package/foundation/discovery/docs-section-key.d.mts +116 -0
- package/foundation/discovery/docs-section-key.mjs +322 -0
- package/foundation/discovery/docs-section-key.test.mjs +246 -0
- package/foundation/discovery/template-adapter.d.mts +113 -11
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
- package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
- package/foundation/discovery/template-adapter.mjs +774 -83
- package/foundation/discovery/template-adapter.test.mjs +57 -0
- package/foundation/discovery/template-conflict-release.d.mts +13 -0
- package/foundation/discovery/template-conflict-release.mjs +40 -0
- package/foundation/discovery/template-conflict-release.test.mjs +40 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/discovery/theming-targets.test.mjs +4 -0
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +278 -0
- package/foundation/doc-compiler/bundle.test.mjs +266 -0
- package/foundation/doc-compiler/compile.d.mts +343 -0
- package/foundation/doc-compiler/compile.mjs +558 -0
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +305 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +714 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +291 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +22 -0
- package/foundation/doc-compiler/ir.mjs +471 -0
- package/foundation/doc-compiler/lenses.d.mts +36 -0
- package/foundation/doc-compiler/lenses.mjs +173 -0
- package/foundation/doc-compiler/links.d.mts +162 -0
- package/foundation/doc-compiler/links.mjs +294 -0
- package/foundation/doc-compiler/links.test.mjs +192 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +127 -0
- package/foundation/doc-compiler/read.mjs +325 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/doc-compiler/tree.d.mts +288 -0
- package/foundation/doc-compiler/tree.mjs +876 -0
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/fs/module-loader.d.mts +1 -0
- package/foundation/fs/module-loader.mjs +50 -1
- package/foundation/fs/module-loader.stdout.test.mjs +332 -0
- package/foundation/fs/path-safety.d.mts +3 -2
- package/foundation/fs/path-safety.mjs +49 -19
- package/foundation/fs/path-safety.test.mjs +50 -0
- package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
- package/foundation/identity/provider-identity.d.mts +90 -0
- package/foundation/identity/provider-identity.mjs +320 -0
- package/foundation/identity/provider-identity.test.mjs +254 -0
- package/foundation/identity/providers.d.mts +7 -0
- package/foundation/identity/providers.mjs +16 -0
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -45
- package/foundation/integrations/autolink.test.mjs +1 -1
- package/foundation/integrations/cli-requirement.d.mts +45 -0
- package/foundation/integrations/cli-requirement.mjs +154 -0
- package/foundation/integrations/cli-requirement.test.mjs +84 -0
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +3 -2
- package/foundation/integrations/contribution-inventory.mjs +27 -24
- package/foundation/integrations/contribution-inventory.test.mjs +86 -27
- package/foundation/integrations/integration-warnings.d.mts +9 -2
- package/foundation/integrations/integration-warnings.mjs +52 -21
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +63 -3
- package/foundation/integrations/integrations.mjs +122 -9
- package/foundation/integrations/integrations.test.mjs +415 -1
- package/foundation/integrations/provider-conflicts.test.mjs +125 -0
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +131 -29
- package/foundation/response/base.d.ts +8 -4
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +13 -4
- package/foundation/response/error-codes.mjs +8 -2
- package/foundation/response/error-codes.test.mjs +137 -10
- package/foundation/response/json-contract.test.mjs +57 -17
- package/foundation/response/json.d.mts +4 -2
- package/foundation/response/json.mjs +8 -10
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +41 -21
- package/foundation/response/response-types.doc.test.mjs +158 -0
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.d.mts +8 -0
- package/foundation/text/string-utils.mjs +40 -10
- package/foundation/xle/expand.d.mts +2 -0
- package/foundation/xle/expand.mjs +4 -3
- package/foundation/xle/expand.test.mjs +54 -0
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -11
- package/assets/templates/themes/manifest.json +0 -95
- package/clients/cli/lib/update-check.mjs +0 -83
- package/clients/cli/lib/update-check.test.mjs +0 -137
- package/clients/cli/update-hint-commands.test.mjs +0 -54
package/clients/cli/index.mjs
CHANGED
|
@@ -16,7 +16,6 @@ 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 {checkForUpdate} from './lib/update-check.mjs';
|
|
20
19
|
import {getCliInvocation} from '../../foundation/env/package-manager.mjs';
|
|
21
20
|
import {API_VERSION, setJsonMode} from '../../foundation/response/json.mjs';
|
|
22
21
|
import {buildManifest} from './lib/manifest.mjs';
|
|
@@ -25,7 +24,8 @@ import {emit, section, text, records} from './formatters/index.mjs';
|
|
|
25
24
|
import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
|
|
26
25
|
import {levenshteinDistance} from '../../foundation/text/string-utils.mjs';
|
|
27
26
|
import {installJsonShim} from './lib/json-shim.mjs';
|
|
28
|
-
import {markReportsResult} from './lib/define-command.mjs';
|
|
27
|
+
import {addExitCodesHelp, markReportsResult} from './lib/define-command.mjs';
|
|
28
|
+
import {doc as manifestDoc} from './commands/manifest.doc.mjs';
|
|
29
29
|
import {isAstryxInitialized} from '../../foundation/agent-docs/agent-docs.mjs';
|
|
30
30
|
import * as debug from '../../foundation/debug/index.mjs';
|
|
31
31
|
|
|
@@ -275,8 +275,13 @@ const commands = [
|
|
|
275
275
|
{name: 'doctor', path: './commands/doctor.mjs', register: 'registerDoctor'},
|
|
276
276
|
];
|
|
277
277
|
|
|
278
|
-
const UPDATE_HINT_COMMANDS = new Set(['component', 'docs']);
|
|
279
278
|
const SETUP_NUDGE_EXEMPT = new Set(['init', 'agent-docs']);
|
|
279
|
+
/** An integration package's manifest: the package is not an app to set up. */
|
|
280
|
+
const INTEGRATION_MANIFEST_FILES = [
|
|
281
|
+
'astryx.integration.ts',
|
|
282
|
+
'astryx.integration.mjs',
|
|
283
|
+
'astryx.integration.js',
|
|
284
|
+
];
|
|
280
285
|
|
|
281
286
|
/**
|
|
282
287
|
* Build a fresh, fully-wired Astryx CLI program (root options, hooks, all
|
|
@@ -352,7 +357,7 @@ export async function createProgram() {
|
|
|
352
357
|
)
|
|
353
358
|
.option(
|
|
354
359
|
'--json',
|
|
355
|
-
'Output as typed JSON. Success envelope: { type, data }. Error envelope: { error, suggestions? }.',
|
|
360
|
+
'Output as typed JSON. Success envelope: { apiVersion, type, data, meta? }. Error envelope: { apiVersion, error, code, suggestions? }.',
|
|
356
361
|
)
|
|
357
362
|
.addHelpCommand('help', 'Show all commands')
|
|
358
363
|
.action((options, cmd) => {
|
|
@@ -499,25 +504,6 @@ export async function createProgram() {
|
|
|
499
504
|
process.exit(1);
|
|
500
505
|
});
|
|
501
506
|
|
|
502
|
-
/**
|
|
503
|
-
* Post-action hook: print update hint after any command output.
|
|
504
|
-
* Only fires for commands that produce output agents read (component, docs, etc.).
|
|
505
|
-
* Suppressed when --json is active to avoid contaminating stdout.
|
|
506
|
-
*/
|
|
507
|
-
program.hook('postAction', (thisCommand, actionCommand) => {
|
|
508
|
-
if (program.opts().json) return;
|
|
509
|
-
try {
|
|
510
|
-
if (UPDATE_HINT_COMMANDS.has(actionCommand.name())) {
|
|
511
|
-
const hint = checkForUpdate();
|
|
512
|
-
if (hint) {
|
|
513
|
-
console.error(`\n${hint}`);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
} catch {
|
|
517
|
-
// Never let update check break the CLI
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
|
|
521
507
|
/**
|
|
522
508
|
* Enforcement layer 3 — setup nudge. If this project hasn't run `astryx init`
|
|
523
509
|
* yet (no Astryx marker in any agent-doc file — see isAstryxInitialized), remind
|
|
@@ -539,6 +525,8 @@ export async function createProgram() {
|
|
|
539
525
|
if (SETUP_NUDGE_EXEMPT.has(actionCommand.name())) return;
|
|
540
526
|
const cwd = process.cwd();
|
|
541
527
|
if (!fs.existsSync(path.join(cwd, 'package.json'))) return; // not a project
|
|
528
|
+
// An integration package is not an app: `init` is not its next step.
|
|
529
|
+
if (INTEGRATION_MANIFEST_FILES.some(file => fs.existsSync(path.join(cwd, file)))) return;
|
|
542
530
|
if (isAstryxInitialized(cwd)) return; // already set up — stay quiet
|
|
543
531
|
// Same wording as the core/cli postinstall nudges. #4151's getCliInvocation()
|
|
544
532
|
// renders the correct form for THIS project — scoped `npx @astryxdesign/cli`
|
|
@@ -557,16 +545,18 @@ export async function createProgram() {
|
|
|
557
545
|
mod[cmd.register](program);
|
|
558
546
|
} catch (e) {
|
|
559
547
|
// Command fails to load but CLI still works
|
|
548
|
+
const reason = /** @type {any} */ (e).message;
|
|
560
549
|
const stub = program
|
|
561
550
|
.command(cmd.name)
|
|
562
|
-
.description(`(failed to load: ${
|
|
551
|
+
.description(`(failed to load: ${reason})`)
|
|
563
552
|
.action(() => {
|
|
564
553
|
// Nothing loaded, so nothing was answered — say that rather than
|
|
565
554
|
// leaving the run's result unreported.
|
|
566
555
|
debug.recordCommandResult(debug.NO_RESULT_SET);
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
556
|
+
// cliError, so --json still gets its one envelope.
|
|
557
|
+
cliError(`Command "${cmd.name}" failed to load: ${reason}`, {
|
|
558
|
+
code: ERROR_CODES.ERR_UNKNOWN,
|
|
559
|
+
});
|
|
570
560
|
});
|
|
571
561
|
markReportsResult(stub);
|
|
572
562
|
}
|
|
@@ -601,20 +591,21 @@ export async function createProgram() {
|
|
|
601
591
|
}
|
|
602
592
|
// Human-readable summary as greppable records (agents should use --json).
|
|
603
593
|
// One record per command: name, whether it supports --json, and the
|
|
604
|
-
// description.
|
|
594
|
+
// description. Field names are the manifest entry's own keys.
|
|
605
595
|
emit(
|
|
606
596
|
section(`${manifest.name} v${manifest.version} (${manifest.commands.length} commands)`),
|
|
607
597
|
records(
|
|
608
598
|
manifest.commands.map(c => ({
|
|
609
|
-
|
|
599
|
+
name: c.name,
|
|
610
600
|
json: c.json ? 'yes' : '',
|
|
611
601
|
description: c.description || '',
|
|
612
602
|
})),
|
|
613
|
-
{fields: ['
|
|
603
|
+
{fields: ['name', 'json', 'description']},
|
|
614
604
|
),
|
|
615
605
|
text(`Run \`${getCliInvocation()} manifest --json\` for the full structured manifest.`),
|
|
616
606
|
);
|
|
617
607
|
});
|
|
608
|
+
addExitCodesHelp(manifestCommand, manifestDoc.exitCodes);
|
|
618
609
|
markReportsResult(manifestCommand);
|
|
619
610
|
|
|
620
611
|
// Hidden command used by package.json postinstall scripts
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file ASTRYX_LATEST_VERSION is not a CLI control: setting it changes nothing
|
|
5
|
+
* a command prints. It used to append an update hint to `component` and
|
|
6
|
+
* `docs`.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {describe, it, expect, beforeEach, afterEach} from 'vitest';
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as os from 'node:os';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import {runCli} from '../../test-utils/run-cli.mjs';
|
|
14
|
+
|
|
15
|
+
const VARIABLE = 'ASTRYX_LATEST_VERSION';
|
|
16
|
+
|
|
17
|
+
/** @type {string} */
|
|
18
|
+
let dir;
|
|
19
|
+
/** @type {string | undefined} */
|
|
20
|
+
let saved;
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
saved = process.env[VARIABLE];
|
|
24
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-latest-version-'));
|
|
25
|
+
// A project on an old core, so a "newer version" hint would have a reason to fire.
|
|
26
|
+
fs.writeFileSync(
|
|
27
|
+
path.join(dir, 'package.json'),
|
|
28
|
+
JSON.stringify({name: 'app', private: true, dependencies: {'@astryxdesign/core': '^0.0.1'}}),
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(() => {
|
|
33
|
+
if (saved === undefined) delete process.env[VARIABLE];
|
|
34
|
+
else process.env[VARIABLE] = saved;
|
|
35
|
+
fs.rmSync(dir, {recursive: true, force: true});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('ASTRYX_LATEST_VERSION', () => {
|
|
39
|
+
it('does not change what astryx docs prints', async () => {
|
|
40
|
+
delete process.env[VARIABLE];
|
|
41
|
+
const without = await runCli(['docs'], {cwd: dir});
|
|
42
|
+
process.env[VARIABLE] = '999.0.0';
|
|
43
|
+
const withVariable = await runCli(['docs'], {cwd: dir});
|
|
44
|
+
|
|
45
|
+
expect(withVariable.status).toBe(without.status);
|
|
46
|
+
expect(withVariable.stdout).toBe(without.stdout);
|
|
47
|
+
expect(withVariable.stderr).toBe(without.stderr);
|
|
48
|
+
expect(withVariable.stderr).not.toMatch(/newer version/i);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -133,6 +133,13 @@ describe('cliError — JSON mode', () => {
|
|
|
133
133
|
expect(env.suggestions).toEqual([{name: 'Button', reason: 'closest match'}]);
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
+
it('replaces an unregistered code with ERR_UNKNOWN', () => {
|
|
137
|
+
expect(() =>
|
|
138
|
+
cliError('EACCES: permission denied', {code: 'EACCES'}),
|
|
139
|
+
).toThrow('__exit_1__');
|
|
140
|
+
expect(JSON.parse(stdout[0]).code).toBe('ERR_UNKNOWN');
|
|
141
|
+
});
|
|
142
|
+
|
|
136
143
|
it('always exits 1 in JSON mode (custom exitCode is ignored — contract)', () => {
|
|
137
144
|
expect(() => cliError('msg', {exitCode: 2})).toThrow('__exit_1__');
|
|
138
145
|
expect(exitCode).toBe(1);
|
|
@@ -71,7 +71,7 @@ function formatPropsTable(props) {
|
|
|
71
71
|
lines.push('| Prop | Type | Default | Description |');
|
|
72
72
|
lines.push('|------|------|---------|-------------|');
|
|
73
73
|
for (const p of props) {
|
|
74
|
-
const def = p.default ? `\`${mdCell(p.default)}\`` : '
|
|
74
|
+
const def = p.default ? `\`${mdCell(p.default)}\`` : '-';
|
|
75
75
|
const req = p.required ? ' **(required)**' : '';
|
|
76
76
|
lines.push(
|
|
77
77
|
`| \`${mdCell(p.name)}\` | \`${mdCell(p.type)}\` | ${def} | ${mdCell(p.description)}${req} |`,
|
|
@@ -190,11 +190,11 @@ function formatTargetsTable(docs, themeData) {
|
|
|
190
190
|
...themeVariants.map((/** @type {string} */ v) => `${v}*`),
|
|
191
191
|
];
|
|
192
192
|
|
|
193
|
-
const variantsStr = variantParts.length > 0 ? variantParts.join(', ') : '
|
|
194
|
-
const statesStr = states.length > 0 ? states.join(', ') : '
|
|
193
|
+
const variantsStr = variantParts.length > 0 ? variantParts.join(', ') : '-';
|
|
194
|
+
const statesStr = states.length > 0 ? states.join(', ') : '-';
|
|
195
195
|
const dataAttrs = getTargetDataAttributes(target);
|
|
196
196
|
const dataAttrsStr =
|
|
197
|
-
dataAttrs.length > 0 ? dataAttrs.map(attr => `\`${attr}\``).join(', ') : '
|
|
197
|
+
dataAttrs.length > 0 ? dataAttrs.map(attr => `\`${attr}\``).join(', ') : '-';
|
|
198
198
|
|
|
199
199
|
const className = target.deprecatedFor
|
|
200
200
|
? `\`${target.className}\` _(deprecated; use \`${target.deprecatedFor}\`)_`
|
|
@@ -342,7 +342,7 @@ export function formatFull(docs, options = {}) {
|
|
|
342
342
|
const publicVars = docs.theming.vars.filter((/** @type {any} */ v) => !v.private && !v.derived);
|
|
343
343
|
|
|
344
344
|
if (publicVars.length > 0) {
|
|
345
|
-
sections.push('**Themeable CSS variables**
|
|
345
|
+
sections.push('**Themeable CSS variables** - additional properties that can be overridden in `defineTheme` component overrides.\n');
|
|
346
346
|
const varLines = [];
|
|
347
347
|
varLines.push('| CSS Variable | Default | Description |');
|
|
348
348
|
varLines.push('|-------------|---------|-------------|');
|
|
@@ -544,7 +544,7 @@ export function formatBrief(docs, componentName, importHint, options = {}) {
|
|
|
544
544
|
signatureProps.length > 0
|
|
545
545
|
? `${displayName}(${signatureProps.join(', ')})`
|
|
546
546
|
: displayName;
|
|
547
|
-
output.push(importHint ? `${sigStr}
|
|
547
|
+
output.push(importHint ? `${sigStr} <- from '${importHint}'` : sigStr);
|
|
548
548
|
|
|
549
549
|
// Description (shortened)
|
|
550
550
|
if (description) {
|
|
@@ -569,7 +569,7 @@ export function formatBrief(docs, componentName, importHint, options = {}) {
|
|
|
569
569
|
// Derived properties (if any)
|
|
570
570
|
if (docs.theming?.derived?.length) {
|
|
571
571
|
const derivedNames = docs.theming.derived
|
|
572
|
-
.map((/** @type {any} */ d) => d.expand === 'container' ? `${d.property}
|
|
572
|
+
.map((/** @type {any} */ d) => d.expand === 'container' ? `${d.property} -> container tokens` : `${d.property} -> ${(d.vars || []).join(', ')}`)
|
|
573
573
|
.join('; ');
|
|
574
574
|
output.push(` Derived: ${derivedNames}`);
|
|
575
575
|
}
|
|
@@ -579,7 +579,7 @@ export function formatBrief(docs, componentName, importHint, options = {}) {
|
|
|
579
579
|
const { themeData = null } = options;
|
|
580
580
|
const targetParts = docs.theming.targets.map((/** @type {any} */ t) => {
|
|
581
581
|
const parts = [t.className];
|
|
582
|
-
if (t.deprecatedFor) parts.push(`deprecated
|
|
582
|
+
if (t.deprecatedFor) parts.push(`deprecated->${t.deprecatedFor}`);
|
|
583
583
|
const dataAttrs = getTargetDataAttributes(t);
|
|
584
584
|
if (dataAttrs.length) parts.push(`preferred attrs: ${dataAttrs.join(', ')}`);
|
|
585
585
|
if (t.visualProps?.length) parts.push(`variants: ${t.visualProps.join(', ')}`);
|
|
@@ -595,7 +595,7 @@ export function formatBrief(docs, componentName, importHint, options = {}) {
|
|
|
595
595
|
|
|
596
596
|
// Other props
|
|
597
597
|
if (otherProps.length > 0) {
|
|
598
|
-
output.push(` ${otherProps.join('
|
|
598
|
+
output.push(` ${otherProps.join(', ')}`);
|
|
599
599
|
}
|
|
600
600
|
|
|
601
601
|
// First code example
|
|
@@ -157,7 +157,7 @@ describe('deprecated theming target guidance', () => {
|
|
|
157
157
|
|
|
158
158
|
it('keeps the replacement in brief agent guidance', () => {
|
|
159
159
|
expect(formatBrief(docs, 'Example')).toContain(
|
|
160
|
-
'astryx-old-target deprecated
|
|
160
|
+
'astryx-old-target deprecated->new-target',
|
|
161
161
|
);
|
|
162
162
|
});
|
|
163
163
|
});
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import {recordCommandResult} from '../../../foundation/debug/index.mjs';
|
|
28
|
+
import {text} from '../formatters/index.mjs';
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Marks a Commander command that reports what it answered with, and says HOW:
|
|
@@ -78,6 +79,21 @@ export function markReportsResult(cmd) {
|
|
|
78
79
|
return cmd;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
/** The CommandDoc and wrapped FunctionDoc a command was built from. */
|
|
83
|
+
export const COMMAND_DOCS = Symbol.for('astryx.command.docs');
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The docs a command was built from; undefined for a hand-registered command.
|
|
87
|
+
* @param {import('commander').Command} cmd
|
|
88
|
+
* @returns {{
|
|
89
|
+
* doc: import('@astryxdesign/cli/authoring').CommandDoc,
|
|
90
|
+
* fn?: import('@astryxdesign/cli/authoring').FunctionDoc,
|
|
91
|
+
* } | undefined}
|
|
92
|
+
*/
|
|
93
|
+
export function commandDocsOf(cmd) {
|
|
94
|
+
return /** @type {any} */ (cmd)?.[COMMAND_DOCS];
|
|
95
|
+
}
|
|
96
|
+
|
|
81
97
|
/**
|
|
82
98
|
* Build a Commander command from a CommandDoc and attach it to `parent`.
|
|
83
99
|
*
|
|
@@ -102,6 +118,7 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
|
|
|
102
118
|
.join(' ');
|
|
103
119
|
|
|
104
120
|
const cmd = parent.command(argSpec ? `${token} ${argSpec}` : token);
|
|
121
|
+
Object.defineProperty(cmd, COMMAND_DOCS, {value: {doc, fn}, configurable: true});
|
|
105
122
|
if (doc.summary) cmd.description(doc.summary);
|
|
106
123
|
|
|
107
124
|
const paramDesc = (/** @type {string | undefined} */ name) =>
|
|
@@ -126,12 +143,10 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
|
|
|
126
143
|
cmd.addOption(option);
|
|
127
144
|
}
|
|
128
145
|
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
// help carries no per-command examples epilog. Keeping both out preserves the
|
|
134
|
-
// exact `--help`/manifest surface as registrations migrate to this converter.
|
|
146
|
+
// Help ends with the documented exit codes. `choices` stay in the option
|
|
147
|
+
// text: Commander `.choices()` would replace the api layer's
|
|
148
|
+
// ERR_INVALID_ARGUMENT validation.
|
|
149
|
+
addExitCodesHelp(cmd, doc.exitCodes);
|
|
135
150
|
|
|
136
151
|
if (action) {
|
|
137
152
|
// The recording seam. An action's job ends at "here is what I answered
|
|
@@ -149,3 +164,14 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
|
|
|
149
164
|
}
|
|
150
165
|
return cmd;
|
|
151
166
|
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* End `cmd`'s help with a CommandDoc's exit codes.
|
|
170
|
+
* @param {import('commander').Command} cmd
|
|
171
|
+
* @param {import('@astryxdesign/cli/authoring').CommandDoc['exitCodes']} exitCodes
|
|
172
|
+
*/
|
|
173
|
+
export function addExitCodesHelp(cmd, exitCodes) {
|
|
174
|
+
if (!exitCodes?.length) return;
|
|
175
|
+
const lines = exitCodes.map(({code, when}) => ` ${code} ${when}`);
|
|
176
|
+
cmd.addHelpText('after', `\n${text(['Exit codes:', ...lines].join('\n')).toString()}`);
|
|
177
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file The component and hook text renderers add no non-ASCII characters of
|
|
5
|
+
* their own: given ASCII-only docs, every view they produce is plain ASCII.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {describe, it, expect} from 'vitest';
|
|
9
|
+
import {
|
|
10
|
+
formatBrief,
|
|
11
|
+
formatCompact,
|
|
12
|
+
formatFull,
|
|
13
|
+
formatProps,
|
|
14
|
+
} from './component-format.mjs';
|
|
15
|
+
import {
|
|
16
|
+
formatHookBrief,
|
|
17
|
+
formatHookCompact,
|
|
18
|
+
formatHookFull,
|
|
19
|
+
formatHookParams,
|
|
20
|
+
} from './hook-format.mjs';
|
|
21
|
+
|
|
22
|
+
const NON_ASCII = /[\u0080-\uffff]/g;
|
|
23
|
+
|
|
24
|
+
/** @param {string} out @returns {string[]} */
|
|
25
|
+
const nonAscii = out => out.match(NON_ASCII) ?? [];
|
|
26
|
+
|
|
27
|
+
// Every optional field left empty and every optional path taken, so each
|
|
28
|
+
// placeholder, separator, and arrow the renderers emit shows up at least once.
|
|
29
|
+
const componentDoc = {
|
|
30
|
+
name: 'Widget',
|
|
31
|
+
description: 'A widget for tests.',
|
|
32
|
+
props: [
|
|
33
|
+
{name: 'variant', type: "'solid' | 'ghost'", description: 'Look.'},
|
|
34
|
+
{name: 'label', type: 'string', description: 'Label.', required: true},
|
|
35
|
+
{name: 'disabled', type: 'boolean', description: 'Disables it.'},
|
|
36
|
+
{name: 'tone', type: 'string', description: 'Tone.'},
|
|
37
|
+
],
|
|
38
|
+
theming: {
|
|
39
|
+
vars: [{name: '--widget-gap', default: '8px', description: 'Gap.'}],
|
|
40
|
+
derived: [
|
|
41
|
+
{property: 'padding', expand: 'container'},
|
|
42
|
+
{property: 'radius', vars: ['--widget-radius']},
|
|
43
|
+
],
|
|
44
|
+
targets: [
|
|
45
|
+
{className: 'astryx-widget', deprecatedFor: 'astryx-widget-v2'},
|
|
46
|
+
{className: 'astryx-widget-v2', visualProps: ['variant']},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const hookDoc = {
|
|
52
|
+
name: 'useWidget',
|
|
53
|
+
importPath: '@astryxdesign/core/useWidget',
|
|
54
|
+
usage: {description: 'Widget behavior.'},
|
|
55
|
+
params: [
|
|
56
|
+
{name: 'options', type: 'object', description: 'Options.', required: true},
|
|
57
|
+
{name: 'delay', type: 'number', description: 'Delay.'},
|
|
58
|
+
],
|
|
59
|
+
returns: [{name: 'open', type: 'boolean', description: 'Open state.'}],
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
describe('component text output is ASCII', () => {
|
|
63
|
+
it.each([
|
|
64
|
+
['formatFull', () => formatFull(componentDoc)],
|
|
65
|
+
['formatCompact', () => formatCompact(componentDoc, 'Widget')],
|
|
66
|
+
['formatBrief', () => formatBrief(componentDoc, 'Widget', '@astryxdesign/core/Widget')],
|
|
67
|
+
['formatProps', () => formatProps(componentDoc, 'Widget')],
|
|
68
|
+
])('%s', (_name, render) => {
|
|
69
|
+
expect(nonAscii(render())).toEqual([]);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('hook text output is ASCII', () => {
|
|
74
|
+
it.each([
|
|
75
|
+
['formatHookFull', () => formatHookFull(hookDoc)],
|
|
76
|
+
['formatHookCompact', () => formatHookCompact(hookDoc, hookDoc.importPath)],
|
|
77
|
+
['formatHookBrief', () => formatHookBrief(hookDoc)],
|
|
78
|
+
['formatHookParams', () => formatHookParams(hookDoc)],
|
|
79
|
+
])('%s', (_name, render) => {
|
|
80
|
+
expect(nonAscii(render())).toEqual([]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Every CommandDoc's exit codes reach generated help and the manifest.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import {fileURLToPath, pathToFileURL} from 'node:url';
|
|
11
|
+
import {describe, it, expect} from 'vitest';
|
|
12
|
+
import {program, JSON_SUPPORTED} from '../index.mjs';
|
|
13
|
+
import {buildManifest} from './manifest.mjs';
|
|
14
|
+
import {runCli} from '../../../test-utils/run-cli.mjs';
|
|
15
|
+
|
|
16
|
+
const COMMANDS = path.join(path.dirname(fileURLToPath(import.meta.url)), '../commands');
|
|
17
|
+
|
|
18
|
+
/** @type {any[]} */
|
|
19
|
+
const commandDocs = [];
|
|
20
|
+
for (const file of fs.readdirSync(COMMANDS).sort()) {
|
|
21
|
+
if (!file.endsWith('.doc.mjs')) continue;
|
|
22
|
+
const {doc} = await import(pathToFileURL(path.join(COMMANDS, file)).href);
|
|
23
|
+
if (doc?.type === 'command') commandDocs.push(doc);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const manifest = buildManifest(program, {jsonSupported: JSON_SUPPORTED, version: '0.0.0-test'});
|
|
27
|
+
/** @type {Map<string, any>} */
|
|
28
|
+
const entries = new Map();
|
|
29
|
+
const walk = (/** @type {any} */ c) => {
|
|
30
|
+
entries.set(c.name, c);
|
|
31
|
+
(c.subcommands || []).forEach(walk);
|
|
32
|
+
};
|
|
33
|
+
manifest.commands.forEach(walk);
|
|
34
|
+
|
|
35
|
+
describe('command exit codes', () => {
|
|
36
|
+
it('every CommandDoc documents its exit codes', () => {
|
|
37
|
+
expect(commandDocs.length).toBeGreaterThan(30);
|
|
38
|
+
for (const doc of commandDocs) {
|
|
39
|
+
expect(doc.exitCodes?.length, doc.name).toBeGreaterThan(0);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it.each(commandDocs.map((d) => [d.name, d]))(
|
|
44
|
+
'`astryx %s --help` lists the documented exit codes',
|
|
45
|
+
async (name, doc) => {
|
|
46
|
+
const {status, stdout} = await runCli([...name.split(' '), '--help']);
|
|
47
|
+
expect(status).toBe(0);
|
|
48
|
+
const section = stdout.slice(stdout.indexOf('\nExit codes:\n'));
|
|
49
|
+
expect(section.startsWith('\nExit codes:\n'), stdout).toBe(true);
|
|
50
|
+
expect(stdout.match(/\nExit codes?:\n/g), 'one exit-code section').toHaveLength(1);
|
|
51
|
+
for (const {code, when} of doc.exitCodes) {
|
|
52
|
+
expect(section).toContain(`\n ${code} ${when}\n`);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
it('bare `astryx layout` exits 1 in both modes, as documented', async () => {
|
|
58
|
+
const doc = commandDocs.find((d) => d.name === 'layout');
|
|
59
|
+
expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/^no subcommand/);
|
|
60
|
+
expect((await runCli(['layout'])).status).toBe(1);
|
|
61
|
+
expect((await runCli(['layout', '--json'])).status).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('`astryx discover` with a blank query exits 1 only when packages are discovered', async () => {
|
|
65
|
+
const doc = commandDocs.find((d) => d.name === 'discover');
|
|
66
|
+
expect(doc.exitCodes.find((e) => e.code === 1)?.when).toMatch(/blank query when packages are discovered/);
|
|
67
|
+
const project = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-exit-discover-'));
|
|
68
|
+
try {
|
|
69
|
+
expect((await runCli(['discover', ' ', '--json'], {cwd: project})).status).toBe(0);
|
|
70
|
+
const pkg = path.join(project, 'node_modules/@acme/ui');
|
|
71
|
+
fs.mkdirSync(path.join(pkg, 'components'), {recursive: true});
|
|
72
|
+
fs.writeFileSync(path.join(pkg, 'package.json'), '{"name":"@acme/ui","version":"1.0.0","type":"module"}');
|
|
73
|
+
fs.writeFileSync(path.join(pkg, 'astryx.integration.mjs'), "export default {components: './components'};\n");
|
|
74
|
+
fs.writeFileSync(
|
|
75
|
+
path.join(pkg, 'components/Widget.doc.mjs'),
|
|
76
|
+
'export const doc = {type: "component", name: "Widget", description: "A widget"};\n',
|
|
77
|
+
);
|
|
78
|
+
fs.writeFileSync(path.join(pkg, 'components/Widget.tsx'), 'export function Widget() { return null; }\n');
|
|
79
|
+
fs.writeFileSync(path.join(project, 'package.json'), '{"name":"app","type":"module"}');
|
|
80
|
+
fs.writeFileSync(path.join(project, 'astryx.config.mjs'), "export default {integrations: ['@acme/ui']};\n");
|
|
81
|
+
expect((await runCli(['discover', '--json'], {cwd: project})).status).toBe(0);
|
|
82
|
+
const blank = await runCli(['discover', ' ', '--json'], {cwd: project});
|
|
83
|
+
expect(blank.status).toBe(1);
|
|
84
|
+
expect(JSON.parse(blank.stdout).code).toBe('ERR_INVALID_ARGUMENT');
|
|
85
|
+
} finally {
|
|
86
|
+
fs.rmSync(project, {recursive: true, force: true});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('the manifest carries every command exit code', () => {
|
|
91
|
+
for (const doc of commandDocs) {
|
|
92
|
+
expect(entries.get(doc.name)?.exitCodes, doc.name).toEqual(
|
|
93
|
+
doc.exitCodes.map(({code, when}) => ({code, when})),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
* - Brief: signature line with import hint, description, key params
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
discoverHooks,
|
|
14
|
+
findHookDoc,
|
|
15
|
+
} from '../../../foundation/discovery/hook-discovery.mjs';
|
|
13
16
|
import {loadDocs} from '../../../foundation/discovery/component-loader.mjs';
|
|
14
17
|
import {formatAccessibility, mdCell} from './component-format.mjs';
|
|
15
18
|
|
|
@@ -23,7 +26,9 @@ function buildSignature(docs) {
|
|
|
23
26
|
const name = docs.name;
|
|
24
27
|
|
|
25
28
|
// Build params string — only top-level params (skip options.foo nested params)
|
|
26
|
-
const topParams = (docs.params || []).filter(
|
|
29
|
+
const topParams = (docs.params || []).filter(
|
|
30
|
+
(/** @type {any} */ p) => !p.name.includes('.'),
|
|
31
|
+
);
|
|
27
32
|
const paramStr = topParams
|
|
28
33
|
.map((/** @type {any} */ p) => {
|
|
29
34
|
const opt = p.required ? '' : '?';
|
|
@@ -57,7 +62,7 @@ function formatParamsTable(params) {
|
|
|
57
62
|
lines.push('| Param | Type | Default | Description |');
|
|
58
63
|
lines.push('|-------|------|---------|-------------|');
|
|
59
64
|
for (const p of params) {
|
|
60
|
-
const def = p.default ? `\`${mdCell(p.default)}\`` : '
|
|
65
|
+
const def = p.default ? `\`${mdCell(p.default)}\`` : '-';
|
|
61
66
|
const req = p.required ? ' **(required)**' : '';
|
|
62
67
|
lines.push(
|
|
63
68
|
`| \`${mdCell(p.name)}\` | \`${mdCell(p.type)}\` | ${def} | ${mdCell(p.description)}${req} |`,
|
|
@@ -150,7 +155,9 @@ export function formatHookCompact(docs, importPath) {
|
|
|
150
155
|
const imp = importPath || docs.importPath;
|
|
151
156
|
if (imp) {
|
|
152
157
|
sections.push('## Import\n');
|
|
153
|
-
sections.push(
|
|
158
|
+
sections.push(
|
|
159
|
+
`\`\`\`tsx\nimport { ${docs.name} } from '${imp}';\n\`\`\`\n`,
|
|
160
|
+
);
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
// Best Practices (matches component compact)
|
|
@@ -198,7 +205,7 @@ export function formatHookCompact(docs, importPath) {
|
|
|
198
205
|
/**
|
|
199
206
|
* Format a brief, LLM-optimized hook summary.
|
|
200
207
|
* Matches component formatBrief conventions:
|
|
201
|
-
* signature
|
|
208
|
+
* signature <- from 'import/path'
|
|
202
209
|
* description
|
|
203
210
|
* key params
|
|
204
211
|
* @param {any} docs
|
|
@@ -211,7 +218,7 @@ export function formatHookBrief(docs) {
|
|
|
211
218
|
// Signature line with import hint (matches component brief)
|
|
212
219
|
const sig = buildSignature(docs);
|
|
213
220
|
const imp = docs.importPath;
|
|
214
|
-
output.push(imp ? `${sig}
|
|
221
|
+
output.push(imp ? `${sig} <- from '${imp}'` : sig);
|
|
215
222
|
|
|
216
223
|
// Description (shortened, matches component brief)
|
|
217
224
|
const desc = docs.usage?.description || '';
|
|
@@ -225,12 +232,14 @@ export function formatHookBrief(docs) {
|
|
|
225
232
|
output.push(` Related: ${docs.relatedComponents.join(', ')}`);
|
|
226
233
|
}
|
|
227
234
|
|
|
228
|
-
// Key params (matches component brief 'prop
|
|
235
|
+
// Key params (matches component brief 'prop, prop' line)
|
|
229
236
|
const paramNames = (docs.params || [])
|
|
230
237
|
.filter((/** @type {any} */ p) => !p.name.includes('.'))
|
|
231
|
-
.map((/** @type {any} */ p) =>
|
|
238
|
+
.map((/** @type {any} */ p) =>
|
|
239
|
+
p.required ? `${p.name}: ${p.type.split('|')[0].trim()}` : p.name,
|
|
240
|
+
);
|
|
232
241
|
if (paramNames.length > 0) {
|
|
233
|
-
output.push(` ${paramNames.join('
|
|
242
|
+
output.push(` ${paramNames.join(', ')}`);
|
|
234
243
|
}
|
|
235
244
|
|
|
236
245
|
return output.join('\n') + '\n';
|
|
@@ -253,7 +262,7 @@ export async function formatHookBriefAll(coreDir) {
|
|
|
253
262
|
const docPath = findHookDoc(coreDir, hookName);
|
|
254
263
|
if (docPath) {
|
|
255
264
|
try {
|
|
256
|
-
const docs = await loadDocs(docPath);
|
|
265
|
+
const docs = await loadDocs(docPath, {root: 'hooks'});
|
|
257
266
|
output.push(formatHookBrief(docs));
|
|
258
267
|
} catch {
|
|
259
268
|
output.push(`${hookName}\n (no docs)\n`);
|
|
@@ -29,6 +29,9 @@
|
|
|
29
29
|
* 4. Routing unknown-subcommand attempts through the same error
|
|
30
30
|
* envelope path (so `astryx bogus-cmd --json` gets exit 1 + envelope
|
|
31
31
|
* instead of exit 0 + help envelope).
|
|
32
|
+
* 5. Emitting an error envelope, not the help envelope, when Commander
|
|
33
|
+
* shows help because the invocation failed (`help <unknown>`, or a
|
|
34
|
+
* command group with no subcommand), which exits 1.
|
|
32
35
|
*
|
|
33
36
|
* Non-JSON behavior is preserved exactly: every code path that printed
|
|
34
37
|
* to stderr before still prints to stderr. Commander writes its
|
|
@@ -117,6 +120,35 @@ export function buildHelpEnvelope(cmd) {
|
|
|
117
120
|
};
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
/**
|
|
124
|
+
* The error envelope for help Commander shows because the invocation failed
|
|
125
|
+
* (it then exits 1): `help <name>` for an unknown name on the root, or a
|
|
126
|
+
* command group run without a subcommand.
|
|
127
|
+
*
|
|
128
|
+
* @param {import('commander').Command} cmd the command whose help was shown
|
|
129
|
+
* @returns {ReturnType<typeof toErrorEnvelope>}
|
|
130
|
+
*/
|
|
131
|
+
export function buildHelpErrorEnvelope(cmd) {
|
|
132
|
+
const available = cmd.commands
|
|
133
|
+
.filter(s => !(/** @type {any} */ (s))._hidden && s.name() !== 'help')
|
|
134
|
+
.map(s => s.name());
|
|
135
|
+
if (!cmd.parent) {
|
|
136
|
+
// Commander dispatches `help <name>` with ['help', <name>, ...] in args.
|
|
137
|
+
const requested = cmd.args[1];
|
|
138
|
+
return toErrorEnvelope(
|
|
139
|
+
requested ? `unknown command '${requested}'` : 'unknown command',
|
|
140
|
+
available.map(name => ({name, reason: 'available command'})),
|
|
141
|
+
ERROR_CODES.ERR_UNKNOWN_COMMAND,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const group = fullNameOf(cmd);
|
|
145
|
+
return toErrorEnvelope(
|
|
146
|
+
`'${group}' needs a subcommand`,
|
|
147
|
+
available.map(name => ({name: `${group} ${name}`, reason: 'available subcommand'})),
|
|
148
|
+
ERROR_CODES.ERR_MISSING_ARGUMENT,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
120
152
|
/**
|
|
121
153
|
* Emit a JSON error envelope to stdout (the JSON contract uses stdout
|
|
122
154
|
* for both success and error).
|
|
@@ -310,7 +342,9 @@ function patchOutputHelp(cmd) {
|
|
|
310
342
|
if (jsonActive()) {
|
|
311
343
|
if (!process.__xdsJsonHandled) {
|
|
312
344
|
process.__xdsJsonHandled = true;
|
|
313
|
-
const env =
|
|
345
|
+
const env = contextOptions?.error
|
|
346
|
+
? buildHelpErrorEnvelope(cmd)
|
|
347
|
+
: buildHelpEnvelope(cmd);
|
|
314
348
|
process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
|
|
315
349
|
}
|
|
316
350
|
return;
|
|
@@ -334,7 +368,9 @@ function patchPrototype(CommandCtor) {
|
|
|
334
368
|
if (jsonActive()) {
|
|
335
369
|
if (!process.__xdsJsonHandled) {
|
|
336
370
|
process.__xdsJsonHandled = true;
|
|
337
|
-
const env =
|
|
371
|
+
const env = contextOptions?.error
|
|
372
|
+
? buildHelpErrorEnvelope(this)
|
|
373
|
+
: buildHelpEnvelope(this);
|
|
338
374
|
process.stdout.write(`${JSON.stringify(env, null, 2)}\n`);
|
|
339
375
|
}
|
|
340
376
|
return;
|