fallow 2.97.0 → 2.99.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.97.0",
3
+ "version": "2.99.0",
4
4
  "description": "Deterministic codebase intelligence for TypeScript and JavaScript. Quality, risk, architecture, dependencies, duplication, and safe cleanup evidence for humans, CI, and agents. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, zero-config framework support.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -83,13 +83,13 @@
83
83
  "@tanstack/intent": "0.0.42"
84
84
  },
85
85
  "optionalDependencies": {
86
- "@fallow-cli/darwin-arm64": "2.97.0",
87
- "@fallow-cli/darwin-x64": "2.97.0",
88
- "@fallow-cli/linux-x64-gnu": "2.97.0",
89
- "@fallow-cli/linux-arm64-gnu": "2.97.0",
90
- "@fallow-cli/linux-x64-musl": "2.97.0",
91
- "@fallow-cli/linux-arm64-musl": "2.97.0",
92
- "@fallow-cli/win32-arm64-msvc": "2.97.0",
93
- "@fallow-cli/win32-x64-msvc": "2.97.0"
86
+ "@fallow-cli/darwin-arm64": "2.99.0",
87
+ "@fallow-cli/darwin-x64": "2.99.0",
88
+ "@fallow-cli/linux-x64-gnu": "2.99.0",
89
+ "@fallow-cli/linux-arm64-gnu": "2.99.0",
90
+ "@fallow-cli/linux-x64-musl": "2.99.0",
91
+ "@fallow-cli/linux-arm64-musl": "2.99.0",
92
+ "@fallow-cli/win32-arm64-msvc": "2.99.0",
93
+ "@fallow-cli/win32-x64-msvc": "2.99.0"
94
94
  }
95
95
  }
package/schema.json CHANGED
@@ -159,6 +159,9 @@
159
159
  "unrendered-components": "warn",
160
160
  "unused-component-props": "warn",
161
161
  "unused-component-emits": "warn",
162
+ "unused-component-inputs": "warn",
163
+ "unused-component-outputs": "warn",
164
+ "unused-svelte-events": "warn",
162
165
  "unused-server-actions": "warn",
163
166
  "unused-load-data-keys": "warn",
164
167
  "prop-drilling": "off",
@@ -175,6 +178,7 @@
175
178
  "coverage-gaps": "off",
176
179
  "feature-flags": "off",
177
180
  "stale-suppressions": "warn",
181
+ "require-suppression-reason": "off",
178
182
  "unused-catalog-entries": "warn",
179
183
  "empty-catalog-groups": "warn",
180
184
  "unresolved-catalog-references": "error",
@@ -1052,6 +1056,21 @@
1052
1056
  "$ref": "#/$defs/Severity",
1053
1057
  "default": "error"
1054
1058
  },
1059
+ "unused-component-inputs": {
1060
+ "description": "Angular `@Input()` / signal `input()` / `model()` declared input read\nnowhere inside its own component (neither the inline/external template nor\nthe class body). The single-file dead-input direction, the Angular\nanalogue of `unused-component-prop`. Defaults to `warn`, not `error`: an\ninput can be part of a deliberately-stable public component API, so\nanalyzer confidence is lower; warn encodes that without failing CI.",
1061
+ "$ref": "#/$defs/Severity",
1062
+ "default": "error"
1063
+ },
1064
+ "unused-component-outputs": {
1065
+ "description": "Angular `@Output()` / signal `output()` declared output emitted nowhere\ninside its own component (no `this.<output>.emit(...)`). The single-file\ndead-output direction, the Angular analogue of `unused-component-emit`.\nDefaults to `warn`, not `error`: an output can be part of a\ndeliberately-stable public component API, so analyzer confidence is lower;\nwarn encodes that without failing CI.",
1066
+ "$ref": "#/$defs/Severity",
1067
+ "default": "error"
1068
+ },
1069
+ "unused-svelte-events": {
1070
+ "description": "Svelte component dispatching a custom event via `createEventDispatcher()`\nwhose event name is listened to nowhere in the analyzed project. The\ncross-file dead-output direction (no eslint-plugin-svelte / svelte-check\nrule covers the listener side). Defaults to `warn`, not `error`: a\ndispatched event can be part of a deliberately-stable public component\nAPI, or a listener may be added later, so analyzer confidence is lower;\nwarn encodes that without failing CI.",
1071
+ "$ref": "#/$defs/Severity",
1072
+ "default": "warn"
1073
+ },
1055
1074
  "unused-server-actions": {
1056
1075
  "description": "Next.js Server Action (an export of a `\"use server\"` file) referenced by\nno code in the project: no import-and-call, no `action={fn}` binding, no\n`<form action={fn}>`. Cross-graph dead-export direction, reclassified out\nof `unused-export` for `\"use server\"` files. Defaults to `warn`, not\n`error`: the rule is new and false-negative-preferring, and reflective\naction-dispatch shapes can hide a real consumer; warn encodes that\nwithout failing CI until corpus-validated.",
1057
1076
  "$ref": "#/$defs/Severity",
@@ -1121,6 +1140,11 @@
1121
1140
  "$ref": "#/$defs/Severity",
1122
1141
  "default": "warn"
1123
1142
  },
