fallow 3.33.1 → 3.34.1

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.
@@ -24,7 +24,7 @@
24
24
 
25
25
 
26
26
  /**
27
- * Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator. Current kind values: `audit`, `explain`, `inspect_target`, `trace`, `trace-error`, `review-envelope`, `review-reconcile`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `list-workspaces`, `health`, `dupes`, `dead-code-grouped`, `architecture-grouped`, `impact`, `impact-cross-repo`, `security`, `security-survivors`, `security-blind-spots`, `dead-code`, `architecture`, `combined`, `feature-flags`, `audit-brief`, `decision-surface`, `review-walkthrough-guide`, `review-walkthrough-validation`, `suppression-inventory`, `doctor`, `type-aware-status`, `similar-code`, `similar-code-inspect`, `similar-code-review`, `similar-code-status`, `similar-code-cache-clear`. Consumers should branch on `kind` instead of probing for unique field presence. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array. `ErrorOutput` is the `--format json` failure document, emitted on stdout with a non-zero exit; it carries no `kind` and is discriminated by the `error: true` field.
27
+ * Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator. Current kind values: `audit`, `explain`, `inspect_target`, `trace`, `trace-error`, `review-envelope`, `review-reconcile`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `list-workspaces`, `health`, `dupes`, `dead-code-grouped`, `architecture-grouped`, `impact`, `impact-cross-repo`, `security`, `security-survivors`, `security-blind-spots`, `dead-code`, `architecture`, `combined`, `feature-flags`, `audit-brief`, `decision-surface`, `review-walkthrough-guide`, `review-walkthrough-validation`, `suppression-inventory`, `doctor`, `type-aware-status`, `similar-code`, `similar-code-inspect`, `similar-code-review`, `similar-code-status`, `similar-code-cache-clear`, `mutation`, `mutation-plan`, `mutation-inspect`. Consumers should branch on `kind` instead of probing for unique field presence. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array. `ErrorOutput` is the `--format json` failure document, emitted on stdout with a non-zero exit; it carries no `kind` and is discriminated by the `error: true` field.
28
28
  */
29
29
  export type FallowJsonOutput = (FallowOutput | CodeClimateOutput | ErrorOutput)
30
30
  /**
@@ -116,11 +116,17 @@ kind: "similar-code-review"
116
116
  kind: "similar-code-status"
117
117
  }) | (SimilarCodeCacheClearOutput & {
118
118
  kind: "similar-code-cache-clear"
119
+ }) | (MutationReport & {
120
+ kind: "mutation"
121
+ }) | (MutationPlanOutput & {
122
+ kind: "mutation-plan"
123
+ }) | (MutationInspectOutput & {
124
+ kind: "mutation-inspect"
119
125
  }))
120
126
  /**
121
127
  * Schema projection for the audit envelope's exact version.
122
128
  */
123
- export type AuditSchemaVersion = 12
129
+ export type AuditSchemaVersion = 13
124
130
  /**
125
131
  * Fallow CLI version that produced this envelope. Renders to the JSON wire as
126
132
  * a bare string (e.g. `"2.74.0"`).
@@ -269,7 +275,7 @@ export type IssueAction = (FixAction | SuppressLineAction | SuppressFileAction |
269
275
  * Discriminant string for [`FixAction`]. Kebab-case per the JSON output
270
276
  * contract.
271
277
  */
272
- export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "move-to-prod" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "migrate-deprecated-export" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override" | "resolve-policy-violation" | "move-to-server-module" | "split-mixed-barrel" | "hoist-directive" | "wire-server-action" | "provide-inject" | "use-load-data" | "render-component" | "use-component-prop" | "review-component-prop" | "emit-component-event" | "wire-svelte-event" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict" | "add-suppression-reason" | "remove-stale-suppression")
278
+ export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "move-to-prod" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "migrate-deprecated-export" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override" | "resolve-policy-violation" | "move-to-server-module" | "split-mixed-barrel" | "hoist-directive" | "wire-server-action" | "provide-inject" | "use-load-data" | "render-component" | "use-component-prop" | "review-component-prop" | "emit-component-event" | "wire-svelte-event" | "compose-effect-layer" | "fail-tagged-error" | "remove-catch-tag-handler" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict" | "add-suppression-reason" | "remove-stale-suppression")
273
279
  /**
274
280
  * Singleton discriminant for [`SuppressLineAction`].
275
281
  */
@@ -445,6 +451,10 @@ export type DependencyOverrideSource = ("pnpm-workspace.yaml" | "package.json")
445
451
  * surfacing them statically catches the issue first.
446
452
  */
447
453
  export type DependencyOverrideMisconfigReason = ("unparsable-key" | "empty-value")
