fallow 3.28.0 → 3.30.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/capabilities.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.28.0",
3
+ "version": "3.30.0",
4
4
  "manifest_version": "1",
5
5
  "description": "Codebase analyzer for TypeScript/JavaScript: unused code, circular dependencies, code duplication, complexity hotspots, and architecture boundary violations",
6
6
  "global_flags": [
@@ -132,7 +132,7 @@
132
132
  "name": "--baseline",
133
133
  "type": "string",
134
134
  "required": false,
135
- "description": "Compare against a previously saved baseline file"
135
+ "description": "Compare against a previously saved baseline file. Used by bare `fallow`, `dead-code`, `dupes` and `health`; other subcommands reject it"
136
136
  },
137
137
  {
138
138
  "name": "--baseline-mode",
@@ -154,7 +154,7 @@
154
154
  "name": "--save-baseline",
155
155
  "type": "string",
156
156
  "required": false,
157
- "description": "Save the current results as a baseline file"
157
+ "description": "Save the current results as a baseline file. Used by bare `fallow`, `dead-code`, `dupes` and `health`; other subcommands reject it. The path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
158
158
  },
159
159
  {
160
160
  "name": "--production",
@@ -295,13 +295,13 @@
295
295
  "name": "--sarif-file",
296
296
  "type": "string",
297
297
  "required": false,
298
- "description": "Write SARIF output to a file (in addition to the primary --format output)"
298
+ "description": "Write SARIF output to a file (in addition to the primary --format output). Used by bare `fallow`, `dead-code` and `security`. The path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
299
299
  },
300
300
  {
301
301
  "name": "--output-file",
302
302
  "type": "string",
303
303
  "required": false,
304
- "description": "Write the report to a file instead of stdout, for any --format (no ANSI codes). Useful on large projects where the terminal scrollback truncates the top. Progress and the confirmation stay on stderr",
304
+ "description": "Write the report to a file instead of stdout, for any --format (no ANSI codes). Useful on large projects where the terminal scrollback truncates the top. Progress and the confirmation stay on stderr. The path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory",
305
305
  "short": "-o"
306
306
  },
307
307
  {
@@ -330,6 +330,16 @@
330
330
  "false"
331
331
  ]
332
332
  },
333
+ {
334
+ "name": "--fail-on-parse-error",
335
+ "type": "bool",
336
+ "required": false,
337
+ "description": "Exit with code 1 if fallow could not parse a source file cleanly",
338
+ "possible_values": [
339
+ "true",
340
+ "false"
341
+ ]
342
+ },
333
343
  {
334
344
  "name": "--tolerance",
335
345
  "type": "string",
@@ -347,7 +357,7 @@
347
357
  "name": "--save-regression-baseline",
348
358
  "type": "string",
349
359
  "required": false,
350
- "description": "Save the current issue counts as a regression baseline. Omit PATH to update regression.baseline in the discovered fallow config, or create .fallowrc.json when none exists. Provide PATH to write a standalone file"
360
+ "description": "Save the current issue counts as a regression baseline. Omit PATH to update regression.baseline in the discovered fallow config, or create .fallowrc.json when none exists. Provide PATH to write a standalone file; PATH must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
351
361
  },
352
362
  {
353
363
  "name": "--only",
@@ -481,13 +491,13 @@
481
491
  "name": "--save-snapshot",
482
492
  "type": "string",
483
493
  "required": false,
484
- "description": "Save a vital signs snapshot for trend tracking in combined mode. Provide a path or omit for the default `.fallow/snapshots/` location"
494
+ "description": "Save a vital signs snapshot for trend tracking in combined mode. Provide a path or omit for the default `.fallow/snapshots/` location. A given path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
485
495
  },
486
496
  {
487
497
  "name": "--coverage",
488
498
  "type": "string",
489
499
  "required": false,
490
- "description": "Path to Istanbul coverage data for exact CRAP scores in combined mode. Also settable via `FALLOW_COVERAGE` or `health.coverage`"
500
+ "description": "Path to Istanbul or raw V8 coverage data for exact CRAP scores in combined mode. Also settable via `FALLOW_COVERAGE` or `health.coverage`"
491
501
  },
492
502
  {
493
503
  "name": "--coverage-root",
@@ -495,6 +505,18 @@
495
505
  "required": false,
496
506
  "description": "Absolute prefix to strip from Istanbul file paths in combined mode. Also settable via `FALLOW_COVERAGE_ROOT` or `health.coverageRoot`"
497
507
  },
508
+ {
509
+ "name": "--dupes-baseline",
510
+ "type": "string",
511
+ "required": false,
512
+ "description": "Compare duplication clone groups against a saved baseline in combined mode (produced by `fallow dupes --save-baseline`)"
513
+ },
514
+ {
515
+ "name": "--health-baseline",
516
+ "type": "string",
517
+ "required": false,
518
+ "description": "Compare health findings against a saved baseline in combined mode (produced by `fallow health --save-baseline`)"
519
+ },
498
520
  {
499
521
  "name": "--include-entry-exports",
500
522
  "type": "bool",
@@ -597,6 +619,16 @@
597
619
  "false"
598
620
  ]
599
621
  },
622
+ {
623
+ "name": "--deprecated-exports-in-use",
624
+ "type": "bool",
625
+ "required": false,
626
+ "description": "Opt in to `@deprecated` exports that are still in use and only report that issue type",
627
+ "possible_values": [
628
+ "true",
629
+ "false"
630
+ ]
631
+ },
600
632
  {
601
633
  "name": "--unused-enum-members",
602
634
  "type": "bool",
@@ -1023,6 +1055,16 @@
1023
1055
  "required": false,
1024
1056
  "description": "Shortest import path between two modules, as two file paths (e.g. `--path src/app.ts src/db.ts`). Mutually exclusive with the symbol target and the call-chain flags"
1025
1057
  },
