@doccov/sdk 0.26.0 → 0.27.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.
@@ -484,7 +484,7 @@ declare function getExportMissing(exp: SpecExport7, doccov: DocCovSpec2): Missin
484
484
  declare function isExportFullyDocumented(exp: SpecExport7, doccov: DocCovSpec2): boolean;
485
485
  import { DocCovSpec as DocCovSpec3 } from "@doccov/spec";
486
486
  import { OpenPkg as OpenPkg3 } from "@openpkg-ts/spec";
487
- import { ApiSurfaceResult } from "@doccov/spec";
487
+ import { ApiSurfaceResult, DocumentationHealth } from "@doccov/spec";
488
488
  /**
489
489
  * Drift summary with category breakdown.
490
490
  */
@@ -594,6 +594,10 @@ interface DocCovReport {
594
594
  * API surface analysis (forgotten exports).
595
595
  */
596
596
  apiSurface?: ApiSurfaceResult;
597
+ /**
598
+ * Unified documentation health score.
599
+ */
600
+ health?: DocumentationHealth;
597
601
  }
598
602
  /**
599
603
  * Generate a DocCov report from an OpenPkg spec.
@@ -38,7 +38,7 @@ import {
38
38
  renderSparkline,
39
39
  saveReport,
40
40
  saveSnapshot
41
- } from "../shared/chunk-yqqqk8by.js";
41
+ } from "../shared/chunk-v62zsv8j.js";
42
42
  import"../shared/chunk-esptwrfq.js";
43
43
  export {
44
44
  saveSnapshot,
package/dist/index.d.ts CHANGED
@@ -1,3 +1,39 @@
1
+ import { DocumentationHealth, DriftCategory, MissingDocRule } from "@doccov/spec";
2
+ /**
3
+ * Input data for computing documentation health score.
4
+ */
5
+ interface HealthInput {
6
+ /** Coverage score (0-100) */
7
+ coverageScore: number;
8
+ /** Number of documented exports */
9
+ documentedExports: number;
10
+ /** Total exports analyzed */
11
+ totalExports: number;
12
+ /** Missing docs by rule */
13
+ missingByRule: Record<MissingDocRule, number>;
14
+ /** Total drift issues */
15
+ driftIssues: number;
16
+ /** Fixable drift issues */
17
+ fixableDrift: number;
18
+ /** Drift by category */
19
+ driftByCategory: Record<DriftCategory, number>;
20
+ /** Example validation results (optional) */
21
+ examples?: {
22
+ passed: number;
23
+ failed: number;
24
+ total: number;
25
+ };
26
+ }
27
+ /**
28
+ * Compute unified documentation health score.
29
+ *
30
+ * Formula: health = completeness × (1 - drift_ratio × 0.5)
31
+ * - Max 50% drift penalty
32
+ * - Optional 30% example penalty if examples validated
33
+ *
34
+ * Score thresholds: green 80+, yellow 60-79, red <60
35
+ */
36
+ declare function computeHealth(input: HealthInput): DocumentationHealth;
1
37
  import { DocCovSpec, TypeReferenceLocation } from "@doccov/spec";
2
38
  import { OpenPkg } from "@openpkg-ts/spec";
3
39
  type OpenPkgSpec = OpenPkg;
