fallow 3.31.0 → 3.33.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.
@@ -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`, `impact`, `impact-cross-repo`, `security`, `security-survivors`, `security-blind-spots`, `dead-code`, `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`. 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`. 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
  /**
@@ -72,6 +72,8 @@ kind: "health"
72
72
  kind: "dupes"
73
73
  }) | (CheckGroupedOutput & {
74
74
  kind: "dead-code-grouped"
75
+ }) | (ArchitectureGroupedOutput & {
76
+ kind: "architecture-grouped"
75
77
  }) | ((ImpactReport | SemanticSymbolImpact) & {
76
78
  kind: "impact"
77
79
  }) | (CrossRepoImpactReport & {
@@ -84,6 +86,8 @@ kind: "security-survivors"
84
86
  kind: "security-blind-spots"
85
87
  }) | (CheckOutput & {
86
88
  kind: "dead-code"
89
+ }) | (ArchitectureOutput & {
90
+ kind: "architecture"
87
91
  }) | (CombinedOutput & {
88
92
  kind: "combined"
89
93
  }) | (FeatureFlagsOutput & {
@@ -108,11 +112,15 @@ kind: "similar-code"
108
112
  kind: "similar-code-inspect"
109
113
  }) | (SimilarCodeReviewOutput & {
110
114
  kind: "similar-code-review"
115
+ }) | (SimilarCodeStatusOutput & {
116
+ kind: "similar-code-status"
117
+ }) | (SimilarCodeCacheClearOutput & {
118
+ kind: "similar-code-cache-clear"
111
119
  }))
112
120
  /**
113
121
  * Schema projection for the audit envelope's exact version.
114
122
  */
115
- export type AuditSchemaVersion = 11
123
+ export type AuditSchemaVersion = 12
116
124
  /**
117
125
  * Fallow CLI version that produced this envelope. Renders to the JSON wire as
118
126
  * a bare string (e.g. `"2.74.0"`).
@@ -204,7 +212,7 @@ export type TypeAwareAbstentionReason = ("no-project" | "ambiguous-project" | "b
204
212
  /**
205
213
  * Schema projection for the dead-code envelope's exact version.
206
214
  */
207
- export type CheckSchemaVersion = 9
215
+ export type CheckSchemaVersion = 10
208
216
  /**
209
217
  * A suggested action attached to a finding in the JSON output. Each finding
210
218
  * carries an `actions` array; consumers (agents, IDE clients, CI bots) can
@@ -261,7 +269,7 @@ export type IssueAction = (FixAction | SuppressLineAction | SuppressFileAction |
261
269
  * Discriminant string for [`FixAction`]. Kebab-case per the JSON output
262
270
  * contract.
263
271
  */
264
- 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" | "emit-component-event" | "wire-svelte-event" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict" | "add-suppression-reason" | "remove-stale-suppression")
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")
265
273
  /**
266
274
  * Singleton discriminant for [`SuppressLineAction`].
267
275
  */
@@ -380,7 +388,7 @@ export type ReExportCycleKind = ("multi-node" | "self-loop")
380
388
  /**
381
389
  * Which rule-pack rule kind produced a [`PolicyViolation`].
382
390
  */
383
- export type PolicyRuleKind = ("banned-call" | "banned-import" | "banned-effect" | "banned-export")
391
+ export type PolicyRuleKind = ("banned-call" | "banned-import" | "banned-effect" | "banned-export" | "gdp-proof-producer")
384
392
  /**
385
393
  * Effective severity of a single [`PolicyViolation`]. Per-rule `severity`
386
394
  * overrides the `rules."policy-violation"` master; `off` rules emit nothing,
@@ -562,7 +570,7 @@ kind: "malformed-tsconfig"
562
570
  kind: "tsconfig-reference-dir-missing"
563
571
  } | {
564
572
  /**
565
- * `serde_yaml_ng` parse error text.
573
+ * YAML parse error text.
566
574
  */
567
575
  error: string
568
576
  kind: "malformed-pnpm-workspace-yaml"