454
+ /**
455
+ * Kind of an Effect layer definition.
456
+ */
457
+ export type EffectLayerKind = ("top_level" | "static_member")
448
458
  /**
449
459
  * Which advisory a loaded baseline earned on this run.
450
460
  *
@@ -561,6 +571,12 @@ kind: "malformed-package-json"
561
571
  pattern: string
562
572
  kind: "glob-matched-no-package-json"
563
573
  } | {
574
+ /**
575
+ * The workspace entry, as written in the file.
576
+ */
577
+ pattern: string
578
+ kind: "workspace-glob-outside-root"
579
+ } | {
564
580
  /**
565
581
  * JSONC parse error text.
566
582
  */
@@ -679,6 +695,14 @@ kind: "file-scores-unavailable"
679
695
  cause: string
680
696
  kind: "hotspots-skipped"
681
697
  } | {
698
+ /**
699
+ * Kebab-case token: `shallow-clone` (the fetched history is
700
+ * incomplete) or `too-few-commits` (fewer analyzed commits than the
701
+ * minimum revisions of one file). The set is open.
702
+ */
703
+ cause: string
704
+ kind: "change-coupling-skipped"
705
+ } | {
682
706
  /**
683
707
  * `true` when the run also asked for ownership attribution, which a
684
708
  * shallow clone skews further by inflating single-author dominance.
@@ -821,6 +845,14 @@ export type ExceededThreshold = ("cyclomatic" | "cognitive" | "both" | "crap" |
821
845
  * scores. Default thresholds: cognitive 25/40, cyclomatic 30/50.
822
846
  */
823
847
  export type FindingSeverity = ("moderate" | "high" | "critical")
848
+ /**
849
+ * Whether the mutation evidence still describes the current source file.
850
+ */
851
+ export type HealthMutationState = ("fresh" | "stale")
852
+ /**
853
+ * Why mutation evidence is stale.
854
+ */
855
+ export type HealthMutationStaleReason = ("file-missing" | "no-digest" | "source-changed")
824
856
  /**
825
857
  * Coverage tier classification for CRAP findings.
826
858
  */
@@ -874,7 +906,7 @@ export type CoverageSourceConsistency = ("uniform" | "mixed")
874
906
  * set is OPEN: a later release can add a section, so a consumer must accept
875
907
  * a token that it does not know.
876
908
  */
877
- export type HealthSection = ("complexity" | "vital-signs" | "score" | "file-scores" | "coverage-gaps" | "hotspots" | "targets" | "trend" | "runtime-coverage" | "css")
909
+ export type HealthSection = ("complexity" | "vital-signs" | "score" | "file-scores" | "coverage-gaps" | "hotspots" | "change-coupling" | "targets" | "trend" | "runtime-coverage" | "mutation" | "css")
878
910
  /**
879
911
  * Lifecycle state for a configured threshold override.
880
912
  */
@@ -985,6 +1017,10 @@ export type RuntimeCoverageRiskBand = ("low" | "medium" | "high")
985
1017
  * License or trial watermark applied to runtime coverage output.
986
1018
  */
987
1019
  export type RuntimeCoverageWatermark = ("trial-expired" | "license-expired-grace" | "unknown")
1020
+ /**
1021
+ * Whether the result is conclusive.
1022
+ */
1023
+ export type MutationCompletionStatus = ("complete" | "partial")
988
1024
  /**
989
1025
  * Coverage-intelligence JSON contract version. Scoped to the
990
1026
  * `coverage_intelligence` block and independent of the top-level fallow
@@ -1014,7 +1050,7 @@ export type CoverageIntelligenceMatchConfidence = ("path-function-line" | "path-
1014
1050
  /**
1015
1051
  * Category of refactoring recommendation.
1016
1052
  */
1017
- export type RecommendationCategory = ("urgent_churn_complexity" | "break_circular_dependency" | "split_high_impact" | "remove_dead_code" | "extract_complex_functions" | "extract_dependencies" | "add_test_coverage")
1053
+ export type RecommendationCategory = ("urgent_churn_complexity" | "break_circular_dependency" | "split_high_impact" | "remove_dead_code" | "extract_complex_functions" | "extract_dependencies" | "add_test_coverage" | "resolve_hidden_coupling")
1018
1054
  /**
1019
1055
  * A ranked refactoring recommendation for a file.
1020
1056
  *
@@ -1097,6 +1133,22 @@ export type StylingFindingConfidence = ("high" | "low")
1097
1133
  * Agent handling hint for a [`StylingFinding`].
1098
1134
  */
1099
1135
  export type StylingAgentDisposition = ("fix-confidently" | "verify-first")
1136
+ /**
1137
+ * The rule that owns a diff-risk finding.
1138
+ */
1139
+ export type DiffRiskRule = ("weakened-tests" | "added-suppression" | "test-only-branch" | "diverged-clone-sibling" | "added-dependency")
1140
+ /**
1141
+ * How a `weakened-tests` finding weakened the tests.
1142
+ */
1143
+ export type WeakenedTestsKind = ("skip-only" | "removed-tests" | "assertion-drop" | "coverage-threshold")
1144
+ /**
1145
+ * The severity of a diff-risk finding, from its rule.
1146
+ */
1147
+ export type DiffRiskSeverity = ("error" | "warn")
1148
+ /**
1149
+ * The type of a diff-risk action. Every type is a suppression.
1150
+ */
1151
+ export type DiffRiskActionType = ("suppress-line" | "suppress-file" | "suppress-in-config")
1100
1152
  /**
1101
1153
  * `target` block of [`InspectOutput`], tagged by `type`.
1102
1154
  */
@@ -1129,6 +1181,16 @@ export type InspectSectionStatus = ("ok" | "partial" | "unavailable" | "error")
1129
1181
  * Granularity an [`InspectEvidenceSection`] payload covers.
1130
1182
  */
1131
1183
  export type InspectEvidenceScope = ("symbol" | "file" | "project_filtered_to_file")
1184
+ /**
1185
+ * Whether a whole-word text search for an export name finds a consumer that
1186
+ * the module graph resolves. The levels sort from best to worst.
1187
+ */
1188
+ export type SearchVisibility = ("found" | "renamed" | "missed")
1189
+ /**
1190
+ * Why a text search for an export name does not find the uses in a consumer,
1191
+ * or why a consumer is not a search target (`pass-through`).
1192
+ */
1193
+ export type SearchGapReason = ("import-alias" | "default-import" | "re-export-alias" | "namespace-use" | "dynamic-import" | "pass-through")
1132
1194
  /**
1133
1195
  * Wire-shape version of the [`DependencyUsage`] object.
1134
1196
  *
@@ -1244,7 +1306,7 @@ export type LogicalGroupStatus = ("ok" | "empty" | "invalid_path")
1244
1306
  /**
1245
1307
  * Exact schema version for [`HealthOutput`].
1246
1308
  */
1247
- export type HealthSchemaVersion = 11
1309
+ export type HealthSchemaVersion = 12
1248
1310
  /**
1249
1311
  * Resolver mode label for grouped envelopes (dead-code, dupes, health).
1250
1312
  *
@@ -1304,8 +1366,11 @@ export type SecuritySchemaVersion = ("1" | "2" | "3" | "4" | "5" | "6" | "7" | "
1304
1366
  /**
1305
1367
  * Severity level for rules.
1306
1368
  *
1307
- * Controls whether an issue type causes CI failure (`error`), is reported
1308
- * without failing (`warn`), or is suppressed entirely (`off`).
1369
+ * Controls whether an issue type sets a non-zero exit code (`error`), is
1370
+ * reported without an effect on the exit code (`warn`), or is suppressed
1371
+ * entirely (`off`). `--fail-on-issues` promotes `warn` to `error`. The
1372
+ * dead-code count gate of the GitHub Action counts `warn` findings unless its
1373
+ * `fail-on-issues` input is `false`.
1309
1374
  */
1310
1375
  export type Severity = ("error" | "warn" | "off")
1311
1376
  /**
@@ -1382,7 +1447,7 @@ export type SecurityBlindSpotsSchemaVersion = "1"
1382
1447
  /**
1383
1448
  * Schema projection for the combined envelope's exact version.
1384
1449
  */
1385
- export type CombinedSchemaVersion = 13
1450
+ export type CombinedSchemaVersion = 14
1386
1451
  /**
1387
1452
  * Schema projection for the feature-flags envelope's exact version.
1388
1453
  */
@@ -1427,7 +1492,7 @@ export type VendorFlagState = ("on" | "off" | "rolled_out" | "archived" | "exper
1427
1492
  * Independently-versioned wire-version newtype for the brief envelope.
1428
1493
  * Serializes as the integer `REVIEW_BRIEF_SCHEMA_VERSION`.
1429
1494
  */
1430
- export type ReviewBriefSchemaVersion = 12
1495
+ export type ReviewBriefSchemaVersion = 13
1431
1496
  /**
1432
1497
  * The exactly-three shippable decision categories (the SOLID-3). No cut category
1433
1498
  * (abstraction / deletion / convention / irreversibility) is representable: this
@@ -1467,6 +1532,25 @@ export type WeakeningKind = ("test-weakened" | "threshold-lowered" | "suppressio
1467
1532
  * Where a cognitive-complexity improvement came from.
1468
1533
  */
1469
1534
  export type CognitiveAttribution = ("nesting-reset" | "fewer-branch-points" | "mixed")
1535
+ /**
1536
+ * Whether the project has tests to measure against.
1537
+ */
1538
+ export type TestReachStatus = ("measured" | "no-tests")
1539
+ /**
1540
+ * Why mock detection is or is not active.
1541
+ */
1542
+ export type TestReachMasking = ("active" | "no-mocks" | "capped")
1543
+ /**
1544
+ * How tests reach one changed export.
1545
+ *
1546
+ * Treat this as an open set: a later version can add a class. A consumer
1547
+ * must read an unknown value as "needs attention".
1548
+ */
1549
+ export type TestReachClass = ("mocked-only" | "none" | "none-file" | "transitive" | "direct" | "framework")
1550
+ /**
1551
+ * Whether the export existed before the change.
1552
+ */
1553
+ export type ExportChange = ("modified" | "new")
1470
1554
  /**
1471
1555
  * Independently-versioned wire-version newtype. Serializes as the integer
1472
1556
  * [`DECISION_SURFACE_SCHEMA_VERSION`].
@@ -1600,6 +1684,46 @@ export type SimilarCodeStatusSchemaVersion = "1"
1600
1684
  * Version singleton for vector-cache clear output.
1601
1685
  */
1602
1686
  export type SimilarCodeCacheClearSchemaVersion = "1"
1687
+ /**
1688
+ * Version singleton for a mutation report.
1689
+ */
1690
+ export type MutationSchemaVersion = "1"
1691
+ /**
1692
+ * Why a run is partial.
1693
+ */
1694
+ export type MutationIncompleteReason = ("runtime-error" | "mutant-limit" | "time-budget" | "skipped-files" | "unloaded-files" | "baseline-failure" | "worktree-changed" | "typecheck-failed" | "worktree-unchecked")
1695
+ /**
1696
+ * Which code a run mutates.
1697
+ */
1698
+ export type MutationScopeKind = ("changed" | "all" | "paths")
1699
+ /**
1700
+ * The result of one mutant.
1701
+ */
1702
+ export type MutantStatus = ("killed" | "timeout" | "survived" | "no_coverage" | "runtime_error" | "flaky" | "pruned" | "pending" | "equivalent" | "compile_error")
1703
+ /**
1704
+ * Why the type check did not check a survivor.
1705
+ */
1706
+ export type MutationTypecheckSkipReason = ("no-project" | "not-type-checked" | "source-changed" | "file-missing" | "unsupported-file")
1707
+ /**
1708
+ * Version singleton for a mutation plan.
1709
+ */
1710
+ export type MutationPlanSchemaVersion = "1"
1711
+ /**
1712
+ * The status of a mutant in a plan.
1713
+ */
1714
+ export type MutationPlanDisposition = ("planned" | "pending" | "no_coverage" | "pruned")
1715
+ /**
1716
+ * Version singleton for a mutation inspect packet.
1717
+ */
1718
+ export type MutationInspectSchemaVersion = "1"
1719
+ /**
1720
+ * Whether the saved report still describes the current file.
1721
+ */
1722
+ export type MutationInspectStatus = ("fresh" | "stale")
1723
+ /**
1724
+ * Why an inspect packet is stale.
1725
+ */
1726
+ export type MutationStaleReason = ("file-missing" | "no-digest" | "source-changed" | "mutant-not-reproduced")
1603
1727
  /**
1604
1728
  * Discriminator value for [`CodeClimateIssue::kind`].
1605
1729
  */
@@ -1667,7 +1791,8 @@ gate_outcomes?: (GateOutcomes | null)
1667
1791
  */
1668
1792
  _meta?: (Meta | null)
1669
1793
  /**
1670
- * Dead-code findings scoped to the audit changeset.
1794
+ * Dead-code findings scoped to the audit changeset. Absent when no file
1795
+ * changed, or when `summary.dead_code_skipped` says the pass was skipped.
1671
1796
  */
1672
1797
  dead_code?: (CheckOutput | null)
1673
1798
  /**
@@ -1678,6 +1803,12 @@ duplication?: (DupesReportPayload | null)
1678
1803
  * Complexity findings scoped to the audit changeset.
1679
1804
  */
1680
1805
  complexity?: (HealthReport | null)
1806
+ /**
1807
+ * Diff-risk findings: facts about the change itself, such as weakened
1808
+ * tests or added suppressions. Every finding is introduced. Absent when
1809
+ * the change has no diff-risk finding.
1810
+ */
1811
+ diff_risk?: (DiffRiskReport | null)
1681
1812
  /**
1682
1813
  * Read-only follow-up commands computed from this run's findings. See
1683
1814
  * `CheckOutput::next_steps` for the contract.
@@ -1696,6 +1827,24 @@ dead_code_issues: number
1696
1827
  * Whether any reported dead-code issue has error severity.
1697
1828
  */
1698
1829
  dead_code_has_errors: boolean
1830
+ /**
1831
+ * True when `--only`, `--skip` or `audit.deadCode = false` skipped the
1832
+ * dead-code sub-analysis. The dead-code counts are then 0 and do not mean
1833
+ * a clean result. Omitted when the sub-analysis ran.
1834
+ */
1835
+ dead_code_skipped?: boolean
1836
+ /**
1837
+ * True when `--only`, `--skip` or `audit.health = false` skipped the
1838
+ * health sub-analysis. The complexity and styling counts are then 0 and
1839
+ * do not mean a clean result. Omitted when the sub-analysis ran.
1840
+ */
1841
+ complexity_skipped?: boolean
1842
+ /**
1843
+ * True when `--only`, `--skip` or `audit.dupes = false` skipped the
1844
+ * duplication sub-analysis. The clone-group counts are then 0 and do not
1845
+ * mean a clean result. Omitted when the sub-analysis ran.
1846
+ */
1847
+ duplication_skipped?: boolean
1699
1848
  /**
1700
1849
  * Total complexity findings reported for the changed files.
1701
1850
  */
@@ -1742,6 +1891,7 @@ duplication_inherited: number
1742
1891
  styling_introduced: number
1743
1892
  styling_inherited: number
1744
1893
  duplication_demoted: number
1894
+ diff_risk_introduced: number
1745
1895
  }
1746
1896
  /**
1747
1897
  * The verdict of every gate a run evaluated, keyed by name.
@@ -3086,6 +3236,23 @@ unused_component_outputs?: UnusedComponentOutputFinding[]
3086
3236
  * `warn`.
3087
3237
  */
3088
3238
  unused_svelte_events?: UnusedSvelteEventFinding[]
3239
+ /**
3240
+ * Effect layers composed only into other layers that nothing uses.
3241
+ * Gated on the project declaring `effect`. Default severity is `warn`.
3242
+ */
3243
+ unused_effect_layers?: UnusedEffectLayerFinding[]
3244
+ /**
3245
+ * Effect tagged error classes that only type positions or `catchTag`
3246
+ * handlers reference. Gated on the project declaring `effect`. Default
3247
+ * severity is `warn`.
3248
+ */
3249
+ unused_tagged_errors?: UnusedTaggedErrorFinding[]
3250
+ /**
3251
+ * `catchTag` / `catchTags` handlers for a project tag that no code
3252
+ * produces and that no `unused_tagged_errors` entry covers. Gated on the
3253
+ * project declaring `effect`. Default severity is `warn`.
3254
+ */
3255
+ unproduced_catch_tags?: UnproducedCatchTagFinding[]
3089
3256
  /**
3090
3257
  * Next.js Server Actions (exports of `"use server"` files) that no code in
3091
3258
  * the project references. Reclassified out of `unused_exports` for
@@ -3211,7 +3378,8 @@ _meta?: (Meta | null)
3211
3378
  *
3212
3379
  * - workspace discovery, at config load: `undeclared-workspace`,
3213
3380
  * `malformed-package-json`, `glob-matched-no-package-json`,
3214
- * `malformed-tsconfig`, `tsconfig-reference-dir-missing`;
3381
+ * `workspace-glob-outside-root`, `malformed-tsconfig`,
3382
+ * `tsconfig-reference-dir-missing`;
3215
3383
  * - source discovery, during the file walk: `skipped-large-file`,
3216
3384
  * `skipped-minified-file`, `skipped-source-dotdir`,
3217
3385
  * `excluded-by-default-ignore`, `source-read-failure`,
@@ -3293,6 +3461,10 @@ export interface CheckSummary {
3293
3461
  * Total number of issues across all categories.
3294
3462
  */
3295
3463
  total_issues: number
3464
+ /**
3465
+ * Prop chains whose saved effective severity explicitly enforces error policy.
3466
+ */
3467
+ prop_drilling_chains?: number
3296
3468
  /**
3297
3469
  * Unused source files.
3298
3470
  */
@@ -3364,6 +3536,18 @@ unused_component_outputs?: number
3364
3536
  * whose name is listened to nowhere in the project.
3365
3537
  */
3366
3538
  unused_svelte_events?: number
3539
+ /**
3540
+ * Effect layers composed only into layers that nothing uses.
3541
+ */
3542
+ unused_effect_layers?: number
3543
+ /**
3544
+ * Effect tagged error classes that no code constructs or fails with.
3545
+ */
3546
+ unused_tagged_errors?: number
3547
+ /**
3548
+ * `catchTag` handlers for a project tag that no code produces.
3549
+ */
3550
+ unproduced_catch_tags?: number
3367
3551
  /**
3368
3552
  * Next.js Server Actions (exports of `"use server"` files) referenced by no
3369
3553
  * code in the project.
@@ -6279,6 +6463,181 @@ introduced?: (AuditIntroduced | null)
6279
6463
  */
6280
6464
  effective_severity?: (EffectiveSeverity | null)
6281
6465
  }