1143
+ "require-suppression-reason": {
1144
+ "description": "Opt-in suppression hygiene rule: when enabled, every `fallow-ignore-*`\ncomment and `@expected-unused` tag must carry a `-- <reason>` suffix.",
1145
+ "$ref": "#/$defs/Severity",
1146
+ "default": "off"
1147
+ },
1124
1148
  "unused-catalog-entries": {
1125
1149
  "$ref": "#/$defs/Severity",
1126
1150
  "default": "warn"
@@ -1731,6 +1755,36 @@
1731
1755
  }
1732
1756
  ]
1733
1757
  },
1758
+ "unused-component-inputs": {
1759
+ "anyOf": [
1760
+ {
1761
+ "$ref": "#/$defs/Severity"
1762
+ },
1763
+ {
1764
+ "type": "null"
1765
+ }
1766
+ ]
1767
+ },
1768
+ "unused-component-outputs": {
1769
+ "anyOf": [
1770
+ {
1771
+ "$ref": "#/$defs/Severity"
1772
+ },
1773
+ {
1774
+ "type": "null"
1775
+ }
1776
+ ]
1777
+ },
1778
+ "unused-svelte-events": {
1779
+ "anyOf": [
1780
+ {
1781
+ "$ref": "#/$defs/Severity"
1782
+ },
1783
+ {
1784
+ "type": "null"
1785
+ }
1786
+ ]
1787
+ },
1734
1788
  "unused-server-actions": {
1735
1789
  "anyOf": [
1736
1790
  {
@@ -1891,6 +1945,16 @@
1891
1945
  }
1892
1946
  ]
1893
1947
  },
