fallow 2.72.0 → 2.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "2.72.0",
3
+ "version": "2.74.0",
4
4
  "description": "Codebase intelligence for TypeScript and JavaScript. Finds unused code, duplication, circular dependencies, complexity hotspots, and architecture drift. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, 94 framework plugins.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -73,13 +73,13 @@
73
73
  "@tanstack/intent": "0.0.40"
74
74
  },
75
75
  "optionalDependencies": {
76
- "@fallow-cli/darwin-arm64": "2.72.0",
77
- "@fallow-cli/darwin-x64": "2.72.0",
78
- "@fallow-cli/linux-x64-gnu": "2.72.0",
79
- "@fallow-cli/linux-arm64-gnu": "2.72.0",
80
- "@fallow-cli/linux-x64-musl": "2.72.0",
81
- "@fallow-cli/linux-arm64-musl": "2.72.0",
82
- "@fallow-cli/win32-arm64-msvc": "2.72.0",
83
- "@fallow-cli/win32-x64-msvc": "2.72.0"
76
+ "@fallow-cli/darwin-arm64": "2.74.0",
77
+ "@fallow-cli/darwin-x64": "2.74.0",
78
+ "@fallow-cli/linux-x64-gnu": "2.74.0",
79
+ "@fallow-cli/linux-arm64-gnu": "2.74.0",
80
+ "@fallow-cli/linux-x64-musl": "2.74.0",
81
+ "@fallow-cli/linux-arm64-musl": "2.74.0",
82
+ "@fallow-cli/win32-arm64-msvc": "2.74.0",
83
+ "@fallow-cli/win32-x64-msvc": "2.74.0"
84
84
  }
85
85
  }
package/schema.json CHANGED
@@ -79,6 +79,13 @@
79
79
  "$ref": "#/$defs/IgnoreCatalogReferenceRule"
80
80
  }
81
81
  },
82
+ "ignoreDependencyOverrides": {
83
+ "description": "Rules for suppressing `unused-dependency-override` and\n`misconfigured-dependency-override` findings.\n\nEach rule matches by override target package, optionally scoped to the\ndeclaring source file (`pnpm-workspace.yaml` or `package.json`). Useful\nfor overrides targeting purely-transitive packages (CVE-fix pattern)\nwhere the conservative static algorithm would otherwise cry wolf.",
84
+ "type": "array",
85
+ "items": {
86
+ "$ref": "#/$defs/IgnoreDependencyOverrideRule"
87
+ }
88
+ },
82
89
  "ignoreExportsUsedInFile": {
83
90
  "description": "Suppress unused-export findings when the exported symbol is referenced\ninside the file that declares it. This mirrors Knip's\n`ignoreExportsUsedInFile` option while still reporting exports that have\nno references at all.",
84
91
  "$ref": "#/$defs/IgnoreExportsUsedInFileConfig",
@@ -158,7 +165,10 @@
158
165
  "feature-flags": "off",
159
166
  "stale-suppressions": "warn",
160
167
  "unused-catalog-entries": "warn",
161
- "unresolved-catalog-references": "error"
168
+ "empty-catalog-groups": "warn",
169
+ "unresolved-catalog-references": "error",
170
+ "unused-dependency-overrides": "warn",
171
+ "misconfigured-dependency-overrides": "error"
162
172
  }
163
173
  },
164
174
  "boundaries": {
@@ -566,6 +576,27 @@
566
576
  "package"
567
577
  ]
568
578
  },