6466
+ /**
6467
+ * Wire-shape envelope for an [`UnusedEffectLayer`] finding. There is no safe auto-fix: a test or a script outside the project graph can still use the layer. Actions are manual
6468
+ * remediation guidance plus a line-level suppress.
6469
+ */
6470
+ export interface UnusedEffectLayerFinding {
6471
+ /**
6472
+ * The module that defines the layer.
6473
+ */
6474
+ path: string
6475
+ /**
6476
+ * `FooLive`, or `FooService.layer` for a static member.
6477
+ */
6478
+ name: string
6479
+ kind: EffectLayerKind
6480
+ /**
6481
+ * 1-based line number of the layer name.
6482
+ */
6483
+ line: number
6484
+ /**
6485
+ * 0-based byte column offset of the layer name.
6486
+ */
6487
+ col: number
6488
+ /**
6489
+ * The unused layers that compose this layer, sorted by name.
6490
+ */
6491
+ dead_consumers: string[]
6492
+ /**
6493
+ * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
6494
+ * `~<k>` suffix when several findings of one type share an identity.
6495
+ * Line and column are not inputs, so the id survives line shifts,
6496
+ * reformats and reorders. A rename of the file or the symbol gives a
6497
+ * new id. Absent in output from older versions.
6498
+ */
6499
+ finding_id?: (string | null)
6500
+ /**
6501
+ * Suggested next steps. Always emitted (possibly empty for
6502
+ * forward-compat).
6503
+ */
6504
+ actions: IssueAction[]
6505
+ /**
6506
+ * Set by the audit pass when this finding is introduced relative to
6507
+ * the merge-base.
6508
+ */
6509
+ introduced?: (AuditIntroduced | null)
6510
+ /**
6511
+ * Gate severity of this finding after `rules` and `overrides[].rules`
6512
+ * resolve for its path. CI formats read it for the annotation, SARIF
6513
+ * and CodeClimate level. Absent in output from older versions. Not
6514
+ * part of the finding identity, baseline keys or fingerprints.
6515
+ */
6516
+ effective_severity?: (EffectiveSeverity | null)
6517
+ }
6518
+ /**
6519
+ * Wire-shape envelope for an [`UnusedTaggedError`] finding. There is no safe auto-fix: the error can be part of a public API contract. Actions are manual
6520
+ * remediation guidance plus a line-level suppress.
6521
+ */
6522
+ export interface UnusedTaggedErrorFinding {
6523
+ /**
6524
+ * The module that declares the class.
6525
+ */
6526
+ path: string
6527
+ /**
6528
+ * The class name.
6529
+ */
6530
+ name: string
6531
+ /**
6532
+ * The `_tag` value of the class.
6533
+ */
6534
+ tag: string
6535
+ /**
6536
+ * 1-based line number of the class name.
6537
+ */
6538
+ line: number
6539
+ /**
6540
+ * 0-based byte column offset of the class name.
6541
+ */
6542
+ col: number
6543
+ /**
6544
+ * The `catchTag` / `catchTags` handlers that name the tag.
6545
+ */
6546
+ catch_sites: EffectCatchSite[]
6547
+ /**
6548
+ * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
6549
+ * `~<k>` suffix when several findings of one type share an identity.
6550
+ * Line and column are not inputs, so the id survives line shifts,
6551
+ * reformats and reorders. A rename of the file or the symbol gives a
6552
+ * new id. Absent in output from older versions.
6553
+ */
6554
+ finding_id?: (string | null)
6555
+ /**
6556
+ * Suggested next steps. Always emitted (possibly empty for
6557
+ * forward-compat).
6558
+ */
6559
+ actions: IssueAction[]
6560
+ /**
6561
+ * Set by the audit pass when this finding is introduced relative to
6562
+ * the merge-base.
6563
+ */
6564
+ introduced?: (AuditIntroduced | null)
6565
+ /**
6566
+ * Gate severity of this finding after `rules` and `overrides[].rules`
6567
+ * resolve for its path. CI formats read it for the annotation, SARIF
6568
+ * and CodeClimate level. Absent in output from older versions. Not
6569
+ * part of the finding identity, baseline keys or fingerprints.
6570
+ */
6571
+ effective_severity?: (EffectiveSeverity | null)
6572
+ }
6573
+ /**
6574
+ * A source location of a `catchTag` or `catchTags` handler.
6575
+ */
6576
+ export interface EffectCatchSite {
6577
+ /**
6578
+ * The module that contains the handler.
6579
+ */
6580
+ path: string
6581
+ /**
6582
+ * 1-based line number of the handled tag.
6583
+ */
6584
+ line: number
6585
+ /**
6586
+ * 0-based byte column offset of the handled tag.
6587
+ */
6588
+ col: number
6589
+ }
6590
+ /**
6591
+ * Wire-shape envelope for an [`UnproducedCatchTag`] finding. There is no safe auto-fix: the handler can guard against a future producer. Actions are manual
6592
+ * remediation guidance plus a line-level suppress.
6593
+ */
6594
+ export interface UnproducedCatchTagFinding {
6595
+ /**
6596
+ * The module that contains the handler.
6597
+ */
6598
+ path: string
6599
+ /**
6600
+ * The handled tag.
6601
+ */
6602
+ tag: string
6603
+ /**
6604
+ * 1-based line number of the handled tag.
6605
+ */
6606
+ line: number
6607
+ /**
6608
+ * 0-based byte column offset of the handled tag.
6609
+ */
6610
+ col: number
6611
+ /**
6612
+ * The project classes that declare the tag, sorted by name.
6613
+ */
6614
+ candidate_classes: string[]
6615
+ /**
6616
+ * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
6617
+ * `~<k>` suffix when several findings of one type share an identity.
6618
+ * Line and column are not inputs, so the id survives line shifts,
6619
+ * reformats and reorders. A rename of the file or the symbol gives a
6620
+ * new id. Absent in output from older versions.
6621
+ */
6622
+ finding_id?: (string | null)
6623
+ /**
6624
+ * Suggested next steps. Always emitted (possibly empty for
6625
+ * forward-compat).
6626
+ */
6627
+ actions: IssueAction[]
6628
+ /**
6629
+ * Set by the audit pass when this finding is introduced relative to
6630
+ * the merge-base.
6631
+ */
6632
+ introduced?: (AuditIntroduced | null)
6633
+ /**
6634
+ * Gate severity of this finding after `rules` and `overrides[].rules`
6635
+ * resolve for its path. CI formats read it for the annotation, SARIF
6636
+ * and CodeClimate level. Absent in output from older versions. Not
6637
+ * part of the finding identity, baseline keys or fingerprints.
6638
+ */
6639
+ effective_severity?: (EffectiveSeverity | null)
6640
+ }
6282
6641
  /**
6283
6642
  * Wire-shape envelope for an [`UnusedServerAction`] finding. There is no safe
6284
6643
  * auto-fix: the fix is binary but judgement-bearing (wire the action up to a
@@ -6425,11 +6784,10 @@ actions: IssueAction[]
6425
6784
  */
6426
6785
  introduced?: (AuditIntroduced | null)
6427
6786
  /**
6428
- * Rule severity of this finding. This type never gates the run, so the
6429
- * value does not change the exit code. `fallow report --from` reads it
6430
- * for the SARIF level, so the level does not depend on the config at
6431
- * render time. Absent in output from older versions. Not part of the
6432
- * finding identity, baseline keys or fingerprints.
6787
+ * Rule severity after resolving overrides for the source hop. An explicit
6788
+ * `error` enforces the chain; `warn` stays advisory under strict flags.
6789
+ * Saved reports use this value for CI levels. Absent in older output.
6790
+ * Not part of finding identity, baseline keys or fingerprints.
6433
6791
  */
6434
6792
  effective_severity?: (EffectiveSeverity | null)
6435
6793
  }
@@ -7481,11 +7839,24 @@ hotspots?: HotspotFinding[]
7481
7839
  * beside it rather than gating this summary.
7482
7840
  */
7483
7841
  hotspot_summary?: (HotspotSummary | null)
7842
+ /**
7843
+ * Hidden change coupling: file pairs that change together in the git
7844
+ * history without an import or re-export chain between them. Present
7845
+ * when the hotspots section ran and the run read the git history.
7846
+ * Advisory: no health score weight.
7847
+ */
7848
+ change_coupling?: (ChangeCouplingReport | null)
7484
7849
  /**
7485
7850
  * Runtime coverage findings from the paid sidecar (only populated with
7486
7851
  * `--runtime-coverage`).
7487
7852
  */
7488
7853
  runtime_coverage?: (RuntimeCoverageReport | null)
7854
+ /**
7855
+ * The join of a saved mutation report with the complexity findings
7856
+ * (only populated with `--mutation-report`). It never changes the CRAP
7857
+ * scores or the health score.
7858
+ */
7859
+ mutation?: (HealthMutationSummary | null)
7489
7860
  /**
7490
7861
  * Combined coverage, runtime, complexity, and change-scope verdicts.
7491
7862
  */
@@ -7621,6 +7992,13 @@ effective_severity?: (EffectiveSeverity | null)
7621
7992
  * CRAP score (change risk anti-pattern), when coverage data exists.
7622
7993
  */
7623
7994
  crap?: (number | null)
7995
+ /**
7996
+ * Mutation evidence of the function from a saved `fallow mutation`
7997
+ * report (`fallow health --mutation-report`). A separate value: it never
7998
+ * changes `crap` or the health score. Absent without the flag, and when
7999
+ * no function result of the report matches the finding.
8000
+ */
8001
+ mutation?: (HealthFindingMutation | null)
7624
8002
  /**
7625
8003
  * Test coverage percentage (0-100) backing the CRAP score.
7626
8004
  */
@@ -7719,45 +8097,118 @@ custom: number
7719
8097
  max_effect_dep_arity?: (number | null)
7720
8098
  }
7721
8099
  /**
7722
- * Component-level aggregate attached to a template complexity finding,
7723
- * pairing the template's scores with the worst class-side function.
8100
+ * The mutation evidence of one complexity finding.
7724
8101
  */
7725
- export interface ComponentRollup {
8102
+ export interface HealthFindingMutation {
8103
+ state: HealthMutationState
7726
8104
  /**
7727
- * Component name.
8105
+ * Why the evidence is stale. Absent when the state is `fresh`.
7728
8106
  */
7729
- component: string
8107
+ stale_reason?: (HealthMutationStaleReason | null)
7730
8108
  /**
7731
- * Name of the worst-scoring function in the component class.
8109
+ * The mutation score of the function, a fraction from 0 to 1:
8110
+ * `(killed + timeout) / (killed + timeout + survived)`. Absent when the
8111
+ * state is `stale`, and when no mutant of the function ran to a tested
8112
+ * result.
7732
8113
  */
7733
- class_worst_function: string
8114
+ score?: (number | null)
7734
8115
  /**
7735
- * Cyclomatic complexity of that worst class function.
8116
+ * The number of mutants of the function for each status. Absent when
8117
+ * the state is `stale`.
7736
8118
  */
7737
- class_cyclomatic: number
8119
+ counts?: (MutationStatusCounts | null)
8120
+ }
7738
8121
  /**
7739
- * Cognitive complexity of that worst class function.
8122
+ * The number of mutants for each status, and the mutation score.
7740
8123
  */
7741
- class_cognitive: number
8124
+ export interface MutationStatusCounts {
7742
8125
  /**
7743
- * Template file path relative to the project root.
8126
+ * Each mutant.
7744
8127
  */
7745
- template_path: string
8128
+ total: number
7746
8129
  /**
7747
- * Cyclomatic complexity of the template.
8130
+ * Killed mutants.
7748
8131
  */
7749
- template_cyclomatic: number
8132
+ killed: number
7750
8133
  /**
7751
- * Cognitive complexity of the template.
8134
+ * Mutants that passed their timeout.
7752
8135
  */
7753
- template_cognitive: number
7754
- }
8136
+ timeout: number
7755
8137
  /**
7756
- * A single complexity increment, located at its source line/column.
7757
- *
7758
- * `weight` is the amount this construct added to `metric`; for nested
7759
- * cognitive increments `weight == 1 + nesting`. Consumers that render inline
7760
- * (the VS Code editor breakdown) group contributions by `line` and sum the
8138
+ * Mutants that each covering test let pass.
8139
+ */
8140
+ survived: number
8141
+ /**
8142
+ * Mutants that no test reaches.
8143
+ */
8144
+ no_coverage: number
8145
+ /**
8146
+ * Mutants with a runner fault.
8147
+ */
8148
+ runtime_error: number
8149
+ /**
8150
+ * Mutants where the second run in a new companion changed whether the
8151
+ * tests detect the mutant.
8152
+ */
8153
+ flaky: number
8154
+ /**
8155
+ * Mutants that a static rule removed.
8156
+ */
8157
+ pruned: number
8158
+ /**
8159
+ * Mutants that did not run.
8160
+ */
8161
+ pending: number
8162
+ /**
8163
+ * Mutants that a verdict marks as equivalent.
8164
+ */
8165
+ equivalent: number
8166
+ /**
8167
+ * Survived mutants that do not type-check. A report from a version
8168
+ * before `--typecheck` has no such field, so it reads as 0.
8169
+ */
8170
+ compile_error?: number
8171
+ }
8172
+ /**
8173
+ * Component-level aggregate attached to a template complexity finding,
8174
+ * pairing the template's scores with the worst class-side function.
8175
+ */
8176
+ export interface ComponentRollup {
8177
+ /**
8178
+ * Component name.
8179
+ */
8180
+ component: string
8181
+ /**
8182
+ * Name of the worst-scoring function in the component class.
8183
+ */
8184
+ class_worst_function: string
8185
+ /**
8186
+ * Cyclomatic complexity of that worst class function.
8187
+ */
8188
+ class_cyclomatic: number
8189
+ /**
8190
+ * Cognitive complexity of that worst class function.
8191
+ */
8192
+ class_cognitive: number
8193
+ /**
8194
+ * Template file path relative to the project root.
8195
+ */
8196
+ template_path: string
8197
+ /**
8198
+ * Cyclomatic complexity of the template.
8199
+ */
8200
+ template_cyclomatic: number
8201
+ /**
8202
+ * Cognitive complexity of the template.
8203
+ */
8204
+ template_cognitive: number
8205
+ }
8206
+ /**
8207
+ * A single complexity increment, located at its source line/column.
8208
+ *
8209
+ * `weight` is the amount this construct added to `metric`; for nested
8210
+ * cognitive increments `weight == 1 + nesting`. Consumers that render inline
8211
+ * (the VS Code editor breakdown) group contributions by `line` and sum the
7761
8212
  * weights, deferring the per-kind list to a hover.
7762
8213
  */