@@ -602,8 +610,15 @@ kind: "bun-lockb-override-resolution-skipped"
602
610
  } | {
603
611
  kind: "bun-lock-override-resolution-skipped"
604
612
  } | {
613
+ kind: "pnpm-lock-override-resolution-skipped"
614
+ } | {
615
+ kind: "npm-lock-override-resolution-skipped"
616
+ } | {
605
617
  kind: "bun-resolutions-shadowed-by-overrides"
606
618
  } | {
619
+ cause: PnpmWorkspaceOverridesIgnoredCause
620
+ kind: "pnpm-workspace-overrides-ignored"
621
+ } | {
607
622
  kind: "node-modules-missing"
608
623
  } | {
609
624
  kind: "boundaries-not-configured"
@@ -690,6 +705,13 @@ kind: "ownership-unavailable"
690
705
  error: string
691
706
  kind: "trend-snapshot-unreadable"
692
707
  } | {
708
+ /**
709
+ * Why the groups have no baseline, as a kebab-case token:
710
+ * `snapshot-has-no-groups` or `grouped-by-mismatch`. The set is open.
711
+ */
712
+ cause: string
713
+ kind: "trend-group-baseline-unavailable"
714
+ } | {
693
715
  /**
694
716
  * The plugin that read the config, as it labels itself:
695
717
  * `module-federation` for a standalone `module-federation.config.*`,
@@ -761,6 +783,11 @@ kind: "ignore-dependencies-glob-unmatched"
761
783
  pattern: string
762
784
  kind: "ignore-findings-pattern-unmatched"
763
785
  })
786
+ /**
787
+ * Why the declared pnpm version ignores the `overrides` section of
788
+ * `pnpm-workspace.yaml`.
789
+ */
790
+ export type PnpmWorkspaceOverridesIgnoredCause = ("package-json-overrides" | "pnpm-version")
764
791
  /**
765
792
  * Discriminant for [`CloneGroupAction::kind`]. Mirrors the action types
766
793
  * emitted by the legacy `build_clone_group_actions` walker.
@@ -839,6 +866,15 @@ export type CoverageInputFormat = ("istanbul" | "v8")
839
866
  * Whether CRAP findings in the report used one coverage-source kind or a mix.
840
867
  */
841
868
  export type CoverageSourceConsistency = ("uniform" | "mixed")
869
+ /**
870
+ * One health section that a run produced.
871
+ *
872
+ * A section is in [`HealthReport::sections`] when the run computed it and
873
+ * the report carries its result, also when that result is empty. The value
874
+ * set is OPEN: a later release can add a section, so a consumer must accept
875
+ * a token that it does not know.
876
+ */
877
+ export type HealthSection = ("complexity" | "vital-signs" | "score" | "file-scores" | "coverage-gaps" | "hotspots" | "targets" | "trend" | "runtime-coverage" | "css")
842
878
  /**
843
879
  * Lifecycle state for a configured threshold override.
844
880
  */
@@ -1093,6 +1129,21 @@ export type InspectSectionStatus = ("ok" | "partial" | "unavailable" | "error")
1093
1129
  * Granularity an [`InspectEvidenceSection`] payload covers.
1094
1130
  */
1095
1131
  export type InspectEvidenceScope = ("symbol" | "file" | "project_filtered_to_file")
1132
+ /**
1133
+ * Wire-shape version of the [`DependencyUsage`] object.
1134
+ *
1135
+ * The object has its own version, because it is an optional part of the
1136
+ * `DependencyTrace` envelope.
1137
+ */
1138
+ export type DependencyUsageSchemaVersion = "1"
1139
+ /**
1140
+ * How the usage was found.
1141
+ */
1142
+ export type UsageConfidence = "syntactic"
1143
+ /**
1144
+ * The shape of a project wrapper.
1145
+ */
1146
+ export type WrapperShape = ("call" | "alias")
1096
1147
  /**
1097
1148
  * Wire-version discriminator for [`ImportPathTrace`]. Independent from the
1098
1149
  * global `SchemaVersion`: the import-path payload versions on its own cadence,
@@ -1202,11 +1253,24 @@ export type HealthSchemaVersion = 11
1202
1253
  * groups by GitLab CODEOWNERS `[Section]` header name.
1203
1254
  */
1204
1255
  export type GroupByMode = ("owner" | "directory" | "package" | "section")
1256
+ /**
1257
+ * What the group trend compared, for one group.
1258
+ *
1259
+ * The value set is open: read an unknown value as "no trend for this group".
1260
+ */
1261
+ export type GroupTrendStatus = ("compared" | "new_group" | "no_group_baseline")
1205
1262
  /**
1206
1263
  * Schema projection for the duplication envelope's CLI and programmatic
1207
1264
  * version lineages.
1208
1265
  */
1209
1266
  export type DupesSchemaVersion = (4 | 10)
1267
+ /**
1268
+ * Schema projection for the architecture envelope's exact version.
1269
+ *
1270
+ * The schema emitter registers this type by name and points the
1271
+ * `ArchitectureOutput` and `ArchitectureGroupedOutput` definitions at it.
1272
+ */
1273
+ export type ArchitectureSchemaVersion = 1
1210
1274
  /**
1211
1275
  * Wire-version discriminator for [`ImpactReport`]. Independent from the global
1212
1276
  * `SchemaVersion` (the impact report versions on its own cadence) and from the
@@ -1318,7 +1382,7 @@ export type SecurityBlindSpotsSchemaVersion = "1"
1318
1382
  /**
1319
1383
  * Schema projection for the combined envelope's exact version.
1320
1384
  */
1321
- export type CombinedSchemaVersion = 12
1385
+ export type CombinedSchemaVersion = 13
1322
1386
  /**
1323
1387
  * Schema projection for the feature-flags envelope's exact version.
1324
1388
  */
@@ -1363,7 +1427,7 @@ export type VendorFlagState = ("on" | "off" | "rolled_out" | "archived" | "exper
1363
1427
  * Independently-versioned wire-version newtype for the brief envelope.
1364
1428
  * Serializes as the integer `REVIEW_BRIEF_SCHEMA_VERSION`.
1365
1429
  */
1366
- export type ReviewBriefSchemaVersion = 11
1430
+ export type ReviewBriefSchemaVersion = 12
1367
1431
  /**
1368
1432
  * The exactly-three shippable decision categories (the SOLID-3). No cut category
1369
1433
  * (abstraction / deletion / convention / irreversibility) is representable: this
@@ -1528,6 +1592,14 @@ export type SimilarCodeDomainOutcome = ("same-responsibility" | "related-but-dis
1528
1592
  * How review matched an external verdict to the current candidate.
1529
1593
  */
1530
1594
  export type SimilarCodeVerdictMatch = ("candidate-id" | "review-key" | "unverified" | "ambiguous-review-key")
1595
+ /**
1596
+ * Version singleton for local-provider status output.
1597
+ */
1598
+ export type SimilarCodeStatusSchemaVersion = "1"
1599
+ /**
1600
+ * Version singleton for vector-cache clear output.
1601
+ */
1602
+ export type SimilarCodeCacheClearSchemaVersion = "1"
1531
1603
  /**
1532
1604
  * Discriminator value for [`CodeClimateIssue::kind`].
1533
1605
  */
@@ -1687,7 +1759,8 @@ duplication_demoted: number
1687
1759
  * gate and leaves the object absent.
1688
1760
  *
1689
1761
  * The names this build can emit are `error-severity-findings`, `regression`,
1690
- * `stale-baseline`, `baseline-growth`, `duplication-threshold`, `health-min-score`,
1762
+ * `stale-baseline`, `baseline-growth`, `duplication-threshold`,
1763
+ * `duplication-findings`, `health-min-score`,
1691
1764
  * `health-min-severity`, `health-findings`, `health-coverage-gaps`,
1692
1765
  * `health-runtime-coverage`, `security`, `security-advisory`, `audit-verdict`,
1693
1766
  * `type-aware-require` and `parse-error`. The set is OPEN: a name a consumer does not
@@ -1725,7 +1798,9 @@ enforced: boolean
1725
1798
  /**
1726
1799
  * The measured value the gate compared, when there is one: the duplication
1727
1800
  * percentage, the health score, the number of findings at or above the
1728
- * severity floor, or the number of files in `files`. Whole numbers are
1801
+ * severity floor, the number of `error` findings of `health-findings` and
1802
+ * of `error-severity-findings`, or
1803
+ * the number of files in `files`. Whole numbers are
1729
1804
  * carried as JSON numbers, so a count of three reads as `3.0`. Absent for
1730
1805
  * gates that compare no number.
1731
1806
  */
@@ -1738,7 +1813,9 @@ threshold?: (number | null)
1738
1813
  /**
1739
1814
  * How the limit was spelled, for a gate whose `threshold` number does not
1740
1815
  * carry its own unit. `health-min-severity` sets it to the severity floor
1741
- * (`moderate`, `high` or `critical`); `regression` sets it to the
1816
+ * (`moderate`, `high` or `critical`); `health-findings` and
1817
+ * `error-severity-findings` set it to `error`, the rule severity they
1818
+ * count; `regression` sets it to the
1742
1819
  * tolerance as the user wrote it (`"50%"` or `"5"`), because `threshold`
1743
1820
  * there is the allowance in issues and the percentage would otherwise be
1744
1821
  * unrecoverable on the grouped envelope, which carries no `regression`
@@ -2976,6 +3053,10 @@ dynamic_segment_name_conflicts?: DynamicSegmentNameConflictFinding[]
2976
3053
  * array natively. Default severity is `warn`.
2977
3054
  */
2978
3055
  unused_component_props?: UnusedComponentPropFinding[]
3056
+ /**
3057
+ * Used optional component inputs absent from inspected reachable callers. Off by default.
3058
+ */
3059
+ absent_component_props?: AbsentComponentPropFinding[]
2979
3060
  /**
2980
3061
  * Vue `<script setup>` `defineEmits` events emitted nowhere in their own SFC
2981
3062
  * (no `emit('<name>')` call). Wrapped in [`UnusedComponentEmitFinding`] so
@@ -3055,6 +3136,16 @@ thin_wrappers?: ThinWrapperFinding[]
3055
3136
  * enables it.
3056
3137
  */
3057
3138
  duplicate_prop_shapes?: DuplicatePropShapeFinding[]
3139
+ /**
3140
+ * Number of `unused_exports`, `unused_types`, `unused_class_members` and
3141
+ * `unused_enum_members` findings that this run did not report because
3142
+ * their file is an unused file. Deleting the file removes them, so they
3143
+ * add no information. `--show-cascade` or the `showCascade` config key
3144
+ * keeps them in the report, and then this count is zero. The count is
3145
+ * taken after the scope and the rules and before a baseline. Serialized
3146
+ * only when not zero, so a run without such findings keeps its JSON.
3147
+ */
3148
+ cascade_hidden?: number
3058
3149
  /**
3059
3150
  * Count deltas against the matched baseline, in baseline runs.
3060
3151
  */
@@ -3252,6 +3343,10 @@ unrendered_components?: number
3252
3343
  * Vue, Svelte, or React props referenced nowhere inside their own component.
3253
3344
  */
3254
3345
  unused_component_props?: number
3346
+ /**
3347
+ * Optional consumed props omitted by known reachable callers, for manual review.
3348
+ */
3349
+ absent_component_props?: number
3255
3350
  /**
3256
3351
  * Vue `<script setup>` emits emitted nowhere inside their own SFC.
3257
3352
  */
@@ -3942,6 +4037,12 @@ line: number
3942
4037
  * Workspace roots that import this package even though the declaring workspace does not.
3943
4038
  */
3944
4039
  used_in_workspaces?: string[]
4040
+ /**
4041
+ * Workspace roots whose package.json declares this package for the files
4042
+ * that import it. Only a root finding fills this field: these imports use
4043
+ * the nearer workspace declaration, so the root declaration stays unused.
4044
+ */
4045
+ declared_and_imported_in?: string[]
3945
4046
  /**
3946
4047
  * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
3947
4048
  * `~<k>` suffix when several findings of one type share an identity.
@@ -4003,6 +4104,12 @@ line: number
4003
4104
  * Workspace roots that import this package even though the declaring workspace does not.
4004
4105
  */
4005
4106
  used_in_workspaces?: string[]
4107
+ /**
4108
+ * Workspace roots whose package.json declares this package for the files
4109
+ * that import it. Only a root finding fills this field: these imports use
4110
+ * the nearer workspace declaration, so the root declaration stays unused.
4111
+ */
4112
+ declared_and_imported_in?: string[]
4006
4113
  /**
4007
4114
  * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
4008
4115
  * `~<k>` suffix when several findings of one type share an identity.
@@ -4064,6 +4171,12 @@ line: number
4064
4171
  * Workspace roots that import this package even though the declaring workspace does not.
4065
4172
  */
4066
4173
  used_in_workspaces?: string[]
4174
+ /**
4175
+ * Workspace roots whose package.json declares this package for the files
4176
+ * that import it. Only a root finding fills this field: these imports use
4177
+ * the nearer workspace declaration, so the root declaration stays unused.
4178
+ */
4179
+ declared_and_imported_in?: string[]
4067
4180
  /**
4068
4181
  * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
4069
4182
  * `~<k>` suffix when several findings of one type share an identity.
@@ -5043,7 +5156,8 @@ kind: PolicyRuleKind
5043
5156
  * What matched: the written callee path for `banned-call` (e.g.
5044
5157
  * `cp.exec`), the raw import specifier for `banned-import` (e.g.
5045
5158
  * `moment/locale/nl`), `<effect>: <callee>` for `banned-effect`, or the
5046
- * exported name for `banned-export`.
5159
+ * exported name for `banned-export`. For `gdp-proof-producer`, the canonical
5160
+ * factory with its JSON-quoted literal label or `...` for a dynamic label.
5047
5161
  */
5048
5162
  matched: string
5049
5163
  severity: PolicyViolationSeverity
@@ -5866,6 +5980,92 @@ introduced?: (AuditIntroduced | null)
5866
5980
  */
5867
5981
  effective_severity?: (EffectiveSeverity | null)
5868
5982
  }
5983
+ /**
5984
+ * Wire-shape envelope for an [`AbsentComponentProp`] finding. There is no safe
5985
+ * auto-fix: removing a declared prop is judgement-bearing (the prop may be part
5986
+ * of a deliberately-stable public component API). Actions are manual
5987
+ * remediation guidance plus a line-level suppress at the prop declaration.
5988
+ */
5989
+ export interface AbsentComponentPropFinding {
5990
+ /**
5991
+ * Source path of the input declaration.
5992
+ */
5993
+ path: string
5994
+ /**
5995
+ * Semantic declaration name, or SFC filename stem.
5996
+ */
5997
+ component_name: string
5998
+ /**
5999
+ * Public framework token.
6000
+ */
6001
+ framework: string
6002
+ /**
6003
+ * Public optional input name.
6004
+ */
6005
+ prop_name: string
6006
+ /**
6007
+ * 1-based declaration line.
6008
+ */
6009
+ line: number
6010
+ /**
6011
+ * 0-based declaration byte column.
6012
+ */
6013
+ col: number
6014
+ /**
6015
+ * Whether omission has a declared default.
6016
+ */
6017
+ has_default: boolean
6018
+ /**
6019
+ * Every inspected reachable caller, deterministically ordered.
6020
+ */
6021
+ inspected_call_sites: ComponentPropCallSite[]
6022
+ /**
6023
+ * Manual-review meaning and limits of static evidence.
6024
+ */
6025
+ explanation: string
6026
+ /**
6027
+ * Stable id of this finding: `dc1:<rule>:<16 hex digits>`, with a
6028
+ * `~<k>` suffix when several findings of one type share an identity.
6029
+ * Line and column are not inputs, so the id survives line shifts,
6030
+ * reformats and reorders. A rename of the file or the symbol gives a
6031
+ * new id. Absent in output from older versions.
6032
+ */
6033
+ finding_id?: (string | null)
6034
+ /**
6035
+ * Suggested next steps. Always emitted (possibly empty for
6036
+ * forward-compat).
6037
+ */
6038
+ actions: IssueAction[]
6039
+ /**
6040
+ * Set by the audit pass when this finding is introduced relative to
6041
+ * the merge-base.
6042
+ */
6043
+ introduced?: (AuditIntroduced | null)
6044
+ /**
6045
+ * Gate severity of this finding after `rules` and `overrides[].rules`
6046
+ * resolve for its path. CI formats read it for the annotation, SARIF
6047
+ * and CodeClimate level. Absent in output from older versions. Not
6048
+ * part of the finding identity, baseline keys or fingerprints.
6049
+ */
6050
+ effective_severity?: (EffectiveSeverity | null)
6051
+ }
6052
+ /**
6053
+ * One inspected reachable component invocation.
6054
+ */
6055
+ export interface ComponentPropCallSite {
6056
+ /**
6057
+ * Caller source path.
6058
+ */
6059
+ path: string
6060
+ /**
6061
+ * 1-based opening-tag line.
6062
+ */
6063
+ line: number
6064
+ /**
6065
+ * 0-based original-source byte column.
6066
+ */
6067
+ col: number
6068
+ }
5869
6069
  /**
5870
6070
  * Wire-shape envelope for an [`UnusedComponentEmit`] finding. There is no safe
5871
6071
  * auto-fix: removing a declared emit is judgement-bearing (the event may be
@@ -6486,6 +6686,18 @@ stale_entries: number
6486
6686
  * when every entry went unmatched.
6487
6687
  */
6488
6688
  current_findings: number
6689
+ /**
6690
+ * Health only: the number of functions above a complexity threshold that
6691
+ * the baseline does not accept. This is a count of functions, like
6692
+ * `summary.functions_above_threshold`, not a count of baseline entries,
6693
+ * and it is the value before `--top`. A run that does not list the
6694
+ * complexity findings (for example `--score`) still reports it, so a
6695
+ * reader can tell the new functions from the accepted ones.
6696
+ *
6697
+ * `dead-code` and `dupes` do not emit it. An envelope from a fallow
6698
+ * version before this member does not carry it either.
6699
+ */
6700
+ remaining_findings?: (number | null)
6489
6701
  /**
6490
6702
  * True when this run analyzed only part of the project, so a whole-project
6491
6703
  * baseline matches less of it for reasons that are not rot. The channels
@@ -6558,11 +6770,12 @@ unrecognised_format?: boolean
6558
6770
  */
6559
6771
  saved_by?: string
6560
6772
  /**
6561
- * `legacy` when the loaded dead-code baseline has no `identity`, so its
6562
- * entries use the old key forms and some of them hold a line. The run
6563
- * still applies the file. `--save-baseline` rewrites it with line-free
6564
- * keys. Absent for a current baseline and on `dupes` and `health`. The
6565
- * value set is OPEN.
6773
+ * `legacy` when the loaded baseline uses an old key form. For dead-code,
6774
+ * the file has no `identity`, so some entries hold a line. For `dupes`,
6775
+ * some entries use the clone key that older versions shared between
6776
+ * unrelated groups whose code did not parse on its own. The run still
6777
+ * applies the file. `--save-baseline` rewrites it with current keys.
6778
+ * Absent for a current baseline and on `health`. The value set is OPEN.
6566
6779
  */
6567
6780
  format?: string
6568
6781
  /**
@@ -6701,7 +6914,7 @@ reason?: (string | null)
6701
6914
  * all of it applied, which is a different and false claim.
6702
6915
  *
6703
6916
  * The names this build can emit are `changed-since`, `diff-filter`,
6704
- * `package-baselines` and `sarif-file`. The reasons are `git-missing`,
6917
+ * `package-baselines`, `sarif-file` and `group-filter`. The reasons are `git-missing`,
6705
6918
  * `not-a-repository`, `git-failed` and `invalid-ref` for `changed-since`,
6706
6919
  * `unknown-workspace`, `git-missing`, `not-a-repository` and `git-failed`
6707
6920
  * for `package-baselines`, `oversize`,
@@ -6719,8 +6932,9 @@ reason?: (string | null)
6719
6932
  * whole object narrows the report tells its reader an unwritten SARIF file
6720
6933
  * widened the analysis, which is what `affects` exists to prevent.
6721
6934
  *
6722
- * `scope_size` is emitted for `diff-filter`, in added lines, and for
6723
- * `changed-since`, in changed files that the run analyzed. `package-baselines`
6935
+ * `scope_size` is emitted for `diff-filter`, in added lines, for
6936
+ * `changed-since`, in changed files that the run analyzed, and for
6937
+ * `group-filter`, in groups that the run kept. `package-baselines`
6724
6938
  * and `sarif-file` measure no scope; the applied package refs travel in
6725
6939
  * `package_baselines`. A consumer reads the unit off the name, so a name that
6726
6940
  * starts to measure its own scope in a later release needs no change here.
@@ -6749,7 +6963,8 @@ affects: RequestEffect
6749
6963
  * `--diff-stdin`, `$FALLOW_DIFF_FILE build/pr.diff`, or
6750
6964
  * `diffFile pr.diff` for the programmatic option) for `diff-filter`,
6751
6965
  * `workspaces.changedSince` for `package-baselines`, the target path for
6752
- * `sarif-file`. Echoed rather than normalised, so a
6966
+ * `sarif-file`, the comma-joined selector patterns for `group-filter`.
6967
+ * Echoed rather than normalised, so a
6753
6968
  * consumer must not join it to the project root the way it joins every
6754
6969
  * other path-shaped field.
6755
6970
  */
@@ -6766,7 +6981,7 @@ requested: string
6766
6981
  * rule dropped does not count, so a change to a README only gives `0`. A
6767
6982
  * combined run counts a file that any of its analyses kept, because a
6768
6983
  * per-analysis `production` setting can give its analyses different
6769
- * files.
6984
+ * files. `group-filter` counts the groups that the run kept.
6770
6985
  * Read the unit off the name the entry is keyed under, never across names,
6771
6986
  * and read an absent member as "not measured" rather than as zero.
6772
6987
  *
@@ -6983,6 +7198,15 @@ end_col: number
6983
7198
  * wants the source reads it from the file.
6984
7199
  */
6985
7200
  fragment?: string
7201
+ /**
7202
+ * Whether the file path is a symlink, or lies under a symlinked
7203
+ * directory, inside the project root. Omitted when `false`.
7204
+ *
7205
+ * A clone with a symlinked instance can be the same file under two
7206
+ * paths, not copied code. `duplicates.ignoreSymlinks` (or
7207
+ * `fallow dupes --ignore-symlinks`) removes these instances.
7208
+ */
7209
+ is_symlink?: boolean
6986
7210
  }
6987
7211
  /**
6988
7212
  * Per-action wire shape attached to each `CloneGroupFinding` and
@@ -7197,6 +7421,15 @@ export interface HealthReport {
7197
7421
  */
7198
7422
  findings: HealthFinding[]
7199
7423
  summary: HealthSummary
