@astryxdesign/cli 0.6.4 → 0.6.5-canary.01972bc
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 +56 -0
- package/README.md +103 -95
- package/api/build/_adapter.d.mts +36 -2
- package/api/build/_adapter.mjs +41 -10
- package/api/build/build.doc.mjs +8 -3
- package/api/build/build.test.mjs +60 -2
- package/api/build/kit/kit.mjs +109 -26
- package/api/build/kit/rank.d.mts +24 -8
- package/api/build/kit/rank.mjs +277 -97
- package/api/build/kit/rank.test.mjs +231 -48
- package/api/component/_adapter.d.mts +25 -0
- package/api/component/_adapter.mjs +59 -5
- package/api/component/component.d.mts +6 -3
- package/api/component/component.doc.mjs +37 -17
- package/api/component/component.mjs +249 -9
- package/api/component/component.type.d.mts +25 -0
- package/api/component/component.type.mjs +44 -0
- 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 +61 -18
- package/api/discover/discover.mjs +220 -36
- package/api/discover/discover.test.mjs +11 -2
- package/api/discover/discover.type.d.mts +147 -8
- package/api/discover/discover.type.mjs +102 -12
- 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 +8 -3
- package/api/docs/_adapter.mjs +14 -6
- package/api/docs/docOverlays.test.mjs +27 -1
- package/api/docs/docs.doc.mjs +2 -2
- package/api/docs/docs.test.mjs +54 -18
- package/api/docs/integration-tree.test.mjs +17 -0
- package/api/docs/integrationDocs.test.mjs +27 -5
- package/api/doctor/doctor.d.mts +8 -3
- package/api/doctor/doctor.doc.mjs +17 -8
- package/api/doctor/doctor.mjs +90 -9
- package/api/doctor/doctor.test.mjs +122 -10
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/error.d.mts +22 -0
- package/api/error.mjs +42 -0
- package/api/gap-report/gap-report.doc.mjs +19 -10
- package/api/hook/hook.doc.mjs +6 -3
- package/api/index.d.mts +1 -0
- package/api/index.mjs +5 -3
- package/api/init/init.doc.mjs +17 -12
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +7 -3
- package/api/integration/add-contribution.test.mjs +3 -3
- package/api/integration/add-helpers.d.mts +5 -2
- package/api/integration/add-helpers.mjs +36 -9
- package/api/integration/add-theme.mjs +266 -23
- package/api/integration/add-theme.test.mjs +247 -0
- package/api/integration/authoring-checks.mjs +12 -9
- package/api/integration/authoring-checks.type.d.mts +8 -0
- package/api/integration/authoring-checks.type.mjs +7 -3
- package/api/integration/integration-authoring.type.d.mts +4 -1
- package/api/integration/integration-authoring.type.mjs +6 -1
- package/api/integration/integrationAdd.doc.mjs +6 -0
- package/api/integration/integrationAddTheme.doc.mjs +10 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -1
- package/api/integration/integrationDocConflicts.doc.mjs +1 -1
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/integrationTemplateConflicts.doc.mjs +1 -1
- package/api/integration/pack-check.lifecycle-output.test.mjs +107 -0
- package/api/integration/pack-check.mjs +92 -10
- package/api/integration/pack-check.test.mjs +140 -1
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/integration/validate-integration.d.mts +4 -2
- package/api/integration/validate-integration.mjs +7 -2
- package/api/integration/validate-integration.test.mjs +55 -0
- package/api/integration/validate-integration.type.d.mts +5 -0
- package/api/integration/validate-integration.type.mjs +5 -1
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/expand/expand.mjs +12 -7
- package/api/layout/expand/expand.receipt.test.mjs +74 -0
- package/api/layout/layout.type.d.mts +1 -0
- package/api/layout/layout.type.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +1 -1
- package/api/search/search.d.mts +51 -1
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +299 -17
- package/api/search/search.test.mjs +216 -18
- package/api/swizzle/copy/copy.mjs +66 -3
- package/api/swizzle/swizzle.doc.mjs +11 -5
- package/api/template/copy/copy.mjs +15 -9
- package/api/template/copy/copy.receipt.test.mjs +77 -0
- package/api/template/copy/copy.test.mjs +9 -0
- package/api/template/show/show.mjs +15 -4
- package/api/template/show/show.test.mjs +76 -0
- package/api/template/template-integration.test.mjs +14 -0
- package/api/template/template.d.mts +1 -1
- package/api/template/template.doc.mjs +8 -3
- package/api/template/template.mjs +1 -0
- package/api/template/template.type.d.mts +2 -0
- package/api/template/template.type.mjs +2 -0
- package/api/theme/add/add.mjs +17 -25
- package/api/theme/add/add.rollback.test.mjs +158 -0
- package/api/theme/add/add.staging.test.mjs +40 -23
- package/api/theme/build/build.d.mts +24 -0
- package/api/theme/build/build.family.test.mjs +7 -12
- package/api/theme/build/build.mjs +243 -26
- package/api/theme/build/build.project-core.test.mjs +165 -0
- package/api/theme/build/build.rollback.test.mjs +148 -0
- package/api/theme/generateTonalPalette.doc.mjs +1 -2
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +9 -10
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +2 -1
- package/api/theme/themePaletteGenerate.doc.mjs +15 -8
- package/api/theme/themeTargets.doc.mjs +3 -2
- package/api/theme/themeTemplate.doc.mjs +2 -1
- package/api/upgrade/run/files-changed.test.mjs +111 -0
- package/api/upgrade/run/run.mjs +25 -6
- package/api/upgrade/run/run.test.mjs +45 -1
- package/api/upgrade/upgrade.doc.mjs +24 -22
- package/api/upgrade/upgrade.type.d.mts +1 -0
- package/api/upgrade/upgrade.type.mjs +3 -2
- package/assets/codemods/__tests__/runner.test.mjs +3 -1
- package/assets/codemods/file-count.test.mjs +163 -0
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +5 -4
- package/assets/docs/README.md +4 -2
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +8 -2
- package/assets/docs/elevation.doc.mjs +6 -4
- package/assets/docs/getting-started.doc.mjs +5 -16
- package/assets/docs/icons.doc.mjs +3 -21
- package/assets/docs/illustrations.doc.mjs +7 -15
- package/assets/docs/internationalization.doc.mjs +7 -5
- package/assets/docs/layout.doc.dense.mjs +130 -82
- package/assets/docs/layout.doc.mjs +133 -77
- package/assets/docs/migration.doc.mjs +19 -21
- package/assets/docs/motion.doc.mjs +16 -3
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +8 -0
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +8 -3
- package/assets/docs/spacing.doc.mjs +7 -2
- package/assets/docs/styling-libraries.doc.mjs +6 -2
- package/assets/docs/styling.doc.mjs +19 -23
- package/assets/docs/theme.doc.dense.mjs +58 -18
- package/assets/docs/theme.doc.mjs +57 -47
- package/assets/docs/theme.doc.zh.mjs +9 -8
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +389 -8
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/add-a-component.doc.mjs +75 -0
- package/assets/docs/tree/add-a-theme.doc.mjs +85 -0
- package/assets/docs/tree/add-a-topic.doc.mjs +144 -0
- package/assets/docs/tree/agent-guidance.doc.mjs +138 -0
- package/assets/docs/tree/block-template.doc.mjs +130 -0
- package/assets/docs/tree/build-the-template.doc.mjs +28 -0
- package/assets/docs/tree/building-blocks.doc.mjs +46 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +137 -0
- package/assets/docs/tree/checks.doc.mjs +119 -0
- package/assets/docs/tree/codemods.doc.mjs +147 -0
- package/assets/docs/tree/component-family.doc.mjs +113 -0
- package/assets/docs/tree/component-imports.doc.mjs +69 -0
- package/assets/docs/tree/component-lookups.doc.mjs +149 -0
- package/assets/docs/tree/components.doc.mjs +23 -0
- package/assets/docs/tree/configuration.doc.mjs +23 -0
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +182 -0
- package/assets/docs/tree/define-the-theme.doc.mjs +118 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +57 -0
- package/assets/docs/tree/docs.doc.mjs +21 -0
- package/assets/docs/tree/document-the-template.doc.mjs +28 -0
- package/assets/docs/tree/document-the-theme.doc.mjs +68 -0
- package/assets/docs/tree/export-template-assets.doc.mjs +147 -0
- package/assets/docs/tree/extend-or-replace.doc.mjs +103 -0
- package/assets/docs/tree/fonts-and-assets.doc.mjs +106 -0
- package/assets/docs/tree/generate-a-palette.doc.mjs +66 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +105 -0
- package/assets/docs/tree/help.doc.mjs +16 -0
- package/assets/docs/tree/integrations.doc.mjs +25 -451
- package/assets/docs/tree/links.doc.mjs +98 -0
- package/assets/docs/tree/package-and-test.doc.mjs +32 -0
- package/assets/docs/tree/page-template.doc.mjs +71 -0
- package/assets/docs/tree/publishing.doc.mjs +111 -0
- package/assets/docs/tree/quick-start.doc.mjs +272 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +104 -0
- package/assets/docs/tree/replace-a-core-template.doc.mjs +172 -0
- package/assets/docs/tree/sections-and-placement.doc.mjs +108 -0
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +59 -0
- package/assets/docs/tree/ship.doc.mjs +16 -0
- package/assets/docs/tree/short-and-findable.doc.mjs +108 -0
- package/assets/docs/tree/single-component.doc.mjs +165 -0
- package/assets/docs/tree/start-a-template.doc.mjs +143 -0
- package/assets/docs/tree/subcomponent.doc.mjs +115 -0
- package/assets/docs/tree/template-assets.doc.mjs +64 -0
- package/assets/docs/tree/template-doc-overview.doc.mjs +121 -0
- package/assets/docs/tree/template-fonts.doc.mjs +102 -0
- package/assets/docs/tree/template-grading-rubric.doc.mjs +452 -0
- package/assets/docs/tree/template-icons.doc.mjs +97 -0
- package/assets/docs/tree/template-images-media.doc.mjs +127 -0
- package/assets/docs/tree/template-styles.doc.mjs +93 -0
- package/assets/docs/tree/templates.doc.mjs +34 -0
- package/assets/docs/tree/test-in-an-app.doc.mjs +115 -0
- package/assets/docs/tree/test-template-in-app.doc.mjs +128 -0
- package/assets/docs/tree/themes.doc.mjs +39 -0
- package/assets/docs/tree/troubleshooting.doc.mjs +153 -0
- package/assets/docs/tree/upgrading.doc.mjs +103 -0
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +51 -0
- package/assets/docs/tree/verify-packed-template.doc.mjs +77 -0
- package/assets/docs/tree/versioning.doc.mjs +162 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +64 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +154 -0
- package/assets/docs/typography.doc.mjs +24 -4
- package/assets/docs/working-with-ai.doc.mjs +30 -22
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/assets/templates/pages/ai-chat/template.doc.mjs +16 -1
- package/assets/templates/pages/ai-chat-landing/template.doc.mjs +9 -1
- package/assets/templates/pages/blank/template.doc.mjs +3 -1
- package/assets/templates/pages/canvas-editor/template.doc.mjs +9 -1
- package/assets/templates/pages/centered-hero/template.doc.mjs +3 -1
- package/assets/templates/pages/checkout-wizard/template.doc.mjs +1 -0
- package/assets/templates/pages/classic-gallery/template.doc.mjs +3 -1
- package/assets/templates/pages/contact-form/template.doc.mjs +16 -1
- package/assets/templates/pages/dashboard/template.doc.mjs +15 -1
- package/assets/templates/pages/dashboard-alert-rail/template.doc.mjs +23 -1
- package/assets/templates/pages/dashboard-cohort-funnel/template.doc.mjs +10 -1
- package/assets/templates/pages/dashboard-comparison/template.doc.mjs +9 -1
- package/assets/templates/pages/dashboard-composition/template.doc.mjs +10 -1
- package/assets/templates/pages/dashboard-progress/template.doc.mjs +17 -1
- package/assets/templates/pages/dashboard-scorecard/template.doc.mjs +2 -1
- package/assets/templates/pages/detail-page/template.doc.mjs +8 -0
- package/assets/templates/pages/documentation/template.doc.mjs +10 -1
- package/assets/templates/pages/documentation-design/template.doc.mjs +10 -1
- package/assets/templates/pages/documentation-technical/template.doc.mjs +10 -1
- package/assets/templates/pages/editor/template.doc.mjs +9 -1
- package/assets/templates/pages/file-explorer/template.doc.mjs +3 -1
- package/assets/templates/pages/form-two-column/template.doc.mjs +17 -1
- package/assets/templates/pages/form-wizard/template.doc.mjs +14 -1
- package/assets/templates/pages/form-wizard-dialog/template.doc.mjs +1 -0
- package/assets/templates/pages/gallery-hero/template.doc.mjs +10 -1
- package/assets/templates/pages/ide/template.doc.mjs +9 -1
- package/assets/templates/pages/incident-console/template.doc.mjs +10 -1
- package/assets/templates/pages/kanban-board/template.doc.mjs +11 -1
- package/assets/templates/pages/library/template.doc.mjs +15 -1
- package/assets/templates/pages/login/template.doc.mjs +10 -1
- package/assets/templates/pages/login-card/template.doc.mjs +11 -1
- package/assets/templates/pages/login-split/template.doc.mjs +10 -1
- package/assets/templates/pages/login-sso/template.doc.mjs +10 -1
- package/assets/templates/pages/messaging-shell/template.doc.mjs +11 -1
- package/assets/templates/pages/mixed-gallery/template.doc.mjs +10 -1
- package/assets/templates/pages/payment-form/template.doc.mjs +3 -1
- package/assets/templates/pages/product-detail/template.doc.mjs +9 -1
- package/assets/templates/pages/product-gallery/template.doc.mjs +10 -1
- package/assets/templates/pages/settings/template.doc.mjs +3 -1
- package/assets/templates/pages/settings-dialog/template.doc.mjs +9 -1
- package/assets/templates/pages/settings-sidebar/template.doc.mjs +9 -1
- package/assets/templates/pages/shell-nav/template.doc.mjs +10 -1
- package/assets/templates/pages/shell-side-nav/template.doc.mjs +14 -1
- package/assets/templates/pages/shell-top-nav/template.doc.mjs +11 -1
- package/assets/templates/pages/side-gallery/template.doc.mjs +3 -1
- package/assets/templates/pages/table/template.doc.mjs +11 -1
- package/assets/templates/pages/table-filter/template.doc.mjs +21 -1
- package/assets/templates/pages/table-grouped/template.doc.mjs +15 -1
- package/assets/templates/pages/table-inbox/template.doc.mjs +18 -6
- package/assets/templates/pages/table-page/template.doc.mjs +20 -1
- package/assets/templates/pages/table-tree/template.doc.mjs +14 -1
- package/assets/templates/pages/theme-showcase/template.doc.mjs +10 -1
- package/assets/templates/pages/work-item-detail/template.doc.mjs +10 -0
- package/assets/templates/themes/butter/icons.tsx +2 -0
- package/assets/templates/themes/chocolate/icons.tsx +2 -0
- package/assets/templates/themes/gothic/icons.tsx +2 -0
- package/assets/templates/themes/matcha/icons.tsx +2 -0
- package/assets/templates/themes/neutral/icons.tsx +2 -0
- package/assets/templates/themes/stone/icons.tsx +2 -0
- package/assets/templates/themes/y2k/icons.tsx +2 -0
- package/authoring/config/config.doc.mjs +9 -1
- package/authoring/config/parse.d.mts +2 -0
- package/authoring/config/parse.mjs +19 -0
- package/authoring/config/parse.test.mjs +8 -0
- package/authoring/config/type.ts +11 -0
- 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 +3 -2
- package/authoring/doctypes/_schema.mjs +6 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +4 -2
- package/authoring/doctypes/component/component.doc.mjs +6 -0
- package/authoring/doctypes/component/type.ts +8 -0
- package/authoring/doctypes/reference/reference.doc.mjs +7 -0
- package/authoring/doctypes/reference/type.ts +5 -0
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +1 -0
- package/authoring/doctypes/template/parse.test.mjs +21 -0
- package/authoring/doctypes/template/template.doc.mjs +7 -1
- package/authoring/doctypes/template/type.ts +12 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +10 -0
- package/authoring/index.mjs +1 -0
- package/authoring/integration/integration.doc.mjs +12 -10
- package/clients/cli/commands/component/index.mjs +152 -55
- package/clients/cli/commands/component-batch.test.mjs +341 -0
- package/clients/cli/commands/component-ownership.test.mjs +89 -0
- package/clients/cli/commands/component.doc.mjs +27 -9
- package/clients/cli/commands/discover.doc.mjs +53 -9
- package/clients/cli/commands/discover.mjs +393 -118
- package/clients/cli/commands/discover.sources.test.mjs +267 -0
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +60 -17
- package/clients/cli/commands/docs.test.mjs +113 -24
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -2
- package/clients/cli/commands/doctor-integration.test.mjs +53 -0
- package/clients/cli/commands/doctor.doc.mjs +3 -1
- package/clients/cli/commands/doctor.mjs +53 -9
- package/clients/cli/commands/gap-report.doc.mjs +10 -9
- package/clients/cli/commands/init.doc.mjs +9 -6
- package/clients/cli/commands/integration-add.doc.mjs +17 -7
- package/clients/cli/commands/integration-authoring.test.mjs +70 -9
- package/clients/cli/commands/integration-pack.doc.mjs +5 -9
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration-verify.doc.mjs +22 -0
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +76 -43
- package/clients/cli/commands/layout-expand.doc.mjs +3 -1
- package/clients/cli/commands/layout.expand-receipt.test.mjs +94 -0
- package/clients/cli/commands/layout.mjs +16 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +10 -3
- package/clients/cli/commands/search.mjs +21 -2
- package/clients/cli/commands/search.test.mjs +21 -4
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.copy-receipt.test.mjs +60 -0
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/template.mjs +19 -5
- package/clients/cli/commands/template.show-media.test.mjs +62 -0
- package/clients/cli/commands/text-json-parity.test.mjs +7 -1
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -2
- package/clients/cli/commands/theme-palette.doc.mjs +1 -2
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +2 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +14 -0
- package/clients/cli/commands/upgrade.doc.mjs +62 -3
- package/clients/cli/commands/write-failure.test.mjs +175 -0
- package/clients/cli/index.mjs +28 -6
- package/clients/cli/lib/define-command.mjs +28 -4
- package/clients/cli/lib/define-command.test.mjs +54 -0
- package/clients/cli/lib/exit-codes.test.mjs +17 -1
- package/clients/cli/lib/json-shim.mjs +24 -14
- package/clients/cli/lib/manifest.mjs +48 -156
- package/clients/cli/lib/manifest.test.mjs +103 -9
- package/clients/cli/lib/parse-error-format.test.mjs +81 -0
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/agent-docs/agent-docs.test.mjs +3 -2
- package/foundation/discovery/authoring-self-docs.mjs +1 -0
- package/foundation/discovery/authoring-self-docs.test.mjs +6 -2
- package/foundation/discovery/cli-self-docs.mjs +16 -2
- package/foundation/discovery/cli-self-docs.test.mjs +20 -0
- package/foundation/discovery/docs-discovery.mjs +5 -1
- package/foundation/discovery/docs-discovery.test.mjs +21 -0
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.d.mts +14 -0
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +37 -1
- package/foundation/discovery/template-adapter.mjs +21 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +5 -4
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/tree.d.mts +4 -0
- package/foundation/doc-compiler/tree.mjs +6 -1
- package/foundation/doc-compiler/tree.test.mjs +65 -14
- package/foundation/integrations/cli-requirement.d.mts +75 -11
- package/foundation/integrations/cli-requirement.mjs +120 -23
- package/foundation/integrations/cli-requirement.test.mjs +141 -9
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +14 -1
- package/foundation/integrations/integrations.mjs +41 -1
- package/foundation/integrations/integrations.test.mjs +31 -0
- package/foundation/response/batch.type.d.mts +33 -0
- package/foundation/response/batch.type.mjs +34 -0
- package/foundation/response/error-codes.doc.mjs +6 -8
- package/foundation/response/error-codes.test.mjs +30 -5
- package/foundation/response/response-types.doc.d.mts +5 -4
- package/foundation/response/response-types.doc.mjs +49 -19
- package/foundation/response/response-types.doc.test.mjs +23 -0
- package/foundation/response/response.doc.mjs +11 -10
- package/package.json +9 -9
- package/assets/docs/tree/integrations.test.mjs +0 -62
- package/assets/docs/tree/writing-docs.doc.mjs +0 -286
package/api/build/_adapter.mjs
CHANGED
|
@@ -2,20 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @file The build subject's environment access: the page templates a project
|
|
5
|
-
* can scaffold.
|
|
5
|
+
* can scaffold, and the components it can use.
|
|
6
6
|
*
|
|
7
|
-
* @input Template discovery for `cwd` — the CLI's own templates
|
|
8
|
-
* the project's configured integrations
|
|
7
|
+
* @input Template and component discovery for `cwd` — the CLI's own templates
|
|
8
|
+
* and Core's components, plus any that the project's configured integrations
|
|
9
|
+
* contribute.
|
|
9
10
|
* @output Ready page templates as `{name, displayName, description, category,
|
|
10
|
-
* command}`, where `command` is the `astryx template` command that
|
|
11
|
-
* exactly that template
|
|
12
|
-
* @position Beside build.mjs (api/build/). The kit leaf reads templates
|
|
13
|
-
* through here, because a subject's `_adapter.mjs` is its
|
|
14
|
-
* access.
|
|
15
|
-
*
|
|
11
|
+
* keywords, command}`, where `command` is the `astryx template` command that
|
|
12
|
+
* selects exactly that template; components as `{name, keywords}`.
|
|
13
|
+
* @position Beside build.mjs (api/build/). The kit leaf reads templates and
|
|
14
|
+
* components only through here, because a subject's `_adapter.mjs` is its
|
|
15
|
+
* only environment access. This adds no discovery of its own: templates come
|
|
16
|
+
* from the template subject's, components from search's.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
import {discoverTemplates} from '../template/template.mjs';
|
|
20
|
+
import {componentKeywords} from '../search/search.mjs';
|
|
21
|
+
import {findCoreDir} from '../../foundation/fs/paths.mjs';
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* A page template the kit can recommend starting from.
|
|
@@ -23,8 +26,16 @@ import {discoverTemplates} from '../template/template.mjs';
|
|
|
23
26
|
* @property {string} name The template's own id, as search reports it.
|
|
24
27
|
* @property {string} command `astryx template <id> --type page`, the command that selects exactly this template: an integration replacement is selected by the Core id it replaces, and `--type page` keeps a block with the same id from making it ambiguous. Search prints template commands the same way.
|
|
25
28
|
* @property {string} displayName Human-facing name.
|
|
26
|
-
* @property {string} description What the page is
|
|
29
|
+
* @property {string} description What the page is and how it is laid out.
|
|
27
30
|
* @property {string} category The template's own `Family - Variant` label; empty when it declares none.
|
|
31
|
+
* @property {string[]} keywords The ideas the page serves, as its own descriptor names them; empty when it declares none.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A component the project can use, as the ranker reads it.
|
|
36
|
+
* @typedef {object} ComponentWords
|
|
37
|
+
* @property {string} name The component's name, e.g. `DateRangeInput`.
|
|
38
|
+
* @property {string[]} keywords The keywords its own doc declares.
|
|
28
39
|
*/
|
|
29
40
|
|
|
30
41
|
/**
|
|
@@ -53,8 +64,28 @@ export async function loadPageTemplates(cwd) {
|
|
|
53
64
|
displayName: t.displayName || t.name,
|
|
54
65
|
description: t.description || '',
|
|
55
66
|
category: t.category || '',
|
|
67
|
+
keywords: t.keywords ?? [],
|
|
56
68
|
// The id `template()` resolves back to this entry: an active replacement
|
|
57
69
|
// owns the Core id it names, so that id selects it, not its own.
|
|
58
70
|
command: `astryx template ${t.replaces ?? t.dirName} --type page`,
|
|
59
71
|
}));
|
|
60
72
|
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The components the project can use, Core's and its integrations', each with
|
|
76
|
+
* the keywords its own doc declares: what the ranker reads to tell a part of a
|
|
77
|
+
* page from a page. Search's own discovery, so both agree on what exists; empty
|
|
78
|
+
* when Core cannot be found.
|
|
79
|
+
*
|
|
80
|
+
* @param {string} cwd
|
|
81
|
+
* @returns {Promise<ComponentWords[]>}
|
|
82
|
+
*/
|
|
83
|
+
export async function loadComponents(cwd) {
|
|
84
|
+
const coreDir = findCoreDir(cwd);
|
|
85
|
+
if (!coreDir) return [];
|
|
86
|
+
try {
|
|
87
|
+
return await componentKeywords(coreDir, cwd);
|
|
88
|
+
} catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
package/api/build/build.doc.mjs
CHANGED
|
@@ -19,8 +19,8 @@ export const doc = {
|
|
|
19
19
|
'The "build a page" entry point. Called with no query it returns the ' +
|
|
20
20
|
'how-to-build-a-page playbook as data: the workflow steps with their ' +
|
|
21
21
|
'commands, the on-system rules, and related lookups. Called with a query it names the page template to ' +
|
|
22
|
-
'START from (always one: the page template a ranker built for long descriptions puts first
|
|
23
|
-
'shell) and the next two templates, ' +
|
|
22
|
+
'START from (always one: the page template a ranker built for long descriptions puts first; for a part ' +
|
|
23
|
+
'of a page, the page it names; else the app shell) and the next two templates, ' +
|
|
24
24
|
'and the unified search grouped around it: the other close page templates, drop-in blocks, and ' +
|
|
25
25
|
'idea-specific components/hooks, plus the always-on frame + foundation. A template carries the page ' +
|
|
26
26
|
'frame and spacing, so the kit never recommends composing a page from components.',
|
|
@@ -40,6 +40,7 @@ export const doc = {
|
|
|
40
40
|
type: 'string',
|
|
41
41
|
description:
|
|
42
42
|
'Directory to resolve @astryxdesign/core and templates from.',
|
|
43
|
+
default: 'process.cwd()',
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
46
|
name: 'options.type',
|
|
@@ -69,7 +70,11 @@ export const doc = {
|
|
|
69
70
|
throws: [
|
|
70
71
|
{
|
|
71
72
|
code: 'ERR_INVALID_ARGUMENT',
|
|
72
|
-
when: 'options.type is not a known domain, or options.limit is not a positive integer',
|
|
73
|
+
when: 'a query is given and options.type is not a known domain, or options.limit is not a positive integer',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: 'ERR_CORE_NOT_FOUND',
|
|
77
|
+
when: 'a query is given and @astryxdesign/core cannot be found from cwd',
|
|
73
78
|
},
|
|
74
79
|
],
|
|
75
80
|
examples: [
|
package/api/build/build.test.mjs
CHANGED
|
@@ -8,7 +8,7 @@ import {describe, it, expect, vi} from 'vitest';
|
|
|
8
8
|
import * as path from 'node:path';
|
|
9
9
|
import {fileURLToPath} from 'node:url';
|
|
10
10
|
import {build} from './build.mjs';
|
|
11
|
-
import {search} from '../search/search.mjs';
|
|
11
|
+
import {search, searchedComponents} from '../search/search.mjs';
|
|
12
12
|
|
|
13
13
|
// api/build/ -> up 3 = packages/cli, up 4 = repo root (has packages/core).
|
|
14
14
|
const REPO = path.resolve(
|
|
@@ -152,6 +152,16 @@ describe('build API', () => {
|
|
|
152
152
|
});
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
+
describe('build kit — reuses the components its search gathered', () => {
|
|
156
|
+
it('keeps them beside the search response, out of its JSON', async () => {
|
|
157
|
+
const all = await search('date picker', {cwd: REPO});
|
|
158
|
+
expect(searchedComponents(all)?.map(c => c.name)).toContain('DateRangeInput');
|
|
159
|
+
expect(JSON.stringify(all)).not.toContain('"keywords"');
|
|
160
|
+
const pagesOnly = await search('date picker', {cwd: REPO, type: 'template'});
|
|
161
|
+
expect(searchedComponents(pagesOnly)).toBeNull();
|
|
162
|
+
}, 60_000);
|
|
163
|
+
});
|
|
164
|
+
|
|
155
165
|
describe('build kit — coverage gates the pages group', () => {
|
|
156
166
|
it('does not call a one-word coincidence a direct match', async () => {
|
|
157
167
|
// A page's keywords include every component its source renders, so any
|
|
@@ -179,6 +189,28 @@ describe('build kit — coverage gates the pages group', () => {
|
|
|
179
189
|
}
|
|
180
190
|
});
|
|
181
191
|
|
|
192
|
+
it('does not call a page that only mentions every word a direct match', async () => {
|
|
193
|
+
// `empty state` and `command palette` name components. A page whose text
|
|
194
|
+
// mentions both words, or that renders the component, is a layout
|
|
195
|
+
// reference, not the page the reader asked for.
|
|
196
|
+
for (const query of ['empty state', 'command palette']) {
|
|
197
|
+
const r = await build(query, {cwd: REPO});
|
|
198
|
+
if (r.type !== 'build.kit') throw new Error('expected build.kit');
|
|
199
|
+
expect(r.data.directMatch, query).toBe(false);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('keeps the page and component a query names first', async () => {
|
|
204
|
+
const pageOf = async (/** @type {string} */ query) => {
|
|
205
|
+
const r = await build(query, {cwd: REPO});
|
|
206
|
+
if (r.type !== 'build.kit') throw new Error('expected build.kit');
|
|
207
|
+
return r.data;
|
|
208
|
+
};
|
|
209
|
+
expect((await pageOf('checkout flow')).pages[0]).toMatchObject({name: 'checkout-wizard'});
|
|
210
|
+
expect((await pageOf('sign in with sso')).pages[0]).toMatchObject({name: 'login-sso'});
|
|
211
|
+
expect((await pageOf('search results')).domain.map(e => e.name)).toContain('PowerSearch');
|
|
212
|
+
});
|
|
213
|
+
|
|
182
214
|
it('leaves single-concept queries alone (nothing to cover)', async () => {
|
|
183
215
|
const r = await build('dashboard', {cwd: REPO});
|
|
184
216
|
expect(r.type).toBe('build.kit');
|
|
@@ -237,7 +269,7 @@ describe('build kit — a thin kit says what to try next', () => {
|
|
|
237
269
|
// A skeleton is a 35-line excerpt: a reader who studies it and composes
|
|
238
270
|
// the rest loses the spacing the template exists to carry. A loose match
|
|
239
271
|
// is still the best start there is, so `start` scaffolds it.
|
|
240
|
-
const r = await build('
|
|
272
|
+
const r = await build('quarterly business review', {cwd: REPO});
|
|
241
273
|
expect(r.type).toBe('build.kit');
|
|
242
274
|
if (r.type !== 'build.kit') return;
|
|
243
275
|
expect(r.data.directMatch).toBe(false);
|
|
@@ -335,9 +367,35 @@ describe('build kit — every page starts from a template', () => {
|
|
|
335
367
|
const placed = await build('an empty state for a settings page', {cwd: REPO});
|
|
336
368
|
if (placed.type !== 'build.kit') throw new Error(placed.type);
|
|
337
369
|
expect(placed.data.start).toMatchObject({name: 'settings', basis: 'closest'});
|
|
370
|
+
expect(placed.data.start?.reason).toMatch(/part of a page, so it starts from the page it names/);
|
|
338
371
|
const loose = await build('a date range picker', {cwd: REPO});
|
|
339
372
|
if (loose.type !== 'build.kit') throw new Error(loose.type);
|
|
340
373
|
expect(loose.data.start).toMatchObject({name: 'shell-top-nav', basis: 'fallback'});
|
|
374
|
+
expect(loose.data.start?.reason).toMatch(/part of a page and names no page, so it starts from the app shell/);
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it('starts a change to an existing page from the app shell', async () => {
|
|
378
|
+
// The page is the builder's to keep; no template scaffolds it.
|
|
379
|
+
const r = await build('add a sort toggle to the existing reports dashboard', {cwd: REPO});
|
|
380
|
+
if (r.type !== 'build.kit') throw new Error(r.type);
|
|
381
|
+
expect(r.data.start).toMatchObject({name: 'shell-top-nav', basis: 'fallback'});
|
|
382
|
+
expect(r.data.start?.reason).toMatch(/changes a page you already have, so keep it/);
|
|
383
|
+
expect(r.data.start?.reason).not.toMatch(/too little of the idea fits/);
|
|
384
|
+
// A direct match the response reports is still named.
|
|
385
|
+
if (r.data.directMatch) expect(r.data.start?.reason).toContain(`\`${r.data.pages[0].name}\``);
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
it('does not call a new page that mentions something existing a change', async () => {
|
|
389
|
+
for (const idea of [
|
|
390
|
+
'a new dashboard inspired by the existing one',
|
|
391
|
+
'a new dashboard based on the existing dashboard',
|
|
392
|
+
'clone the existing dashboard as a new page',
|
|
393
|
+
]) {
|
|
394
|
+
const r = await build(idea, {cwd: REPO});
|
|
395
|
+
if (r.type !== 'build.kit') throw new Error(r.type);
|
|
396
|
+
expect(r.data.start?.name).toBe('dashboard');
|
|
397
|
+
expect(r.data.start?.reason).not.toMatch(/already have/);
|
|
398
|
+
}
|
|
341
399
|
});
|
|
342
400
|
|
|
343
401
|
it('names a direct match the ranker outweighed in the reason', async () => {
|
package/api/build/kit/kit.mjs
CHANGED
|
@@ -27,10 +27,13 @@
|
|
|
27
27
|
* the invocation stays the renderer's job.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import {search} from '../../search/search.mjs';
|
|
30
|
+
import {search, searchedComponents} from '../../search/search.mjs';
|
|
31
|
+
import {findCoreDir} from '../../../foundation/fs/paths.mjs';
|
|
32
|
+
import {AstryxError} from '../../error.mjs';
|
|
33
|
+
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
31
34
|
import {getResultCoverage} from '../../search/coverage.mjs';
|
|
32
|
-
import {loadPageTemplates} from '../_adapter.mjs';
|
|
33
|
-
import {pickAlternatives, pickStart, rankPages} from './rank.mjs';
|
|
35
|
+
import {loadComponents, loadPageTemplates} from '../_adapter.mjs';
|
|
36
|
+
import {ideaKind, pickAlternatives, pickStart, rankPages} from './rank.mjs';
|
|
34
37
|
|
|
35
38
|
/** A page at/above this score is a confident direct match. */
|
|
36
39
|
const PAGE_DIRECT = 95;
|
|
@@ -115,6 +118,24 @@ const asTemplate = t => ({
|
|
|
115
118
|
command: `${t.command} <path>`,
|
|
116
119
|
});
|
|
117
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Why a part of a page, or a change to a page the builder already has, starts
|
|
123
|
+
* where it does (spec:AST-048/FR3, FR9): the rest of the start's reason, or
|
|
124
|
+
* null for a whole page.
|
|
125
|
+
* @param {import('./rank.mjs').IdeaKind} kind
|
|
126
|
+
* @param {boolean} inPage whether the start is the page the idea names
|
|
127
|
+
* @returns {string | null}
|
|
128
|
+
*/
|
|
129
|
+
function placement(kind, inPage) {
|
|
130
|
+
if (kind === 'edit')
|
|
131
|
+
return 'the idea changes a page you already have, so keep it and add blocks to it; a new page starts from the app shell.';
|
|
132
|
+
if (kind === 'part')
|
|
133
|
+
return inPage
|
|
134
|
+
? 'the idea is a part of a page, so it starts from the page it names.'
|
|
135
|
+
: 'the idea is a part of a page and names no page, so it starts from the app shell.';
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
118
139
|
/**
|
|
119
140
|
* The template to start from: the ready page the ranker puts first when it
|
|
120
141
|
* has the evidence to lead, else the first fallback shell the project can
|
|
@@ -126,12 +147,13 @@ const asTemplate = t => ({
|
|
|
126
147
|
* the reason names it, so the reader knows why the kit starts elsewhere.
|
|
127
148
|
*
|
|
128
149
|
* @param {import('./rank.mjs').RankedPage[]} ranked
|
|
150
|
+
* @param {import('./rank.mjs').IdeaKind} kind
|
|
129
151
|
* @param {SearchResultEntry[]} pages
|
|
130
152
|
* @param {boolean} directMatch
|
|
131
153
|
* @param {PageTemplate[]} catalog
|
|
132
154
|
* @returns {Omit<BuildStart, 'alternatives'> | null}
|
|
133
155
|
*/
|
|
134
|
-
function chooseStart(ranked, pages, directMatch, catalog) {
|
|
156
|
+
function chooseStart(ranked, kind, pages, directMatch, catalog) {
|
|
135
157
|
const direct = directMatch ? pages[0].name : null;
|
|
136
158
|
const unready =
|
|
137
159
|
direct && !catalog.some(t => t.name === direct) ? direct : null;
|
|
@@ -139,20 +161,32 @@ function chooseStart(ranked, pages, directMatch, catalog) {
|
|
|
139
161
|
// match the ranker outweighed is named, and so are the loose page matches
|
|
140
162
|
// search listed when the kit falls back to the shell.
|
|
141
163
|
const loose = pages.map(p => `\`${p.name}\``).join(', ');
|
|
142
|
-
|
|
164
|
+
/**
|
|
165
|
+
* A part's or an edit's reason, naming a direct match that is not the start.
|
|
166
|
+
* @param {string} place
|
|
167
|
+
* @param {string} startName
|
|
168
|
+
*/
|
|
169
|
+
const placed = (place, startName) =>
|
|
170
|
+
direct && direct !== startName
|
|
171
|
+
? `Search matched \`${direct}\` by name, but ${place}`
|
|
172
|
+
: place[0].toUpperCase() + place.slice(1);
|
|
173
|
+
const pick = pickStart(ranked, kind);
|
|
143
174
|
const closest = pick && catalog.find(t => t.name === pick.name);
|
|
144
|
-
if (closest) {
|
|
175
|
+
if (pick && closest) {
|
|
145
176
|
const agrees = closest.name === direct;
|
|
177
|
+
const place = placement(kind, pick.base && pick.familyNamed);
|
|
146
178
|
return {
|
|
147
179
|
...asTemplate(closest),
|
|
148
180
|
basis: agrees ? 'direct' : 'closest',
|
|
149
|
-
reason:
|
|
150
|
-
?
|
|
151
|
-
:
|
|
152
|
-
?
|
|
153
|
-
:
|
|
154
|
-
?
|
|
155
|
-
:
|
|
181
|
+
reason: unready
|
|
182
|
+
? `\`${unready}\` matches but is not ready yet; this is the closest ready template.`
|
|
183
|
+
: place
|
|
184
|
+
? placed(place, closest.name)
|
|
185
|
+
: agrees
|
|
186
|
+
? 'Matches the idea.'
|
|
187
|
+
: direct
|
|
188
|
+
? `Search matched \`${direct}\` by name, but this template fits more of the idea.`
|
|
189
|
+
: 'The closest template; none is exactly this page.',
|
|
156
190
|
};
|
|
157
191
|
}
|
|
158
192
|
for (const id of FALLBACK_STARTS) {
|
|
@@ -161,18 +195,21 @@ function chooseStart(ranked, pages, directMatch, catalog) {
|
|
|
161
195
|
// The shell can also be the ranker's best guess without the evidence to
|
|
162
196
|
// lead ("horizontal site navigation"); say so rather than "no match".
|
|
163
197
|
const nearest = ranked[0]?.name === shell.name && ranked[0].hits > 0;
|
|
198
|
+
const place = placement(kind, false);
|
|
164
199
|
return {
|
|
165
200
|
...asTemplate(shell),
|
|
166
201
|
basis: 'fallback',
|
|
167
202
|
reason: unready
|
|
168
203
|
? `\`${unready}\` matches but is not ready yet, so start from the app shell.`
|
|
169
|
-
:
|
|
170
|
-
?
|
|
171
|
-
:
|
|
172
|
-
?
|
|
173
|
-
:
|
|
174
|
-
?
|
|
175
|
-
:
|
|
204
|
+
: place
|
|
205
|
+
? placed(place, shell.name)
|
|
206
|
+
: direct
|
|
207
|
+
? `Search matched \`${direct}\` by name, but too little of the idea fits it, so start from the app shell.`
|
|
208
|
+
: nearest
|
|
209
|
+
? 'No template is a clear match; the app shell is the closest.'
|
|
210
|
+
: loose
|
|
211
|
+
? `Search matched ${loose} only loosely, so start from the app shell.`
|
|
212
|
+
: 'No template matched, so start from the app shell.',
|
|
176
213
|
};
|
|
177
214
|
}
|
|
178
215
|
}
|
|
@@ -188,12 +225,30 @@ function chooseStart(ranked, pages, directMatch, catalog) {
|
|
|
188
225
|
*/
|
|
189
226
|
export async function buildKit(query, options = {}) {
|
|
190
227
|
const {cwd = process.cwd(), type, limit = 60} = options;
|
|
228
|
+
// A kit is built from Core's components, hooks, and templates. An open
|
|
229
|
+
// search without core covers the docs alone, so the kit asks for core here.
|
|
230
|
+
if (type !== 'doc' && !findCoreDir(cwd)) {
|
|
231
|
+
throw new AstryxError(
|
|
232
|
+
'Could not find @astryxdesign/core package',
|
|
233
|
+
undefined,
|
|
234
|
+
ERROR_CODES.ERR_CORE_NOT_FOUND,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
191
237
|
// search()'s JSDoc @returns widens results to object[]; the SearchResponse
|
|
192
238
|
// shape is the contract (api/search/search.type.mjs). Cast locally rather than
|
|
193
239
|
// tightening the search @returns (a separate follow-up).
|
|
194
240
|
const result =
|
|
195
241
|
/** @type {import('../../search/search.type.mjs').SearchResponse} */ (
|
|
196
|
-
await search(query, {
|
|
242
|
+
await search(query, {
|
|
243
|
+
cwd,
|
|
244
|
+
type,
|
|
245
|
+
// Search wider than the surfaced kit so a flood of doc matches cannot
|
|
246
|
+
// bury the page templates past the cutoff; the caller's `limit` still
|
|
247
|
+
// caps the kit below. A non-positive or non-integer limit is passed
|
|
248
|
+
// through unchanged so search rejects it (ERR_INVALID_ARGUMENT).
|
|
249
|
+
limit:
|
|
250
|
+
Number.isInteger(limit) && limit > 0 ? Math.max(limit, 200) : limit,
|
|
251
|
+
})
|
|
197
252
|
);
|
|
198
253
|
const results = result.data.results;
|
|
199
254
|
// The TOTAL number of matches, not the number that survived `limit`. The kit
|
|
@@ -257,13 +312,41 @@ export async function buildKit(query, options = {}) {
|
|
|
257
312
|
command: `${page.command} --skeleton`,
|
|
258
313
|
}));
|
|
259
314
|
|
|
315
|
+
// The caller's `limit` caps the surfaced kit, even though the search above
|
|
316
|
+
// ran wider to find templates that a flood of doc matches would otherwise
|
|
317
|
+
// bury past the cutoff. Keep pages first, then blocks, then components.
|
|
318
|
+
let budget = limit;
|
|
319
|
+
/**
|
|
320
|
+
* @template T
|
|
321
|
+
* @param {T[]} arr
|
|
322
|
+
* @returns {T[]}
|
|
323
|
+
*/
|
|
324
|
+
const toLimit = arr => {
|
|
325
|
+
const out = arr.slice(0, Math.max(0, budget));
|
|
326
|
+
budget -= out.length;
|
|
327
|
+
return out;
|
|
328
|
+
};
|
|
329
|
+
const pagesKept = toLimit(pages);
|
|
330
|
+
const blocksKept = toLimit(blocks);
|
|
331
|
+
const domainKept = toLimit(domain);
|
|
332
|
+
|
|
260
333
|
// A kit narrowed to components or hooks has no page to start from; every
|
|
261
334
|
// other kit does, so the reader is never left to compose a page from scratch.
|
|
262
335
|
const wantsPages = !type || type === 'template';
|
|
263
336
|
const catalog = wantsPages ? await loadPageTemplates(cwd) : [];
|
|
264
337
|
const ranked = wantsPages ? rankPages(query, catalog) : [];
|
|
338
|
+
// A part of a page starts where it lives (spec:AST-048/FR3); the project's
|
|
339
|
+
// own components say what a part is. The search above already gathered them
|
|
340
|
+
// unless it was narrowed to templates.
|
|
341
|
+
const kind = wantsPages
|
|
342
|
+
? ideaKind(
|
|
343
|
+
query,
|
|
344
|
+
catalog,
|
|
345
|
+
searchedComponents(result) ?? (await loadComponents(cwd)),
|
|
346
|
+
)
|
|
347
|
+
: 'page';
|
|
265
348
|
const chosen = wantsPages
|
|
266
|
-
? chooseStart(ranked, matchedPages, directMatch, catalog)
|
|
349
|
+
? chooseStart(ranked, kind, matchedPages, directMatch, catalog)
|
|
267
350
|
: null;
|
|
268
351
|
// Name the ranker's next two templates beside the start: the reader judges
|
|
269
352
|
// meaning better than keywords do, and an acceptable template is in these
|
|
@@ -288,7 +371,7 @@ export async function buildKit(query, options = {}) {
|
|
|
288
371
|
// not resolve — the same defect `getCliInvocation` exists to prevent, and
|
|
289
372
|
// the renderer applies it. A JSON caller gets the parts, not a sentence.
|
|
290
373
|
const hint =
|
|
291
|
-
|
|
374
|
+
pagesKept.length + blocksKept.length + domainKept.length < THIN_KIT
|
|
292
375
|
? {
|
|
293
376
|
reason:
|
|
294
377
|
'Few matches. This is keyword search, not semantic — try other wordings.',
|
|
@@ -306,9 +389,9 @@ export async function buildKit(query, options = {}) {
|
|
|
306
389
|
matchCount,
|
|
307
390
|
directMatch,
|
|
308
391
|
start,
|
|
309
|
-
pages,
|
|
310
|
-
blocks,
|
|
311
|
-
domain,
|
|
392
|
+
pages: pagesKept,
|
|
393
|
+
blocks: blocksKept,
|
|
394
|
+
domain: domainKept,
|
|
312
395
|
frame: FRAME,
|
|
313
396
|
foundation: FOUNDATION,
|
|
314
397
|
hint,
|
package/api/build/kit/rank.d.mts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* @typedef {import('../_adapter.mjs').PageTemplate} PageTemplate
|
|
6
|
-
* @typedef {{name: string, score: number, hits: number, familyNamed: boolean, containerMatched: boolean}} RankedPage
|
|
7
|
-
*/
|
|
8
4
|
/**
|
|
9
5
|
* Rank page templates against an idea, best first. Ties go to the template
|
|
10
6
|
* with the shorter id (the family's broader page), then by name.
|
|
@@ -14,6 +10,17 @@
|
|
|
14
10
|
* @returns {RankedPage[]}
|
|
15
11
|
*/
|
|
16
12
|
export function rankPages(query: string, pages: PageTemplate[]): RankedPage[];
|
|
13
|
+
/**
|
|
14
|
+
* What an idea asks for (spec:AST-048/FR3): a whole `page`; a `part` of one,
|
|
15
|
+
* when its head noun names one of the system's components and it lists fewer
|
|
16
|
+
* than PAGE_PIECES pieces; or an `edit` of a page the builder already has.
|
|
17
|
+
*
|
|
18
|
+
* @param {string} query
|
|
19
|
+
* @param {PageTemplate[]} pages
|
|
20
|
+
* @param {ComponentWords[]} components
|
|
21
|
+
* @returns {IdeaKind}
|
|
22
|
+
*/
|
|
23
|
+
export function ideaKind(query: string, pages: PageTemplate[], components: ComponentWords[]): IdeaKind;
|
|
17
24
|
/**
|
|
18
25
|
* The next closest templates after the start, best first: the ones a reader
|
|
19
26
|
* should check the idea against when the start's shape is wrong. Each matched
|
|
@@ -26,19 +33,28 @@ export function rankPages(query: string, pages: PageTemplate[]): RankedPage[];
|
|
|
26
33
|
*/
|
|
27
34
|
export function pickAlternatives(ranked: RankedPage[], startName: string, count?: number): RankedPage[];
|
|
28
35
|
/**
|
|
29
|
-
* The template to start from, or null
|
|
30
|
-
* evidence to lead
|
|
31
|
-
*
|
|
36
|
+
* The template to start from, or null for the kit's neutral app shell. A page
|
|
37
|
+
* needs evidence to lead: two matched terms, the idea naming the template's
|
|
38
|
+
* family, or its container. A part starts from the base template of the family
|
|
39
|
+
* the idea places it in, else from the app shell (spec:AST-048/FR3); an edit of
|
|
40
|
+
* a page the builder already has starts from the app shell (FR9). Either way,
|
|
41
|
+
* the app shell is the shell template the idea describes when one leads.
|
|
32
42
|
*
|
|
33
43
|
* @param {RankedPage[]} ranked
|
|
44
|
+
* @param {IdeaKind} [kind]
|
|
34
45
|
* @returns {RankedPage | null}
|
|
35
46
|
*/
|
|
36
|
-
export function pickStart(ranked: RankedPage[]): RankedPage | null;
|
|
47
|
+
export function pickStart(ranked: RankedPage[], kind?: IdeaKind): RankedPage | null;
|
|
37
48
|
export type PageTemplate = import("../_adapter.mjs").PageTemplate;
|
|
49
|
+
export type ComponentWords = import("../_adapter.mjs").ComponentWords;
|
|
38
50
|
export type RankedPage = {
|
|
39
51
|
name: string;
|
|
40
52
|
score: number;
|
|
41
53
|
hits: number;
|
|
42
54
|
familyNamed: boolean;
|
|
43
55
|
containerMatched: boolean;
|
|
56
|
+
family: string;
|
|
57
|
+
base: boolean;
|
|
58
|
+
matched: Set<string>;
|
|
44
59
|
};
|
|
60
|
+
export type IdeaKind = "page" | "part" | "edit";
|