7763
8214
  export interface ComplexityContribution {
@@ -8473,11 +8924,11 @@ function_count: number
8473
8924
  lines: number
8474
8925
  /**
8475
8926
  * Highest CRAP score among the file's functions. Always the raw measured
8476
- * value; threshold overrides never rewrite it.
8927
+ * value; threshold overrides and suppressions never rewrite it.
8477
8928
  */
8478
8929
  crap_max: number
8479
8930
  /**
8480
- * Functions whose rounded CRAP score meets or exceeds their effective
8931
+ * Unsuppressed functions whose rounded CRAP score meets or exceeds their effective
8481
8932
  * ceiling, resolved from `health.thresholdOverrides` over the global
8482
8933
  * `maxCrap` / `--max-crap` value. Zero when CRAP enforcement is disabled
8483
8934
  * (global ceiling `0`).
@@ -8491,6 +8942,26 @@ crap_above_threshold: number
8491
8942
  * function at or above the canonical baseline. Omitted when zero.
8492
8943
  */
8493
8944
  crap_exempted?: number
8945
+ /**
8946
+ * Concrete scored functions accepted by a complexity suppression, including
8947
+ * subthreshold functions and disabled-enforcement runs. Omitted when zero.
8948
+ * May overlap with configured exemptions; the counts are not a partition.
8949
+ */
8950
+ crap_suppressed?: number
8951
+ /**
8952
+ * Highest rounded CRAP among unsuppressed scored functions, including
8953
+ * subthreshold and configured-exempt functions. Present with the paired
8954
+ * unsuppressed threshold whenever a scored suppression exists. Explicitly
8955
+ * zero when every scored function is suppressed; raw crap_max is unchanged.
8956
+ */
8957
+ crap_unsuppressed_max?: (number | null)
8958
+ /**
8959
+ * Lowest effective ceiling among unsuppressed scored functions, or the run
8960
+ * global when none remain. Emitted with crap_unsuppressed_max. Consumers
8961
+ * receiving an absent or partial pair fall back to the complete legacy pair:
8962
+ * crap_max and crap_effective_threshold (or the run global when absent).
8963
+ */
8964
+ crap_unsuppressed_effective_threshold?: (number | null)
8494
8965
  /**
8495
8966
  * Lowest effective CRAP ceiling among the file's functions, present only
8496
8967
  * when it differs from the run global (`summary.max_crap_threshold`).
@@ -8712,6 +9183,19 @@ complexity_density: number
8712
9183
  */
8713
9184
  fan_in: number
8714
9185
  trend: ChurnTrend
9186
+ /**
9187
+ * Change dispersion: the median number of analyzed files in the commits
9188
+ * that changed this file, over the change coupling history window. Bulk
9189
+ * commits above the coupling file cap are not counted. Absent when the
9190
+ * history has no commit ids (for example imported churn without them).
9191
+ */
9192
+ median_files_per_commit?: (number | null)
9193
+ /**
9194
+ * Change dispersion: the median number of changed lines (added plus
9195
+ * deleted, analyzed files only) in the commits that changed this file.
9196
+ * Same window and rules as `median_files_per_commit`.
9197
+ */
9198
+ median_lines_per_commit?: (number | null)
8715
9199
  /**
8716
9200
  * Ownership metrics, when ownership analysis ran.
8717
9201
  */
@@ -8885,6 +9369,105 @@ epoch_secs: number
8885
9369
  */
8886
9370
  reproducible: boolean
8887
9371
  }
9372
+ /**
9373
+ * Hidden change coupling: pairs of files that change together in the git
9374
+ * history while no import or re-export chain connects them.
9375
+ *
9376
+ * An agent that follows the import graph cannot find the second file of a
9377
+ * hidden pair. The section is advisory: it has no health score weight and
9378
+ * never gates.
9379
+ */
9380
+ export interface ChangeCouplingReport {
9381
+ /**
9382
+ * History window that the section reads, for example `"12 months"`.
9383
+ * Without `--since` the window is 12 months, wider than the hotspot
9384
+ * window.
9385
+ */
9386
+ since: string
9387
+ /**
9388
+ * Commits that changed at least one analyzed file and were not skipped.
9389
+ */
9390
+ commits_analyzed: number
9391
+ /**
9392
+ * Commits skipped because they changed more analyzed files than
9393
+ * `thresholds.max_files_per_commit`.
9394
+ */
9395
+ commits_skipped: number
9396
+ /**
9397
+ * Hidden pairs in scope before `--top` cuts `pairs`.
9398
+ */
9399
+ total_pairs: number
9400
+ thresholds: ChangeCouplingThresholds
9401
+ /**
9402
+ * Hidden pairs, sorted by `degree` and then `shared_revisions` (both
9403
+ * descending), then by path. Empty when the history cannot show
9404
+ * coupling; `workspace_diagnostics` then tells why.
9405
+ */
9406
+ pairs: HiddenCouplingPair[]
9407
+ }
9408
+ /**
9409
+ * Thresholds that a hidden pair met.
9410
+ */
9411
+ export interface ChangeCouplingThresholds {
9412
+ /**
9413
+ * Commits with more analyzed files than this are skipped.
9414
+ */
9415
+ max_files_per_commit: number
9416
+ /**
9417
+ * Minimum commits for each file of a pair.
9418
+ */
9419
+ min_revisions: number
9420
+ /**
9421
+ * Minimum commits that change both files of a pair.
9422
+ */
9423
+ min_shared_revisions: number
9424
+ /**
9425
+ * Minimum coupling degree, from 0 to 1.
9426
+ */
9427
+ min_degree: number
9428
+ /**
9429
+ * Degree at or above which a pair is `strong`.
9430
+ */
9431
+ strong_degree: number
9432
+ }
9433
+ /**
9434
+ * Two files that change together without a static edge between them.
9435
+ */
9436
+ export interface HiddenCouplingPair {
9437
+ /**
9438
+ * First file, relative to the project root. Sorts before `path_b`.
9439
+ */
9440
+ path_a: string
9441
+ /**
9442
+ * Second file, relative to the project root.
9443
+ */
9444
+ path_b: string
9445
+ /**
9446
+ * Commits that changed `path_a` in the window.
9447
+ */
9448
+ revisions_a: number
9449
+ /**
9450
+ * Commits that changed `path_b` in the window.
9451
+ */
9452
+ revisions_b: number
9453
+ /**
9454
+ * Commits that changed both files.
9455
+ */
9456
+ shared_revisions: number
9457
+ /**
9458
+ * Coupling degree from 0 to 1: `shared_revisions` divided by the mean of
9459
+ * `revisions_a` and `revisions_b`.
9460
+ */
9461
+ degree: number
9462
+ /**
9463
+ * True when `degree` reaches `thresholds.strong_degree`. The check uses
9464
+ * the rounded `degree` that the report shows, so 0.495 counts as 0.5.
9465
+ * A strong pair gives each file the `hidden_coupling` target factor. A
9466
+ * file that no other target rule claims becomes a
9467
+ * `resolve_hidden_coupling` refactoring target.
9468
+ */
9469
+ strong?: boolean
9470
+ }
8888
9471
  /**
8889
9472
  * Runtime coverage findings merged into the health report or emitted by
8890
9473
  * `fallow coverage analyze`. Present in health output when --runtime-coverage
@@ -9439,6 +10022,50 @@ stale: boolean
9439
10022
  */
9440
10023
  stale_after_days: number
9441
10024
  }
10025
+ /**
10026
+ * The join of a saved mutation report with the complexity findings.
10027
+ */
10028
+ export interface HealthMutationSummary {
10029
+ /**
10030
+ * The completion status of the run that wrote the report. Only
10031
+ * `complete` makes an empty survivor list conclusive. Absent when the
10032
+ * report has no completion.
10033
+ */
10034
+ completion?: (MutationCompletionStatus | null)
10035
+ /**
10036
+ * The number of function results in the report.
10037
+ */
10038
+ functions: number
10039
+ /**
10040
+ * The number of complexity findings with fresh mutation evidence.
10041
+ */
10042
+ findings_fresh: number
10043
+ /**
10044
+ * The number of complexity findings with stale mutation evidence.
10045
+ */
10046
+ findings_stale: number
10047
+ /**
10048
+ * The number of complexity findings that no function result of the
10049
+ * report matches. A finding matches when the path, the first line and
10050
+ * the name are equal.
10051
+ */
10052
+ findings_unmatched: number
10053
+ /**
10054
+ * The report files that do not match the current source, sorted by
10055
+ * path. Their functions have no score.
10056
+ */
10057
+ stale_files?: HealthMutationStaleFile[]
10058
+ }
10059
+ /**
10060
+ * One file of the mutation report that does not match the current source.
10061
+ */
10062
+ export interface HealthMutationStaleFile {
10063
+ /**
10064
+ * The root-relative path, with forward slashes.
10065
+ */
10066
+ path: string
10067
+ reason: HealthMutationStaleReason
10068
+ }
9442
10069
  /**
9443
10070
  * Combined coverage, runtime, complexity, and change-scope verdicts.
9444
10071
  */
@@ -9695,6 +10322,11 @@ direct_callers?: DirectCallerEvidence[]
9695
10322
  * Other duplicate-code instances that share a clone group with this target.
9696
10323
  */
9697
10324
  clone_siblings?: CloneSiblingEvidence[]
10325
+ /**
10326
+ * Files that change together with this target without a static edge
10327
+ * (populated for `ResolveHiddenCoupling` targets), strongest first.
10328
+ */
10329
+ co_change_partners?: CoChangePartnerEvidence[]
9698
10330
  }
9699
10331
  /**
9700
10332
  * A function referenced in target evidence.
@@ -9764,6 +10396,23 @@ end_line: number
9764
10396
  */
9765
10397
  fingerprint: string
9766
10398
  }
10399
+ /**
10400
+ * A hidden change-coupling partner referenced in target evidence.
10401
+ */
10402
+ export interface CoChangePartnerEvidence {
10403
+ /**
10404
+ * File that changes together with the target.
10405
+ */
10406
+ path: string
10407
+ /**
10408
+ * Commits that changed both files.
10409
+ */
10410
+ shared_revisions: number
10411
+ /**
10412
+ * Coupling degree from 0 to 1.
10413
+ */
10414
+ degree: number
10415
+ }
9767
10416
  /**
9768
10417
  * Suggested action attached to a [`RefactoringTarget`].
9769
10418
  *
@@ -11223,6 +11872,88 @@ actions: CssCandidateAction[]
11223
11872
  */
11224
11873
  introduced?: (boolean | null)
