@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4
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 +96 -99
- package/api/build/build.doc.mjs +1 -6
- package/api/build/build.test.mjs +0 -22
- package/api/build/kit/kit.mjs +5 -44
- package/api/component/_adapter.d.mts +0 -25
- package/api/component/_adapter.mjs +5 -59
- package/api/component/component.d.mts +3 -6
- package/api/component/component.doc.mjs +17 -37
- package/api/component/component.mjs +9 -249
- package/api/component/component.type.d.mts +0 -25
- package/api/component/component.type.mjs +0 -44
- package/api/discover/_adapter.d.mts +6 -114
- package/api/discover/_adapter.mjs +17 -372
- package/api/discover/detail/detail.d.mts +6 -18
- package/api/discover/detail/detail.mjs +13 -67
- package/api/discover/detail/detail.test.mjs +0 -85
- package/api/discover/discover.d.mts +9 -3
- package/api/discover/discover.doc.mjs +18 -61
- package/api/discover/discover.mjs +36 -220
- package/api/discover/discover.test.mjs +2 -11
- package/api/discover/discover.type.d.mts +8 -147
- package/api/discover/discover.type.mjs +12 -102
- package/api/discover/list/list.d.mts +6 -20
- package/api/discover/list/list.mjs +12 -45
- package/api/discover/list/list.test.mjs +0 -46
- package/api/discover/search/search.d.mts +16 -18
- package/api/discover/search/search.mjs +56 -102
- package/api/discover/search/search.test.mjs +10 -144
- package/api/docs/_adapter.d.mts +3 -8
- package/api/docs/_adapter.mjs +6 -14
- package/api/docs/docOverlays.test.mjs +1 -27
- package/api/docs/docs.doc.mjs +2 -2
- package/api/docs/docs.test.mjs +243 -0
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +314 -0
- package/api/doctor/doctor.d.mts +3 -8
- package/api/doctor/doctor.doc.mjs +8 -17
- package/api/doctor/doctor.mjs +9 -90
- package/api/doctor/doctor.test.mjs +10 -122
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/gap-report/gap-report.doc.mjs +10 -19
- package/api/hook/hook.doc.mjs +3 -6
- package/api/index.d.mts +2 -1
- package/api/index.mjs +5 -5
- package/api/init/init.doc.mjs +12 -17
- package/api/integration/add-helpers.d.mts +2 -5
- package/api/integration/add-helpers.mjs +9 -36
- package/api/integration/add-theme.mjs +1 -22
- package/api/integration/add-theme.test.mjs +0 -34
- package/api/integration/authoring-checks.mjs +2 -2
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/pack-check.mjs +9 -82
- package/api/integration/pack-check.test.mjs +0 -90
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/index.ts +1 -0
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/_adapter.d.mts +34 -0
- package/api/layout/_adapter.mjs +148 -0
- package/api/layout/check/check.d.mts +16 -0
- package/api/layout/check/check.mjs +40 -0
- package/api/layout/expand/expand.d.mts +22 -0
- package/api/layout/expand/expand.mjs +155 -0
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.d.mts +13 -0
- package/api/layout/grammar/grammar.mjs +87 -0
- package/api/layout/layout.d.mts +6 -0
- package/api/layout/layout.mjs +17 -0
- package/api/layout/layout.test.mjs +297 -0
- package/api/layout/layout.type.d.mts +89 -0
- package/api/layout/layout.type.mjs +103 -0
- package/api/layout/layoutCheck.doc.d.mts +11 -0
- package/api/layout/layoutCheck.doc.mjs +85 -0
- package/api/layout/layoutExpand.doc.d.mts +11 -0
- package/api/layout/layoutExpand.doc.mjs +107 -0
- package/api/layout/layoutGrammar.doc.d.mts +11 -0
- package/api/layout/layoutGrammar.doc.mjs +57 -0
- package/api/search/search.d.mts +1 -27
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +16 -228
- package/api/search/search.test.mjs +512 -0
- package/api/swizzle/swizzle.doc.mjs +5 -7
- package/api/template/copy/copy.mjs +1 -1
- package/api/template/copy/copy.test.mjs +0 -9
- package/api/template/template-integration.test.mjs +65 -1
- package/api/template/template.doc.mjs +1 -2
- package/api/template/template.mjs +1 -1
- package/api/theme/add/add.mjs +25 -17
- package/api/theme/add/add.staging.test.mjs +23 -40
- package/api/theme/build/build.family.test.mjs +12 -7
- package/api/theme/build/build.mjs +18 -8
- package/api/theme/generateTonalPalette.doc.mjs +2 -1
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +10 -9
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +1 -2
- package/api/theme/themePaletteGenerate.doc.mjs +8 -15
- package/api/theme/themeTargets.doc.mjs +2 -3
- package/api/theme/themeTemplate.doc.mjs +1 -2
- package/api/upgrade/run/run.mjs +4 -6
- package/api/upgrade/upgrade.doc.mjs +22 -24
- package/api/upgrade/upgrade.type.mjs +2 -2
- package/assets/codemods/__tests__/runner.test.mjs +1 -3
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +4 -5
- package/assets/docs/README.md +2 -4
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +2 -8
- package/assets/docs/elevation.doc.mjs +4 -6
- package/assets/docs/getting-started.doc.mjs +16 -5
- package/assets/docs/icons.doc.mjs +21 -2
- package/assets/docs/illustrations.doc.mjs +15 -7
- package/assets/docs/internationalization.doc.mjs +5 -7
- package/assets/docs/layout.doc.dense.mjs +82 -130
- package/assets/docs/layout.doc.mjs +77 -133
- package/assets/docs/migration.doc.mjs +21 -19
- package/assets/docs/motion.doc.mjs +3 -16
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +0 -8
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +3 -8
- package/assets/docs/spacing.doc.mjs +2 -7
- package/assets/docs/styling-libraries.doc.mjs +2 -6
- package/assets/docs/styling.doc.mjs +23 -19
- package/assets/docs/theme.doc.dense.mjs +18 -58
- package/assets/docs/theme.doc.mjs +46 -56
- package/assets/docs/theme.doc.zh.mjs +8 -9
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +8 -389
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/integrations.doc.mjs +451 -25
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/typography.doc.mjs +4 -24
- package/assets/docs/working-with-ai.doc.mjs +22 -30
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/authoring/config/config.doc.mjs +2 -10
- package/authoring/config/parse.d.mts +0 -2
- package/authoring/config/parse.mjs +0 -19
- package/authoring/config/parse.test.mjs +0 -8
- package/authoring/config/type.ts +2 -13
- package/authoring/doctypes/_schema.d.mts +2 -3
- package/authoring/doctypes/_schema.mjs +0 -6
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +2 -4
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +1 -1
- package/authoring/doctypes/component/component.doc.mjs +0 -6
- package/authoring/doctypes/component/type.ts +0 -8
- package/authoring/doctypes/reference/reference.doc.mjs +0 -7
- package/authoring/doctypes/reference/type.ts +0 -5
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +2 -2
- package/authoring/index.d.mts +0 -1
- package/authoring/index.d.ts +0 -10
- package/authoring/index.mjs +0 -1
- package/authoring/integration/integration.doc.mjs +10 -12
- package/clients/cli/command-result-coverage.test.mjs +7 -7
- package/clients/cli/commands/component/index.mjs +55 -152
- package/clients/cli/commands/component-ownership.test.mjs +0 -89
- package/clients/cli/commands/component.doc.mjs +9 -27
- package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
- package/clients/cli/commands/discover.doc.mjs +9 -53
- package/clients/cli/commands/discover.mjs +118 -393
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +17 -60
- package/clients/cli/commands/docs.test.mjs +294 -0
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
- package/clients/cli/commands/doctor-integration.test.mjs +0 -53
- package/clients/cli/commands/doctor.doc.mjs +1 -3
- package/clients/cli/commands/doctor.mjs +5 -49
- package/clients/cli/commands/gap-report.doc.mjs +9 -10
- package/clients/cli/commands/init.doc.mjs +6 -9
- package/clients/cli/commands/integration-add.doc.mjs +9 -9
- package/clients/cli/commands/integration-authoring.test.mjs +10 -61
- package/clients/cli/commands/integration-pack.doc.mjs +9 -5
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +43 -74
- package/clients/cli/commands/layout-check.doc.mjs +65 -0
- package/clients/cli/commands/layout-expand.doc.mjs +83 -0
- package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
- package/clients/cli/commands/layout.doc.mjs +34 -0
- package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
- package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
- package/clients/cli/commands/layout.mjs +275 -0
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +3 -10
- package/clients/cli/commands/search.mjs +2 -21
- package/clients/cli/commands/search.test.mjs +4 -21
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/text-json-parity.test.mjs +16 -5
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
- package/clients/cli/commands/theme-palette.doc.mjs +2 -1
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -2
- package/clients/cli/commands/upgrade.doc.mjs +3 -62
- package/clients/cli/index.mjs +10 -28
- package/clients/cli/lib/define-command.mjs +4 -28
- package/clients/cli/lib/define-command.test.mjs +0 -54
- package/clients/cli/lib/exit-codes.test.mjs +9 -18
- package/clients/cli/lib/json-shim.mjs +14 -24
- package/clients/cli/lib/json-shim.test.mjs +20 -6
- package/clients/cli/lib/manifest.mjs +13 -18
- package/clients/cli/lib/manifest.test.mjs +2 -5
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
- package/foundation/discovery/authoring-self-docs.mjs +0 -1
- package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
- package/foundation/discovery/cli-self-docs.mjs +2 -16
- package/foundation/discovery/cli-self-docs.test.mjs +0 -20
- package/foundation/discovery/docs-discovery.mjs +1 -5
- package/foundation/discovery/docs-discovery.test.mjs +0 -21
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
- package/foundation/doc-compiler/tree.d.mts +0 -4
- package/foundation/doc-compiler/tree.mjs +1 -6
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/integrations/cli-requirement.d.mts +6 -26
- package/foundation/integrations/cli-requirement.mjs +11 -46
- package/foundation/integrations/cli-requirement.test.mjs +2 -7
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +1 -14
- package/foundation/integrations/integrations.mjs +1 -41
- package/foundation/integrations/integrations.test.mjs +0 -31
- package/foundation/response/error-codes.doc.mjs +8 -6
- package/foundation/response/error-codes.test.mjs +5 -30
- package/foundation/response/response-types.doc.d.mts +3 -4
- package/foundation/response/response-types.doc.mjs +27 -40
- package/foundation/response/response-types.doc.test.mjs +0 -23
- package/foundation/response/response.doc.mjs +10 -11
- package/foundation/xle/browser.d.mts +3 -3
- package/foundation/xle/browser.mjs +3 -3
- package/foundation/xle/expand.mjs +2 -2
- package/foundation/xle/parse.mjs +1 -1
- package/foundation/xle/print.mjs +2 -2
- package/foundation/xle/splice.mjs +1 -1
- package/package.json +9 -9
- package/api/discover/_adapter.test.mjs +0 -215
- package/api/discover/_catalog-view.d.mts +0 -115
- package/api/discover/_catalog-view.mjs +0 -203
- package/api/discover/_catalog-view.test.mjs +0 -128
- package/api/discover/detail/item/item.d.mts +0 -26
- package/api/discover/detail/item/item.mjs +0 -78
- package/api/discover/detail/item/item.test.mjs +0 -73
- package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
- package/api/theme/add/add.rollback.test.mjs +0 -158
- package/api/theme/build/build.rollback.test.mjs +0 -148
- package/api/upgrade/run/files-changed.test.mjs +0 -111
- package/assets/codemods/file-count.test.mjs +0 -163
- package/assets/docs/tree/add-a-component.doc.mjs +0 -75
- package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
- package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
- package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
- package/assets/docs/tree/block-template.doc.mjs +0 -130
- package/assets/docs/tree/build-the-template.doc.mjs +0 -28
- package/assets/docs/tree/building-blocks.doc.mjs +0 -46
- package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
- package/assets/docs/tree/checks.doc.mjs +0 -119
- package/assets/docs/tree/codemods.doc.mjs +0 -147
- package/assets/docs/tree/component-family.doc.mjs +0 -113
- package/assets/docs/tree/component-imports.doc.mjs +0 -69
- package/assets/docs/tree/component-lookups.doc.mjs +0 -149
- package/assets/docs/tree/components.doc.mjs +0 -23
- package/assets/docs/tree/configuration.doc.mjs +0 -23
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
- package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
- package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
- package/assets/docs/tree/docs.doc.mjs +0 -21
- package/assets/docs/tree/document-the-template.doc.mjs +0 -28
- package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
- package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
- package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
- package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
- package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
- package/assets/docs/tree/help.doc.mjs +0 -16
- package/assets/docs/tree/links.doc.mjs +0 -98
- package/assets/docs/tree/package-and-test.doc.mjs +0 -32
- package/assets/docs/tree/page-template.doc.mjs +0 -71
- package/assets/docs/tree/publishing.doc.mjs +0 -111
- package/assets/docs/tree/quick-start.doc.mjs +0 -272
- package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
- package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
- package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
- package/assets/docs/tree/ship.doc.mjs +0 -16
- package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
- package/assets/docs/tree/single-component.doc.mjs +0 -165
- package/assets/docs/tree/start-a-template.doc.mjs +0 -143
- package/assets/docs/tree/subcomponent.doc.mjs +0 -115
- package/assets/docs/tree/template-assets.doc.mjs +0 -64
- package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
- package/assets/docs/tree/template-fonts.doc.mjs +0 -102
- package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
- package/assets/docs/tree/template-icons.doc.mjs +0 -97
- package/assets/docs/tree/template-images-media.doc.mjs +0 -127
- package/assets/docs/tree/template-styles.doc.mjs +0 -93
- package/assets/docs/tree/templates.doc.mjs +0 -34
- package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
- package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
- package/assets/docs/tree/themes.doc.mjs +0 -39
- package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
- package/assets/docs/tree/upgrading.doc.mjs +0 -103
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
- package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
- package/assets/docs/tree/versioning.doc.mjs +0 -161
- package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
- package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
- package/authoring/discover/discover.doc.d.mts +0 -13
- package/authoring/discover/discover.doc.mjs +0 -138
- package/authoring/discover/parse.d.mts +0 -24
- package/authoring/discover/parse.mjs +0 -128
- package/authoring/discover/parse.test.mjs +0 -124
- package/authoring/discover/type.ts +0 -87
- package/clients/cli/commands/component-batch.test.mjs +0 -341
- package/clients/cli/commands/discover.sources.test.mjs +0 -267
- package/clients/cli/commands/integration-verify.doc.mjs +0 -22
- package/clients/cli/lib/parse-error-format.test.mjs +0 -81
- package/foundation/response/batch.type.d.mts +0 -33
- package/foundation/response/batch.type.mjs +0 -34
package/api/search/search.mjs
CHANGED
|
@@ -42,18 +42,6 @@
|
|
|
42
42
|
* sentence, a near miss is usually a different word: "site" is not "side",
|
|
43
43
|
* "cable" is not "table".
|
|
44
44
|
*
|
|
45
|
-
* A multi-word query has a reserved top tier (see {@link scoreQuery}): the
|
|
46
|
-
* whole query as a candidate's name or keyword (190-200), then the whole query
|
|
47
|
-
* as a phrase inside a doc's title or one of its headings (170), then a whole
|
|
48
|
-
* title of two words or more inside the query (160-169), then a candidate that
|
|
49
|
-
* matches every word of the query, at least one of them by name or keyword
|
|
50
|
-
* (151-159). Below those sits everything else: a partial match, or every word
|
|
51
|
-
* matched only in prose or through the components a page renders. A section titled "Light/Dark Mode" answers `dark
|
|
52
|
-
* mode` better than any doc that merely names `mode` in code, however exactly;
|
|
53
|
-
* "Dark mode" answers `how do I add dark mode`; and a guide whose title and
|
|
54
|
-
* description hold both words of `troubleshoot integration` answers it better
|
|
55
|
-
* than a doc named `integration`.
|
|
56
|
-
*
|
|
57
45
|
* Description and guidance are separate tiers on purpose. A component's own
|
|
58
46
|
* one-line description saying "notification" is a claim about what it IS; the
|
|
59
47
|
* same word inside another component's best-practice advice is a passing
|
|
@@ -117,9 +105,6 @@ import {setResultCoverage} from './coverage.mjs';
|
|
|
117
105
|
* @property {string} [description]
|
|
118
106
|
* @property {string[]} [prose]
|
|
119
107
|
* @property {string[]} [guidance]
|
|
120
|
-
* @property {string[]} [titles] - A doc's title and the headings inside it:
|
|
121
|
-
* the lines a reader scans to pick it. The whole query standing in one of
|
|
122
|
-
* them, or one of them standing whole in the query, is a top-tier match.
|
|
123
108
|
* @property {string} [_import]
|
|
124
109
|
* @property {string} [_title]
|
|
125
110
|
* @property {string} [_topic] - A doc result's topic or docs-tree route.
|
|
@@ -429,120 +414,6 @@ function bestForToken(tok, candidate, opts = {}) {
|
|
|
429
414
|
return best;
|
|
430
415
|
}
|
|
431
416
|
|
|
432
|
-
/**
|
|
433
|
-
* The score of a whole-query phrase inside a doc's title or heading: a keyword
|
|
434
|
-
* substring hit (70) promoted by the same 100 as the exact tier. Below an
|
|
435
|
-
* exact name or keyword (190-200), above the token-sum path (~151 at most).
|
|
436
|
-
*/
|
|
437
|
-
const TITLE_PHRASE_SCORE = 170;
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* The score of a whole title inside a longer query, before its coverage bonus:
|
|
441
|
-
* one step below {@link TITLE_PHRASE_SCORE}. The bonus (one per query term the
|
|
442
|
-
* candidate matches, at most 9) orders the sections that share a common title,
|
|
443
|
-
* so "best practices for spacing" puts Spacing's Best Practices first.
|
|
444
|
-
*/
|
|
445
|
-
const TITLE_IN_QUERY_SCORE = 160;
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* The score of a candidate that matches every content word of a multi-word
|
|
449
|
-
* query, before a bonus of up to 8 for how strong its strongest match is: just
|
|
450
|
-
* above anything that matches only some of the words. The token-sum path tops
|
|
451
|
-
* out near 150 for a partial match (a 100 on one word, the per-word bonus, and
|
|
452
|
-
* the coverage term), so an AND-match with one keyword-strength hit (see
|
|
453
|
-
* {@link STRONG_TOKEN_SCORE}) always outranks an OR-match, and stays below the
|
|
454
|
-
* title tiers.
|
|
455
|
-
*/
|
|
456
|
-
const FULL_COVERAGE_SCORE = 151;
|
|
457
|
-
|
|
458
|
-
/**
|
|
459
|
-
* The strongest single-word hit an every-word match needs to take that tier: a
|
|
460
|
-
* keyword substring. Two passing mentions in prose, or the components a page
|
|
461
|
-
* happens to render, are breadth, not relevance; they stay on the token sum,
|
|
462
|
-
* below an exact name or keyword hit on one of the words.
|
|
463
|
-
*/
|
|
464
|
-
const STRONG_TOKEN_SCORE = 70;
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* The words of a title or query, lowercased, without punctuation or code ticks.
|
|
468
|
-
* @param {string} text
|
|
469
|
-
* @returns {string[]}
|
|
470
|
-
*/
|
|
471
|
-
function phraseWords(text) {
|
|
472
|
-
return unlinkText(text).toLowerCase().match(/[a-z0-9]+/g) ?? [];
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Whether two words are the same word, allowing a plural on either side, so
|
|
477
|
-
* `data attributes selector` still reads "Data attribute selectors".
|
|
478
|
-
* @param {string} a
|
|
479
|
-
* @param {string} b
|
|
480
|
-
*/
|
|
481
|
-
function samePhraseWord(a, b) {
|
|
482
|
-
return (
|
|
483
|
-
a === b ||
|
|
484
|
-
`${a}s` === b ||
|
|
485
|
-
`${b}s` === a ||
|
|
486
|
-
`${a}es` === b ||
|
|
487
|
-
`${b}es` === a
|
|
488
|
-
);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
/**
|
|
492
|
-
* Whether `plural` is the plural of `word`: `integrations` of `integration`,
|
|
493
|
-
* `boxes` of `box`. `es` only follows s, x, z, ch, or sh, so `notes` is not a
|
|
494
|
-
* plural of `not`.
|
|
495
|
-
* @param {string} plural
|
|
496
|
-
* @param {string} word
|
|
497
|
-
*/
|
|
498
|
-
function pluralOf(plural, word) {
|
|
499
|
-
if (word.length < 3) return false;
|
|
500
|
-
if (plural === `${word}s`) return true;
|
|
501
|
-
return /(?:s|x|z|ch|sh)$/.test(word) && plural === `${word}es`;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* The first title or heading that holds every word of the query, in order and
|
|
506
|
-
* side by side, or null.
|
|
507
|
-
* @param {string} term - Lowercased full query.
|
|
508
|
-
* @param {string[] | undefined} titles
|
|
509
|
-
* @returns {string | null}
|
|
510
|
-
*/
|
|
511
|
-
export function headingWithPhrase(term, titles) {
|
|
512
|
-
const query = phraseWords(term);
|
|
513
|
-
if (query.length < 2 || !titles) return null;
|
|
514
|
-
for (const title of titles) {
|
|
515
|
-
const words = phraseWords(String(title ?? ''));
|
|
516
|
-
for (let i = 0; i + query.length <= words.length; i++) {
|
|
517
|
-
if (query.every((word, j) => samePhraseWord(words[i + j], word)))
|
|
518
|
-
return title;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
return null;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* The first title or heading of two words or more that the query holds whole,
|
|
526
|
-
* in order and side by side, or null. A question such as "how do I add dark
|
|
527
|
-
* mode" names the "Dark mode" section outright, around words no title has.
|
|
528
|
-
* @param {string} term - Lowercased full query.
|
|
529
|
-
* @param {string[] | undefined} titles
|
|
530
|
-
* @returns {string | null}
|
|
531
|
-
*/
|
|
532
|
-
export function titleInQuery(term, titles) {
|
|
533
|
-
const query = phraseWords(term);
|
|
534
|
-
if (!titles) return null;
|
|
535
|
-
for (const title of titles) {
|
|
536
|
-
const words = phraseWords(String(title ?? ''));
|
|
537
|
-
if (words.length < 2 || words.length > query.length) continue;
|
|
538
|
-
for (let i = 0; i + words.length <= query.length; i++) {
|
|
539
|
-
if (words.every((word, j) => samePhraseWord(query[i + j], word)))
|
|
540
|
-
return title;
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
417
|
/**
|
|
547
418
|
* @param {string} term - Lowercased full query.
|
|
548
419
|
* @param {string[]} tokens - Content tokens from tokenizeQuery(term).
|
|
@@ -566,22 +437,16 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
566
437
|
// is usually a different word, not a typo.
|
|
567
438
|
const fuzzy = tokens.length <= 1;
|
|
568
439
|
const full = scoreCandidate(term, candidate, {fuzzy});
|
|
569
|
-
// A query of several words keeps its phrase tiers below even when stopwords
|
|
570
|
-
// leave one content word: "make an integration" is still the phrase an
|
|
571
|
-
// author declares as a keyword, and "build an integration" still names a
|
|
572
|
-
// title outright, though each tokenizes to `integration` alone.
|
|
573
|
-
const phrase = phraseWords(term).length >= 2;
|
|
574
440
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
441
|
+
// 0–1 content tokens: keep whole-phrase fuzzy matching (typo tolerance for
|
|
442
|
+
// single words), but if stopwords left exactly one DIFFERENT token (e.g.
|
|
443
|
+
// "pricing page" → "pricing"), score that token too and take the stronger.
|
|
444
|
+
if (tokens.length <= 1) {
|
|
579
445
|
const single =
|
|
580
446
|
tokens.length === 1 ? bestForToken(tokens[0], candidate, {fuzzy}) : null;
|
|
581
447
|
if (full && (!single || full.score >= single.score)) return asFull(full);
|
|
582
448
|
return single ? asFull(single) : null;
|
|
583
|
-
}
|
|
584
|
-
if (tokens.length <= 1 && !phrase) return fewTokens();
|
|
449
|
+
}
|
|
585
450
|
|
|
586
451
|
// The full (untokenized) query matching a candidate's name or a declared
|
|
587
452
|
// keyword VERBATIM — full.score 90 or 100, the only two scoreCandidate
|
|
@@ -598,22 +463,6 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
598
463
|
return asFull({score: full.score + 100, reason: full.reason});
|
|
599
464
|
}
|
|
600
465
|
|
|
601
|
-
// The whole query standing as a phrase in a doc's title or one of its
|
|
602
|
-
// headings is the next tier down, and still above the token-sum path. The
|
|
603
|
-
// reader named what the section is about, in order: `dark mode` is the
|
|
604
|
-
// "Light/Dark Mode" section. Without this, the title scores a keyword
|
|
605
|
-
// substring (70) and loses to a doc that happens to name `mode` exactly in
|
|
606
|
-
// a code tick (90 on one token, 98 with coverage), so API enum docs outrank
|
|
607
|
-
// the guide section.
|
|
608
|
-
const heading = headingWithPhrase(term, candidate.titles);
|
|
609
|
-
if (heading != null) {
|
|
610
|
-
return asFull({
|
|
611
|
-
score: TITLE_PHRASE_SCORE,
|
|
612
|
-
reason: `title "${heading}" holds the whole query`,
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
if (tokens.length <= 1) return fewTokens();
|
|
616
|
-
|
|
617
466
|
// Multi-word natural language: score each content token, counting only
|
|
618
467
|
// strong hits, then reward coverage so candidates matching more terms win.
|
|
619
468
|
let strongest = 0;
|
|
@@ -628,42 +477,8 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
628
477
|
hitTerms.push(tok);
|
|
629
478
|
}
|
|
630
479
|
}
|
|
631
|
-
// The reverse of the title tier, a step lower: the query holds a whole title
|
|
632
|
-
// of two words or more, so the reader asked a question around the section's
|
|
633
|
-
// name ("how do I add dark mode"). Coverage breaks ties between sections
|
|
634
|
-
// that share a title such as "Best Practices".
|
|
635
|
-
const named = titleInQuery(term, candidate.titles);
|
|
636
|
-
if (named != null) {
|
|
637
|
-
return {
|
|
638
|
-
score: TITLE_IN_QUERY_SCORE + Math.min(matched, 9),
|
|
639
|
-
reason: `the query names the title "${named}"`,
|
|
640
|
-
matched,
|
|
641
|
-
total,
|
|
642
|
-
};
|
|
643
|
-
}
|
|
644
480
|
if (matched === 0) return full ? asFull(full) : null;
|
|
645
481
|
|
|
646
|
-
const reason = `matches ${matched}/${tokens.length} terms: ${hitTerms.join(', ')}`;
|
|
647
|
-
|
|
648
|
-
// Every word matched is its own tier. Summed per word, a doc that matches
|
|
649
|
-
// both words of `troubleshoot integration` in its title and description
|
|
650
|
-
// (50 + bonus + coverage = 77) lost to thirty docs that each match
|
|
651
|
-
// `integration` alone, by name or in a code tick (98-108). The reader asked for
|
|
652
|
-
// both; a candidate that has both comes first, ordered among its peers by
|
|
653
|
-
// how strong its strongest match is. It needs one keyword-strength hit:
|
|
654
|
-
// every word mentioned in prose, or rendered by a page, is breadth, and
|
|
655
|
-
// stays on the token sum below an exact hit on one word.
|
|
656
|
-
if (matched === tokens.length && strongest >= STRONG_TOKEN_SCORE) {
|
|
657
|
-
return {
|
|
658
|
-
score:
|
|
659
|
-
FULL_COVERAGE_SCORE +
|
|
660
|
-
Math.floor((strongest - MIN_TOKEN_SCORE) / 6.25),
|
|
661
|
-
reason,
|
|
662
|
-
matched,
|
|
663
|
-
total,
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
|
|
667
482
|
// Base the score on the STRONGEST concept that matched, plus a bonus per
|
|
668
483
|
// additional matched concept and a coverage term.
|
|
669
484
|
//
|
|
@@ -685,8 +500,14 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
685
500
|
const tokenScore = Math.round(
|
|
686
501
|
strongest + Math.min(matched - 1, 3) * 12 + coverage * 15,
|
|
687
502
|
);
|
|
503
|
+
|
|
688
504
|
if (full && full.score >= tokenScore) return asFull(full);
|
|
689
|
-
return {
|
|
505
|
+
return {
|
|
506
|
+
score: tokenScore,
|
|
507
|
+
reason: `matches ${matched}/${tokens.length} terms: ${hitTerms.join(', ')}`,
|
|
508
|
+
matched,
|
|
509
|
+
total,
|
|
510
|
+
};
|
|
690
511
|
}
|
|
691
512
|
|
|
692
513
|
/**
|
|
@@ -697,8 +518,6 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
697
518
|
* @param {string} term - Lowercased search term.
|
|
698
519
|
* @param {object} candidate
|
|
699
520
|
* @param {string} candidate.name - Primary identifier (component/hook name, topic, template name).
|
|
700
|
-
* @param {string} [candidate.domain] - A component, hook, or template name
|
|
701
|
-
* also matches typed as words: `command palette` is CommandPalette.
|
|
702
521
|
* @param {string[]} [candidate.keywords] - Authored intent (componentsUsed, category words).
|
|
703
522
|
* @param {string[]} [candidate.weakKeywords] - Derived signal (components a page renders).
|
|
704
523
|
* @param {string} [candidate.description]
|
|
@@ -711,7 +530,6 @@ export function scoreCandidate(
|
|
|
711
530
|
term,
|
|
712
531
|
{
|
|
713
532
|
name,
|
|
714
|
-
domain,
|
|
715
533
|
keywords = [],
|
|
716
534
|
weakKeywords = [],
|
|
717
535
|
description = '',
|
|
@@ -734,26 +552,10 @@ export function scoreCandidate(
|
|
|
734
552
|
};
|
|
735
553
|
|
|
736
554
|
const nameLower = name.toLowerCase();
|
|
737
|
-
// A placed guide's name is its route, and the route's last segment is its
|
|
738
|
-
// name too, as a flat topic's is: `codemods` is cli/integrations/codemods.
|
|
739
|
-
const leafLower = nameLower.slice(nameLower.lastIndexOf('/') + 1);
|
|
740
555
|
|
|
741
556
|
// ── Name signals ────────────────────────────────────────────────
|
|
742
|
-
|
|
743
|
-
// guides, `tab` the `tabs` doc.
|
|
744
|
-
// A component, hook, or template name typed as words is its name:
|
|
745
|
-
// `command palette` is CommandPalette. A doc's name is a route or key,
|
|
746
|
-
// matched as written.
|
|
747
|
-
const spelled =
|
|
748
|
-
domain !== 'doc' &&
|
|
749
|
-
!/[\s_-]/.test(nameLower) &&
|
|
750
|
-
nameLower === term.replace(/\s+/g, '');
|
|
751
|
-
if (nameLower === term || leafLower === term || spelled) {
|
|
557
|
+
if (nameLower === term) {
|
|
752
558
|
consider(100, 'exact name');
|
|
753
|
-
} else if (pluralOf(nameLower, term) || pluralOf(term, nameLower)) {
|
|
754
|
-
// One point under the exact spelling, so the doc named `tokens` still
|
|
755
|
-
// outranks the Token component for `tokens`.
|
|
756
|
-
consider(99, 'plural of the name');
|
|
757
559
|
} else {
|
|
758
560
|
if (sameWord(term, nameLower)) consider(95, `name "${name}"`);
|
|
759
561
|
// The term is a word of the name, or starts one: "input" in TextInput.
|
|
@@ -1160,14 +962,11 @@ async function gatherDocs(cwd) {
|
|
|
1160
962
|
keywords: [
|
|
1161
963
|
node.route.slice(node.route.lastIndexOf('/') + 1),
|
|
1162
964
|
...(Array.isArray(selfDoc?.keywords) ? selfDoc.keywords : []),
|
|
1163
|
-
// A namespace doc's own keywords, which it declares for search.
|
|
1164
|
-
...(Array.isArray(node.keywords) ? node.keywords : []),
|
|
1165
965
|
...defined,
|
|
1166
966
|
...codeTerms({content}),
|
|
1167
967
|
],
|
|
1168
968
|
description: node.summary || '',
|
|
1169
969
|
prose: sectionProse({title: node.title, content}),
|
|
1170
|
-
titles: [node.title],
|
|
1171
970
|
_topic: node.route,
|
|
1172
971
|
_title: path.join(' › '),
|
|
1173
972
|
_command: `astryx docs ${node.route}`,
|
|
@@ -1287,16 +1086,12 @@ function topicCandidates(
|
|
|
1287
1086
|
const sections = doc?.sections ?? [];
|
|
1288
1087
|
const docTitle = path || doc?.title || title || name;
|
|
1289
1088
|
const split = sections.length > 1;
|
|
1290
|
-
// A placed guide also answers to its last route segment's words:
|
|
1291
|
-
// `quick start` is cli/integrations/quick-start.
|
|
1292
|
-
const leaf = name.slice(name.lastIndexOf('/') + 1);
|
|
1293
1089
|
/** @type {Candidate[]} */
|
|
1294
1090
|
const out = [
|
|
1295
1091
|
{
|
|
1296
1092
|
domain: 'doc',
|
|
1297
1093
|
name,
|
|
1298
1094
|
keywords: [
|
|
1299
|
-
...(leaf !== name ? [leaf.replaceAll('-', ' ')] : []),
|
|
1300
1095
|
...(doc?.title || title ? [doc?.title || title] : []),
|
|
1301
1096
|
...(Array.isArray(doc?.keywords) ? doc.keywords : []),
|
|
1302
1097
|
],
|
|
@@ -1304,11 +1099,6 @@ function topicCandidates(
|
|
|
1304
1099
|
prose: split
|
|
1305
1100
|
? sections.map(section => section.title).filter(Boolean)
|
|
1306
1101
|
: sections.flatMap(sectionProse),
|
|
1307
|
-
titles: [
|
|
1308
|
-
doc?.title || title || name,
|
|
1309
|
-
// A topic read whole answers for the headings inside it.
|
|
1310
|
-
...(split ? [] : sections.flatMap(s => [s.title, ...headings(s)])),
|
|
1311
|
-
].filter(Boolean),
|
|
1312
1102
|
_topic: name,
|
|
1313
1103
|
_title: docTitle,
|
|
1314
1104
|
_command: split ? `astryx docs ${name} --index` : `astryx docs ${name}`,
|
|
@@ -1329,7 +1119,6 @@ function topicCandidates(
|
|
|
1329
1119
|
],
|
|
1330
1120
|
description: sectionSummary(section),
|
|
1331
1121
|
prose: sectionProse(section),
|
|
1332
|
-
titles: [section.title, ...headings(section)].filter(Boolean),
|
|
1333
1122
|
_topic: name,
|
|
1334
1123
|
_section: key,
|
|
1335
1124
|
_title: `${docTitle} › ${section.title}`,
|
|
@@ -1507,11 +1296,10 @@ export async function search(query, options = {}) {
|
|
|
1507
1296
|
const tokens = tokenizeQuery(term);
|
|
1508
1297
|
|
|
1509
1298
|
// `astryx docs` reads docs without @astryxdesign/core, so a docs-only
|
|
1510
|
-
// search must too. Every other domain reads core
|
|
1511
|
-
// an error without core; an open search then covers the docs alone.
|
|
1299
|
+
// search must too. Every other domain reads core.
|
|
1512
1300
|
const docsOnly = type === 'doc';
|
|
1513
1301
|
const coreDir = docsOnly ? null : findCoreDir(cwd);
|
|
1514
|
-
if (
|
|
1302
|
+
if (!docsOnly && !coreDir) {
|
|
1515
1303
|
throw new AstryxError(
|
|
1516
1304
|
'Could not find @astryxdesign/core package',
|
|
1517
1305
|
undefined,
|
|
@@ -1521,7 +1309,7 @@ export async function search(query, options = {}) {
|
|
|
1521
1309
|
|
|
1522
1310
|
// Gather candidates from each requested domain in parallel.
|
|
1523
1311
|
/** @param {string} d */
|
|
1524
|
-
const wants = d =>
|
|
1312
|
+
const wants = d => !type || type === d;
|
|
1525
1313
|
const [components, hooks, docTopics, templates] = await Promise.all([
|
|
1526
1314
|
wants('component')
|
|
1527
1315
|
? gatherComponents(/** @type {string} */ (coreDir), cwd)
|