1058
+ {
1059
+ "name": "--eager-only",
1060
+ "type": "bool",
1061
+ "required": false,
1062
+ "description": "With `--path`, follow only static value imports, so the route explains why TO loads before FROM runs",
1063
+ "possible_values": [
1064
+ "true",
1065
+ "false"
1066
+ ]
1067
+ },
1026
1068
  {
1027
1069
  "name": "--callers",
1028
1070
  "type": "bool",
@@ -1232,7 +1274,7 @@
1232
1274
  },
1233
1275
  {
1234
1276
  "name": "list",
1235
- "description": "List discovered entry points, files, plugins, boundaries, and workspaces",
1277
+ "description": "List discovered entry points, files, plugins, boundaries, workspaces, and the startup import weight",
1236
1278
  "flags": [
1237
1279
  {
1238
1280
  "name": "--entry-points",
@@ -1284,6 +1326,16 @@
1284
1326
  "false"
1285
1327
  ]
1286
1328
  },
1329
+ {
1330
+ "name": "--entry-weight",
1331
+ "type": "bool",
1332
+ "required": false,
1333
+ "description": "Show the startup import weight of each runtime entry point, in source bytes (not bundle size)",
1334
+ "possible_values": [
1335
+ "true",
1336
+ "false"
1337
+ ]
1338
+ },
1287
1339
  {
1288
1340
  "name": "path",
1289
1341
  "type": "string",
@@ -1591,7 +1643,7 @@
1591
1643
  "name": "--min-severity",
1592
1644
  "type": "string",
1593
1645
  "required": false,
1594
- "description": "Only exit with error for findings at or above this severity. Use --min-severity critical to ignore moderate/high findings in CI. Composes with --min-score (the run fails if either gate trips)",
1646
+ "description": "Only exit with error for findings at or above this severity. Use --min-severity critical to ignore moderate/high findings in CI. Composes with --min-score (the run fails if either gate trips). The complexity-* rules apply first: a finding whose rule is warn never fails the run, whatever its severity",
1595
1647
  "possible_values": [
1596
1648
  "moderate",
1597
1649
  "high",
@@ -1624,7 +1676,7 @@
1624
1676
  "name": "--save-snapshot",
1625
1677
  "type": "string",
1626
1678
  "required": false,
1627
- "description": "Save a vital signs snapshot for trend tracking. Defaults to `.fallow/snapshots/{timestamp}.json` if no path is given. Forces file-scores, hotspot, and score computation for complete metrics"
1679
+ "description": "Save a vital signs snapshot for trend tracking. Defaults to `.fallow/snapshots/{timestamp}.json` if no path is given. A given path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory. Forces file-scores, hotspot, and score computation for complete metrics"
1628
1680
  },
1629
1681
  {
1630
1682
  "name": "--trend",
@@ -1640,7 +1692,7 @@
1640
1692
  "name": "--coverage",
1641
1693
  "type": "string",
1642
1694
  "required": false,
1643
- "description": "Path to coverage data (coverage-final.json) for exact per-function CRAP scores. Generate with `jest --coverage`, `vitest run --coverage --provider istanbul`, or any Istanbul-compatible tool. Requires Istanbul format (not v8/c8 native format). Accepts a single Istanbul coverage map JSON file or a directory containing coverage-final.json. Use --coverage-root when the file was generated in a different environment (CI runner, Docker). Affects CRAP scores only, not --coverage-gaps. Also configurable via FALLOW_COVERAGE env var"
1695
+ "description": "Path to coverage data for exact per-function CRAP scores. Accepts an Istanbul coverage map JSON file (coverage-final.json, from `jest --coverage`, `vitest run --coverage`, c8 or nyc), a directory containing coverage-final.json, a raw V8 coverage directory (`NODE_V8_COVERAGE=<dir> node --test`), or a single V8 coverage JSON file. Transpiled V8 scripts (tsx, bundles) map back to their source files through the source map that Node records in the dump. A script that differs from the file on disk and has no source map keeps the estimate. Use --coverage-root when the data was generated in a different environment (CI runner, Docker). Affects CRAP scores only, not --coverage-gaps. Also configurable via FALLOW_COVERAGE env var"
1644
1696
  },
1645
1697
  {
1646
1698
  "name": "--coverage-root",
@@ -1652,7 +1704,7 @@
1652
1704
  "name": "--runtime-coverage",
1653
1705
  "type": "string",
1654
1706
  "required": false,
1655
- "description": "File or directory containing runtime coverage input. Accepts a V8 coverage directory, a single V8 JSON file, or a single Istanbul coverage map JSON file (commonly coverage-final.json)"
1707
+ "description": "File or directory containing runtime coverage input. Accepts a V8 coverage directory, a single V8 JSON file, or a single Istanbul coverage map JSON file (commonly coverage-final.json). A single local capture is free. Continuous or multi-capture monitoring needs a license (see `fallow license`)"
1656
1708
  },
1657
1709
  {
1658
1710
  "name": "--min-invocations-hot",
@@ -1690,6 +1742,77 @@
1690
1742
  "type": "string",
1691
1743
  "required": false,
1692
1744
  "description": "Show only the top N flags"
1745
+ },
1746
+ {
1747
+ "name": "--retirement",
1748
+ "type": "bool",
1749
+ "required": false,
1750
+ "description": "Add a retirement report: one row per flag, with the reasons the flag can be retired. Advisory only; nothing is removed",
1751
+ "possible_values": [
1752
+ "true",
1753
+ "false"
1754
+ ]
1755
+ },
1756
+ {
1757
+ "name": "--reason",
1758
+ "type": "string",
1759
+ "required": false,
1760
+ "description": "Keep only retirement rows with this reason (repeatable)",
1761
+ "possible_values": [
1762
+ "single-read-site",
1763
+ "test-only",
1764
+ "literal-constant",
1765
+ "identical-branches",
1766
+ "empty-branch",
1767
+ "guards-dead-code",
1768
+ "defined-never-read",
1769
+ "fully-rolled-out",
1770
+ "archived-in-vendor",
1771
+ "missing-in-vendor",
1772
+ "vendor-only"
1773
+ ]
1774
+ },
1775
+ {
1776
+ "name": "--sort",
1777
+ "type": "string",
1778
+ "required": false,
1779
+ "description": "Order of the retirement rows",
1780
+ "default": "age",
1781
+ "possible_values": [
1782
+ "age",
1783
+ "sites",
1784
+ "name"
1785
+ ]
1786
+ },
1787
+ {
1788
+ "name": "--flag-age",
1789
+ "type": "string",
1790
+ "required": false,
1791
+ "description": "How to measure flag age: blame (lower bound), pickaxe (first commit with the name, slower) or off",
1792
+ "default": "blame",
1793
+ "possible_values": [
1794
+ "blame",
1795
+ "pickaxe",
1796
+ "off"
1797
+ ]
1798
+ },
1799
+ {
1800
+ "name": "--min-age",
1801
+ "type": "string",
1802
+ "required": false,
1803
+ "description": "Keep only retirement rows at least this many days old"
1804
+ },
1805
+ {
1806
+ "name": "--flag-state",
1807
+ "type": "string",
1808
+ "required": false,
1809
+ "description": "Vendor flag export (JSON, read offline) that adds the fully-rolled-out, archived-in-vendor, missing-in-vendor and vendor-only reasons"
1810
+ },
1811
+ {
1812
+ "name": "--max-flag-age",
1813
+ "type": "string",
1814
+ "required": false,
1815
+ "description": "Exit with code 1 when a flag in scope is older than this many days. Opt-in; needs a flag age"
1693
1816
  }
1694
1817
  ]
1695
1818
  },