@@ -43,19 +79,19 @@ type SpecDocDrift = {
43
79
  /**
44
80
  * Drift categories group related drift types for progressive disclosure.
45
81
  */
46
- type DriftCategory = "structural" | "semantic" | "example";
82
+ type DriftCategory2 = "structural" | "semantic" | "example";
47
83
  /**
48
84
  * Maps each drift type to its category.
49
85
  */
50
- declare const DRIFT_CATEGORIES: Record<DriftType, DriftCategory>;
86
+ declare const DRIFT_CATEGORIES: Record<DriftType, DriftCategory2>;
51
87
  /**
52
88
  * Human-readable category labels.
53
89
  */
54
- declare const DRIFT_CATEGORY_LABELS: Record<DriftCategory, string>;
90
+ declare const DRIFT_CATEGORY_LABELS: Record<DriftCategory2, string>;
55
91
  /**
56
92
  * Category descriptions for help text.
57
93
  */
58
- declare const DRIFT_CATEGORY_DESCRIPTIONS: Record<DriftCategory, string>;
94
+ declare const DRIFT_CATEGORY_DESCRIPTIONS: Record<DriftCategory2, string>;
59
95
  /**
60
96
  * Result of computing drift for a single export.
61
97
  */
@@ -92,7 +128,7 @@ interface ExportRegistry {
92
128
  * Extended drift with category and fixability metadata.
93
129
  */
94
130
  interface CategorizedDrift extends SpecDocDrift {
95
- category: DriftCategory;
131
+ category: DriftCategory2;
96
132
  fixable: boolean;
97
133
  }
98
134
  /**
@@ -100,7 +136,7 @@ interface CategorizedDrift extends SpecDocDrift {
100
136
  */
101
137
  interface DriftSummary {
102
138
  total: number;
103
- byCategory: Record<DriftCategory, number>;
139
+ byCategory: Record<DriftCategory2, number>;
104
140
  fixable: number;
105
141
  }
106
142
  /**
@@ -136,7 +172,7 @@ declare function categorizeDrift(drift: SpecDocDrift): CategorizedDrift;
136
172
  * console.log(grouped.example.length); // Number of example issues
137
173
  * ```
138
174
  */
139
- declare function groupDriftsByCategory(drifts: SpecDocDrift[]): Record<DriftCategory, CategorizedDrift[]>;
175
+ declare function groupDriftsByCategory(drifts: SpecDocDrift[]): Record<DriftCategory2, CategorizedDrift[]>;
140
176
  /**
141
177
  * Get drift summary counts by category.
142
178
  *
@@ -301,7 +337,7 @@ declare function hasNonAssertionComments(code: string): boolean;
301
337
  * Detect assertion failures by comparing stdout to expected values.
302
338
  */
303
339
  declare function detectExampleAssertionFailures(entry: SpecExport2, runtimeResults: Map<number, ExampleRunResult>): SpecDocDrift[];
304
- import { DocCovDrift, DocCovSpec as DocCovSpec2, ExportAnalysis, MissingDocRule } from "@doccov/spec";
340
+ import { DocCovDrift, DocCovSpec as DocCovSpec2, ExportAnalysis, MissingDocRule as MissingDocRule2 } from "@doccov/spec";
305
341
  import { SpecExport as SpecExport7 } from "@openpkg-ts/spec";
306
342
  /**
307
343
  * Get the full analysis data for an export.
@@ -334,7 +370,7 @@ declare function getExportDrift(exp: SpecExport7, doccov: DocCovSpec2): DocCovDr
334
370
  * @param doccov - The DocCov spec containing analysis data
335
371
  * @returns Array of missing rule IDs or empty array if none
336
372
  */
337
- declare function getExportMissing(exp: SpecExport7, doccov: DocCovSpec2): MissingDocRule[];
373
+ declare function getExportMissing(exp: SpecExport7, doccov: DocCovSpec2): MissingDocRule2[];
338
374
  /**
339
375
  * Check if an has complete documentation.
340
376
  *
@@ -345,7 +381,7 @@ declare function getExportMissing(exp: SpecExport7, doccov: DocCovSpec2): Missin
345
381
  declare function isExportFullyDocumented(exp: SpecExport7, doccov: DocCovSpec2): boolean;
346
382
  import { DocCovSpec as DocCovSpec3 } from "@doccov/spec";
347
383
  import { OpenPkg as OpenPkg2 } from "@openpkg-ts/spec";
348
- import { ApiSurfaceResult } from "@doccov/spec";
384
+ import { ApiSurfaceResult, DocumentationHealth as DocumentationHealth2 } from "@doccov/spec";
349
385
  /**
350
386
  * DocCov report schema version.
351
387
  */
@@ -405,7 +441,7 @@ interface DriftReportSummary {
405
441
  /**
406
442
  * Count of issues per category.
407
443
  */
408
- byCategory: Record<DriftCategory, number>;
444
+ byCategory: Record<DriftCategory2, number>;
409
445
  /**
410
446
  * Number of auto-fixable issues.
411
447
  */
@@ -427,7 +463,7 @@ interface DriftReport {
427
463
  /**
428
464
  * Issues grouped by category.
429
465
  */
430
- byCategory: Record<DriftCategory, CategorizedDrift[]>;
466
+ byCategory: Record<DriftCategory2, CategorizedDrift[]>;
431
467
  /**
432
468
  * Flat list of all drift issues (backward compatible).
433
469
  */
@@ -525,6 +561,10 @@ interface DocCovReport {
525
561
  * API surface analysis (forgotten exports).
526
562
  */
527
563
  apiSurface?: ApiSurfaceResult;
564
+ /**
565
+ * Unified documentation health score.
566
+ */
567
+ health?: DocumentationHealth2;
528
568
  }
529
569
  /**
530
570
  * Generate a DocCov report from an OpenPkg spec.
@@ -792,9 +832,17 @@ interface CheckConfig {
792
832
  * - 'run': Execute examples and validate assertions
793
833
  */
794
834
  examples?: ExampleValidationMode | ExampleValidationMode[] | string;
795
- /** Minimum coverage percentage required (0-100) */
835
+ /** Minimum health score required (0-100). Unified metric combining coverage + accuracy. */
836
+ minHealth?: number;
837
+ /**
838
+ * Minimum coverage percentage required (0-100)
839
+ * @deprecated Use `minHealth` instead. Will be removed in next major.
840
+ */
796
841
  minCoverage?: number;
797
- /** Maximum drift percentage allowed (0-100) */
842
+ /**
843
+ * Maximum drift percentage allowed (0-100)
844
+ * @deprecated Use `minHealth` instead. Drift is now factored into health score.
845
+ */
798
846
  maxDrift?: number;
799
847
  /** Minimum API surface completeness percentage (0-100) - deprecated, use apiSurface.minCompleteness */
800
848
  minApiSurface?: number;
@@ -1010,7 +1058,7 @@ interface WorkspacePackage {
1010
1058
  private: boolean;
1011
1059
  }
1012
1060
  /** Entry point source - where the entry was detected from */
1013
- type EntryPointSource = "types" | "exports" | "main" | "module" | "fallback";
1061
+ type EntryPointSource = "types" | "exports" | "main" | "module" | "fallback" | "explicit";
1014
1062
  /** Entry point detection result */
1015
1063
  interface EntryPointInfo {
1016
1064
  /** Path to entry file (relative to package root) */
@@ -1790,6 +1838,22 @@ interface SpecDiffWithDocs extends SpecDiff2 {
1790
1838
  memberChanges?: MemberChange[];
1791
1839
  /** Breaking changes categorized by severity (high/medium/low) */
1792
1840
  categorizedBreaking?: CategorizedBreaking[];
1841
+ /** Coverage score from old spec */
1842
+ oldCoverage: number;
1843
+ /** Coverage score from new spec */
1844
+ newCoverage: number;
1845
+ /** Change in coverage (newCoverage - oldCoverage) */
1846
+ coverageDelta: number;
1847
+ /** Number of new drift issues introduced */
1848
+ driftIntroduced: number;
1849
+ /** Number of drift issues resolved */
1850
+ driftResolved: number;
1851
+ /** New exports that are undocumented */
1852
+ newUndocumented: string[];
1853
+ /** Exports with improved coverage */
1854
+ improvedExports: string[];
1855
+ /** Exports with regressed coverage */
1856
+ regressedExports: string[];
1793
1857
  }
1794
1858
  /**
1795
1859
  * Options for diffSpecWithDocs
@@ -2615,7 +2679,7 @@ interface SpecSummary {
2615
2679
  * ```
2616
2680
  */
2617
2681
  declare function extractSpecSummary(openpkg: OpenPkg8, doccov: DocCovSpec4): SpecSummary;
2618
- import { OpenPkg as OpenPkg_ikpscozpjh } from "@openpkg-ts/spec";
2682
+ import { OpenPkg as OpenPkg_tgtzybcxvb } from "@openpkg-ts/spec";
2619
2683
  /**
2620
2684
  * Build Plan types for AI-powered repository scanning.
2621
2685
  */
@@ -2712,7 +2776,7 @@ interface BuildPlanExecutionResult {
2712
2776
  /** Whether all required steps succeeded */
2713
2777
  success: boolean;
2714
2778
  /** Generated OpenPkg spec (if successful) */
2715
- spec?: OpenPkg_ikpscozpjh;
2779
+ spec?: OpenPkg_tgtzybcxvb;
2716
2780
  /** Results for each step */
2717
2781
  stepResults: BuildPlanStepResult[];
2718
2782
  /** Total execution time in milliseconds */
@@ -2720,4 +2784,4 @@ interface BuildPlanExecutionResult {
2720
2784
  /** Overall error message if failed */
2721
2785
  error?: string;
2722
2786
  }
2723
- export { validateSpecCache, validateExamples, typecheckExamples, typecheckExample, shouldValidate, serializeJSDoc, saveSpecCache, saveSnapshot, saveReport, safeParseJson, runExamplesWithPackage, runExamples, runExample, resolveTarget, resolveCompiledPath, renderSparkline, renderApiSurface, readPackageJson, pruneHistory, pruneByTier, previewForgottenExportFixes, parseGitHubUrl2 as parseScanGitHubUrl, parseMarkdownFiles, parseMarkdownFile, parseListFlag, parseJSDocToPatch, parseGitHubUrl, parseExamplesFlag, parseAssertions, mergeFixes, mergeFilters, loadSpecCache, loadSnapshots, loadCachedReport, listWorkspacePackages, isStandardJSONSchema, isSchemaType, isFixableDrift, isExportFullyDocumented, isExecutableLang, installDependencies, hashString, hashFiles, hashFile, hasNonAssertionComments, hasDocsImpact, hasDocsForExport, groupFixesByFile, groupDriftsByCategory, getUndocumentedExports, getTrend, getSupportedLibraries, getSpecCachePath, getRunCommand, getReportPath, getRegisteredAdapters, getPrimaryBuildScript, getInstallCommand, getExtendedTrend, getExportScore, getExportMissing, getExportDrift, getExportAnalysis, getDriftSummary, getDocumentedExports, getDocsImpactSummary, getDiffReportPath, generateReportFromDocCov, generateReport, generateForgottenExportFixes, generateFixesForExport, generateFix, formatPackageList, formatDriftSummaryLine, formatDelta, findRemovedReferences, findPackageByName, findJSDocLocation, findExportReferences, findDeprecatedReferences, findAdapter, fetchSpecFromGitHub, fetchSpec, fetchGitHubContext, extractStandardSchemasFromProject, extractStandardSchemas, extractSpecSummary, extractSchemaType, extractSchemaOutputType, extractPackageSpec, extractImports, extractFunctionCalls, ensureSpecCoverage, diffSpecWithDocs, diffHashes, detectRuntimeSchemas, detectPackageManager, detectMonorepo, detectExampleRuntimeErrors, detectExampleAssertionFailures, detectEntryPoint, detectBuildInfo, defineConfig, createSourceFile, createNodeCommandRunner, computeSnapshot, computeExportDrift, computeDrift, clearSpecCache, categorizeDrifts, categorizeDrift, calculateAggregateCoverage, buildRawUrl, buildExportRegistry, buildDocCovSpec, buildDisplayUrl, buildCloneUrl, blockReferencesExport, applyPatchToJSDoc, applyForgottenExportFixes, applyEdits, analyzeProject2 as analyzeProject, analyzeFile, analyzeDocsImpact, analyze, WorkspacePackage, WorkspaceConfig, VALIDATION_INFO, TypecheckValidationResult, TypecheckResult, TypecheckOptions, SummaryDriftIssue, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, SpecSummary, SpecDocDrift, SpecDiffWithDocs, SpecCacheConfig, SpecCache, SchemaExtractionResult, SchemaExtractionMode, SchemaDetectionResult, SchemaDetectionContext, SchemaAdapter, SandboxFileSystem, SPEC_CACHE_FILE, RuntimeDrift, RunValidationResult, RunExamplesWithPackageResult, RunExamplesWithPackageOptions, RunExampleOptions, RetentionTier, ResolvedTarget, ResolvedFilters, ResolveTargetOptions, ReleaseTag, RETENTION_DAYS, REPORT_VERSION, REPORT_EXTENSIONS, ProjectInfo, PresenceResult, ParsedGitHubUrl, PackageManagerInfo, PackageManager, PackageJson, PackageExports, OpenPkgSpec, NodeFileSystem, MonorepoType, MonorepoInfo, MemberChange, MarkdownDocFile, MarkdownCodeBlock, LLMAssertion, JSDocTag, JSDocReturn, JSDocPatch, JSDocParam, JSDocEdit, InstallResult, InstallOptions, HISTORY_DIR, GitHubRepoMetadata, GitHubProjectContext, GenerateForgottenExportFixesOptions, ForgottenExportResult, ForgottenExportFix, FixType, FixSuggestion, FilterSource, FilterOptions, FileSystem, FetchGitHubContextOptions, ExtractStandardSchemasOptions, ExtendedTrendAnalysis, ExportReference, ExportDriftResult, ExportCoverageData, ExampleValidationTypeError, ExampleValidationResult, ExampleValidationOptions, ExampleValidationMode, ExampleValidation, ExampleTypeError, ExampleRunResult, EntryPointSource, EntryPointInfo, DriftType, DriftSummary, DriftResult, DriftReportSummary, DriftReport, DriftCategory, DocsImpactResult, DocsImpactReference, DocsImpact, DocsConfig, DocsChangeType, DocCovReport, DocCovOptions, DocCovConfig, DocCov, DiffWithDocsOptions, Diagnostic, DetectedSchemaEntry, DetectedPackageManager, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, DRIFT_CATEGORIES, DEFAULT_REPORT_PATH, DEFAULT_REPORT_DIR, CoverageTrend, CoverageSummary, CoverageSnapshot, CommandRunner, CommandResult, CheckConfig, CategorizedDrift, CacheValidationResult, CacheContext, CACHE_VERSION, BuildPlanTarget, BuildPlanStepResult, BuildPlanStep, BuildPlanExecutionResult, BuildPlanEnvironment, BuildPlan, BuildInfo, BuildHints, BuildDocCovOptions, ApplyForgottenExportResult, ApplyEditsResult, AnalyzeProjectOptions, AnalyzeOptions, AnalysisResult, ALL_VALIDATIONS };
2787
+ export { validateSpecCache, validateExamples, typecheckExamples, typecheckExample, shouldValidate, serializeJSDoc, saveSpecCache, saveSnapshot, saveReport, safeParseJson, runExamplesWithPackage, runExamples, runExample, resolveTarget, resolveCompiledPath, renderSparkline, renderApiSurface, readPackageJson, pruneHistory, pruneByTier, previewForgottenExportFixes, parseGitHubUrl2 as parseScanGitHubUrl, parseMarkdownFiles, parseMarkdownFile, parseListFlag, parseJSDocToPatch, parseGitHubUrl, parseExamplesFlag, parseAssertions, mergeFixes, mergeFilters, loadSpecCache, loadSnapshots, loadCachedReport, listWorkspacePackages, isStandardJSONSchema, isSchemaType, isFixableDrift, isExportFullyDocumented, isExecutableLang, installDependencies, hashString, hashFiles, hashFile, hasNonAssertionComments, hasDocsImpact, hasDocsForExport, groupFixesByFile, groupDriftsByCategory, getUndocumentedExports, getTrend, getSupportedLibraries, getSpecCachePath, getRunCommand, getReportPath, getRegisteredAdapters, getPrimaryBuildScript, getInstallCommand, getExtendedTrend, getExportScore, getExportMissing, getExportDrift, getExportAnalysis, getDriftSummary, getDocumentedExports, getDocsImpactSummary, getDiffReportPath, generateReportFromDocCov, generateReport, generateForgottenExportFixes, generateFixesForExport, generateFix, formatPackageList, formatDriftSummaryLine, formatDelta, findRemovedReferences, findPackageByName, findJSDocLocation, findExportReferences, findDeprecatedReferences, findAdapter, fetchSpecFromGitHub, fetchSpec, fetchGitHubContext, extractStandardSchemasFromProject, extractStandardSchemas, extractSpecSummary, extractSchemaType, extractSchemaOutputType, extractPackageSpec, extractImports, extractFunctionCalls, ensureSpecCoverage, diffSpecWithDocs, diffHashes, detectRuntimeSchemas, detectPackageManager, detectMonorepo, detectExampleRuntimeErrors, detectExampleAssertionFailures, detectEntryPoint, detectBuildInfo, defineConfig, createSourceFile, createNodeCommandRunner, computeSnapshot, computeHealth, computeExportDrift, computeDrift, clearSpecCache, categorizeDrifts, categorizeDrift, calculateAggregateCoverage, buildRawUrl, buildExportRegistry, buildDocCovSpec, buildDisplayUrl, buildCloneUrl, blockReferencesExport, applyPatchToJSDoc, applyForgottenExportFixes, applyEdits, analyzeProject2 as analyzeProject, analyzeFile, analyzeDocsImpact, analyze, WorkspacePackage, WorkspaceConfig, VALIDATION_INFO, TypecheckValidationResult, TypecheckResult, TypecheckOptions, SummaryDriftIssue, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, SpecSummary, SpecDocDrift, SpecDiffWithDocs, SpecCacheConfig, SpecCache, SchemaExtractionResult, SchemaExtractionMode, SchemaDetectionResult, SchemaDetectionContext, SchemaAdapter, SandboxFileSystem, SPEC_CACHE_FILE, RuntimeDrift, RunValidationResult, RunExamplesWithPackageResult, RunExamplesWithPackageOptions, RunExampleOptions, RetentionTier, ResolvedTarget, ResolvedFilters, ResolveTargetOptions, ReleaseTag, RETENTION_DAYS, REPORT_VERSION, REPORT_EXTENSIONS, ProjectInfo, PresenceResult, ParsedGitHubUrl, PackageManagerInfo, PackageManager, PackageJson, PackageExports, OpenPkgSpec, NodeFileSystem, MonorepoType, MonorepoInfo, MemberChange, MarkdownDocFile, MarkdownCodeBlock, LLMAssertion, JSDocTag, JSDocReturn, JSDocPatch, JSDocParam, JSDocEdit, InstallResult, InstallOptions, HealthInput, HISTORY_DIR, GitHubRepoMetadata, GitHubProjectContext, GenerateForgottenExportFixesOptions, ForgottenExportResult, ForgottenExportFix, FixType, FixSuggestion, FilterSource, FilterOptions, FileSystem, FetchGitHubContextOptions, ExtractStandardSchemasOptions, ExtendedTrendAnalysis, ExportReference, ExportDriftResult, ExportCoverageData, ExampleValidationTypeError, ExampleValidationResult, ExampleValidationOptions, ExampleValidationMode, ExampleValidation, ExampleTypeError, ExampleRunResult, EntryPointSource, EntryPointInfo, DriftType, DriftSummary, DriftResult, DriftReportSummary, DriftReport, DriftCategory2 as DriftCategory, DocsImpactResult, DocsImpactReference, DocsImpact, DocsConfig, DocsChangeType, DocCovReport, DocCovOptions, DocCovConfig, DocCov, DiffWithDocsOptions, Diagnostic, DetectedSchemaEntry, DetectedPackageManager, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, DRIFT_CATEGORIES, DEFAULT_REPORT_PATH, DEFAULT_REPORT_DIR, CoverageTrend, CoverageSummary, CoverageSnapshot, CommandRunner, CommandResult, CheckConfig, CategorizedDrift, CacheValidationResult, CacheContext, CACHE_VERSION, BuildPlanTarget, BuildPlanStepResult, BuildPlanStep, BuildPlanExecutionResult, BuildPlanEnvironment, BuildPlan, BuildInfo, BuildHints, BuildDocCovOptions, ApplyForgottenExportResult, ApplyEditsResult, AnalyzeProjectOptions, AnalyzeOptions, AnalysisResult, ALL_VALIDATIONS };
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  categorizeDrifts,
15
15
  computeDrift,
16
16
  computeExportDrift,
17
+ computeHealth,
17
18
  computeSnapshot,
18
19
  createSourceFile,
19
20
  detectExampleAssertionFailures,
@@ -59,7 +60,7 @@ import {
59
60
  saveSnapshot,
60
61
  serializeJSDoc,
61
62
  ts
62
- } from "./shared/chunk-yqqqk8by.js";
63
+ } from "./shared/chunk-v62zsv8j.js";
63
64
  import {
64
65
  mergeFilters,
65
66
  parseListFlag
@@ -622,7 +623,7 @@ ${extraction.errors.map((e) => ` - ${e}`).join(`
622
623
  `)}`);
623
624
  }
624
625
  }
625
- const result = runAnalysis({
626
+ const result = await runAnalysis({
626
627
  entryFile,
627
628
  packageDir,
628
629
  content,
@@ -2494,7 +2495,7 @@ function extractMethodCallsAST(code) {
2494
2495
  if (ts.isIdentifier(objectExpr.expression)) {
2495
2496
  objectName = objectExpr.expression.text;
2496
2497
  }
2497
- } else if (ts.isThisKeyword(objectExpr)) {
2498
+ } else if (objectExpr.kind === ts.SyntaxKind.ThisKeyword) {
2498
2499
  objectName = "this";
2499
2500
  }
2500
2501
  if (objectName && !isBuiltInIdentifier(objectName)) {
@@ -3112,22 +3113,84 @@ function diffSpecWithDocs(oldSpec, newSpec, options = {}) {
3112
3113
  const baseDiff = diffSpec(oldSpec, newSpec);
3113
3114
  const memberChanges = diffMemberChanges(oldSpec, newSpec, baseDiff.breaking);
3114
3115
  const categorizedBreaking = categorizeBreakingChanges(baseDiff.breaking, oldSpec, newSpec, memberChanges);
3116
+ const { oldCoverage, newCoverage, coverageDelta, improvedExports, regressedExports } = computeCoverageMetrics(oldSpec, newSpec);
3117
+ const { driftIntroduced, driftResolved } = computeDriftMetrics(oldSpec, newSpec);
3118
+ const oldExportIds = new Set(oldSpec.exports?.map((e) => e.id) ?? []);
3119
+ const newUndocumented = (newSpec.exports ?? []).filter((e) => !oldExportIds.has(e.id) && !hasDocumentation(e)).map((e) => e.name);
3120
+ const baseResult = {
3121
+ ...baseDiff,
3122
+ memberChanges: memberChanges.length > 0 ? memberChanges : undefined,
3123
+ categorizedBreaking: categorizedBreaking.length > 0 ? categorizedBreaking : undefined,
3124
+ oldCoverage,
3125
+ newCoverage,
3126
+ coverageDelta,
3127
+ driftIntroduced,
3128
+ driftResolved,
3129
+ newUndocumented,
3130
+ improvedExports,
3131
+ regressedExports
3132
+ };
3115
3133
  if (!options.markdownFiles?.length) {
3116
- return {
3117
- ...baseDiff,
3118
- memberChanges: memberChanges.length > 0 ? memberChanges : undefined,
3119
- categorizedBreaking: categorizedBreaking.length > 0 ? categorizedBreaking : undefined
3120
- };
3134
+ return baseResult;
3121
3135
  }
3122
3136
  const newExportNames = newSpec.exports?.map((e) => e.name) ?? [];
3123
3137
  const docsImpact = analyzeDocsImpact(baseDiff, options.markdownFiles, newExportNames, memberChanges);
3124
3138
  return {
3125
- ...baseDiff,
3126
- docsImpact,
3127
- memberChanges: memberChanges.length > 0 ? memberChanges : undefined,
3128
- categorizedBreaking: categorizedBreaking.length > 0 ? categorizedBreaking : undefined
3139
+ ...baseResult,
3140
+ docsImpact
3129
3141
  };
3130
3142
  }
3143
+ function computeCoverageMetrics(oldSpec, newSpec) {
3144
+ const oldCoverage = getSpecCoverage(oldSpec);
3145
+ const newCoverage = getSpecCoverage(newSpec);
3146
+ const coverageDelta = newCoverage - oldCoverage;
3147
+ const oldExportScores = new Map;
3148
+ for (const exp of oldSpec.exports ?? []) {
3149
+ const enriched = exp;
3150
+ oldExportScores.set(exp.id, enriched.docs?.coverageScore ?? 0);
3151
+ }
3152
+ const improvedExports = [];
3153
+ const regressedExports = [];
3154
+ for (const exp of newSpec.exports ?? []) {
3155
+ const enriched = exp;
3156
+ const oldScore = oldExportScores.get(exp.id);
3157
+ if (oldScore === undefined)
3158
+ continue;
3159
+ const newScore = enriched.docs?.coverageScore ?? 0;
3160
+ if (newScore > oldScore) {
3161
+ improvedExports.push(exp.name);
3162
+ } else if (newScore < oldScore) {
3163
+ regressedExports.push(exp.name);
3164
+ }
3165
+ }
3166
+ return { oldCoverage, newCoverage, coverageDelta, improvedExports, regressedExports };
3167
+ }
3168
+ function getSpecCoverage(spec) {
3169
+ const exports = spec.exports ?? [];
3170
+ if (exports.length === 0)
3171
+ return 0;
3172
+ const totalScore = exports.reduce((sum, exp) => {
3173
+ const enriched = exp;
3174
+ return sum + (enriched.docs?.coverageScore ?? 0);
3175
+ }, 0);
3176
+ return Math.round(totalScore / exports.length);
3177
+ }
3178
+ function computeDriftMetrics(oldSpec, newSpec) {
3179
+ const oldDriftCount = countDriftIssues(oldSpec);
3180
+ const newDriftCount = countDriftIssues(newSpec);
3181
+ const driftIntroduced = Math.max(0, newDriftCount - oldDriftCount);
3182
+ const driftResolved = Math.max(0, oldDriftCount - newDriftCount);
3183
+ return { driftIntroduced, driftResolved };
3184
+ }
3185
+ function countDriftIssues(spec) {
3186
+ return (spec.exports ?? []).reduce((sum, exp) => {
3187
+ const enriched = exp;
3188
+ return sum + (enriched.docs?.drift?.length ?? 0);
3189
+ }, 0);
3190
+ }
3191
+ function hasDocumentation(exp) {
3192
+ return Boolean(exp.docs?.description || exp.description);
3193
+ }
3131
3194
  function hasDocsImpact(diff) {
3132
3195
  if (!diff.docsImpact)
3133
3196
  return false;
@@ -3668,6 +3731,7 @@ export {
3668
3731
  createSourceFile,
3669
3732
  createNodeCommandRunner,
3670
3733
  computeSnapshot,
3734
+ computeHealth,
3671
3735
  computeExportDrift,
3672
3736
  computeDrift,
3673
3737
  clearSpecCache,
@@ -3,6 +3,57 @@ import {
3
3
  REPORT_VERSION
4
4
  } from "./chunk-esptwrfq.js";
5
5
 
6
+ // src/analysis/health.ts
7
+ function computeHealth(input) {
8
+ const {
9
+ coverageScore,
10
+ documentedExports,
11
+ totalExports,
12
+ missingByRule,
13
+ driftIssues,
14
+ fixableDrift,
15
+ driftByCategory,
16
+ examples
17
+ } = input;
18
+ const completenessScore = coverageScore;
19
+ const driftRatio = documentedExports > 0 ? driftIssues / documentedExports : 0;
20
+ const driftPenalty = Math.min(driftRatio * 0.5, 0.5);
21
+ const accuracyScore = Math.round((1 - driftPenalty) * 100);
22
+ let exampleScore;
23
+ if (examples && examples.total > 0) {
24
+ exampleScore = Math.round(examples.passed / examples.total * 100);
25
+ }
26
+ let health = completenessScore * (1 - driftPenalty);
27
+ if (exampleScore !== undefined) {
28
+ const examplePenalty = (100 - exampleScore) / 100 * 0.3;
29
+ health = health * (1 - examplePenalty);
30
+ }
31
+ const result = {
32
+ score: Math.round(health),
33
+ completeness: {
34
+ score: Math.round(completenessScore),
35
+ documented: documentedExports,
36
+ total: totalExports,
37
+ missing: missingByRule
38
+ },
39
+ accuracy: {
40
+ score: accuracyScore,
41
+ issues: driftIssues,
42
+ fixable: fixableDrift,
43
+ byCategory: driftByCategory
44
+ }
45
+ };
46
+ if (examples) {
47
+ result.examples = {
48
+ score: exampleScore,
49
+ passed: examples.passed,
50
+ failed: examples.failed,
51
+ total: examples.total
52
+ };
53
+ }
54
+ return result;
55
+ }
56
+
6
57
  // src/fix/deterministic-fixes.ts
7
58
  var FIXABLE_DRIFT_TYPES = new Set([
8
59
  "param-mismatch",
@@ -2179,8 +2230,18 @@ function buildDocCovSpec(options) {
2179
2230
  }
2180
2231
  }
2181
2232
  const exportCount = openpkg.exports?.length ?? 0;
2233
+ const coverageScore = exportCount > 0 ? Math.round(totalScore / exportCount) : 100;
2234
+ const health = computeHealth({
2235
+ coverageScore,
2236
+ documentedExports: documentedCount,
2237
+ totalExports: exportCount,
2238
+ missingByRule,
2239
+ driftIssues: totalDrift,
2240
+ fixableDrift,
2241
+ driftByCategory
2242
+ });
2182
2243
  const summary = {
2183
- score: exportCount > 0 ? Math.round(totalScore / exportCount) : 100,
2244
+ score: coverageScore,
2184
2245
  totalExports: exportCount,
2185
2246
  documentedExports: documentedCount,
2186
2247
  missingByRule,
@@ -2188,7 +2249,8 @@ function buildDocCovSpec(options) {
2188
2249
  total: totalDrift,
2189
2250
  fixable: fixableDrift,
2190
2251
  byCategory: driftByCategory
2191
- }
2252
+ },
2253
+ health
2192
2254
  };
2193
2255
  const apiSurface = computeApiSurface(forgottenExports, openpkg.types?.length ?? 0, apiSurfaceIgnore);
2194
2256
  return {
@@ -2285,13 +2347,14 @@ function computeExportCoverage(exp) {
2285
2347
  }
2286
2348
  function toCategorizedDrift(drift) {
2287
2349
  const driftType = drift.type;
2350
+ const specDrift = { ...drift, type: driftType };
2288
2351
  return {
2289
2352
  type: driftType,
2290
2353
  target: drift.target,
2291
2354
  issue: drift.issue,
2292
2355
  suggestion: drift.suggestion,
2293
2356
  category: DRIFT_CATEGORIES[driftType],
2294
- fixable: isFixableDrift(drift)
2357
+ fixable: isFixableDrift(specDrift)
2295
2358
  };
2296
2359
  }
2297
2360
 
@@ -3145,4 +3208,4 @@ function getExtendedTrend(spec, cwd, options) {
3145
3208
  };
3146
3209
  }
3147
3210
 
3148
- export { isFixableDrift, generateFix, generateFixesForExport, mergeFixes, categorizeDrifts, ts, parseJSDocToPatch, applyPatchToJSDoc, serializeJSDoc, findJSDocLocation, applyEdits, createSourceFile, generateForgottenExportFixes, groupFixesByFile, applyForgottenExportFixes, previewForgottenExportFixes, isBuiltInIdentifier, detectExampleRuntimeErrors, parseAssertions, hasNonAssertionComments, detectExampleAssertionFailures, buildExportRegistry, computeDrift, computeExportDrift, buildDocCovSpec, DRIFT_CATEGORIES2 as DRIFT_CATEGORIES, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, categorizeDrift, groupDriftsByCategory, getDriftSummary, formatDriftSummaryLine, calculateAggregateCoverage, ensureSpecCoverage, getExportAnalysis, getExportScore, getExportDrift, getExportMissing, isExportFullyDocumented, generateReport, generateReportFromDocCov, loadCachedReport, saveReport, isCachedReportValid, renderApiSurface, isStandardJSONSchema, resolveCompiledPath, extractStandardSchemas, extractStandardSchemasFromProject, detectRuntimeSchemas, HISTORY_DIR, RETENTION_DAYS, computeSnapshot, saveSnapshot, loadSnapshots, getTrend, renderSparkline, formatDelta, pruneHistory, pruneByTier, loadSnapshotsForDays, generateWeeklySummaries, getExtendedTrend };
3211
+ export { computeHealth, isFixableDrift, generateFix, generateFixesForExport, mergeFixes, categorizeDrifts, ts, parseJSDocToPatch, applyPatchToJSDoc, serializeJSDoc, findJSDocLocation, applyEdits, createSourceFile, generateForgottenExportFixes, groupFixesByFile, applyForgottenExportFixes, previewForgottenExportFixes, isBuiltInIdentifier, detectExampleRuntimeErrors, parseAssertions, hasNonAssertionComments, detectExampleAssertionFailures, buildExportRegistry, computeDrift, computeExportDrift, buildDocCovSpec, DRIFT_CATEGORIES2 as DRIFT_CATEGORIES, DRIFT_CATEGORY_LABELS, DRIFT_CATEGORY_DESCRIPTIONS, categorizeDrift, groupDriftsByCategory, getDriftSummary, formatDriftSummaryLine, calculateAggregateCoverage, ensureSpecCoverage, getExportAnalysis, getExportScore, getExportDrift, getExportMissing, isExportFullyDocumented, generateReport, generateReportFromDocCov, loadCachedReport, saveReport, isCachedReportValid, renderApiSurface, isStandardJSONSchema, resolveCompiledPath, extractStandardSchemas, extractStandardSchemasFromProject, detectRuntimeSchemas, HISTORY_DIR, RETENTION_DAYS, computeSnapshot, saveSnapshot, loadSnapshots, getTrend, renderSparkline, formatDelta, pruneHistory, pruneByTier, loadSnapshotsForDays, generateWeeklySummaries, getExtendedTrend };
@@ -46,9 +46,17 @@ interface CheckConfig {
46
46
  * - 'run': Execute examples and validate assertions
47
47
  */
48
48
  examples?: ExampleValidationMode | ExampleValidationMode[] | string;
49
- /** Minimum coverage percentage required (0-100) */
49
+ /** Minimum health score required (0-100). Unified metric combining coverage + accuracy. */
50
+ minHealth?: number;
51
+ /**
52
+ * Minimum coverage percentage required (0-100)
53
+ * @deprecated Use `minHealth` instead. Will be removed in next major.
54
+ */
50
55
  minCoverage?: number;
51
- /** Maximum drift percentage allowed (0-100) */
56
+ /**
57
+ * Maximum drift percentage allowed (0-100)
58
+ * @deprecated Use `minHealth` instead. Drift is now factored into health score.
59
+ */
52
60
  maxDrift?: number;
53
61
  /** Minimum API surface completeness percentage (0-100) - deprecated, use apiSurface.minCompleteness */
54
62
  minApiSurface?: number;
@@ -170,7 +178,7 @@ interface CategorizedDrift extends SpecDocDrift {
170
178
  category: DriftCategory;
171
179
  fixable: boolean;
172
180
  }
173
- import { ApiSurfaceResult } from "@doccov/spec";
181
+ import { ApiSurfaceResult, DocumentationHealth } from "@doccov/spec";
174
182
  /**
175
183
  * DocCov report schema version.
176
184
  */
@@ -350,5 +358,9 @@ interface DocCovReport {
350
358
  * API surface analysis (forgotten exports).
351
359
  */
352
360
  apiSurface?: ApiSurfaceResult;
361
+ /**
362
+ * Unified documentation health score.
363
+ */
364
+ health?: DocumentationHealth;
353
365
  }
354
366
  export { parseListFlag, mergeFilters, getReportPath, getDiffReportPath, ResolvedFilters, ReleaseTag, REPORT_VERSION, REPORT_EXTENSIONS, FilterSource, FilterOptions, ExportCoverageData, DriftReportSummary, DriftReport, DocCovReport, DEFAULT_REPORT_PATH, DEFAULT_REPORT_DIR, CoverageSummary };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doccov/sdk",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "DocCov SDK - Documentation coverage and drift detection for TypeScript",
5
5
  "keywords": [
6
6
  "typescript",
@@ -47,7 +47,7 @@
47
47
  "dist"
48
48
  ],
49
49
  "dependencies": {
50
- "@doccov/spec": "^0.26.0",
50
+ "@doccov/spec": "^0.27.0",
51
51
  "@openpkg-ts/extract": "^0.16.0",
52
52
  "@openpkg-ts/spec": "^0.12.0",
53
53
  "@vercel/sandbox": "^1.0.3",