579
+ "IgnoreDependencyOverrideRule": {
580
+ "description": "Rule for suppressing an `unused-dependency-override` or\n`misconfigured-dependency-override` finding.\n\nA finding is suppressed when ALL provided fields match the finding:\n- `package` matches the override's target package name exactly\n (case-sensitive). For parent-chain overrides (`react>react-dom`), the\n target is the rightmost segment (`react-dom`).\n- `source`, if set, scopes the suppression to overrides declared in that\n source file. Accepts `\"pnpm-workspace.yaml\"` or `\"package.json\"`.\n When omitted, both sources match.\n\nTypical use cases:\n- Library-internal CI tooling overrides we cannot drop yet\n- Overrides targeting purely-transitive packages (CVE-fix pattern)",
581
+ "type": "object",
582
+ "properties": {
583
+ "package": {
584
+ "description": "Override target package name (exact match; case-sensitive).",
585
+ "type": "string"
586
+ },
587
+ "source": {
588
+ "description": "Source file scope: `\"pnpm-workspace.yaml\"` or `\"package.json\"`.\n`None` matches both sources.",
589
+ "type": [
590
+ "string",
591
+ "null"
592
+ ]
593
+ }
594
+ },
595
+ "additionalProperties": false,
596
+ "required": [
597
+ "package"
598
+ ]
599
+ },
569
600
  "IgnoreExportsUsedInFileConfig": {
570
601
  "description": "Controls whether exports referenced only inside their defining file are\nreported as unused exports.",
571
602
  "anyOf": [
@@ -923,9 +954,21 @@
923
954
  "$ref": "#/$defs/Severity",
924
955
  "default": "warn"
925
956
  },
957
+ "empty-catalog-groups": {
958
+ "$ref": "#/$defs/Severity",
959
+ "default": "warn"
960
+ },
926
961
  "unresolved-catalog-references": {
927
962
  "$ref": "#/$defs/Severity",
928
963
  "default": "error"
964
+ },
965
+ "unused-dependency-overrides": {
966
+ "$ref": "#/$defs/Severity",
967
+ "default": "warn"
968
+ },
969
+ "misconfigured-dependency-overrides": {
970
+ "$ref": "#/$defs/Severity",
971
+ "default": "error"
929
972
  }
930
973
  }
931
974
  },
@@ -1001,7 +1044,7 @@
1001
1044
  "const": "feature-sliced"
1002
1045
  },
1003
1046
  {
1004
- "description": "Bulletproof React: app → features → shared + server.\nFeature modules are isolated from each other; shared utilities and server\ninfrastructure form the base layers.",
1047
+ "description": "Bulletproof React: app → features → shared + server.\nFeature modules are isolated from each other via `autoDiscover`: every\nimmediate child of `src/features/` becomes its own `features/<name>` zone,\nand cross-feature imports are reported as boundary violations.\n\n**Trade-off (intentional):** top-level files in `src/features/` (e.g.\n`src/features/index.ts` barrel, `src/features/types.ts`) do NOT match any\nchild pattern and are unclassified, meaning they are unrestricted by the\npreset. This is deliberate so feature barrels can re-export children\nwithout producing false-positive `features → features/<child>` violations.\nTo classify top-level files strictly, override the `features` zone with\nan explicit user definition that includes a `patterns` field.",
1005
1048
  "type": "string",
1006
1049
  "const": "bulletproof"
1007
1050
  }
@@ -1022,6 +1065,13 @@
1022
1065
  "type": "string"
1023
1066
  }
1024
1067
  },
1068
+ "autoDiscover": {
1069
+ "description": "Directories whose immediate child directories should become separate\nzones under this logical group.\n\nFor example, `{ \"name\": \"features\", \"autoDiscover\": [\"src/features\"] }`\ncreates zones such as `features/auth` and `features/billing`, each with\na pattern for its own subtree. Rules that reference `features` expand to\nevery discovered child zone. If `patterns` is also set, the parent zone\nremains as a fallback after discovered child zones.",
1070
+ "type": "array",
1071
+ "items": {
1072
+ "type": "string"
1073
+ }
1074
+ },
1025
1075
  "root": {
1026
1076
  "description": "Optional subtree scope for monorepo per-package boundaries.\n\nWhen set, the zone's `patterns` are matched against paths *relative*\nto this directory rather than the project root. At classification\ntime, fallow checks that a candidate path starts with `root` and\nstrips that prefix before glob-matching the patterns against the\nremainder. Files outside the subtree never match the zone.\n\nUseful for monorepos where each package has the same internal\ndirectory layout: instead of writing `packages/app/src/**` and\n`packages/core/src/**` (which collide on shared zone names), set\n`root: \"packages/app/\"` and `patterns: [\"src/**\"]` per package.\n\nTrailing slash and leading `./` are normalized; backslashes are\nconverted to forward slashes. Patterns must NOT redundantly include\nthe root prefix: `root: \"packages/app/\"` with\n`patterns: [\"packages/app/src/**\"]` is rejected with\n`FALLOW-BOUNDARY-ROOT-REDUNDANT-PREFIX` because patterns are\nresolved relative to the root.",
1027
1077
  "type": [
@@ -1031,8 +1081,7 @@
1031
1081
  }
1032
1082
  },