@@ -1779,7 +1902,7 @@
1779
1902
  "name": "--coverage",
1780
1903
  "type": "string",
1781
1904
  "required": false,
1782
- "description": "Path to Istanbul-format coverage data (coverage-final.json) for accurate per-function CRAP scores in the health sub-analysis. Also configurable via FALLOW_COVERAGE or health.coverage"
1905
+ "description": "Path to Istanbul coverage data (coverage-final.json) or raw V8 coverage (a `NODE_V8_COVERAGE` directory or one V8 JSON file) for accurate per-function CRAP scores in the health sub-analysis. Also configurable via FALLOW_COVERAGE or health.coverage"
1783
1906
  },
1784
1907
  {
1785
1908
  "name": "--coverage-root",
@@ -1831,7 +1954,7 @@
1831
1954
  "name": "--runtime-coverage",
1832
1955
  "type": "string",
1833
1956
  "required": false,
1834
- "description": "Paid runtime-coverage sidecar input. Accepts a V8 directory, a single V8 JSON file, or an Istanbul coverage map JSON. Spawns the `fallow-cov` sidecar as part of the audit pipeline so the `hot-path-touched` verdict surfaces alongside dead-code and complexity findings without requiring a second `fallow health` invocation in CI. License-gated; the verdict is informational (no exit code change) until a future `--gate hot-path-touched` knob lands"
1957
+ "description": "Runtime coverage input. Accepts a V8 directory, a single V8 JSON file, or an Istanbul coverage map JSON. Runs the `fallow-cov` sidecar inside the audit, so the `hot-path-touched` verdict shows next to the dead-code and complexity findings without a second `fallow health` run in CI. The verdict is informational and does not change the exit code. A single local capture is free. Continuous or multi-capture monitoring needs a license (see `fallow license`)"
1835
1958
  },
1836
1959
  {
1837
1960
  "name": "--min-invocations-hot",
@@ -1984,7 +2107,7 @@
1984
2107
  "name": "--runtime-coverage",
1985
2108
  "type": "string",
1986
2109
  "required": false,
1987
- "description": "Paid runtime-coverage sidecar input. Accepts a V8 directory, a single V8 JSON file, or an Istanbul coverage map JSON. When set, `fallow security` annotates tainted-sink candidates with production runtime state and uses that state as an additive ranking signal"
2110
+ "description": "Runtime coverage input. Accepts a V8 directory, a single V8 JSON file, or an Istanbul coverage map JSON. When set, `fallow security` adds production runtime state to tainted-sink candidates and uses that state as an extra ranking signal. A single local capture is free. Continuous or multi-capture monitoring needs a license (see `fallow license`)"
1988
2111
  },
1989
2112
  {
1990
2113
  "name": "--min-invocations-hot",
@@ -2355,6 +2478,43 @@
2355
2478
  "license_note": null,
2356
2479
  "docs_url": "https://docs.fallow.tools/explanations/dead-code#private-type-leaks"
2357
2480
  },