7424
+ /**
7425
+ * The sections that this run produced, in a fixed order. A renderer
7426
+ * reads it to tell an empty section from a section that the run did not
7427
+ * produce: `findings` is the complexity list only when `complexity` is
7428
+ * in this array. The value set is OPEN (see [`HealthSection`]). Absent
7429
+ * in an envelope from a fallow version before this member, and on a
7430
+ * report that no health run built.
7431
+ */
7432
+ sections?: (HealthSection[] | null)
7200
7433
  /**
7201
7434
  * Configured threshold override states. Entries are emitted for active
7202
7435
  * exceptions, stale exceptions, and full-run no-match cleanup hints.
@@ -7436,7 +7669,9 @@ threshold_source?: (ThresholdSource | null)
7436
7669
  actions: HealthFindingAction[]
7437
7670
  /**
7438
7671
  * Audit-mode flag indicating whether the finding is new versus the base
7439
- * snapshot.
7672
+ * snapshot. A complexity finding is new when no base finding has the same
7673
+ * path and function name, or when a metric that it exceeds has a higher
7674
+ * value than in that base finding.
7440
7675
  */
7441
7676
  introduced?: (boolean | null)
7442
7677
  }
@@ -9633,6 +9868,11 @@ score?: (number | null)
9633
9868
  * Letter grade from the snapshot.
9634
9869
  */
9635
9870
  grade?: (string | null)
9871
+ /**
9872
+ * Formula used for the stored score; absent on legacy snapshots.
9873
+ * A score delta is emitted only when this matches the current score formula.
9874
+ */
9875
+ score_formula_version?: (number | null)
9636
9876
  /**
9637
9877
  * Coverage model used for CRAP computation in this snapshot.
9638
9878
  */
@@ -11452,25 +11692,35 @@ export interface DependencyTrace {
11452
11692
  */
11453
11693
  package_name: string
11454
11694
  /**
11455
- * Files that import this dependency.
11695
+ * Files that import this dependency, each listed once.
11456
11696
  */
11457
11697
  imported_by: string[]
11458
11698
  /**
11459
- * Files that import this dependency with type-only imports.
11699
+ * Files whose every import of this dependency is type-only, each listed
11700
+ * once.
11460
11701
  */
11461
11702
  type_only_imported_by: string[]
11462
11703
  /**
11463
- * Whether the dependency is invoked from package.json scripts or CI configs.
11704
+ * Whether the dependency is invoked from package.json scripts, CI configs
11705
+ * or git hooks.
11464
11706
  */
11465
11707
  used_in_scripts: boolean
11466
11708
  /**
11467
- * Whether the dependency is used at all.
11709
+ * Whether the dependency is used at all: imported, invoked from scripts,
11710
+ * or listed as a peer by a used package (`peer_of`).
11468
11711
  */
11469
11712
  is_used: boolean
11470
11713
  /**
11471
- * Total import count.
11714
+ * Number of files that import this dependency.
11472
11715
  */
11473
11716
  import_count: number
11717
+ /**
11718
+ * Used packages that list this dependency in their installed
11719
+ * `peerDependencies`, required or optional, sorted by name. The
11720
+ * unused-dependency check credits such a peer, because the package that
11721
+ * lists it loads it at runtime. Absent when no used package lists it.
11722
+ */
11723
+ peer_of?: string[]
11474
11724
  /**
11475
11725
  * The configs that declare this name as a Module Federation remote alias
11476
11726
  * under `remotes`, one per config. A remote alias is provided by a
@@ -11478,211 +11728,518 @@ import_count: number
11478
11728
  * Federation config declares the name (issue #2796).
11479
11729
  */
11480
11730
  sources?: TraceSource[]
11731
+ /**
11732
+ * Why the unused devDependency check credits the dependency as tooling
11733
+ * when no file imports it and no script, CI workflow or git hook runs it.
11734
+ * When present, `is_used` is `true`. Absent otherwise.
11735
+ */
11736
+ tooling_credit?: (ToolingCredit | null)
11737
+ /**
11738
+ * The manifests that the unused-dependency check flags for this name,
11739
+ * relative to the project root and sorted. The check reads each
11740
+ * declaring manifest on its own. An import credits the nearest manifest
11741
+ * that installs the package, so a name that one workspace uses can still
11742
+ * be unused in the root manifest or in another workspace. Absent when no
11743
+ * manifest is flagged.
11744
+ */
11745
+ unused_in?: string[]
11746
+ /**
11747
+ * How the code uses each imported name of the dependency. Present on
11748
+ * `fallow trace --dependency`, and on the MCP `trace_dependency` tool
11749
+ * when a usage parameter is set. Absent on
11750
+ * `fallow dead-code --trace-dependency`. The object has its own
11751
+ * `schema_version`.
11752
+ */
11753
+ usage?: (DependencyUsage | null)
11481
11754
  }
11482
11755
  /**
11483
- * Result of tracing a clone: all groups containing the code at a source
11484
- * location or addressed by a stable clone fingerprint.
11756
+ * Why the unused devDependency check counts a dependency as used tooling
11757
+ * although no source file imports it.
11485
11758
  */