1948
+ "require-suppression-reason": {
1949
+ "anyOf": [
1950
+ {
1951
+ "$ref": "#/$defs/Severity"
1952
+ },
1953
+ {
1954
+ "type": "null"
1955
+ }
1956
+ ]
1957
+ },
1894
1958
  "unused-catalog-entries": {
1895
1959
  "anyOf": [
1896
1960
  {
@@ -164,13 +164,16 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
164
164
  | `unrendered-component` | `--unrendered-components` | - | `// fallow-ignore-next-line unrendered-component` | A Vue / Svelte component is reachable through a barrel but rendered nowhere |
165
165
  | `unused-component-prop` | `--unused-component-props` | - | `// fallow-ignore-next-line unused-component-prop` | A Vue defineProps prop or React component prop is referenced nowhere in its own component |
166
166
  | `unused-component-emit` | `--unused-component-emits` | - | `// fallow-ignore-next-line unused-component-emit` | A Vue <script setup> defineEmits event is emitted nowhere in its own component |
167
+ | `unused-component-input` | `--unused-component-inputs` | - | `// fallow-ignore-next-line unused-component-input` | An Angular @Input() / signal input() / model() is read nowhere in its own component (class body or template); needs `@angular/core` dep |
168
+ | `unused-component-output` | `--unused-component-outputs` | - | `// fallow-ignore-next-line unused-component-output` | An Angular @Output() / signal output() is emitted (.emit()) nowhere in its own component; needs `@angular/core` dep |
169
+ | `unused-svelte-event` | `--unused-svelte-events` | - | `// fallow-ignore-next-line unused-svelte-event` | A Svelte createEventDispatcher event is listened to nowhere in the project; needs `svelte` dep |
167
170
  | `unused-server-action` | `--unused-server-actions` | - | `// fallow-ignore-next-line unused-server-action` | A Next.js Server Action exported from a "use server" file is referenced by no code in the project |
168
171
  | `unused-load-data-key` | `--unused-load-data-keys` | - | `// fallow-ignore-next-line unused-load-data-key` | A SvelteKit load() return-object key is read by no consumer (needs @sveltejs/kit dep) |
169
172
  | `prop-drilling` | - | - | `// fallow-ignore-next-line prop-drilling` | A React/Preact prop is forwarded unchanged through 3+ pass-through components to a distant consumer; Opt-in: set rules.prop-drilling to warn or error to enable. Defaults to off. |
170
173
  | `thin-wrapper` | - | - | `// fallow-ignore-next-line thin-wrapper` | A React/Preact component whose whole body is a single spread-forwarded child render (a candidate for inlining); Opt-in: set rules.thin-wrapper to warn or error to enable. Defaults to off. |
171
174
  | `duplicate-prop-shape` | - | - | `// fallow-ignore-next-line duplicate-prop-shape` | Three or more React/Preact components across two or more files declare an identical prop-name set (a missing shared Props type); Opt-in: set rules.duplicate-prop-shape to warn or error to enable. Defaults to off. |
172
- | `route-collision` | - | - | - | Two or more Next.js App Router route files resolve to the same URL |
173
- | `dynamic-segment-name-conflict` | - | - | - | Sibling Next.js dynamic route segments use different slug names at the same position |
175
+ | `route-collision` | - | - | `// fallow-ignore-file route-collision` | Two or more Next.js App Router route files resolve to the same URL |
176
+ | `dynamic-segment-name-conflict` | - | - | `// fallow-ignore-file dynamic-segment-name-conflict` | Sibling Next.js dynamic route segments use different slug names at the same position |
174
177
  | `high-cyclomatic-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has high cyclomatic complexity |
175
178
  | `high-cognitive-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has high cognitive complexity |
176
179
  | `high-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function exceeds both complexity thresholds |
@@ -66,6 +66,9 @@ Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#
66
66
  | `--unrendered-components` | A Vue / Svelte component is reachable through a barrel but rendered nowhere |
67
67
  | `--unused-component-props` | A Vue defineProps prop or React component prop is referenced nowhere in its own component |
68
68
  | `--unused-component-emits` | A Vue <script setup> defineEmits event is emitted nowhere in its own component |
69
+ | `--unused-component-inputs` | An Angular @Input() / signal input() / model() is read nowhere in its own component (class body or template); needs `@angular/core` dep |
70
+ | `--unused-component-outputs` | An Angular @Output() / signal output() is emitted (.emit()) nowhere in its own component; needs `@angular/core` dep |
71
+ | `--unused-svelte-events` | A Svelte createEventDispatcher event is listened to nowhere in the project |
69
72
  | `--unused-server-actions` | A Next.js Server Action exported from a "use server" file is referenced by no code in the project |
70
73
  | `--unused-load-data-keys` | A SvelteKit load() return-object key is read by no consumer |
71
74
  | `--unresolved-imports` | Unresolved imports |
@@ -501,7 +504,7 @@ fallow health --format json --quiet --trend
501
504
  {
502
505
  "kind": "health",
503
506
  "schema_version": 7,
504
- "version": "2.97.0",
507
+ "version": "2.99.0",
505
508
  "elapsed_ms": 32,
506
509
  "summary": {
507
510
  "files_analyzed": 482,
@@ -888,7 +891,7 @@ fallow audit \
888
891
  {
889
892
  "kind": "audit",
890
893
  "schema_version": 7,
891
- "version": "2.97.0",
894
+ "version": "2.99.0",
892
895
  "command": "audit",
893
896
  "verdict": "fail",
894
897
  "changed_files_count": 12,
@@ -963,7 +966,7 @@ fallow flags --format json --quiet --workspace my-package
963
966
  ```json
964
967
  {
965
968
  "schema_version": 7,
966
- "version": "2.97.0",
969
+ "version": "2.99.0",
967
970
  "elapsed_ms": 116,
968
971
  "feature_flags": [],
969
972
  "total_flags": 0
@@ -1063,7 +1066,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1063
1066
  {
1064
1067
  "kind": "security",
1065
1068
  "schema_version": "4",
1066
- "version": "2.97.0",
1069
+ "version": "2.99.0",
1067
1070
  "elapsed_ms": 42,
1068
1071
  "config": {
1069
1072
  "rules": {
@@ -1092,7 +1095,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1092
1095
  {
1093
1096
  "kind": "security",
1094
1097
  "schema_version": "4",
1095
- "version": "2.97.0",
1098
+ "version": "2.99.0",
1096
1099
  "elapsed_ms": 42,
1097
1100
  "config": {
1098
1101
  "rules": {
@@ -1709,7 +1712,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1709
1712
  {
1710
1713
  "kind": "dead-code",
1711
1714
  "schema_version": 7,
1712
- "version": "2.97.0",
1715
+ "version": "2.99.0",
1713
1716
  "elapsed_ms": 45,
1714
1717
  "total_issues": 12,
1715
1718
  "entry_points": {
@@ -1869,7 +1872,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1869
1872
  {
1870
1873
  "kind": "dupes",
1871
1874
  "schema_version": 7,
1872
- "version": "2.97.0",
1875
+ "version": "2.99.0",
1873
1876
  "elapsed_ms": 82,
1874
1877
  "total_clones": 15,
1875
1878
  "total_lines_duplicated": 230,
@@ -1913,11 +1916,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1913
1916
  {
1914
1917
  "kind": "combined",
1915
1918
  "schema_version": 7,
1916
- "version": "2.97.0",
1919
+ "version": "2.99.0",
1917
1920
  "elapsed_ms": 159,
1918
1921
  "check": {
1919
1922
  "schema_version": 7,
1920
- "version": "2.97.0",
1923
+ "version": "2.99.0",
1921
1924
  "elapsed_ms": 45,
1922
1925
  "total_issues": 12,
1923
1926
  "unused_files": [],
@@ -78,6 +78,18 @@ Don't use `--changed-since` when auditing the full project. Use it for PR checks
78
78
 
79
79
  ---
80
80
 
81
+ ## Svelte Event Findings Are Project-Wide Listener Checks
82
+
83
+ `unused-svelte-event` reports a Svelte `createEventDispatcher` event that has no reachable listener in the project. This is different from `unused-component-emit`, which checks whether a Vue component ever emits its declared event.
84
+
85
+ ```bash
86
+ fallow dead-code --format json --quiet --unused-svelte-events
87
+ ```
88
+
89
+ Dynamic event names, dispatcher values that escape the component, and projects without a declared Svelte dependency are abstained to avoid false positives.
90
+
91
+ ---
92
+
81
93
  ## Filter Flags Are Additive
82
94
 
83
95
  Issue type filter flags (`--unused-exports`, `--unused-files`, etc.) are inclusive. They select which issue types to show. Using multiple flags shows the union.
@@ -323,6 +335,10 @@ Conservative semantics: a method carrying any decorator NOT in the list still ge
323
335
 
324
336
  The default empty list preserves today's skip-all behavior, so existing NestJS / Angular / TypeORM projects see no change.
325
337
 
338
+ ### Angular `@Input()` / `@Output()` are still covered by the component rules
339
+
340
+ The skip above applies only to generic `unused-class-member` detection. The dedicated Angular component rules (`unused-component-input` for `@Input()` / signal `input()` / `model()`, and `unused-component-output` for `@Output()` / signal `output()`, both default `warn`, gated on `@angular/core`) scope usage to the component itself: an input is dead when it is read by no code in its own class body or template (inline `template` or external `templateUrl`), and an output is dead when it is emitted (`.emit()`) nowhere in its own component. The scope is the component, not the project: an input that a parent binds via `[input]="..."` but the component itself never reads IS flagged, because the parent binding is satisfied while the value goes unused inside the component. These rules abstain on the whole component for any `extends` clause, a `{...this}` spread, JS-reserved-word names, accessor (`get` / `set`) inputs, and observable-stream `@Output`s (only `new EventEmitter()` initializers are harvested); `model()` is treated as input-only. Suppress an individual finding with `// fallow-ignore-next-line unused-component-input` or `-output`.
341
+
326
342
  ---
327
343
 
328
344
  ## JSDoc Visibility Tags Keep Exports Alive
@@ -138,10 +138,12 @@ export type AuditGate = ("new-only" | "all")
138
138
  * Current per-instance flips:
139
139
  *
140
140
  * - `remove-catalog-entry` (`unused-catalog-entries`): `true` only when the
141
- * finding's `hardcoded_consumers` array is empty. When a workspace
142
- * package still pins a hardcoded version of the same package, `fallow fix`
143
- * skips the entry to avoid breaking `pnpm install`, and the action is
144
- * emitted with `auto_fixable: false`.
141
+ * finding's `hardcoded_consumers` array is empty and the source is
142
+ * `pnpm-workspace.yaml`. When a workspace package still pins a hardcoded
143
+ * version of the same package, `fallow fix` skips the entry to avoid
144
+ * breaking `pnpm install`. Bun `package.json` catalog entries are also
145
+ * emitted with `auto_fixable: false` because the current fixer is
146
+ * YAML-only.
145
147
  * - `remove-dependency` vs `move-dependency` (dependency findings): when the
146
148
  * finding's `used_in_workspaces` array is non-empty, the primary action
147
149
  * flips to `move-dependency` with `auto_fixable: false` (`fallow fix` will
@@ -172,7 +174,7 @@ export type IssueAction = (FixAction | SuppressLineAction | SuppressFileAction |
172
174
  * Discriminant string for [`FixAction`]. Kebab-case per the JSON output
173
175
  * contract.
174
176
  */
175
- 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" | "refactor-cycle" | "refactor-re-export-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" | "resolve-policy-violation" | "move-to-server-module" | "split-mixed-barrel" | "hoist-directive" | "resolve-route-collision" | "resolve-dynamic-segment-name-conflict")
177
+ 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" | "refactor-cycle" | "refactor-re-export-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" | "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")
176
178
  /**
177
179
  * Singleton discriminant for [`SuppressLineAction`].
178
180
  */
@@ -253,6 +255,10 @@ export type SuppressionOrigin = ({
253
255
  * The issue kind token from the comment (e.g., "unused-exports"), or None for blanket.
254
256
  */
255
257
  issue_kind?: (string | null)
258
+ /**
259
+ * Human-authored reason after `--`, when present.
260
+ */
261
+ reason?: (string | null)
256
262
  /**
257
263
  * Whether this was a file-level suppression.
258
264
  */
@@ -272,6 +278,10 @@ type: "comment"
272
278
  * The name of the export that was tagged.
273
279
  */
274
280
  export_name: string
281
+ /**
282
+ * Human-authored reason after `--`, when present.
283
+ */
284
+ reason?: (string | null)
275
285
  type: "jsdoc_tag"
276
286
  })
277
287
  /**
@@ -1032,24 +1042,25 @@ policy_violations?: PolicyViolationFinding[]
1032
1042
  */
1033
1043
  stale_suppressions?: StaleSuppression[]
1034
1044
  /**
1035
- * Entries in pnpm-workspace.yaml's catalog: or catalogs: sections not
1036
- * referenced by any workspace package via the catalog: protocol. Wrapped
1037
- * in [`UnusedCatalogEntryFinding`] so each entry carries a typed
1045
+ * Entries in package manager catalog sections not referenced by any
1046
+ * workspace package via the catalog: protocol. Supports
1047
+ * `pnpm-workspace.yaml` catalogs and Bun root `package.json` catalogs.
1048
+ * Wrapped in [`UnusedCatalogEntryFinding`] so each entry carries a typed
1038
1049
  * `actions` array natively, with per-instance `auto_fixable` derived
1039
- * from `hardcoded_consumers`.
1050
+ * from `hardcoded_consumers` and the catalog source file.
1040
1051
  */
1041
1052
  unused_catalog_entries?: UnusedCatalogEntryFinding[]
1042
1053
  /**
1043
- * Named groups under pnpm-workspace.yaml's catalogs: section that declare
1044
- * no package entries. The top-level catalog: map is not reported. Wrapped
1045
- * in [`EmptyCatalogGroupFinding`].
1054
+ * Named groups under package manager catalogs sections that declare no
1055
+ * package entries. The top-level catalog: map is not reported. Wrapped in
1056
+ * [`EmptyCatalogGroupFinding`].
1046
1057
  */
1047
1058
  empty_catalog_groups?: EmptyCatalogGroupFinding[]
1048
1059
  /**
1049
1060
  * Workspace package.json references to catalogs (`catalog:` or
1050
- * `catalog:<name>`) that do not declare the consumed package. pnpm install
1051
- * will error until the named catalog grows to include the package or the
1052
- * reference is switched / removed. Wrapped in
1061
+ * `catalog:<name>`) that do not declare the consumed package. The package
1062
+ * manager install will error until the named catalog grows to include the
1063
+ * package or the reference is switched / removed. Wrapped in
1053
1064
  * [`UnresolvedCatalogReferenceFinding`] with the discriminated
1054
1065
  * `add-catalog-entry` / `update-catalog-reference` primary at position 0.
1055
1066
  */
@@ -1134,6 +1145,28 @@ unused_component_props?: UnusedComponentPropFinding[]
1134
1145
  * `warn`.
1135
1146
  */
1136
1147
  unused_component_emits?: UnusedComponentEmitFinding[]
1148
+ /**
1149
+ * Angular `@Input()` / signal `input()` / `model()` inputs read nowhere in
1150
+ * their own component (neither the template nor the class body). Wrapped in
1151
+ * [`UnusedComponentInputFinding`] so each entry carries a typed `actions`
1152
+ * array natively. Default severity is `warn`.
1153
+ */
1154
+ unused_component_inputs?: UnusedComponentInputFinding[]
1155
+ /**
1156
+ * Angular `@Output()` / signal `output()` outputs emitted nowhere in their
1157
+ * own component (no `this.<output>.emit(...)`). Wrapped in
1158
+ * [`UnusedComponentOutputFinding`] so each entry carries a typed `actions`
1159
+ * array natively. Default severity is `warn`.
1160
+ */
1161
+ unused_component_outputs?: UnusedComponentOutputFinding[]
1162
+ /**
1163
+ * Svelte components dispatching a custom event via `createEventDispatcher()`
1164
+ * whose event name is listened to nowhere project-wide (cross-file
1165
+ * dead-output direction). Wrapped in [`UnusedSvelteEventFinding`] so each
1166
+ * entry carries a typed `actions` array natively. Default severity is
1167
+ * `warn`.
1168
+ */
1169
+ unused_svelte_events?: UnusedSvelteEventFinding[]
1137
1170
  /**
1138
1171
  * Next.js Server Actions (exports of `"use server"` files) that no code in
1139
1172
  * the project references. Reclassified out of `unused_exports` for
@@ -1277,6 +1310,19 @@ unused_component_props?: number
1277
1310
  * Vue `<script setup>` emits emitted nowhere inside their own SFC.
1278
1311
  */
1279
1312
  unused_component_emits?: number
1313
+ /**
1314
+ * Angular `@Input()` bindings referenced nowhere inside their own component.
1315
+ */
1316
+ unused_component_inputs?: number
1317
+ /**
1318
+ * Angular `@Output()` bindings emitted nowhere inside their own component.
1319
+ */
1320
+ unused_component_outputs?: number
1321
+ /**
1322
+ * Svelte components dispatching a custom event via `createEventDispatcher`
1323
+ * whose name is listened to nowhere in the project.
1324
+ */
1325
+ unused_svelte_events?: number
1280
1326
  /**
1281
1327
  * Next.js Server Actions (exports of `"use server"` files) referenced by no
1282
1328
  * code in the project.
@@ -1417,11 +1463,12 @@ type: FixActionType
1417
1463
  * FINDING, not per action type: the same `type` may carry
1418
1464
  * `auto_fixable: true` on one finding and `auto_fixable: false` on
1419
1465
  * another when per-instance guards in the applier discriminate (e.g.
1420
- * `remove-catalog-entry` flips on `hardcoded_consumers`, the primary
1421
- * dependency action flips between `remove-dependency` /
1422
- * `move-dependency` on `used_in_workspaces`). Filter on this bool of
1423
- * each individual action, not on `type`. See the [`IssueAction`]
1424
- * enum-level docs for the full list of per-instance flips.
1466
+ * `remove-catalog-entry` flips on `hardcoded_consumers` and catalog
1467
+ * source file, the primary dependency action flips between
1468
+ * `remove-dependency` / `move-dependency` on `used_in_workspaces`).
1469
+ * Filter on this bool of each individual action, not on `type`. See the
1470
+ * [`IssueAction`] enum-level docs for the full list of per-instance
1471
+ * flips.
1425
1472
  */
1426
1473
  auto_fixable: boolean
1427
1474
  /**
@@ -2393,12 +2440,20 @@ line: number
2393
2440
  */
2394
2441
  col: number
2395
2442
  origin: SuppressionOrigin
2443
+ /**
2444
+ * True when `rules.require-suppression-reason` reported a suppression
2445
+ * comment or tag that has no reason.
2446
+ */
2447
+ missing_reason?: boolean
2448
+ /**
2449
+ * Suggested next steps. Always emitted.
2450
+ */
2451
+ actions: IssueAction[]
2396
2452
  }
2397
2453
  /**
2398
2454
  * Wire-shape envelope for an [`UnusedCatalogEntry`] finding. Per-instance
2399
- * `auto_fixable` flips to `false` when `hardcoded_consumers` is non-empty:
2400
- * the entry cannot be removed safely while a workspace package still pins
2401
- * the same package via a hardcoded version range.
2455
+ * `auto_fixable` flips to `false` when `hardcoded_consumers` is non-empty or
2456
+ * the source is not `pnpm-workspace.yaml`.
2402
2457
  */
2403
2458
  export interface UnusedCatalogEntryFinding {
2404
2459
  /**
@@ -2406,16 +2461,16 @@ export interface UnusedCatalogEntryFinding {
2406
2461
  */
2407
2462
  entry_name: string
2408
2463
  /**
2409
- * Catalog group: `"default"` for the top-level `catalog:` map, or the
2410
- * named catalog key for entries declared under `catalogs.<name>:`.
2464
+ * Catalog group: `"default"` for the default catalog map, or the named
2465
+ * catalog key for entries declared under `catalogs.<name>`.
2411
2466
  */
2412
2467
  catalog_name: string
2413
2468
  /**
2414
- * Path to `pnpm-workspace.yaml`, relative to the analyzed root.
2469
+ * Path to the catalog source file, relative to the analyzed root.
2415
2470
  */
2416
2471
  path: string
2417
2472
  /**
2418
- * 1-based line number of the catalog entry within `pnpm-workspace.yaml`.
2473
+ * 1-based line number of the catalog entry within the source file.
2419
2474
  */
2420
2475
  line: number
2421
2476
  /**
@@ -2437,20 +2492,20 @@ introduced?: (AuditIntroduced | null)
2437
2492
  }
2438
2493
  /**
2439
2494
  * Wire-shape envelope for an [`EmptyCatalogGroup`] finding. Carries a
2440
- * straightforward `remove-empty-catalog-group` primary plus a YAML-comment
2441
- * suppress.
2495
+ * `remove-empty-catalog-group` primary. YAML-sourced findings also include a
2496
+ * YAML-comment suppress action.
2442
2497
  */
2443
2498
  export interface EmptyCatalogGroupFinding {
2444
2499
  /**
2445
- * Catalog group name declared under the top-level `catalogs:` map.
2500
+ * Catalog group name declared under the `catalogs` map.
2446
2501
  */
2447
2502
  catalog_name: string
2448
2503
  /**
2449
- * Path to `pnpm-workspace.yaml`, relative to the analyzed root.
2504
+ * Path to the catalog source file, relative to the analyzed root.
2450
2505
  */
2451
2506
  path: string
2452
2507
  /**
2453
- * 1-based line number of the empty group header within `pnpm-workspace.yaml`.
2508
+ * 1-based line number of the empty group header within the source file.
2454
2509
  */
2455
2510
  line: number
2456
2511
  /**
@@ -2496,10 +2551,10 @@ path: string
2496
2551
  */
2497
2552
  line: number
2498
2553
  /**
2499
- * Other catalogs (in the same `pnpm-workspace.yaml`) that DO declare this
2500
- * package. Empty when no catalog has the package. Sorted lexicographically.
2501
- * Lets agents and humans decide whether to switch the reference to a
2502
- * different catalog or to add the entry to the named catalog.
2554
+ * Other catalogs in the same catalog source that DO declare this package.
2555
+ * Empty when no catalog has the package. Sorted lexicographically. Lets
2556
+ * agents and humans decide whether to switch the reference to a different
2557
+ * catalog or to add the entry to the named catalog.
2503
2558
  */
2504
2559
  available_in_catalogs?: string[]
2505
2560
  /**
@@ -2745,7 +2800,8 @@ introduced?: (AuditIntroduced | null)
2745
2800
  /**
2746
2801
  * Wire-shape envelope for an [`UnprovidedInject`] finding. There is no safe
2747
2802
  * auto-fix: the fix is binary but judgement-bearing (add a `provide` for the
2748
- * key, or delete the dead inject). The only action is a line-level suppress.
2803
+ * key, or delete the dead inject). Actions are manual remediation guidance
2804
+ * plus a line-level suppress.
2749
2805
  */
2750
2806
  export interface UnprovidedInjectFinding {
2751
2807
  /**
@@ -2782,8 +2838,8 @@ introduced?: (AuditIntroduced | null)
2782
2838
  /**
2783
2839
  * Wire-shape envelope for an [`UnrenderedComponent`] finding. There is no safe
2784
2840
  * auto-fix: the fix is binary but judgement-bearing (render the component
2785
- * somewhere, or delete the dead component). The only action is a line-level
2786
- * suppress.
2841
+ * somewhere, or delete the dead component). Actions are manual remediation
2842
+ * guidance plus a line-level suppress.
2787
2843
  */
2788
2844
  export interface UnrenderedComponentFinding {
2789
2845
  /**
@@ -2915,8 +2971,8 @@ introduced?: (AuditIntroduced | null)
2915
2971
  /**
2916
2972
  * Wire-shape envelope for an [`UnusedComponentProp`] finding. There is no safe
2917
2973
  * auto-fix: removing a declared prop is judgement-bearing (the prop may be part
2918
- * of a deliberately-stable public component API). The only action is a
2919
- * line-level suppress at the prop declaration.
2974
+ * of a deliberately-stable public component API). Actions are manual
2975
+ * remediation guidance plus a line-level suppress at the prop declaration.
2920
2976
  */
2921
2977
  export interface UnusedComponentPropFinding {
2922
2978
  /**
@@ -2953,8 +3009,8 @@ introduced?: (AuditIntroduced | null)
2953
3009
  /**
2954
3010
  * Wire-shape envelope for an [`UnusedComponentEmit`] finding. There is no safe
2955
3011
  * auto-fix: removing a declared emit is judgement-bearing (the event may be
2956
- * part of a deliberately-stable public component API). The only action is a
2957
- * line-level suppress at the emit declaration.
3012
+ * part of a deliberately-stable public component API). Actions are manual
3013
+ * remediation guidance plus a line-level suppress at the emit declaration.
2958
3014
  */
2959
3015
  export interface UnusedComponentEmitFinding {
2960
3016
  /**
@@ -2988,10 +3044,126 @@ actions: IssueAction[]
2988
3044
  */
2989
3045
  introduced?: (AuditIntroduced | null)
2990
3046
  }
3047
+ /**
3048
+ * Wire-shape envelope for an [`UnusedComponentInput`] finding. There is no safe
3049
+ * auto-fix: removing a declared input is judgement-bearing (the input may be
3050
+ * part of a deliberately-stable public component API). The only action is a
3051
+ * line-level suppress at the input declaration.
3052
+ */
3053
+ export interface UnusedComponentInputFinding {
3054
+ /**
3055
+ * The Angular component/directive `.ts` file declaring the unused input.
3056
+ */
3057
+ path: string
3058
+ /**
3059
+ * The component name (the `.ts` file stem).
3060
+ */
3061
+ component_name: string
3062
+ /**
3063
+ * The declared input name that is never read.
3064
+ */
3065
+ input_name: string
3066
+ /**
3067
+ * 1-based line number of the input declaration.
3068
+ */
3069
+ line: number
3070
+ /**
3071
+ * 0-based byte column offset of the input declaration.
3072
+ */
3073
+ col: number
3074
+ /**
3075
+ * Suggested next steps. Always emitted (possibly empty for
3076
+ * forward-compat).
3077
+ */
3078
+ actions: IssueAction[]
3079
+ /**
3080
+ * Set by the audit pass when this finding is introduced relative to
3081
+ * the merge-base.
3082
+ */
3083
+ introduced?: (AuditIntroduced | null)
3084
+ }
3085
+ /**
3086
+ * Wire-shape envelope for an [`UnusedComponentOutput`] finding. There is no safe
3087
+ * auto-fix: removing a declared output is judgement-bearing (the event may be
3088
+ * part of a deliberately-stable public component API). The only action is a
3089
+ * line-level suppress at the output declaration.
3090
+ */
3091
+ export interface UnusedComponentOutputFinding {
3092
+ /**
3093
+ * The Angular component/directive `.ts` file declaring the unused output.
3094
+ */
3095
+ path: string
3096
+ /**
3097
+ * The component name (the `.ts` file stem).
3098
+ */
3099
+ component_name: string
3100
+ /**
3101
+ * The declared output name that is never emitted.
3102
+ */
3103
+ output_name: string
3104
+ /**
3105
+ * 1-based line number of the output declaration.
3106
+ */
3107
+ line: number
3108
+ /**
3109
+ * 0-based byte column offset of the output declaration.
3110
+ */
3111
+ col: number
3112
+ /**
3113
+ * Suggested next steps. Always emitted (possibly empty for
3114
+ * forward-compat).
3115
+ */
3116
+ actions: IssueAction[]
3117
+ /**
3118
+ * Set by the audit pass when this finding is introduced relative to
3119
+ * the merge-base.
3120
+ */
3121
+ introduced?: (AuditIntroduced | null)
3122
+ }
3123
+ /**
3124
+ * Wire-shape envelope for an [`UnusedSvelteEvent`] finding. There is no safe
3125
+ * auto-fix: removing a dispatched event is judgement-bearing (the event may be
3126
+ * part of a deliberately-stable public component API, or a listener may be
3127
+ * added later). Actions are manual remediation guidance plus a line-level
3128
+ * suppress at the `dispatch` call.
3129
+ */
3130
+ export interface UnusedSvelteEventFinding {
3131
+ /**
3132
+ * The `.svelte` component dispatching the unlistened event.
3133
+ */
3134
+ path: string
3135
+ /**
3136
+ * The component name (the `.svelte` file stem).
3137
+ */
3138
+ component_name: string
3139
+ /**
3140
+ * The dispatched event name that is listened to nowhere.
3141
+ */
3142
+ event_name: string
3143
+ /**
3144
+ * 1-based line number of the `dispatch('<name>')` call.
3145
+ */
3146
+ line: number
3147
+ /**
3148
+ * 0-based byte column offset of the `dispatch('<name>')` call.
3149
+ */
3150
+ col: number
3151
+ /**
3152
+ * Suggested next steps. Always emitted (possibly empty for
3153
+ * forward-compat).
3154
+ */
3155
+ actions: IssueAction[]
3156
+ /**
3157
+ * Set by the audit pass when this finding is introduced relative to
3158
+ * the merge-base.
3159
+ */
3160
+ introduced?: (AuditIntroduced | null)
3161
+ }
2991
3162
  /**
2992
3163
  * Wire-shape envelope for an [`UnusedServerAction`] finding. There is no safe
2993
3164
  * auto-fix: the fix is binary but judgement-bearing (wire the action up to a
2994
- * consumer, or delete it). The only action is a line-level suppress.
3165
+ * consumer, or delete it). Actions are manual remediation guidance plus a
3166
+ * line-level suppress.
2995
3167
  */
2996
3168
  export interface UnusedServerActionFinding {
2997
3169
  /**
@@ -3024,7 +3196,8 @@ introduced?: (AuditIntroduced | null)
3024
3196
  /**
3025
3197
  * Wire-shape envelope for an [`UnusedLoadDataKey`] finding. There is no safe
3026
3198
  * auto-fix: a `load()` fetch can have side effects, so deleting the key is a
3027
- * human call. The only action is a line-level suppress.
3199
+ * human call. Actions are manual remediation guidance plus a line-level
3200
+ * suppress.
3028
3201
  */
3029
3202
  export interface UnusedLoadDataKeyFinding {
3030
3203
  /**
@@ -6964,24 +7137,25 @@ policy_violations?: PolicyViolationFinding[]
6964
7137
  */
6965
7138
  stale_suppressions?: StaleSuppression[]
6966
7139
  /**
6967
- * Entries in pnpm-workspace.yaml's catalog: or catalogs: sections not
6968
- * referenced by any workspace package via the catalog: protocol. Wrapped
6969
- * in [`UnusedCatalogEntryFinding`] so each entry carries a typed
7140
+ * Entries in package manager catalog sections not referenced by any
7141
+ * workspace package via the catalog: protocol. Supports
7142
+ * `pnpm-workspace.yaml` catalogs and Bun root `package.json` catalogs.
7143
+ * Wrapped in [`UnusedCatalogEntryFinding`] so each entry carries a typed
6970
7144
  * `actions` array natively, with per-instance `auto_fixable` derived
6971
- * from `hardcoded_consumers`.
7145
+ * from `hardcoded_consumers` and the catalog source file.
6972
7146
  */
6973
7147
  unused_catalog_entries?: UnusedCatalogEntryFinding[]
6974
7148
  /**
6975
- * Named groups under pnpm-workspace.yaml's catalogs: section that declare
6976
- * no package entries. The top-level catalog: map is not reported. Wrapped
6977
- * in [`EmptyCatalogGroupFinding`].
7149
+ * Named groups under package manager catalogs sections that declare no
7150
+ * package entries. The top-level catalog: map is not reported. Wrapped in
7151
+ * [`EmptyCatalogGroupFinding`].
6978
7152
  */
6979
7153
  empty_catalog_groups?: EmptyCatalogGroupFinding[]
6980
7154
  /**
6981
7155
  * Workspace package.json references to catalogs (`catalog:` or
6982
- * `catalog:<name>`) that do not declare the consumed package. pnpm install
6983
- * will error until the named catalog grows to include the package or the
6984
- * reference is switched / removed. Wrapped in
7156
+ * `catalog:<name>`) that do not declare the consumed package. The package
7157
+ * manager install will error until the named catalog grows to include the
7158
+ * package or the reference is switched / removed. Wrapped in
6985
7159
  * [`UnresolvedCatalogReferenceFinding`] with the discriminated
6986
7160
  * `add-catalog-entry` / `update-catalog-reference` primary at position 0.
6987
7161
  */
@@ -7066,6 +7240,28 @@ unused_component_props?: UnusedComponentPropFinding[]
7066
7240
  * `warn`.
7067
7241
  */
7068
7242
  unused_component_emits?: UnusedComponentEmitFinding[]
7243
+ /**
7244
+ * Angular `@Input()` / signal `input()` / `model()` inputs read nowhere in
7245
+ * their own component (neither the template nor the class body). Wrapped in
7246
+ * [`UnusedComponentInputFinding`] so each entry carries a typed `actions`
7247
+ * array natively. Default severity is `warn`.
7248
+ */
7249
+ unused_component_inputs?: UnusedComponentInputFinding[]
7250
+ /**
7251
+ * Angular `@Output()` / signal `output()` outputs emitted nowhere in their
7252
+ * own component (no `this.<output>.emit(...)`). Wrapped in
7253
+ * [`UnusedComponentOutputFinding`] so each entry carries a typed `actions`
7254
+ * array natively. Default severity is `warn`.
7255
+ */
7256
+ unused_component_outputs?: UnusedComponentOutputFinding[]
7257
+ /**
7258
+ * Svelte components dispatching a custom event via `createEventDispatcher()`
7259
+ * whose event name is listened to nowhere project-wide (cross-file
7260
+ * dead-output direction). Wrapped in [`UnusedSvelteEventFinding`] so each
7261
+ * entry carries a typed `actions` array natively. Default severity is
7262
+ * `warn`.
7263
+ */
7264
+ unused_svelte_events?: UnusedSvelteEventFinding[]
7069
7265
  /**
7070
7266
  * Next.js Server Actions (exports of `"use server"` files) that no code in
7071
7267
  * the project references. Reclassified out of `unused_exports` for