1033
1083
  "required": [
1034
- "name",
1035
- "patterns"
1084
+ "name"
1036
1085
  ]
1037
1086
  },
1038
1087
  "BoundaryRule": {
@@ -1381,6 +1430,16 @@
1381
1430
  }
1382
1431
  ]
1383
1432
  },
1433
+ "empty-catalog-groups": {
1434
+ "anyOf": [
1435
+ {
1436
+ "$ref": "#/$defs/Severity"
1437
+ },
1438
+ {
1439
+ "type": "null"
1440
+ }
1441
+ ]
1442
+ },
1384
1443
  "unresolved-catalog-references": {
1385
1444
  "anyOf": [
1386
1445
  {
@@ -1390,6 +1449,26 @@
1390
1449
  "type": "null"
1391
1450
  }
1392
1451
  ]
1452
+ },
1453
+ "unused-dependency-overrides": {
1454
+ "anyOf": [
1455
+ {
1456
+ "$ref": "#/$defs/Severity"
1457
+ },
1458
+ {
1459
+ "type": "null"
1460
+ }
1461
+ ]
1462
+ },
1463
+ "misconfigured-dependency-overrides": {
1464
+ "anyOf": [
1465
+ {
1466
+ "$ref": "#/$defs/Severity"
1467
+ },
1468
+ {
1469
+ "type": "null"
1470
+ }
1471
+ ]
1393
1472
  }
1394
1473
  }
1395
1474
  },
@@ -100,6 +100,8 @@ cargo install fallow-cli # build from source
100
100
  | Test-only dependencies | n/a | Production deps only imported from test files (should be devDependencies) |
101
101
  | Unused pnpm catalog entries | `--unused-catalog-entries` | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
102
102
  | Unresolved pnpm catalog references | `--unresolved-catalog-references` | `package.json` references to `catalog:` / `catalog:<name>` whose catalog does not declare the package; `pnpm install` would fail. Default `error`. Suppress via `ignoreCatalogReferences: [{ package, catalog?, consumer? }]` in fallow config (package.json has no comment syntax). |
103
+ | Unused pnpm dependency overrides | `--unused-dependency-overrides` | `pnpm-workspace.yaml#overrides` / `package.json#pnpm.overrides` entries forcing a version no workspace package depends on. Default `warn`; the `hint` field flags entries that may be intentional pins for transitive CVEs. Suppress via `ignoreDependencyOverrides: [{ package, source? }]` in fallow config. |
104
+ | Misconfigured pnpm dependency overrides | `--misconfigured-dependency-overrides` | `pnpm.overrides` entries whose key is unparsable (empty, dangling separators, malformed selectors) or value is missing/empty. `pnpm install` would fail. Default `error`. Suppression: same `ignoreDependencyOverrides` config rule. |
103
105
 
104
106
  ## MCP Tools
105
107
 
@@ -109,7 +111,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
109
111
  |------|-------------|
110
112
  | `analyze` | Full dead code analysis (unused files/exports/types/dependencies/members + circular dependencies + boundary violations + stale suppressions). Private type leaks are an opt-in API hygiene check via `issue_types: ["private-type-leaks"]`. Set `boundary_violations: true` as a convenience alias for `issue_types: ["boundary-violations"]`. Set `group_by` to `"owner"`, `"directory"`, `"package"`, or `"section"` to partition results. The `section` mode reads GitLab CODEOWNERS `[Section]` headers and emits `owners` metadata per group |