2481
+ {
2482
+ "id": "deprecated-export-in-use",
2483
+ "rule_id": "fallow/deprecated-export-in-use",
2484
+ "command": "dead-code",
2485
+ "category": "Dead code",
2486
+ "description": "Export marked @deprecated is still referenced",
2487
+ "label": "Deprecated Exports in Use",
2488
+ "config_key": "deprecated-exports-in-use",
2489
+ "registry_index": 5,
2490
+ "aliases": [],
2491
+ "lsp": false,
2492
+ "filter_flag": "--deprecated-exports-in-use",
2493
+ "result_key": "deprecated_exports_in_use",
2494
+ "summary_label": "Deprecated exports in use",
2495
+ "summary_docs_anchor": "deprecated-exports-in-use",
2496
+ "sarif_rule_ids": [
2497
+ "fallow/deprecated-export-in-use"
2498
+ ],
2499
+ "codeclimate_check_names": [
2500
+ "fallow/deprecated-export-in-use"
2501
+ ],
2502
+ "ts_alias": {
2503
+ "name": "DeprecatedExportInUse",
2504
+ "parent": "DeprecatedExportInUseFinding"
2505
+ },
2506
+ "counts_in_total": true,
2507
+ "fixable": false,
2508
+ "suppressible": true,
2509
+ "suppress_comment": "// fallow-ignore-next-line deprecated-export-in-use",
2510
+ "default_severity": "off",
2511
+ "opt_in": true,
2512
+ "frameworks": [],
2513
+ "note": "Opt-in migration sweep; the rule defaults to off",
2514
+ "license": "free",
2515
+ "license_note": null,
2516
+ "docs_url": "https://docs.fallow.tools/explanations/dead-code#deprecated-exports-in-use"
2517
+ },
2358
2518
  {
2359
2519
  "id": "unused-dependency",
2360
2520
  "rule_id": "fallow/unused-dependency",
@@ -2363,7 +2523,7 @@
2363
2523
  "description": "Dependency listed but never imported",
2364
2524
  "label": "Unused Dependencies",
2365
2525
  "config_key": "unused-dependencies",
2366
- "registry_index": 5,
2526
+ "registry_index": 6,
2367
2527
  "aliases": [],
2368
2528
  "lsp": true,
2369
2529
  "filter_flag": "--unused-deps",
@@ -2400,7 +2560,7 @@
2400
2560
  "description": "Dev dependency listed but never imported",
2401
2561
  "label": "Unused Dev Dependencies",
2402
2562
  "config_key": "unused-dev-dependencies",
2403
- "registry_index": 6,
2563
+ "registry_index": 7,
2404
2564
  "aliases": [
2405
2565
  "unused-dev-deps",
2406
2566
  "unused-dev-dependencies"
@@ -2440,7 +2600,7 @@
2440
2600
  "description": "Optional dependency listed but never imported",
2441
2601
  "label": "Unused Optional Dependencies",
2442
2602
  "config_key": "unused-optional-dependencies",
2443
- "registry_index": 7,
2603
+ "registry_index": 8,
2444
2604
  "aliases": [
2445
2605
  "unused-optional-deps",
2446
2606
  "unused-optional-dependencies"
@@ -2480,7 +2640,7 @@
2480
2640
  "description": "Production dependency only used via type-only imports",
2481
2641
  "label": "Type-Only Dependencies",
2482
2642
  "config_key": "type-only-dependencies",
2483
- "registry_index": 14,
2643
+ "registry_index": 15,
2484
2644
  "aliases": [],
2485
2645
  "lsp": true,
2486
2646
  "filter_flag": "--unused-deps",
@@ -2517,7 +2677,7 @@
2517
2677
  "description": "Production dependency only imported by test files",
2518
2678
  "label": "Test-Only Dependencies",
2519
2679
  "config_key": "test-only-dependencies",
2520
- "registry_index": 15,
2680
+ "registry_index": 16,
2521
2681
  "aliases": [],
2522
2682
  "lsp": true,
2523
2683
  "filter_flag": "--unused-deps",
@@ -2554,7 +2714,7 @@
2554
2714
  "description": "devDependency imported by production code with a runtime import",
2555
2715
  "label": "Dev Dependencies Used in Production",
2556
2716
  "config_key": "dev-dependencies-in-production",
2557
- "registry_index": 16,
2717
+ "registry_index": 17,
2558
2718
  "aliases": [],
2559
2719
  "lsp": true,
2560
2720
  "filter_flag": "--unused-deps",
@@ -2591,7 +2751,7 @@
2591
2751
  "description": "Enum member is never referenced",
2592
2752
  "label": "Unused Enum Members",
2593
2753
  "config_key": "unused-enum-members",
2594
- "registry_index": 8,
2754
+ "registry_index": 9,
2595
2755
  "aliases": [],
2596
2756
  "lsp": true,
2597
2757
  "filter_flag": "--unused-enum-members",
@@ -2628,7 +2788,7 @@
2628
2788
  "description": "Class member is never referenced",
2629
2789
  "label": "Unused Class Members",
2630
2790
  "config_key": "unused-class-members",
2631
- "registry_index": 9,
2791
+ "registry_index": 10,
2632
2792
  "aliases": [],
2633
2793
  "lsp": true,
2634
2794
  "filter_flag": "--unused-class-members",
@@ -2665,7 +2825,7 @@
2665
2825
  "description": "Store member is never accessed by any consumer",
2666
2826
  "label": "Unused Store Members",
2667
2827
  "config_key": "unused-store-members",
2668
- "registry_index": 10,
2828
+ "registry_index": 11,
2669
2829
  "aliases": [
2670
2830
  "unused-store-members"
2671
2831
  ],
@@ -2704,7 +2864,7 @@
2704
2864
  "description": "Import could not be resolved",
2705
2865
  "label": "Unresolved Imports",
2706
2866
  "config_key": "unresolved-imports",
2707
- "registry_index": 11,
2867
+ "registry_index": 12,
2708
2868
  "aliases": [],
2709
2869
  "lsp": true,
2710
2870
  "filter_flag": "--unresolved-imports",
@@ -2741,7 +2901,7 @@
2741
2901
  "description": "Dependency used but not in package.json",
2742
2902
  "label": "Unlisted Dependencies",
2743
2903
  "config_key": "unlisted-dependencies",
2744
- "registry_index": 12,
2904
+ "registry_index": 13,
2745
2905
  "aliases": [],
2746
2906
  "lsp": true,
2747
2907
  "filter_flag": "--unlisted-deps",
@@ -2778,7 +2938,7 @@
2778
2938
  "description": "Export name appears in multiple modules",
2779
2939
  "label": "Duplicate Exports",
2780
2940
  "config_key": "duplicate-exports",
2781
- "registry_index": 13,
2941
+ "registry_index": 14,
2782
2942
  "aliases": [],
2783
2943
  "lsp": true,
2784
2944
  "filter_flag": "--duplicate-exports",
@@ -2815,7 +2975,7 @@
2815
2975
  "description": "Circular dependency chain detected",
2816
2976
  "label": "Circular Dependencies",
2817
2977
  "config_key": "circular-dependencies",
2818
- "registry_index": 17,
2978
+ "registry_index": 18,
2819
2979
  "aliases": [
2820
2980
  "circular-dependencies"
2821
2981
  ],
@@ -2854,7 +3014,7 @@
2854
3014
  "description": "Two or more barrel files re-export from each other in a loop",
2855
3015
  "label": "Re-Export Cycles",
2856
3016
  "config_key": "re-export-cycle",
2857
- "registry_index": 18,
3017
+ "registry_index": 19,
2858
3018
  "aliases": [
2859
3019
  "re-export-cycles",
2860
3020
  "reexport-cycle",
@@ -2895,7 +3055,7 @@
2895
3055
  "description": "Import crosses a configured architecture boundary",
2896
3056
  "label": "Boundary Violations",
2897
3057
  "config_key": "boundary-violation",
2898
- "registry_index": 19,
3058
+ "registry_index": 20,
2899
3059
  "aliases": [],
2900
3060
  "lsp": true,
2901
3061
  "filter_flag": "--boundary-violations",
@@ -2932,7 +3092,7 @@
2932
3092
  "description": "Source file matches no configured architecture boundary zone",
2933
3093
  "label": "Boundary Coverage",
2934
3094
  "config_key": "boundary-violation",
2935
- "registry_index": 20,
3095
+ "registry_index": 21,
2936
3096
  "aliases": [
2937
3097
  "boundary-coverage-violations"
2938
3098
  ],
@@ -2968,7 +3128,7 @@
2968
3128
  "description": "Zoned file calls a callee its zone forbids",
2969
3129
  "label": "Boundary Call Violations",
2970
3130
  "config_key": "boundary-violation",
2971
- "registry_index": 21,
3131
+ "registry_index": 22,
2972
3132
  "aliases": [
2973
3133
  "boundary-calls",
2974
3134
  "boundary-call-violations"
@@ -3005,7 +3165,7 @@
3005
3165
  "description": "Banned usage matched a rule-pack rule",
3006
3166
  "label": "Policy Violations",
3007
3167
  "config_key": "policy-violation",
3008
- "registry_index": 22,
3168
+ "registry_index": 23,
3009
3169
  "aliases": [
3010
3170
  "policy-violations"
3011
3171
  ],
@@ -3041,7 +3201,7 @@
3041
3201
  "description": "Suppression comment or tag no longer matches any issue",
3042
3202
  "label": "Stale Suppressions",
3043
3203
  "config_key": "stale-suppressions",
3044
- "registry_index": 37,
3204
+ "registry_index": 38,
3045
3205
  "aliases": [],
3046
3206
  "lsp": true,
3047
3207
  "filter_flag": "--stale-suppressions",
@@ -3077,7 +3237,7 @@
3077
3237
  "description": "Suppression comment omits a required reason",
3078
3238
  "label": "Missing Suppression Reasons",
3079
3239
  "config_key": "require-suppression-reason",
3080
- "registry_index": 38,
3240
+ "registry_index": 39,
3081
3241
  "aliases": [
3082
3242
  "missing-suppression-reasons"
3083
3243
  ],
@@ -3109,7 +3269,7 @@
3109
3269
  "description": "Catalog entry not referenced by any workspace package",
3110
3270
  "label": "Unused Catalog Entries",
3111
3271
  "config_key": "unused-catalog-entries",
3112
- "registry_index": 39,
3272
+ "registry_index": 40,
3113
3273
  "aliases": [
3114
3274
  "catalog",
3115
3275
  "unused-catalog-entries"
@@ -3149,7 +3309,7 @@
3149
3309
  "description": "Named catalog group has no entries",
3150
3310
  "label": "Empty Catalog Groups",
3151
3311
  "config_key": "empty-catalog-groups",
3152
- "registry_index": 40,
3312
+ "registry_index": 41,
3153
3313
  "aliases": [
3154
3314
  "empty-catalog",
3155
3315
  "empty-catalog-groups"
@@ -3189,7 +3349,7 @@
3189
3349
  "description": "package.json references a catalog that does not declare the package",
3190
3350
  "label": "Unresolved Catalog References",
3191
3351
  "config_key": "unresolved-catalog-references",
3192
- "registry_index": 41,
3352
+ "registry_index": 42,
3193
3353
  "aliases": [
3194
3354
  "unresolved-catalog",
3195
3355
  "unresolved-catalog-references"
@@ -3229,7 +3389,7 @@
3229
3389
  "description": "Package-manager override target is not declared or resolved",
3230
3390
  "label": "Unused Dependency Overrides",
3231
3391
  "config_key": "unused-dependency-overrides",
3232
- "registry_index": 42,
3392
+ "registry_index": 43,
3233
3393
  "aliases": [
3234
3394
  "unused-dependency-overrides",
3235
3395
  "unused-override",
@@ -3270,7 +3430,7 @@
3270
3430
  "description": "Package-manager override has an unparsable key or value",
3271
3431
  "label": "Misconfigured Dependency Overrides",
3272
3432
  "config_key": "misconfigured-dependency-overrides",
3273
- "registry_index": 43,
3433
+ "registry_index": 44,
3274
3434
  "aliases": [
3275
3435
  "misconfigured-dependency-overrides",
3276
3436
  "misconfigured-override",
@@ -3311,7 +3471,7 @@
3311
3471
  "description": "\"use client\" file exports a server-only / route-config name",
3312
3472
  "label": "Invalid Client Exports",
3313
3473
  "config_key": "invalid-client-export",
3314
- "registry_index": 23,
3474
+ "registry_index": 24,
3315
3475
  "aliases": [
3316
3476
  "invalid-client-exports"
3317
3477
  ],
@@ -3349,7 +3509,7 @@
3349
3509
  "description": "Barrel re-exports both a \"use client\" module and a server-only module",
3350
3510
  "label": "Mixed Client/Server Barrels",
3351
3511
  "config_key": "mixed-client-server-barrel",
3352
- "registry_index": 24,
3512
+ "registry_index": 25,
3353
3513
  "aliases": [
3354
3514
  "mixed-client-server-barrels"
3355
3515
  ],
@@ -3385,7 +3545,7 @@
3385
3545
  "description": "\"use client\" / \"use server\" directive is not in the leading position and is ignored",
3386
3546
  "label": "Misplaced Directives",
3387
3547
  "config_key": "misplaced-directive",
3388
- "registry_index": 25,
3548
+ "registry_index": 26,
3389
3549
  "aliases": [
3390
3550
  "misplaced-directives"
3391
3551
  ],
@@ -3421,7 +3581,7 @@
3421
3581
  "description": "inject() / getContext() reads a key that no provide() / setContext() supplies",
3422
3582
  "label": "Unprovided Injects",
3423
3583
  "config_key": "unprovided-injects",
3424
- "registry_index": 26,
3584
+ "registry_index": 27,
3425
3585
  "aliases": [
3426
3586
  "unprovided-injects"
3427
3587
  ],
@@ -3457,7 +3617,7 @@
3457
3617
  "description": "A Vue / Svelte component is reachable through a barrel but rendered nowhere",
3458
3618
  "label": "Unrendered Components",
3459
3619
  "config_key": "unrendered-components",
3460
- "registry_index": 27,
3620
+ "registry_index": 28,
3461
3621
  "aliases": [
3462
3622
  "unrendered-components"
3463
3623
  ],
@@ -3493,7 +3653,7 @@
3493
3653
  "description": "A Vue, Svelte, or React component prop is referenced nowhere in its own component",
3494
3654
  "label": "Unused Component Props",
3495
3655
  "config_key": "unused-component-props",
3496
- "registry_index": 28,
3656
+ "registry_index": 29,
3497
3657
  "aliases": [
3498
3658
  "unused-component-props"
3499
3659
  ],
@@ -3529,7 +3689,7 @@
3529
3689
  "description": "A Vue <script setup> defineEmits event is emitted nowhere in its own component",
3530
3690
  "label": "Unused Component Emits",
3531
3691
  "config_key": "unused-component-emits",
3532
- "registry_index": 29,
3692
+ "registry_index": 30,
3533
3693
  "aliases": [
3534
3694
  "unused-component-emits"
3535
3695
  ],
@@ -3565,7 +3725,7 @@
3565
3725
  "description": "An Angular @Input() / signal input() / model() input is read nowhere in its own component",
3566
3726
  "label": "Unused Component Inputs",
3567
3727
  "config_key": "unused-component-inputs",
3568
- "registry_index": 30,
3728
+ "registry_index": 31,
3569
3729
  "aliases": [
3570
3730
  "unused-component-inputs"
3571
3731
  ],
@@ -3601,7 +3761,7 @@
3601
3761
  "description": "An Angular @Output() / signal output() output is emitted nowhere in its own component",
3602
3762
  "label": "Unused Component Outputs",
3603
3763
  "config_key": "unused-component-outputs",
3604
- "registry_index": 31,
3764
+ "registry_index": 32,
3605
3765
  "aliases": [
3606
3766
  "unused-component-outputs"
3607
3767
  ],
@@ -3637,7 +3797,7 @@
3637
3797
  "description": "A Svelte component dispatches a createEventDispatcher event whose name is listened to nowhere in the project",
3638
3798
  "label": "Unused Svelte Events",
3639
3799
  "config_key": "unused-svelte-events",
3640
- "registry_index": 32,
3800
+ "registry_index": 33,
3641
3801
  "aliases": [
3642
3802
  "unused-svelte-events"
3643
3803
  ],
@@ -3673,7 +3833,7 @@
3673
3833
  "description": "A Next.js Server Action exported from a \"use server\" file is referenced by no code in the project",
3674
3834
  "label": "Unused Server Actions",
3675
3835
  "config_key": "unused-server-actions",
3676
- "registry_index": 33,
3836
+ "registry_index": 34,
3677
3837
  "aliases": [
3678
3838
  "unused-server-actions"
3679
3839
  ],
@@ -3709,7 +3869,7 @@
3709
3869
  "description": "A SvelteKit load() return-object key is read by no consumer",
3710
3870
  "label": "Unused Load Data Keys",
3711
3871
  "config_key": "unused-load-data-keys",
3712
- "registry_index": 34,
3872
+ "registry_index": 35,
3713
3873
  "aliases": [
3714
3874
  "unused-load-data-keys"
3715
3875
  ],
@@ -3745,7 +3905,7 @@
3745
3905
  "description": "A React/Preact prop is forwarded unchanged through 3+ pass-through components to a distant consumer",
3746
3906
  "label": "Prop Drilling",
3747
3907
  "config_key": "prop-drilling",
3748
- "registry_index": 49,
3908
+ "registry_index": 50,
3749
3909
  "aliases": [],
3750
3910
  "lsp": false,
3751
3911
  "filter_flag": null,
@@ -3777,7 +3937,7 @@
3777
3937
  "description": "A React/Preact component whose whole body is a single spread-forwarded child render (a candidate for inlining)",
3778
3938
  "label": "Thin Wrappers",
3779
3939
  "config_key": "thin-wrapper",
3780
- "registry_index": 50,
3940
+ "registry_index": 51,
3781
3941
  "aliases": [
3782
3942
  "thin-wrappers"
3783
3943
  ],
@@ -3811,7 +3971,7 @@
3811
3971
  "description": "Three or more React/Preact components across two or more files declare an identical prop-name set (a missing shared Props type)",
3812
3972
  "label": "Duplicate Prop Shapes",
3813
3973
  "config_key": "duplicate-prop-shape",
3814
- "registry_index": 51,
3974
+ "registry_index": 52,
3815
3975
  "aliases": [
3816
3976
  "duplicate-prop-shapes"
3817
3977
  ],
@@ -3845,7 +4005,7 @@
3845
4005
  "description": "Two or more Next.js App Router route files resolve to the same URL",
3846
4006
  "label": "Route Collisions",
3847
4007
  "config_key": "route-collision",
3848
- "registry_index": 35,
4008
+ "registry_index": 36,
3849
4009
  "aliases": [
3850
4010
  "route-collisions"
3851
4011
  ],
@@ -3883,7 +4043,7 @@
3883
4043
  "description": "Sibling Next.js dynamic route segments use different slug names at the same position",
3884
4044
  "label": "Dynamic Segment Conflicts",
3885
4045
  "config_key": "dynamic-segment-name-conflict",
3886
- "registry_index": 36,
4046
+ "registry_index": 37,
3887
4047
  "aliases": [
3888
4048
  "dynamic-segment-name-conflicts"
3889
4049
  ],
@@ -4071,7 +4231,7 @@
4071
4231
  "description": "CSS or CSS-in-JS hardcoded styling value bypasses the design token system",
4072
4232
  "label": "CSS Token Drift",
4073
4233
  "config_key": "css-token-drift",
4074
- "registry_index": 52,
4234
+ "registry_index": 53,
4075
4235
  "aliases": [],
4076
4236
  "lsp": false,
4077
4237
  "filter_flag": null,
@@ -4101,7 +4261,7 @@
4101
4261
  "description": "CSS or CSS-in-JS declaration block is duplicated across rules",
4102
4262
  "label": "CSS Duplicate Block",
4103
4263
  "config_key": "css-duplicate-block",
4104
- "registry_index": 53,
4264
+ "registry_index": 54,
4105
4265
  "aliases": [],
4106
4266
  "lsp": false,
4107
4267
  "filter_flag": null,
@@ -4131,7 +4291,7 @@
4131
4291
  "description": "CSS selector, nesting, or important usage is structurally complex",
4132
4292
  "label": "CSS Selector Complexity",
4133
4293
  "config_key": "css-selector-complexity",
4134
- "registry_index": 54,
4294
+ "registry_index": 55,
4135
4295
  "aliases": [],
4136
4296
  "lsp": false,
4137
4297
  "filter_flag": null,
@@ -4161,7 +4321,7 @@
4161
4321
  "description": "CSS or CSS-in-JS surface appears unused",
4162
4322
  "label": "CSS Dead Surface",
4163
4323
  "config_key": "css-dead-surface",
4164
- "registry_index": 55,
4324
+ "registry_index": 56,
4165
4325
  "aliases": [],
4166
4326
  "lsp": false,
4167
4327
  "filter_flag": null,
@@ -4191,7 +4351,7 @@
4191
4351
  "description": "CSS or CSS-in-JS reference resolves to no stylesheet definition",
4192
4352
  "label": "CSS Broken Reference",
4193
4353
  "config_key": "css-broken-reference",
4194
- "registry_index": 56,
4354
+ "registry_index": 57,
4195
4355
  "aliases": [],
4196
4356
  "lsp": false,
4197
4357
  "filter_flag": null,
@@ -4581,7 +4741,7 @@
4581
4741
  "description": "Detected feature flag pattern",
4582
4742
  "label": "Feature Flags",
4583
4743
  "config_key": "feature-flags",
4584
- "registry_index": 47,
4744
+ "registry_index": 48,
4585
4745
  "aliases": [],
4586
4746
  "lsp": false,
4587
4747
  "filter_flag": null,
@@ -4603,6 +4763,36 @@
4603
4763
  "license_note": null,
4604
4764
  "docs_url": "https://docs.fallow.tools/cli/flags"
4605
4765
  },
4766
+ {
4767
+ "id": "flag-retirement-candidate",
4768
+ "rule_id": "fallow/flag-retirement-candidate",
4769
+ "command": "flags",
4770
+ "category": "Flags",
4771
+ "description": "Feature flag is a retirement candidate",
4772
+ "label": null,
4773
+ "config_key": null,
4774
+ "registry_index": null,
4775
+ "aliases": [],
4776
+ "lsp": false,
4777
+ "filter_flag": null,
4778
+ "result_key": null,
4779
+ "summary_label": null,
4780
+ "summary_docs_anchor": null,
4781
+ "sarif_rule_ids": null,
4782
+ "codeclimate_check_names": null,
4783
+ "ts_alias": null,
4784
+ "counts_in_total": false,
4785
+ "fixable": false,
4786
+ "suppressible": false,
4787
+ "suppress_comment": null,
4788
+ "default_severity": null,
4789
+ "opt_in": null,
4790
+ "frameworks": [],
4791
+ "note": null,
4792
+ "license": "free",
4793
+ "license_note": null,
4794
+ "docs_url": "https://docs.fallow.tools/cli/flags#retirement-report"
4795
+ },
4606
4796
  {
4607
4797
  "id": "tainted-sink",
4608
4798
  "rule_id": "security/tainted-sink",
@@ -6101,7 +6291,7 @@
6101
6291
  "FALLOW_CACHE_DIR": "Directory for fallow's persistent analysis cache. Relative paths resolve from the project root and override cache.dir.",
6102
6292
  "FALLOW_CACHE_MAX_SIZE": "Extraction cache size cap in megabytes (default 256). Wins over the cache.maxSizeMb config field.",
6103
6293
  "FALLOW_EXTENDS_TIMEOUT_SECS": "Timeout in seconds for fetching https:// configs referenced via the extends field (default 5).",
6104
- "FALLOW_COVERAGE": "Path to Istanbul coverage data (coverage-final.json) for accurate per-function CRAP scores. CLI --coverage flag overrides this; it wins over the health.coverage config field. Honored by the health, bare fallow, audit, and viz CLI commands and by the MCP audit and check_health tools on both their typed route and their CLI fallback, where the explicit coverage parameter overrides it. Viz reads it through the same precedence and has no coverage flag of its own.",
6294
+ "FALLOW_COVERAGE": "Path to Istanbul coverage data (coverage-final.json) or raw V8 coverage (a NODE_V8_COVERAGE directory or one V8 JSON file) for accurate per-function CRAP scores. CLI --coverage flag overrides this; it wins over the health.coverage config field. Honored by the health, bare fallow, audit, and viz CLI commands and by the MCP audit and check_health tools on both their typed route and their CLI fallback, where the explicit coverage parameter overrides it. Viz reads it through the same precedence and has no coverage flag of its own.",
6105
6295
  "FALLOW_COVERAGE_ROOT": "Absolute coverage-data path prefix for rebasing Istanbul paths in CI or containers. CLI --coverage-root flag overrides this; it wins over the health.coverageRoot config field. Honored by the health, bare fallow, audit, and viz CLI commands and by the MCP audit and check_health tools on both their typed route and their CLI fallback, where the explicit coverage_root parameter overrides it. Viz reads it through the same precedence and has no coverage flag of its own.",
6106
6296
  "FALLOW_MAX_FILE_SIZE": "Per-file size ceiling in megabytes for source discovery (default 5; 0 = no limit). CLI --max-file-size flag overrides this.",
6107
6297
  "FALLOW_TYPE_AWARE": "Enable or disable TypeScript semantic (type-aware) analysis for the run (true/false/1/0/yes/no/on/off). Precedence: --type-aware/--no-type-aware CLI flags, then FALLOW_TYPE_AWARE, then the audit.typeAware config field, then typeAware.enabled.",
@@ -6132,8 +6322,10 @@
6132
6322
  "FALLOW_TIMEOUT_SECS": "MCP server: per-tool-call CLI subprocess timeout in seconds (default 120). Raise for long runs like production coverage on large dumps.",
6133
6323
  "FALLOW_DIFF_FILE": "MCP server: path to a unified diff that scopes all findings by changed line.",
6134
6324
  "FALLOW_CHANGED_SINCE": "MCP server: git ref that scopes file discovery for analysis tools.",
6325
+ "FALLOW_MCP_WARM_SESSION": "MCP server: set to 0, false, off or no to stop typed tool calls from keeping parsed modules in memory between calls (default on).",
6135
6326
  "FALLOW_INTEGRATION_SURFACE": "Telemetry integration_surface override for non-CLI surfaces (mcp/lsp/vscode/napi/programmatic). Set by the MCP server on the CLI it spawns.",
6136
- "FALLOW_MCP_TOOL": "Telemetry mcp_tool dimension, validated against the MCP tool-name allowlist. Set by the MCP server alongside FALLOW_INTEGRATION_SURFACE=mcp."
6327
+ "FALLOW_MCP_TOOL": "Telemetry mcp_tool dimension, validated against the MCP tool-name allowlist. Set by the MCP server alongside FALLOW_INTEGRATION_SURFACE=mcp.",
6328
+ "FALLOW_LSP_REUSE_SESSION": "Language server: set to 0/false/off/no to load a new project session on each analysis run. By default the server keeps one session per project root between saves and parses only the changed files."
6137
6329
  },
6138
6330
  "severity_levels": [
6139
6331
  "error",
@@ -6640,7 +6832,7 @@
6640
6832
  ],
6641
6833
  "license": "free",
6642
6834
  "license_note": null,
6643
- "read_only": true,
6835
+ "read_only": false,
6644
6836
  "code_mode_alias": "analyze"
6645
6837
  },
6646
6838
  {
@@ -6655,7 +6847,7 @@
6655
6847
  ],
6656
6848
  "license": "free",
6657
6849
  "license_note": null,
6658
- "read_only": true,
6850
+ "read_only": false,
6659
6851
  "code_mode_alias": "checkChanged"
6660
6852
  },
6661
6853
  {
@@ -6748,7 +6940,7 @@
6748
6940
  ],
6749
6941
  "license": "free",
6750
6942
  "license_note": null,
6751
- "read_only": true,
6943
+ "read_only": false,
6752
6944
  "code_mode_alias": "findDupes"
6753
6945
  },
6754
6946
  {
@@ -6769,7 +6961,7 @@
6769
6961
  ],
6770
6962
  "license": "free",
6771
6963
  "license_note": null,
6772
- "read_only": true,
6964
+ "read_only": false,
6773
6965
  "code_mode_alias": "checkHealth"
6774
6966
  },
6775
6967
  {
@@ -7262,7 +7454,7 @@
7262
7454
  ]
7263
7455
  },
7264
7456
  "plugins": {
7265
- "count": 127,
7457
+ "count": 128,
7266
7458
  "note": "Built-in framework plugins, auto-activated when their enabler dependency is present; run fallow list --plugins for the set active in a specific project",
7267
7459
  "names": [
7268
7460
  "nextjs",
@@ -7276,6 +7468,7 @@
7276
7468
  "react-router",
7277
7469
  "redwoodsdk",
7278
7470
  "tanstack-router",
7471
+ "waku",
7279
7472
  "react-native",
7280
7473
  "expo",
7281
7474
  "expo-router",