@dotsetlabs/bellwether 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +291 -0
- package/LICENSE +21 -0
- package/README.md +739 -0
- package/dist/auth/credentials.d.ts +64 -0
- package/dist/auth/credentials.js +218 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/keychain.d.ts +64 -0
- package/dist/auth/keychain.js +268 -0
- package/dist/baseline/ab-testing.d.ts +80 -0
- package/dist/baseline/ab-testing.js +236 -0
- package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
- package/dist/baseline/ai-compatibility-scorer.js +606 -0
- package/dist/baseline/calibration.d.ts +77 -0
- package/dist/baseline/calibration.js +136 -0
- package/dist/baseline/category-matching.d.ts +85 -0
- package/dist/baseline/category-matching.js +289 -0
- package/dist/baseline/change-impact-analyzer.d.ts +98 -0
- package/dist/baseline/change-impact-analyzer.js +592 -0
- package/dist/baseline/comparator.d.ts +64 -0
- package/dist/baseline/comparator.js +916 -0
- package/dist/baseline/confidence.d.ts +55 -0
- package/dist/baseline/confidence.js +122 -0
- package/dist/baseline/converter.d.ts +61 -0
- package/dist/baseline/converter.js +585 -0
- package/dist/baseline/dependency-analyzer.d.ts +89 -0
- package/dist/baseline/dependency-analyzer.js +567 -0
- package/dist/baseline/deprecation-tracker.d.ts +133 -0
- package/dist/baseline/deprecation-tracker.js +322 -0
- package/dist/baseline/diff.d.ts +55 -0
- package/dist/baseline/diff.js +1584 -0
- package/dist/baseline/documentation-scorer.d.ts +205 -0
- package/dist/baseline/documentation-scorer.js +466 -0
- package/dist/baseline/embeddings.d.ts +118 -0
- package/dist/baseline/embeddings.js +251 -0
- package/dist/baseline/error-analyzer.d.ts +198 -0
- package/dist/baseline/error-analyzer.js +721 -0
- package/dist/baseline/evaluation/evaluator.d.ts +42 -0
- package/dist/baseline/evaluation/evaluator.js +323 -0
- package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
- package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
- package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
- package/dist/baseline/evaluation/golden-dataset.js +717 -0
- package/dist/baseline/evaluation/index.d.ts +15 -0
- package/dist/baseline/evaluation/index.js +15 -0
- package/dist/baseline/evaluation/types.d.ts +186 -0
- package/dist/baseline/evaluation/types.js +8 -0
- package/dist/baseline/external-dependency-detector.d.ts +181 -0
- package/dist/baseline/external-dependency-detector.js +524 -0
- package/dist/baseline/golden-output.d.ts +162 -0
- package/dist/baseline/golden-output.js +636 -0
- package/dist/baseline/health-scorer.d.ts +174 -0
- package/dist/baseline/health-scorer.js +451 -0
- package/dist/baseline/incremental-checker.d.ts +97 -0
- package/dist/baseline/incremental-checker.js +174 -0
- package/dist/baseline/index.d.ts +31 -0
- package/dist/baseline/index.js +42 -0
- package/dist/baseline/migration-generator.d.ts +137 -0
- package/dist/baseline/migration-generator.js +554 -0
- package/dist/baseline/migrations.d.ts +60 -0
- package/dist/baseline/migrations.js +197 -0
- package/dist/baseline/performance-tracker.d.ts +214 -0
- package/dist/baseline/performance-tracker.js +577 -0
- package/dist/baseline/pr-comment-generator.d.ts +117 -0
- package/dist/baseline/pr-comment-generator.js +546 -0
- package/dist/baseline/response-fingerprint.d.ts +127 -0
- package/dist/baseline/response-fingerprint.js +728 -0
- package/dist/baseline/response-schema-tracker.d.ts +129 -0
- package/dist/baseline/response-schema-tracker.js +420 -0
- package/dist/baseline/risk-scorer.d.ts +54 -0
- package/dist/baseline/risk-scorer.js +434 -0
- package/dist/baseline/saver.d.ts +89 -0
- package/dist/baseline/saver.js +554 -0
- package/dist/baseline/scenario-generator.d.ts +151 -0
- package/dist/baseline/scenario-generator.js +905 -0
- package/dist/baseline/schema-compare.d.ts +86 -0
- package/dist/baseline/schema-compare.js +557 -0
- package/dist/baseline/schema-evolution.d.ts +189 -0
- package/dist/baseline/schema-evolution.js +467 -0
- package/dist/baseline/semantic.d.ts +203 -0
- package/dist/baseline/semantic.js +908 -0
- package/dist/baseline/synonyms.d.ts +60 -0
- package/dist/baseline/synonyms.js +386 -0
- package/dist/baseline/telemetry.d.ts +165 -0
- package/dist/baseline/telemetry.js +294 -0
- package/dist/baseline/test-pruner.d.ts +120 -0
- package/dist/baseline/test-pruner.js +387 -0
- package/dist/baseline/types.d.ts +449 -0
- package/dist/baseline/types.js +5 -0
- package/dist/baseline/version.d.ts +138 -0
- package/dist/baseline/version.js +206 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/response-cache.d.ts +151 -0
- package/dist/cache/response-cache.js +287 -0
- package/dist/ci/index.d.ts +60 -0
- package/dist/ci/index.js +342 -0
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.js +352 -0
- package/dist/cli/commands/badge.d.ts +3 -0
- package/dist/cli/commands/badge.js +74 -0
- package/dist/cli/commands/baseline-accept.d.ts +15 -0
- package/dist/cli/commands/baseline-accept.js +178 -0
- package/dist/cli/commands/baseline-migrate.d.ts +12 -0
- package/dist/cli/commands/baseline-migrate.js +164 -0
- package/dist/cli/commands/baseline.d.ts +14 -0
- package/dist/cli/commands/baseline.js +449 -0
- package/dist/cli/commands/beta.d.ts +10 -0
- package/dist/cli/commands/beta.js +231 -0
- package/dist/cli/commands/check.d.ts +11 -0
- package/dist/cli/commands/check.js +820 -0
- package/dist/cli/commands/cloud/badge.d.ts +3 -0
- package/dist/cli/commands/cloud/badge.js +74 -0
- package/dist/cli/commands/cloud/diff.d.ts +6 -0
- package/dist/cli/commands/cloud/diff.js +79 -0
- package/dist/cli/commands/cloud/history.d.ts +6 -0
- package/dist/cli/commands/cloud/history.js +102 -0
- package/dist/cli/commands/cloud/link.d.ts +9 -0
- package/dist/cli/commands/cloud/link.js +119 -0
- package/dist/cli/commands/cloud/login.d.ts +7 -0
- package/dist/cli/commands/cloud/login.js +499 -0
- package/dist/cli/commands/cloud/projects.d.ts +6 -0
- package/dist/cli/commands/cloud/projects.js +44 -0
- package/dist/cli/commands/cloud/shared.d.ts +7 -0
- package/dist/cli/commands/cloud/shared.js +42 -0
- package/dist/cli/commands/cloud/teams.d.ts +8 -0
- package/dist/cli/commands/cloud/teams.js +169 -0
- package/dist/cli/commands/cloud/upload.d.ts +8 -0
- package/dist/cli/commands/cloud/upload.js +181 -0
- package/dist/cli/commands/contract.d.ts +11 -0
- package/dist/cli/commands/contract.js +280 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.js +82 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.js +187 -0
- package/dist/cli/commands/explore.d.ts +11 -0
- package/dist/cli/commands/explore.js +437 -0
- package/dist/cli/commands/feedback.d.ts +9 -0
- package/dist/cli/commands/feedback.js +174 -0
- package/dist/cli/commands/golden.d.ts +12 -0
- package/dist/cli/commands/golden.js +407 -0
- package/dist/cli/commands/history.d.ts +10 -0
- package/dist/cli/commands/history.js +202 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +219 -0
- package/dist/cli/commands/interview.d.ts +3 -0
- package/dist/cli/commands/interview.js +903 -0
- package/dist/cli/commands/link.d.ts +10 -0
- package/dist/cli/commands/link.js +169 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +499 -0
- package/dist/cli/commands/preset.d.ts +33 -0
- package/dist/cli/commands/preset.js +297 -0
- package/dist/cli/commands/profile.d.ts +33 -0
- package/dist/cli/commands/profile.js +286 -0
- package/dist/cli/commands/registry.d.ts +11 -0
- package/dist/cli/commands/registry.js +146 -0
- package/dist/cli/commands/shared.d.ts +79 -0
- package/dist/cli/commands/shared.js +196 -0
- package/dist/cli/commands/teams.d.ts +8 -0
- package/dist/cli/commands/teams.js +169 -0
- package/dist/cli/commands/test.d.ts +9 -0
- package/dist/cli/commands/test.js +500 -0
- package/dist/cli/commands/upload.d.ts +8 -0
- package/dist/cli/commands/upload.js +223 -0
- package/dist/cli/commands/validate-config.d.ts +6 -0
- package/dist/cli/commands/validate-config.js +35 -0
- package/dist/cli/commands/verify.d.ts +11 -0
- package/dist/cli/commands/verify.js +283 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.js +253 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +178 -0
- package/dist/cli/interactive.d.ts +47 -0
- package/dist/cli/interactive.js +216 -0
- package/dist/cli/output/terminal-reporter.d.ts +19 -0
- package/dist/cli/output/terminal-reporter.js +104 -0
- package/dist/cli/output.d.ts +226 -0
- package/dist/cli/output.js +438 -0
- package/dist/cli/utils/env.d.ts +5 -0
- package/dist/cli/utils/env.js +14 -0
- package/dist/cli/utils/progress.d.ts +59 -0
- package/dist/cli/utils/progress.js +206 -0
- package/dist/cli/utils/server-context.d.ts +10 -0
- package/dist/cli/utils/server-context.js +36 -0
- package/dist/cloud/auth.d.ts +144 -0
- package/dist/cloud/auth.js +374 -0
- package/dist/cloud/client.d.ts +24 -0
- package/dist/cloud/client.js +65 -0
- package/dist/cloud/http-client.d.ts +38 -0
- package/dist/cloud/http-client.js +215 -0
- package/dist/cloud/index.d.ts +23 -0
- package/dist/cloud/index.js +25 -0
- package/dist/cloud/mock-client.d.ts +107 -0
- package/dist/cloud/mock-client.js +545 -0
- package/dist/cloud/types.d.ts +515 -0
- package/dist/cloud/types.js +15 -0
- package/dist/config/defaults.d.ts +160 -0
- package/dist/config/defaults.js +169 -0
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.js +122 -0
- package/dist/config/template.d.ts +42 -0
- package/dist/config/template.js +647 -0
- package/dist/config/validator.d.ts +2112 -0
- package/dist/config/validator.js +658 -0
- package/dist/constants/cloud.d.ts +107 -0
- package/dist/constants/cloud.js +110 -0
- package/dist/constants/core.d.ts +521 -0
- package/dist/constants/core.js +556 -0
- package/dist/constants/testing.d.ts +1283 -0
- package/dist/constants/testing.js +1568 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/contract/index.js +5 -0
- package/dist/contract/validator.d.ts +177 -0
- package/dist/contract/validator.js +574 -0
- package/dist/cost/index.d.ts +6 -0
- package/dist/cost/index.js +5 -0
- package/dist/cost/tracker.d.ts +134 -0
- package/dist/cost/tracker.js +313 -0
- package/dist/discovery/discovery.d.ts +16 -0
- package/dist/discovery/discovery.js +173 -0
- package/dist/discovery/types.d.ts +51 -0
- package/dist/discovery/types.js +2 -0
- package/dist/docs/agents.d.ts +3 -0
- package/dist/docs/agents.js +995 -0
- package/dist/docs/contract.d.ts +51 -0
- package/dist/docs/contract.js +1681 -0
- package/dist/docs/generator.d.ts +4 -0
- package/dist/docs/generator.js +4 -0
- package/dist/docs/html-reporter.d.ts +9 -0
- package/dist/docs/html-reporter.js +757 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +11 -0
- package/dist/docs/junit-reporter.d.ts +18 -0
- package/dist/docs/junit-reporter.js +210 -0
- package/dist/docs/report.d.ts +14 -0
- package/dist/docs/report.js +44 -0
- package/dist/docs/sarif-reporter.d.ts +19 -0
- package/dist/docs/sarif-reporter.js +335 -0
- package/dist/docs/shared.d.ts +35 -0
- package/dist/docs/shared.js +162 -0
- package/dist/docs/templates.d.ts +12 -0
- package/dist/docs/templates.js +76 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/retry.d.ts +92 -0
- package/dist/errors/retry.js +323 -0
- package/dist/errors/types.d.ts +321 -0
- package/dist/errors/types.js +584 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/interview/dependency-resolver.d.ts +11 -0
- package/dist/interview/dependency-resolver.js +32 -0
- package/dist/interview/interviewer.d.ts +232 -0
- package/dist/interview/interviewer.js +1939 -0
- package/dist/interview/mock-response-generator.d.ts +7 -0
- package/dist/interview/mock-response-generator.js +102 -0
- package/dist/interview/orchestrator.d.ts +237 -0
- package/dist/interview/orchestrator.js +1296 -0
- package/dist/interview/rate-limiter.d.ts +15 -0
- package/dist/interview/rate-limiter.js +55 -0
- package/dist/interview/response-validator.d.ts +10 -0
- package/dist/interview/response-validator.js +132 -0
- package/dist/interview/schema-inferrer.d.ts +8 -0
- package/dist/interview/schema-inferrer.js +71 -0
- package/dist/interview/schema-test-generator.d.ts +71 -0
- package/dist/interview/schema-test-generator.js +834 -0
- package/dist/interview/smart-value-generator.d.ts +155 -0
- package/dist/interview/smart-value-generator.js +554 -0
- package/dist/interview/stateful-test-runner.d.ts +19 -0
- package/dist/interview/stateful-test-runner.js +106 -0
- package/dist/interview/types.d.ts +561 -0
- package/dist/interview/types.js +2 -0
- package/dist/llm/anthropic.d.ts +41 -0
- package/dist/llm/anthropic.js +355 -0
- package/dist/llm/client.d.ts +123 -0
- package/dist/llm/client.js +42 -0
- package/dist/llm/factory.d.ts +38 -0
- package/dist/llm/factory.js +145 -0
- package/dist/llm/fallback.d.ts +140 -0
- package/dist/llm/fallback.js +379 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.js +15 -0
- package/dist/llm/ollama.d.ts +37 -0
- package/dist/llm/ollama.js +330 -0
- package/dist/llm/openai.d.ts +25 -0
- package/dist/llm/openai.js +320 -0
- package/dist/llm/token-budget.d.ts +161 -0
- package/dist/llm/token-budget.js +395 -0
- package/dist/logging/logger.d.ts +70 -0
- package/dist/logging/logger.js +130 -0
- package/dist/metrics/collector.d.ts +106 -0
- package/dist/metrics/collector.js +547 -0
- package/dist/metrics/index.d.ts +7 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/prometheus.d.ts +20 -0
- package/dist/metrics/prometheus.js +241 -0
- package/dist/metrics/types.d.ts +209 -0
- package/dist/metrics/types.js +5 -0
- package/dist/persona/builtins.d.ts +54 -0
- package/dist/persona/builtins.js +219 -0
- package/dist/persona/index.d.ts +8 -0
- package/dist/persona/index.js +8 -0
- package/dist/persona/loader.d.ts +30 -0
- package/dist/persona/loader.js +190 -0
- package/dist/persona/types.d.ts +144 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/validation.d.ts +94 -0
- package/dist/persona/validation.js +332 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/templates.d.ts +180 -0
- package/dist/prompts/templates.js +431 -0
- package/dist/registry/client.d.ts +49 -0
- package/dist/registry/client.js +191 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/types.d.ts +140 -0
- package/dist/registry/types.js +6 -0
- package/dist/scenarios/evaluator.d.ts +43 -0
- package/dist/scenarios/evaluator.js +206 -0
- package/dist/scenarios/index.d.ts +10 -0
- package/dist/scenarios/index.js +9 -0
- package/dist/scenarios/loader.d.ts +20 -0
- package/dist/scenarios/loader.js +285 -0
- package/dist/scenarios/types.d.ts +153 -0
- package/dist/scenarios/types.js +8 -0
- package/dist/security/index.d.ts +17 -0
- package/dist/security/index.js +18 -0
- package/dist/security/payloads.d.ts +61 -0
- package/dist/security/payloads.js +268 -0
- package/dist/security/security-tester.d.ts +42 -0
- package/dist/security/security-tester.js +582 -0
- package/dist/security/types.d.ts +166 -0
- package/dist/security/types.js +8 -0
- package/dist/transport/base-transport.d.ts +59 -0
- package/dist/transport/base-transport.js +38 -0
- package/dist/transport/http-transport.d.ts +67 -0
- package/dist/transport/http-transport.js +238 -0
- package/dist/transport/mcp-client.d.ts +141 -0
- package/dist/transport/mcp-client.js +496 -0
- package/dist/transport/sse-transport.d.ts +88 -0
- package/dist/transport/sse-transport.js +316 -0
- package/dist/transport/stdio-transport.d.ts +43 -0
- package/dist/transport/stdio-transport.js +238 -0
- package/dist/transport/types.d.ts +125 -0
- package/dist/transport/types.js +16 -0
- package/dist/utils/concurrency.d.ts +123 -0
- package/dist/utils/concurrency.js +213 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +37 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jsonpath.d.ts +87 -0
- package/dist/utils/jsonpath.js +326 -0
- package/dist/utils/markdown.d.ts +113 -0
- package/dist/utils/markdown.js +265 -0
- package/dist/utils/network.d.ts +14 -0
- package/dist/utils/network.js +17 -0
- package/dist/utils/sanitize.d.ts +92 -0
- package/dist/utils/sanitize.js +191 -0
- package/dist/utils/semantic.d.ts +194 -0
- package/dist/utils/semantic.js +1051 -0
- package/dist/utils/smart-truncate.d.ts +94 -0
- package/dist/utils/smart-truncate.js +361 -0
- package/dist/utils/timeout.d.ts +153 -0
- package/dist/utils/timeout.js +205 -0
- package/dist/utils/yaml-parser.d.ts +58 -0
- package/dist/utils/yaml-parser.js +86 -0
- package/dist/validation/index.d.ts +32 -0
- package/dist/validation/index.js +32 -0
- package/dist/validation/semantic-test-generator.d.ts +50 -0
- package/dist/validation/semantic-test-generator.js +176 -0
- package/dist/validation/semantic-types.d.ts +66 -0
- package/dist/validation/semantic-types.js +94 -0
- package/dist/validation/semantic-validator.d.ts +38 -0
- package/dist/validation/semantic-validator.js +340 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.js +5 -0
- package/dist/verification/types.d.ts +133 -0
- package/dist/verification/types.js +5 -0
- package/dist/verification/verifier.d.ts +30 -0
- package/dist/verification/verifier.js +309 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +48 -0
- package/dist/workflow/auto-generator.d.ts +27 -0
- package/dist/workflow/auto-generator.js +513 -0
- package/dist/workflow/discovery.d.ts +40 -0
- package/dist/workflow/discovery.js +195 -0
- package/dist/workflow/executor.d.ts +82 -0
- package/dist/workflow/executor.js +611 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/loader.d.ts +24 -0
- package/dist/workflow/loader.js +194 -0
- package/dist/workflow/state-tracker.d.ts +98 -0
- package/dist/workflow/state-tracker.js +424 -0
- package/dist/workflow/types.d.ts +337 -0
- package/dist/workflow/types.js +5 -0
- package/package.json +94 -0
- package/schemas/bellwether-check.schema.json +651 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documentation quality scoring for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Calculates documentation quality metrics including:
|
|
5
|
+
* - Description coverage (percentage of tools with descriptions)
|
|
6
|
+
* - Description quality (depth, clarity, actionable language)
|
|
7
|
+
* - Parameter documentation (percentage of params documented)
|
|
8
|
+
* - Example coverage (percentage of tools with examples)
|
|
9
|
+
*
|
|
10
|
+
* Overall score: 0-100 with grade A-F.
|
|
11
|
+
*/
|
|
12
|
+
import type { MCPTool } from '../transport/types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Issue severity levels for documentation problems.
|
|
15
|
+
*/
|
|
16
|
+
export type DocumentationIssueSeverity = 'error' | 'warning' | 'info';
|
|
17
|
+
/**
|
|
18
|
+
* Types of documentation issues that can be detected.
|
|
19
|
+
*/
|
|
20
|
+
export type DocumentationIssueType = 'missing_description' | 'short_description' | 'missing_param_description' | 'no_examples';
|
|
21
|
+
/**
|
|
22
|
+
* A specific documentation issue found during scoring.
|
|
23
|
+
*/
|
|
24
|
+
export interface DocumentationIssue {
|
|
25
|
+
/** Tool name where issue was found */
|
|
26
|
+
tool: string;
|
|
27
|
+
/** Type of issue */
|
|
28
|
+
type: DocumentationIssueType;
|
|
29
|
+
/** Severity level */
|
|
30
|
+
severity: DocumentationIssueSeverity;
|
|
31
|
+
/** Human-readable message describing the issue */
|
|
32
|
+
message: string;
|
|
33
|
+
/** Parameter name (for parameter-specific issues) */
|
|
34
|
+
paramName?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Component scores that make up the overall documentation score.
|
|
38
|
+
*/
|
|
39
|
+
export interface DocumentationComponents {
|
|
40
|
+
/** Percentage of tools with descriptions (0-100) */
|
|
41
|
+
descriptionCoverage: number;
|
|
42
|
+
/** Quality score for descriptions (0-100) */
|
|
43
|
+
descriptionQuality: number;
|
|
44
|
+
/** Percentage of parameters with descriptions (0-100) */
|
|
45
|
+
parameterDocumentation: number;
|
|
46
|
+
/** Percentage of tools with examples (0-100) */
|
|
47
|
+
exampleCoverage: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Documentation grade (A-F).
|
|
51
|
+
*/
|
|
52
|
+
export type DocumentationGrade = 'A' | 'B' | 'C' | 'D' | 'F';
|
|
53
|
+
/**
|
|
54
|
+
* Complete documentation quality score for a set of tools.
|
|
55
|
+
*/
|
|
56
|
+
export interface DocumentationScore {
|
|
57
|
+
/** Overall score (0-100) */
|
|
58
|
+
overallScore: number;
|
|
59
|
+
/** Grade (A-F) */
|
|
60
|
+
grade: DocumentationGrade;
|
|
61
|
+
/** Component scores */
|
|
62
|
+
components: DocumentationComponents;
|
|
63
|
+
/** Specific issues found */
|
|
64
|
+
issues: DocumentationIssue[];
|
|
65
|
+
/** Improvement suggestions */
|
|
66
|
+
suggestions: string[];
|
|
67
|
+
/** Number of tools scored */
|
|
68
|
+
toolCount: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Score for a single tool's documentation.
|
|
72
|
+
*/
|
|
73
|
+
export interface ToolDocumentationScore {
|
|
74
|
+
/** Tool name */
|
|
75
|
+
tool: string;
|
|
76
|
+
/** Individual score (0-100) */
|
|
77
|
+
score: number;
|
|
78
|
+
/** Issues found for this tool */
|
|
79
|
+
issues: DocumentationIssue[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Change in documentation score between baselines.
|
|
83
|
+
*/
|
|
84
|
+
export interface DocumentationScoreChange {
|
|
85
|
+
/** Previous overall score */
|
|
86
|
+
previousScore: number;
|
|
87
|
+
/** Current overall score */
|
|
88
|
+
currentScore: number;
|
|
89
|
+
/** Score change (positive = improved) */
|
|
90
|
+
change: number;
|
|
91
|
+
/** Previous grade */
|
|
92
|
+
previousGrade: DocumentationGrade;
|
|
93
|
+
/** Current grade */
|
|
94
|
+
currentGrade: DocumentationGrade;
|
|
95
|
+
/** Whether documentation improved */
|
|
96
|
+
improved: boolean;
|
|
97
|
+
/** Whether documentation degraded */
|
|
98
|
+
degraded: boolean;
|
|
99
|
+
/** Issues that were fixed */
|
|
100
|
+
issuesFixed: number;
|
|
101
|
+
/** New issues introduced */
|
|
102
|
+
newIssues: number;
|
|
103
|
+
/** Human-readable summary */
|
|
104
|
+
summary: string;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Serializable documentation score summary for baseline storage.
|
|
108
|
+
*/
|
|
109
|
+
export interface DocumentationScoreSummary {
|
|
110
|
+
/** Overall score (0-100) */
|
|
111
|
+
overallScore: number;
|
|
112
|
+
/** Grade (A-F) */
|
|
113
|
+
grade: string;
|
|
114
|
+
/** Number of issues found */
|
|
115
|
+
issueCount: number;
|
|
116
|
+
/** Number of tools scored */
|
|
117
|
+
toolCount: number;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Score documentation quality for a set of tools.
|
|
121
|
+
*
|
|
122
|
+
* @param tools - Array of MCP tools to score
|
|
123
|
+
* @returns Complete documentation score with components, issues, and suggestions
|
|
124
|
+
*/
|
|
125
|
+
export declare function scoreDocumentation(tools: MCPTool[]): DocumentationScore;
|
|
126
|
+
/**
|
|
127
|
+
* Score a single tool's documentation quality.
|
|
128
|
+
*
|
|
129
|
+
* @param tool - MCP tool to score
|
|
130
|
+
* @returns Tool score with issues
|
|
131
|
+
*/
|
|
132
|
+
export declare function scoreToolDocumentation(tool: MCPTool): ToolDocumentationScore;
|
|
133
|
+
/**
|
|
134
|
+
* Calculate description coverage score.
|
|
135
|
+
* Percentage of tools that have non-empty descriptions.
|
|
136
|
+
*/
|
|
137
|
+
export declare function calculateDescriptionCoverage(tools: MCPTool[]): number;
|
|
138
|
+
/**
|
|
139
|
+
* Calculate description quality score.
|
|
140
|
+
* Assesses length, imperative mood, behavior description, and examples.
|
|
141
|
+
*/
|
|
142
|
+
export declare function calculateDescriptionQuality(tools: MCPTool[]): number;
|
|
143
|
+
/**
|
|
144
|
+
* Calculate parameter documentation score.
|
|
145
|
+
* Percentage of parameters across all tools that have descriptions.
|
|
146
|
+
*/
|
|
147
|
+
export declare function calculateParameterDocumentation(tools: MCPTool[]): number;
|
|
148
|
+
/**
|
|
149
|
+
* Calculate example coverage score.
|
|
150
|
+
* Percentage of tools that have schema-level or property-level examples.
|
|
151
|
+
*/
|
|
152
|
+
export declare function calculateExampleCoverage(tools: MCPTool[]): number;
|
|
153
|
+
/**
|
|
154
|
+
* Check if a tool has any examples defined in its schema.
|
|
155
|
+
*/
|
|
156
|
+
export declare function hasExamples(tool: MCPTool): boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Convert a numeric score to a letter grade.
|
|
159
|
+
*/
|
|
160
|
+
export declare function scoreToGrade(score: number): DocumentationGrade;
|
|
161
|
+
/**
|
|
162
|
+
* Generate improvement suggestions based on issues found.
|
|
163
|
+
*/
|
|
164
|
+
export declare function generateSuggestions(issues: DocumentationIssue[], tools: MCPTool[]): string[];
|
|
165
|
+
/**
|
|
166
|
+
* Compare documentation scores between baselines.
|
|
167
|
+
*
|
|
168
|
+
* @param previous - Previous documentation score (or summary)
|
|
169
|
+
* @param current - Current documentation score
|
|
170
|
+
* @returns Change analysis
|
|
171
|
+
*/
|
|
172
|
+
export declare function compareDocumentationScores(previous: DocumentationScore | DocumentationScoreSummary | undefined, current: DocumentationScore): DocumentationScoreChange;
|
|
173
|
+
/**
|
|
174
|
+
* Format documentation score as a human-readable string.
|
|
175
|
+
*/
|
|
176
|
+
export declare function formatDocumentationScore(score: DocumentationScore): string;
|
|
177
|
+
/**
|
|
178
|
+
* Format documentation score as a compact one-line summary.
|
|
179
|
+
*/
|
|
180
|
+
export declare function formatDocumentationScoreCompact(score: DocumentationScore): string;
|
|
181
|
+
/**
|
|
182
|
+
* Format documentation score change as a human-readable string.
|
|
183
|
+
*/
|
|
184
|
+
export declare function formatDocumentationScoreChange(change: DocumentationScoreChange): string;
|
|
185
|
+
/**
|
|
186
|
+
* Convert documentation score to a serializable summary for baseline storage.
|
|
187
|
+
*/
|
|
188
|
+
export declare function toDocumentationScoreSummary(score: DocumentationScore): DocumentationScoreSummary;
|
|
189
|
+
/**
|
|
190
|
+
* Get the emoji indicator for a documentation grade.
|
|
191
|
+
*/
|
|
192
|
+
export declare function getGradeIndicator(grade: DocumentationGrade): string;
|
|
193
|
+
/**
|
|
194
|
+
* Get the badge color for a documentation grade.
|
|
195
|
+
*/
|
|
196
|
+
export declare function getGradeBadgeColor(grade: DocumentationGrade): 'green' | 'yellow' | 'orange' | 'red';
|
|
197
|
+
/**
|
|
198
|
+
* Check if a documentation score meets a minimum threshold.
|
|
199
|
+
*/
|
|
200
|
+
export declare function meetsDocumentationThreshold(score: DocumentationScore, minScore: number): boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Check if documentation score meets a minimum grade.
|
|
203
|
+
*/
|
|
204
|
+
export declare function meetsDocumentationGrade(score: DocumentationScore, minGrade: DocumentationGrade): boolean;
|
|
205
|
+
//# sourceMappingURL=documentation-scorer.d.ts.map
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documentation quality scoring for MCP tools.
|
|
3
|
+
*
|
|
4
|
+
* Calculates documentation quality metrics including:
|
|
5
|
+
* - Description coverage (percentage of tools with descriptions)
|
|
6
|
+
* - Description quality (depth, clarity, actionable language)
|
|
7
|
+
* - Parameter documentation (percentage of params documented)
|
|
8
|
+
* - Example coverage (percentage of tools with examples)
|
|
9
|
+
*
|
|
10
|
+
* Overall score: 0-100 with grade A-F.
|
|
11
|
+
*/
|
|
12
|
+
import { DOCUMENTATION_SCORING } from '../constants.js';
|
|
13
|
+
// ==================== Main Scoring Functions ====================
|
|
14
|
+
/**
|
|
15
|
+
* Score documentation quality for a set of tools.
|
|
16
|
+
*
|
|
17
|
+
* @param tools - Array of MCP tools to score
|
|
18
|
+
* @returns Complete documentation score with components, issues, and suggestions
|
|
19
|
+
*/
|
|
20
|
+
export function scoreDocumentation(tools) {
|
|
21
|
+
if (tools.length === 0) {
|
|
22
|
+
return {
|
|
23
|
+
overallScore: 100,
|
|
24
|
+
grade: 'A',
|
|
25
|
+
components: {
|
|
26
|
+
descriptionCoverage: 100,
|
|
27
|
+
descriptionQuality: 100,
|
|
28
|
+
parameterDocumentation: 100,
|
|
29
|
+
exampleCoverage: 100,
|
|
30
|
+
},
|
|
31
|
+
issues: [],
|
|
32
|
+
suggestions: [],
|
|
33
|
+
toolCount: 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// Score individual tools and collect issues
|
|
37
|
+
const toolScores = tools.map(scoreToolDocumentation);
|
|
38
|
+
const issues = toolScores.flatMap((t) => t.issues);
|
|
39
|
+
// Calculate component scores
|
|
40
|
+
const descriptionCoverage = calculateDescriptionCoverage(tools);
|
|
41
|
+
const descriptionQuality = calculateDescriptionQuality(tools);
|
|
42
|
+
const parameterDocumentation = calculateParameterDocumentation(tools);
|
|
43
|
+
const exampleCoverage = calculateExampleCoverage(tools);
|
|
44
|
+
// Calculate weighted overall score
|
|
45
|
+
const weights = DOCUMENTATION_SCORING.WEIGHTS;
|
|
46
|
+
const overallScore = Math.round(descriptionCoverage * weights.descriptionCoverage +
|
|
47
|
+
descriptionQuality * weights.descriptionQuality +
|
|
48
|
+
parameterDocumentation * weights.parameterDocumentation +
|
|
49
|
+
exampleCoverage * weights.exampleCoverage);
|
|
50
|
+
const grade = scoreToGrade(overallScore);
|
|
51
|
+
const suggestions = generateSuggestions(issues, tools);
|
|
52
|
+
return {
|
|
53
|
+
overallScore,
|
|
54
|
+
grade,
|
|
55
|
+
components: {
|
|
56
|
+
descriptionCoverage,
|
|
57
|
+
descriptionQuality,
|
|
58
|
+
parameterDocumentation,
|
|
59
|
+
exampleCoverage,
|
|
60
|
+
},
|
|
61
|
+
issues,
|
|
62
|
+
suggestions,
|
|
63
|
+
toolCount: tools.length,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Score a single tool's documentation quality.
|
|
68
|
+
*
|
|
69
|
+
* @param tool - MCP tool to score
|
|
70
|
+
* @returns Tool score with issues
|
|
71
|
+
*/
|
|
72
|
+
export function scoreToolDocumentation(tool) {
|
|
73
|
+
const issues = [];
|
|
74
|
+
let score = 100;
|
|
75
|
+
const penalties = DOCUMENTATION_SCORING.PENALTIES;
|
|
76
|
+
const descConfig = DOCUMENTATION_SCORING.DESCRIPTION;
|
|
77
|
+
// Check tool description
|
|
78
|
+
const description = tool.description?.trim() ?? '';
|
|
79
|
+
if (description.length === 0) {
|
|
80
|
+
issues.push({
|
|
81
|
+
tool: tool.name,
|
|
82
|
+
type: 'missing_description',
|
|
83
|
+
severity: DOCUMENTATION_SCORING.SEVERITY.missingDescription,
|
|
84
|
+
message: `Tool "${tool.name}" has no description`,
|
|
85
|
+
});
|
|
86
|
+
score -= penalties.missingDescription;
|
|
87
|
+
}
|
|
88
|
+
else if (description.length < descConfig.MIN_ACCEPTABLE_LENGTH) {
|
|
89
|
+
issues.push({
|
|
90
|
+
tool: tool.name,
|
|
91
|
+
type: 'short_description',
|
|
92
|
+
severity: DOCUMENTATION_SCORING.SEVERITY.shortDescription,
|
|
93
|
+
message: `Tool "${tool.name}" has a very short description (${description.length} chars)`,
|
|
94
|
+
});
|
|
95
|
+
score -= penalties.shortDescription;
|
|
96
|
+
}
|
|
97
|
+
// Check parameter descriptions
|
|
98
|
+
const schema = tool.inputSchema;
|
|
99
|
+
if (schema?.properties) {
|
|
100
|
+
const params = Object.entries(schema.properties);
|
|
101
|
+
const undocumentedParams = params.filter(([_, p]) => !p.description?.trim());
|
|
102
|
+
for (const [paramName] of undocumentedParams) {
|
|
103
|
+
issues.push({
|
|
104
|
+
tool: tool.name,
|
|
105
|
+
type: 'missing_param_description',
|
|
106
|
+
severity: DOCUMENTATION_SCORING.SEVERITY.missingParamDescription,
|
|
107
|
+
message: `Parameter "${paramName}" in "${tool.name}" has no description`,
|
|
108
|
+
paramName,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (undocumentedParams.length > 0 && params.length > 0) {
|
|
112
|
+
const coverage = 1 - undocumentedParams.length / params.length;
|
|
113
|
+
score -= Math.round((1 - coverage) * penalties.undocumentedParamMultiplier);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
tool: tool.name,
|
|
118
|
+
score: Math.max(0, score),
|
|
119
|
+
issues,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ==================== Component Score Calculations ====================
|
|
123
|
+
/**
|
|
124
|
+
* Calculate description coverage score.
|
|
125
|
+
* Percentage of tools that have non-empty descriptions.
|
|
126
|
+
*/
|
|
127
|
+
export function calculateDescriptionCoverage(tools) {
|
|
128
|
+
if (tools.length === 0)
|
|
129
|
+
return 100;
|
|
130
|
+
const withDescription = tools.filter((t) => t.description?.trim().length);
|
|
131
|
+
return Math.round((withDescription.length / tools.length) * 100);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Calculate description quality score.
|
|
135
|
+
* Assesses length, imperative mood, behavior description, and examples.
|
|
136
|
+
*/
|
|
137
|
+
export function calculateDescriptionQuality(tools) {
|
|
138
|
+
if (tools.length === 0)
|
|
139
|
+
return 100;
|
|
140
|
+
const descConfig = DOCUMENTATION_SCORING.DESCRIPTION;
|
|
141
|
+
let totalScore = 0;
|
|
142
|
+
for (const tool of tools) {
|
|
143
|
+
const desc = tool.description?.trim() ?? '';
|
|
144
|
+
let score = 0;
|
|
145
|
+
// Length scoring
|
|
146
|
+
if (desc.length >= descConfig.MIN_GOOD_LENGTH) {
|
|
147
|
+
score += descConfig.GOOD_LENGTH_SCORE;
|
|
148
|
+
}
|
|
149
|
+
else if (desc.length >= descConfig.MIN_ACCEPTABLE_LENGTH) {
|
|
150
|
+
score += descConfig.ACCEPTABLE_LENGTH_SCORE;
|
|
151
|
+
}
|
|
152
|
+
// Check for imperative verb at start (e.g., "Creates", "Gets", "Sends")
|
|
153
|
+
if (DOCUMENTATION_SCORING.IMPERATIVE_PATTERN.test(desc)) {
|
|
154
|
+
score += descConfig.IMPERATIVE_VERB_BONUS;
|
|
155
|
+
}
|
|
156
|
+
// Check for mention of behavior or return value
|
|
157
|
+
if (DOCUMENTATION_SCORING.BEHAVIOR_PATTERN.test(desc)) {
|
|
158
|
+
score += descConfig.BEHAVIOR_DESCRIPTION_BONUS;
|
|
159
|
+
}
|
|
160
|
+
// Check for examples or specific details
|
|
161
|
+
if (DOCUMENTATION_SCORING.EXAMPLES_PATTERN.test(desc)) {
|
|
162
|
+
score += descConfig.EXAMPLES_BONUS;
|
|
163
|
+
}
|
|
164
|
+
totalScore += score;
|
|
165
|
+
}
|
|
166
|
+
return Math.round(totalScore / tools.length);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Calculate parameter documentation score.
|
|
170
|
+
* Percentage of parameters across all tools that have descriptions.
|
|
171
|
+
*/
|
|
172
|
+
export function calculateParameterDocumentation(tools) {
|
|
173
|
+
let totalParams = 0;
|
|
174
|
+
let documentedParams = 0;
|
|
175
|
+
for (const tool of tools) {
|
|
176
|
+
const schema = tool.inputSchema;
|
|
177
|
+
if (schema?.properties) {
|
|
178
|
+
for (const prop of Object.values(schema.properties)) {
|
|
179
|
+
totalParams++;
|
|
180
|
+
if (prop.description?.trim()) {
|
|
181
|
+
documentedParams++;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (totalParams === 0)
|
|
187
|
+
return 100;
|
|
188
|
+
return Math.round((documentedParams / totalParams) * 100);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Calculate example coverage score.
|
|
192
|
+
* Percentage of tools that have schema-level or property-level examples.
|
|
193
|
+
*/
|
|
194
|
+
export function calculateExampleCoverage(tools) {
|
|
195
|
+
if (tools.length === 0)
|
|
196
|
+
return 100;
|
|
197
|
+
let toolsWithExamples = 0;
|
|
198
|
+
for (const tool of tools) {
|
|
199
|
+
if (hasExamples(tool)) {
|
|
200
|
+
toolsWithExamples++;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return Math.round((toolsWithExamples / tools.length) * 100);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if a tool has any examples defined in its schema.
|
|
207
|
+
*/
|
|
208
|
+
export function hasExamples(tool) {
|
|
209
|
+
const schema = tool.inputSchema;
|
|
210
|
+
// Check for schema-level examples
|
|
211
|
+
if (schema?.examples && schema.examples.length > 0) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
// Check for property-level examples
|
|
215
|
+
if (schema?.properties) {
|
|
216
|
+
return Object.values(schema.properties).some((p) => p.examples?.length);
|
|
217
|
+
}
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
// ==================== Grade & Suggestions ====================
|
|
221
|
+
/**
|
|
222
|
+
* Convert a numeric score to a letter grade.
|
|
223
|
+
*/
|
|
224
|
+
export function scoreToGrade(score) {
|
|
225
|
+
const thresholds = DOCUMENTATION_SCORING.GRADE_THRESHOLDS;
|
|
226
|
+
if (score >= thresholds.A)
|
|
227
|
+
return 'A';
|
|
228
|
+
if (score >= thresholds.B)
|
|
229
|
+
return 'B';
|
|
230
|
+
if (score >= thresholds.C)
|
|
231
|
+
return 'C';
|
|
232
|
+
if (score >= thresholds.D)
|
|
233
|
+
return 'D';
|
|
234
|
+
return 'F';
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Generate improvement suggestions based on issues found.
|
|
238
|
+
*/
|
|
239
|
+
export function generateSuggestions(issues, tools) {
|
|
240
|
+
const suggestions = [];
|
|
241
|
+
const maxSuggestions = DOCUMENTATION_SCORING.MAX_SUGGESTIONS;
|
|
242
|
+
// Suggest fixing missing descriptions
|
|
243
|
+
const missingDescriptions = issues.filter((i) => i.type === 'missing_description');
|
|
244
|
+
if (missingDescriptions.length > 0) {
|
|
245
|
+
const toolNames = missingDescriptions.map((i) => i.tool);
|
|
246
|
+
if (toolNames.length <= 3) {
|
|
247
|
+
suggestions.push(`Add descriptions to tool(s): ${toolNames.join(', ')}`);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
suggestions.push(`Add descriptions to ${missingDescriptions.length} tool(s) missing documentation`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Suggest expanding short descriptions
|
|
254
|
+
const shortDescriptions = issues.filter((i) => i.type === 'short_description');
|
|
255
|
+
if (shortDescriptions.length > 0) {
|
|
256
|
+
suggestions.push(`Expand descriptions for ${shortDescriptions.length} tool(s) to at least ${DOCUMENTATION_SCORING.DESCRIPTION.MIN_GOOD_LENGTH} characters`);
|
|
257
|
+
}
|
|
258
|
+
// Suggest adding parameter descriptions
|
|
259
|
+
const missingParams = issues.filter((i) => i.type === 'missing_param_description');
|
|
260
|
+
if (missingParams.length > 0) {
|
|
261
|
+
const uniqueTools = new Set(missingParams.map((i) => i.tool));
|
|
262
|
+
suggestions.push(`Add descriptions to ${missingParams.length} parameter(s) across ${uniqueTools.size} tool(s)`);
|
|
263
|
+
}
|
|
264
|
+
// Check for missing examples
|
|
265
|
+
if (tools.length > 0) {
|
|
266
|
+
const toolsWithoutExamples = tools.filter((t) => !hasExamples(t));
|
|
267
|
+
const ratio = toolsWithoutExamples.length / tools.length;
|
|
268
|
+
if (ratio > DOCUMENTATION_SCORING.EXAMPLES_SUGGESTION_THRESHOLD) {
|
|
269
|
+
suggestions.push('Consider adding examples to tool schemas to improve documentation');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return suggestions.slice(0, maxSuggestions);
|
|
273
|
+
}
|
|
274
|
+
// ==================== Comparison Functions ====================
|
|
275
|
+
/**
|
|
276
|
+
* Compare documentation scores between baselines.
|
|
277
|
+
*
|
|
278
|
+
* @param previous - Previous documentation score (or summary)
|
|
279
|
+
* @param current - Current documentation score
|
|
280
|
+
* @returns Change analysis
|
|
281
|
+
*/
|
|
282
|
+
export function compareDocumentationScores(previous, current) {
|
|
283
|
+
if (!previous) {
|
|
284
|
+
return {
|
|
285
|
+
previousScore: 0,
|
|
286
|
+
currentScore: current.overallScore,
|
|
287
|
+
change: current.overallScore,
|
|
288
|
+
previousGrade: 'F',
|
|
289
|
+
currentGrade: current.grade,
|
|
290
|
+
improved: current.overallScore > 0,
|
|
291
|
+
degraded: false,
|
|
292
|
+
issuesFixed: 0,
|
|
293
|
+
newIssues: current.issues.length,
|
|
294
|
+
summary: `Initial documentation score: ${current.overallScore} (${current.grade})`,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
const prevScore = previous.overallScore;
|
|
298
|
+
const prevGrade = previous.grade || scoreToGrade(prevScore);
|
|
299
|
+
const prevIssueCount = 'issueCount' in previous ? previous.issueCount : previous.issues.length;
|
|
300
|
+
const change = current.overallScore - prevScore;
|
|
301
|
+
const improved = change > 0;
|
|
302
|
+
const degraded = change < 0;
|
|
303
|
+
// Calculate issues fixed/introduced
|
|
304
|
+
const currentIssueCount = current.issues.length;
|
|
305
|
+
const issuesFixed = Math.max(0, prevIssueCount - currentIssueCount);
|
|
306
|
+
const newIssues = Math.max(0, currentIssueCount - prevIssueCount);
|
|
307
|
+
// Generate summary
|
|
308
|
+
let summary;
|
|
309
|
+
if (change === 0) {
|
|
310
|
+
summary = `Documentation score unchanged at ${current.overallScore} (${current.grade})`;
|
|
311
|
+
}
|
|
312
|
+
else if (improved) {
|
|
313
|
+
summary = `Documentation improved: ${prevScore} -> ${current.overallScore} (+${change}) | Grade: ${prevGrade} -> ${current.grade}`;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
summary = `Documentation degraded: ${prevScore} -> ${current.overallScore} (${change}) | Grade: ${prevGrade} -> ${current.grade}`;
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
previousScore: prevScore,
|
|
320
|
+
currentScore: current.overallScore,
|
|
321
|
+
change,
|
|
322
|
+
previousGrade: prevGrade,
|
|
323
|
+
currentGrade: current.grade,
|
|
324
|
+
improved,
|
|
325
|
+
degraded,
|
|
326
|
+
issuesFixed,
|
|
327
|
+
newIssues,
|
|
328
|
+
summary,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
// ==================== Formatting Functions ====================
|
|
332
|
+
/**
|
|
333
|
+
* Format documentation score as a human-readable string.
|
|
334
|
+
*/
|
|
335
|
+
export function formatDocumentationScore(score) {
|
|
336
|
+
const lines = [];
|
|
337
|
+
lines.push(`Documentation Quality: ${score.overallScore}/100 (${score.grade})`);
|
|
338
|
+
lines.push('');
|
|
339
|
+
lines.push('Components:');
|
|
340
|
+
lines.push(` Description Coverage: ${score.components.descriptionCoverage}%`);
|
|
341
|
+
lines.push(` Description Quality: ${score.components.descriptionQuality}%`);
|
|
342
|
+
lines.push(` Parameter Documentation: ${score.components.parameterDocumentation}%`);
|
|
343
|
+
lines.push(` Example Coverage: ${score.components.exampleCoverage}%`);
|
|
344
|
+
if (score.issues.length > 0) {
|
|
345
|
+
lines.push('');
|
|
346
|
+
lines.push(`Issues (${score.issues.length}):`);
|
|
347
|
+
const issuesByType = groupIssuesByType(score.issues);
|
|
348
|
+
for (const [type, issues] of Object.entries(issuesByType)) {
|
|
349
|
+
lines.push(` ${formatIssueType(type)}: ${issues.length}`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (score.suggestions.length > 0) {
|
|
353
|
+
lines.push('');
|
|
354
|
+
lines.push('Suggestions:');
|
|
355
|
+
for (const suggestion of score.suggestions) {
|
|
356
|
+
lines.push(` - ${suggestion}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return lines.join('\n');
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Format documentation score as a compact one-line summary.
|
|
363
|
+
*/
|
|
364
|
+
export function formatDocumentationScoreCompact(score) {
|
|
365
|
+
const issueCount = score.issues.length;
|
|
366
|
+
const issueSuffix = issueCount > 0 ? ` | ${issueCount} issue(s)` : '';
|
|
367
|
+
return `Documentation: ${score.overallScore}/100 (${score.grade})${issueSuffix}`;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Format documentation score change as a human-readable string.
|
|
371
|
+
*/
|
|
372
|
+
export function formatDocumentationScoreChange(change) {
|
|
373
|
+
const lines = [];
|
|
374
|
+
lines.push(change.summary);
|
|
375
|
+
if (change.issuesFixed > 0) {
|
|
376
|
+
lines.push(` Issues fixed: ${change.issuesFixed}`);
|
|
377
|
+
}
|
|
378
|
+
if (change.newIssues > 0) {
|
|
379
|
+
lines.push(` New issues: ${change.newIssues}`);
|
|
380
|
+
}
|
|
381
|
+
return lines.join('\n');
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Convert documentation score to a serializable summary for baseline storage.
|
|
385
|
+
*/
|
|
386
|
+
export function toDocumentationScoreSummary(score) {
|
|
387
|
+
return {
|
|
388
|
+
overallScore: score.overallScore,
|
|
389
|
+
grade: score.grade,
|
|
390
|
+
issueCount: score.issues.length,
|
|
391
|
+
toolCount: score.toolCount,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
// ==================== Helpers ====================
|
|
395
|
+
/**
|
|
396
|
+
* Group issues by their type.
|
|
397
|
+
*/
|
|
398
|
+
function groupIssuesByType(issues) {
|
|
399
|
+
const grouped = {};
|
|
400
|
+
for (const issue of issues) {
|
|
401
|
+
if (!grouped[issue.type]) {
|
|
402
|
+
grouped[issue.type] = [];
|
|
403
|
+
}
|
|
404
|
+
grouped[issue.type].push(issue);
|
|
405
|
+
}
|
|
406
|
+
return grouped;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Format issue type for display.
|
|
410
|
+
*/
|
|
411
|
+
function formatIssueType(type) {
|
|
412
|
+
return type
|
|
413
|
+
.split('_')
|
|
414
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
415
|
+
.join(' ');
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Get the emoji indicator for a documentation grade.
|
|
419
|
+
*/
|
|
420
|
+
export function getGradeIndicator(grade) {
|
|
421
|
+
switch (grade) {
|
|
422
|
+
case 'A':
|
|
423
|
+
return '✓';
|
|
424
|
+
case 'B':
|
|
425
|
+
return '✓';
|
|
426
|
+
case 'C':
|
|
427
|
+
return '~';
|
|
428
|
+
case 'D':
|
|
429
|
+
return '!';
|
|
430
|
+
case 'F':
|
|
431
|
+
return '✗';
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Get the badge color for a documentation grade.
|
|
436
|
+
*/
|
|
437
|
+
export function getGradeBadgeColor(grade) {
|
|
438
|
+
switch (grade) {
|
|
439
|
+
case 'A':
|
|
440
|
+
return 'green';
|
|
441
|
+
case 'B':
|
|
442
|
+
return 'green';
|
|
443
|
+
case 'C':
|
|
444
|
+
return 'yellow';
|
|
445
|
+
case 'D':
|
|
446
|
+
return 'orange';
|
|
447
|
+
case 'F':
|
|
448
|
+
return 'red';
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Check if a documentation score meets a minimum threshold.
|
|
453
|
+
*/
|
|
454
|
+
export function meetsDocumentationThreshold(score, minScore) {
|
|
455
|
+
return score.overallScore >= minScore;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Check if documentation score meets a minimum grade.
|
|
459
|
+
*/
|
|
460
|
+
export function meetsDocumentationGrade(score, minGrade) {
|
|
461
|
+
const gradeOrder = ['F', 'D', 'C', 'B', 'A'];
|
|
462
|
+
const scoreIndex = gradeOrder.indexOf(score.grade);
|
|
463
|
+
const minIndex = gradeOrder.indexOf(minGrade);
|
|
464
|
+
return scoreIndex >= minIndex;
|
|
465
|
+
}
|
|
466
|
+
//# sourceMappingURL=documentation-scorer.js.map
|