111
113
  | `check_changed` | Incremental analysis of files changed since a git ref |
112
- | `find_dupes` | Code duplication detection. Set `changed_since` to scope to changed files since a git ref |
114
+ | `find_dupes` | Code duplication detection. Set `changed_since` to scope to changed files since a git ref. Set `min_occurrences` (≥ 2, default 2) to hide pair-only clones and focus on widespread copy-paste; JSON gains `stats.clone_groups_below_min_occurrences` when the filter hides anything |
113
115
  | `fix_preview` | Dry-run auto-fix preview |
114
116
  | `fix_apply` | Apply auto-fixes (destructive) |
115
117
  | `check_health` | Complexity metrics, health scores, hotspots, and refactoring targets. Set `group_by` to `owner`, `directory`, `package`, or `section` for per-group `vital_signs` / `health_score`; SARIF results gain `properties.group`, CodeClimate issues gain a top-level `group` field |
@@ -138,10 +138,11 @@ By default, `fallow dupes` skips generated framework output matching `**/.next/*
138
138
  |------|------|---------|-------------|
139
139
  | `--format` | `human\|json\|sarif\|compact\|markdown\|codeclimate\|gitlab-codequality\|pr-comment-github\|pr-comment-gitlab\|review-github\|review-gitlab` | `human` | Output format |
140
140
  | `--quiet` | bool | `false` | Suppress progress bars |
141
- | `--top` | number | — | Show only the N largest clone groups (sorted by line count descending). Summary stats reflect the full project. |
141
+ | `--top` | number | — | Show only the N most-duplicated clone groups (sorted by instance count desc, tiebreak: line count desc, then path/line). Summary stats reflect the full project. |
142
142
  | `--mode` | `strict\|mild\|weak\|semantic` | `mild` | Detection mode |
143
143
  | `--min-tokens` | number | `50` | Minimum token count for a clone |
144
144
  | `--min-lines` | number | `5` | Minimum line count for a clone |
145
+ | `--min-occurrences` | number | `2` | Minimum number of occurrences before a clone group is reported (must be ≥ 2). Raise to skip pair-only clones and focus on widespread copy-paste worth refactoring. `fallow init` writes `minOccurrences: 3` into new projects. |
145
146
  | `--threshold` | number | `0` | Fail if duplication exceeds this percentage |
146
147
  | `--skip-local` | bool | `false` | Only report cross-directory duplicates |
147
148
  | `--cross-language` | bool | `false` | Strip type annotations for TS↔JS matching |
@@ -191,7 +192,7 @@ fallow dupes --format json --quiet --baseline fallow-baselines/dupes.json --thre
191
192
 
192
193
  ## `fix`: Auto-Remove Unused Code
193
194
 
194
- Auto-removes unused exports and dependencies.
195
+ Auto-removes unused exports, dependencies, enum members, and pnpm catalog entries.
195
196
 
196
197
  ### Flags
197
198
 
@@ -203,6 +204,13 @@ Auto-removes unused exports and dependencies.
203
204
  | `--format` | `human\|json` | `human` | Output format |
204
205
  | `--quiet` | bool | `false` | Suppress progress bars |
205
206
 
207
+ ### What gets fixed
208
+
209
+ - Unused exports (removes the `export` keyword; whole-enum block when every member is unused)
210
+ - Unused dependencies (removed from `package.json`)
211
+ - Unused enum members (removed from the declaration)
212
+ - Unused pnpm catalog entries (removed from `pnpm-workspace.yaml` by line-aware deletion; comments preserved). When the last entry of a catalog group is removed, the header is rewritten to `catalog: {}` / `<name>: {}` so pnpm doesn't reject the resulting null value. Entries with non-empty `hardcoded_consumers` are skipped to avoid breaking `pnpm install`; the skip is surfaced in the JSON fix output as `{"type": "remove_catalog_entry", "applied": false, "skipped": true, "skip_reason": "hardcoded_consumers", "consumers": [...]}`. After a successful catalog edit the CLI emits a one-line `Run pnpm install to refresh pnpm-lock.yaml` reminder. The JSON envelope carries a top-level `"skipped"` count alongside `"total_fixed"` for partial-fix gating.
213
+
206
214
  ### Examples
207
215
 
208
216
  ```bash