11225
11874
  }
11875
+ /**
11876
+ * The diff-risk section of `fallow audit` JSON.
11877
+ */
11878
+ export interface DiffRiskReport {
11879
+ /**
11880
+ * Findings, ordered by path, line, rule and kind.
11881
+ */
11882
+ findings: DiffRiskFinding[]
11883
+ }
11884
+ /**
11885
+ * One diff-risk finding.
11886
+ */
11887
+ export interface DiffRiskFinding {
11888
+ rule: DiffRiskRule
11889
+ /**
11890
+ * How the tests were weakened. Present only on `weakened-tests`.
11891
+ */
11892
+ kind?: (WeakenedTestsKind | null)
11893
+ /**
11894
+ * Root-relative path of the changed file, with forward slashes.
11895
+ */
11896
+ path: string
11897
+ /**
11898
+ * 1-based head line. Absent when the finding is about the whole file,
11899
+ * for example removed tests or a deleted file.
11900
+ */
11901
+ line?: (number | null)
11902
+ /**
11903
+ * One-sentence statement of the fact.
11904
+ */
11905
+ message: string
11906
+ /**
11907
+ * The token, the count change, or the value change that supports the
11908
+ * finding.
11909
+ */
11910
+ evidence: string
11911
+ severity: DiffRiskSeverity
11912
+ /**
11913
+ * Always `true`: the change introduced the finding.
11914
+ */
11915
+ introduced: boolean
11916
+ /**
11917
+ * Related locations, such as the unchanged siblings of a clone group.
11918
+ */
11919
+ related?: DiffRiskLocation[]
11920
+ /**
11921
+ * Suppression actions.
11922
+ */
11923
+ actions: DiffRiskAction[]
11924
+ }
11925
+ /**
11926
+ * A location that relates to a diff-risk finding, such as an unchanged clone
11927
+ * sibling.
11928
+ */
11929
+ export interface DiffRiskLocation {
11930
+ /**
11931
+ * Root-relative path, with forward slashes.
11932
+ */
11933
+ path: string
11934
+ /**
11935
+ * 1-based line.
11936
+ */
11937
+ line: number
11938
+ }
11939
+ /**
11940
+ * One action on a diff-risk finding.
11941
+ */
11942
+ export interface DiffRiskAction {
11943
+ type: DiffRiskActionType
11944
+ /**
11945
+ * Always `false`: Fallow does not apply a suppression for you.
11946
+ */
11947
+ auto_fixable: boolean
11948
+ /**
11949
+ * Human-readable description of the action.
11950
+ */
11951
+ description: string
11952
+ /**
11953
+ * The suppression comment to insert. Absent on `suppress-in-config`.
11954
+ */
11955
+ comment?: (string | null)
11956
+ }
11226
11957
  /**
11227
11958
  * Envelope emitted by `fallow explain <issue-type> --format json`.
11228
11959
  *
@@ -11468,6 +12199,29 @@ from_file: string
11468
12199
  * Reference kind, such as named import, default import, or re-export.
11469
12200
  */
11470
12201
  kind: string
12202
+ /**
12203
+ * 1-based line of the import statement in `from_file`. Absent when the
12204
+ * graph holds no source position for the reference or the file cannot be
12205
+ * read.
12206
+ */
12207
+ line?: (number | null)
12208
+ /**
12209
+ * Whether a whole-word text search for the export name finds this
12210
+ * consumer. Absent when no check applies, for example when the consumer
12211
+ * source cannot be read.
12212
+ */
12213
+ search_visibility?: (SearchVisibility | null)
12214
+ /**
12215
+ * Why a text search does not find the uses in this consumer. With
12216
+ * `search_visibility` `found`, only `pass-through` occurs: the consumer
12217
+ * forwards the export and does not use it.
12218
+ */
12219
+ reason?: (SearchGapReason | null)
12220
+ /**
12221
+ * The name to search for in this consumer instead of the export name.
12222
+ * Absent when the export name finds the uses or no single name does.
12223
+ */
12224
+ search_as?: (string | null)
11471
12225
  }
11472
12226
  /**
11473
12227
  * Direct references that credit one namespace of an export binding.
@@ -11556,7 +12310,8 @@ owner_file_reachable: boolean
11556
12310
  */
11557
12311
  owner_is_entry_point: boolean
11558
12312
  /**
11559
- * Files that reference the owning export directly.
12313
+ * Files that reference the owning export directly. The search visibility
12314
+ * fields on each entry check the owner export name, not the member name.
11560
12315
  */
11561
12316
  owner_direct_references: ExportReference[]
11562
12317
  /**
@@ -12126,6 +12881,28 @@ consumed_symbols: string[]
12126
12881
  * Scope note for the syntactic trace.
12127
12882
  */
12128
12883
  note: string
12884
+ /**
12885
+ * Whether a whole-word text search for the consumed symbol names finds
12886
+ * this consumer. When the consumer uses more than one symbol, the worst
12887
+ * level wins (`missed`, then `renamed`, then `found`). Absent when no
12888
+ * check applies, for example when the consumer source cannot be read.
12889
+ */
12890
+ search_visibility?: (SearchVisibility | null)
12891
+ /**
12892
+ * Why a text search does not find the uses of the worst symbol. With
12893
+ * `search_visibility` `found`, only `pass-through` occurs.
12894
+ */
12895
+ reason?: (SearchGapReason | null)
12896
+ /**
12897
+ * The name to search for in this consumer instead of the symbol name.
12898
+ */
12899
+ search_as?: (string | null)
12900
+ /**
12901
+ * The entry of `consumed_symbols` that `search_visibility`, `reason`
12902
+ * and `search_as` describe: the worst symbol, `default` for a default
12903
+ * export. Present when `search_visibility` is present.
12904
+ */
12905
+ search_symbol?: (string | null)
12129
12906
  }
12130
12907
  /**
12131
12908
  * Result of asking how one module reaches another: the shortest import path.
@@ -13084,11 +13861,24 @@ hotspots?: HotspotFinding[]
13084
13861
  * beside it rather than gating this summary.
13085
13862
  */
13086
13863
  hotspot_summary?: (HotspotSummary | null)
13864
+ /**
13865
+ * Hidden change coupling: file pairs that change together in the git
13866
+ * history without an import or re-export chain between them. Present
13867
+ * when the hotspots section ran and the run read the git history.
13868
+ * Advisory: no health score weight.
13869
+ */
13870
+ change_coupling?: (ChangeCouplingReport | null)
13087
13871
  /**
13088
13872
  * Runtime coverage findings from the paid sidecar (only populated with
13089
13873
  * `--runtime-coverage`).
13090
13874
  */
13091
13875
  runtime_coverage?: (RuntimeCoverageReport | null)
13876
+ /**
13877
+ * The join of a saved mutation report with the complexity findings
13878
+ * (only populated with `--mutation-report`). It never changes the CRAP
13879
+ * scores or the health score.
13880
+ */
13881
+ mutation?: (HealthMutationSummary | null)
13092
13882
  /**
13093
13883
  * Combined coverage, runtime, complexity, and change-scope verdicts.
13094
13884
  */
@@ -13990,6 +14780,23 @@ unused_component_outputs?: UnusedComponentOutputFinding[]
13990
14780
  * `warn`.
13991
14781
  */
13992
14782
  unused_svelte_events?: UnusedSvelteEventFinding[]
14783
+ /**
14784
+ * Effect layers composed only into other layers that nothing uses.
14785
+ * Gated on the project declaring `effect`. Default severity is `warn`.
14786
+ */
14787
+ unused_effect_layers?: UnusedEffectLayerFinding[]
14788
+ /**
14789
+ * Effect tagged error classes that only type positions or `catchTag`
14790
+ * handlers reference. Gated on the project declaring `effect`. Default
14791
+ * severity is `warn`.
14792
+ */
14793
+ unused_tagged_errors?: UnusedTaggedErrorFinding[]
14794
+ /**
14795
+ * `catchTag` / `catchTags` handlers for a project tag that no code
14796
+ * produces and that no `unused_tagged_errors` entry covers. Gated on the
14797
+ * project declaring `effect`. Default severity is `warn`.
14798
+ */
14799
+ unproduced_catch_tags?: UnproducedCatchTagFinding[]
13993
14800
  /**
13994
14801
  * Next.js Server Actions (exports of `"use server"` files) that no code in
13995
14802
  * the project references. Reclassified out of `unused_exports` for
@@ -15701,6 +16508,23 @@ unused_component_outputs?: UnusedComponentOutputFinding[]
15701
16508
  * `warn`.
15702
16509
  */
15703
16510
  unused_svelte_events?: UnusedSvelteEventFinding[]
16511
+ /**
16512
+ * Effect layers composed only into other layers that nothing uses.
16513
+ * Gated on the project declaring `effect`. Default severity is `warn`.
16514
+ */
16515
+ unused_effect_layers?: UnusedEffectLayerFinding[]
16516
+ /**
16517
+ * Effect tagged error classes that only type positions or `catchTag`
16518
+ * handlers reference. Gated on the project declaring `effect`. Default
16519
+ * severity is `warn`.
16520
+ */
16521
+ unused_tagged_errors?: UnusedTaggedErrorFinding[]
16522
+ /**
16523
+ * `catchTag` / `catchTags` handlers for a project tag that no code
16524
+ * produces and that no `unused_tagged_errors` entry covers. Gated on the
16525
+ * project declaring `effect`. Default severity is `warn`.
16526
+ */
16527
+ unproduced_catch_tags?: UnproducedCatchTagFinding[]
15704
16528
  /**
15705
16529
  * Next.js Server Actions (exports of `"use server"` files) that no code in
15706
16530
  * the project references. Reclassified out of `unused_exports` for
@@ -15826,7 +16650,8 @@ _meta?: (Meta | null)
15826
16650
  *
15827
16651
  * - workspace discovery, at config load: `undeclared-workspace`,
15828
16652
  * `malformed-package-json`, `glob-matched-no-package-json`,
15829
- * `malformed-tsconfig`, `tsconfig-reference-dir-missing`;
16653
+ * `workspace-glob-outside-root`, `malformed-tsconfig`,
16654
+ * `tsconfig-reference-dir-missing`;
15830
16655
  * - source discovery, during the file walk: `skipped-large-file`,
15831
16656
  * `skipped-minified-file`, `skipped-source-dotdir`,
15832
16657
  * `excluded-by-default-ignore`, `source-read-failure`,
@@ -16624,6 +17449,12 @@ complexity?: (HealthReport | null)
16624
17449
  * comparison ran.
16625
17450
  */
16626
17451
  branching?: (BranchingReport | null)
17452
+ /**
17453
+ * How tests reach the value exports that the diff changes. Advisory,
17454
+ * never gates. Absent when the diff changes no value export or no diff
17455
+ * is known.
17456
+ */
17457
+ test_reach?: (TestReachFacts | null)
16627
17458
  }
16628
17459
  /**
16629
17460
  * The ranked, capped decision surface plus the set of signal_ids the
@@ -16877,6 +17708,28 @@ affected_by_dir_omitted: number
16877
17708
  * deliberately skips story and test consumers that the affected set counts.
16878
17709
  */
16879
17710
  coordination_gap: CoordinationGapFact[]
17711
+ /**
17712
+ * Co-change gaps: a changed file has a hidden change-coupling partner
17713
+ * that is absent from the diff. The two files changed together in most
17714
+ * commits of the history window, but no import or re-export chain
17715
+ * connects them, so the graph facts above cannot point at the partner.
17716
+ * Advisory, never gates. Omitted when empty.
17717
+ * At most 10 entries (`CO_CHANGE_GAP_CAP`), strongest degree first.
17718
+ */
17719
+ co_change_gap?: CoChangeGapFact[]
17720
+ /**
17721
+ * All co-change gaps, before the cap cuts `co_change_gap`. Omitted
17722
+ * when zero.
17723
+ */
17724
+ co_change_gap_count?: number
17725
+ /**
17726
+ * Consumers that a whole-word text search for a changed export name does
17727
+ * not find (`missed`), or finds only under another local name
17728
+ * (`renamed`). Only exports whose declaration statement overlaps an added
17729
+ * diff line count, and only consumers outside the diff. Absent when no
17730
+ * such consumer exists.
17731
+ */
17732
+ search_gap?: (SearchGapFacts | null)
16880
17733
  }
