@astryxdesign/cli 0.6.3-canary.db4e378 → 0.6.3-canary.db52d98
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 +38 -15
- 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 +14 -7
- package/api/build/build.test.mjs +184 -6
- package/api/build/build.type.d.mts +57 -2
- package/api/build/build.type.mjs +30 -7
- package/api/build/help/help.d.mts +4 -0
- package/api/build/help/help.mjs +24 -11
- 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 +1 -0
- package/api/component/component.mjs +60 -12
- package/api/component/list/list.mjs +3 -2
- package/api/discover/discover.doc.mjs +1 -0
- package/api/docs/_adapter.d.mts +252 -34
- package/api/docs/_adapter.mjs +923 -132
- package/api/docs/detail/detail.mjs +11 -3
- package/api/docs/detail/section/section.mjs +24 -13
- package/api/docs/detail/section/section.test.mjs +15 -6
- package/api/docs/docs.d.mts +5 -3
- package/api/docs/docs.doc.mjs +39 -17
- package/api/docs/docs.mjs +44 -8
- package/api/docs/docs.test.mjs +158 -4
- package/api/docs/docs.type.d.mts +181 -2
- package/api/docs/docs.type.mjs +117 -3
- package/api/docs/index/index.mjs +11 -3
- package/api/docs/index/index.test.mjs +1 -1
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +14 -14
- 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 +54 -4
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +331 -16
- package/api/doctor/doctor.test.mjs +420 -7
- package/api/gap-report/gap-report.doc.mjs +1 -0
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/list/list.d.mts +1 -1
- 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 +2 -1
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +114 -12
- package/api/integration/add-contribution.test.mjs +174 -3
- 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 +2 -0
- 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 +7 -0
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +1 -0
- 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 +34 -0
- package/api/integration/pack-check.test.mjs +138 -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 +50 -102
- package/api/integration/validate-integration.test.mjs +88 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +2 -1
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +1 -0
- package/api/layout/_adapter.mjs +20 -5
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +1 -0
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search.d.mts +59 -1
- package/api/search/search.doc.mjs +5 -3
- package/api/search/search.mjs +458 -77
- package/api/search/search.test.mjs +91 -2
- package/api/search/search.type.d.mts +13 -1
- package/api/search/search.type.mjs +4 -1
- package/api/swizzle/swizzle.doc.mjs +1 -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.doc.mjs +28 -7
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +6 -8
- package/api/template/template.type.mjs +3 -2
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +10 -17
- package/api/theme/add/add.test.mjs +14 -1
- 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/template/template.test.mjs +5 -0
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +1 -0
- 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 +2 -1
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +97 -69
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/upgrade.doc.mjs +6 -1
- package/api/upgrade/upgrade.type.d.mts +34 -0
- package/api/upgrade/upgrade.type.mjs +15 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +8 -2
- package/assets/codemods/integration-discovery.test.mjs +15 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/next/index.mjs +19 -1
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/docs/getting-started.doc.mjs +2 -2
- 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 +3 -3
- 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} +66 -38
- 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 +3 -3
- 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/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -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/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/codemod/codemod.doc.mjs +1 -1
- package/authoring/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +1 -1
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +3 -3
- package/authoring/doctypes/_schema.d.mts +119 -117
- package/authoring/doctypes/_schema.mjs +54 -3
- package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
- package/authoring/doctypes/base/type.ts +6 -5
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +2 -2
- package/authoring/doctypes/component/type.ts +2 -2
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +1 -1
- package/authoring/doctypes/function/function.doc.mjs +3 -2
- package/authoring/doctypes/function/type.ts +3 -2
- package/authoring/doctypes/hook/type.ts +2 -2
- package/authoring/doctypes/load-contract.test.mjs +28 -2
- package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
- package/authoring/doctypes/namespace/parse.test.mjs +23 -25
- package/authoring/doctypes/namespace/type.ts +5 -2
- package/authoring/doctypes/parse.d.mts +4 -2
- package/authoring/doctypes/parse.mjs +10 -5
- package/authoring/doctypes/reference/reference.doc.mjs +35 -6
- package/authoring/doctypes/reference/type.ts +30 -13
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +1 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +4 -0
- package/authoring/doctypes/template/parse.test.mjs +18 -0
- package/authoring/doctypes/template/template.doc.mjs +9 -3
- package/authoring/doctypes/template/type.ts +8 -0
- 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 +2 -1
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/identity/identity.doc.mjs +2 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +7 -4
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.mjs +11 -45
- package/clients/cli/commands/build.doc.mjs +12 -7
- package/clients/cli/commands/build.mjs +105 -67
- package/clients/cli/commands/build.text-fields.test.mjs +41 -0
- package/clients/cli/commands/component/index.mjs +1 -1
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/discover.broken-integration.test.mjs +7 -8
- package/clients/cli/commands/discover.doc.mjs +1 -1
- package/clients/cli/commands/discover.mjs +1 -1
- package/clients/cli/commands/docs.doc.mjs +21 -9
- package/clients/cli/commands/docs.mjs +184 -70
- package/clients/cli/commands/docs.test.mjs +120 -16
- 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.test.mjs +90 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +53 -16
- package/clients/cli/commands/gap-report.doc.mjs +1 -1
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/init.doc.mjs +1 -1
- package/clients/cli/commands/integration-add.controls.test.mjs +1 -1
- package/clients/cli/commands/integration-add.doc.mjs +11 -1
- 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/layout-check.doc.mjs +1 -1
- package/clients/cli/commands/layout-expand.doc.mjs +1 -1
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +1 -1
- package/clients/cli/commands/search.mjs +11 -2
- package/clients/cli/commands/setup-nudge.test.mjs +6 -0
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +24 -7
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/text-json-parity.test.mjs +719 -0
- package/clients/cli/commands/theme-add.doc.mjs +2 -2
- package/clients/cli/commands/theme-build.doc.mjs +1 -1
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- 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.doc.mjs +1 -1
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +3 -2
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +2 -0
- package/clients/cli/formatters/index.test.mjs +6 -0
- package/clients/cli/index.mjs +8 -0
- package/clients/cli/lib/hook-format.mjs +14 -5
- package/clients/cli/lib/manifest.mjs +9 -2
- package/foundation/agent-docs/agent-docs.d.mts +3 -2
- package/foundation/agent-docs/agent-docs.mjs +13 -9
- package/foundation/agent-docs/agent-docs.test.mjs +19 -1
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +123 -80
- package/foundation/config/project.test.mjs +144 -21
- package/foundation/discovery/authoring-self-docs.d.mts +18 -0
- package/foundation/discovery/authoring-self-docs.mjs +37 -15
- package/foundation/discovery/authoring-self-docs.test.mjs +25 -9
- 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 +38 -0
- package/foundation/discovery/component-discovery.mjs +48 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +112 -11
- package/foundation/discovery/docs-discovery.mjs +231 -36
- package/foundation/discovery/docs-discovery.test.mjs +111 -32
- package/foundation/discovery/docs-output-budget.d.mts +2 -2
- package/foundation/discovery/docs-output-budget.mjs +1 -1
- package/foundation/discovery/docs-section-key.d.mts +28 -10
- package/foundation/discovery/docs-section-key.mjs +134 -33
- package/foundation/discovery/docs-section-key.test.mjs +41 -19
- package/foundation/discovery/template-adapter.d.mts +99 -6
- package/foundation/discovery/template-adapter.mjs +480 -57
- 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/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 +220 -39
- package/foundation/doc-compiler/compile.mjs +311 -15
- 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 +28 -1
- 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 +13 -0
- package/foundation/doc-compiler/ir.mjs +196 -12
- package/foundation/doc-compiler/lenses.d.mts +8 -5
- package/foundation/doc-compiler/lenses.mjs +50 -4
- 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/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -57
- 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 +51 -26
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- 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.mjs +121 -29
- 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 +12 -2
- package/foundation/response/error-codes.mjs +7 -1
- package/foundation/response/error-codes.test.mjs +55 -11
- package/foundation/response/response-types.doc.d.mts +5 -1
- package/foundation/response/response-types.doc.mjs +20 -11
- 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.mjs +1 -1
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -9
- package/assets/templates/themes/manifest.json +0 -95
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export type BuildPlaybookCommand = {
|
|
8
8
|
/**
|
|
9
|
-
* Bare subcommand with `<placeholder>` arguments (e.g. `template <name>
|
|
9
|
+
* Bare subcommand with `<placeholder>` arguments (e.g. `template <name> <path>`) and no package-manager prefix — render it with your own CLI invocation.
|
|
10
10
|
*/
|
|
11
11
|
command: string;
|
|
12
12
|
/**
|
|
@@ -45,7 +45,61 @@ export type BuildHelpResponse = {
|
|
|
45
45
|
};
|
|
46
46
|
};
|
|
47
47
|
/**
|
|
48
|
-
*
|
|
48
|
+
* The page template a kit recommends starting from.
|
|
49
|
+
*/
|
|
50
|
+
export type BuildStart = {
|
|
51
|
+
/**
|
|
52
|
+
* Template id, as `astryx template <name>` takes it.
|
|
53
|
+
*/
|
|
54
|
+
name: string;
|
|
55
|
+
/**
|
|
56
|
+
* Human-facing template name.
|
|
57
|
+
*/
|
|
58
|
+
displayName: string;
|
|
59
|
+
/**
|
|
60
|
+
* What the page is: its layout and the ideas it serves.
|
|
61
|
+
*/
|
|
62
|
+
description: string;
|
|
63
|
+
/**
|
|
64
|
+
* The scaffold command that selects exactly this template, `astryx template <id> --type page <path>`: `<id>` is the Core id an integration replacement stands in for, else the template's own id, `<path>` is a placeholder for the file or folder to write the template to, and the `astryx` prefix is for the caller to replace with its own invocation.
|
|
65
|
+
*/
|
|
66
|
+
command: string;
|
|
67
|
+
/**
|
|
68
|
+
* Why this template. The page ranker picks every start: it weighs each matched word by how rare it is among page templates, favors the family the idea's head names and the container it names ("in a modal"), and discounts words that only modify another. `direct` when its pick is also search's direct match (`directMatch`); `closest` when it is not; `fallback` when no template has the evidence to lead and the page starts from the app shell.
|
|
69
|
+
*/
|
|
70
|
+
basis: "direct" | "closest" | "fallback";
|
|
71
|
+
/**
|
|
72
|
+
* One sentence saying the same as `basis`, for a reader.
|
|
73
|
+
*/
|
|
74
|
+
reason: string;
|
|
75
|
+
/**
|
|
76
|
+
* The ranker's next closest page templates (≤2), for when the start's layout is wrong.
|
|
77
|
+
*/
|
|
78
|
+
alternatives: BuildAlternative[];
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* A page template to consider instead of the start.
|
|
82
|
+
*/
|
|
83
|
+
export type BuildAlternative = {
|
|
84
|
+
/**
|
|
85
|
+
* Template id, as `astryx template <name>` takes it.
|
|
86
|
+
*/
|
|
87
|
+
name: string;
|
|
88
|
+
/**
|
|
89
|
+
* Human-facing template name.
|
|
90
|
+
*/
|
|
91
|
+
displayName: string;
|
|
92
|
+
/**
|
|
93
|
+
* What the page is: its layout and the ideas it serves.
|
|
94
|
+
*/
|
|
95
|
+
description: string;
|
|
96
|
+
/**
|
|
97
|
+
* The scaffold command, in the same form as the start's.
|
|
98
|
+
*/
|
|
99
|
+
command: string;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* astryx --json build "<idea>" — the page template to start from, and the kit around it.
|
|
49
103
|
*
|
|
50
104
|
* Entries are raw `SearchResultEntry` objects (no package-manager-prefixed
|
|
51
105
|
* command strings — the CLI adds those); `frame`/`foundation` are static
|
|
@@ -58,6 +112,7 @@ export type BuildKitResponse = {
|
|
|
58
112
|
hasResults: boolean;
|
|
59
113
|
matchCount: number;
|
|
60
114
|
directMatch: boolean;
|
|
115
|
+
start: BuildStart | null;
|
|
61
116
|
pages: import("../search/search.type.mjs").SearchResultEntry[];
|
|
62
117
|
blocks: import("../search/search.type.mjs").SearchResultEntry[];
|
|
63
118
|
domain: import("../search/search.type.mjs").SearchResultEntry[];
|
package/api/build/build.type.mjs
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file Colocated types for the `build` command — source of truth for the
|
|
5
5
|
* `build.help` (playbook) and `build.kit` (composition kit) JSON responses.
|
|
6
|
-
* Re-exported by types/build.d.ts.
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* A command the playbook tells the caller to run.
|
|
11
10
|
*
|
|
12
11
|
* @typedef {object} BuildPlaybookCommand
|
|
13
|
-
* @property {string} command Bare subcommand with `<placeholder>` arguments (e.g. `template <name>
|
|
12
|
+
* @property {string} command Bare subcommand with `<placeholder>` arguments (e.g. `template <name> <path>`) and no package-manager prefix — render it with your own CLI invocation.
|
|
14
13
|
* @property {string} [purpose] What running it is for.
|
|
15
14
|
*/
|
|
16
15
|
|
|
@@ -37,7 +36,30 @@
|
|
|
37
36
|
*/
|
|
38
37
|
|
|
39
38
|
/**
|
|
40
|
-
*
|
|
39
|
+
* The page template a kit recommends starting from.
|
|
40
|
+
*
|
|
41
|
+
* @typedef {object} BuildStart
|
|
42
|
+
* @property {string} name Template id, as `astryx template <name>` takes it.
|
|
43
|
+
* @property {string} displayName Human-facing template name.
|
|
44
|
+
* @property {string} description What the page is: its layout and the ideas it serves.
|
|
45
|
+
* @property {string} command The scaffold command that selects exactly this template, `astryx template <id> --type page <path>`: `<id>` is the Core id an integration replacement stands in for, else the template's own id, `<path>` is a placeholder for the file or folder to write the template to, and the `astryx` prefix is for the caller to replace with its own invocation.
|
|
46
|
+
* @property {'direct' | 'closest' | 'fallback'} basis Why this template. The page ranker picks every start: it weighs each matched word by how rare it is among page templates, favors the family the idea's head names and the container it names ("in a modal"), and discounts words that only modify another. `direct` when its pick is also search's direct match (`directMatch`); `closest` when it is not; `fallback` when no template has the evidence to lead and the page starts from the app shell.
|
|
47
|
+
* @property {string} reason One sentence saying the same as `basis`, for a reader.
|
|
48
|
+
* @property {BuildAlternative[]} alternatives The ranker's next closest page templates (≤2), for when the start's layout is wrong.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* A page template to consider instead of the start.
|
|
53
|
+
*
|
|
54
|
+
* @typedef {object} BuildAlternative
|
|
55
|
+
* @property {string} name Template id, as `astryx template <name>` takes it.
|
|
56
|
+
* @property {string} displayName Human-facing template name.
|
|
57
|
+
* @property {string} description What the page is: its layout and the ideas it serves.
|
|
58
|
+
* @property {string} command The scaffold command, in the same form as the start's.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* astryx --json build "<idea>" — the page template to start from, and the kit around it.
|
|
41
63
|
*
|
|
42
64
|
* Entries are raw `SearchResultEntry` objects (no package-manager-prefixed
|
|
43
65
|
* command strings — the CLI adds those); `frame`/`foundation` are static
|
|
@@ -47,14 +69,15 @@
|
|
|
47
69
|
* @property {'build.kit'} type
|
|
48
70
|
* @property {object} data
|
|
49
71
|
* @property {string} data.query
|
|
50
|
-
* @property {boolean} data.hasResults False when search returned nothing
|
|
72
|
+
* @property {boolean} data.hasResults False when search returned nothing. The kit still names a template in `start`.
|
|
51
73
|
* @property {number} data.matchCount Total ranked search matches for the query — counted before the search `limit`, the kit's score floors, and its per-group caps, so it is never a cap read back.
|
|
52
74
|
* @property {boolean} data.directMatch True when the top page template is a confident direct match.
|
|
53
|
-
* @property {
|
|
75
|
+
* @property {BuildStart | null} data.start The page template to start from: the ranker's pick, else the app shell. Null only when the kit is narrowed to components or hooks (`type`), or when the project has no page template to offer.
|
|
76
|
+
* @property {import('../search/search.type.mjs').SearchResultEntry[]} data.pages Closest page templates by search (≤3). Each entry's `command` carries `--skeleton` when `directMatch` is false, so it previews the layout; `start.command` is the scaffold.
|
|
54
77
|
* @property {import('../search/search.type.mjs').SearchResultEntry[]} data.blocks Drop-in block patterns covering parts of the idea (≤5).
|
|
55
78
|
* @property {import('../search/search.type.mjs').SearchResultEntry[]} data.domain Idea-specific components/hooks (≤6), excluding frame/foundation.
|
|
56
|
-
* @property {string[]} data.frame Always-on page-shell component names.
|
|
57
|
-
* @property {string[]} data.foundation Always-on layout/typography/action component names.
|
|
79
|
+
* @property {string[]} data.frame Always-on page-shell component names. Every page template already uses them.
|
|
80
|
+
* @property {string[]} data.foundation Always-on layout/typography/action component names. Every page template already uses them.
|
|
58
81
|
* @property {{reason: string, commands: string[]}} [data.hint] Present only when the kit is thin. `reason` says why, `commands` are bare subcommands (e.g. `component --list`) for the caller to render with its own invocation — so a reader is never handed a command that does not resolve in their project.
|
|
59
82
|
*/
|
|
60
83
|
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
* package-manager prefix, which keeps the JSON environment-agnostic; the CLI
|
|
11
11
|
* renders each one with the caller's invocation, as it does build.kit's
|
|
12
12
|
* `hint.commands`.
|
|
13
|
+
*
|
|
14
|
+
* The workflow starts every page from a template, because a template already
|
|
15
|
+
* has the frame, spacing, and section rhythm that a page composed from
|
|
16
|
+
* components has to rediscover.
|
|
13
17
|
*/
|
|
14
18
|
/**
|
|
15
19
|
* The page-building playbook (emitted when `build` runs with no query).
|
package/api/build/help/help.mjs
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
* package-manager prefix, which keeps the JSON environment-agnostic; the CLI
|
|
10
10
|
* renders each one with the caller's invocation, as it does build.kit's
|
|
11
11
|
* `hint.commands`.
|
|
12
|
+
*
|
|
13
|
+
* The workflow starts every page from a template, because a template already
|
|
14
|
+
* has the frame, spacing, and section rhythm that a page composed from
|
|
15
|
+
* components has to rediscover.
|
|
12
16
|
*/
|
|
13
17
|
|
|
14
18
|
/**
|
|
@@ -24,39 +28,48 @@ export function buildHelp() {
|
|
|
24
28
|
title: 'How to build a page with Astryx',
|
|
25
29
|
steps: [
|
|
26
30
|
{
|
|
27
|
-
title:
|
|
31
|
+
title: 'Find the page template to start from',
|
|
28
32
|
commands: [{command: 'build "<what you\'re building>"'}],
|
|
29
33
|
returns:
|
|
30
|
-
'the
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
title: 'If a [page] template matches, scaffold it and adapt',
|
|
34
|
-
commands: [{command: 'template <name> [path]'}],
|
|
34
|
+
'the [page] template to start from (always one: the closest match, or the app shell when nothing matches), the next two templates, and the [block]s and [component]s for the parts it lacks',
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
title: '
|
|
37
|
+
title: 'Scaffold that template into your project',
|
|
38
38
|
commands: [
|
|
39
39
|
{
|
|
40
|
-
command: 'template <name>
|
|
41
|
-
purpose:
|
|
40
|
+
command: 'template <name> <path>',
|
|
41
|
+
purpose: 'write the page template to <path>',
|
|
42
42
|
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: 'Adapt it: keep its frame and spacing, replace its content',
|
|
47
|
+
commands: [
|
|
43
48
|
{
|
|
44
49
|
command: 'template <BlockName>',
|
|
45
|
-
purpose:
|
|
50
|
+
purpose:
|
|
51
|
+
'print a block to put inside a section, for a part the template lacks',
|
|
46
52
|
},
|
|
47
53
|
{
|
|
48
54
|
command: 'component <Name>',
|
|
49
|
-
purpose: '
|
|
55
|
+
purpose: 'read props before you change a component',
|
|
50
56
|
},
|
|
51
57
|
],
|
|
52
58
|
},
|
|
53
59
|
],
|
|
54
60
|
rules: [
|
|
61
|
+
'Start every page from a page template. Never lay out a page from scratch.',
|
|
62
|
+
'Changing a page you already have? Keep it. Add blocks and components inside its sections.',
|
|
63
|
+
"Keep the template's page frame, gap, and padding values. Replace its data, copy, and sections.",
|
|
55
64
|
'No <div>/raw HTML for layout — use VStack/HStack/Grid/Stack/Card etc.',
|
|
56
65
|
'No style={{}} — use component props, and design tokens for values.',
|
|
57
66
|
'Wrap the app in <Theme theme={...}> and import core reset.css + astryx.css.',
|
|
58
67
|
],
|
|
59
68
|
related: [
|
|
69
|
+
{
|
|
70
|
+
command: 'template --list --type page',
|
|
71
|
+
purpose: 'every page template',
|
|
72
|
+
},
|
|
60
73
|
{command: 'docs tokens', purpose: 'the design tokens'},
|
|
61
74
|
{
|
|
62
75
|
command: 'search <query>',
|
package/api/build/kit/kit.d.mts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
5
|
+
* The page template to start from, and the kit around it.
|
|
6
6
|
*
|
|
7
7
|
* @param {string} query what you're building (e.g. "analytics dashboard")
|
|
8
8
|
* @param {{cwd?: string, type?: import('../../search/search.type.mjs').SearchDomain, limit?: number}} [options]
|
|
@@ -13,3 +13,6 @@ export function buildKit(query: string, options?: {
|
|
|
13
13
|
type?: import("../../search/search.type.mjs").SearchDomain;
|
|
14
14
|
limit?: number;
|
|
15
15
|
}): Promise<import("../build.type.mjs").BuildKitResponse>;
|
|
16
|
+
export type SearchResultEntry = import("../../search/search.type.mjs").SearchResultEntry;
|
|
17
|
+
export type BuildStart = import("../build.type.mjs").BuildStart;
|
|
18
|
+
export type PageTemplate = import("../_adapter.mjs").PageTemplate;
|
package/api/build/kit/kit.mjs
CHANGED
|
@@ -1,44 +1,57 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @file build.kit leaf — the
|
|
4
|
+
* @file build.kit leaf — the page template to start from, and the kit around it.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Every kit names a page template to START from: the page the page ranker
|
|
7
|
+
* (rank.mjs) puts first when it has the evidence to lead, else the app shell.
|
|
8
|
+
* The ranker is the only thing that picks the start, so one noisy signal —
|
|
9
|
+
* search matching "site" to a gallery's "side" — cannot choose the page. A
|
|
10
|
+
* template carries the page frame, the spacing, and the section rhythm; a page
|
|
11
|
+
* composed from components carries none of that, so the kit never recommends
|
|
12
|
+
* composing from scratch while a template exists. Next to the start it names
|
|
13
|
+
* the ranker's next two templates, then groups the unified search into the
|
|
14
|
+
* blocks that cover parts and the domain components to fill gaps, plus the
|
|
15
|
+
* always-on frame + foundation names. `pages` and `directMatch` keep search's
|
|
16
|
+
* own view for callers that read them.
|
|
9
17
|
*
|
|
10
18
|
* The kit carries RAW `SearchResultEntry` objects and static name arrays only —
|
|
11
19
|
* never pre-formatted command strings. All CLI prefixing (formatCliCommand /
|
|
12
20
|
* getCliInvocation) and the section prose live in the command renderer, so the
|
|
13
21
|
* JSON shape stays package-manager-agnostic and stable across environments.
|
|
14
22
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
23
|
+
* Two commands are the kit's own: `start.command`, the scaffold (`astryx
|
|
24
|
+
* template <id> --type page <path>`, with `<path>` a placeholder), and the `--skeleton`
|
|
25
|
+
* a page entry carries when it is not a direct match, so a loose page reads
|
|
26
|
+
* as a layout preview rather than the thing to build. Neither is prefixing —
|
|
18
27
|
* the invocation stays the renderer's job.
|
|
19
28
|
*/
|
|
20
29
|
|
|
21
30
|
import {search} from '../../search/search.mjs';
|
|
22
31
|
import {getResultCoverage} from '../../search/coverage.mjs';
|
|
32
|
+
import {loadPageTemplates} from '../_adapter.mjs';
|
|
33
|
+
import {pickAlternatives, pickStart, rankPages} from './rank.mjs';
|
|
23
34
|
|
|
24
35
|
/** A page at/above this score is a confident direct match. */
|
|
25
36
|
const PAGE_DIRECT = 95;
|
|
26
|
-
/** Below this a page is too weak to offer
|
|
37
|
+
/** Below this a page is too weak to offer at all. */
|
|
27
38
|
const PAGE_FLOOR = 50;
|
|
28
|
-
/** Below this a block/domain-component match is incidental noise. */
|
|
29
|
-
const DOMAIN_FLOOR = 55;
|
|
30
39
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
* Below this a block/domain-component match is incidental noise. A single
|
|
41
|
+
* description word in a multi-word idea scores 50 plus at most 7.5 of coverage
|
|
42
|
+
* garnish, so it stays below; a name or keyword hit clears it. `build "weekly
|
|
43
|
+
* brief"` used to offer Toast, Popover and TextInput because their
|
|
44
|
+
* descriptions say "brief".
|
|
45
|
+
*/
|
|
46
|
+
const DOMAIN_FLOOR = 60;
|
|
47
|
+
/**
|
|
48
|
+
* How much of a multi-word query a page must cover to be offered on breadth.
|
|
39
49
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
50
|
+
* Score alone cannot carry this. A page's derived keywords include every
|
|
51
|
+
* component its source renders, so `build "actionable warning banner"` once
|
|
52
|
+
* scored `login`, `contact-form` and `documentation-design` at 95 apiece — an
|
|
53
|
+
* exact hit on "banner" alone, plus the coverage garnish. Matching one of
|
|
54
|
+
* three concepts is not the same claim as matching three.
|
|
42
55
|
*/
|
|
43
56
|
const PAGE_COVERAGE = 0.5;
|
|
44
57
|
/**
|
|
@@ -50,12 +63,21 @@ const PAGE_COVERAGE = 0.5;
|
|
|
50
63
|
* Astryx contains, which is exactly the failure `build` exists to prevent.
|
|
51
64
|
*/
|
|
52
65
|
const THIN_KIT = 3;
|
|
66
|
+
/**
|
|
67
|
+
* Where a page starts when no page template matched: the first of these the
|
|
68
|
+
* project can scaffold. A top nav over empty, full-width content is the least
|
|
69
|
+
* opinionated frame that still has navigation; `blank` is the floor, with no
|
|
70
|
+
* chrome at all. Either one still hands the reader a page frame and its
|
|
71
|
+
* padding, which composing from components does not.
|
|
72
|
+
*/
|
|
73
|
+
const FALLBACK_STARTS = ['shell-top-nav', 'blank'];
|
|
53
74
|
|
|
54
75
|
/**
|
|
55
76
|
* Always-surfaced primitives. Every page needs a shell + layout/typography/
|
|
56
77
|
* action atoms, but these never keyword-match an idea ("dashboard" != "Stack"),
|
|
57
78
|
* so search alone never returns them. Kept here (not the renderer) because they
|
|
58
79
|
* are ALSO used to exclude these names from the idea-specific `domain` group.
|
|
80
|
+
* Every page template already uses them.
|
|
59
81
|
*/
|
|
60
82
|
const FRAME = ['AppShell', 'TopNav', 'SideNav', 'Layout'];
|
|
61
83
|
const FOUNDATION = [
|
|
@@ -75,7 +97,90 @@ const FOUNDATION = [
|
|
|
75
97
|
const ALWAYS = new Set([...FRAME, ...FOUNDATION]);
|
|
76
98
|
|
|
77
99
|
/**
|
|
78
|
-
*
|
|
100
|
+
* @typedef {import('../../search/search.type.mjs').SearchResultEntry} SearchResultEntry
|
|
101
|
+
* @typedef {import('../build.type.mjs').BuildStart} BuildStart
|
|
102
|
+
* @typedef {import('../_adapter.mjs').PageTemplate} PageTemplate
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* A page template as the kit names it: the command that selects exactly that
|
|
107
|
+
* template, scaffolding into `<path>`, a placeholder for the file or folder to
|
|
108
|
+
* write it to.
|
|
109
|
+
* @param {PageTemplate} t
|
|
110
|
+
*/
|
|
111
|
+
const asTemplate = t => ({
|
|
112
|
+
name: t.name,
|
|
113
|
+
displayName: t.displayName,
|
|
114
|
+
description: t.description,
|
|
115
|
+
command: `${t.command} <path>`,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The template to start from: the ready page the ranker puts first when it
|
|
120
|
+
* has the evidence to lead, else the first fallback shell the project can
|
|
121
|
+
* scaffold. Null only when the project has no page template to offer at all.
|
|
122
|
+
*
|
|
123
|
+
* `direct` means two independent signals agree: the ranker's pick is also
|
|
124
|
+
* search's direct match. The ranker sees only ready templates, so a template
|
|
125
|
+
* still marked not ready is never the start; when search matched one directly
|
|
126
|
+
* the reason names it, so the reader knows why the kit starts elsewhere.
|
|
127
|
+
*
|
|
128
|
+
* @param {import('./rank.mjs').RankedPage[]} ranked
|
|
129
|
+
* @param {SearchResultEntry[]} pages
|
|
130
|
+
* @param {boolean} directMatch
|
|
131
|
+
* @param {PageTemplate[]} catalog
|
|
132
|
+
* @returns {Omit<BuildStart, 'alternatives'> | null}
|
|
133
|
+
*/
|
|
134
|
+
function chooseStart(ranked, pages, directMatch, catalog) {
|
|
135
|
+
const direct = directMatch ? pages[0].name : null;
|
|
136
|
+
const unready =
|
|
137
|
+
direct && !catalog.some(t => t.name === direct) ? direct : null;
|
|
138
|
+
// The reason never denies a match the same response reports: a direct
|
|
139
|
+
// match the ranker outweighed is named, and so are the loose page matches
|
|
140
|
+
// search listed when the kit falls back to the shell.
|
|
141
|
+
const loose = pages.map(p => `\`${p.name}\``).join(', ');
|
|
142
|
+
const pick = pickStart(ranked);
|
|
143
|
+
const closest = pick && catalog.find(t => t.name === pick.name);
|
|
144
|
+
if (closest) {
|
|
145
|
+
const agrees = closest.name === direct;
|
|
146
|
+
return {
|
|
147
|
+
...asTemplate(closest),
|
|
148
|
+
basis: agrees ? 'direct' : 'closest',
|
|
149
|
+
reason: agrees
|
|
150
|
+
? 'Matches the idea.'
|
|
151
|
+
: unready
|
|
152
|
+
? `\`${unready}\` matches but is not ready yet; this is the closest ready template.`
|
|
153
|
+
: direct
|
|
154
|
+
? `Search matched \`${direct}\` by name, but this template fits more of the idea.`
|
|
155
|
+
: 'The closest template; none is exactly this page.',
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
for (const id of FALLBACK_STARTS) {
|
|
159
|
+
const shell = catalog.find(t => t.name === id);
|
|
160
|
+
if (shell) {
|
|
161
|
+
// The shell can also be the ranker's best guess without the evidence to
|
|
162
|
+
// lead ("horizontal site navigation"); say so rather than "no match".
|
|
163
|
+
const nearest = ranked[0]?.name === shell.name && ranked[0].hits > 0;
|
|
164
|
+
return {
|
|
165
|
+
...asTemplate(shell),
|
|
166
|
+
basis: 'fallback',
|
|
167
|
+
reason: unready
|
|
168
|
+
? `\`${unready}\` matches but is not ready yet, so start from the app shell.`
|
|
169
|
+
: direct
|
|
170
|
+
? `Search matched \`${direct}\` by name, but too little of the idea fits it, so start from the app shell.`
|
|
171
|
+
: nearest
|
|
172
|
+
? 'No template is a clear match; the app shell is the closest.'
|
|
173
|
+
: loose
|
|
174
|
+
? `Search matched ${loose} only loosely, so start from the app shell.`
|
|
175
|
+
: 'No template matched, so start from the app shell.',
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The page template to start from, and the kit around it.
|
|
79
184
|
*
|
|
80
185
|
* @param {string} query what you're building (e.g. "analytics dashboard")
|
|
81
186
|
* @param {{cwd?: string, type?: import('../../search/search.type.mjs').SearchDomain, limit?: number}} [options]
|
|
@@ -98,7 +203,7 @@ export async function buildKit(query, options = {}) {
|
|
|
98
203
|
const matchCount = result.data.matchCount;
|
|
99
204
|
|
|
100
205
|
/**
|
|
101
|
-
* Did this result answer enough of the query to stand as a page?
|
|
206
|
+
* Did this result answer enough of the query to stand as a page on breadth?
|
|
102
207
|
* Single-concept queries have nothing to cover, so they always pass. Coverage
|
|
103
208
|
* stays in a module-private WeakMap and never enters public search/build JSON.
|
|
104
209
|
* @param {object} r
|
|
@@ -110,7 +215,7 @@ export async function buildKit(query, options = {}) {
|
|
|
110
215
|
return (coverage?.matched ?? 0) / total >= PAGE_COVERAGE;
|
|
111
216
|
};
|
|
112
217
|
|
|
113
|
-
const
|
|
218
|
+
const matchedPages = results
|
|
114
219
|
.filter(
|
|
115
220
|
r =>
|
|
116
221
|
r.domain === 'template' &&
|
|
@@ -135,32 +240,42 @@ export async function buildKit(query, options = {}) {
|
|
|
135
240
|
!ALWAYS.has(r.name),
|
|
136
241
|
)
|
|
137
242
|
.slice(0, 6);
|
|
138
|
-
const directMatch =
|
|
243
|
+
const directMatch =
|
|
244
|
+
matchedPages.length > 0 && matchedPages[0].score >= PAGE_DIRECT;
|
|
139
245
|
|
|
140
246
|
/**
|
|
141
|
-
* On a loose match,
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* thing to a human in that case: RECOMMENDED START prints
|
|
147
|
-
* `template <name> --skeleton` and the PAGE TEMPLATES heading reads "use as
|
|
148
|
-
* a layout reference". But prose is not what a program reads. A JSON caller
|
|
149
|
-
* takes `command` and gets the scaffold, so the two audiences were given
|
|
150
|
-
* opposite advice from the same kit.
|
|
151
|
-
*
|
|
152
|
-
* That matters most for the caller least able to notice. `template <name>`
|
|
153
|
-
* emits the whole page, and an agent handed a full template it did not quite
|
|
154
|
-
* ask for tends to adapt it anyway — which is how a request for one thing
|
|
155
|
-
* comes back as a competent version of another. `--skeleton` gives the
|
|
156
|
-
* layout without the invitation.
|
|
157
|
-
*
|
|
158
|
-
* Copied rather than mutated: these entries come from `search()` and are not
|
|
159
|
-
* this function's to modify.
|
|
247
|
+
* On a loose match, a page entry's `command` previews the layout rather
|
|
248
|
+
* than printing the whole template: `--skeleton` gives the shape without
|
|
249
|
+
* presenting the page as the thing to build. The recommendation itself is
|
|
250
|
+
* `start`, which always scaffolds. Copied rather than mutated: these entries
|
|
251
|
+
* come from `search()` and are not this function's to modify.
|
|
160
252
|
*/
|
|
161
|
-
const
|
|
162
|
-
?
|
|
163
|
-
:
|
|
253
|
+
const pages = directMatch
|
|
254
|
+
? matchedPages
|
|
255
|
+
: matchedPages.map(page => ({
|
|
256
|
+
...page,
|
|
257
|
+
command: `${page.command} --skeleton`,
|
|
258
|
+
}));
|
|
259
|
+
|
|
260
|
+
// A kit narrowed to components or hooks has no page to start from; every
|
|
261
|
+
// other kit does, so the reader is never left to compose a page from scratch.
|
|
262
|
+
const wantsPages = !type || type === 'template';
|
|
263
|
+
const catalog = wantsPages ? await loadPageTemplates(cwd) : [];
|
|
264
|
+
const ranked = wantsPages ? rankPages(query, catalog) : [];
|
|
265
|
+
const chosen = wantsPages
|
|
266
|
+
? chooseStart(ranked, matchedPages, directMatch, catalog)
|
|
267
|
+
: null;
|
|
268
|
+
// Name the ranker's next two templates beside the start: the reader judges
|
|
269
|
+
// meaning better than keywords do, and an acceptable template is in these
|
|
270
|
+
// three far more often than it is the start alone.
|
|
271
|
+
/** @type {BuildStart | null} */
|
|
272
|
+
const start = chosen && {
|
|
273
|
+
...chosen,
|
|
274
|
+
alternatives: pickAlternatives(ranked, chosen.name).flatMap(r => {
|
|
275
|
+
const t = catalog.find(c => c.name === r.name);
|
|
276
|
+
return t ? [asTemplate(t)] : [];
|
|
277
|
+
}),
|
|
278
|
+
};
|
|
164
279
|
|
|
165
280
|
// What to try when the kit comes back thin. Keyword search over a design
|
|
166
281
|
// system misses in a predictable way — the reader's words and the package's
|
|
@@ -185,12 +300,13 @@ export async function buildKit(query, options = {}) {
|
|
|
185
300
|
type: 'build.kit',
|
|
186
301
|
data: {
|
|
187
302
|
query: result.data.query,
|
|
188
|
-
// Distinguishes "search found nothing"
|
|
189
|
-
//
|
|
303
|
+
// Distinguishes "search found nothing" from a weak-but-non-empty result
|
|
304
|
+
// set. Either way the kit still names a template to start from.
|
|
190
305
|
hasResults: matchCount > 0,
|
|
191
306
|
matchCount,
|
|
192
307
|
directMatch,
|
|
193
|
-
|
|
308
|
+
start,
|
|
309
|
+
pages,
|
|
194
310
|
blocks,
|
|
195
311
|
domain,
|
|
196
312
|
frame: FRAME,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('../_adapter.mjs').PageTemplate} PageTemplate
|
|
6
|
+
* @typedef {{name: string, score: number, hits: number, familyNamed: boolean, containerMatched: boolean}} RankedPage
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Rank page templates against an idea, best first. Ties go to the template
|
|
10
|
+
* with the shorter id (the family's broader page), then by name.
|
|
11
|
+
*
|
|
12
|
+
* @param {string} query
|
|
13
|
+
* @param {PageTemplate[]} pages
|
|
14
|
+
* @returns {RankedPage[]}
|
|
15
|
+
*/
|
|
16
|
+
export function rankPages(query: string, pages: PageTemplate[]): RankedPage[];
|
|
17
|
+
/**
|
|
18
|
+
* The next closest templates after the start, best first: the ones a reader
|
|
19
|
+
* should check the idea against when the start's shape is wrong. Each matched
|
|
20
|
+
* at least one term and scored at least half of what a start needs.
|
|
21
|
+
*
|
|
22
|
+
* @param {RankedPage[]} ranked
|
|
23
|
+
* @param {string} startName
|
|
24
|
+
* @param {number} [count]
|
|
25
|
+
* @returns {RankedPage[]}
|
|
26
|
+
*/
|
|
27
|
+
export function pickAlternatives(ranked: RankedPage[], startName: string, count?: number): RankedPage[];
|
|
28
|
+
/**
|
|
29
|
+
* The template to start from, or null when the best one has too little
|
|
30
|
+
* evidence to lead and the page should start from the app shell. Evidence is
|
|
31
|
+
* two matched terms, the idea naming the template's family, or its container.
|
|
32
|
+
*
|
|
33
|
+
* @param {RankedPage[]} ranked
|
|
34
|
+
* @returns {RankedPage | null}
|
|
35
|
+
*/
|
|
36
|
+
export function pickStart(ranked: RankedPage[]): RankedPage | null;
|
|
37
|
+
export type PageTemplate = import("../_adapter.mjs").PageTemplate;
|
|
38
|
+
export type RankedPage = {
|
|
39
|
+
name: string;
|
|
40
|
+
score: number;
|
|
41
|
+
hits: number;
|
|
42
|
+
familyNamed: boolean;
|
|
43
|
+
containerMatched: boolean;
|
|
44
|
+
};
|