@@ -424,7 +432,7 @@ fallow health --format json --quiet --trend
424
432
  ```json
425
433
  {
426
434
  "schema_version": 3,
427
- "version": "2.71.1",
435
+ "version": "2.73.0",
428
436
  "elapsed_ms": 32,
429
437
  "summary": {
430
438
  "files_analyzed": 482,
@@ -810,7 +818,7 @@ fallow audit \
810
818
  ```json
811
819
  {
812
820
  "schema_version": 3,
813
- "version": "2.71.1",
821
+ "version": "2.73.0",
814
822
  "command": "audit",
815
823
  "verdict": "fail",
816
824
  "changed_files_count": 12,
@@ -883,7 +891,7 @@ fallow flags --format json --quiet --workspace my-package
883
891
  ```json
884
892
  {
885
893
  "schema_version": 3,
886
- "version": "2.71.1",
894
+ "version": "2.73.0",
887
895
  "elapsed_ms": 116,
888
896
  "feature_flags": [],
889
897
  "total_flags": 0
@@ -1302,7 +1310,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1302
1310
  ```json
1303
1311
  {
1304
1312
  "schema_version": 3,
1305
- "version": "2.71.1",
1313
+ "version": "2.73.0",
1306
1314
  "elapsed_ms": 45,
1307
1315
  "total_issues": 12,
1308
1316
  "entry_points": {
@@ -1449,7 +1457,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1449
1457
  ```json
1450
1458
  {
1451
1459
  "schema_version": 3,
1452
- "version": "2.71.1",
1460
+ "version": "2.73.0",
1453
1461
  "elapsed_ms": 82,
1454
1462
  "total_clones": 15,
1455
1463
  "total_lines_duplicated": 230,
@@ -1493,7 +1501,7 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1493
1501
  {
1494
1502
  "check": {
1495
1503
  "schema_version": 3,
1496
- "version": "2.71.1",
1504
+ "version": "2.73.0",
1497
1505
  "elapsed_ms": 45,
1498
1506
  "total_issues": 12,
1499
1507
  "unused_files": [],
@@ -1515,7 +1523,7 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1515
1523
  },
1516
1524
  "dupes": {
1517
1525
  "schema_version": 3,
1518
- "version": "2.71.1",
1526
+ "version": "2.73.0",
1519
1527
  "elapsed_ms": 82,
1520
1528
  "total_clones": 15,
1521
1529
  "total_lines_duplicated": 230,
@@ -1524,7 +1532,7 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1524
1532
  },
1525
1533
  "health": {
1526
1534
  "schema_version": 3,
1527
- "version": "2.71.1",
1535
+ "version": "2.73.0",
1528
1536
  "elapsed_ms": 32,
1529
1537
  "summary": {},
1530
1538
  "findings": [],
@@ -117,10 +117,22 @@ stale_suppressions: StaleSuppression[]
117
117
  * Entries in pnpm-workspace.yaml's catalog: or catalogs: sections not referenced by any workspace package via the catalog: protocol.
118
118
  */
119
119
  unused_catalog_entries?: UnusedCatalogEntry[]
120
+ /**
121
+ * Named groups under pnpm-workspace.yaml's catalogs: section that declare no package entries. The top-level catalog: map is not reported.
122
+ */
123
+ empty_catalog_groups?: EmptyCatalogGroup[]
120
124
  /**
121
125
  * Workspace package.json references to catalogs (catalog: or catalog:<name>) that do not declare the consumed package. pnpm install will error until the named catalog grows to include the package or the reference is switched / removed.
122
126
  */
123
127
  unresolved_catalog_references?: UnresolvedCatalogReference[]
128
+ /**
129
+ * Entries in pnpm-workspace.yaml's overrides: section, or package.json's pnpm.overrides block, whose target package is not declared by any workspace package and is not present in pnpm-lock.yaml. Default severity is warn because projects without a readable lockfile fall back to manifest-only checks; the hint field flags those conservative cases.
130
+ */
131
+ unused_dependency_overrides?: UnusedDependencyOverride[]
132
+ /**
133
+ * pnpm.overrides entries whose key or value does not parse as a valid override spec (empty key, empty value, malformed selector, unbalanced parent matcher). pnpm install will reject these. Default severity is error.
134
+ */
135
+ misconfigured_dependency_overrides?: MisconfiguredDependencyOverride[]
124
136
  entry_points?: EntryPoints
125
137
  summary?: CheckSummary
126
138
  baseline_deltas?: BaselineDeltas
@@ -143,7 +155,7 @@ export interface FixAction {
143
155
  /**
144
156
  * Kebab-case identifier for the fix action.
145
157
  */
146
- type: ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference")
158
+ type: ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override")
147
159
  /**
148
160
  * Whether `fallow fix` can apply this fix automatically.
149
161
  */
@@ -207,9 +219,9 @@ export interface AddToConfigAction {
207
219
  */
208
220
  type: "add-to-config"
209
221
  /**
210
- * Always false for config actions.
222
+ * True when `fallow fix` can apply this config action automatically for the current action type. `ignoreExports` duplicate-export actions are auto-fixable when a config file exists; older scalar config-ignore actions remain manual.
211
223
  */
212
- auto_fixable: false
224
+ auto_fixable: boolean
213
225
  /**
214
226
  * Human-readable description of the config change.
215
227
  */
@@ -219,12 +231,14 @@ description: string
219
231
  */
220
232
  config_key: string
221
233
  /**
222
- * Value to add to the config key. Shape depends on `config_key`. For scalar config keys (`ignoreDependencies`, others) this is a string such as `"lodash"`. For `ignoreExports` this is an array of `{ file, exports }` rule objects so the snippet can be merged into the user's config verbatim.
234
+ * Value to add to the config key. Shape depends on `config_key`. For scalar config keys (`ignoreDependencies`, others) this is a string such as `"lodash"`. For `ignoreExports` this is an array of `{ file, exports }` rule objects so the snippet can be merged into the user's config verbatim. For `ignoreCatalogReferences` and `ignoreDependencyOverrides` this is an object whose shape matches the rule entry users add to their fallow config.
223
235
  */
224
236
  value: (string | {
225
237
  file: string
226
238
  exports: string[]
227
- }[])
239
+ }[] | {
240
+
241
+ })
228
242
  /**
229
243
  * Optional URL pointing at a stable JSON Schema fragment that describes the shape of `value`. Agents that intend to validate `value` before writing it into a user's config can fetch the linked schema and run it against `value`. The URL is a JSON Pointer fragment into fallow's main config schema (e.g. `schema.json#/properties/ignoreExports` for the ignoreExports action, or `schema.json#/properties/ignoreDependencies/items` for the per-package ignoreDependencies action). Strictly additive: consumers that ignore the field keep working unchanged.
230
244
  */
@@ -594,6 +608,25 @@ hardcoded_consumers?: string[]
594
608
  actions?: IssueAction[]
595
609
  introduced?: AuditIntroduced
596
610
  }
611
+ /**
612
+ * A named pnpm catalog group under catalogs: with no package entries.
613
+ */
614
+ export interface EmptyCatalogGroup {
615
+ /**
616
+ * Named catalog group under the top-level catalogs: map.
617
+ */
618
+ catalog_name: string
619
+ /**
620
+ * Relative path to pnpm-workspace.yaml.
621
+ */
622
+ path: string
623
+ /**
624
+ * 1-based line number of the empty catalog group header.
625
+ */
626
+ line: number
627
+ actions?: IssueAction[]
628
+ introduced?: AuditIntroduced
629
+ }
597
630
  /**
598
631
  * A workspace package.json reference (catalog: or catalog:<name>) pointing at a catalog that does not declare the consumed package. `pnpm install` will fail with ERR_PNPM_CATALOG_ENTRY_NOT_FOUND_FOR_CATALOG_PROTOCOL.
599
632
  */
@@ -621,6 +654,80 @@ available_in_catalogs?: string[]
621
654
  actions?: IssueAction[]
622
655
  introduced?: AuditIntroduced
623
656
  }
657
+ /**
658
+ * A pnpm.overrides entry whose target package is not declared in any workspace package.json (directly or as a declared parent in a parent>child override). May still be intentional for a transitive CVE pin; see `hint`.
659
+ */
660
+ export interface UnusedDependencyOverride {
661
+ /**
662
+ * Full original override key as written (e.g. 'react>react-dom', '@types/react@<18').
663
+ */
664
+ raw_key: string
665
+ /**
666
+ * Target package the override rewrites (rightmost segment for parent>child keys).
667
+ */
668
+ target_package: string
669
+ /**
670
+ * Optional parent package (left side of `>`). Omitted for bare-target keys.
671
+ */
672
+ parent_package?: string
673
+ /**
674
+ * Optional version selector on the target (e.g. '<18' for '@types/react@<18'). Omitted when absent.
675
+ */
676
+ version_constraint?: string
677
+ /**
678
+ * Right-hand side of the entry: the version pnpm should force.
679
+ */
680
+ version_range: string
681
+ /**
682
+ * File the override was declared in. Matches the value users write in `ignoreDependencyOverrides[].source`.
683
+ */
684
+ source: ("pnpm-workspace.yaml" | "package.json")
685
+ /**
686
+ * Relative path to the source file.
687
+ */
688
+ path: string
689
+ /**
690
+ * 1-based line number of the entry.
691
+ */
692
+ line: number
693
+ /**
694
+ * Soft hint reminding consumers to verify the override before removal. Present because projects without a readable lockfile use the conservative package-manifest fallback. Omitted when absent.
695
+ */
696
+ hint?: string
697
+ actions?: IssueAction[]
698
+ introduced?: AuditIntroduced
699
+ }
700
+ /**
701
+ * A pnpm.overrides entry whose key or value does not parse as a valid pnpm override spec. `pnpm install` will reject these.
702
+ */
703
+ export interface MisconfiguredDependencyOverride {
704
+ /**
705
+ * Full original override key as written.
706
+ */
707
+ raw_key: string
708
+ /**
709
+ * Right-hand side of the entry, exactly as written. Empty when the value was missing.
710
+ */
711
+ raw_value: string
712
+ /**
713
+ * Classifier for the misconfiguration. 'unparsable-key' = the key is not a valid pnpm shape; 'empty-value' = the value is missing, empty, or contains line breaks.
714
+ */
715
+ reason: ("unparsable-key" | "empty-value")
716
+ /**
717
+ * File the override was declared in.
718
+ */
719
+ source: ("pnpm-workspace.yaml" | "package.json")
720
+ /**
721
+ * Relative path to the source file.
722
+ */
723
+ path: string
724
+ /**
725
+ * 1-based line number of the entry.
726
+ */
727
+ line: number
728
+ actions?: IssueAction[]
729
+ introduced?: AuditIntroduced
730
+ }
624
731
  /**
625
732
  * Entry point detection summary showing total detected entry points and their sources.
626
733
  */
@@ -655,7 +762,10 @@ circular_dependencies?: number
655
762
  boundary_violations?: number
656
763
  stale_suppressions?: number
657
764
  unused_catalog_entries?: number
765
+ empty_catalog_groups?: number
658
766
  unresolved_catalog_references?: number
767
+ unused_dependency_overrides?: number
768
+ misconfigured_dependency_overrides?: number
659
769
  }
660
770
  /**
661
771
  * Per-category delta comparison against a saved baseline. Shows current count, baseline count, and delta for each category.