16881
17734
  /**
16882
17735
  * One directory of the blast radius and how many affected files it holds.
@@ -16917,28 +17770,120 @@ consumed_symbols: string[]
16917
17770
  note: string
16918
17771
  }
16919
17772
  /**
16920
- * The weighted focus map: the ranked `review-here` units plus the FULL
16921
- * `deprioritized` escape-hatch list, so nothing is hidden.
16922
- *
16923
- * Completeness invariant (the escape-hatch done-condition): the two lists
16924
- * partition the unit set, so `review_here.len() + deprioritized.len()` equals
16925
- * the total unit count by construction.
17773
+ * One co-change gap: `changed_file` is in the diff, `partner_file` is not,
17774
+ * and history shows that the two files usually change together.
16926
17775
  */
16927
- export interface FocusMap {
17776
+ export interface CoChangeGapFact {
16928
17777
  /**
16929
- * Units labeled `review-here`, ranked by composite score (descending), ties
16930
- * broken by path for determinism.
17778
+ * Root-relative path of the changed file.
16931
17779
  */
16932
- review_here: FocusUnit[]
17780
+ changed_file: string
16933
17781
  /**
16934
- * EVERY de-prioritized unit (`not-prioritized`, plus runtime-backed `skip`
16935
- * units on the paid path) -- the escape hatch. Always present and fully
16936
- * enumerated so a reviewer can always "show me what you de-prioritized"; the
16937
- * human brief collapses it by default and re-expands under
16938
- * `--show-deprioritized`. Nothing is ever hidden, including a `skip`.
17782
+ * Root-relative path of the hidden partner that the diff does not touch.
16939
17783
  */
16940
- deprioritized: FocusUnit[]
16941
- }
17784
+ partner_file: string
17785
+ /**
17786
+ * Commits in the history window that changed both files.
17787
+ */
17788
+ shared_revisions: number
17789
+ /**
17790
+ * Coupling degree from 0 to 1.
17791
+ */
17792
+ degree: number
17793
+ /**
17794
+ * Scope note: history evidence, not a proof that the partner must change.
17795
+ */
17796
+ note: string
17797
+ }
17798
+ /**
17799
+ * The literal-search gap of the changed exports: the consumers that a text
17800
+ * search for the export name does not find or finds only under another name.
17801
+ */
17802
+ export interface SearchGapFacts {
17803
+ /**
17804
+ * Sum of the per-export totals, before the per-export cap. A consumer of
17805
+ * two changed exports counts once for each export.
17806
+ */
17807
+ total: number
17808
+ /**
17809
+ * One entry per changed export with at least one such consumer, sorted
17810
+ * by file and line.
17811
+ */
17812
+ exports: ExportSearchGapFact[]
17813
+ }
17814
+ /**
17815
+ * The `missed` and `renamed` consumers of one changed export.
17816
+ */
17817
+ export interface ExportSearchGapFact {
17818
+ /**
17819
+ * Root-relative path of the changed file that declares the export.
17820
+ */
17821
+ file: string
17822
+ /**
17823
+ * The export name, `default` for a default export.
17824
+ */
17825
+ export_name: string
17826
+ /**
17827
+ * 1-based line of the export.
17828
+ */
17829
+ line: number
17830
+ /**
17831
+ * Number of `missed` and `renamed` consumers of this export, before the
17832
+ * cap.
17833
+ */
17834
+ total: number
17835
+ /**
17836
+ * At most [`SEARCH_GAP_CONSUMER_CAP`] consumers, `missed` first, then by
17837
+ * path.
17838
+ */
17839
+ consumers: SearchGapConsumerFact[]
17840
+ }
17841
+ /**
17842
+ * One consumer that a text search for the export name does not find, or
17843
+ * finds only under another local name.
17844
+ */
17845
+ export interface SearchGapConsumerFact {
17846
+ /**
17847
+ * Root-relative path of the consumer.
17848
+ */
17849
+ consumer_file: string
17850
+ /**
17851
+ * 1-based line of the import statement in the consumer, when known.
17852
+ */
17853
+ line?: (number | null)
17854
+ search_visibility: SearchVisibility
17855
+ /**
17856
+ * Why the text search does not find the uses.
17857
+ */
17858
+ reason?: (SearchGapReason | null)
17859
+ /**
17860
+ * The name to search for in this consumer instead.
17861
+ */
17862
+ search_as?: (string | null)
17863
+ }
17864
+ /**
17865
+ * The weighted focus map: the ranked `review-here` units plus the FULL
17866
+ * `deprioritized` escape-hatch list, so nothing is hidden.
17867
+ *
17868
+ * Completeness invariant (the escape-hatch done-condition): the two lists
17869
+ * partition the unit set, so `review_here.len() + deprioritized.len()` equals
17870
+ * the total unit count by construction.
17871
+ */
17872
+ export interface FocusMap {
17873
+ /**
17874
+ * Units labeled `review-here`, ranked by composite score (descending), ties
17875
+ * broken by path for determinism.
17876
+ */
17877
+ review_here: FocusUnit[]
17878
+ /**
17879
+ * EVERY de-prioritized unit (`not-prioritized`, plus runtime-backed `skip`
17880
+ * units on the paid path) -- the escape hatch. Always present and fully
17881
+ * enumerated so a reviewer can always "show me what you de-prioritized"; the
17882
+ * human brief collapses it by default and re-expands under
17883
+ * `--show-deprioritized`. Nothing is ever hidden, including a `skip`.
17884
+ */
17885
+ deprioritized: FocusUnit[]
17886
+ }
16942
17887
  /**
16943
17888
  * One review unit on the focus map: its file, composite score, label, human
16944
17889
  * reason, and any confidence flags.
@@ -17370,6 +18315,111 @@ branch_points_delta: number
17370
18315
  */
17371
18316
  functions_delta: number
17372
18317
  }
18318
+ /**
18319
+ * How tests reach the value exports that the diff changes.
18320
+ *
18321
+ * A changed export is a value export whose declaring statement overlaps an
18322
+ * added line. The section is advisory: it never changes the verdict or the
18323
+ * exit code.
18324
+ */
18325
+ export interface TestReachFacts {
18326
+ status: TestReachStatus
18327
+ masking: TestReachMasking
18328
+ /**
18329
+ * Number of changed value exports.
18330
+ */
18331
+ total: number
18332
+ counts: TestReachCounts
18333
+ /**
18334
+ * The exports that need attention (`mocked-only`, `none`, `none-file`,
18335
+ * `transitive`), at most [`TEST_REACH_EXPORT_CAP`]. The order is reach
18336
+ * class, then `modified` before `new`, then file, line and name. Empty
18337
+ * for `no-tests`.
18338
+ */
18339
+ exports: ExportTestReachFact[]
18340
+ /**
18341
+ * Number of attention rows left out by the cap.
18342
+ */
18343
+ exports_omitted: number
18344
+ /**
18345
+ * True when the project uses an end-to-end test runner (Playwright or
18346
+ * Cypress). End-to-end tests drive the running app and do not import
18347
+ * source files, so the reach classes do not count them. Absent when no
18348
+ * such runner is present.
18349
+ */
18350
+ e2e_runner?: boolean
18351
+ }
18352
+ /**
18353
+ * Number of changed exports per reach class. The keys are exactly the
18354
+ * [`TestReachClass`] values.
18355
+ */
18356
+ export interface TestReachCounts {
18357
+ /**
18358
+ * Exports that a test file references.
18359
+ */
18360
+ direct: number
18361
+ /**
18362
+ * Exports that tests reach only through other modules.
18363
+ */
18364
+ transitive: number
18365
+ /**
18366
+ * Exports that only mocking tests reference.
18367
+ */
18368
+ "mocked-only": number
18369
+ /**
18370
+ * Exports in a test-reached file without a test-reachable reference.
18371
+ */
18372
+ none: number
18373
+ /**
18374
+ * Exports in a file that no test loads.
18375
+ */
18376
+ "none-file": number
18377
+ /**
18378
+ * Framework configuration exports.
18379
+ */
18380
+ framework: number
18381
+ }
18382
+ /**
18383
+ * One changed export that needs attention.
18384
+ */
18385
+ export interface ExportTestReachFact {
18386
+ /**
18387
+ * Root-relative path of the file that declares the export.
18388
+ */
18389
+ file: string
18390
+ /**
18391
+ * The export name, `default` for a default export.
18392
+ */
18393
+ export_name: string
18394
+ /**
18395
+ * 1-based line of the export.
18396
+ */
18397
+ line: number
18398
+ reach: TestReachClass
18399
+ change: ExportChange
18400
+ /**
18401
+ * Test files that name the export, sorted, at most
18402
+ * [`TEST_REACH_FILE_CAP`]. On a `mocked-only` row these are the mocking
18403
+ * tests. Absent when no test file names the export.
18404
+ */
18405
+ tests?: (string[] | null)
18406
+ /**
18407
+ * Number of test files that name the export, before the cap. Present with
18408
+ * `tests`.
18409
+ */
18410
+ tests_total?: (number | null)
18411
+ /**
18412
+ * True when one of the test files that name the export changed in this
18413
+ * diff. Present with `tests`.
18414
+ */
18415
+ test_changed?: (boolean | null)
18416
+ /**
18417
+ * The mocked modules on the import paths, sorted, at most
18418
+ * [`TEST_REACH_FILE_CAP`]. A mocked module can be a barrel in front of
18419
+ * the declaring file. Present only on `mocked-only` rows.
18420
+ */
18421
+ mocked_targets?: (string[] | null)
18422
+ }
17373
18423
  /**
17374
18424
  * The separable `decision-surface` envelope: the single call that puts taste-
17375
18425
  * decisions in front of a human, callable WITHOUT the full pipeline (the
@@ -17569,6 +18619,12 @@ decisions: DecisionSurface
17569
18619
  * never had a base snapshot.
17570
18620
  */
17571
18621
  branching?: (BranchingReport | null)
18622
+ /**
18623
+ * How tests reach the value exports that the diff changes. Advisory,
18624
+ * never gates. Absent when the diff changes no value export or no diff
18625
+ * is known.
18626
+ */
18627
+ test_reach?: (TestReachFacts | null)
17572
18628
  }
17573
18629
  /**
17574
18630
  * The review direction artifact: the order to review in, the coherent units,
@@ -18656,6 +19712,770 @@ removed: boolean
18656
19712
  */
18657
19713
  model_removed: boolean
18658
19714
  }
