fallow 3.28.0 → 3.29.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/README.md +1 -1
- package/capabilities.json +137 -68
- package/issue-registry.json +85 -48
- package/package.json +10 -10
- package/schema.json +77 -4
- package/scripts/lazy-verify.js +14 -16
- package/scripts/lazy-verify.test.js +24 -13
- package/scripts/sentinel-path.js +4 -4
- package/scripts/sentinel-path.test.js +1 -4
- package/scripts/verify-binary.js +4 -2
- package/skills/fallow/SKILL.md +2 -2
- package/skills/fallow/references/cli-reference.md +25 -21
- package/skills/fallow/references/issue-types.md +1 -0
- package/skills/fallow/references/mcp.md +5 -3
- package/types/output-contract.d.ts +834 -101
package/issue-registry.json
CHANGED
|
@@ -177,6 +177,43 @@
|
|
|
177
177
|
"license_note": null,
|
|
178
178
|
"docs_url": "https://docs.fallow.tools/explanations/dead-code#private-type-leaks"
|
|
179
179
|
},
|
|
180
|
+
{
|
|
181
|
+
"id": "deprecated-export-in-use",
|
|
182
|
+
"rule_id": "fallow/deprecated-export-in-use",
|
|
183
|
+
"command": "dead-code",
|
|
184
|
+
"category": "Dead code",
|
|
185
|
+
"description": "Export marked @deprecated is still referenced",
|
|
186
|
+
"label": "Deprecated Exports in Use",
|
|
187
|
+
"config_key": "deprecated-exports-in-use",
|
|
188
|
+
"registry_index": 5,
|
|
189
|
+
"aliases": [],
|
|
190
|
+
"lsp": false,
|
|
191
|
+
"filter_flag": "--deprecated-exports-in-use",
|
|
192
|
+
"result_key": "deprecated_exports_in_use",
|
|
193
|
+
"summary_label": "Deprecated exports in use",
|
|
194
|
+
"summary_docs_anchor": "deprecated-exports-in-use",
|
|
195
|
+
"sarif_rule_ids": [
|
|
196
|
+
"fallow/deprecated-export-in-use"
|
|
197
|
+
],
|
|
198
|
+
"codeclimate_check_names": [
|
|
199
|
+
"fallow/deprecated-export-in-use"
|
|
200
|
+
],
|
|
201
|
+
"ts_alias": {
|
|
202
|
+
"name": "DeprecatedExportInUse",
|
|
203
|
+
"parent": "DeprecatedExportInUseFinding"
|
|
204
|
+
},
|
|
205
|
+
"counts_in_total": true,
|
|
206
|
+
"fixable": false,
|
|
207
|
+
"suppressible": true,
|
|
208
|
+
"suppress_comment": "// fallow-ignore-next-line deprecated-export-in-use",
|
|
209
|
+
"default_severity": "off",
|
|
210
|
+
"opt_in": true,
|
|
211
|
+
"frameworks": [],
|
|
212
|
+
"note": "Opt-in migration sweep; the rule defaults to off",
|
|
213
|
+
"license": "free",
|
|
214
|
+
"license_note": null,
|
|
215
|
+
"docs_url": "https://docs.fallow.tools/explanations/dead-code#deprecated-exports-in-use"
|
|
216
|
+
},
|
|
180
217
|
{
|
|
181
218
|
"id": "unused-dependency",
|
|
182
219
|
"rule_id": "fallow/unused-dependency",
|
|
@@ -185,7 +222,7 @@
|
|
|
185
222
|
"description": "Dependency listed but never imported",
|
|
186
223
|
"label": "Unused Dependencies",
|
|
187
224
|
"config_key": "unused-dependencies",
|
|
188
|
-
"registry_index":
|
|
225
|
+
"registry_index": 6,
|
|
189
226
|
"aliases": [],
|
|
190
227
|
"lsp": true,
|
|
191
228
|
"filter_flag": "--unused-deps",
|
|
@@ -222,7 +259,7 @@
|
|
|
222
259
|
"description": "Dev dependency listed but never imported",
|
|
223
260
|
"label": "Unused Dev Dependencies",
|
|
224
261
|
"config_key": "unused-dev-dependencies",
|
|
225
|
-
"registry_index":
|
|
262
|
+
"registry_index": 7,
|
|
226
263
|
"aliases": [
|
|
227
264
|
"unused-dev-deps",
|
|
228
265
|
"unused-dev-dependencies"
|
|
@@ -262,7 +299,7 @@
|
|
|
262
299
|
"description": "Optional dependency listed but never imported",
|
|
263
300
|
"label": "Unused Optional Dependencies",
|
|
264
301
|
"config_key": "unused-optional-dependencies",
|
|
265
|
-
"registry_index":
|
|
302
|
+
"registry_index": 8,
|
|
266
303
|
"aliases": [
|
|
267
304
|
"unused-optional-deps",
|
|
268
305
|
"unused-optional-dependencies"
|
|
@@ -302,7 +339,7 @@
|
|
|
302
339
|
"description": "Enum member is never referenced",
|
|
303
340
|
"label": "Unused Enum Members",
|
|
304
341
|
"config_key": "unused-enum-members",
|
|
305
|
-
"registry_index":
|
|
342
|
+
"registry_index": 9,
|
|
306
343
|
"aliases": [],
|
|
307
344
|
"lsp": true,
|
|
308
345
|
"filter_flag": "--unused-enum-members",
|
|
@@ -339,7 +376,7 @@
|
|
|
339
376
|
"description": "Class member is never referenced",
|
|
340
377
|
"label": "Unused Class Members",
|
|
341
378
|
"config_key": "unused-class-members",
|
|
342
|
-
"registry_index":
|
|
379
|
+
"registry_index": 10,
|
|
343
380
|
"aliases": [],
|
|
344
381
|
"lsp": true,
|
|
345
382
|
"filter_flag": "--unused-class-members",
|
|
@@ -376,7 +413,7 @@
|
|
|
376
413
|
"description": "Store member is never accessed by any consumer",
|
|
377
414
|
"label": "Unused Store Members",
|
|
378
415
|
"config_key": "unused-store-members",
|
|
379
|
-
"registry_index":
|
|
416
|
+
"registry_index": 11,
|
|
380
417
|
"aliases": [
|
|
381
418
|
"unused-store-members"
|
|
382
419
|
],
|
|
@@ -415,7 +452,7 @@
|
|
|
415
452
|
"description": "Import could not be resolved",
|
|
416
453
|
"label": "Unresolved Imports",
|
|
417
454
|
"config_key": "unresolved-imports",
|
|
418
|
-
"registry_index":
|
|
455
|
+
"registry_index": 12,
|
|
419
456
|
"aliases": [],
|
|
420
457
|
"lsp": true,
|
|
421
458
|
"filter_flag": "--unresolved-imports",
|
|
@@ -452,7 +489,7 @@
|
|
|
452
489
|
"description": "Dependency used but not in package.json",
|
|
453
490
|
"label": "Unlisted Dependencies",
|
|
454
491
|
"config_key": "unlisted-dependencies",
|
|
455
|
-
"registry_index":
|
|
492
|
+
"registry_index": 13,
|
|
456
493
|
"aliases": [],
|
|
457
494
|
"lsp": true,
|
|
458
495
|
"filter_flag": "--unlisted-deps",
|
|
@@ -489,7 +526,7 @@
|
|
|
489
526
|
"description": "Export name appears in multiple modules",
|
|
490
527
|
"label": "Duplicate Exports",
|
|
491
528
|
"config_key": "duplicate-exports",
|
|
492
|
-
"registry_index":
|
|
529
|
+
"registry_index": 14,
|
|
493
530
|
"aliases": [],
|
|
494
531
|
"lsp": true,
|
|
495
532
|
"filter_flag": "--duplicate-exports",
|
|
@@ -526,7 +563,7 @@
|
|
|
526
563
|
"description": "Production dependency only used via type-only imports",
|
|
527
564
|
"label": "Type-Only Dependencies",
|
|
528
565
|
"config_key": "type-only-dependencies",
|
|
529
|
-
"registry_index":
|
|
566
|
+
"registry_index": 15,
|
|
530
567
|
"aliases": [],
|
|
531
568
|
"lsp": true,
|
|
532
569
|
"filter_flag": "--unused-deps",
|
|
@@ -563,7 +600,7 @@
|
|
|
563
600
|
"description": "Production dependency only imported by test files",
|
|
564
601
|
"label": "Test-Only Dependencies",
|
|
565
602
|
"config_key": "test-only-dependencies",
|
|
566
|
-
"registry_index":
|
|
603
|
+
"registry_index": 16,
|
|
567
604
|
"aliases": [],
|
|
568
605
|
"lsp": true,
|
|
569
606
|
"filter_flag": "--unused-deps",
|
|
@@ -600,7 +637,7 @@
|
|
|
600
637
|
"description": "devDependency imported by production code with a runtime import",
|
|
601
638
|
"label": "Dev Dependencies Used in Production",
|
|
602
639
|
"config_key": "dev-dependencies-in-production",
|
|
603
|
-
"registry_index":
|
|
640
|
+
"registry_index": 17,
|
|
604
641
|
"aliases": [],
|
|
605
642
|
"lsp": true,
|
|
606
643
|
"filter_flag": "--unused-deps",
|
|
@@ -637,7 +674,7 @@
|
|
|
637
674
|
"description": "Circular dependency chain detected",
|
|
638
675
|
"label": "Circular Dependencies",
|
|
639
676
|
"config_key": "circular-dependencies",
|
|
640
|
-
"registry_index":
|
|
677
|
+
"registry_index": 18,
|
|
641
678
|
"aliases": [
|
|
642
679
|
"circular-dependencies"
|
|
643
680
|
],
|
|
@@ -676,7 +713,7 @@
|
|
|
676
713
|
"description": "Two or more barrel files re-export from each other in a loop",
|
|
677
714
|
"label": "Re-Export Cycles",
|
|
678
715
|
"config_key": "re-export-cycle",
|
|
679
|
-
"registry_index":
|
|
716
|
+
"registry_index": 19,
|
|
680
717
|
"aliases": [
|
|
681
718
|
"re-export-cycles",
|
|
682
719
|
"reexport-cycle",
|
|
@@ -717,7 +754,7 @@
|
|
|
717
754
|
"description": "Import crosses a configured architecture boundary",
|
|
718
755
|
"label": "Boundary Violations",
|
|
719
756
|
"config_key": "boundary-violation",
|
|
720
|
-
"registry_index":
|
|
757
|
+
"registry_index": 20,
|
|
721
758
|
"aliases": [],
|
|
722
759
|
"lsp": true,
|
|
723
760
|
"filter_flag": "--boundary-violations",
|
|
@@ -754,7 +791,7 @@
|
|
|
754
791
|
"description": "Source file matches no configured architecture boundary zone",
|
|
755
792
|
"label": "Boundary Coverage",
|
|
756
793
|
"config_key": "boundary-violation",
|
|
757
|
-
"registry_index":
|
|
794
|
+
"registry_index": 21,
|
|
758
795
|
"aliases": [
|
|
759
796
|
"boundary-coverage-violations"
|
|
760
797
|
],
|
|
@@ -790,7 +827,7 @@
|
|
|
790
827
|
"description": "Zoned file calls a callee its zone forbids",
|
|
791
828
|
"label": "Boundary Call Violations",
|
|
792
829
|
"config_key": "boundary-violation",
|
|
793
|
-
"registry_index":
|
|
830
|
+
"registry_index": 22,
|
|
794
831
|
"aliases": [
|
|
795
832
|
"boundary-calls",
|
|
796
833
|
"boundary-call-violations"
|
|
@@ -827,7 +864,7 @@
|
|
|
827
864
|
"description": "Banned usage matched a rule-pack rule",
|
|
828
865
|
"label": "Policy Violations",
|
|
829
866
|
"config_key": "policy-violation",
|
|
830
|
-
"registry_index":
|
|
867
|
+
"registry_index": 23,
|
|
831
868
|
"aliases": [
|
|
832
869
|
"policy-violations"
|
|
833
870
|
],
|
|
@@ -863,7 +900,7 @@
|
|
|
863
900
|
"description": "\"use client\" file exports a server-only / route-config name",
|
|
864
901
|
"label": "Invalid Client Exports",
|
|
865
902
|
"config_key": "invalid-client-export",
|
|
866
|
-
"registry_index":
|
|
903
|
+
"registry_index": 24,
|
|
867
904
|
"aliases": [
|
|
868
905
|
"invalid-client-exports"
|
|
869
906
|
],
|
|
@@ -901,7 +938,7 @@
|
|
|
901
938
|
"description": "Barrel re-exports both a \"use client\" module and a server-only module",
|
|
902
939
|
"label": "Mixed Client/Server Barrels",
|
|
903
940
|
"config_key": "mixed-client-server-barrel",
|
|
904
|
-
"registry_index":
|
|
941
|
+
"registry_index": 25,
|
|
905
942
|
"aliases": [
|
|
906
943
|
"mixed-client-server-barrels"
|
|
907
944
|
],
|
|
@@ -937,7 +974,7 @@
|
|
|
937
974
|
"description": "\"use client\" / \"use server\" directive is not in the leading position and is ignored",
|
|
938
975
|
"label": "Misplaced Directives",
|
|
939
976
|
"config_key": "misplaced-directive",
|
|
940
|
-
"registry_index":
|
|
977
|
+
"registry_index": 26,
|
|
941
978
|
"aliases": [
|
|
942
979
|
"misplaced-directives"
|
|
943
980
|
],
|
|
@@ -973,7 +1010,7 @@
|
|
|
973
1010
|
"description": "inject() / getContext() reads a key that no provide() / setContext() supplies",
|
|
974
1011
|
"label": "Unprovided Injects",
|
|
975
1012
|
"config_key": "unprovided-injects",
|
|
976
|
-
"registry_index":
|
|
1013
|
+
"registry_index": 27,
|
|
977
1014
|
"aliases": [
|
|
978
1015
|
"unprovided-injects"
|
|
979
1016
|
],
|
|
@@ -1009,7 +1046,7 @@
|
|
|
1009
1046
|
"description": "A Vue / Svelte component is reachable through a barrel but rendered nowhere",
|
|
1010
1047
|
"label": "Unrendered Components",
|
|
1011
1048
|
"config_key": "unrendered-components",
|
|
1012
|
-
"registry_index":
|
|
1049
|
+
"registry_index": 28,
|
|
1013
1050
|
"aliases": [
|
|
1014
1051
|
"unrendered-components"
|
|
1015
1052
|
],
|
|
@@ -1045,7 +1082,7 @@
|
|
|
1045
1082
|
"description": "A Vue, Svelte, or React component prop is referenced nowhere in its own component",
|
|
1046
1083
|
"label": "Unused Component Props",
|
|
1047
1084
|
"config_key": "unused-component-props",
|
|
1048
|
-
"registry_index":
|
|
1085
|
+
"registry_index": 29,
|
|
1049
1086
|
"aliases": [
|
|
1050
1087
|
"unused-component-props"
|
|
1051
1088
|
],
|
|
@@ -1081,7 +1118,7 @@
|
|
|
1081
1118
|
"description": "A Vue <script setup> defineEmits event is emitted nowhere in its own component",
|
|
1082
1119
|
"label": "Unused Component Emits",
|
|
1083
1120
|
"config_key": "unused-component-emits",
|
|
1084
|
-
"registry_index":
|
|
1121
|
+
"registry_index": 30,
|
|
1085
1122
|
"aliases": [
|
|
1086
1123
|
"unused-component-emits"
|
|
1087
1124
|
],
|
|
@@ -1117,7 +1154,7 @@
|
|
|
1117
1154
|
"description": "An Angular @Input() / signal input() / model() input is read nowhere in its own component",
|
|
1118
1155
|
"label": "Unused Component Inputs",
|
|
1119
1156
|
"config_key": "unused-component-inputs",
|
|
1120
|
-
"registry_index":
|
|
1157
|
+
"registry_index": 31,
|
|
1121
1158
|
"aliases": [
|
|
1122
1159
|
"unused-component-inputs"
|
|
1123
1160
|
],
|
|
@@ -1153,7 +1190,7 @@
|
|
|
1153
1190
|
"description": "An Angular @Output() / signal output() output is emitted nowhere in its own component",
|
|
1154
1191
|
"label": "Unused Component Outputs",
|
|
1155
1192
|
"config_key": "unused-component-outputs",
|
|
1156
|
-
"registry_index":
|
|
1193
|
+
"registry_index": 32,
|
|
1157
1194
|
"aliases": [
|
|
1158
1195
|
"unused-component-outputs"
|
|
1159
1196
|
],
|
|
@@ -1189,7 +1226,7 @@
|
|
|
1189
1226
|
"description": "A Svelte component dispatches a createEventDispatcher event whose name is listened to nowhere in the project",
|
|
1190
1227
|
"label": "Unused Svelte Events",
|
|
1191
1228
|
"config_key": "unused-svelte-events",
|
|
1192
|
-
"registry_index":
|
|
1229
|
+
"registry_index": 33,
|
|
1193
1230
|
"aliases": [
|
|
1194
1231
|
"unused-svelte-events"
|
|
1195
1232
|
],
|
|
@@ -1225,7 +1262,7 @@
|
|
|
1225
1262
|
"description": "A Next.js Server Action exported from a \"use server\" file is referenced by no code in the project",
|
|
1226
1263
|
"label": "Unused Server Actions",
|
|
1227
1264
|
"config_key": "unused-server-actions",
|
|
1228
|
-
"registry_index":
|
|
1265
|
+
"registry_index": 34,
|
|
1229
1266
|
"aliases": [
|
|
1230
1267
|
"unused-server-actions"
|
|
1231
1268
|
],
|
|
@@ -1261,7 +1298,7 @@
|
|
|
1261
1298
|
"description": "A SvelteKit load() return-object key is read by no consumer",
|
|
1262
1299
|
"label": "Unused Load Data Keys",
|
|
1263
1300
|
"config_key": "unused-load-data-keys",
|
|
1264
|
-
"registry_index":
|
|
1301
|
+
"registry_index": 35,
|
|
1265
1302
|
"aliases": [
|
|
1266
1303
|
"unused-load-data-keys"
|
|
1267
1304
|
],
|
|
@@ -1297,7 +1334,7 @@
|
|
|
1297
1334
|
"description": "Two or more Next.js App Router route files resolve to the same URL",
|
|
1298
1335
|
"label": "Route Collisions",
|
|
1299
1336
|
"config_key": "route-collision",
|
|
1300
|
-
"registry_index":
|
|
1337
|
+
"registry_index": 36,
|
|
1301
1338
|
"aliases": [
|
|
1302
1339
|
"route-collisions"
|
|
1303
1340
|
],
|
|
@@ -1335,7 +1372,7 @@
|
|
|
1335
1372
|
"description": "Sibling Next.js dynamic route segments use different slug names at the same position",
|
|
1336
1373
|
"label": "Dynamic Segment Conflicts",
|
|
1337
1374
|
"config_key": "dynamic-segment-name-conflict",
|
|
1338
|
-
"registry_index":
|
|
1375
|
+
"registry_index": 37,
|
|
1339
1376
|
"aliases": [
|
|
1340
1377
|
"dynamic-segment-name-conflicts"
|
|
1341
1378
|
],
|
|
@@ -1373,7 +1410,7 @@
|
|
|
1373
1410
|
"description": "Suppression comment or tag no longer matches any issue",
|
|
1374
1411
|
"label": "Stale Suppressions",
|
|
1375
1412
|
"config_key": "stale-suppressions",
|
|
1376
|
-
"registry_index":
|
|
1413
|
+
"registry_index": 38,
|
|
1377
1414
|
"aliases": [],
|
|
1378
1415
|
"lsp": true,
|
|
1379
1416
|
"filter_flag": "--stale-suppressions",
|
|
@@ -1409,7 +1446,7 @@
|
|
|
1409
1446
|
"description": "Suppression comment omits a required reason",
|
|
1410
1447
|
"label": "Missing Suppression Reasons",
|
|
1411
1448
|
"config_key": "require-suppression-reason",
|
|
1412
|
-
"registry_index":
|
|
1449
|
+
"registry_index": 39,
|
|
1413
1450
|
"aliases": [
|
|
1414
1451
|
"missing-suppression-reasons"
|
|
1415
1452
|
],
|
|
@@ -1441,7 +1478,7 @@
|
|
|
1441
1478
|
"description": "Catalog entry not referenced by any workspace package",
|
|
1442
1479
|
"label": "Unused Catalog Entries",
|
|
1443
1480
|
"config_key": "unused-catalog-entries",
|
|
1444
|
-
"registry_index":
|
|
1481
|
+
"registry_index": 40,
|
|
1445
1482
|
"aliases": [
|
|
1446
1483
|
"catalog",
|
|
1447
1484
|
"unused-catalog-entries"
|
|
@@ -1481,7 +1518,7 @@
|
|
|
1481
1518
|
"description": "Named catalog group has no entries",
|
|
1482
1519
|
"label": "Empty Catalog Groups",
|
|
1483
1520
|
"config_key": "empty-catalog-groups",
|
|
1484
|
-
"registry_index":
|
|
1521
|
+
"registry_index": 41,
|
|
1485
1522
|
"aliases": [
|
|
1486
1523
|
"empty-catalog",
|
|
1487
1524
|
"empty-catalog-groups"
|
|
@@ -1521,7 +1558,7 @@
|
|
|
1521
1558
|
"description": "package.json references a catalog that does not declare the package",
|
|
1522
1559
|
"label": "Unresolved Catalog References",
|
|
1523
1560
|
"config_key": "unresolved-catalog-references",
|
|
1524
|
-
"registry_index":
|
|
1561
|
+
"registry_index": 42,
|
|
1525
1562
|
"aliases": [
|
|
1526
1563
|
"unresolved-catalog",
|
|
1527
1564
|
"unresolved-catalog-references"
|
|
@@ -1561,7 +1598,7 @@
|
|
|
1561
1598
|
"description": "Package-manager override target is not declared or resolved",
|
|
1562
1599
|
"label": "Unused Dependency Overrides",
|
|
1563
1600
|
"config_key": "unused-dependency-overrides",
|
|
1564
|
-
"registry_index":
|
|
1601
|
+
"registry_index": 43,
|
|
1565
1602
|
"aliases": [
|
|
1566
1603
|
"unused-dependency-overrides",
|
|
1567
1604
|
"unused-override",
|
|
@@ -1602,7 +1639,7 @@
|
|
|
1602
1639
|
"description": "Package-manager override has an unparsable key or value",
|
|
1603
1640
|
"label": "Misconfigured Dependency Overrides",
|
|
1604
1641
|
"config_key": "misconfigured-dependency-overrides",
|
|
1605
|
-
"registry_index":
|
|
1642
|
+
"registry_index": 44,
|
|
1606
1643
|
"aliases": [
|
|
1607
1644
|
"misconfigured-dependency-overrides",
|
|
1608
1645
|
"misconfigured-override",
|
|
@@ -1643,7 +1680,7 @@
|
|
|
1643
1680
|
"description": "Detected feature flag pattern",
|
|
1644
1681
|
"label": "Feature Flags",
|
|
1645
1682
|
"config_key": "feature-flags",
|
|
1646
|
-
"registry_index":
|
|
1683
|
+
"registry_index": 48,
|
|
1647
1684
|
"aliases": [],
|
|
1648
1685
|
"lsp": false,
|
|
1649
1686
|
"filter_flag": null,
|
|
@@ -1673,7 +1710,7 @@
|
|
|
1673
1710
|
"description": "A React/Preact prop is forwarded unchanged through 3+ pass-through components to a distant consumer",
|
|
1674
1711
|
"label": "Prop Drilling",
|
|
1675
1712
|
"config_key": "prop-drilling",
|
|
1676
|
-
"registry_index":
|
|
1713
|
+
"registry_index": 50,
|
|
1677
1714
|
"aliases": [],
|
|
1678
1715
|
"lsp": false,
|
|
1679
1716
|
"filter_flag": null,
|
|
@@ -1705,7 +1742,7 @@
|
|
|
1705
1742
|
"description": "A React/Preact component whose whole body is a single spread-forwarded child render (a candidate for inlining)",
|
|
1706
1743
|
"label": "Thin Wrappers",
|
|
1707
1744
|
"config_key": "thin-wrapper",
|
|
1708
|
-
"registry_index":
|
|
1745
|
+
"registry_index": 51,
|
|
1709
1746
|
"aliases": [
|
|
1710
1747
|
"thin-wrappers"
|
|
1711
1748
|
],
|
|
@@ -1739,7 +1776,7 @@
|
|
|
1739
1776
|
"description": "Three or more React/Preact components across two or more files declare an identical prop-name set (a missing shared Props type)",
|
|
1740
1777
|
"label": "Duplicate Prop Shapes",
|
|
1741
1778
|
"config_key": "duplicate-prop-shape",
|
|
1742
|
-
"registry_index":
|
|
1779
|
+
"registry_index": 52,
|
|
1743
1780
|
"aliases": [
|
|
1744
1781
|
"duplicate-prop-shapes"
|
|
1745
1782
|
],
|
|
@@ -1773,7 +1810,7 @@
|
|
|
1773
1810
|
"description": "CSS or CSS-in-JS hardcoded styling value bypasses the design token system",
|
|
1774
1811
|
"label": "CSS Token Drift",
|
|
1775
1812
|
"config_key": "css-token-drift",
|
|
1776
|
-
"registry_index":
|
|
1813
|
+
"registry_index": 53,
|
|
1777
1814
|
"aliases": [],
|
|
1778
1815
|
"lsp": false,
|
|
1779
1816
|
"filter_flag": null,
|
|
@@ -1803,7 +1840,7 @@
|
|
|
1803
1840
|
"description": "CSS or CSS-in-JS declaration block is duplicated across rules",
|
|
1804
1841
|
"label": "CSS Duplicate Block",
|
|
1805
1842
|
"config_key": "css-duplicate-block",
|
|
1806
|
-
"registry_index":
|
|
1843
|
+
"registry_index": 54,
|
|
1807
1844
|
"aliases": [],
|
|
1808
1845
|
"lsp": false,
|
|
1809
1846
|
"filter_flag": null,
|
|
@@ -1833,7 +1870,7 @@
|
|
|
1833
1870
|
"description": "CSS selector, nesting, or important usage is structurally complex",
|
|
1834
1871
|
"label": "CSS Selector Complexity",
|
|
1835
1872
|
"config_key": "css-selector-complexity",
|
|
1836
|
-
"registry_index":
|
|
1873
|
+
"registry_index": 55,
|
|
1837
1874
|
"aliases": [],
|
|
1838
1875
|
"lsp": false,
|
|
1839
1876
|
"filter_flag": null,
|
|
@@ -1863,7 +1900,7 @@
|
|
|
1863
1900
|
"description": "CSS or CSS-in-JS surface appears unused",
|
|
1864
1901
|
"label": "CSS Dead Surface",
|
|
1865
1902
|
"config_key": "css-dead-surface",
|
|
1866
|
-
"registry_index":
|
|
1903
|
+
"registry_index": 56,
|
|
1867
1904
|
"aliases": [],
|
|
1868
1905
|
"lsp": false,
|
|
1869
1906
|
"filter_flag": null,
|
|
@@ -1893,7 +1930,7 @@
|
|
|
1893
1930
|
"description": "CSS or CSS-in-JS reference resolves to no stylesheet definition",
|
|
1894
1931
|
"label": "CSS Broken Reference",
|
|
1895
1932
|
"config_key": "css-broken-reference",
|
|
1896
|
-
"registry_index":
|
|
1933
|
+
"registry_index": 57,
|
|
1897
1934
|
"aliases": [],
|
|
1898
1935
|
"lsp": false,
|
|
1899
1936
|
"filter_flag": null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fallow",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.29.0",
|
|
4
4
|
"mcpName": "io.github.fallow-rs/fallow",
|
|
5
5
|
"description": "Codebase intelligence for TypeScript and JavaScript. Free static analysis of code and styles, optional paid runtime intelligence (Fallow Runtime). Quality, risk, architecture, dependencies, duplication, and design-system drift for humans, CI, and the agents writing your code. Zero-config framework support.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -88,14 +88,14 @@
|
|
|
88
88
|
"@tanstack/intent": "0.4.0"
|
|
89
89
|
},
|
|
90
90
|
"optionalDependencies": {
|
|
91
|
-
"@fallow-cli/darwin-arm64": "3.
|
|
92
|
-
"@fallow-cli/darwin-x64": "3.
|
|
93
|
-
"@fallow-cli/linux-x64-gnu": "3.
|
|
94
|
-
"@fallow-cli/linux-arm64-gnu": "3.
|
|
95
|
-
"@fallow-cli/linux-x64-musl": "3.
|
|
96
|
-
"@fallow-cli/linux-arm64-musl": "3.
|
|
97
|
-
"@fallow-cli/win32-arm64-msvc": "3.
|
|
98
|
-
"@fallow-cli/win32-x64-msvc": "3.
|
|
99
|
-
"fallow-type-aware": "3.
|
|
91
|
+
"@fallow-cli/darwin-arm64": "3.29.0",
|
|
92
|
+
"@fallow-cli/darwin-x64": "3.29.0",
|
|
93
|
+
"@fallow-cli/linux-x64-gnu": "3.29.0",
|
|
94
|
+
"@fallow-cli/linux-arm64-gnu": "3.29.0",
|
|
95
|
+
"@fallow-cli/linux-x64-musl": "3.29.0",
|
|
96
|
+
"@fallow-cli/linux-arm64-musl": "3.29.0",
|
|
97
|
+
"@fallow-cli/win32-arm64-msvc": "3.29.0",
|
|
98
|
+
"@fallow-cli/win32-x64-msvc": "3.29.0",
|
|
99
|
+
"fallow-type-aware": "3.29.0"
|
|
100
100
|
}
|
|
101
101
|
}
|
package/schema.json
CHANGED
|
@@ -190,13 +190,14 @@
|
|
|
190
190
|
"$ref": "#/$defs/TypeAwareConfig"
|
|
191
191
|
},
|
|
192
192
|
"rules": {
|
|
193
|
-
"description": "Sets per-issue-type severity, keyed by kebab-case rule id: `error` reports and fails CI (non-zero exit), `warn` reports without failing, `off` disables detection and reporting entirely (e.g. `{ \"unused-files\": \"error\", \"unused-exports\": \"warn\", \"private-type-leaks\": \"off\" }`). Set a rule `off` to silence it, `warn` to demote below CI gating, or `error` to promote a warn/off-default rule to gating; most rules default to `error`, dev/optional-dependency and component/store/inject/CSS/catalog rules default to `warn`, and opt-in rules (`private-type-leaks`, `security-*`, `prop-drilling`, `thin-wrapper`, `duplicate-prop-shape`, `coverage-gaps`, `feature-flags`, `require-suppression-reason`) default to `off`. Singular aliases (`unused-file`) and `warning`/`none` severity spellings are accepted.",
|
|
193
|
+
"description": "Sets per-issue-type severity, keyed by kebab-case rule id: `error` reports and fails CI (non-zero exit), `warn` reports without failing, `off` disables detection and reporting entirely (e.g. `{ \"unused-files\": \"error\", \"unused-exports\": \"warn\", \"private-type-leaks\": \"off\" }`). Set a rule `off` to silence it, `warn` to demote below CI gating, or `error` to promote a warn/off-default rule to gating; most rules default to `error`, dev/optional-dependency and component/store/inject/CSS/catalog rules default to `warn`, and opt-in rules (`private-type-leaks`, `deprecated-exports-in-use`, `security-*`, `prop-drilling`, `thin-wrapper`, `duplicate-prop-shape`, `coverage-gaps`, `feature-flags`, `require-suppression-reason`) default to `off`. Singular aliases (`unused-file`) and `warning`/`none` severity spellings are accepted.",
|
|
194
194
|
"$ref": "#/$defs/RulesConfig",
|
|
195
195
|
"default": {
|
|
196
196
|
"unused-files": "error",
|
|
197
197
|
"unused-exports": "error",
|
|
198
198
|
"unused-types": "error",
|
|
199
199
|
"private-type-leaks": "off",
|
|
200
|
+
"deprecated-exports-in-use": "off",
|
|
200
201
|
"unused-dependencies": "error",
|
|
201
202
|
"unused-dev-dependencies": "warn",
|
|
202
203
|
"unused-optional-dependencies": "warn",
|
|
@@ -220,6 +221,9 @@
|
|
|
220
221
|
"css-selector-complexity": "warn",
|
|
221
222
|
"css-dead-surface": "warn",
|
|
222
223
|
"css-broken-reference": "warn",
|
|
224
|
+
"complexity-cyclomatic": "error",
|
|
225
|
+
"complexity-cognitive": "error",
|
|
226
|
+
"complexity-crap": "error",
|
|
223
227
|
"unresolved-imports": "error",
|
|
224
228
|
"unlisted-dependencies": "error",
|
|
225
229
|
"duplicate-exports": "error",
|
|
@@ -363,7 +367,12 @@
|
|
|
363
367
|
"default": false
|
|
364
368
|
},
|
|
365
369
|
"autoImports": {
|
|
366
|
-
"description": "When true, drops Nuxt convention-based entry-pattern fallbacks so genuinely-unreferenced convention files surface as unused-file. Component fallbacks are kept when nuxt.config customizes components: in a way fallow does not model, and composable/util fallbacks are kept when it customizes imports:; a config that scans no more than the Nuxt defaults (components: false, components: [], components: { dirs: [] }, components: true, imports: { scan: false }, imports: {}, imports: { dirs: [] }) is treated like the default and its fallbacks are dropped; imports: { autoImport: false } on its own is not, because it only switches the injection off while the same directories stay registered behind #imports. A nuxt.config that carries any top-level key fallow cannot read statically, a computed key, an accessor, or a spread such as { ...base, devtools: {} }, keeps both surfaces' fallbacks for that root, because the spread may hold the keys that decide. Each root is classified on its own config, so one custom nuxt.config in a monorepo does not keep every other workspace's fallbacks. Component names follow Nuxt: a component under components/global or components/islands is named after its own directory (components/global/Foo.vue is `<Foo>`), and .client, .server, .global and .island suffixes are stripped. A name imported or re-exported by hand from #components or #imports credits its convention file just like a template tag or a bare call; a namespace import names nothing and credits nothing. Boolean, defaults to false; set it for a Nuxt project that has explicitly configured its auto-import directories. Synthesis of auto-import graph edges (resolving `<Card />` or `useUserStore()` to their convention files) happens regardless of this flag.",
|
|
370
|
+
"description": "When true, drops Nuxt convention-based entry-pattern fallbacks so genuinely-unreferenced convention files surface as unused-file. Component fallbacks are kept when nuxt.config customizes components: in a way fallow does not model, and composable/util fallbacks are kept when it customizes imports:; a config that scans no more than the Nuxt defaults (components: false, components: [], components: { dirs: [] }, components: true, imports: { scan: false }, imports: {}, imports: { dirs: [] }) is treated like the default and its fallbacks are dropped; imports: { autoImport: false } on its own is not, because it only switches the injection off while the same directories stay registered behind #imports. A nuxt.config that carries any top-level key fallow cannot read statically, a computed key, an accessor, or a spread such as { ...base, devtools: {} }, keeps both surfaces' fallbacks for that root, because the spread may hold the keys that decide. Only top-level keys count when the config object is readable: a nested key such as a routeRules path ending in components does not keep a fallback. Nested components or imports keys in $production, $development, $test or `$env.<name>`, and components or imports hooks (a components:* key or a nested components object in hooks, also inside those overrides), count as that surface's key; such an override object or hooks object that fallow cannot read statically falls back to a text match for the keys. Each root is classified on its own config plus the configs of its local layers, so one custom nuxt.config in a monorepo does not keep every other workspace's fallbacks. A local layer is a directory named in extends, or a `layers/<name>` directory, that holds a nuxt.config; its convention files are entry points with the flag off and auto-import sources with it on, and `#layers/<name>/` resolves to it by its $meta.name (a `layers/<name>` directory without one uses its directory name). A remote or package layer is only a dependency reference. Component names follow Nuxt: a component under components/global or components/islands is named after its own directory (components/global/Foo.vue is `<Foo>`), and .client, .server, .global and .island suffixes are stripped. A name imported or re-exported by hand from #components or #imports credits its convention file just like a template tag or a bare call; a namespace import names nothing and credits nothing. Boolean, defaults to false; set it for a Nuxt project that has explicitly configured its auto-import directories. Synthesis of auto-import graph edges (resolving `<Card />` or `useUserStore()` to their convention files) happens regardless of this flag.",
|
|
371
|
+
"type": "boolean",
|
|
372
|
+
"default": false
|
|
373
|
+
},
|
|
374
|
+
"failOnParseError": {
|
|
375
|
+
"description": "When true, the run fails with exit code 1 if fallow could not parse a source file cleanly (a `source-parse-degraded` entry in `workspace_diagnostics[]`), and the `parse-error` entry of `gate_outcomes` names each such file. Boolean, defaults to false, so a file the parser rejects only warns. Applies to `fallow dead-code`, `fallow health`, `fallow audit` and the bare `fallow` run; the CLI flag `--fail-on-parse-error` arms the same gate for one run. Older fallow versions reject this key as unknown, so pair it with `minimumVersion` set to the release that added it.",
|
|
367
376
|
"type": "boolean",
|
|
368
377
|
"default": false
|
|
369
378
|
},
|
|
@@ -1055,7 +1064,7 @@
|
|
|
1055
1064
|
"default": 15
|
|
1056
1065
|
},
|
|
1057
1066
|
"maxCrap": {
|
|
1058
|
-
"description": "Maximum allowed CRAP (Change Risk Anti-Patterns) score per function\n(default: 30.0). CRAP combines cyclomatic complexity with test\ncoverage: high complexity plus low coverage produces a high CRAP\nscore. Functions meeting or exceeding this threshold are reported.\nUse `--coverage` with Istanbul data for accurate per-function CRAP;\notherwise fallow estimates coverage from the module graph. Governs\nfindings and the threshold-relative file-score signals\n(`crap_above_threshold`, the `risk` triage tag, and the\n`add_test_coverage` refactoring target); measured values such as\n`crap_max` and the overall health score never move with it. Set to\n`0` to disable CRAP enforcement entirely: no findings, nothing counts\nabove threshold, and file-score rows disclose baseline breaches as\nexempt instead.",
|
|
1067
|
+
"description": "Maximum allowed CRAP (Change Risk Anti-Patterns) score per function\n(default: 30.0). CRAP combines cyclomatic complexity with test\ncoverage: high complexity plus low coverage produces a high CRAP\nscore. Functions meeting or exceeding this threshold are reported.\nUse `--coverage` with Istanbul data for accurate per-function CRAP;\notherwise fallow estimates coverage from the module graph. Governs\nfindings and the threshold-relative file-score signals\n(`crap_above_threshold`, the `risk` triage tag, and the\n`add_test_coverage` refactoring target); measured values such as\n`crap_max` and the overall health score never move with it. Set to\n`0` to disable CRAP enforcement entirely: no findings, nothing counts\nabove threshold, and file-score rows disclose baseline breaches as\nexempt instead. The `complexity-crap` rule is different: it decides if\na finding fails the run, and `off` hides the findings but keeps the\nfile-score signals.",
|
|
1059
1068
|
"type": "number",
|
|
1060
1069
|
"format": "double",
|
|
1061
1070
|
"default": 30.0
|
|
@@ -1076,7 +1085,7 @@
|
|
|
1076
1085
|
"default": 60
|
|
1077
1086
|
},
|
|
1078
1087
|
"coverage": {
|
|
1079
|
-
"description": "Path to Istanbul
|
|
1088
|
+
"description": "Path to Istanbul coverage data (coverage-final.json) or raw V8 coverage\n(a `NODE_V8_COVERAGE` directory or one V8 JSON file) for accurate\nper-function CRAP scores. Relative paths resolve against the project root. The CLI\n`--coverage` flag and `FALLOW_COVERAGE` environment variable override\nthis value. Consulted by `fallow health`, bare `fallow`, `fallow audit`,\n`fallow viz`, and the MCP `audit` / `check_health` tools.",
|
|
1080
1089
|
"type": [
|
|
1081
1090
|
"string",
|
|
1082
1091
|
"null"
|
|
@@ -1310,6 +1319,11 @@
|
|
|
1310
1319
|
"$ref": "#/$defs/Severity",
|
|
1311
1320
|
"default": "off"
|
|
1312
1321
|
},
|
|
1322
|
+
"deprecated-exports-in-use": {
|
|
1323
|
+
"description": "An export marked `@deprecated` that still has at least one reachable\nreference. Opt-in; defaults to `off`. A per-path override resolves on\nthe file that declares the export, not on the consumer.",
|
|
1324
|
+
"$ref": "#/$defs/Severity",
|
|
1325
|
+
"default": "off"
|
|
1326
|
+
},
|
|
1313
1327
|
"unused-dependencies": {
|
|
1314
1328
|
"description": "A declared `dependencies` entry never observed used. Defaults to\n`error`.",
|
|
1315
1329
|
"$ref": "#/$defs/Severity",
|
|
@@ -1425,6 +1439,21 @@
|
|
|
1425
1439
|
"$ref": "#/$defs/Severity",
|
|
1426
1440
|
"default": "warn"
|
|
1427
1441
|
},
|
|
1442
|
+
"complexity-cyclomatic": {
|
|
1443
|
+
"description": "A function above the cyclomatic ceiling (`health.maxCyclomatic` or a\n`thresholdOverrides` entry). The threshold decides if the finding\nexists; this rule decides if it fails the run. Defaults to `error`.\n`warn` reports the finding without a failure, and `off` hides it. A\nfinding above several ceilings takes the most severe of their rules.\nThe rule applies before the `health --min-severity` band gate.\nAfter you set a kind to `off`, save the health baseline again: its\nentries for the hidden findings no longer match.",
|
|
1444
|
+
"$ref": "#/$defs/Severity",
|
|
1445
|
+
"default": "error"
|
|
1446
|
+
},
|
|
1447
|
+
"complexity-cognitive": {
|
|
1448
|
+
"description": "A function above the cognitive ceiling (`health.maxCognitive` or a\n`thresholdOverrides` entry). The threshold decides if the finding\nexists; this rule decides if it fails the run. Defaults to `error`.",
|
|
1449
|
+
"$ref": "#/$defs/Severity",
|
|
1450
|
+
"default": "error"
|
|
1451
|
+
},
|
|
1452
|
+
"complexity-crap": {
|
|
1453
|
+
"description": "A function above the CRAP ceiling (`health.maxCrap` or a\n`thresholdOverrides` entry). The threshold decides if the finding\nexists; this rule decides if it fails the run. Defaults to `error`.\n`off` hides the findings only. `health.maxCrap: 0` also turns off the\nthreshold-relative file-score signals.",
|
|
1454
|
+
"$ref": "#/$defs/Severity",
|
|
1455
|
+
"default": "error"
|
|
1456
|
+
},
|
|
1428
1457
|
"unresolved-imports": {
|
|
1429
1458
|
"description": "An import specifier that resolves to no file or package. Defaults to\n`error`.",
|
|
1430
1459
|
"$ref": "#/$defs/Severity",
|
|
@@ -2049,6 +2078,17 @@
|
|
|
2049
2078
|
}
|
|
2050
2079
|
]
|
|
2051
2080
|
},
|
|
2081
|
+
"deprecated-exports-in-use": {
|
|
2082
|
+
"description": "Optional override for [`RulesConfig::deprecated_exports_in_use`].",
|
|
2083
|
+
"anyOf": [
|
|
2084
|
+
{
|
|
2085
|
+
"$ref": "#/$defs/Severity"
|
|
2086
|
+
},
|
|
2087
|
+
{
|
|
2088
|
+
"type": "null"
|
|
2089
|
+
}
|
|
2090
|
+
]
|
|
2091
|
+
},
|
|
2052
2092
|
"unused-dependencies": {
|
|
2053
2093
|
"description": "Optional override for [`RulesConfig::unused_dependencies`].",
|
|
2054
2094
|
"anyOf": [
|
|
@@ -2302,6 +2342,39 @@
|
|
|
2302
2342
|
}
|
|
2303
2343
|
]
|
|
2304
2344
|
},
|
|
2345
|
+
"complexity-cyclomatic": {
|
|
2346
|
+
"description": "Optional override for [`RulesConfig::complexity_cyclomatic`].",
|
|
2347
|
+
"anyOf": [
|
|
2348
|
+
{
|
|
2349
|
+
"$ref": "#/$defs/Severity"
|
|
2350
|
+
},
|
|
2351
|
+
{
|
|
2352
|
+
"type": "null"
|
|
2353
|
+
}
|
|
2354
|
+
]
|
|
2355
|
+
},
|
|
2356
|
+
"complexity-cognitive": {
|
|
2357
|
+
"description": "Optional override for [`RulesConfig::complexity_cognitive`].",
|
|
2358
|
+
"anyOf": [
|
|
2359
|
+
{
|
|
2360
|
+
"$ref": "#/$defs/Severity"
|
|
2361
|
+
},
|
|
2362
|
+
{
|
|
2363
|
+
"type": "null"
|
|
2364
|
+
}
|
|
2365
|
+
]
|
|
2366
|
+
},
|
|
2367
|
+
"complexity-crap": {
|
|
2368
|
+
"description": "Optional override for [`RulesConfig::complexity_crap`].",
|
|
2369
|
+
"anyOf": [
|
|
2370
|
+
{
|
|
2371
|
+
"$ref": "#/$defs/Severity"
|
|
2372
|
+
},
|
|
2373
|
+
{
|
|
2374
|
+
"type": "null"
|
|
2375
|
+
}
|
|
2376
|
+
]
|
|
2377
|
+
},
|
|
2305
2378
|
"unresolved-imports": {
|
|
2306
2379
|
"description": "Optional override for [`RulesConfig::unresolved_imports`].",
|
|
2307
2380
|
"anyOf": [
|