@shrkcrft/cli 0.1.0-alpha.29 → 0.1.0-alpha.31
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/dist/asset-preview/apply-asset-preview.js +1 -1
- package/dist/authoring/authoring-kit.d.ts +9 -1
- package/dist/authoring/authoring-kit.d.ts.map +1 -1
- package/dist/authoring/authoring-kit.js +26 -13
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts +11 -0
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts.map +1 -0
- package/dist/bootstrap/unlinked-workspace-dependency.js +99 -0
- package/dist/command-registry.d.ts +100 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +130 -3
- package/dist/commands/api-diff.command.d.ts.map +1 -1
- package/dist/commands/api-diff.command.js +12 -0
- package/dist/commands/apply.command.d.ts.map +1 -1
- package/dist/commands/apply.command.js +3 -0
- package/dist/commands/arch.command.d.ts.map +1 -1
- package/dist/commands/arch.command.js +26 -7
- package/dist/commands/architecture.command.d.ts.map +1 -1
- package/dist/commands/architecture.command.js +8 -2
- package/dist/commands/baseline.command.d.ts +76 -0
- package/dist/commands/baseline.command.d.ts.map +1 -1
- package/dist/commands/baseline.command.js +599 -75
- package/dist/commands/biome.command.d.ts.map +1 -1
- package/dist/commands/biome.command.js +20 -0
- package/dist/commands/boundaries.command.d.ts +9 -1
- package/dist/commands/boundaries.command.d.ts.map +1 -1
- package/dist/commands/boundaries.command.js +88 -20
- package/dist/commands/bundle.command.d.ts.map +1 -1
- package/dist/commands/bundle.command.js +57 -11
- package/dist/commands/cache-align.command.d.ts.map +1 -1
- package/dist/commands/cache-align.command.js +3 -1
- package/dist/commands/changelog-data.d.ts.map +1 -1
- package/dist/commands/changelog-data.js +164 -0
- package/dist/commands/changes.command.d.ts.map +1 -1
- package/dist/commands/changes.command.js +15 -0
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +1260 -324
- package/dist/commands/checks.command.d.ts.map +1 -1
- package/dist/commands/checks.command.js +188 -40
- package/dist/commands/ci.command.d.ts.map +1 -1
- package/dist/commands/ci.command.js +35 -2
- package/dist/commands/code-intel.command.d.ts.map +1 -1
- package/dist/commands/code-intel.command.js +8 -1
- package/dist/commands/command-catalog.d.ts +23 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +152 -35
- package/dist/commands/commands.command.d.ts +21 -3
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +172 -27
- package/dist/commands/compress.command.d.ts.map +1 -1
- package/dist/commands/compress.command.js +4 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +50 -12
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +40 -5
- package/dist/commands/contract-templates.command.d.ts.map +1 -1
- package/dist/commands/contract-templates.command.js +9 -1
- package/dist/commands/contract.command.d.ts.map +1 -1
- package/dist/commands/contract.command.js +35 -0
- package/dist/commands/conventions.command.d.ts.map +1 -1
- package/dist/commands/conventions.command.js +189 -29
- package/dist/commands/coverage.command.d.ts.map +1 -1
- package/dist/commands/coverage.command.js +9 -0
- package/dist/commands/daily.commands.d.ts +0 -1
- package/dist/commands/daily.commands.d.ts.map +1 -1
- package/dist/commands/daily.commands.js +12 -76
- package/dist/commands/dashboard.command.d.ts.map +1 -1
- package/dist/commands/dashboard.command.js +10 -0
- package/dist/commands/dev.command.d.ts.map +1 -1
- package/dist/commands/dev.command.js +45 -2
- package/dist/commands/diagnostics.command.d.ts +0 -2
- package/dist/commands/diagnostics.command.d.ts.map +1 -1
- package/dist/commands/diagnostics.command.js +5 -78
- package/dist/commands/diff-check.command.d.ts +6 -4
- package/dist/commands/diff-check.command.d.ts.map +1 -1
- package/dist/commands/diff-check.command.js +190 -103
- package/dist/commands/docs-references.command.d.ts +20 -0
- package/dist/commands/docs-references.command.d.ts.map +1 -0
- package/dist/commands/docs-references.command.js +520 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +60 -5
- package/dist/commands/drift.command.d.ts.map +1 -1
- package/dist/commands/drift.command.js +17 -4
- package/dist/commands/eslint.command.d.ts.map +1 -1
- package/dist/commands/eslint.command.js +20 -0
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +23 -1
- package/dist/commands/feedback-dispatch.command.d.ts.map +1 -1
- package/dist/commands/feedback-dispatch.command.js +29 -0
- package/dist/commands/feedback.command.d.ts.map +1 -1
- package/dist/commands/feedback.command.js +6 -1
- package/dist/commands/finish.command.d.ts.map +1 -1
- package/dist/commands/finish.command.js +32 -8
- package/dist/commands/fix.command.d.ts.map +1 -1
- package/dist/commands/fix.command.js +19 -0
- package/dist/commands/gate.command.d.ts +6 -1
- package/dist/commands/gate.command.d.ts.map +1 -1
- package/dist/commands/gate.command.js +50 -124
- package/dist/commands/gates.command.d.ts +54 -0
- package/dist/commands/gates.command.d.ts.map +1 -1
- package/dist/commands/gates.command.js +1314 -64
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +4 -0
- package/dist/commands/generated.command.d.ts +62 -0
- package/dist/commands/generated.command.d.ts.map +1 -1
- package/dist/commands/generated.command.js +639 -156
- package/dist/commands/graph-code-subverbs.d.ts +15 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +203 -25
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +79 -37
- package/dist/commands/help.command.d.ts +30 -6
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +323 -199
- package/dist/commands/helper.command.d.ts +1 -0
- package/dist/commands/helper.command.d.ts.map +1 -1
- package/dist/commands/helper.command.js +195 -56
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +115 -12
- package/dist/commands/infer.command.d.ts.map +1 -1
- package/dist/commands/infer.command.js +20 -45
- package/dist/commands/ingest.command.d.ts +0 -1
- package/dist/commands/ingest.command.d.ts.map +1 -1
- package/dist/commands/ingest.command.js +25 -41
- package/dist/commands/knowledge-author.command.d.ts +0 -3
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +10 -23
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +469 -129
- package/dist/commands/languages.command.d.ts.map +1 -1
- package/dist/commands/languages.command.js +27 -0
- package/dist/commands/lint.command.d.ts.map +1 -1
- package/dist/commands/lint.command.js +3 -0
- package/dist/commands/mcp.command.d.ts +18 -0
- package/dist/commands/mcp.command.d.ts.map +1 -1
- package/dist/commands/mcp.command.js +33 -8
- package/dist/commands/onboard.command.d.ts.map +1 -1
- package/dist/commands/onboard.command.js +20 -0
- package/dist/commands/owners.command.d.ts.map +1 -1
- package/dist/commands/owners.command.js +14 -2
- package/dist/commands/packs-new.d.ts +13 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +500 -335
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +378 -36
- package/dist/commands/paths.command.d.ts.map +1 -1
- package/dist/commands/paths.command.js +9 -1
- package/dist/commands/pipelines.command.d.ts.map +1 -1
- package/dist/commands/pipelines.command.js +7 -1
- package/dist/commands/plan-check.command.d.ts.map +1 -1
- package/dist/commands/plan-check.command.js +3 -0
- package/dist/commands/plan.command.d.ts.map +1 -1
- package/dist/commands/plan.command.js +3 -0
- package/dist/commands/playbooks.command.d.ts.map +1 -1
- package/dist/commands/playbooks.command.js +7 -2
- package/dist/commands/policy-lint.command.d.ts +19 -2
- package/dist/commands/policy-lint.command.d.ts.map +1 -1
- package/dist/commands/policy-lint.command.js +224 -65
- package/dist/commands/policy.command.d.ts.map +1 -1
- package/dist/commands/policy.command.js +6 -1
- package/dist/commands/pr.command.d.ts.map +1 -1
- package/dist/commands/pr.command.js +14 -0
- package/dist/commands/presets.command.d.ts.map +1 -1
- package/dist/commands/presets.command.js +12 -27
- package/dist/commands/profiles.command.d.ts.map +1 -1
- package/dist/commands/profiles.command.js +94 -26
- package/dist/commands/provenance.command.js +1 -1
- package/dist/commands/quality.command.d.ts.map +1 -1
- package/dist/commands/quality.command.js +129 -33
- package/dist/commands/recommend.command.d.ts +20 -4
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +172 -278
- package/dist/commands/registrations.command.d.ts.map +1 -1
- package/dist/commands/registrations.command.js +138 -13
- package/dist/commands/registry-lifecycle-run.d.ts +14 -0
- package/dist/commands/registry-lifecycle-run.d.ts.map +1 -0
- package/dist/commands/registry-lifecycle-run.js +336 -0
- package/dist/commands/registry.command.d.ts.map +1 -1
- package/dist/commands/registry.command.js +235 -62
- package/dist/commands/release.command.d.ts.map +1 -1
- package/dist/commands/release.command.js +99 -20
- package/dist/commands/report.command.d.ts.map +1 -1
- package/dist/commands/report.command.js +38 -2
- package/dist/commands/reuse-coverage.command.d.ts +23 -0
- package/dist/commands/reuse-coverage.command.d.ts.map +1 -0
- package/dist/commands/reuse-coverage.command.js +536 -0
- package/dist/commands/reuse.command.d.ts +3 -18
- package/dist/commands/reuse.command.d.ts.map +1 -1
- package/dist/commands/reuse.command.js +395 -244
- package/dist/commands/review.command.d.ts.map +1 -1
- package/dist/commands/review.command.js +33 -1
- package/dist/commands/rounds.command.d.ts.map +1 -1
- package/dist/commands/rounds.command.js +5 -0
- package/dist/commands/safety.command.d.ts.map +1 -1
- package/dist/commands/safety.command.js +9 -0
- package/dist/commands/scaffolds.command.d.ts.map +1 -1
- package/dist/commands/scaffolds.command.js +97 -25
- package/dist/commands/search.command.d.ts +0 -8
- package/dist/commands/search.command.d.ts.map +1 -1
- package/dist/commands/search.command.js +136 -28
- package/dist/commands/self-config-xrefs.command.d.ts +24 -0
- package/dist/commands/self-config-xrefs.command.d.ts.map +1 -0
- package/dist/commands/self-config-xrefs.command.js +170 -0
- package/dist/commands/self-config.command.d.ts.map +1 -1
- package/dist/commands/self-config.command.js +261 -65
- package/dist/commands/smart-context.command.d.ts.map +1 -1
- package/dist/commands/smart-context.command.js +39 -3
- package/dist/commands/spec.command.d.ts.map +1 -1
- package/dist/commands/spec.command.js +3 -0
- package/dist/commands/stats.command.d.ts.map +1 -1
- package/dist/commands/stats.command.js +3 -0
- package/dist/commands/surface.command.d.ts +6 -1
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +256 -54
- package/dist/commands/task-context.command.js +1 -1
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +22 -1
- package/dist/commands/templates.command.d.ts +4 -0
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +109 -22
- package/dist/commands/test.command.d.ts.map +1 -1
- package/dist/commands/test.command.js +161 -33
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +29 -3
- package/dist/commands/trace.command.d.ts.map +1 -1
- package/dist/commands/trace.command.js +29 -4
- package/dist/commands/watch.command.d.ts.map +1 -1
- package/dist/commands/watch.command.js +3 -0
- package/dist/commands/why.command.d.ts.map +1 -1
- package/dist/commands/why.command.js +3 -0
- package/dist/commands/wiring.command.d.ts +18 -4
- package/dist/commands/wiring.command.d.ts.map +1 -1
- package/dist/commands/wiring.command.js +362 -74
- package/dist/dashboard/code-intelligence-data.js +4 -4
- package/dist/diff/deleted-orphan-coverage.d.ts +32 -0
- package/dist/diff/deleted-orphan-coverage.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-coverage.js +107 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts +23 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-scope-notes.js +49 -0
- package/dist/diff/deleted-orphans.d.ts +32 -0
- package/dist/diff/deleted-orphans.d.ts.map +1 -1
- package/dist/diff/deleted-orphans.js +42 -2
- package/dist/dispatch/closest-match.d.ts +15 -0
- package/dist/dispatch/closest-match.d.ts.map +1 -0
- package/dist/dispatch/closest-match.js +47 -0
- package/dist/dispatch/global-flags.d.ts +94 -0
- package/dist/dispatch/global-flags.d.ts.map +1 -0
- package/dist/dispatch/global-flags.js +123 -0
- package/dist/dispatch/guard-invocation-input.d.ts +24 -0
- package/dist/dispatch/guard-invocation-input.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation-input.js +1 -0
- package/dist/dispatch/guard-invocation.d.ts +33 -0
- package/dist/dispatch/guard-invocation.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation.js +183 -0
- package/dist/dispatch/help-intercept.d.ts +22 -0
- package/dist/dispatch/help-intercept.d.ts.map +1 -0
- package/dist/dispatch/help-intercept.js +42 -0
- package/dist/dispatch/i-declared-invocation.d.ts +17 -0
- package/dist/dispatch/i-declared-invocation.d.ts.map +1 -0
- package/dist/dispatch/i-declared-invocation.js +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts +28 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts.map +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.js +1 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts +15 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection-kind.js +15 -0
- package/dist/dispatch/invocation-rejection.d.ts +18 -0
- package/dist/dispatch/invocation-rejection.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection.js +1 -0
- package/dist/dispatch/judge-invocation.d.ts +24 -0
- package/dist/dispatch/judge-invocation.d.ts.map +1 -0
- package/dist/dispatch/judge-invocation.js +50 -0
- package/dist/dispatch/positional-mode.d.ts +18 -0
- package/dist/dispatch/positional-mode.d.ts.map +1 -0
- package/dist/dispatch/positional-mode.js +18 -0
- package/dist/dispatch/read-tracking-map.d.ts +28 -0
- package/dist/dispatch/read-tracking-map.d.ts.map +1 -0
- package/dist/dispatch/read-tracking-map.js +58 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts +30 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts.map +1 -0
- package/dist/dispatch/refuse-sibling-valve-flags.js +65 -0
- package/dist/dispatch/subverb-spec.d.ts +26 -0
- package/dist/dispatch/subverb-spec.d.ts.map +1 -0
- package/dist/dispatch/subverb-spec.js +1 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts +22 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts.map +1 -0
- package/dist/dispatch/undocumented-flag-reads.js +283 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts +13 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal-mode.js +13 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts +22 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal.js +57 -0
- package/dist/dispatch/unread-flags.d.ts +152 -0
- package/dist/dispatch/unread-flags.d.ts.map +1 -0
- package/dist/dispatch/unread-flags.js +295 -0
- package/dist/dispatch/verdict-valve-flag.d.ts +21 -0
- package/dist/dispatch/verdict-valve-flag.d.ts.map +1 -0
- package/dist/dispatch/verdict-valve-flag.js +21 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts +14 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts.map +1 -0
- package/dist/dispatch/walk-declared-subverbs.js +28 -0
- package/dist/exit-codes.d.ts +41 -3
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +153 -14
- package/dist/finish/run-finish.d.ts +72 -5
- package/dist/finish/run-finish.d.ts.map +1 -1
- package/dist/finish/run-finish.js +453 -104
- package/dist/gates/accepted-empty-note.d.ts +10 -0
- package/dist/gates/accepted-empty-note.d.ts.map +1 -0
- package/dist/gates/accepted-empty-note.js +11 -0
- package/dist/gates/allow-empty.d.ts +25 -0
- package/dist/gates/allow-empty.d.ts.map +1 -0
- package/dist/gates/allow-empty.js +27 -0
- package/dist/gates/asset-doctor-failing-units.d.ts +16 -0
- package/dist/gates/asset-doctor-failing-units.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failing-units.js +14 -0
- package/dist/gates/asset-doctor-failure-line.d.ts +16 -0
- package/dist/gates/asset-doctor-failure-line.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failure-line.js +28 -0
- package/dist/gates/empty-rule-advice-lines.d.ts +15 -0
- package/dist/gates/empty-rule-advice-lines.d.ts.map +1 -0
- package/dist/gates/empty-rule-advice-lines.js +20 -0
- package/dist/gates/gate-envelope.d.ts +85 -8
- package/dist/gates/gate-envelope.d.ts.map +1 -1
- package/dist/gates/gate-envelope.js +56 -7
- package/dist/gates/gate-rule-globs.d.ts +67 -0
- package/dist/gates/gate-rule-globs.d.ts.map +1 -0
- package/dist/gates/gate-rule-globs.js +139 -0
- package/dist/gates/gate-rule-view.d.ts +25 -6
- package/dist/gates/gate-rule-view.d.ts.map +1 -1
- package/dist/gates/gate-rule-view.js +105 -77
- package/dist/gates/i-coverage-dead-glob.d.ts +19 -0
- package/dist/gates/i-coverage-dead-glob.d.ts.map +1 -0
- package/dist/gates/i-coverage-dead-glob.js +1 -0
- package/dist/gates/i-coverage-negation.d.ts +13 -0
- package/dist/gates/i-coverage-negation.d.ts.map +1 -0
- package/dist/gates/i-coverage-negation.js +1 -0
- package/dist/gates/i-registration-query-settle-input.d.ts +18 -0
- package/dist/gates/i-registration-query-settle-input.d.ts.map +1 -0
- package/dist/gates/i-registration-query-settle-input.js +1 -0
- package/dist/gates/i-unit-state-note-row.d.ts +16 -0
- package/dist/gates/i-unit-state-note-row.d.ts.map +1 -0
- package/dist/gates/i-unit-state-note-row.js +1 -0
- package/dist/gates/i-unit-state-notes.d.ts +32 -0
- package/dist/gates/i-unit-state-notes.d.ts.map +1 -0
- package/dist/gates/i-unit-state-notes.js +1 -0
- package/dist/gates/incomplete-registry-inventory.d.ts +19 -0
- package/dist/gates/incomplete-registry-inventory.d.ts.map +1 -0
- package/dist/gates/incomplete-registry-inventory.js +63 -0
- package/dist/gates/measure-registration-roles.d.ts +10 -0
- package/dist/gates/measure-registration-roles.d.ts.map +1 -0
- package/dist/gates/measure-registration-roles.js +9 -0
- package/dist/gates/plane-verdict.d.ts +14 -0
- package/dist/gates/plane-verdict.d.ts.map +1 -0
- package/dist/gates/plane-verdict.js +22 -0
- package/dist/gates/qualify-clean-for-units.d.ts +12 -0
- package/dist/gates/qualify-clean-for-units.d.ts.map +1 -0
- package/dist/gates/qualify-clean-for-units.js +18 -0
- package/dist/gates/registration-graph-verdict.d.ts +34 -0
- package/dist/gates/registration-graph-verdict.d.ts.map +1 -0
- package/dist/gates/registration-graph-verdict.js +70 -0
- package/dist/gates/registration-roles.d.ts +9 -0
- package/dist/gates/registration-roles.d.ts.map +1 -0
- package/dist/gates/registration-roles.js +1 -0
- package/dist/gates/registry-liveness.d.ts +11 -0
- package/dist/gates/registry-liveness.d.ts.map +1 -0
- package/dist/gates/registry-liveness.js +13 -0
- package/dist/gates/rule-coverage.d.ts +225 -4
- package/dist/gates/rule-coverage.d.ts.map +1 -1
- package/dist/gates/rule-coverage.js +610 -43
- package/dist/gates/run-gate-planes.d.ts +58 -0
- package/dist/gates/run-gate-planes.d.ts.map +1 -0
- package/dist/gates/run-gate-planes.js +403 -0
- package/dist/gates/scaffold-selftest.d.ts +56 -0
- package/dist/gates/scaffold-selftest.d.ts.map +1 -0
- package/dist/gates/scaffold-selftest.js +119 -0
- package/dist/gates/seam-rejected-rules.d.ts +28 -0
- package/dist/gates/seam-rejected-rules.d.ts.map +1 -0
- package/dist/gates/seam-rejected-rules.js +95 -0
- package/dist/gates/self-test-check.d.ts +29 -0
- package/dist/gates/self-test-check.d.ts.map +1 -0
- package/dist/gates/self-test-check.js +1 -0
- package/dist/gates/self-test-subject.d.ts +28 -0
- package/dist/gates/self-test-subject.d.ts.map +1 -0
- package/dist/gates/self-test-subject.js +1 -0
- package/dist/gates/self-test.d.ts +20 -0
- package/dist/gates/self-test.d.ts.map +1 -0
- package/dist/gates/self-test.js +82 -0
- package/dist/gates/settle-verdict.d.ts +14 -0
- package/dist/gates/settle-verdict.d.ts.map +1 -0
- package/dist/gates/settle-verdict.js +13 -0
- package/dist/gates/settled-verdict.d.ts +8 -0
- package/dist/gates/settled-verdict.d.ts.map +1 -0
- package/dist/gates/settled-verdict.js +1 -0
- package/dist/gates/template-registry-coverage.d.ts +18 -0
- package/dist/gates/template-registry-coverage.d.ts.map +1 -0
- package/dist/gates/template-registry-coverage.js +24 -0
- package/dist/gates/unit-state-notes.d.ts +40 -0
- package/dist/gates/unit-state-notes.d.ts.map +1 -0
- package/dist/gates/unit-state-notes.js +71 -0
- package/dist/gates/verdict-line.d.ts +18 -0
- package/dist/gates/verdict-line.d.ts.map +1 -0
- package/dist/gates/verdict-line.js +40 -0
- package/dist/graph/graph-reuse-lookup.d.ts +10 -0
- package/dist/graph/graph-reuse-lookup.d.ts.map +1 -0
- package/dist/graph/graph-reuse-lookup.js +41 -0
- package/dist/graph/index-behind-hint.d.ts +11 -0
- package/dist/graph/index-behind-hint.d.ts.map +1 -0
- package/dist/graph/index-behind-hint.js +27 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-flags.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.js +1 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts +10 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate.js +9 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +204 -83
- package/dist/output/failure-hints.d.ts.map +1 -1
- package/dist/output/failure-hints.js +11 -9
- package/dist/output/rejected-entries-note.d.ts +57 -0
- package/dist/output/rejected-entries-note.d.ts.map +1 -0
- package/dist/output/rejected-entries-note.js +103 -0
- package/dist/output/stdout-is-pipe.d.ts +13 -0
- package/dist/output/stdout-is-pipe.d.ts.map +1 -0
- package/dist/output/stdout-is-pipe.js +21 -0
- package/dist/packs/stale-build-warning.d.ts +11 -0
- package/dist/packs/stale-build-warning.d.ts.map +1 -0
- package/dist/packs/stale-build-warning.js +23 -0
- package/dist/quality/run-quality.d.ts +123 -0
- package/dist/quality/run-quality.d.ts.map +1 -0
- package/dist/quality/run-quality.js +442 -0
- package/dist/schemas/json-schemas.d.ts +184 -3
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +113 -2
- package/dist/shrk.d.ts +3 -0
- package/dist/shrk.d.ts.map +1 -0
- package/dist/shrk.js +30 -0
- package/dist/surface/audience-applicability.d.ts +26 -0
- package/dist/surface/audience-applicability.d.ts.map +1 -0
- package/dist/surface/audience-applicability.js +60 -0
- package/dist/surface/catalog-command-safety.d.ts +18 -0
- package/dist/surface/catalog-command-safety.d.ts.map +1 -0
- package/dist/surface/catalog-command-safety.js +62 -0
- package/dist/surface/cli-command-resolver.d.ts +21 -0
- package/dist/surface/cli-command-resolver.d.ts.map +1 -0
- package/dist/surface/cli-command-resolver.js +87 -0
- package/dist/surface/command-dispatch-kind.d.ts +20 -0
- package/dist/surface/command-dispatch-kind.d.ts.map +1 -0
- package/dist/surface/command-dispatch-kind.js +20 -0
- package/dist/surface/command-index-entry.d.ts +40 -0
- package/dist/surface/command-index-entry.d.ts.map +1 -0
- package/dist/surface/command-index-entry.js +1 -0
- package/dist/surface/command-index.d.ts +77 -0
- package/dist/surface/command-index.d.ts.map +1 -0
- package/dist/surface/command-index.js +323 -0
- package/dist/surface/i-command-index.d.ts +22 -0
- package/dist/surface/i-command-index.d.ts.map +1 -0
- package/dist/surface/i-command-index.js +1 -0
- package/dist/surface/i-command-string-context.d.ts +20 -0
- package/dist/surface/i-command-string-context.d.ts.map +1 -0
- package/dist/surface/i-command-string-context.js +1 -0
- package/dist/surface/i-surface-denial.d.ts +13 -0
- package/dist/surface/i-surface-denial.d.ts.map +1 -0
- package/dist/surface/i-surface-denial.js +1 -0
- package/dist/surface/load-surface-context.d.ts +17 -1
- package/dist/surface/load-surface-context.d.ts.map +1 -1
- package/dist/surface/load-surface-context.js +48 -10
- package/dist/surface/not-enabled-error.d.ts +38 -4
- package/dist/surface/not-enabled-error.d.ts.map +1 -1
- package/dist/surface/not-enabled-error.js +96 -6
- package/dist/surface/profiles.d.ts +7 -0
- package/dist/surface/profiles.d.ts.map +1 -1
- package/dist/surface/resolve-command-string.d.ts +10 -0
- package/dist/surface/resolve-command-string.d.ts.map +1 -0
- package/dist/surface/resolve-command-string.js +572 -0
- package/dist/surface/surface-config-writer.d.ts +7 -2
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +25 -6
- package/dist/surface/surface-layer.d.ts +11 -0
- package/dist/surface/surface-layer.d.ts.map +1 -0
- package/dist/surface/surface-layer.js +11 -0
- package/dist/surface/surface-refusal-reason.d.ts +16 -0
- package/dist/surface/surface-refusal-reason.d.ts.map +1 -0
- package/dist/surface/surface-refusal-reason.js +16 -0
- package/dist/surface/surface-selector.d.ts +26 -0
- package/dist/surface/surface-selector.d.ts.map +1 -0
- package/dist/surface/surface-selector.js +42 -0
- package/dist/surface/surface-summary.d.ts +61 -18
- package/dist/surface/surface-summary.d.ts.map +1 -1
- package/dist/surface/surface-summary.js +147 -60
- package/dist/surface/tier.d.ts +85 -22
- package/dist/surface/tier.d.ts.map +1 -1
- package/dist/surface/tier.js +132 -30
- package/dist/usage/usage-log.d.ts +6 -1
- package/dist/usage/usage-log.d.ts.map +1 -1
- package/dist/usage/usage-log.js +7 -2
- package/dist/validation/run-validation-loop.d.ts +9 -0
- package/dist/validation/run-validation-loop.d.ts.map +1 -1
- package/dist/validation/run-validation-loop.js +14 -11
- package/dist/validation/typecheck-emitted.d.ts +8 -9
- package/dist/validation/typecheck-emitted.d.ts.map +1 -1
- package/dist/validation/typecheck-emitted.js +17 -97
- package/package.json +34 -34
|
@@ -1,97 +1,59 @@
|
|
|
1
1
|
import { GraphStore, GraphQueryApi } from '@shrkcrft/graph';
|
|
2
|
-
import { resolveProjectConfig } from '@shrkcrft/inspector';
|
|
2
|
+
import { curatedDeclarationMap, rankReuseCandidates, resolveCuratedReuse, resolveProjectConfig, reuseImportLine, } from '@shrkcrft/inspector';
|
|
3
|
+
import { MatchConfidenceVerdict, ReuseCandidateSource, ReuseImportStyle, ReuseMatchSource, ReuseNameMatch, UnfollowedReExportKind, } from '@shrkcrft/core';
|
|
3
4
|
import { flagBool, flagNumber, resolveCwd, } from "../command-registry.js";
|
|
5
|
+
import { PositionalMode } from "../dispatch/positional-mode.js";
|
|
6
|
+
import { ExitCode } from "../exit-codes.js";
|
|
7
|
+
import { graphReuseLookup } from "../graph/graph-reuse-lookup.js";
|
|
8
|
+
import { indexBehindHint } from "../graph/index-behind-hint.js";
|
|
4
9
|
import { asJson, header } from "../output/format-output.js";
|
|
5
|
-
const STOP = new Set([
|
|
6
|
-
'the', 'a', 'an', 'to', 'for', 'of', 'and', 'or', 'with', 'in', 'on', 'into', 'my',
|
|
7
|
-
'add', 'use', 'using', 'create', 'make', 'new', 'build', 'want', 'need', 'how', 'do',
|
|
8
|
-
]);
|
|
9
|
-
function tokenize(s) {
|
|
10
|
-
// Min length 3: 2-char tokens (`ui`, `id`) substring-match unrelated text
|
|
11
|
-
// (`guidance`, `valid`) and produce false-positive primitive matches.
|
|
12
|
-
return [
|
|
13
|
-
...new Set(s
|
|
14
|
-
.toLowerCase()
|
|
15
|
-
.replace(/[^a-z0-9]+/g, ' ')
|
|
16
|
-
.split(' ')
|
|
17
|
-
.filter((t) => t.length >= 3 && !STOP.has(t))),
|
|
18
|
-
];
|
|
19
|
-
}
|
|
20
|
-
function scorePrimitive(p, tokens) {
|
|
21
|
-
// Substring match (so intent "debounce" matches symbol `useDebounce`); the
|
|
22
|
-
// 3-char minimum above keeps it from over-matching on tiny fragments.
|
|
23
|
-
const symbolLower = p.symbol.toLowerCase();
|
|
24
|
-
const hay = [p.symbol, ...(p.roles ?? []), ...(p.keywords ?? []), p.description ?? '']
|
|
25
|
-
.join(' ')
|
|
26
|
-
.toLowerCase();
|
|
27
|
-
let s = 0;
|
|
28
|
-
const matched = [];
|
|
29
|
-
let symbolHit = false;
|
|
30
|
-
for (const t of tokens) {
|
|
31
|
-
if (hay.includes(t)) {
|
|
32
|
-
s += 1;
|
|
33
|
-
matched.push(t);
|
|
34
|
-
if (symbolLower.includes(t))
|
|
35
|
-
symbolHit = true;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// A role the intent mentions is a strong signal; re-weight role hits.
|
|
39
|
-
for (const role of p.roles ?? []) {
|
|
40
|
-
const rl = role.toLowerCase();
|
|
41
|
-
if (rl.length >= 3 && tokens.some((t) => rl.includes(t)))
|
|
42
|
-
s += 0.5;
|
|
43
|
-
}
|
|
44
|
-
return { score: s, matched, symbolHit };
|
|
45
|
-
}
|
|
46
10
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* the query was a single token and that token hit. A single generic keyword hit on
|
|
50
|
-
* a multi-token intent (the "nearest collision on an unrelated entry" failure mode)
|
|
51
|
-
* is a weak match — surfaced as a did-you-mean, never as a confident answer.
|
|
11
|
+
* The did-you-mean ranker. The engine lives in `@shrkcrft/inspector` (pure, so
|
|
12
|
+
* a read-only MCP tool can call it); re-exported here for existing importers.
|
|
52
13
|
*/
|
|
53
|
-
|
|
54
|
-
if (detail.matched.length === 0)
|
|
55
|
-
return false;
|
|
56
|
-
if (detail.symbolHit)
|
|
57
|
-
return true;
|
|
58
|
-
if (detail.matched.length >= 2)
|
|
59
|
-
return true;
|
|
60
|
-
return queryTokenCount <= 1;
|
|
61
|
-
}
|
|
14
|
+
export { rankReuseSuggestions } from '@shrkcrft/inspector';
|
|
62
15
|
const INDEX_RE = /(^|\/)index\.[cm]?[jt]sx?$/;
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
16
|
+
/** Whether the uncurated public export surface was consulted, and how much of it. */
|
|
17
|
+
var ExportSurfaceStatus;
|
|
18
|
+
(function (ExportSurfaceStatus) {
|
|
19
|
+
/** Every workspace package root was walked in full. */
|
|
20
|
+
ExportSurfaceStatus["Searched"] = "searched";
|
|
21
|
+
/**
|
|
22
|
+
* Searched, but part of the surface could not be walked — a package with no
|
|
23
|
+
* resolved entry, or a local re-export the index could not follow. `reason`
|
|
24
|
+
* says which; the unwalked part is listed.
|
|
25
|
+
*/
|
|
26
|
+
ExportSurfaceStatus["Partial"] = "partial";
|
|
27
|
+
/** Nothing was searched: no graph index, or no package entry to start from. */
|
|
28
|
+
ExportSurfaceStatus["NotSearched"] = "not-searched";
|
|
29
|
+
/** `--curated-only`. */
|
|
30
|
+
ExportSurfaceStatus["Disabled"] = "disabled";
|
|
31
|
+
})(ExportSurfaceStatus || (ExportSurfaceStatus = {}));
|
|
32
|
+
const SOURCE_WORD = {
|
|
33
|
+
[ReuseMatchSource.Symbol]: 'name',
|
|
34
|
+
[ReuseMatchSource.Role]: 'roles',
|
|
35
|
+
[ReuseMatchSource.Keyword]: 'keywords',
|
|
36
|
+
[ReuseMatchSource.Description]: 'description',
|
|
37
|
+
};
|
|
38
|
+
const NAME_MATCH_WORDS = {
|
|
39
|
+
[ReuseNameMatch.Exact]: 'exact name match',
|
|
40
|
+
[ReuseNameMatch.Covers]: 'name covers the intent',
|
|
41
|
+
[ReuseNameMatch.Partial]: 'partial name match',
|
|
42
|
+
[ReuseNameMatch.None]: 'no name match',
|
|
43
|
+
};
|
|
86
44
|
export const reuseCommand = {
|
|
87
45
|
name: 'reuse',
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
46
|
+
// The positionals are the free-form intent (`coverage` is a trie child).
|
|
47
|
+
positionals: PositionalMode.Free,
|
|
48
|
+
description: 'Intent → the canonical primitive to reuse. Ranks configured reusePrimitives[] AND (with a code graph) the uncurated public export surface of every workspace package — an exactly-named exported construct outranks a curated entry that names only part of the intent or matched only through its metadata, and is labelled uncurated. Resolves each answer to its declaration, public import path (a default import for a default export), sibling exports and real consumer files. `shrk reuse coverage` measures curation drift. Deterministic; no AI.',
|
|
49
|
+
usage: 'shrk reuse "<what I want to build>" [--limit N] [--all] [--curated-only] [--include-types] [--json] · shrk reuse coverage',
|
|
50
|
+
booleanFlags: new Set(['json', 'all', 'curated-only', 'include-types']),
|
|
91
51
|
async run(args) {
|
|
92
52
|
const cwd = resolveCwd(args);
|
|
93
53
|
const wantJson = flagBool(args, 'json');
|
|
94
54
|
const wantAll = flagBool(args, 'all');
|
|
55
|
+
const curatedOnly = flagBool(args, 'curated-only');
|
|
56
|
+
const includeTypes = flagBool(args, 'include-types');
|
|
95
57
|
// `--limit N` caps both the confident results (historic default 3) and the
|
|
96
58
|
// did-you-mean suggestion list. When omitted, suggestions default to 5 (a
|
|
97
59
|
// couple more than results — the point of a did-you-mean is a short menu).
|
|
@@ -100,8 +62,8 @@ export const reuseCommand = {
|
|
|
100
62
|
const suggestK = limitFlag ?? 5;
|
|
101
63
|
const intent = args.positional.join(' ').trim();
|
|
102
64
|
if (!intent) {
|
|
103
|
-
process.stderr.write('Usage: shrk reuse "<what I want to build>" [--limit N] [--all] [--json]\n');
|
|
104
|
-
return
|
|
65
|
+
process.stderr.write('Usage: shrk reuse "<what I want to build>" [--limit N] [--all] [--curated-only] [--include-types] [--json]\n');
|
|
66
|
+
return ExitCode.UsageError;
|
|
105
67
|
}
|
|
106
68
|
const loaded = await resolveProjectConfig(cwd);
|
|
107
69
|
if (!loaded.ok) {
|
|
@@ -124,193 +86,180 @@ export const reuseCommand = {
|
|
|
124
86
|
for (const d of planeDiagnostics)
|
|
125
87
|
process.stdout.write(` ! ${d}\n`);
|
|
126
88
|
};
|
|
127
|
-
if (primitives.length === 0) {
|
|
128
|
-
if (wantJson) {
|
|
129
|
-
process.stdout.write(asJson({ schema: 'sharkcraft.reuse/v1', intent, results: [], ...planeJson }) + '\n');
|
|
130
|
-
return 0;
|
|
131
|
-
}
|
|
132
|
-
process.stdout.write(header(`Reuse: "${intent}"`));
|
|
133
|
-
process.stdout.write(' No reuse primitives configured. Declare `reusePrimitives[]` in sharkcraft.config.ts\n' +
|
|
134
|
-
' to map roles/intents to canonical symbols (see docs/reuse.md).\n');
|
|
135
|
-
writePlaneNotes();
|
|
136
|
-
return 0;
|
|
137
|
-
}
|
|
138
|
-
const tokens = tokenize(intent);
|
|
139
|
-
const confidenceOf = (matched) => tokens.length === 0 ? 0 : matched / tokens.length;
|
|
140
|
-
const scored = primitives
|
|
141
|
-
.map((p) => ({ p, detail: scorePrimitive(p, tokens) }))
|
|
142
|
-
.filter((x) => x.detail.score > 0)
|
|
143
|
-
.sort((a, b) => b.detail.score - a.detail.score || a.p.symbol.localeCompare(b.p.symbol));
|
|
144
|
-
const confident = scored.filter((x) => isConfidentMatch(x.detail, tokens.length));
|
|
145
|
-
const ranked = confident.slice(0, Math.max(1, limit));
|
|
146
89
|
const store = new GraphStore(cwd);
|
|
147
90
|
const api = store.exists() ? GraphQueryApi.fromStore(cwd) : null;
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
91
|
+
// The public surface, whenever a graph exists: the uncurated candidates
|
|
92
|
+
// (unless --curated-only), AND — always — how a curated `importPath`
|
|
93
|
+
// exports its symbol, so the printed import line compiles. Lazy + memoized.
|
|
94
|
+
const fullSurface = api ? api.publicExportSurface() : undefined;
|
|
95
|
+
const lookup = api ? graphReuseLookup(api) : undefined;
|
|
96
|
+
// ONE resolution per curated entry — the record `shrk reuse coverage` judges
|
|
97
|
+
// the entry by: its construct, its import line, whether that compiles.
|
|
98
|
+
const resolutionList = primitives.map((p) => resolveCuratedReuse(p, fullSurface, lookup));
|
|
99
|
+
const resolutions = new Map(primitives.map((p, i) => [p, resolutionList[i]]));
|
|
100
|
+
// The uncurated export surface — searched whenever a graph exists and has a
|
|
101
|
+
// package root, unless the caller asked for the curated index alone. A
|
|
102
|
+
// skipped (or partial) search is said out loud: "no uncurated match" and
|
|
103
|
+
// "never looked" must not read alike.
|
|
104
|
+
let surface;
|
|
105
|
+
let exportSurface;
|
|
106
|
+
if (curatedOnly) {
|
|
107
|
+
exportSurface = { status: ExportSurfaceStatus.Disabled, reason: '--curated-only', roots: 0, packagesWithoutEntry: [], size: 0 };
|
|
108
|
+
}
|
|
109
|
+
else if (!fullSurface) {
|
|
110
|
+
exportSurface = {
|
|
111
|
+
status: ExportSurfaceStatus.NotSearched,
|
|
112
|
+
reason: 'no graph index — run `shrk graph index`',
|
|
113
|
+
roots: 0,
|
|
114
|
+
packagesWithoutEntry: [],
|
|
115
|
+
size: 0,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
else if (fullSurface.roots.length === 0) {
|
|
119
|
+
// Zero roots walked is "never looked", never "looked, found nothing".
|
|
120
|
+
exportSurface = {
|
|
121
|
+
status: ExportSurfaceStatus.NotSearched,
|
|
122
|
+
reason: fullSurface.packagesWithoutEntry.length > 0
|
|
123
|
+
? 'no package entry resolves to an indexed file'
|
|
124
|
+
: 'no workspace packages (package.json `workspaces`)',
|
|
125
|
+
roots: 0,
|
|
126
|
+
packagesWithoutEntry: fullSurface.packagesWithoutEntry.map((p) => ({ package: p.package, reason: p.reason })),
|
|
127
|
+
size: 0,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
surface = fullSurface;
|
|
132
|
+
const local = fullSurface.unfollowedReExports.filter((u) => u.kind === UnfollowedReExportKind.Unresolved);
|
|
133
|
+
const gaps = [];
|
|
134
|
+
if (fullSurface.packagesWithoutEntry.length > 0) {
|
|
135
|
+
const total = fullSurface.roots.length + fullSurface.packagesWithoutEntry.length;
|
|
136
|
+
gaps.push(`${fullSurface.packagesWithoutEntry.length} of ${total} package(s) have no resolved entry`);
|
|
167
137
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
138
|
+
if (local.length > 0)
|
|
139
|
+
gaps.push(`${local.length} re-export(s) the index could not follow`);
|
|
140
|
+
exportSurface = {
|
|
141
|
+
status: gaps.length > 0 ? ExportSurfaceStatus.Partial : ExportSurfaceStatus.Searched,
|
|
142
|
+
...(gaps.length > 0 ? { reason: gaps.join('; ') } : {}),
|
|
143
|
+
roots: fullSurface.roots.length,
|
|
144
|
+
packagesWithoutEntry: fullSurface.packagesWithoutEntry.map((p) => ({ package: p.package, reason: p.reason })),
|
|
145
|
+
size: fullSurface.exports.length,
|
|
146
|
+
...(fullSurface.unfollowedReExports.length > 0
|
|
147
|
+
? {
|
|
148
|
+
unresolvedReExports: fullSurface.unfollowedReExports.length,
|
|
149
|
+
unfollowedReExports: [...fullSurface.unfollowedReExports],
|
|
150
|
+
}
|
|
151
|
+
: {}),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
// The curated constructs, by resolved declaration — exactly the exclusion
|
|
155
|
+
// `shrk reuse coverage` applies (a same-named export of a DIFFERENT
|
|
156
|
+
// construct stays a candidate).
|
|
157
|
+
const curatedDeclaredIn = api ? curatedDeclarationMap(primitives, resolutionList) : undefined;
|
|
158
|
+
const ranking = rankReuseCandidates(primitives, surface, intent, {
|
|
159
|
+
limit,
|
|
160
|
+
suggestLimit: suggestK,
|
|
161
|
+
includeTypes,
|
|
162
|
+
curatedOnly,
|
|
163
|
+
...(curatedDeclaredIn ? { curatedDeclaredIn } : {}),
|
|
164
|
+
});
|
|
165
|
+
const confidenceJson = {
|
|
166
|
+
confident: ranking.confident,
|
|
167
|
+
verdict: ranking.verdict,
|
|
168
|
+
floor: ranking.floor,
|
|
169
|
+
bestScore: ranking.bestScore,
|
|
170
|
+
};
|
|
171
|
+
// The miss path only (nothing matched by NAME): is the index behind? The
|
|
172
|
+
// freshness walk is not free, so it never runs on a hit.
|
|
173
|
+
const behind = api && !ranking.nameAnswered ? indexBehindHint(cwd) : null;
|
|
174
|
+
const surfaceJson = {
|
|
175
|
+
exportSurface,
|
|
176
|
+
curationGap: ranking.curationGap,
|
|
177
|
+
superseded: ranking.superseded,
|
|
178
|
+
...(behind ? { indexBehind: behind } : {}),
|
|
179
|
+
};
|
|
180
|
+
const writeSurfaceNotes = () => {
|
|
181
|
+
if (exportSurface.status === ExportSurfaceStatus.NotSearched) {
|
|
182
|
+
process.stdout.write(api
|
|
183
|
+
? ` ⚠ uncurated export surface NOT searched (${exportSurface.reason ?? 'no package root'})\n`
|
|
184
|
+
: ' ⚠ uncurated export surface NOT searched (no graph index) — run `shrk graph index`\n');
|
|
173
185
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
186
|
+
const byReason = new Map();
|
|
187
|
+
for (const p of exportSurface.packagesWithoutEntry) {
|
|
188
|
+
const list = byReason.get(p.reason);
|
|
189
|
+
if (list)
|
|
190
|
+
list.push(p.package);
|
|
191
|
+
else
|
|
192
|
+
byReason.set(p.reason, [p.package]);
|
|
180
193
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
// Weak overlap only (a single generic keyword collision on an unrelated
|
|
185
|
-
// entry): below the confidence floor. A miss must look like a miss — never
|
|
186
|
-
// return the nearest collision as a confident answer. Offer did-you-mean.
|
|
187
|
-
if (ranked.length === 0) {
|
|
188
|
-
// Rank the weakly-overlapping candidates (score > 0) and cap at K — never
|
|
189
|
-
// the whole catalog. `suggestions` and the legacy `didYouMean` alias carry
|
|
190
|
-
// the same scored rows; `--all` additionally dumps every declared role.
|
|
191
|
-
const suggestions = scored.slice(0, Math.max(1, suggestK)).map((x) => ({
|
|
192
|
-
symbol: x.p.symbol,
|
|
193
|
-
score: x.detail.score,
|
|
194
|
-
confidence: confidenceOf(x.detail.matched.length),
|
|
195
|
-
matched: x.detail.matched,
|
|
196
|
-
roles: x.p.roles,
|
|
197
|
-
}));
|
|
198
|
-
const roles = [...new Set(primitives.flatMap((p) => p.roles))].sort();
|
|
199
|
-
if (wantJson) {
|
|
200
|
-
process.stdout.write(asJson({
|
|
201
|
-
schema: 'sharkcraft.reuse/v1',
|
|
202
|
-
intent,
|
|
203
|
-
confident: false,
|
|
204
|
-
results: [],
|
|
205
|
-
suggestions,
|
|
206
|
-
didYouMean: suggestions,
|
|
207
|
-
...(wantAll ? { availableRoles: roles } : {}),
|
|
208
|
-
...planeJson,
|
|
209
|
-
}) + '\n');
|
|
210
|
-
return 0;
|
|
194
|
+
for (const [reason, pkgs] of byReason) {
|
|
195
|
+
const shown = pkgs.slice(0, 4).join(', ') + (pkgs.length > 4 ? `, +${pkgs.length - 4} more` : '');
|
|
196
|
+
process.stdout.write(` ⚠ ${pkgs.length} package(s) not searched — ${reason} (${shown})\n`);
|
|
211
197
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
process.stdout.write(`
|
|
198
|
+
const unfollowed = exportSurface.unfollowedReExports ?? [];
|
|
199
|
+
const local = unfollowed.filter((u) => u.kind === UnfollowedReExportKind.Unresolved);
|
|
200
|
+
if (local.length > 0) {
|
|
201
|
+
const shown = local.slice(0, 3).map(formatUnfollowed).join(', ') + (local.length > 3 ? `, +${local.length - 3} more` : '');
|
|
202
|
+
process.stdout.write(` ⚠ ${local.length} re-export(s) not followed — part of the surface NOT searched (${shown})\n`);
|
|
217
203
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
process.stdout.write(` • ${r}\n`);
|
|
204
|
+
const external = unfollowed.length - local.length;
|
|
205
|
+
if (external > 0) {
|
|
206
|
+
process.stdout.write(` (${external} re-export(s) of modules outside the workspace not followed)\n`);
|
|
222
207
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
const results = ranked.map(({ p, detail }) => {
|
|
227
|
-
const score = detail.score;
|
|
228
|
-
const r = {
|
|
229
|
-
symbol: p.symbol,
|
|
230
|
-
score,
|
|
231
|
-
confidence: confidenceOf(detail.matched.length),
|
|
232
|
-
matched: detail.matched,
|
|
233
|
-
roles: p.roles,
|
|
234
|
-
siblings: [],
|
|
235
|
-
consumers: [],
|
|
236
|
-
};
|
|
237
|
-
if (p.description)
|
|
238
|
-
r.description = p.description;
|
|
239
|
-
if (p.importPath)
|
|
240
|
-
r.importPath = p.importPath;
|
|
241
|
-
if (api) {
|
|
242
|
-
// Disambiguate same-named declarations deterministically: prefer
|
|
243
|
-
// exported symbols, then shallowest path; disclose the alternates.
|
|
244
|
-
const candidates = api
|
|
245
|
-
.findSymbol(p.symbol, { exact: true })
|
|
246
|
-
.slice()
|
|
247
|
-
.sort((a, b) => (a.path ?? '').localeCompare(b.path ?? ''));
|
|
248
|
-
const exported = candidates.filter((c) => c.data?.['isExported'] === true);
|
|
249
|
-
const pool = exported.length > 0 ? exported : candidates;
|
|
250
|
-
const sym = pool[0];
|
|
251
|
-
if (sym) {
|
|
252
|
-
if (sym.path)
|
|
253
|
-
r.declaredIn = sym.path;
|
|
254
|
-
if (sym.line)
|
|
255
|
-
r.declaredLine = sym.line;
|
|
256
|
-
if (sym.path) {
|
|
257
|
-
const fileNode = api.findFile(sym.path);
|
|
258
|
-
if (fileNode) {
|
|
259
|
-
r.siblings = api
|
|
260
|
-
.symbolsIn(fileNode.id)
|
|
261
|
-
.filter((s) => s.data?.['isExported'] === true && s.label && s.label !== p.symbol)
|
|
262
|
-
.map((s) => s.label)
|
|
263
|
-
.slice(0, 8);
|
|
264
|
-
// When no public importPath is configured, surface a re-exporting
|
|
265
|
-
// barrel as a hint (we never fabricate a module specifier from a
|
|
266
|
-
// deep file path — that would be a broken/unusable import).
|
|
267
|
-
if (!r.importPath) {
|
|
268
|
-
const barrel = api.importersOf(fileNode.id).find((n) => n.path && INDEX_RE.test(n.path));
|
|
269
|
-
if (barrel?.path)
|
|
270
|
-
r.reExportedVia = barrel.path;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
const sites = api.referenceSitesOf(sym.id);
|
|
275
|
-
r.consumerTotal = sites.length;
|
|
276
|
-
r.consumers = sites
|
|
277
|
-
.slice(0, 5)
|
|
278
|
-
.map((s) => ({ path: s.node.path ?? s.node.id, ...(s.line ? { line: s.line } : {}) }));
|
|
279
|
-
const alts = pool.slice(1).map((c) => c.path).filter((x) => !!x);
|
|
280
|
-
if (alts.length > 0)
|
|
281
|
-
r.alternates = alts;
|
|
282
|
-
}
|
|
283
|
-
else {
|
|
284
|
-
r.notFound = true;
|
|
285
|
-
}
|
|
208
|
+
for (const s of ranking.superseded) {
|
|
209
|
+
process.stdout.write(` (superseded: ${s.symbol} from ${s.package} → use ${s.supersededBy.join(' / ')} — per reusePrimitives[].supersedes)\n`);
|
|
286
210
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return
|
|
292
|
-
|
|
211
|
+
if (behind)
|
|
212
|
+
process.stdout.write(` ⚠ ${behind}\n`);
|
|
213
|
+
};
|
|
214
|
+
if (ranking.results.length === 0) {
|
|
215
|
+
return writeNoAnswer({
|
|
216
|
+
intent,
|
|
217
|
+
ranking,
|
|
218
|
+
primitivesCount: primitives.length,
|
|
219
|
+
roles: [...new Set(primitives.flatMap((p) => p.roles))].sort(),
|
|
220
|
+
wantJson,
|
|
221
|
+
wantAll,
|
|
222
|
+
extraJson: { ...confidenceJson, ...surfaceJson, ...planeJson },
|
|
223
|
+
writeNotes: () => {
|
|
224
|
+
writePlaneNotes();
|
|
225
|
+
writeSurfaceNotes();
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const results = ranking.results.map((c) => enrichResult(c, api, c.primitive ? resolutions.get(c.primitive) : undefined));
|
|
293
230
|
if (wantJson) {
|
|
294
|
-
process.stdout.write(asJson({
|
|
231
|
+
process.stdout.write(asJson({
|
|
232
|
+
schema: 'sharkcraft.reuse/v1',
|
|
233
|
+
intent,
|
|
234
|
+
graphIndexed: !!api,
|
|
235
|
+
...confidenceJson,
|
|
236
|
+
results,
|
|
237
|
+
...surfaceJson,
|
|
238
|
+
...planeJson,
|
|
239
|
+
}) + '\n');
|
|
295
240
|
return 0;
|
|
296
241
|
}
|
|
297
242
|
process.stdout.write(header(`Reuse: "${intent}"`));
|
|
298
243
|
writePlaneNotes();
|
|
244
|
+
writeSurfaceNotes();
|
|
299
245
|
if (!api) {
|
|
300
246
|
process.stdout.write(' (code graph missing — import path/siblings/consumers limited; run `shrk graph index`)\n');
|
|
301
247
|
}
|
|
302
248
|
let i = 0;
|
|
303
249
|
for (const r of results) {
|
|
304
250
|
i += 1;
|
|
305
|
-
process.stdout.write(`\n${i}. ${r.symbol}\n`);
|
|
251
|
+
process.stdout.write(`\n${i}. ${r.symbol} [${resultLabel(r)}]\n`);
|
|
306
252
|
if (r.description)
|
|
307
253
|
process.stdout.write(` ${r.description}\n`);
|
|
308
|
-
process.stdout.write(` match:
|
|
254
|
+
process.stdout.write(` match: ${matchLine(r)}\n`);
|
|
309
255
|
if (r.notFound) {
|
|
310
256
|
process.stdout.write(' ⚠ symbol not found in the code graph — verify reusePrimitives[].symbol (typo/rename?) or run `shrk graph index`\n');
|
|
311
257
|
}
|
|
312
258
|
if (r.importLine) {
|
|
313
259
|
process.stdout.write(` import: ${r.importLine}\n`);
|
|
260
|
+
if (r.importPathAgrees === false) {
|
|
261
|
+
process.stdout.write(` ⚠ '${r.importPath}' does not export ${r.symbol} (per the index) — this import would not compile; see \`shrk reuse coverage\`\n`);
|
|
262
|
+
}
|
|
314
263
|
}
|
|
315
264
|
else if (r.reExportedVia) {
|
|
316
265
|
process.stdout.write(` re-exported via: ${r.reExportedVia} (set reusePrimitives[].importPath for a copy-paste import)\n`);
|
|
@@ -318,6 +267,8 @@ export const reuseCommand = {
|
|
|
318
267
|
if (r.declaredIn) {
|
|
319
268
|
process.stdout.write(` declared in: ${r.declaredIn}${r.declaredLine ? ':' + r.declaredLine : ''}\n`);
|
|
320
269
|
}
|
|
270
|
+
if (r.via && r.via.length > 0)
|
|
271
|
+
process.stdout.write(` reached via: ${r.via.join(' → ')}\n`);
|
|
321
272
|
if (r.alternates && r.alternates.length > 0) {
|
|
322
273
|
process.stdout.write(` ⚠ name also declared in: ${r.alternates.join(', ')}\n`);
|
|
323
274
|
}
|
|
@@ -333,6 +284,206 @@ export const reuseCommand = {
|
|
|
333
284
|
process.stdout.write(` - ${c.path}${c.line ? ':' + c.line : ''}\n`);
|
|
334
285
|
}
|
|
335
286
|
}
|
|
287
|
+
if (ranking.curationGap) {
|
|
288
|
+
process.stdout.write('\n ⚠ Curation gap: an uncurated export matches this intent by NAME, while the best curated\n' +
|
|
289
|
+
' candidate names only part of it, or matched only through its roles/keywords/description.\n' +
|
|
290
|
+
' Add the export to reusePrimitives[] — or list it in the curated entry\'s `supersedes` — and\n' +
|
|
291
|
+
' run `shrk reuse coverage` to see every such gap.\n');
|
|
292
|
+
}
|
|
336
293
|
return 0;
|
|
337
294
|
},
|
|
338
295
|
};
|
|
296
|
+
/** No confident answer: a weak did-you-mean, or a plain "nothing shares a term". */
|
|
297
|
+
function writeNoAnswer(o) {
|
|
298
|
+
const { ranking, wantAll } = o;
|
|
299
|
+
const suggestions = ranking.suggestions;
|
|
300
|
+
const weak = ranking.verdict === MatchConfidenceVerdict.NoConfidentMatch;
|
|
301
|
+
if (o.wantJson) {
|
|
302
|
+
process.stdout.write(asJson({
|
|
303
|
+
schema: 'sharkcraft.reuse/v1',
|
|
304
|
+
intent: o.intent,
|
|
305
|
+
results: [],
|
|
306
|
+
suggestions,
|
|
307
|
+
// The legacy alias, kept on the weak branch where it always lived.
|
|
308
|
+
...(weak ? { didYouMean: suggestions } : {}),
|
|
309
|
+
...(wantAll ? { availableRoles: o.roles } : {}),
|
|
310
|
+
...o.extraJson,
|
|
311
|
+
}) + '\n');
|
|
312
|
+
return 0;
|
|
313
|
+
}
|
|
314
|
+
process.stdout.write(header(`Reuse: "${o.intent}"`));
|
|
315
|
+
if (o.primitivesCount === 0) {
|
|
316
|
+
process.stdout.write(' No reuse primitives configured. Declare `reusePrimitives[]` in sharkcraft.config.ts\n' +
|
|
317
|
+
' to map roles/intents to canonical symbols (see docs/reuse.md).\n');
|
|
318
|
+
}
|
|
319
|
+
if (weak) {
|
|
320
|
+
// Weak overlap only (a single generic keyword collision on an unrelated
|
|
321
|
+
// entry, or an export sharing only part of the name): below the confidence
|
|
322
|
+
// floor. A miss must look like a miss — never the nearest collision as an answer.
|
|
323
|
+
process.stdout.write(' No confident match — the intent only weakly overlaps existing candidates.\n' +
|
|
324
|
+
' Did you mean (weak, verify before reusing):\n');
|
|
325
|
+
for (const s of suggestions)
|
|
326
|
+
process.stdout.write(` • ${suggestionLine(s)}\n`);
|
|
327
|
+
if (wantAll) {
|
|
328
|
+
process.stdout.write(' Full catalog (all declared roles):\n');
|
|
329
|
+
for (const r of o.roles.slice(0, 40))
|
|
330
|
+
process.stdout.write(` • ${r}\n`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else if (o.primitivesCount > 0) {
|
|
334
|
+
// Zero overlap: rather than dump the whole catalog, the alphabetized
|
|
335
|
+
// nearest top-K (every score is 0 here), stated as such. The full catalog
|
|
336
|
+
// is available only behind an explicit `--all`.
|
|
337
|
+
if (wantAll) {
|
|
338
|
+
process.stdout.write(' No primitive matched — no candidate shares any term — showing full catalog:\n');
|
|
339
|
+
for (const r of o.roles.slice(0, 40))
|
|
340
|
+
process.stdout.write(` • ${r}\n`);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
process.stdout.write(' No strong match — no candidate shares any term with the intent.\n' +
|
|
344
|
+
' Nearest primitives (pass --all for the full catalog):\n');
|
|
345
|
+
for (const s of suggestions) {
|
|
346
|
+
process.stdout.write(` • ${s.symbol} (score ${s.score}; roles: ${s.roles.join(', ') || '—'})\n`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
o.writeNotes();
|
|
351
|
+
return 0;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Resolve one ranked candidate through the code graph (declaration, import,
|
|
355
|
+
* siblings, consumers). A curated row is printed from its
|
|
356
|
+
* `IReuseCuratedResolution` — the SAME record `shrk reuse coverage` judges the
|
|
357
|
+
* entry by — so the declaration shown and the import line printed are the ones
|
|
358
|
+
* the coverage verdict checked.
|
|
359
|
+
*/
|
|
360
|
+
function enrichResult(c, api, res) {
|
|
361
|
+
const r = {
|
|
362
|
+
symbol: c.symbol,
|
|
363
|
+
source: c.source,
|
|
364
|
+
score: c.score,
|
|
365
|
+
confidence: c.confidence,
|
|
366
|
+
matched: c.matched,
|
|
367
|
+
matchedVia: c.matchedVia,
|
|
368
|
+
nameMatch: c.nameMatch,
|
|
369
|
+
roles: c.primitive?.roles ?? [],
|
|
370
|
+
siblings: [],
|
|
371
|
+
consumers: [],
|
|
372
|
+
};
|
|
373
|
+
const p = c.primitive;
|
|
374
|
+
if (p) {
|
|
375
|
+
if (p.description)
|
|
376
|
+
r.description = p.description;
|
|
377
|
+
if (p.importPath) {
|
|
378
|
+
r.importPath = p.importPath;
|
|
379
|
+
// The import line is emitted ONLY from a real specifier (the configured
|
|
380
|
+
// importPath), bound the way its module exports the symbol.
|
|
381
|
+
const style = res?.importStyle ?? ReuseImportStyle.Named;
|
|
382
|
+
r.importLine = res?.importLine ?? reuseImportLine(p.symbol, p.importPath, style);
|
|
383
|
+
r.importStyle = style;
|
|
384
|
+
if (style === ReuseImportStyle.Default)
|
|
385
|
+
r.isDefault = true;
|
|
386
|
+
}
|
|
387
|
+
if (res?.importPathAgrees !== undefined)
|
|
388
|
+
r.importPathAgrees = res.importPathAgrees;
|
|
389
|
+
if (api) {
|
|
390
|
+
const d = res?.declaration;
|
|
391
|
+
if (d) {
|
|
392
|
+
r.declaredIn = d.path;
|
|
393
|
+
if (d.line)
|
|
394
|
+
r.declaredLine = d.line;
|
|
395
|
+
const fileNode = api.findFile(d.path);
|
|
396
|
+
if (fileNode) {
|
|
397
|
+
r.siblings = exportedSiblings(api, fileNode.id, d.symbolId);
|
|
398
|
+
// When no public importPath is configured, surface a re-exporting
|
|
399
|
+
// barrel as a hint (we never fabricate a module specifier from a
|
|
400
|
+
// deep file path — that would be a broken/unusable import).
|
|
401
|
+
if (!r.importPath) {
|
|
402
|
+
const barrel = api.importersOf(fileNode.id).find((n) => n.path && INDEX_RE.test(n.path));
|
|
403
|
+
if (barrel?.path)
|
|
404
|
+
r.reExportedVia = barrel.path;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
setConsumers(r, api, d.symbolId);
|
|
408
|
+
if (res && res.alternates.length > 0)
|
|
409
|
+
r.alternates = [...res.alternates];
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
r.notFound = true;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
else if (c.export) {
|
|
417
|
+
// Uncurated: the package name IS a real, copy-pasteable specifier — the
|
|
418
|
+
// construct is reachable from that package's root entry, which is exactly
|
|
419
|
+
// the file `import … from '<pkg>'` resolves to. Nothing is fabricated.
|
|
420
|
+
const e = c.export;
|
|
421
|
+
r.package = e.package;
|
|
422
|
+
r.importPath = e.package;
|
|
423
|
+
r.declaredIn = e.declaredIn;
|
|
424
|
+
if (e.line)
|
|
425
|
+
r.declaredLine = e.line;
|
|
426
|
+
r.via = e.via;
|
|
427
|
+
const style = e.isDefault === true ? ReuseImportStyle.Default : ReuseImportStyle.Named;
|
|
428
|
+
if (e.isDefault)
|
|
429
|
+
r.isDefault = true;
|
|
430
|
+
r.importStyle = style;
|
|
431
|
+
r.importLine = reuseImportLine(c.symbol, e.package, style);
|
|
432
|
+
if (api) {
|
|
433
|
+
const fileNode = api.findFile(e.declaredIn);
|
|
434
|
+
if (fileNode)
|
|
435
|
+
r.siblings = exportedSiblings(api, fileNode.id, e.symbolId);
|
|
436
|
+
setConsumers(r, api, e.symbolId);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return r;
|
|
440
|
+
}
|
|
441
|
+
function exportedSiblings(api, fileNodeId, selfId) {
|
|
442
|
+
return api
|
|
443
|
+
.symbolsIn(fileNodeId)
|
|
444
|
+
.filter((s) => s.data?.['isExported'] === true && s.label && s.id !== selfId)
|
|
445
|
+
.map((s) => s.label)
|
|
446
|
+
.slice(0, 8);
|
|
447
|
+
}
|
|
448
|
+
function setConsumers(r, api, symbolId) {
|
|
449
|
+
const sites = api.referenceSitesOf(symbolId);
|
|
450
|
+
r.consumerTotal = sites.length;
|
|
451
|
+
r.consumers = sites
|
|
452
|
+
.slice(0, 5)
|
|
453
|
+
.map((s) => ({ path: s.node.path ?? s.node.id, ...(s.line ? { line: s.line } : {}) }));
|
|
454
|
+
}
|
|
455
|
+
function formatUnfollowed(u) {
|
|
456
|
+
return `${u.file} → '${u.specifier}'${u.name === '*' ? '' : ` { ${u.name} }`}`;
|
|
457
|
+
}
|
|
458
|
+
/** `[uncurated · exported by @demo/ui · exact name match]` / `[curated · via keywords — not its name]`. */
|
|
459
|
+
function resultLabel(r) {
|
|
460
|
+
if (r.source === ReuseCandidateSource.ExportSurface) {
|
|
461
|
+
return `uncurated · exported by ${r.package ?? '?'} · ${NAME_MATCH_WORDS[r.nameMatch]}`;
|
|
462
|
+
}
|
|
463
|
+
if (r.nameMatch === ReuseNameMatch.None)
|
|
464
|
+
return `curated · via ${metadataVia(r)} — not its name`;
|
|
465
|
+
return `curated · ${NAME_MATCH_WORDS[r.nameMatch]}`;
|
|
466
|
+
}
|
|
467
|
+
function matchLine(r) {
|
|
468
|
+
const pct = Math.round(r.confidence * 100);
|
|
469
|
+
const matched = r.matched.join(', ') || '—';
|
|
470
|
+
if (r.source === ReuseCandidateSource.Curated && r.nameMatch === ReuseNameMatch.None) {
|
|
471
|
+
// The honesty qualifier: a high percentage earned only through metadata
|
|
472
|
+
// must not read like a name match.
|
|
473
|
+
return `score ${r.score} (${pct}% of intent — via ${metadataVia(r)}; not its name; matched: ${matched})`;
|
|
474
|
+
}
|
|
475
|
+
return `score ${r.score} (${pct}% of intent; matched: ${matched})`;
|
|
476
|
+
}
|
|
477
|
+
function metadataVia(r) {
|
|
478
|
+
const words = r.matchedVia.filter((v) => v !== ReuseMatchSource.Symbol).map((v) => SOURCE_WORD[v]);
|
|
479
|
+
return words.length > 0 ? words.join(', ') : 'metadata';
|
|
480
|
+
}
|
|
481
|
+
function suggestionLine(s) {
|
|
482
|
+
const pct = Math.round(s.confidence * 100);
|
|
483
|
+
const matched = s.matched.join(', ') || '—';
|
|
484
|
+
if (s.source === ReuseCandidateSource.ExportSurface) {
|
|
485
|
+
return `${s.symbol} (uncurated · exported by ${s.package ?? '?'} · ${NAME_MATCH_WORDS[s.nameMatch]}; score ${s.score}, ${pct}% of intent; matched: ${matched})`;
|
|
486
|
+
}
|
|
487
|
+
const via = s.nameMatch === ReuseNameMatch.None ? ` — via ${metadataVia(s)}, not its name` : '';
|
|
488
|
+
return `${s.symbol} (score ${s.score}, ${pct}% of intent; matched: ${matched}${via})`;
|
|
489
|
+
}
|