19715
+ /**
19716
+ * The envelope of `fallow mutation`.
19717
+ */
19718
+ export interface MutationReport {
19719
+ schema_version: MutationSchemaVersion
19720
+ version: ToolVersion
19721
+ elapsed_ms: ElapsedMs
19722
+ completion: MutationCompletion
19723
+ scope: MutationScopeOutput
19724
+ /**
19725
+ * The runner. Absent when no companion started, for example when no
19726
+ * test file reaches a mutant.
19727
+ */
19728
+ runner?: (MutationRunnerOutput | null)
19729
+ /**
19730
+ * The result cache. Absent with `--no-cache`, and when no companion
19731
+ * started.
19732
+ */
19733
+ cache?: (MutationCacheOutput | null)
19734
+ summary: MutationSummary
19735
+ /**
19736
+ * Each mutant, ranked mutants first.
19737
+ */
19738
+ mutants: MutantResult[]
19739
+ /**
19740
+ * The results per enclosing function, by file and line.
19741
+ */
19742
+ functions: MutationFunctionResult[]
19743
+ /**
19744
+ * True when the project has no test files.
19745
+ */
19746
+ no_test_files: boolean
19747
+ /**
19748
+ * The tests and test files that failed with no active mutant.
19749
+ */
19750
+ baseline_failures: MutationBaselineFailure[]
19751
+ /**
19752
+ * The selected files that the plan did not instrument.
19753
+ */
19754
+ skipped_files: MutationSkippedFile[]
19755
+ /**
19756
+ * The paths of a `paths` scope that select no file.
19757
+ */
19758
+ unmatched_paths: string[]
19759
+ /**
19760
+ * The instrumented files that the runner never loaded.
19761
+ */
19762
+ unloaded_paths: string[]
19763
+ worktree: MutationWorktreeCheck
19764
+ /**
19765
+ * The errors that did not stop the run.
19766
+ */
19767
+ errors: MutationRunIssue[]
19768
+ timings: MutationTimings
19769
+ /**
19770
+ * The mutated files with their SHA-256 digest at plan time, sorted by
19771
+ * path. `fallow mutation inspect` compares the digest with the current
19772
+ * file.
19773
+ */
19774
+ files: MutationPlanFile[]
19775
+ /**
19776
+ * The join with a verdict document. Absent when the run read no verdict
19777
+ * document (`--verdicts` not set).
19778
+ */
19779
+ verdicts?: (MutationVerdictJoin | null)
19780
+ /**
19781
+ * The type check of the survivors. Absent when the run did not check
19782
+ * them (`--typecheck` not set).
19783
+ */
19784
+ typecheck?: (MutationTypecheckOutput | null)
19785
+ }
19786
+ /**
19787
+ * The completion status of a run.
19788
+ */
19789
+ export interface MutationCompletion {
19790
+ status: MutationCompletionStatus
19791
+ /**
19792
+ * Why the run is partial, sorted. Empty for a complete run.
19793
+ */
19794
+ reasons: MutationIncompleteReason[]
19795
+ }
19796
+ /**
19797
+ * The scope of a plan or a run.
19798
+ */
19799
+ export interface MutationScopeOutput {
19800
+ kind: MutationScopeKind
19801
+ /**
19802
+ * The base ref of a `changed` scope.
19803
+ */
19804
+ base_ref?: (string | null)
19805
+ }
19806
+ /**
19807
+ * The test runner of a run.
19808
+ */
19809
+ export interface MutationRunnerOutput {
19810
+ /**
19811
+ * The runner name, for example `vitest`.
19812
+ */
19813
+ name: string
19814
+ /**
19815
+ * The runner version from the project.
19816
+ */
19817
+ version: string
19818
+ /**
19819
+ * The wire protocol version of the companion.
19820
+ */
19821
+ protocol_version: number
19822
+ runtime: MutationRuntimeOutput
19823
+ /**
19824
+ * The number of companion processes that ran mutants.
19825
+ */
19826
+ concurrency: number
19827
+ /**
19828
+ * Facts of the runner setup that limit the result, kebab-case.
19829
+ * `typecheck-not-run`: the project config enables the Vitest type-check
19830
+ * pass, and the run did not execute it, so a type-level kill is not
19831
+ * counted. Absent when the runner states no fact.
19832
+ */
19833
+ notes?: string[]
19834
+ }
19835
+ /**
19836
+ * The JavaScript runtime that ran the companion.
19837
+ */
19838
+ export interface MutationRuntimeOutput {
19839
+ /**
19840
+ * `node` or `bun`.
19841
+ */
19842
+ name: string
19843
+ /**
19844
+ * The version that the runtime reports.
19845
+ */
19846
+ version: string
19847
+ }
19848
+ /**
19849
+ * The result cache facts of a run.
19850
+ */
19851
+ export interface MutationCacheOutput {
19852
+ /**
19853
+ * The mutants whose status came from the cache. They did not run.
19854
+ */
19855
+ hits: number
19856
+ /**
19857
+ * The results that this run added to the cache.
19858
+ */
19859
+ stored: number
19860
+ /**
19861
+ * The test inputs that the cache key does not cover: modules that a
19862
+ * test loads through a dynamic import that the module graph does not
19863
+ * resolve (`dynamic-imports`), and files that a test reads
19864
+ * (`file-reads`). A change to them does not invalidate a cached result.
19865
+ */
19866
+ not_keyed: string[]
19867
+ }
19868
+ /**
19869
+ * The totals of a run.
19870
+ */
19871
+ export interface MutationSummary {
19872
+ counts: MutationStatusCounts
19873
+ /**
19874
+ * The mutation score over the executed mutants, a fraction from 0 to 1:
19875
+ * `(killed + timeout) / (killed + timeout + survived)`. `null` when no
19876
+ * mutant ran to a tested result. `--min-score` and `mutation.minScore`
19877
+ * compare this value in percent.
19878
+ */
19879
+ score?: (number | null)
19880
+ /**
19881
+ * The share of mutants that a test reaches, a fraction from 0 to 1:
19882
+ * `covered / (covered + no_coverage)` over the whole plan. `covered`
19883
+ * counts each executed mutant with a covering test and each `pending`
19884
+ * mutant that a passing dry-run test covers. A `pending` mutant that no
19885
+ * dry-run test covers is `no_coverage`, so a run that `--max-mutants`
19886
+ * caps reports the coverage of the full run. `equivalent` and `pruned`
19887
+ * mutants never count. `null` when no mutant is covered or unreached.
19888
+ */
19889
+ coverage?: (number | null)
19890
+ }
19891
+ /**
19892
+ * One mutant of a run.
19893
+ */
19894
+ export interface MutantResult {
19895
+ /**
19896
+ * The stable mutant id.
19897
+ */
19898
+ mutant_id: string
19899
+ /**
19900
+ * The root-relative path, with forward slashes.
19901
+ */
19902
+ file: string
19903
+ /**
19904
+ * The 1-based line.
19905
+ */
19906
+ line: number
19907
+ /**
19908
+ * The 1-based column.
19909
+ */
19910
+ column: number
19911
+ /**
19912
+ * The byte span in the original file.
19913
+ *
19914
+ * @minItems 2
19915
+ * @maxItems 2
19916
+ */
19917
+ span: [number, number]
19918
+ /**
19919
+ * The operator name, kebab-case.
19920
+ */
19921
+ operator: string
19922
+ /**
19923
+ * The name of the enclosing function.
19924
+ */
19925
+ function?: (string | null)
19926
+ /**
19927
+ * The 1-based first line of the enclosing function.
19928
+ */
19929
+ function_line?: (number | null)
19930
+ /**
19931
+ * The 1-based execution rank of a planned mutant.
19932
+ */
19933
+ rank?: (number | null)
19934
+ status: MutantStatus
19935
+ /**
19936
+ * The static rule of a `pruned` mutant, kebab-case.
19937
+ */
19938
+ prune_reason?: (string | null)
19939
+ /**
19940
+ * The test that killed the mutant in this run. Absent for a kill by an
19941
+ * error outside a test.
19942
+ *
19943
+ * This is evidence of one run, not a stable fact. A run stops at the
19944
+ * first failing test, and it runs the fastest covering test first, so a
19945
+ * second run on the same code can name another covering test. No
19946
+ * fingerprint or baseline comparison uses this field.
19947
+ */
19948
+ killed_by?: (string | null)
19949
+ /**
19950
+ * The tests that reached the mutant in the dry run, sorted by test id.
19951
+ */
19952
+ covering_tests?: string[]
19953
+ /**
19954
+ * True when the mutant runs while a module loads, outside each test.
19955
+ */
19956
+ static_mutant?: boolean
19957
+ /**
19958
+ * The duration of one run in milliseconds. A `killed` mutant after a
19959
+ * retry reports the retry. Each other status reports the first run.
19960
+ */
19961
+ duration_ms?: (number | null)
19962
+ /**
19963
+ * How tests reach the code of the mutant in the module graph. Only a
19964
+ * `no_coverage` mutant has this field.
19965
+ */
19966
+ test_reach?: (MutantTestReach | null)
19967
+ /**
19968
+ * True when the status comes from a first run and a retry in a new
19969
+ * companion. A `survived` or `timeout` mutant without this field got no
19970
+ * retry, because the time budget ended first.
19971
+ */
19972
+ retried?: boolean
19973
+ /**
19974
+ * True when the status comes from the result cache of an earlier run.
19975
+ * The mutant did not run in this run. `--no-cache` runs each mutant.
19976
+ */
19977
+ cached?: boolean
19978
+ /**
19979
+ * The TypeScript diagnostic codes of the new errors of a
19980
+ * `compile_error` mutant, sorted, at most 8.
19981
+ */
19982
+ type_error_codes?: number[]
19983
+ }
19984
+ /**
19985
+ * How tests reach the code of one mutant in the module graph. The class
19986
+ * gives a static reason why no test covers the mutant.
19987
+ *
19988
+ * A mutant in the top-level statement that declares a value export gets the
19989
+ * class of that export. A mutant outside each such statement gets the class
19990
+ * of its file: `none-file` when no test loads the file, `mocked-only` when no
19991
+ * test loads the file and a mock explains an export of the file, and `none`
19992
+ * when a test loads the file.
19993
+ */
19994
+ export interface MutantTestReach {
19995
+ reach: TestReachClass
19996
+ /**
19997
+ * The export whose declaration holds the mutant. Absent for a mutant
19998
+ * outside each value export declaration.
19999
+ */
20000
+ export_name?: (string | null)
20001
+ /**
20002
+ * For `mocked-only`: the test files whose references a mock removed,
20003
+ * sorted.
20004
+ */
20005
+ tests?: string[]
20006
+ /**
20007
+ * For `mocked-only`: the mocked modules on the reference paths, sorted.
20008
+ * A mocked module can be a barrel in front of the file of the mutant.
20009
+ */
20010
+ mocked_targets?: string[]
20011
+ }
20012
+ /**
20013
+ * The results of the mutants of one function.
20014
+ */
20015
+ export interface MutationFunctionResult {
20016
+ /**
20017
+ * The root-relative path, with forward slashes.
20018
+ */
20019
+ file: string
20020
+ /**
20021
+ * The function name. `null` for code outside each function, and for an
20022
+ * anonymous function.
20023
+ */
20024
+ name?: (string | null)
20025
+ /**
20026
+ * The 1-based first line. `null` for code outside each function.
20027
+ */
20028
+ line?: (number | null)
20029
+ /**
20030
+ * The 1-based last line. `null` for code outside each function.
20031
+ */
20032
+ end_line?: (number | null)
20033
+ /**
20034
+ * True when an added line of the diff is in the function.
20035
+ */
20036
+ in_diff: boolean
20037
+ /**
20038
+ * The cyclomatic complexity, when the analysis measured the function.
20039
+ */
20040
+ cyclomatic?: (number | null)
20041
+ counts: MutationStatusCounts
20042
+ /**
20043
+ * The mutation score of the function.
20044
+ */
20045
+ score?: (number | null)
20046
+ /**
20047
+ * The ids of the survived mutants, in rank order.
20048
+ */
20049
+ survived?: string[]
20050
+ }
20051
+ /**
20052
+ * A test or a test file that failed with no active mutant. Its tests do not
20053
+ * decide a mutant status.
20054
+ */
20055
+ export interface MutationBaselineFailure {
20056
+ /**
20057
+ * The test file, root-relative. `null` for an error outside each test
20058
+ * file.
20059
+ */
20060
+ file?: (string | null)
20061
+ /**
20062
+ * The test id, for a failed test.
20063
+ */
20064
+ test_id?: (string | null)
20065
+ /**
20066
+ * The error message, for an error outside a test, or the reason for a
20067
+ * test that did not pass in the dry run of a restarted companion.
20068
+ */
20069
+ message?: (string | null)
20070
+ /**
20071
+ * The mutants that ran without this test, because the test did not pass
20072
+ * in the dry run of a restarted companion. Each of them ran with its
20073
+ * other covering tests. Absent for a failure of the first dry run.
20074
+ */
20075
+ mutant_ids?: string[]
20076
+ }
20077
+ /**
20078
+ * A selected file that the plan did not instrument.
20079
+ */
20080
+ export interface MutationSkippedFile {
20081
+ /**
20082
+ * The root-relative path, with forward slashes.
20083
+ */
20084
+ path: string
20085
+ /**
20086
+ * Why the plan skipped the file, kebab-case.
20087
+ */
20088
+ reason: string
20089
+ }
20090
+ /**
20091
+ * The git worktree check of a run: a run refuses a dirty worktree unless
20092
+ * `--allow-dirty` is set, and it compares the worktree after the run.
20093
+ */
20094
+ export interface MutationWorktreeCheck {
20095
+ /**
20096
+ * False when the root is not in a git worktree, so no check ran.
20097
+ */
20098
+ checked: boolean
20099
+ /**
20100
+ * True when the caller allowed a dirty worktree.
20101
+ */
20102
+ allow_dirty: boolean
20103
+ /**
20104
+ * The paths that were dirty before the run, sorted.
20105
+ */
20106
+ dirty_at_start?: string[]
20107
+ /**
20108
+ * The paths that the run changed, sorted. A non-empty list is an error.
20109
+ */
20110
+ changed_paths: string[]
20111
+ }
20112
+ /**
20113
+ * An error of a run that did not stop the run.
20114
+ */
20115
+ export interface MutationRunIssue {
20116
+ /**
20117
+ * A stable kebab-case code: `runtime-error`, `static-map-miss`,
20118
+ * `test-files-not-discovered`, `typecheck-failed`, `worktree-changed`
20119
+ * or `worktree-check-failed`.
20120
+ */
20121
+ code: string
20122
+ /**
20123
+ * A description.
20124
+ */
20125
+ message: string
20126
+ /**
20127
+ * The mutant of the issue.
20128
+ */
20129
+ mutant_id?: (string | null)
20130
+ /**
20131
+ * The last part of the companion stderr.
20132
+ */
20133
+ stderr_tail?: (string | null)
20134
+ }
20135
+ /**
20136
+ * The wall time of each phase, in milliseconds.
20137
+ */
20138
+ export interface MutationTimings {
20139
+ /**
20140
+ * The analysis and the plan.
20141
+ */
20142
+ plan_ms: number
20143
+ /**
20144
+ * The companion install, the run directory, and the first `init`.
20145
+ */
20146
+ setup_ms: number
20147
+ /**
20148
+ * The dry run.
20149
+ */
20150
+ dry_run_ms: number
20151
+ /**
20152
+ * The mutant runs.
20153
+ */
20154
+ mutants_ms: number
20155
+ /**
20156
+ * The second runs of survived and timed-out mutants.
20157
+ */
20158
+ retry_ms: number
20159
+ /**
20160
+ * The type check of the survivors. Zero when the run did not check
20161
+ * them.
20162
+ */
20163
+ typecheck_ms: number
20164
+ }
20165
+ /**
20166
+ * One instrumented file of a plan.
20167
+ */
20168
+ export interface MutationPlanFile {
20169
+ /**
20170
+ * The root-relative path, with forward slashes.
20171
+ */
20172
+ path: string
20173
+ /**
20174
+ * The SHA-256 digest of the file, lowercase hex.
20175
+ */
20176
+ source_sha256: string
20177
+ /**
20178
+ * The test files that reach the file in the module graph, sorted.
20179
+ */
20180
+ static_test_files: string[]
20181
+ }
20182
+ /**
20183
+ * The result of the join of a run with a verdict document.
20184
+ */
20185
+ export interface MutationVerdictJoin {
20186
+ /**
20187
+ * The SHA-256 digest of the verdict document, lowercase hex.
20188
+ */
20189
+ verdicts_sha256: string
20190
+ /**
20191
+ * The mutants that got the status `equivalent`, sorted.
20192
+ */
20193
+ applied: string[]
20194
+ /**
20195
+ * The verdicts that a test contradicts, sorted: the mutant was killed or
20196
+ * timed out, so it is not equivalent. The status stays.
20197
+ */
20198
+ contradicted: string[]
20199
+ /**
20200
+ * The verdicts for mutants with no tested result (`pending`,
20201
+ * `runtime_error` or `pruned`), sorted. The status stays.
20202
+ */
20203
+ deferred: string[]
20204
+ /**
20205
+ * The verdicts that match no mutant of this run, sorted. A verdict
20206
+ * document can hold keys for code outside the scope of the run, and an
20207
+ * edit of a function gives its mutants new keys.
20208
+ */
20209
+ unmatched: string[]
20210
+ }
20211
+ /**
20212
+ * The type check of the survivors (`--typecheck`).
20213
+ */
20214
+ export interface MutationTypecheckOutput {
20215
+ /**
20216
+ * True when the type check gave a result for each survivor that it
20217
+ * received. False when the companion failed; the survivors then keep
20218
+ * the status `survived`.
20219
+ */
20220
+ completed: boolean
20221
+ /**
20222
+ * The survivors that the type check received.
20223
+ */
20224
+ survivors: number
20225
+ /**
20226
+ * The survivors that the checker checked.
20227
+ */
20228
+ checked: number
20229
+ /**
20230
+ * The checked survivors that do not type-check. They have the status
20231
+ * `compile_error`.
20232
+ */
20233
+ compile_errors: number
20234
+ /**
20235
+ * The survivors that the checker did not check, by reason.
20236
+ */
20237
+ skipped?: MutationTypecheckSkip[]
20238
+ }
20239
+ /**
20240
+ * The number of survivors with one skip reason.
20241
+ */
20242
+ export interface MutationTypecheckSkip {
20243
+ reason: MutationTypecheckSkipReason
20244
+ /**
20245
+ * The number of survivors.
20246
+ */
20247
+ count: number
20248
+ }
20249
+ /**
20250
+ * The envelope of `fallow mutation --plan`. It runs no user code.
20251
+ */
20252
+ export interface MutationPlanOutput {
20253
+ schema_version: MutationPlanSchemaVersion
20254
+ version: ToolVersion
20255
+ elapsed_ms: ElapsedMs
20256
+ scope: MutationScopeOutput
20257
+ counts: MutationPlanCountsOutput
20258
+ /**
20259
+ * Each mutant, ranked mutants first.
20260
+ */
20261
+ mutants: MutationPlanMutant[]
20262
+ /**
20263
+ * The instrumented files.
20264
+ */
20265
+ files: MutationPlanFile[]
20266
+ /**
20267
+ * The union of the static test files, sorted.
20268
+ */
20269
+ test_files: string[]
20270
+ /**
20271
+ * True when the project has no test files.
20272
+ */
20273
+ no_test_files: boolean
20274
+ /**
20275
+ * True when the plan applied the `framework-config` prune rule.
20276
+ */
20277
+ framework_config_checked: boolean
20278
+ /**
20279
+ * The selected files that the plan did not instrument.
20280
+ */
20281
+ skipped_files: MutationSkippedFile[]
20282
+ /**
20283
+ * The paths of a `paths` scope that select no file.
20284
+ */
20285
+ unmatched_paths: string[]
20286
+ }
20287
+ /**
20288
+ * The totals of a plan.
20289
+ */
20290
+ export interface MutationPlanCountsOutput {
20291
+ /**
20292
+ * Each mutant.
20293
+ */
20294
+ total: number
20295
+ /**
20296
+ * Planned mutants.
20297
+ */
20298
+ planned: number
20299
+ /**
20300
+ * Mutants after the mutant limit.
20301
+ */
20302
+ pending: number
20303
+ /**
20304
+ * Mutants that no test file reaches.
20305
+ */
20306
+ no_coverage: number
20307
+ /**
20308
+ * Mutants in unused files.
20309
+ */
20310
+ pruned_dead_code: number
20311
+ /**
20312
+ * Mutants in generated files.
20313
+ */
20314
+ pruned_generated: number
20315
+ /**
20316
+ * Mutants near a file system, process, network or database sink.
20317
+ */
20318
+ pruned_side_effect_sink: number
20319
+ /**
20320
+ * Mutants in framework config exports.
20321
+ */
20322
+ pruned_framework_config: number
20323
+ }
20324
+ /**
20325
+ * One mutant of a plan.
20326
+ */
20327
+ export interface MutationPlanMutant {
20328
+ /**
20329
+ * The stable mutant id.
20330
+ */
20331
+ mutant_id: string
20332
+ /**
20333
+ * The root-relative path, with forward slashes.
20334
+ */
20335
+ file: string
20336
+ /**
20337
+ * The 1-based line.
20338
+ */
20339
+ line: number
20340
+ /**
20341
+ * The 1-based column.
20342
+ */
20343
+ column: number
20344
+ /**
20345
+ * The byte span in the original file.
20346
+ *
20347
+ * @minItems 2
20348
+ * @maxItems 2
20349
+ */
20350
+ span: [number, number]
20351
+ /**
20352
+ * The operator name, kebab-case.
20353
+ */
20354
+ operator: string
20355
+ /**
20356
+ * The name of the enclosing function.
20357
+ */
20358
+ function?: (string | null)
20359
+ /**
20360
+ * The 1-based first line of the enclosing function.
20361
+ */
20362
+ function_line?: (number | null)
20363
+ /**
20364
+ * The 1-based execution rank of a planned mutant.
20365
+ */
20366
+ rank?: (number | null)
20367
+ disposition: MutationPlanDisposition
20368
+ /**
20369
+ * The static rule of a `pruned` mutant, kebab-case.
20370
+ */
20371
+ prune_reason?: (string | null)
20372
+ /**
20373
+ * How tests reach the code of the mutant in the module graph. Only a
20374
+ * `no_coverage` mutant has this field.
20375
+ */
20376
+ test_reach?: (MutantTestReach | null)
20377
+ }
20378
+ /**
20379
+ * The envelope of `fallow mutation inspect`. It runs no user code.
20380
+ */
20381
+ export interface MutationInspectOutput {
20382
+ schema_version: MutationInspectSchemaVersion
20383
+ version: ToolVersion
20384
+ status: MutationInspectStatus
20385
+ /**
20386
+ * Why the packet is stale. Absent for a fresh packet.
20387
+ */
20388
+ stale_reason?: (MutationStaleReason | null)
20389
+ /**
20390
+ * The stable mutant id.
20391
+ */
20392
+ mutant_id: string
20393
+ /**
20394
+ * The root-relative path, with forward slashes.
20395
+ */
20396
+ file: string
20397
+ /**
20398
+ * The 1-based line.
20399
+ */
20400
+ line: number
20401
+ /**
20402
+ * The 1-based column.
20403
+ */
20404
+ column: number
20405
+ /**
20406
+ * The byte span in the original file.
20407
+ *
20408
+ * @minItems 2
20409
+ * @maxItems 2
20410
+ */
20411
+ span: [number, number]
20412
+ /**
20413
+ * The operator name, kebab-case.
20414
+ */
20415
+ operator: string
20416
+ /**
20417
+ * The name of the enclosing function.
20418
+ */
20419
+ function?: (string | null)
20420
+ /**
20421
+ * The 1-based first line of the enclosing function.
20422
+ */
20423
+ function_line?: (number | null)
20424
+ /**
20425
+ * The 1-based execution rank of a planned mutant.
20426
+ */
20427
+ rank?: (number | null)
20428
+ /**
20429
+ * The status of the mutant in the report. Absent for a plan.
20430
+ */
20431
+ report_status?: (MutantStatus | null)
20432
+ /**
20433
+ * The SHA-256 digest of the file in the report.
20434
+ */
20435
+ report_sha256?: (string | null)
20436
+ /**
20437
+ * The SHA-256 digest of the current file. `null` when the file is
20438
+ * missing.
20439
+ */
20440
+ current_sha256?: (string | null)
20441
+ /**
20442
+ * The original and mutated code. `null` for a stale packet.
20443
+ */
20444
+ code?: (MutationInspectCode | null)
20445
+ /**
20446
+ * The tests that reached the mutant in the dry run, sorted.
20447
+ */
20448
+ covering_tests: string[]
20449
+ /**
20450
+ * The test files that reach the file in the module graph, sorted.
20451
+ */
20452
+ static_test_files: string[]
20453
+ /**
20454
+ * The test that killed the mutant in the run of the report.
20455
+ */
20456
+ killed_by?: (string | null)
20457
+ }
20458
+ /**
20459
+ * The code of one mutant, from the current file.
20460
+ */
20461
+ export interface MutationInspectCode {
20462
+ /**
20463
+ * The original text of the span.
20464
+ */
20465
+ original: string
20466
+ /**
20467
+ * The text that replaces the span.
20468
+ */
20469
+ replacement: string
20470
+ /**
20471
+ * The source lines that contain the span, before the mutation.
20472
+ */
20473
+ original_lines: string
20474
+ /**
20475
+ * The same lines with the replacement applied.
20476
+ */
20477
+ mutated_lines: string
20478
+ }
18659
20479
  /**
18660
20480
  * Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
18661
20481
  */