11486
- export interface CloneTrace {
11759
+ export interface ToolingCredit {
11487
11760
  /**
11488
- * File passed to the trace request, root-relative when a group matches.
11761
+ * The evidence: `plugin-config` when the plugin that declares the
11762
+ * dependency found its own config file, `plugin-reference` when a
11763
+ * package.json script, a CI workflow or a git hook runs one of that
11764
+ * plugin's packages, `ambient-types` for a type package that declares
11765
+ * globals, `types-target` when the project declares or imports the
11766
+ * package that a `@types/` package types, `types-config` when a config
11767
+ * file, such as a tsconfig `types` entry, names the type package,
11768
+ * `known-tooling` for a library from the tooling catalogue,
11769
+ * `known-tooling-config` when a command-line tool from the catalogue has
11770
+ * its own config file, and `own-peer` when the same manifest lists the
11771
+ * devDependency in `peerDependencies`. The set is open.
11489
11772
  */
11490
- file: string
11773
+ reason: string
11491
11774
  /**
11492
- * 1-based line passed to the trace request or representative group line.
11775
+ * The plugin that declares the dependency as tooling.
11493
11776
  */
11494
- line: number
11777
+ plugin?: (string | null)
11495
11778
  /**
11496
- * The matched clone instance, if one exists.
11779
+ * The config file found, relative to the project root, for
11780
+ * `plugin-config` and `known-tooling-config`. A `package.json` path when
11781
+ * the config is a package.json key. For `own-peer`, the manifest that
11782
+ * lists the dependency.
11497
11783
  */
11498
- matched_instance?: (CloneInstance | null)
11784
+ config?: (string | null)
11499
11785
  /**
11500
- * Clone groups matched by the trace request.
11786
+ * The package that a script, CI workflow or git hook runs, for
11787
+ * `plugin-reference`, or the package that a `@types/` package types,
11788
+ * for `types-target`.
11501
11789
  */
11502
- clone_groups: TracedCloneGroup[]
11790
+ reference?: (string | null)
11503
11791
  }
11504
11792
  /**
11505
- * One clone group returned from a clone trace request.
11793
+ * How the code uses each imported name of a dependency.
11506
11794
  */
11507
- export interface TracedCloneGroup {
11795
+ export interface DependencyUsage {
11796
+ schema_version: DependencyUsageSchemaVersion
11797
+ confidence: UsageConfidence
11508
11798
  /**
11509
- * Stable content fingerprint, usually `dup:<8hex>` and widened on rare
11510
- * report collisions.
11799
+ * One entry per imported name, sorted by `name` in byte order. With a
11800
+ * specifier filter, only the selected names, each present even when no
11801
+ * file imports it.
11511
11802
  */
11512
- fingerprint: string
11803
+ specifiers: SpecifierUsage[]
11804
+ unresolved: FileLevelUnresolved
11513
11805
  /**
11514
- * Number of tokens in the duplicated block.
11806
+ * One page of usage sites. Absent unless sites were requested.
11515
11807
  */
11516
- token_count: number
11808
+ sites?: (UsageSitePage | null)
11517
11809
  /**
11518
- * Number of lines in the duplicated block.
11810
+ * The files that import the users of the dependency. Absent unless a
11811
+ * closure depth was requested.
11519
11812
  */
11520
- line_count: number
11813
+ closure?: (ConsumerClosure | null)
11814
+ }
11521
11815
  /**
11522
- * Maximum directory-tree or same-file line distance between instances.
11816
+ * The usage of one imported name.
11523
11817
  */
11524
- spread: number
11818
+ export interface SpecifierUsage {
11525
11819
  /**
11526
- * Lowest all-pairs similarity for a near-miss clone group.
11820
+ * The imported name: `default` for a default import, the first member for
11821
+ * a namespace member, and `*` for a bare namespace use.
11527
11822
  */
11528
- similarity?: number
11823
+ name: string
11529
11824
  /**
11530
- * Root-relative clone instances in this group.
11825
+ * Files with a static import binding of the name, a namespace member use
11826
+ * of it, or a re-export of it from the package.
11531
11827
  */
11532
- instances: CloneInstance[]
11533
- suggestion: RefactoringSuggestion
11828
+ file_count: number
11534
11829
  /**
11535
- * Best-effort name for the extracted function. Advisory only.
11830
+ * The files in `file_count` where every binding of the name is type-only:
11831
+ * an `import type`, or a value import that the file reads only in type
11832
+ * positions.
11536
11833
  */
11537
- suggested_name?: (string | null)
11538
- }
11834
+ type_only_file_count: number
11539
11835
  /**
11540
- * Result of computing the impact closure for a single file as the seed.
11836
+ * Direct calls of the name, not through a project wrapper. The
11837
+ * initializer of a call wrapper (`useSelector.withTypes()`) is a direct
11838
+ * call and counts here.
11541
11839
  */
11542
- export interface ImpactClosureTrace {
11840
+ call_site_count: number
11841
+ unresolved: SpecifierUnresolved
11543
11842
  /**
11544
- * The seed file, root-relative.
11843
+ * Project wrappers of the name, sorted by `file`, then `export`.
11545
11844
  */
11546
- seed: string
11845
+ wrappers: UsageWrapper[]
11846
+ }
11547
11847
  /**
11548
- * Root-relative paths transitively affected by the seed.
11848
+ * Uses of one imported name that the trace cannot resolve to a call. The key
11849
+ * set is closed in schema version 1.
11549
11850
  */
11550
- affected_not_shown: string[]
11851
+ export interface SpecifierUnresolved {
11551
11852
  /**
11552
- * Coordination gaps between the seed and consumers.
11853
+ * The name is the whole initializer of a declarator that is not a
11854
+ * wrapper: `const s = useSelector`.
11553
11855
  */
11554
- coordination_gap: ImpactClosureGap[]
11555
- }
11856
+ value_alias: number
11556
11857
  /**
11557
- * One coordination-gap entry in an [`ImpactClosureTrace`].
11858
+ * Any other value use that is not a call: an argument, an array
11859
+ * element, a property value or an optional call.
11558
11860
  */
11559
- export interface ImpactClosureGap {
11861
+ non_call_reference: number
11560
11862
  /**
11561
- * Root-relative path of the consumer module.
11863
+ * The name is a JSX element: `<Provider>`.
11562
11864
  */
11563
- consumer_file: string
11865
+ jsx_element: number
11564
11866
  /**
11565
- * Exported symbol names the consumer references.
11867
+ * The file re-exports the name from the package, or re-exports a
11868
+ * project wrapper of the name. The trace does not follow the consumers
11869
+ * of the re-export.
11566
11870
  */
11567
- consumed_symbols: string[]
11871
+ re_export: number
11568
11872
  /**
11569
- * Scope note for the syntactic trace.
11873
+ * A wrapper consumer that exports the wrapper again. The trace does not
11874
+ * follow the second hop.
11570
11875
  */
11571
- note: string
11572
- }
11876
+ nested_wrapper: number
11573
11877
  /**
11574
- * Result of asking how one module reaches another: the shortest import path.
11575
- *
11576
- * `reachable` is the only field that separates "no route exists" from "the
11577
- * route is empty because both ends are the same module". Both report
11578
- * `hops: 0`, so a consumer must read `reachable`, never the hop count.
11878
+ * Files with a runtime binding of the name and no usage site, for
11879
+ * example a use in a Vue, Svelte or Astro template.
11579
11880
  */
11580
- export interface ImportPathTrace {
11581
- schema_version: ImportPathTraceSchemaVersion
11881
+ binding_without_site: number
11882
+ }
11582
11883
  /**
11583
- * The module the walk started from, root-relative.
11884
+ * A top-level exported declarator that wraps an imported name. The trace
11885
+ * follows one hop from the wrapper to its consumers.
11584
11886
  */
11585
- from: string
11887
+ export interface UsageWrapper {
11586
11888
  /**
11587
- * The module the walk was looking for, root-relative.
11889
+ * The file that declares the wrapper, root-relative.
11588
11890
  */
11589
- to: string
11891
+ file: string
11590
11892
  /**
11591
- * Whether `to` is reachable from `from` by following import edges.
11893
+ * The exported name of the wrapper.
11592
11894
  */
11593
- reachable: boolean
11895
+ export: string
11896
+ shape: WrapperShape
11594
11897
  /**
11595
- * Number of import edges on the reported route. `0` both when the two ends
11596
- * are the same module and when there is no route at all.
11898
+ * 1-based line of the wrapper initializer.
11597
11899
  */
11598
- hops: number
11900
+ line: number
11599
11901
  /**
11600
- * The route, in import order. Empty whenever `hops` is `0`.
11902
+ * Distinct files with a call of the wrapper, the file of the wrapper
11903
+ * included.
11601
11904
  */
11602
- path: ImportPathHop[]
11905
+ consumer_file_count: number
11603
11906
  /**
11604
- * Human-readable summary of the outcome.
11907
+ * Calls of the wrapper itself. A call of a member of the value that a
11908
+ * call wrapper returns (`store.dispatch()`) is a `non_call_reference`.
11605
11909
  */
11606
- reason: string
11910
+ call_site_count: number
11607
11911
  }
11608
11912
  /**
11609
- * One import edge on an [`ImportPathTrace`].
11913
+ * Uses that hide which names a file reads. The key set is closed in schema
11914
+ * version 1.
11610
11915
  */
11611
- export interface ImportPathHop {
11916
+ export interface FileLevelUnresolved {
11612
11917
  /**
11613
- * The importing module, root-relative.
11918
+ * `import("package")` expressions.
11614
11919
  */
11615
- from: string
11920
+ dynamic_import: number
11616
11921
  /**
11617
- * The imported module, root-relative.
11922
+ * `require("package")` calls.
11618
11923
  */
11619
- to: string
11924
+ require: number
11620
11925
  /**
11621
- * Whether every symbol on this edge is type-only, so the hop is erased at
11622
- * build time. Type-only hops are reported, never skipped: an `import type`
11623
- * chain is a real compile-time coupling.
11926
+ * `import "package"` statements.
11624
11927
  */
11625
- type_only: boolean
11928
+ side_effect_import: number
11626
11929
  /**
11627
- * Whether the edge carries a runtime value but no static one: the target
11628
- * loads only on demand (`import()`, a lazy glob or template pattern) or
11629
- * on another thread (a worker URL, a worker loader request,
11630
- * `child_process.fork`). False for a
11631
- * static hop and for a type-only hop.
11930
+ * `export * from "package"` statements.
11632
11931
  */
11633
- dynamic: boolean
11932
+ star_re_export: number
11634
11933
  /**
11635
- * 1-based line in `from` of the imported binding that creates this edge:
11636
- * the first value-carrying symbol on the import, or the first symbol when
11637
- * every symbol is type-only. On a multi-line import that is the binding's
11638
- * own line, not the `import` keyword's. Absent when the edge carries no
11639
- * span or the source could not be read.
11934
+ * Files that import the package through a specifier that does not name
11935
+ * the package, for example a path alias.
11640
11936
  */
11641
- import_line?: (number | null)
11937
+ unattributed_file: number
11642
11938
  }
11643
11939
  /**
11644
- * The result of a symbol-level call-chain trace. Its own surface (`kind:
11645
- * "trace"`), NOT folded into the ranked brief.
11940
+ * One page of usage sites.
11646
11941
  */
11647
- export interface SymbolChainTrace {
11942
+ export interface UsageSitePage {
11648
11943
  /**
11649
- * The file containing the traced symbol (project-root-relative).
11944
+ * The sites on this page, sorted by `file`, `line`, `col`, kind,
11945
+ * `specifier`, then `via`.
11650
11946
  */
11651
- file: string
11947
+ items: UsageSite[]
11652
11948
  /**
11653
- * The traced symbol name.
11949
+ * The number of sites on all pages.
11654
11950
  */
11655
- symbol: string
11951
+ total: number
11656
11952
  /**
11657
- * Whether the symbol's defining export was found in the graph. When
11658
- * `false`, the chains are empty and `reason` explains why.
11953
+ * The largest number of items on a page.
11659
11954
  */
11660
- symbol_found: boolean
11955
+ limit: number
11661
11956
  /**
11662
- * The chain depth applied to both directions.
11957
+ * An opaque token for the next page. Absent on the last page.
11663
11958
  */
11664
- depth: number
11959
+ next_cursor?: (string | null)
11960
+ }
11665
11961
  /**
11666
- * Whether this trace is best-effort (always `true`: symbol-level chains are
11667
- * labeled best-effort, syntactic per ADR-001).
11962
+ * One use of the dependency in the code.
11668
11963
  */
11669
- best_effort: boolean
11964
+ export interface UsageSite {
11670
11965
  /**
11671
- * Caller chain hops (UP). Present only when `--callers` was requested.
11966
+ * The file, root-relative.
11672
11967
  */
11673
- callers?: (ChainHop[] | null)
11968
+ file: string
11674
11969
  /**
11675
- * Callee chain hops (DOWN) resolved to an import-symbol edge. Present only
11676
- * when `--callees` was requested.
11970
+ * 1-based line.
11677
11971
  */
11678
- callees?: (ChainHop[] | null)
11972
+ line: number
11679
11973
  /**
11680
- * Callees referenced at a call site in the symbol's module that the
11681
- * syntactic walk could NOT resolve to an import-symbol edge (locals,
11682
- * globals, dynamic dispatch, re-bound callees). Reported, never dropped.
11683
- * Present only when `--callees` was requested.
11974
+ * 0-based byte column.
11684
11975
  */
11685
- unresolved_callees?: (UnresolvedCallee[] | null)
11976
+ col: number
11977
+ /**
11978
+ * The imported name. Absent on file-level kinds.
11979
+ */
11980
+ specifier?: (string | null)
11981
+ /**
11982
+ * The local binding that the code uses. Absent on file-level kinds.
11983
+ */
11984
+ local_name?: (string | null)
11985
+ /**
11986
+ * The static member after the imported name, for example `withTypes`.
11987
+ */
11988
+ member?: (string | null)
11989
+ /**
11990
+ * How the code uses the dependency at this site. The known values are
11991
+ * `call`, `wrapper_definition`, `value_alias`, `non_call_reference`,
11992
+ * `jsx_element`, `re_export`, `nested_wrapper`, `dynamic_import`,
11993
+ * `require`, `side_effect_import` and `star_re_export`. The set is open:
11994
+ * read an unknown kind as an unresolved site.
11995
+ */
11996
+ kind: string
11997
+ /**
11998
+ * The wrapper that the site goes through, as `FILE:EXPORT`.
11999
+ */
12000
+ via?: (string | null)
12001
+ }
12002
+ /**
12003
+ * The files that import the users of the dependency, found by a reverse walk
12004
+ * of the import graph.
12005
+ */
12006
+ export interface ConsumerClosure {
12007
+ /**
12008
+ * The largest depth of the walk.
12009
+ */
12010
+ depth: number
12011
+ /**
12012
+ * The number of files in `files`.
12013
+ */
12014
+ file_count: number
12015
+ /**
12016
+ * The files, sorted by `depth`, then `file`. The seed files are not
12017
+ * listed.
12018
+ */
12019
+ files: ClosureFile[]
12020
+ /**
12021
+ * Whether a file at the largest depth has an importer that the walk did
12022
+ * not visit.
12023
+ */
12024
+ truncated: boolean
12025
+ }
12026
+ /**
12027
+ * One file of a [`ConsumerClosure`].
12028
+ */
12029
+ export interface ClosureFile {
12030
+ /**
12031
+ * The file, root-relative.
12032
+ */
12033
+ file: string
12034
+ /**
12035
+ * The number of import edges from the nearest seed file.
12036
+ */
12037
+ depth: number
12038
+ }
12039
+ /**
12040
+ * Result of tracing a clone: all groups containing the code at a source
12041
+ * location or addressed by a stable clone fingerprint.
12042
+ */
12043
+ export interface CloneTrace {
12044
+ /**
12045
+ * File passed to the trace request, root-relative when a group matches.
12046
+ */
12047
+ file: string
12048
+ /**
12049
+ * 1-based line passed to the trace request or representative group line.
12050
+ */
12051
+ line: number
12052
+ /**
12053
+ * The matched clone instance, if one exists.
12054
+ */
12055
+ matched_instance?: (CloneInstance | null)
12056
+ /**
12057
+ * Clone groups matched by the trace request.
12058
+ */
12059
+ clone_groups: TracedCloneGroup[]
12060
+ }
12061
+ /**
12062
+ * One clone group returned from a clone trace request.
12063
+ */
12064
+ export interface TracedCloneGroup {
12065
+ /**
12066
+ * Stable content fingerprint, usually `dup:<8hex>` and widened on rare
12067
+ * report collisions.
12068
+ */
12069
+ fingerprint: string
12070
+ /**
12071
+ * Number of tokens in the duplicated block.
12072
+ */
12073
+ token_count: number
12074
+ /**
12075
+ * Number of lines in the duplicated block.
12076
+ */
12077
+ line_count: number
12078
+ /**
12079
+ * Maximum directory-tree or same-file line distance between instances.
12080
+ */
12081
+ spread: number
12082
+ /**
12083
+ * Lowest all-pairs similarity for a near-miss clone group.
12084
+ */
12085
+ similarity?: number
12086
+ /**
12087
+ * Root-relative clone instances in this group.
12088
+ */
12089
+ instances: CloneInstance[]
12090
+ suggestion: RefactoringSuggestion
12091
+ /**
12092
+ * Best-effort name for the extracted function. Advisory only.
12093
+ */
12094
+ suggested_name?: (string | null)
12095
+ }
12096
+ /**
12097
+ * Result of computing the impact closure for a single file as the seed.
12098
+ */
12099
+ export interface ImpactClosureTrace {
12100
+ /**
12101
+ * The seed file, root-relative.
12102
+ */
12103
+ seed: string
12104
+ /**
12105
+ * Root-relative paths transitively affected by the seed.
12106
+ */
12107
+ affected_not_shown: string[]
12108
+ /**
12109
+ * Coordination gaps between the seed and consumers.
12110
+ */
12111
+ coordination_gap: ImpactClosureGap[]
12112
+ }
12113
+ /**
12114
+ * One coordination-gap entry in an [`ImpactClosureTrace`].
12115
+ */
12116
+ export interface ImpactClosureGap {
12117
+ /**
12118
+ * Root-relative path of the consumer module.
12119
+ */
12120
+ consumer_file: string
12121
+ /**
12122
+ * Exported symbol names the consumer references.
12123
+ */
12124
+ consumed_symbols: string[]
12125
+ /**
12126
+ * Scope note for the syntactic trace.
12127
+ */
12128
+ note: string
12129
+ }
12130
+ /**
12131
+ * Result of asking how one module reaches another: the shortest import path.
12132
+ *
12133
+ * `reachable` is the only field that separates "no route exists" from "the
12134
+ * route is empty because both ends are the same module". Both report
12135
+ * `hops: 0`, so a consumer must read `reachable`, never the hop count.
12136
+ */
12137
+ export interface ImportPathTrace {
12138
+ schema_version: ImportPathTraceSchemaVersion
12139
+ /**
12140
+ * The module the walk started from, root-relative.
12141
+ */
12142
+ from: string
12143
+ /**
12144
+ * The module the walk was looking for, root-relative.
12145
+ */
12146
+ to: string
12147
+ /**
12148
+ * Whether `to` is reachable from `from` by following import edges.
12149
+ */
12150
+ reachable: boolean
12151
+ /**
12152
+ * Number of import edges on the reported route. `0` both when the two ends
12153
+ * are the same module and when there is no route at all.
12154
+ */
12155
+ hops: number
12156
+ /**
12157
+ * The route, in import order. Empty whenever `hops` is `0`.
12158
+ */
12159
+ path: ImportPathHop[]
12160
+ /**
12161
+ * Human-readable summary of the outcome.
12162
+ */
12163
+ reason: string
12164
+ }
12165
+ /**
12166
+ * One import edge on an [`ImportPathTrace`].
12167
+ */
12168
+ export interface ImportPathHop {
12169
+ /**
12170
+ * The importing module, root-relative.
12171
+ */
12172
+ from: string
12173
+ /**
12174
+ * The imported module, root-relative.
12175
+ */
12176
+ to: string
12177
+ /**
12178
+ * Whether every symbol on this edge is type-only, so the hop is erased at
12179
+ * build time. Type-only hops are reported, never skipped: an `import type`
12180
+ * chain is a real compile-time coupling.
12181
+ */
12182
+ type_only: boolean
12183
+ /**
12184
+ * Whether the edge carries a runtime value but no static one: the target
12185
+ * loads only on demand (`import()`, a lazy glob or template pattern) or
12186
+ * on another thread (a worker URL, a worker loader request,
12187
+ * `child_process.fork`). False for a
12188
+ * static hop and for a type-only hop.
12189
+ */
12190
+ dynamic: boolean
12191
+ /**
12192
+ * 1-based line in `from` of the imported binding that creates this edge:
12193
+ * the first value-carrying symbol on the import, or the first symbol when
12194
+ * every symbol is type-only. On a multi-line import that is the binding's
12195
+ * own line, not the `import` keyword's. Absent when the edge carries no
12196
+ * span or the source could not be read.
12197
+ */
12198
+ import_line?: (number | null)
12199
+ }
12200
+ /**
12201
+ * The result of a symbol-level call-chain trace. Its own surface (`kind:
12202
+ * "trace"`), NOT folded into the ranked brief.
12203
+ */
12204
+ export interface SymbolChainTrace {
12205
+ /**
12206
+ * The file containing the traced symbol (project-root-relative).
12207
+ */
12208
+ file: string
12209
+ /**
12210
+ * The traced symbol name.
12211
+ */
12212
+ symbol: string
12213
+ /**
12214
+ * Whether the symbol's defining export was found in the graph. When
12215
+ * `false`, the chains are empty and `reason` explains why.
12216
+ */
12217
+ symbol_found: boolean
12218
+ /**
12219
+ * The chain depth applied to both directions.
12220
+ */
12221
+ depth: number
12222
+ /**
12223
+ * Whether this trace is best-effort (always `true`: symbol-level chains are
12224
+ * labeled best-effort, syntactic per ADR-001).
12225
+ */
12226
+ best_effort: boolean
12227
+ /**
12228
+ * Caller chain hops (UP). Present only when `--callers` was requested.
12229
+ */
12230
+ callers?: (ChainHop[] | null)
12231
+ /**
12232
+ * Callee chain hops (DOWN) resolved to an import-symbol edge. Present only
12233
+ * when `--callees` was requested.
12234
+ */
12235
+ callees?: (ChainHop[] | null)
12236
+ /**
12237
+ * Callees referenced at a call site in the symbol's module that the
12238
+ * syntactic walk could NOT resolve to an import-symbol edge (locals,
12239
+ * globals, dynamic dispatch, re-bound callees). Reported, never dropped.
12240
+ * Present only when `--callees` was requested.
12241
+ */
12242
+ unresolved_callees?: (UnresolvedCallee[] | null)
11686
12243
  /**
11687
12244
  * Set when the name is unresolvable because two different `export *`
11688
12245
  * sources of this file supply it. `symbol_found` is `false` in that case
@@ -12467,6 +13024,15 @@ elapsed_ms: ElapsedMs
12467
13024
  */
12468
13025
  findings: HealthFinding[]
12469
13026
  summary: HealthSummary
13027
+ /**
13028
+ * The sections that this run produced, in a fixed order. A renderer
13029
+ * reads it to tell an empty section from a section that the run did not
13030
+ * produce: `findings` is the complexity list only when `complexity` is
13031
+ * in this array. The value set is OPEN (see [`HealthSection`]). Absent
13032
+ * in an envelope from a fallow version before this member, and on a
13033
+ * report that no health run built.
13034
+ */
13035
+ sections?: (HealthSection[] | null)
12470
13036
  /**
12471
13037
  * Configured threshold override states. Entries are emitted for active
12472
13038
  * exceptions, stale exceptions, and full-run no-match cleanup hints.
@@ -12591,6 +13157,12 @@ grouped_by?: (GroupByMode | null)
12591
13157
  * Per-bucket recomputed metrics; present only in grouped output.
12592
13158
  */
12593
13159
  groups?: (HealthGroup[] | null)
13160
+ /**
13161
+ * The `--group` selector patterns, as given, when the run kept only some
13162
+ * groups. A group that is not in `groups` was filtered out by this
13163
+ * selector. The project-level sections are not filtered.
13164
+ */
13165
+ group_filter?: (string[] | null)
12594
13166
  /**
12595
13167
  * The verdict of every gate this run evaluated, keyed by name. The CLI
12596
13168
  * always emits it, with the command's default exit rule in it also when
@@ -12640,6 +13212,11 @@ next_steps?: NextStep[]
12640
13212
  * a single invocation. `files_analyzed` and `functions_above_threshold`
12641
13213
  * summarise the subset for parity with the project-level
12642
13214
  * project-level health summary.
13215
+ *
13216
+ * A group carries a per-file list (`findings`, `file_scores`, `hotspots`,
13217
+ * `large_functions`, `targets`) only when the project report shows the same
13218
+ * list. A `--score` run keeps the score and the counts of each group and
13219
+ * omits the lists.
12643
13220
  */
12644
13221
  export interface HealthGroup {
12645
13222
  /**
@@ -12664,25 +13241,68 @@ files_analyzed: number
12664
13241
  * Number of findings in this group, mirroring the project-level
12665
13242
  * `summary.functions_above_threshold` semantics post-baseline /
12666
13243
  * post-`--top` truncation. When `--top` was supplied this reflects the
12667
- * rendered finding count, not the un-truncated total.
13244
+ * rendered finding count of the group, not the un-truncated total.
12668
13245
  */
12669
13246
  functions_above_threshold: number
12670
13247
  /**
12671
- * Whether CRAP findings in this group share a single coverage-source kind
12672
- * (`uniform`) or combine Istanbul / estimated / inherited sources
12673
- * (`mixed`). Absent when no grouped finding carries CRAP source data.
13248
+ * Number of critical-severity findings in this group, after the baseline
13249
+ * filter and before `--top`. The project `summary.severity_critical_count`
13250
+ * counts before the baseline filter, so with `--baseline` the group
13251
+ * counts can add up to less.
12674
13252
  */
12675
- coverage_source_consistency?: (CoverageSourceConsistency | null)
13253
+ severity_critical_count: number
12676
13254
  /**
12677
- * Per-group vital signs recomputed from the files in this group. Absent
12678
- * when --score-only suppressed top-level vital signs.
13255
+ * Number of high-severity findings in this group, after the baseline
13256
+ * filter and before `--top`. The project `summary.severity_high_count`
13257
+ * counts before the baseline filter, so with `--baseline` the group
13258
+ * counts can add up to less.
12679
13259
  */
12680
- vital_signs?: (VitalSigns | null)
13260
+ severity_high_count: number
12681
13261
  /**
12682
- * Per-group health score recomputed from the per-group vital signs. Absent
12683
- * when --score was not requested.
13262
+ * Number of moderate-severity findings in this group, after the baseline
13263
+ * filter and before `--top`. The project `summary.severity_moderate_count`
13264
+ * counts before the baseline filter, so with `--baseline` the group
13265
+ * counts can add up to less.
13266
+ */
13267
+ severity_moderate_count: number
13268
+ /**
13269
+ * Number of ranked hotspot entries in this group, before `--top`. This
13270
+ * is the length of the group's ranked hotspot list. It is not
13271
+ * `vital_signs.hotspot_count`, which counts only the files with a
13272
+ * hotspot score of 50 or more and feeds the health score.
13273
+ */
13274
+ hotspot_count: number
13275
+ /**
13276
+ * Whether CRAP findings in this group share a single coverage-source kind
13277
+ * (`uniform`) or combine Istanbul / estimated / inherited sources
13278
+ * (`mixed`). Absent when no grouped finding carries CRAP source data.
13279
+ */
13280
+ coverage_source_consistency?: (CoverageSourceConsistency | null)
13281
+ /**
13282
+ * Per-group vital signs recomputed from the files in this group. Absent
13283
+ * when --score-only suppressed top-level vital signs.
13284
+ */
13285
+ vital_signs?: (VitalSigns | null)
13286
+ /**
13287
+ * Per-group health score recomputed from the per-group vital signs. Absent
13288
+ * when --score was not requested. The duplication penalty counts each
13289
+ * clone group with two or more instances in total and one or more in
13290
+ * this group, and counts only the lines of the instances in this group.
13291
+ * A clone that spans two groups thus lowers the score of each group.
13292
+ * `dupes --group-by` assigns each clone group to one owner instead.
12684
13293
  */
12685
13294
  health_score?: (HealthScore | null)
13295
+ /**
13296
+ * Trend of this group against the same group in the baseline snapshot.
13297
+ * Present only when `--trend` or `--trend-from` was requested and the
13298
+ * baseline holds this group with the same `grouped_by` mode.
13299
+ */
13300
+ trend?: (HealthTrend | null)
13301
+ /**
13302
+ * Why `trend` is present or absent. Present only when a trend was
13303
+ * requested and a baseline snapshot was loaded.
13304
+ */
13305
+ trend_status?: (GroupTrendStatus | null)
12686
13306
  /**
12687
13307
  * Findings restricted to files in this group. Each entry is the typed
12688
13308
  * [`HealthFinding`] wrapper around a
@@ -12797,9 +13417,10 @@ baseline_staleness?: (BaselineStaleness | null)
12797
13417
  /**
12798
13418
  * The verdict of every gate this run armed, keyed by name, absent when
12799
13419
  * it armed none. `dupes` has no default exit rule: a run with no armed
12800
- * gate always exits 0, so an absent object means that the run passed. A
12801
- * gate fails the build when `status` is `fail` AND `enforced` is true.
12802
- * See [`crate::GateOutcomes`].
13420
+ * gate always exits 0, so an absent object means that the run passed.
13421
+ * `--fail-on-issues` and `--ci` arm `duplication-findings`, which fails
13422
+ * on any clone group. A gate fails the build when `status` is `fail` AND
13423
+ * `enforced` is true. See [`crate::GateOutcomes`].
12803
13424
  */
12804
13425
  gate_outcomes?: (GateOutcomes | null)
12805
13426
  /**
@@ -12947,6 +13568,15 @@ end_col: number
12947
13568
  * wants the source reads it from the file.
12948
13569
  */
12949
13570
  fragment?: string
13571
+ /**
13572
+ * Whether the file path is a symlink, or lies under a symlinked
13573
+ * directory, inside the project root. Omitted when `false`.
13574
+ *
13575
+ * A clone with a symlinked instance can be the same file under two
13576
+ * paths, not copied code. `duplicates.ignoreSymlinks` (or
13577
+ * `fallow dupes --ignore-symlinks`) removes these instances.
13578
+ */
13579
+ is_symlink?: boolean
12950
13580
  /**
12951
13581
  * Resolver key for this specific instance (per-instance, not the
12952
13582
  * group-level largest-owner).
@@ -12982,6 +13612,13 @@ groups: CheckGroupedEntry[]
12982
13612
  * only when `true`, like the flat `CheckOutput` field.
12983
13613
  */
12984
13614
  unused_load_data_keys_global_abstain?: boolean
13615
+ /**
13616
+ * Number of export and member findings that the run hid because their
13617
+ * file is an unused file. The count covers the whole run, so it is on
13618
+ * the root and not in a group. Serialized only when not zero, like the
13619
+ * flat `CheckOutput` field.
13620
+ */
13621
+ cascade_hidden?: number
12985
13622
  /**
12986
13623
  * This run's view of the loaded baseline, present only in baseline runs.
12987
13624
  * Carries the staleness counts, the advisory verdict and `gate_trips`, the
@@ -13320,6 +13957,10 @@ dynamic_segment_name_conflicts?: DynamicSegmentNameConflictFinding[]
13320
13957
  * array natively. Default severity is `warn`.
13321
13958
  */
13322
13959
  unused_component_props?: UnusedComponentPropFinding[]
13960
+ /**
13961
+ * Used optional component inputs absent from inspected reachable callers. Off by default.
13962
+ */
13963
+ absent_component_props?: AbsentComponentPropFinding[]
13323
13964
  /**
13324
13965
  * Vue `<script setup>` `defineEmits` events emitted nowhere in their own SFC
13325
13966
  * (no `emit('<name>')` call). Wrapped in [`UnusedComponentEmitFinding`] so
@@ -13399,6 +14040,106 @@ thin_wrappers?: ThinWrapperFinding[]
13399
14040
  * enables it.
13400
14041
  */
13401
14042
  duplicate_prop_shapes?: DuplicatePropShapeFinding[]
14043
+ /**
14044
+ * Number of `unused_exports`, `unused_types`, `unused_class_members` and
14045
+ * `unused_enum_members` findings that this run did not report because
14046
+ * their file is an unused file. Deleting the file removes them, so they
14047
+ * add no information. `--show-cascade` or the `showCascade` config key
14048
+ * keeps them in the report, and then this count is zero. The count is
14049
+ * taken after the scope and the rules and before a baseline. Serialized
14050
+ * only when not zero, so a run without such findings keeps its JSON.
14051
+ */
14052
+ cascade_hidden?: number
14053
+ }
14054
+ /**
14055
+ * Envelope emitted by `fallow architecture --group-by ... --format json`.
14056
+ *
14057
+ * The body is the `CheckGroupedOutput` body of `fallow dead-code`: issues are partitioned into resolver buckets (CODEOWNERS team, directory prefix, workspace package, or GitLab CODEOWNERS section), and each bucket carries the same issue-array shape as `ArchitectureOutput`, plus per-group `key` / `owners` / `total_issues`.
14058
+ */
14059
+ export interface ArchitectureGroupedOutput {
14060
+ schema_version: ArchitectureSchemaVersion
14061
+ version: ToolVersion
14062
+ elapsed_ms: ElapsedMs
14063
+ grouped_by: GroupByMode
14064
+ /**
14065
+ * Total findings across all groups.
14066
+ */
14067
+ total_issues: number
14068
+ /**
14069
+ * One bucket per resolver key.
14070
+ */
14071
+ groups: CheckGroupedEntry[]
14072
+ /**
14073
+ * `true` when the `unused-load-data-key` detector abstained for the whole
14074
+ * project. The abstain has no file, so it is on the root and not in a
14075
+ * group. An empty `unused_load_data_keys` with this flag set does not
14076
+ * mean the project is clean: the rule could not run safely. Serialized
14077
+ * only when `true`, like the flat `CheckOutput` field.
14078
+ */
14079
+ unused_load_data_keys_global_abstain?: boolean
14080
+ /**
14081
+ * Number of export and member findings that the run hid because their
14082
+ * file is an unused file. The count covers the whole run, so it is on
14083
+ * the root and not in a group. Serialized only when not zero, like the
14084
+ * flat `CheckOutput` field.
14085
+ */
14086
+ cascade_hidden?: number
14087
+ /**
14088
+ * This run's view of the loaded baseline, present only in baseline runs.
14089
+ * Carries the staleness counts, the advisory verdict and `gate_trips`, the
14090
+ * same boolean `--fail-on-stale-baseline` exits on, so a CI integration
14091
+ * reads one field instead of restating the rule. Read `change_scoped`
14092
+ * before dividing `matched_entries` by `baseline_entries`: a narrowed run
14093
+ * can report `matched_entries: 0` on a healthy baseline.
14094
+ */
14095
+ baseline_staleness?: (BaselineStaleness | null)
14096
+ /**
14097
+ * The answer to `--finding-id`, present only when the run received one
14098
+ * or more `--finding-id` values. The report then holds only the
14099
+ * requested findings. Read `missing` as resolved only when `conclusive`
14100
+ * is true; a scope, a baseline or a filter can hide a finding that still
14101
+ * exists. See [`crate::FindingIdQuery`].
14102
+ */
14103
+ finding_id_query?: (FindingIdQuery | null)
14104
+ /**
14105
+ * The verdict of every gate this run evaluated, keyed by name. The CLI
14106
+ * always emits it, with the command's default exit rule in it also when
14107
+ * no flag armed a gate, so a CI integration reads the verdict instead of
14108
+ * guessing from a process status it usually cannot see. A gate fails the
14109
+ * build when `status` is `fail` AND `enforced` is true. The typed
14110
+ * programmatic API runs no CLI gate and leaves it absent. See
14111
+ * [`crate::GateOutcomes`].
14112
+ */
14113
+ gate_outcomes?: (GateOutcomes | null)
14114
+ /**
14115
+ * Every narrowing or shaping request this run RECEIVED, keyed by name,
14116
+ * absent when it was asked for nothing. An entry whose `status` is not
14117
+ * `applied` means the run could not do what it was asked and reported
14118
+ * something WIDER instead, so what follows is a valid report of a scope
14119
+ * nobody requested. Honoured requests are published too, with
14120
+ * `status: "applied"`, so an absent object means "nothing was asked for",
14121
+ * never "nothing failed". See [`crate::RequestOutcomes`].
14122
+ */
14123
+ request_outcomes?: (RequestOutcomes | null)
14124
+ /**
14125
+ * Applied package Git refs, omitted outside package-baseline runs.
14126
+ */
14127
+ package_baselines?: PackageBaselineStatus[]
14128
+ /**
14129
+ * `_meta` block with docs and rule definitions, when `--explain` was
14130
+ * passed.
14131
+ */
14132
+ _meta?: (Meta | null)
14133
+ /**
14134
+ * Diagnostics collected for the full analysis before issue grouping.
14135
+ * See [`CheckOutput::workspace_diagnostics`] for the contract.
14136
+ */
14137
+ workspace_diagnostics?: WorkspaceDiagnostic[]
14138
+ /**
14139
+ * Read-only follow-up commands computed from the full (ungrouped) findings.
14140
+ * See [`CheckOutput::next_steps`] for the contract.
14141
+ */
14142
+ next_steps?: NextStep[]
13402
14143
  }
13403
14144
  /**
13404
14145
  * The rendered impact report, derived purely from the store.
@@ -14550,101 +15291,594 @@ needs_human_review: number
14550
15291
  unverdicted: number
14551
15292
  }
14552
15293
  /**
14553
- * One verifier-retained candidate row.
15294
+ * One verifier-retained candidate row.
15295
+ */
15296
+ export interface SecuritySurvivor {
15297
+ /**
15298
+ * Stable candidate id from `security_findings[].finding_id`.
15299
+ */
15300
+ finding_id: string
15301
+ verdict: SecurityVerifierVerdictStatus
15302
+ /**
15303
+ * Short machine-oriented verdict reason.
15304
+ */
15305
+ reason?: (string | null)
15306
+ /**
15307
+ * Longer free-form verdict explanation.
15308
+ */
15309
+ rationale?: (string | null)
15310
+ /**
15311
+ * Optional verifier-provided confidence or review priority.
15312
+ */
15313
+ confidence?: (string | null)
15314
+ /**
15315
+ * Optional verifier-provided impact statement.
15316
+ */
15317
+ impact?: (string | null)
15318
+ /**
15319
+ * Optional verifier-owned remediation direction.
15320
+ */
15321
+ fix_direction?: (string | null)
15322
+ candidate: SecurityFinding
15323
+ }
15324
+ /**
15325
+ * The `fallow security blind-spots --format json` envelope.
15326
+ */
15327
+ export interface SecurityBlindSpotsOutput {
15328
+ schema_version: SecurityBlindSpotsSchemaVersion
15329
+ version: ToolVersion
15330
+ elapsed_ms: ElapsedMs
15331
+ /**
15332
+ * Diagnostics owned by the security analysis used for this view.
15333
+ */
15334
+ workspace_diagnostics?: WorkspaceDiagnostic[]
15335
+ summary: SecurityBlindSpotsSummary
15336
+ /**
15337
+ * Grouped unresolved callee diagnostics, derived from existing samples.
15338
+ */
15339
+ groups: SecurityBlindSpotGroup[]
15340
+ }
15341
+ /**
15342
+ * Aggregate counts for blind-spot output.
15343
+ */
15344
+ export interface SecurityBlindSpotsSummary {
15345
+ /**
15346
+ * Files containing at least one unresolved callee.
15347
+ */
15348
+ unresolved_edge_files: number
15349
+ /**
15350
+ * Total unresolved callee sites in the analysis.
15351
+ */
15352
+ unresolved_callee_sites: number
15353
+ /**
15354
+ * Callee sites captured in the bounded diagnostic sample.
15355
+ */
15356
+ sampled_callee_sites: number
15357
+ }
15358
+ /**
15359
+ * One actionable blind-spot group.
15360
+ */
15361
+ export interface SecurityBlindSpotGroup {
15362
+ reason: SkippedSecurityCalleeReason
15363
+ expression_kind: SkippedSecurityCalleeExpressionKind
15364
+ /**
15365
+ * Count in the bounded diagnostic sample.
15366
+ */
15367
+ sampled_count: number
15368
+ /**
15369
+ * Top files in this bounded diagnostic sample.
15370
+ */
15371
+ files: SecurityBlindSpotFile[]
15372
+ /**
15373
+ * Suggested next action for this group.
15374
+ */
15375
+ suggestion: string
15376
+ }
15377
+ /**
15378
+ * One file inside a blind-spot group.
15379
+ */
15380
+ export interface SecurityBlindSpotFile {
15381
+ /**
15382
+ * File path relative to the analysed root.
15383
+ */
15384
+ path: string
15385
+ /**
15386
+ * Count in the bounded diagnostic sample.
15387
+ */
15388
+ sampled_count: number
15389
+ }
15390
+ /**
15391
+ * Envelope emitted by `fallow architecture --format json`.
15392
+ *
15393
+ * The body is the `CheckOutput` body of `fallow dead-code`: the same issue arrays, `summary`, `entry_points`, actions and `gate_outcomes`. The architecture arrays (`circular_dependencies`, `re_export_cycles`, `package_cycles`, `boundary_violations`, `boundary_coverage_violations`, `boundary_call_violations`, `policy_violations`) carry the findings. The combined and audit envelopes do not use this envelope; their `check` block stays `CheckOutput`.
15394
+ */
15395
+ export interface ArchitectureOutput {
15396
+ schema_version: ArchitectureSchemaVersion
15397
+ version: ToolVersion
15398
+ elapsed_ms: ElapsedMs
15399
+ /**
15400
+ * Total findings across all issue arrays; excludes `next_steps`.
15401
+ */
15402
+ total_issues: number
15403
+ /**
15404
+ * Entry-point totals per source, when the analysis recorded them.
15405
+ */
15406
+ entry_points?: (EntryPoints | null)
15407
+ summary: CheckSummary
15408
+ /**
15409
+ * Files not reachable from any entry point. Wrapped in
15410
+ * [`UnusedFileFinding`] so each entry carries a typed `actions` array
15411
+ * natively, replacing the pre-2.76 post-pass injection.
15412
+ */
15413
+ unused_files: UnusedFileFinding[]
15414
+ /**
15415
+ * Exports never imported by other modules. Wrapped in
15416
+ * [`UnusedExportFinding`] so each entry carries a typed `actions`
15417
+ * array natively.
15418
+ */
15419
+ unused_exports: UnusedExportFinding[]
15420
+ /**
15421
+ * Type exports never imported by other modules. Wrapped in
15422
+ * [`UnusedTypeFinding`]: the inner [`UnusedExport`] struct is shared
15423
+ * with `unused_exports` but the wrapper emits a type-targeted fix
15424
+ * description.
15425
+ */
15426
+ unused_types: UnusedTypeFinding[]
15427
+ /**
15428
+ * Exported symbols whose public signature references same-file private
15429
+ * types. Wrapped in [`PrivateTypeLeakFinding`] so each entry carries a
15430
+ * typed `actions` array natively.
15431
+ */
15432
+ private_type_leaks: PrivateTypeLeakFinding[]
15433
+ /**
15434
+ * Exports marked `@deprecated` that still have at least one consumer in
15435
+ * a reachable file. Wrapped in [`DeprecatedExportInUseFinding`]. Opt-in: the
15436
+ * `deprecated-exports-in-use` rule defaults to `off`.
15437
+ */
15438
+ deprecated_exports_in_use?: DeprecatedExportInUseFinding[]
15439
+ /**
15440
+ * Dependencies listed in package.json but never imported. Wrapped in
15441
+ * [`UnusedDependencyFinding`] so each entry carries a typed `actions`
15442
+ * array natively. The fix action swaps from `remove-dependency` to
15443
+ * `move-dependency` when `used_in_workspaces` is non-empty.
15444
+ */
15445
+ unused_dependencies: UnusedDependencyFinding[]
15446
+ /**
15447
+ * Dev dependencies listed in package.json but never imported. Wrapped
15448
+ * in [`UnusedDevDependencyFinding`]: same bare struct as
15449
+ * `unused_dependencies` with a `devDependencies`-targeted fix
15450
+ * description.
15451
+ */
15452
+ unused_dev_dependencies: UnusedDevDependencyFinding[]
15453
+ /**
15454
+ * Optional dependencies listed in package.json but never imported.
15455
+ * Wrapped in [`UnusedOptionalDependencyFinding`] with an
15456
+ * `optionalDependencies`-targeted fix description.
15457
+ */
15458
+ unused_optional_dependencies: UnusedOptionalDependencyFinding[]
15459
+ /**
15460
+ * Enum members never accessed. Wrapped in
15461
+ * [`UnusedEnumMemberFinding`] so each entry carries a typed `actions`
15462
+ * array natively.
15463
+ */
15464
+ unused_enum_members: UnusedEnumMemberFinding[]
15465
+ /**
15466
+ * Class members never accessed. Wrapped in
15467
+ * [`UnusedClassMemberFinding`]: same inner [`UnusedMember`] struct as
15468
+ * `unused_enum_members`, with a class-targeted fix description and the
15469
+ * `auto_fixable: false` default to reflect dependency-injection
15470
+ * patterns.
15471
+ */
15472
+ unused_class_members: UnusedClassMemberFinding[]
15473
+ /**
15474
+ * Store members (Pinia `state` / `getters` / `actions` key, or a
15475
+ * setup-store returned key) declared but never accessed by any consumer
15476
+ * project-wide. Wrapped in [`UnusedStoreMemberFinding`]: same inner
15477
+ * [`UnusedMember`] struct as `unused_class_members`, with a
15478
+ * store-targeted fix description. Cross-graph: the store binding is
15479
+ * imported (the module is reachable) yet a specific member is dead.
15480
+ */
15481
+ unused_store_members?: UnusedStoreMemberFinding[]
15482
+ /**
15483
+ * Import specifiers that could not be resolved. Wrapped in
15484
+ * [`UnresolvedImportFinding`] so each entry carries a typed `actions`
15485
+ * array natively.
15486
+ */
15487
+ unresolved_imports: UnresolvedImportFinding[]
15488
+ /**
15489
+ * Dependencies used in code but not listed in package.json. Wrapped in
15490
+ * [`UnlistedDependencyFinding`].
15491
+ */
15492
+ unlisted_dependencies: UnlistedDependencyFinding[]
15493
+ /**
15494
+ * Exports with the same name across multiple modules. Wrapped in
15495
+ * [`DuplicateExportFinding`] so each entry carries a typed `actions`
15496
+ * array natively, with the position-0 `add-to-config` `ignoreExports`
15497
+ * snippet wired in at wrapper construction.
15498
+ */
15499
+ duplicate_exports: DuplicateExportFinding[]
15500
+ /**
15501
+ * Production dependencies only used via type-only imports (could be
15502
+ * devDependencies). Only populated in production mode. Wrapped in
15503
+ * [`TypeOnlyDependencyFinding`].
15504
+ */
15505
+ type_only_dependencies: TypeOnlyDependencyFinding[]
15506
+ /**
15507
+ * Production dependencies only imported by test files (could be
15508
+ * devDependencies). Wrapped in [`TestOnlyDependencyFinding`].
15509
+ */
15510
+ test_only_dependencies?: TestOnlyDependencyFinding[]
15511
+ /**
15512
+ * devDependencies imported by production (non-test, non-config) source code
15513
+ * via a runtime/value import; they should be promoted to dependencies.
15514
+ * The promote-side mirror of [`TestOnlyDependencyFinding`]. Wrapped in
15515
+ * [`DevDependencyInProductionFinding`].
15516
+ */
15517
+ dev_dependencies_in_production?: DevDependencyInProductionFinding[]
15518
+ /**
15519
+ * Circular dependency chains detected in the module graph. Wrapped in
15520
+ * [`CircularDependencyFinding`] so each entry carries a typed `actions`
15521
+ * array natively.
15522
+ */
15523
+ circular_dependencies: CircularDependencyFinding[]
15524
+ /**
15525
+ * Cycles or self-loops in the re-export edge subgraph (barrel files
15526
+ * re-exporting from each other in a loop). Wrapped in
15527
+ * [`ReExportCycleFinding`] so each entry carries a typed `actions`
15528
+ * array natively (a `refactor-re-export-cycle` informational primary
15529
+ * plus a `suppress-file` secondary; cycles are file-scoped so a single
15530
+ * suppression breaks the cycle).
15531
+ */
15532
+ re_export_cycles?: ReExportCycleFinding[]
15533
+ /**
15534
+ * Dependency cycles between workspace packages, built from resolved
15535
+ * cross-package imports. Wrapped in [`PackageCycleFinding`] so each
15536
+ * entry carries a typed `actions` array natively.
15537
+ */
15538
+ package_cycles?: PackageCycleFinding[]
15539
+ /**
15540
+ * Imports that cross architecture boundary rules. Wrapped in
15541
+ * [`BoundaryViolationFinding`] so each entry carries a typed `actions`
15542
+ * array natively.
15543
+ */
15544
+ boundary_violations?: BoundaryViolationFinding[]
15545
+ /**
15546
+ * Files that matched no architecture boundary zone while
15547
+ * `boundaries.coverage.requireAllFiles` was enabled.
15548
+ */
15549
+ boundary_coverage_violations?: BoundaryCoverageViolationFinding[]
15550
+ /**
15551
+ * Calls from zoned files to callees forbidden for that zone via
15552
+ * `boundaries.calls.forbidden`. Wrapped in
15553
+ * [`BoundaryCallViolationFinding`] so each entry carries a typed
15554
+ * `actions` array natively.
15555
+ */
15556
+ boundary_call_violations?: BoundaryCallViolationFinding[]
15557
+ /**
15558
+ * Banned calls, imports, and catalogue-derived effects matched by
15559
+ * declarative rule packs
15560
+ * (`rulePacks` config). Wrapped in [`PolicyViolationFinding`] so each
15561
+ * entry carries a typed `actions` array natively. Each finding carries
15562
+ * its effective per-rule severity.
15563
+ */
15564
+ policy_violations?: PolicyViolationFinding[]
15565
+ /**
15566
+ * Suppression comments or JSDoc tags that no longer match any issue.
15567
+ */
15568
+ stale_suppressions?: StaleSuppression[]
15569
+ /**
15570
+ * Entries in package manager catalog sections not referenced by any
15571
+ * workspace package via the catalog: protocol. Supports
15572
+ * `pnpm-workspace.yaml` catalogs and Bun root `package.json` catalogs.
15573
+ * Wrapped in [`UnusedCatalogEntryFinding`] so each entry carries a typed
15574
+ * `actions` array natively, with per-instance `auto_fixable` derived
15575
+ * from `hardcoded_consumers` and the catalog source file.
15576
+ */
15577
+ unused_catalog_entries?: UnusedCatalogEntryFinding[]
15578
+ /**
15579
+ * Named groups under package manager catalogs sections that declare no
15580
+ * package entries. The top-level catalog: map is not reported. Wrapped in
15581
+ * [`EmptyCatalogGroupFinding`].
15582
+ */
15583
+ empty_catalog_groups?: EmptyCatalogGroupFinding[]
15584
+ /**
15585
+ * Workspace package.json references to catalogs (`catalog:` or
15586
+ * `catalog:<name>`) that do not declare the consumed package. The package
15587
+ * manager install will error until the named catalog grows to include the
15588
+ * package or the reference is switched / removed. Wrapped in
15589
+ * [`UnresolvedCatalogReferenceFinding`] with the discriminated
15590
+ * `add-catalog-entry` / `update-catalog-reference` primary at position 0.
15591
+ */
15592
+ unresolved_catalog_references?: UnresolvedCatalogReferenceFinding[]
15593
+ /**
15594
+ * Entries in pnpm-workspace.yaml's overrides section, package.json's
15595
+ * pnpm.overrides block, npm or Bun's top-level overrides object, or Bun's
15596
+ * top-level resolutions object,
15597
+ * whose target package is not declared by any workspace package and is
15598
+ * not present in pnpm-lock.yaml, package-lock.json, npm-shrinkwrap.json,
15599
+ * or bun.lock. Default severity is warn because projects without a
15600
+ * readable lockfile fall back to manifest-only checks; the hint field
15601
+ * flags those conservative cases. When the only lockfile is bun's binary
15602
+ * bun.lockb, resolution cannot be read and the check emits nothing.
15603
+ * Wrapped in [`UnusedDependencyOverrideFinding`].
15604
+ */
15605
+ unused_dependency_overrides?: UnusedDependencyOverrideFinding[]
15606
+ /**
15607
+ * Package-manager override or resolution entries whose key or value does
15608
+ * not parse in the declaration source's grammar (empty key, empty value,
15609
+ * malformed selector, unbalanced parent matcher). The package manager may
15610
+ * reject or ignore these at install time. Default severity is error. Wrapped in
15611
+ * [`MisconfiguredDependencyOverrideFinding`].
15612
+ */
15613
+ misconfigured_dependency_overrides?: MisconfiguredDependencyOverrideFinding[]
15614
+ /**
15615
+ * `"use client"` files that export a Next.js server-only / route-segment
15616
+ * config name (e.g. `metadata`, `revalidate`, `GET`). Next.js rejects this
15617
+ * at build time. Wrapped in [`InvalidClientExportFinding`] so each entry
15618
+ * carries a typed `actions` array natively. Default severity is `warn`.
15619
+ */
15620
+ invalid_client_exports?: InvalidClientExportFinding[]
15621
+ /**
15622
+ * Barrel files that re-export BOTH a `"use client"` origin module AND a
15623
+ * server-only origin module (the Next.js App Router footgun). Wrapped in
15624
+ * [`MixedClientServerBarrelFinding`] so each entry carries a typed
15625
+ * `actions` array natively. Default severity is `warn`.
15626
+ */
15627
+ mixed_client_server_barrels?: MixedClientServerBarrelFinding[]
15628
+ /**
15629
+ * `"use client"` / `"use server"` directives written as expression
15630
+ * statements after a non-directive statement, so the RSC bundler parses
15631
+ * them as ordinary strings and silently ignores them. Wrapped in
15632
+ * [`MisplacedDirectiveFinding`] so each entry carries a typed `actions`
15633
+ * array natively. Default severity is `warn`.
15634
+ */
15635
+ misplaced_directives?: MisplacedDirectiveFinding[]
15636
+ /**
15637
+ * Vue `inject(KEY)` / Svelte `getContext(KEY)` calls whose symbol KEY is
15638
+ * provided nowhere in the project (the injected-never-provided dead-half).
15639
+ * Wrapped in [`UnprovidedInjectFinding`] so each entry carries a typed
15640
+ * `actions` array natively. Default severity is `warn`.
15641
+ */
15642
+ unprovided_injects?: UnprovidedInjectFinding[]
15643
+ /**
15644
+ * Vue/Svelte single-file components that are reachable but rendered nowhere
15645
+ * (the imported-but-never-rendered dead-half). Wrapped in
15646
+ * [`UnrenderedComponentFinding`] so each entry carries a typed `actions`
15647
+ * array natively. Default severity is `warn`.
15648
+ */
15649
+ unrendered_components?: UnrenderedComponentFinding[]
15650
+ /**
15651
+ * Next.js App Router route files that resolve to the same URL within one
15652
+ * app-root (a guaranteed `next build` failure). Wrapped in
15653
+ * [`RouteCollisionFinding`] so each entry carries a typed `actions` array
15654
+ * natively. One finding per colliding file. Default severity is `warn`.
15655
+ */
15656
+ route_collisions?: RouteCollisionFinding[]
15657
+ /**
15658
+ * Sibling Next.js dynamic route segments at one tree position using
15659
+ * different param spellings (a dev / runtime error; `next build` does NOT
15660
+ * catch it). Wrapped in [`DynamicSegmentNameConflictFinding`] so each entry
15661
+ * carries a typed `actions` array natively. Default severity is `warn`.
15662
+ */
15663
+ dynamic_segment_name_conflicts?: DynamicSegmentNameConflictFinding[]
15664
+ /**
15665
+ * Vue `<script setup>` `defineProps`, Svelte 5 `$props()`, and React props
15666
+ * referenced nowhere in their own component. Wrapped in
15667
+ * [`UnusedComponentPropFinding`] so each entry carries a typed `actions`
15668
+ * array natively. Default severity is `warn`.
15669
+ */
15670
+ unused_component_props?: UnusedComponentPropFinding[]
15671
+ /**
15672
+ * Used optional component inputs absent from inspected reachable callers. Off by default.
15673
+ */
15674
+ absent_component_props?: AbsentComponentPropFinding[]
15675
+ /**
15676
+ * Vue `<script setup>` `defineEmits` events emitted nowhere in their own SFC
15677
+ * (no `emit('<name>')` call). Wrapped in [`UnusedComponentEmitFinding`] so
15678
+ * each entry carries a typed `actions` array natively. Default severity is
15679
+ * `warn`.
15680
+ */
15681
+ unused_component_emits?: UnusedComponentEmitFinding[]
15682
+ /**
15683
+ * Angular `@Input()` / signal `input()` / `model()` inputs read nowhere in
15684
+ * their own component (neither the template nor the class body). Wrapped in
15685
+ * [`UnusedComponentInputFinding`] so each entry carries a typed `actions`
15686
+ * array natively. Default severity is `warn`.
14554
15687
  */
14555
- export interface SecuritySurvivor {
15688
+ unused_component_inputs?: UnusedComponentInputFinding[]
14556
15689
  /**
14557
- * Stable candidate id from `security_findings[].finding_id`.
15690
+ * Angular `@Output()` / signal `output()` outputs emitted nowhere in their
15691
+ * own component (no `this.<output>.emit(...)`). Wrapped in
15692
+ * [`UnusedComponentOutputFinding`] so each entry carries a typed `actions`
15693
+ * array natively. Default severity is `warn`.
14558
15694
  */
14559
- finding_id: string
14560
- verdict: SecurityVerifierVerdictStatus
15695
+ unused_component_outputs?: UnusedComponentOutputFinding[]
14561
15696
  /**
14562
- * Short machine-oriented verdict reason.
15697
+ * Svelte components dispatching a custom event via `createEventDispatcher()`
15698
+ * whose event name is listened to nowhere project-wide (cross-file
15699
+ * dead-output direction). Wrapped in [`UnusedSvelteEventFinding`] so each
15700
+ * entry carries a typed `actions` array natively. Default severity is
15701
+ * `warn`.
14563
15702
  */
14564
- reason?: (string | null)
15703
+ unused_svelte_events?: UnusedSvelteEventFinding[]
14565
15704
  /**
14566
- * Longer free-form verdict explanation.
15705
+ * Next.js Server Actions (exports of `"use server"` files) that no code in
15706
+ * the project references. Reclassified out of `unused_exports` for
15707
+ * `"use server"` files. Wrapped in [`UnusedServerActionFinding`] so each
15708
+ * entry carries a typed `actions` array natively. Default severity is
15709
+ * `warn`.
14567
15710
  */
14568
- rationale?: (string | null)
15711
+ unused_server_actions?: UnusedServerActionFinding[]
14569
15712
  /**
14570
- * Optional verifier-provided confidence or review priority.
15713
+ * SvelteKit `+page.{ts,server.ts,js,server.js}` `load()` return-object keys
15714
+ * read by no consumer. Wrapped in [`UnusedLoadDataKeyFinding`] so each entry
15715
+ * carries a typed `actions` array natively. Default severity is `warn`.
14571
15716
  */
14572
- confidence?: (string | null)
15717
+ unused_load_data_keys?: UnusedLoadDataKeyFinding[]
14573
15718
  /**
14574
- * Optional verifier-provided impact statement.
15719
+ * `true` when the `unused-load-data-key` detector abstained project-wide
15720
+ * because a whole-object use of `page.data` / `$page.data` was seen
15721
+ * somewhere (S1 observability: an empty `unused_load_data_keys` with this
15722
+ * flag set is NOT a clean bill, it means the rule could not run safely).
15723
+ * Serialized only when `true` so the default JSON contract is unchanged.
14575
15724
  */
14576
- impact?: (string | null)
15725
+ unused_load_data_keys_global_abstain?: boolean
14577
15726
  /**
14578
- * Optional verifier-owned remediation direction.
15727
+ * React/Preact props forwarded unchanged through `>= N` intermediate
15728
+ * pass-through components until a consumer (located per-chain records).
15729
+ * Wrapped in [`PropDrillingChainFinding`] so each entry carries a typed
15730
+ * `actions` array natively. Health signal: the rule defaults to `off`
15731
+ * (opt-in), so this is dormant and populated ONLY when the user enables it.
14579
15732
  */
14580
- fix_direction?: (string | null)
14581
- candidate: SecurityFinding
14582
- }
15733
+ prop_drilling_chains?: PropDrillingChainFinding[]
14583
15734
  /**
14584
- * The `fallow security blind-spots --format json` envelope.
15735
+ * React/Preact components whose entire body is a single spread-forwarded
15736
+ * child render (`return <Child {...props}/>`): pure structural indirection,
15737
+ * a candidate for inlining at call sites. Wrapped in [`ThinWrapperFinding`]
15738
+ * so each entry carries a typed `actions` array natively. Health signal: the
15739
+ * rule defaults to `off` (opt-in), so this is dormant and populated ONLY
15740
+ * when the user enables it.
14585
15741
  */
14586
- export interface SecurityBlindSpotsOutput {
14587
- schema_version: SecurityBlindSpotsSchemaVersion
14588
- version: ToolVersion
14589
- elapsed_ms: ElapsedMs
15742
+ thin_wrappers?: ThinWrapperFinding[]
14590
15743
  /**
14591
- * Diagnostics owned by the security analysis used for this view.
15744
+ * React/Preact components that participate in a duplicate-prop-shape group:
15745
+ * three or more components across two or more files whose statically-known
15746
+ * prop NAME set is identical after stripping ubiquitous DOM / passthrough
15747
+ * names (a missing shared `Props` type / base component). Wrapped in
15748
+ * [`DuplicatePropShapeFinding`] so each entry carries a typed `actions`
15749
+ * array and its sibling roster natively. Health signal: the rule defaults to
15750
+ * `off` (opt-in), so this is dormant and populated ONLY when the user
15751
+ * enables it.
14592
15752
  */
14593
- workspace_diagnostics?: WorkspaceDiagnostic[]
14594
- summary: SecurityBlindSpotsSummary
15753
+ duplicate_prop_shapes?: DuplicatePropShapeFinding[]
14595
15754
  /**
14596
- * Grouped unresolved callee diagnostics, derived from existing samples.
15755
+ * Number of `unused_exports`, `unused_types`, `unused_class_members` and
15756
+ * `unused_enum_members` findings that this run did not report because
15757
+ * their file is an unused file. Deleting the file removes them, so they
15758
+ * add no information. `--show-cascade` or the `showCascade` config key
15759
+ * keeps them in the report, and then this count is zero. The count is
15760
+ * taken after the scope and the rules and before a baseline. Serialized
15761
+ * only when not zero, so a run without such findings keeps its JSON.
14597
15762
  */
14598
- groups: SecurityBlindSpotGroup[]
14599
- }
15763
+ cascade_hidden?: number
14600
15764
  /**
14601
- * Aggregate counts for blind-spot output.
15765
+ * Count deltas against the matched baseline, in baseline runs.
14602
15766
  */
14603
- export interface SecurityBlindSpotsSummary {
15767
+ baseline_deltas?: (BaselineDeltas | null)
14604
15768
  /**
14605
- * Files containing at least one unresolved callee.
15769
+ * Which baseline snapshot was matched, in baseline runs.
14606
15770
  */
14607
- unresolved_edge_files: number
15771
+ baseline?: (BaselineMatch | null)
14608
15772
  /**
14609
- * Total unresolved callee sites in the analysis.
15773
+ * This run's view of the loaded baseline, present only in baseline runs.
15774
+ * Carries the staleness counts, the advisory verdict and `gate_trips`, the
15775
+ * same boolean `--fail-on-stale-baseline` exits on, so a CI integration
15776
+ * reads one field instead of restating the rule. Read `change_scoped`
15777
+ * before dividing `matched_entries` by `baseline_entries`: a narrowed run
15778
+ * can report `matched_entries: 0` on a healthy baseline.
14610
15779
  */
14611
- unresolved_callee_sites: number
15780
+ baseline_staleness?: (BaselineStaleness | null)
14612
15781
  /**
14613
- * Callee sites captured in the bounded diagnostic sample.
15782
+ * The answer to `--finding-id`, present only when the run received one
15783
+ * or more `--finding-id` values. The report then holds only the
15784
+ * requested findings. Read `missing` as resolved only when `conclusive`
15785
+ * is true; a scope, a baseline or a filter can hide a finding that still
15786
+ * exists. See [`crate::FindingIdQuery`].
14614
15787
  */
14615
- sampled_callee_sites: number
14616
- }
15788
+ finding_id_query?: (FindingIdQuery | null)
14617
15789
  /**
14618
- * One actionable blind-spot group.
15790
+ * Regression verdict against the baseline, in `--fail-on-regression` runs.
14619
15791
  */
14620
- export interface SecurityBlindSpotGroup {
14621
- reason: SkippedSecurityCalleeReason
14622
- expression_kind: SkippedSecurityCalleeExpressionKind
15792
+ regression?: (RegressionResult | null)
14623
15793
  /**
14624
- * Count in the bounded diagnostic sample.
15794
+ * The verdict of every gate this run evaluated, keyed by name. The CLI
15795
+ * always emits it, with the command's default exit rule in it also when
15796
+ * no flag armed a gate, so a CI integration reads the verdict instead of
15797
+ * guessing from a process status it usually cannot see. A gate fails the
15798
+ * build when `status` is `fail` AND `enforced` is true. The typed
15799
+ * programmatic API runs no CLI gate and leaves it absent. See
15800
+ * [`crate::GateOutcomes`].
14625
15801
  */
14626
- sampled_count: number
15802
+ gate_outcomes?: (GateOutcomes | null)
14627
15803
  /**
14628
- * Top files in this bounded diagnostic sample.
15804
+ * Every narrowing or shaping request this run RECEIVED, keyed by name,
15805
+ * absent when it was asked for nothing. An entry whose `status` is not
15806
+ * `applied` means the run could not do what it was asked and reported
15807
+ * something WIDER instead, so what follows is a valid report of a scope
15808
+ * nobody requested. Honoured requests are published too, with
15809
+ * `status: "applied"`, so an absent object means "nothing was asked for",
15810
+ * never "nothing failed". See [`crate::RequestOutcomes`].
14629
15811
  */
14630
- files: SecurityBlindSpotFile[]
15812
+ request_outcomes?: (RequestOutcomes | null)
14631
15813
  /**
14632
- * Suggested next action for this group.
15814
+ * Applied Git refs for exact workspace packages. Absent when no package
15815
+ * baselines were selected, including runs with a global changed-since ref.
14633
15816
  */
14634
- suggestion: string
14635
- }
15817
+ package_baselines?: PackageBaselineStatus[]
14636
15818
  /**
14637
- * One file inside a blind-spot group.
15819
+ * `_meta` block with docs and rule definitions, when `--explain` was
15820
+ * passed.
14638
15821
  */
14639
- export interface SecurityBlindSpotFile {
15822
+ _meta?: (Meta | null)
14640
15823
  /**
14641
- * File path relative to the analysed root.
15824
+ * Non-fatal diagnostics about the project itself, from all three stages
15825
+ * that record them (issue #473):
15826
+ *
15827
+ * - workspace discovery, at config load: `undeclared-workspace`,
15828
+ * `malformed-package-json`, `glob-matched-no-package-json`,
15829
+ * `malformed-tsconfig`, `tsconfig-reference-dir-missing`;
15830
+ * - source discovery, during the file walk: `skipped-large-file`,
15831
+ * `skipped-minified-file`, `skipped-source-dotdir`,
15832
+ * `excluded-by-default-ignore`, `source-read-failure`,
15833
+ * `source-parse-degraded`;
15834
+ * - dead-code analysis, from the dependency-catalog and override
15835
+ * detectors: `malformed-pnpm-workspace-yaml`,
15836
+ * `bun-lockb-override-resolution-skipped`;
15837
+ * - framework plugins, while they read their own build configs:
15838
+ * `plugin-config-unreadable`, `plugin-effect-not-modeled`;
15839
+ * - the dead-code result, for config patterns that matched nothing:
15840
+ * `ignore-dependencies-glob-unmatched`,
15841
+ * `ignore-findings-pattern-unmatched`.
15842
+ *
15843
+ * Analysis-stage and plugin-stage kinds therefore reach only the envelopes
15844
+ * whose run includes a dead-code analyze pass, never a standalone
15845
+ * `fallow dupes --format json`. `path` is project-root-relative with
15846
+ * forward slashes; the array is omitted when empty. The same list is
15847
+ * repeated on each top-level command's envelope so single-command
15848
+ * consumers see it without having to look at a separate top-level field.
15849
+ *
15850
+ * A diagnostic here is advisory and never withholds a finding. Where an
15851
+ * entry reports a source file this run never fully analyzed
15852
+ * (`source-parse-degraded`, `source-read-failure`, `skipped-large-file`,
15853
+ * `skipped-minified-file`, `skipped-source-dotdir`) it can distort a
15854
+ * verdict, so the affected `unused_files[]`, `unused_exports[]`, and
15855
+ * dependency entries additionally carry the caveat themselves in their own
15856
+ * optional `reachability_caveats[]` array, and a reader who never scrolls
15857
+ * back up to this list still sees it. `fallow fix` reads the same array
15858
+ * and withholds the removal while a caveat stands.
15859
+ *
15860
+ * `excluded-by-default-ignore` is the one source-discovery kind that
15861
+ * reports unseen files WITHOUT raising a caveat. It names a built-in
15862
+ * ignore pattern (`** /dist/**`, `** /build/**`, `** /coverage/**`, or one
15863
+ * of the four minified-bundle globs) that removed candidate source files
15864
+ * from the walk, which is designed behavior on generated output rather
15865
+ * than a degraded run, so it is advisory only and no finding inherits it.
15866
+ * One entry per pattern, never per file, so the array stays bounded on a
15867
+ * project of any size. Gitignored trees are pruned before the walk sees
15868
+ * them and count zero, and `** /node_modules/**` is never reported:
15869
+ * installed dependencies are not the first-party source the kind is
15870
+ * about.
14642
15871
  */
14643
- path: string
15872
+ workspace_diagnostics?: WorkspaceDiagnostic[]
14644
15873
  /**
14645
- * Count in the bounded diagnostic sample.
15874
+ * Read-only follow-up commands computed from this run's findings, emitted
15875
+ * at the JSON root so an agent acting on the output is pointed at fallow's
15876
+ * adjacent verification capabilities (trace, complexity breakdown, audit,
15877
+ * workspace scoping). Each command is runnable as-is and never mutating;
15878
+ * see [`NextStep`] for both contracts. Omitted when empty or when
15879
+ * `FALLOW_SUGGESTIONS=off`; does NOT contribute to `total_issues`.
14646
15880
  */
14647
- sampled_count: number
15881
+ next_steps?: NextStep[]
14648
15882
  }
14649
15883
  /**
14650
15884
  * Bare `fallow --format json` envelope.
@@ -14660,7 +15894,8 @@ elapsed_ms: ElapsedMs
14660
15894
  * `--fail-on-issues` or `--ci`, the machine formats of the combined run
14661
15895
  * exit 0 for findings, so most entries have `enforced: false`. With one of
14662
15896
  * these flags, the findings rules and `duplication-threshold` are
14663
- * `enforced`, and every format exits 1 when one fails. For the default
15897
+ * `enforced`, the dupes section adds an enforced `duplication-findings`
15898
+ * entry, and every format exits 1 when one fails. For the default
14664
15899
  * exit rules (`error-severity-findings`,
14665
15900
  * `health-findings`), `status` gives the verdict of the human run. An
14666
15901
  * advisory entry can report `fail` without a failure of the human run: an
@@ -17339,6 +18574,88 @@ outcome: SimilarCodeDomainOutcome
17339
18574
  */
17340
18575
  rationale: string
17341
18576
  }
18577
+ /**
18578
+ * Machine-readable readiness of the exact local companion and pinned model.
18579
+ */
18580
+ export interface SimilarCodeStatusOutput {
18581
+ schema_version: SimilarCodeStatusSchemaVersion
18582
+ version: ToolVersion
18583
+ /**
18584
+ * Companion protocol version.
18585
+ */
18586
+ protocol_version: number
18587
+ /**
18588
+ * Embedding calculation semantics implemented by the companion.
18589
+ */
18590
+ embedding_semantics_version: number
18591
+ /**
18592
+ * Exact companion package version.
18593
+ */
18594
+ companion_version: string
18595
+ /**
18596
+ * Whether every pinned model artifact is ready and verified.
18597
+ */
18598
+ model_ready: boolean
18599
+ /**
18600
+ * Immutable model identifier.
18601
+ */
18602
+ model_id: string
18603
+ /**
18604
+ * Immutable model revision.
18605
+ */
18606
+ model_revision: string
18607
+ /**
18608
+ * Embedding width.
18609
+ */
18610
+ dimensions: number
18611
+ /**
18612
+ * Maximum tokenizer length.
18613
+ */
18614
+ max_tokens: number
18615
+ /**
18616
+ * Model license identifier.
18617
+ */
18618
+ license: string
18619
+ /**
18620
+ * Local model cache directory.
18621
+ */
18622
+ cache_dir: string
18623
+ /**
18624
+ * Expected download size for all pinned artifacts.
18625
+ */
18626
+ download_bytes: number
18627
+ /**
18628
+ * Whether source analysis stays local and offline.
18629
+ */
18630
+ analysis_offline: boolean
18631
+ /**
18632
+ * Whether all installed artifacts passed integrity validation.
18633
+ */
18634
+ integrity_verified: boolean
18635
+ /**
18636
+ * Actionable readiness problem when the model is unavailable.
18637
+ */
18638
+ problem?: (string | null)
18639
+ /**
18640
+ * Whether this setup invocation downloaded new bytes.
18641
+ */
18642
+ downloaded?: (boolean | null)
18643
+ }
18644
+ /**
18645
+ * Result of explicitly clearing the derived project-namespaced vector cache.
18646
+ */
18647
+ export interface SimilarCodeCacheClearOutput {
18648
+ schema_version: SimilarCodeCacheClearSchemaVersion
18649
+ version: ToolVersion
18650
+ /**
18651
+ * Whether an existing vector cache was removed.
18652
+ */
18653
+ removed: boolean
18654
+ /**
18655
+ * Whether model artifacts were removed. Version 1 always emits false.
18656
+ */
18657
+ model_removed: boolean
18658
+ }
17342
18659
  /**
17343
18660
  * Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
17344
18661
  */