fallow 2.104.0 → 3.1.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,7 +1,7 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "2.104.0",
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.",
3
+ "version": "3.1.0",
4
+ "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.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -51,7 +51,9 @@
51
51
  "./bin/*": "./bin/*",
52
52
  "./scripts/*": "./scripts/*",
53
53
  "./skills/*": "./skills/*",
54
- "./schema.json": "./schema.json"
54
+ "./schema.json": "./schema.json",
55
+ "./capabilities.json": "./capabilities.json",
56
+ "./issue-registry.json": "./issue-registry.json"
55
57
  },
56
58
  "typesVersions": {
57
59
  "*": {
@@ -67,7 +69,9 @@
67
69
  "!skills/_artifacts",
68
70
  "types",
69
71
  "README.md",
70
- "schema.json"
72
+ "schema.json",
73
+ "capabilities.json",
74
+ "issue-registry.json"
71
75
  ],
72
76
  "scripts": {
73
77
  "test:platform": "node --test scripts/platform-package.test.js",
@@ -83,13 +87,13 @@
83
87
  "@tanstack/intent": "0.3.2"
84
88
  },
85
89
  "optionalDependencies": {
86
- "@fallow-cli/darwin-arm64": "2.104.0",
87
- "@fallow-cli/darwin-x64": "2.104.0",
88
- "@fallow-cli/linux-x64-gnu": "2.104.0",
89
- "@fallow-cli/linux-arm64-gnu": "2.104.0",
90
- "@fallow-cli/linux-x64-musl": "2.104.0",
91
- "@fallow-cli/linux-arm64-musl": "2.104.0",
92
- "@fallow-cli/win32-arm64-msvc": "2.104.0",
93
- "@fallow-cli/win32-x64-msvc": "2.104.0"
90
+ "@fallow-cli/darwin-arm64": "3.1.0",
91
+ "@fallow-cli/darwin-x64": "3.1.0",
92
+ "@fallow-cli/linux-x64-gnu": "3.1.0",
93
+ "@fallow-cli/linux-arm64-gnu": "3.1.0",
94
+ "@fallow-cli/linux-x64-musl": "3.1.0",
95
+ "@fallow-cli/linux-arm64-musl": "3.1.0",
96
+ "@fallow-cli/win32-arm64-msvc": "3.1.0",
97
+ "@fallow-cli/win32-x64-msvc": "3.1.0"
94
98
  }
95
99
  }
package/schema.json CHANGED
@@ -167,11 +167,17 @@
167
167
  "prop-drilling": "off",
168
168
  "thin-wrapper": "off",
169
169
  "duplicate-prop-shape": "off",
170
+ "css-token-drift": "warn",
171
+ "css-duplicate-block": "warn",
172
+ "css-selector-complexity": "warn",
173
+ "css-dead-surface": "warn",
174
+ "css-broken-reference": "warn",
170
175
  "unresolved-imports": "error",
171
176
  "unlisted-dependencies": "error",
172
177
  "duplicate-exports": "error",
173
178
  "type-only-dependencies": "warn",
174
179
  "test-only-dependencies": "warn",
180
+ "dev-dependencies-in-production": "warn",
175
181
  "circular-dependencies": "error",
176
182
  "re-export-cycle": "warn",
177
183
  "boundary-violation": "error",
@@ -1037,37 +1043,37 @@
1037
1043
  "unused-store-members": {
1038
1044
  "description": "Store members (Pinia `state` / `getters` / `actions` key, or a\nsetup-store returned key) declared but never accessed by any consumer\nproject-wide. Defaults to `warn`, not `error` like the closed-set\nclass/enum member rules: a store has an OPEN declaration surface\n(plugins, `$onAction`, dynamic dispatch) so analyzer confidence is\ngenuinely lower; warn encodes that without failing CI. Promotable to\n`error` once validated on a codebase.",
1039
1045
  "$ref": "#/$defs/Severity",
1040
- "default": "error"
1046
+ "default": "warn"
1041
1047
  },
1042
1048
  "unprovided-injects": {
1043
1049
  "description": "Vue `inject(KEY)` / Svelte `getContext(KEY)` whose symbol KEY is\n`provide`/`setContext`'d nowhere in the project (the\ninjected-never-provided dead-half). Defaults to `warn`, not `error`:\na DI key has an open provide surface (plugins, app-level provide) so\nanalyzer confidence is lower; warn encodes that without failing CI.",
1044
1050
  "$ref": "#/$defs/Severity",
1045
- "default": "error"
1051
+ "default": "warn"
1046
1052
  },
1047
1053
  "unrendered-components": {
1048
1054
  "description": "Vue/Svelte single-file component reachable in the module graph but\nrendered nowhere in the project (the imported-but-never-rendered\ndead-half). Defaults to `warn`, not `error`: a component can be rendered\nreflectively (dynamic `<component :is>`), so analyzer confidence is\nlower; warn encodes that without failing CI.",
1049
1055
  "$ref": "#/$defs/Severity",
1050
- "default": "error"
1056
+ "default": "warn"
1051
1057
  },
1052
1058
  "unused-component-props": {
1053
1059
  "description": "Vue `<script setup>` `defineProps`, Svelte 5 `$props()`, or React\ndeclared prop referenced nowhere inside its own component. The\nsingle-component dead-input direction. Defaults to `warn`, not `error`: a\nprop can be part of a deliberately-stable public component API, so\nanalyzer confidence is lower; warn encodes that without failing CI.",
1054
1060
  "$ref": "#/$defs/Severity",
1055
- "default": "error"
1061
+ "default": "warn"
1056
1062
  },
1057
1063
  "unused-component-emits": {
1058
1064
  "description": "Vue `<script setup>` `defineEmits` declared event emitted nowhere inside\nits own single-file component (no `emit('<name>')` call). The single-file\ndead-input direction. Defaults to `warn`, not `error`: an emit can be part\nof a deliberately-stable public component API, so analyzer confidence is\nlower; warn encodes that without failing CI.",
1059
1065
  "$ref": "#/$defs/Severity",
1060
- "default": "error"
1066
+ "default": "warn"
1061
1067
  },
1062
1068
  "unused-component-inputs": {
1063
1069
  "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.",
1064
1070
  "$ref": "#/$defs/Severity",
1065
- "default": "error"
1071
+ "default": "warn"
1066
1072
  },
1067
1073
  "unused-component-outputs": {
1068
1074
  "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.",
1069
1075
  "$ref": "#/$defs/Severity",
1070
- "default": "error"
1076
+ "default": "warn"
1071
1077
  },
1072
1078
  "unused-svelte-events": {
1073
1079
  "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.",
@@ -1077,7 +1083,7 @@
1077
1083
  "unused-server-actions": {
1078
1084
  "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.",
1079
1085
  "$ref": "#/$defs/Severity",
1080
- "default": "error"
1086
+ "default": "warn"
1081
1087
  },
1082
1088
  "unused-load-data-keys": {
1083
1089
  "description": "SvelteKit `+page.{ts,server.ts,js,server.js}` `load()` return-object key\nread by no consumer: not off the sibling `+page.svelte`'s `data.<key>`,\nnor project-wide via `page.data.<key>` / `$page.data.<key>`. Cross-file\ndead-input direction. Defaults to `warn`, not `error`: the rule is new and\nfalse-negative-preferring (a whole-object `data` pass abstains), and a\nload fetch can have side effects so deletion is a human call; warn encodes\nthat without failing CI until corpus-validated.",
@@ -1099,6 +1105,31 @@
1099
1105
  "$ref": "#/$defs/Severity",
1100
1106
  "default": "off"
1101
1107
  },
1108
+ "css-token-drift": {
1109
+ "description": "A CSS / CSS-in-JS design-token DRIFT finding (a hardcoded value where a\ndesign token exists, e.g. a Tailwind arbitrary value). A styling-domain\nadvisory surfaced in `fallow audit`; defaults to `warn` (verdict-neutral).\nSet to `error` to gate CI on styling drift, or `off` to silence.",
1110
+ "$ref": "#/$defs/Severity",
1111
+ "default": "warn"
1112
+ },
1113
+ "css-duplicate-block": {
1114
+ "description": "A CSS / CSS-in-JS DUPLICATE declaration block (copy-pasted rule body).\nA styling-domain advisory surfaced in `fallow audit`; defaults to `warn`\n(verdict-neutral). Set to `error` to gate, or `off` to silence.",
1115
+ "$ref": "#/$defs/Severity",
1116
+ "default": "warn"
1117
+ },
1118
+ "css-selector-complexity": {
1119
+ "description": "CSS selector / nesting / important-density complexity. A styling-domain\nadvisory surfaced in `fallow audit`; defaults to `warn`\n(verdict-neutral). Set to `error` to gate, or `off` to silence.",
1120
+ "$ref": "#/$defs/Severity",
1121
+ "default": "warn"
1122
+ },
1123
+ "css-dead-surface": {
1124
+ "description": "CSS dead surface, such as unused scoped SFC classes. A styling-domain\nadvisory surfaced in `fallow audit`; defaults to `warn`\n(verdict-neutral). Set to `error` to gate, or `off` to silence.",
1125
+ "$ref": "#/$defs/Severity",
1126
+ "default": "warn"
1127
+ },
1128
+ "css-broken-reference": {
1129
+ "description": "CSS broken references, such as missing classes or keyframes. A\nstyling-domain advisory surfaced by deep CSS audit mode; defaults\nto `warn` (verdict-neutral). Set to `error` to gate, or `off` to silence.",
1130
+ "$ref": "#/$defs/Severity",
1131
+ "default": "warn"
1132
+ },
1102
1133
  "unresolved-imports": {
1103
1134
  "$ref": "#/$defs/Severity",
1104
1135
  "default": "error"
@@ -1119,6 +1150,10 @@
1119
1150
  "$ref": "#/$defs/Severity",
1120
1151
  "default": "warn"
1121
1152
  },
1153
+ "dev-dependencies-in-production": {
1154
+ "$ref": "#/$defs/Severity",
1155
+ "default": "warn"
1156
+ },
1122
1157
  "circular-dependencies": {
1123
1158
  "$ref": "#/$defs/Severity",
1124
1159
  "default": "error"
@@ -1133,7 +1168,7 @@
1133
1168
  },
1134
1169
  "coverage-gaps": {
1135
1170
  "$ref": "#/$defs/Severity",
1136
- "default": "error"
1171
+ "default": "off"
1137
1172
  },
1138
1173
  "feature-flags": {
1139
1174
  "$ref": "#/$defs/Severity",
@@ -1852,6 +1887,56 @@
1852
1887
  }
1853
1888
  ]
1854
1889
  },
1890
+ "css-token-drift": {
1891
+ "anyOf": [
1892
+ {
1893
+ "$ref": "#/$defs/Severity"
1894
+ },
1895
+ {
1896
+ "type": "null"
1897
+ }
1898
+ ]
1899
+ },
1900
+ "css-duplicate-block": {
1901
+ "anyOf": [
1902
+ {
1903
+ "$ref": "#/$defs/Severity"
1904
+ },
1905
+ {
1906
+ "type": "null"
1907
+ }
1908
+ ]
1909
+ },
1910
+ "css-selector-complexity": {
1911
+ "anyOf": [
1912
+ {
1913
+ "$ref": "#/$defs/Severity"
1914
+ },
1915
+ {
1916
+ "type": "null"
1917
+ }
1918
+ ]
1919
+ },
1920
+ "css-dead-surface": {
1921
+ "anyOf": [
1922
+ {
1923
+ "$ref": "#/$defs/Severity"
1924
+ },
1925
+ {
1926
+ "type": "null"
1927
+ }
1928
+ ]
1929
+ },
1930
+ "css-broken-reference": {
1931
+ "anyOf": [
1932
+ {
1933
+ "$ref": "#/$defs/Severity"
1934
+ },
1935
+ {
1936
+ "type": "null"
1937
+ }
1938
+ ]
1939
+ },
1855
1940
  "unresolved-imports": {
1856
1941
  "anyOf": [
1857
1942
  {
@@ -1902,6 +1987,16 @@
1902
1987
  }
1903
1988
  ]
1904
1989
  },
1990
+ "dev-dependencies-in-production": {
1991
+ "anyOf": [
1992
+ {
1993
+ "$ref": "#/$defs/Severity"
1994
+ },
1995
+ {
1996
+ "type": "null"
1997
+ }
1998
+ ]
1999
+ },
1905
2000
  "circular-dependencies": {
1906
2001
  "anyOf": [
1907
2002
  {
@@ -2218,6 +2313,12 @@
2218
2313
  "minimum": 0,
2219
2314
  "default": 0
2220
2315
  },
2316
+ "devDependenciesInProduction": {
2317
+ "type": "integer",
2318
+ "format": "uint",
2319
+ "minimum": 0,
2320
+ "default": 0
2321
+ },
2221
2322
  "boundaryViolations": {
2222
2323
  "type": "integer",
2223
2324
  "format": "uint",
@@ -2250,6 +2351,18 @@
2250
2351
  "gate": {
2251
2352
  "$ref": "#/$defs/AuditGate"
2252
2353
  },
2354
+ "css": {
2355
+ "type": [
2356
+ "boolean",
2357
+ "null"
2358
+ ]
2359
+ },
2360
+ "cssDeep": {
2361
+ "type": [
2362
+ "boolean",
2363
+ "null"
2364
+ ]
2365
+ },
2253
2366
  "deadCodeBaseline": {
2254
2367
  "type": [
2255
2368
  "string",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fallow
3
- description: Codebase intelligence for JavaScript and TypeScript. Free static layer reports quality, changed-code risk, cleanup opportunities (unused files, exports, types, dependencies), code duplication, circular dependencies, complexity hotspots, architecture boundary violations, feature flag patterns, and opt-in security candidates. Runtime coverage merges production execution data into the same health report for hot-path review, cold-path deletion confidence, and stale-flag evidence, with a single local capture available by default and continuous/cloud runtime monitoring available as an optional mode. 123 framework plugins, zero configuration, sub-second static analysis. Use when asked to analyze code health, audit PR risk, find cleanup opportunities or unused code, detect duplicates, check circular dependencies, audit complexity, check architecture boundaries, detect feature flags, surface security candidates, clean up the codebase, auto-fix issues, merge runtime coverage, or run fallow.
3
+ description: Codebase intelligence for TypeScript and JavaScript. Static analysis of code and styles reports changed-code risk, cleanup opportunities, duplication, circular dependencies, complexity hotspots, architecture boundaries, design-system drift, feature flags, and opt-in security candidates. Runtime coverage can merge production execution data for hot-path review, cold-path deletion confidence, and stale-flag evidence. 123 framework plugins, zero configuration, sub-second static analysis. Use when asked to audit PR risk, find unused code or dependencies, detect duplicates, check styling consistency, inspect architecture boundaries, merge runtime coverage, auto-fix supported issues, or run fallow.
4
4
  license: MIT
5
5
  metadata:
6
6
  author: Bart Waardenburg
@@ -8,27 +8,22 @@ metadata:
8
8
  homepage: https://docs.fallow.tools
9
9
  ---
10
10
 
11
- # Fallow: codebase intelligence for JavaScript and TypeScript
11
+ # Fallow: codebase intelligence for TypeScript and JavaScript
12
12
 
13
- Codebase intelligence for JavaScript and TypeScript. The free static layer reports quality, changed-code risk, cleanup opportunities, circular dependencies, code duplication, complexity hotspots, architecture boundary violations, feature flag patterns, and opt-in security candidates. Runtime coverage merges production execution data into the same `fallow health` report for hot-path review, cold-path deletion confidence, and stale-flag evidence, with a single local capture available by default and continuous/cloud runtime monitoring available as an optional mode. 123 framework plugins, zero configuration, sub-second static analysis.
13
+ Codebase intelligence for TypeScript and JavaScript. The static layer analyzes code and styles and reports quality, changed-code risk, cleanup opportunities, circular dependencies, code duplication, complexity hotspots, architecture boundary violations, design-system styling drift, feature flag patterns, and opt-in security candidates. Runtime coverage merges production execution data into the same `fallow health` report for hot-path review, cold-path deletion confidence, and stale-flag evidence, with a single local capture available by default and continuous/cloud runtime monitoring available as an optional mode. 123 framework plugins, zero configuration, sub-second static analysis.
14
14
 
15
15
  ## When to Use
16
- - Finding cleanup opportunities (unused files, exports, types, enum/class members)
17
- - Finding unused or unlisted dependencies
18
- - Detecting code duplication and clones
19
- - Checking code health and complexity hotspots
20
- - Cleaning up a codebase before a release or refactor
21
- - Auditing a project for structural issues
22
- - Setting up CI quality gates or duplication thresholds
23
- - Auto-fixing unused exports and dependencies
24
- - Detecting feature flag patterns (environment gates, SDK calls, config objects) with `fallow flags`
25
- - Investigating why a specific export or file appears unused
26
- - Surfacing local security candidates for an agent to verify (`fallow security`)
27
- - Finding untested but runtime-reachable code (`fallow health --coverage-gaps`)
28
- - Ranking complexity hotspots, code owners, and refactoring targets (`fallow health --hotspots --ownership --targets`)
29
- - Gating CI on regressions with baselines (`--save-baseline` / `--save-regression-baseline`)
30
- - Explaining an issue type or why a function scored high (`fallow explain`, `fallow health --complexity-breakdown`)
31
- - Reviewing what fallow has surfaced over time (`fallow impact`)
16
+ - Find cleanup opportunities: unused files, exports, types, members, dependencies, or stale flags.
17
+ - Detect code duplication, circular dependencies, architecture boundary issues, and complexity hotspots.
18
+ - Check styling consistency, CSS dead surface, and design-token drift.
19
+ - Audit changed code before a commit, PR, release, or refactor.
20
+ - Set up CI quality gates, duplication thresholds, and regression baselines.
21
+ - Auto-fix supported unused exports and dependencies after `--dry-run`.
22
+ - Investigate why a specific export, dependency, file, or issue type was reported.
23
+ - Surface local security candidates for an agent to verify (`fallow security`).
24
+ - Find untested but runtime-reachable code (`fallow health --coverage-gaps`).
25
+ - Rank complexity hotspots, owners, and refactoring targets (`fallow health --hotspots --ownership --targets`).
26
+ - Review what fallow has surfaced over time (`fallow impact`).
32
27
 
33
28
  ## When NOT to Use
34
29
  - Runtime error analysis or debugging
@@ -43,11 +38,9 @@ Codebase intelligence for JavaScript and TypeScript. The free static layer repor
43
38
  Fallow must be installed. If not available, install it:
44
39
 
45
40
  ```bash
46
- npm install -g fallow # prebuilt binaries (fastest)
47
- # or
48
- npx fallow dead-code # run without installing
49
- # or
50
- cargo install fallow-cli # build from source
41
+ npm install -g fallow # prebuilt binaries (fastest, recommended)
42
+ npx fallow dead-code # run without installing
43
+ cargo install fallow-cli # build from source
51
44
  ```
52
45
 
53
46
  ## Agent Rules
@@ -79,6 +72,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
79
72
  | check untested-but-reachable code | `fallow health --coverage-gaps` |
80
73
  | consolidate duplication | `fallow dupes --trace dup:<fingerprint>` |
81
74
  | find feature flags | `fallow flags` |
75
+ | check which architecture rules apply to a file before changing it | `fallow guard <files>` |
82
76
  | surface security candidates | `fallow security` |
83
77
  | understand a finding | `fallow explain <issue-type>` |
84
78
  | scope a monorepo | `--workspace <glob> / --changed-workspaces <ref>`; global flags, prefix any command |
@@ -102,6 +96,8 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
102
96
  | `config-schema` | Print the JSON Schema for fallow configuration files | |
103
97
  | `plugin-schema` | Print the JSON Schema for external plugin files | |
104
98
  | `rule-pack-schema` | Print the JSON Schema for rule pack files | |
99
+ | `rule-pack` | Manage declarative rule packs (policy-as-code) | |
100
+ | `guard` | Show which architecture rules apply to files before changing them | `files` |
105
101
  | `config` | Show the loaded config path and resolved config (verifies which `.fallowrc.json` is in effect) | `--path` |
106
102
  | `list` | Inspect project structure | `--files`, `--entry-points`, `--plugins`, `--boundaries`, `--workspaces` |
107
103
  | `workspaces` | Inspect monorepo workspaces + discovery diagnostics (shorthand for `list --workspaces`) | (no flags) |
@@ -109,7 +105,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
109
105
  | `health` | Function complexity analysis (also covers Angular templates as synthetic `<template>` findings: external `.html` files via `templateUrl` AND inline `@Component({ template: \`...\` })` literals; suppress external with `<!-- fallow-ignore-file complexity -->` at the top of the `.html` file, suppress inline with `// fallow-ignore-next-line complexity` directly above the `@Component` decorator) | `--complexity`, `--max-cyclomatic`, `--max-cognitive`, `--max-crap`, `--top`, `--sort`, `--file-scores`, `--hotspots`, `--ownership`, `--ownership-emails`, `--targets`, `--effort`, `--score`, `--min-score`, `--since`, `--min-commits`, `--save-snapshot`, `--trend`, `--coverage-gaps`, `--coverage`, `--coverage-root`, `--runtime-coverage`, `--min-invocations-hot`, `--min-observation-volume`, `--low-traffic-threshold`, `--css`, `--complexity-breakdown`, `--min-severity`, `--report-only`, `--workspace`, `--changed-workspaces`, `--baseline`, `--save-baseline` |
110
106
  | `flags` | Detect feature flag patterns (env vars, SDK calls, config objects) | `--top` |
111
107
  | `explain` | Explain one issue type without running analysis | `<issue-type>`, `--format json` |
112
- | `audit` | Combined dead-code + complexity + duplication for changed files, returns a verdict; `fallow review` is an alias for `fallow audit --brief` (advisory orientation brief, always exits 0) | `--base`, `--gate`, `--brief`, `--max-decisions`, `--walkthrough-guide`, `--walkthrough-file`, `--show-deprioritized`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--workspace`, `--changed-workspaces`, `--ci`, `--fail-on-issues`, `--explain`, `--explain-skipped`, `--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`, `--max-crap`, `--coverage`, `--coverage-root`, `--include-entry-exports` |
108
+ | `audit` | Combined dead-code + complexity + duplication + styling for changed files, returns a verdict; `fallow review` is an alias for `fallow audit --brief` (advisory orientation brief, always exits 0) | `--base`, `--gate`, `--brief`, `--max-decisions`, `--walkthrough-guide`, `--walkthrough-file`, `--show-deprioritized`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--workspace`, `--changed-workspaces`, `--ci`, `--fail-on-issues`, `--explain`, `--explain-skipped`, `--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`, `--max-crap`, `--coverage`, `--coverage-root`, `--no-css`, `--css-deep`, `--no-css-deep`, `--include-entry-exports` |
113
109
  | `decision-surface` | Surface the consequential structural DECISIONS a change embeds (the apex of the review brief), each framed as a judgment question with the routed expert to ask | `--max-decisions` |
114
110
  | `impact` | Show what fallow has done for you: how many issues it is surfacing, the trend since the last recorded run, and how many commits it contained at the pre-commit gate | `--all`, `--sort`, `--limit` |
115
111
  | `security` | Surface opt-in local security candidates for agent verification (not confirmed vulnerabilities). Rule families include the graph rule `client-server-leak`, a data-driven `tainted-sink` catalogue, and the include-required `hardcoded-secret` category for provider-prefix credentials and high-entropy literals assigned to secret-shaped identifiers. Most catalogue rows require non-literal input; narrowly literal-aware rows flag deterministic unsafe literals. Rules default off; suppress a file with `// fallow-ignore-file security-sink`; scope categories with `security.categories`. Add project-local request object names with `security.requestReceivers`; it extends the built-in `req` / `request` / `ctx` / `context` / `event` allowlist for HTTP `query`, `params`, and `body` reads. `hardcoded-secret` runs only when listed in `security.categories.include`. | `--format human\|json\|sarif`, `--changed-since`, `--file`, `--diff-file`, `--workspace`, `--changed-workspaces`, `--surface`, `--ci`, `--fail-on-issues`, `--sarif-file`, `--summary` |
@@ -139,6 +135,7 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
139
135
  | `unused-optional-dependency` | `--unused-deps` | yes | - | Packages in `optionalDependencies` never imported (often platform-specific; verify before removing) |
140
136
  | `type-only-dependency` | `--unused-deps` | - | - | Production dependency only used via type-only imports; Only reported in --production mode; --unused-deps scopes it together with the other dependency kinds |
141
137
  | `test-only-dependency` | `--unused-deps` | - | - | Production deps only imported from test files (should be devDependencies) |
138
+ | `dev-dependency-in-production` | `--unused-deps` | - | - | devDependency imported by production code with a runtime import |
142
139
  | `unused-enum-member` | `--unused-enum-members` | yes | `// fallow-ignore-next-line unused-enum-member` | Enum values never referenced |
143
140
  | `unused-class-member` | `--unused-class-members` | - | `// fallow-ignore-next-line unused-class-member` | Methods and properties |
144
141
  | `unused-store-member` | `--unused-store-members` | - | `// fallow-ignore-next-line unused-store-member` | Pinia store state/getter/action (needs `pinia` dep) |
@@ -152,7 +149,7 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
152
149
  | `boundary-call-violation` | `--boundary-violations` | - | `// fallow-ignore-next-line boundary-call-violation` | Zoned file calls a callee its zone forbids; Requires boundaries.calls.forbidden patterns |
153
150
  | `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls, imports, or catalogue-derived effects banned by a declarative rule pack (`rulePacks` config key lists standalone JSON/JSONC files of `banned-call`, `banned-import`, and `banned-effect` rules; pure data, no project code executes). Findings identified as `<pack>/<rule-id>`. Default `warn` master; per-rule `severity` overrides per finding and the exit gate reads the effective severity. Invalid or missing packs fail config load with exit 2. `fallow rule-pack-schema` prints the pack JSON Schema. Use the scoped token to suppress one rule; bare `policy-violation` still covers every pack rule on the line or file. |
154
151
  | `stale-suppression` | `--stale-suppressions` | - | - | `fallow-ignore` comments or `@expected-unused` JSDoc tags that no longer match any issue |
155
- | `missing-suppression-reason` | - | - | - | Suppression comment omits a required reason |
152
+ | `missing-suppression-reason` | `--stale-suppressions` | - | - | Suppression comment omits a required reason |
156
153
  | `unused-catalog-entry` | `--unused-catalog-entries` | yes | - | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
157
154
  | `empty-catalog-group` | `--empty-catalog-groups` | - | - | Named `catalogs.<name>:` groups in `pnpm-workspace.yaml` with no entries. Top-level `catalog:` placeholders are ignored. Default `warn`. |
158
155
  | `unresolved-catalog-reference` | `--unresolved-catalog-references` | - | - | `package.json` references to `catalog:` / `catalog:<name>` whose catalog does not declare the package; `pnpm install` would fail. Default `error`. Suppress via `ignoreCatalogReferences: [{ package, catalog?, consumer? }]` in fallow config (package.json has no comment syntax). |
@@ -180,6 +177,11 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
180
177
  | `high-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function exceeds both complexity thresholds |
181
178
  | `high-crap-score` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has a high CRAP score (complexity combined with low coverage) |
182
179
  | `refactoring-target` | `--targets` | - | - | File identified as a high-priority refactoring candidate |
180
+ | `css-token-drift` | - | - | `// fallow-ignore-next-line css-token-drift` | CSS or CSS-in-JS hardcoded styling value bypasses the design token system |
181
+ | `css-duplicate-block` | - | - | `// fallow-ignore-next-line css-duplicate-block` | CSS or CSS-in-JS declaration block is duplicated across rules |
182
+ | `css-selector-complexity` | - | - | `// fallow-ignore-next-line css-selector-complexity` | CSS selector, nesting, or important usage is structurally complex |
183
+ | `css-dead-surface` | - | - | `// fallow-ignore-next-line css-dead-surface` | CSS or CSS-in-JS surface appears unused |
184
+ | `css-broken-reference` | - | - | `// fallow-ignore-next-line css-broken-reference` | CSS or CSS-in-JS reference resolves to no stylesheet definition |
183
185
  | `untested-file` | `--coverage-gaps` | - | `// fallow-ignore-file coverage-gaps` | Runtime-reachable file has no test dependency path |
184
186
  | `untested-export` | `--coverage-gaps` | - | `// fallow-ignore-file coverage-gaps` | Runtime-reachable export has no test dependency path |
185
187
  | `code-duplication` | - | - | `// fallow-ignore-next-line code-duplication` | Duplicated code block; Reported by fallow dupes (and bare fallow / fallow audit) |
@@ -203,15 +205,16 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
203
205
  | `check_changed` | analysis | free | `since`, `baseline`, `fail_on_regression` | Incremental analysis of files changed since a git ref |
204
206
  | `security_candidates` | analysis | free | `gate`, `surface`, `changed_since`, `paths` | Unverified local security candidates, not confirmed vulnerabilities (`fallow security --format json`). Read `security_findings[]` for category, CWE, severity, evidence, trace, optional `reachability`, blind-spot counters, and optional `unresolved_callee_diagnostics` samples for dynamic callee follow-up. `severity` is a review-priority tier, not a verified vulnerability verdict. Each finding also carries an agent-actionable `candidate` (`source_kind`/`sink`/`boundary`), where URL-category sinks may include `url_shape` (`fixed-origin-dynamic-path` or `dynamic-origin`), an optional `taint_flow` source-to-sink triple, and a stable `finding_id` (equal to the SARIF fingerprint) for cross-run correlation; there is no `impact` field (deciding exploitability is the agent's job). Set `surface: true` to include top-level `attack_surface[]` entries with defensive-boundary prompts for a verifier. Set `gate` to `new` for changed-line candidates or `newly-reachable` for candidates that became reachable from entry points; `newly-reachable` requires `changed_since`. `reachability.untrusted_source_trace` is module-level import context only and does not prove value flow; `reachability.taint_confidence` tiers each reachable candidate as `arg-level` (sink argument traces to a same-module source read, strong) or `module-level` (only the module is import-reachable from a source, weak), so tier from this field instead of the evidence text. Verify trace, reachability context, severity, and evidence before editing code. Supports `root`, `config`, `workspace`, `paths`, `changed_since`, `changed_workspaces`, `surface`, `gate`, `no_cache`, and `threads`; `paths` forwards repeated `fallow security --file` filters for finding anchors, trace hops, untrusted-source reachability trace hops, and unresolved-callee diagnostics. See <https://docs.fallow.tools/cli/security-agent-verification> for the verifier packet and verdict recipe. Inherits `FALLOW_DIFF_FILE` from the server environment for line-level diff scoping; raise `FALLOW_TIMEOUT_SECS` for large repos. |
205
207
  | `inspect_target` | analysis | free | `target`, `production` | Compose one evidence bundle for a file or exported symbol. File targets use `target: { type: "file", file }`; symbol targets use `target: { type: "symbol", file, export_name }`. Returns `kind: "inspect_target"`, normalized target identity, `trace_file`, optional `trace_export`, file-scoped dead-code actions, duplication groups filtered to the file, complexity findings filtered to the file, and security candidates scoped to the file. Evidence sections carry `status` and `scope`; symbol targets warn when supporting evidence is file-scoped. Supports `root`, `config`, `production`, `workspace`, `no_cache`, and `threads`; `production` applies to trace, dead-code, and health evidence only. Raise `FALLOW_TIMEOUT_SECS` for large repos. |
208
+ | `guard` | introspection | free | `files` | Report the architecture rules that apply to given files before editing them: boundary zone, allowed import zones, forbidden calls, and rule-pack policies |
206
209
  | `find_dupes` | analysis | free | `mode`, `min_tokens`, `min_occurrences`, `top`, `threshold` | Code duplication detection. Set `changed_since` to scope to changed files since a git ref. Set `min_occurrences` (≥ 2, default 2) to hide pair-only clones and focus on widespread copy-paste; JSON gains `stats.clone_groups_below_min_occurrences` when the filter hides anything. Each `clone_groups[]` entry carries a stable `fingerprint`, usually `dup:<8hex>` and widened only on rare report collisions; pass it to `trace_clone` to deep-dive that group |
207
- | `check_health` | analysis | free | `score`, `file_scores`, `hotspots`, `targets`, `coverage`, `runtime_coverage`, `max_crap`, `group_by` | Complexity metrics, health scores, hotspots, and refactoring targets. Set `complexity_breakdown: true` to add a per-decision-point `contributions[]` array to each complexity finding (each `else-if`, nested `if`, boolean operator, loop, `case`, etc. with its source line and cyclomatic/cognitive weight) so you can explain WHY a function scored high and pinpoint refactor targets. Optional `runtime_coverage` merges a V8 or Istanbul dump; tune it with `min_invocations_hot` (default 100), `min_observation_volume` (default 5000), and `low_traffic_threshold` (default 0.001). When runtime evidence combines with static usage, test coverage, CRAP/complexity, ownership, or change scope, read `coverage_intelligence` for stable `fallow:coverage-intel:<hash>` recommendations. Set `group_by` to `owner`, `directory`, `package`, or `section` for per-group `vital_signs` / `health_score`; SARIF results gain `properties.group`, CodeClimate issues gain a top-level `group` field |
210
+ | `check_health` | analysis | free | `score`, `css`, `file_scores`, `hotspots`, `targets`, `coverage`, `runtime_coverage`, `max_crap`, `group_by` | Complexity metrics, health scores, hotspots, and refactoring targets. Set `complexity_breakdown: true` to add a per-decision-point `contributions[]` array to each complexity finding (each `else-if`, nested `if`, boolean operator, loop, `case`, etc. with its source line and cyclomatic/cognitive weight) so you can explain WHY a function scored high and pinpoint refactor targets. Optional `runtime_coverage` merges a V8 or Istanbul dump; tune it with `min_invocations_hot` (default 100), `min_observation_volume` (default 5000), and `low_traffic_threshold` (default 0.001). When runtime evidence combines with static usage, test coverage, CRAP/complexity, ownership, or change scope, read `coverage_intelligence` for stable `fallow:coverage-intel:<hash>` recommendations. Set `group_by` to `owner`, `directory`, `package`, or `section` for per-group `vital_signs` / `health_score`; SARIF results gain `properties.group`, CodeClimate issues gain a top-level `group` field |
208
211
  | `check_runtime_coverage` | runtime-coverage | freemium | `coverage`, `min_invocations_hot`, `min_observation_volume`, `low_traffic_threshold`, `group_by` | Merge V8 or Istanbul runtime-coverage data into the health report. One local capture is free; continuous/cloud or multi-capture runtime monitoring is paid. Required `coverage` param (V8 dir, V8 JSON, or Istanbul `coverage-final.json`). Tuning knobs: `min_invocations_hot` (default 100), `min_observation_volume` (default 5000), `low_traffic_threshold` (default 0.001), `max_crap` (default 30.0), `top`, `group_by`. Cloud runtime rows can expose `resolutionStatus` / `mappingQuality` on function-list JSON and `resolution_status` / `mapping_quality` in runtime-context JSON. Use `coverage_intelligence` and the confidence table below before acting on file-level runtime signals. Long dumps may exceed the 120s MCP timeout; raise `FALLOW_TIMEOUT_SECS`. Pick this over `check_health` when you have a coverage dump. |
209
212
  | `get_hot_paths` | runtime-coverage | freemium | `coverage`, `top`, `min_invocations_hot` | Runtime-context slice over the same runtime coverage pipeline. Same params as `check_runtime_coverage`; read `runtime_coverage.hot_paths` for production hot paths. |
210
213
  | `get_blast_radius` | runtime-coverage | freemium | `coverage`, `group_by` | Runtime-context slice for blast-radius review. Same params as `check_runtime_coverage`; read `runtime_coverage.blast_radius` for stable `fallow:blast:<hash>` IDs, caller counts, traffic-weighted caller reach, optional cloud deploy touch counts, and low/medium/high risk bands. |
211
214
  | `get_importance` | runtime-coverage | freemium | `coverage`, `group_by` | Runtime-context slice for production-importance review. Same params as `check_runtime_coverage`; read `runtime_coverage.importance` for stable `fallow:importance:<hash>` IDs, invocations, cyclomatic complexity, owner count, 0-100 score, and templated reason. |
212
215
  | `get_cleanup_candidates` | runtime-coverage | freemium | `coverage`, `group_by` | Runtime-context slice for cleanup review. Same params as `check_runtime_coverage`; read `runtime_coverage.findings` for `safe_to_delete`, `review_required`, `low_traffic`, and `coverage_unavailable`. |
213
- | `get_token_blast_radius` | analysis | free | - | Design-token blast radius for Tailwind v4 @theme tokens AND CSS-in-JS defineVars/createTheme-family token definitions: per token, a consumer_count (static lower bound) and a capped located consumers[] sample tagged theme-var/css-var/utility/apply (Tailwind) or js-member (CSS-in-JS cross-module member access); descriptive context for sizing a token change, never a deletion gate |
214
- | `audit` | analysis | free | `gate`, `base`, `max_crap`, `coverage`, `runtime_coverage` | Combined dead-code + complexity + duplication for changed files, returns verdict. Set `gate` to `"new-only"` or `"all"`. Optional `runtime_coverage` (V8 dir / V8 JSON / Istanbul JSON) folds runtime findings into the same call; `min_invocations_hot` tunes the hot-path threshold (default 100). Runtime evidence appears under the audit `complexity` sub-result, including `coverage_intelligence` when combined evidence yields actionable recommendations. |
216
+ | `get_token_blast_radius` | analysis | free | - | Design-token blast radius for Tailwind v4 @theme tokens and CSS-in-JS token definitions (StyleX, vanilla-extract, PandaCSS): per token, a consumer_count (static lower bound) and a capped located consumers[] sample tagged theme-var/css-var/utility/apply (Tailwind), js-member (member access), or js-call (Panda token calls); descriptive context for sizing a token change, never a deletion gate |
217
+ | `audit` | analysis | free | `gate`, `base`, `css_deep`, `max_crap`, `coverage`, `runtime_coverage` | Combined dead-code + complexity + duplication + styling for changed files, returns verdict. Styling analytics are enabled by default; CSS and CSS-in-JS evidence can add `styling_findings`, `css_analytics`, and `styling_health` under the health sub-result. Set `gate` to `"new-only"` or `"all"`. Set `css_deep: false` to skip project-wide styling reachability while keeping local styling checks, or `css_deep: true` to force it back on when config disables it. Optional `runtime_coverage` (V8 dir / V8 JSON / Istanbul JSON) folds runtime findings into the same call; `min_invocations_hot` tunes the hot-path threshold (default 100). Runtime evidence appears under the audit `complexity` sub-result, including `coverage_intelligence` when combined evidence yields actionable recommendations. |
215
218
  | `decision_surface` | analysis | free | `base`, `max_decisions`, `workspace` | Surface the few consequential structural decisions a change embeds (coupling, public API, dependency), each as a judgment question with the routed expert; ranked, capped, and signal_id-anchored |
216
219
  | `fallow_explain` | introspection | free | `issue_type` | Explain one issue type without running analysis. Required `issue_type`; returns rationale, examples, fix guidance, and docs URL |
217
220
  | `fix_preview` | fix | free | `no_create_config` | Dry-run auto-fix preview |
@@ -221,7 +224,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
221
224
  | `feature_flags` | analysis | free | `workspace`, `production` | Detect feature flag patterns (env vars, SDK calls, config objects). Set `top` to limit results |
222
225
  | `impact` | introspection | free | `root` | Read the local, opt-in Fallow Impact value report (`fallow impact --format json`). Runs no analysis: current surfacing counts, trend since the last recorded run, pre-commit gate containment, and (on impact v1.5+) resolved/suppressed attribution. History is read from a per-project file in the user's private config dir (never inside the repo). Read-only and `root`-only; the mutating `enable` / `disable` / `default` lifecycle is not exposed. A never-enabled project returns a populated `{"enabled": false, ...}` report (never `{}`); branch on `enabled` and `enabled_source` (`project` / `user` / `default`) then `record_count`, recommending `fallow impact enable` only when `explicit_decision` is `false` (never asked) and staying silent when `true` (deliberately disabled here). Local-developer signal: fallow never records in CI, so empty there and not a CI metric |
223
226
  | `impact_all` | introspection | free | `sort`, `limit` | Roll every tracked fallow project on this machine into one cross-repo value report (hashed keys plus basename labels, never paths; local-dev only) |
224
- | `trace_export` | trace | free | `file`, `export_name` | Trace why an export is used or unused (`fallow dead-code --trace FILE:EXPORT_NAME --format json`). Required `file` and `export_name`. Returns file reachability, entry-point status, direct references, re-export chains, and a reason string. Use before deleting a supposedly-unused export |
227
+ | `trace_export` | trace | free | `file`, `export_name` | Trace why an export is used or unused (`fallow dead-code --trace FILE:EXPORT_NAME --format json`). Required `file` and `export_name`. Returns file reachability, entry-point status, direct references, re-export chains, and a reason string. If `export_name` is a class / enum / store MEMBER, returns a member trace instead (`member_name`, `member_kind`, `owner_export`, `owner_is_used`) plus a `--unused-<kind>-members` pointer; branch on field presence. Use before deleting a supposedly-unused export or debugging an unused-class-member finding |
225
228
  | `trace_file` | trace | free | `file` | Trace all graph edges for a file (`fallow dead-code --trace-file PATH --format json`). Required `file`. Returns reachability, exports, imports-from, imported-by, and re-exports. Use to decide whether a file is isolated, barrel-only, or imported by live entry points |
226
229
  | `trace_dependency` | trace | free | `package_name` | Trace where a dependency is imported (`fallow dead-code --trace-dependency PACKAGE --format json`). Required `package_name`. Returns importing files, type-only importers, total import count, `used_in_scripts` (true when invoked from package.json scripts or CI configs), and `is_used` (combined import + script signal; mirrors the unused-deps detector so build tools like `microbundle` or `vitest` are not falsely flagged as unused). Use before removing a dependency or moving between `dependencies` and `devDependencies` |
227
230
  | `trace_clone` | trace | free | `file`, `line`, `fingerprint` | Deep-dive a duplicate-code clone group (`fallow dupes --trace <spec> --format json`). Address by exactly one of: `file` + `line` (a source location), or `fingerprint` (a `dup:<id>` from a prior `find_dupes` `clone_groups[].fingerprint`, usually `dup:<8hex>` and widened only on rare report collisions). Returns the matched clone instance plus every clone group containing it; each traced group carries its `fingerprint`, an extract-function `suggestion` with estimated savings, and a best-effort `suggested_name` (omitted when no confident name). Supports `mode`, `min_tokens`, `min_lines`, `threshold`, `skip_local`, `cross_language`, `ignore_imports`. Use to consolidate duplication when you need exact sibling locations and a refactor target |
@@ -244,9 +247,6 @@ All JSON responses include structured `actions` arrays on every finding (dead co
244
247
 
245
248
  `dead-code`, `health`, `dupes`, bare `fallow`, and `audit` JSON output also carry a top-level `next_steps` array of read-only follow-up commands computed from the run's findings: each entry is `{ id, command, reason }`. The `command` is runnable as-is (never a placeholder, never `fix` or any other mutating command); the stable kebab-case `id` (`setup`, `impact-report`, `trace-unused-export`, `trace-clone`, `complexity-breakdown`, `scope-workspaces`, `audit-changed`) maps to a verification step you should run BEFORE acting, for example tracing an export before deleting it. A leading `setup` step (command: `fallow schema`) appears only on unconfigured, non-CI projects with findings and doubles as the onboarding trigger below; it disappears after setup or `fallow init --decline`. An at-most-weekly `impact-report` step (command: `fallow impact`) carries the local value digest when impact tracking has non-zero results; it may ride a clean run. When running via MCP, dispatch on the `id` to the matching tool / `code_execute` host call (`trace_export`, `trace_clone`, `check_health` with `complexity_breakdown: true`, `audit`) rather than shelling out the CLI string. The array is deduplicated, capped at three, and omitted when empty; set `FALLOW_SUGGESTIONS=off` to suppress it.
246
249
 
247
- ## Node.js Bindings
248
- Embedding fallow in a Node.js process (editor extensions, servers, custom tooling)? Use the `@fallow-cli/fallow-node` NAPI bindings instead of spawning the CLI: six async functions (`detectDeadCode`, `detectCircularDependencies`, `detectBoundaryViolations`, `detectDuplication`, `computeComplexity`, `computeHealth`) returning the same JSON envelopes as `--format json`. Read-only analysis only; use the CLI for write-path commands. Details: [Node Bindings](references/node-bindings.md).
249
-
250
250
  ## References
251
251
  - [CLI Reference](references/cli-reference.md): complete command and flag specifications, plus configuration field details
252
252
  - [Gotchas](references/gotchas.md): common pitfalls, edge cases, and correct usage patterns
@@ -508,7 +508,7 @@ fallow health --format json --quiet --trend
508
508
  {
509
509
  "kind": "health",
510
510
  "schema_version": 7,
511
- "version": "2.104.0",
511
+ "version": "3.1.0",
512
512
  "elapsed_ms": 32,
513
513
  "summary": {
514
514
  "files_analyzed": 482,
@@ -811,7 +811,7 @@ The snapshot `snapshot_schema_version` is independent of the report `schema_vers
811
811
 
812
812
  ## `audit`: Changed-File Quality Gate
813
813
 
814
- Audits changed files for dead code, complexity, and duplication. Returns a verdict (pass/warn/fail). Purpose-built for PR quality gates and reviewing AI-generated code. When `--base` is not set, the base is the `git merge-base` against the branch's upstream or the remote default (`origin/HEAD`, `origin/main`, `origin/master`); set `FALLOW_AUDIT_BASE` to pin it without a flag. Defaults to `--gate new-only`, which fails only on findings introduced by the current changeset and reports inherited findings as context.
814
+ Audits changed files for dead code, complexity, duplication, and styling. Returns a verdict (pass/warn/fail). Purpose-built for PR quality gates and reviewing AI-generated code. When `--base` is not set, the base is the `git merge-base` against the branch's upstream or the remote default (`origin/HEAD`, `origin/main`, `origin/master`); set `FALLOW_AUDIT_BASE` to pin it without a flag. Defaults to `--gate new-only`, which fails only on findings introduced by the current changeset and reports inherited findings as context.
815
815
 
816
816
  ### Flags
817
817
 
@@ -827,6 +827,9 @@ Audits changed files for dead code, complexity, and duplication. Returns a verdi
827
827
  | `--max-crap` | `string` | - | Forwarded to the health sub-analysis. Functions meeting or exceeding this CRAP score cause audit to fail. Same formula as `health --max-crap`. Pair with coverage data for accurate per-function CRAP. |
828
828
  | `--coverage` | `string` | - | Path to Istanbul-format coverage data (`coverage-final.json`) for accurate per-function CRAP scores in the health sub-analysis. Same format and semantics as `health --coverage`. Also configurable via `FALLOW_COVERAGE`. Relative paths resolve against `--root`. |
829
829
  | `--coverage-root` | `string` | - | Absolute prefix to strip from file paths in coverage data before prepending the project root. Also configurable via `FALLOW_COVERAGE_ROOT`. Use when coverage was generated under a different checkout root in CI / Docker (e.g., `/home/runner/work/myapp` on GitHub Actions). |
830
+ | `--no-css` | `bool` | `false` | Disable styling analytics in audit |
831
+ | `--css-deep` | `bool` | `false` | Enable deep CSS analysis for audit explicitly: project-wide styling reachability, narrowed back to changed anchors. Deep CSS is on by default; use this to override `audit.cssDeep = false` |
832
+ | `--no-css-deep` | `bool` | `false` | Disable deep CSS analysis while keeping local styling analytics on |
830
833
  | `--gate` | `new-only\|all` | - | Which findings affect the verdict. `new-only` gates only introduced findings; `all` gates every finding in changed files and skips the extra base-snapshot attribution pass. |
831
834
  | `--runtime-coverage` | `string` | - | 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 |
832
835
  | `--min-invocations-hot` | `string` | `100` | Threshold for hot-path classification, forwarded to the sidecar when `--runtime-coverage` is set |
@@ -903,7 +906,7 @@ fallow audit \
903
906
  {
904
907
  "kind": "audit",
905
908
  "schema_version": 7,
906
- "version": "2.104.0",
909
+ "version": "3.1.0",
907
910
  "command": "audit",
908
911
  "verdict": "fail",
909
912
  "changed_files_count": 12,
@@ -978,7 +981,7 @@ fallow flags --format json --quiet --workspace my-package
978
981
  ```json
979
982
  {
980
983
  "schema_version": 7,
981
- "version": "2.104.0",
984
+ "version": "3.1.0",
982
985
  "elapsed_ms": 116,
983
986
  "feature_flags": [],
984
987
  "total_flags": 0
@@ -1079,7 +1082,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1079
1082
  {
1080
1083
  "kind": "security",
1081
1084
  "schema_version": "4",
1082
- "version": "2.104.0",
1085
+ "version": "3.1.0",
1083
1086
  "elapsed_ms": 42,
1084
1087
  "config": {
1085
1088
  "rules": {
@@ -1108,7 +1111,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1108
1111
  {
1109
1112
  "kind": "security",
1110
1113
  "schema_version": "4",
1111
- "version": "2.104.0",
1114
+ "version": "3.1.0",
1112
1115
  "elapsed_ms": 42,
1113
1116
  "config": {
1114
1117
  "rules": {
@@ -1723,6 +1726,7 @@ These are global flags with behavior specific to bare `fallow` combined mode.
1723
1726
  | `FALLOW_REVIEW` | GitLab CI: set to `true` to post inline code review comments on MR diffs. |
1724
1727
  | `FALLOW_REVIEW_GUIDANCE` | Add collapsed "What to do" guidance blocks to `review-github` / `review-gitlab` inline comments. |
1725
1728
  | `FALLOW_SUMMARY_SCOPE` | Sticky PR/MR summary scope for `pr-comment-github` / `pr-comment-gitlab`: `all` (default) keeps project-level findings outside the diff; `diff` applies the diff filter to those findings too. Inline review comments are unaffected. |
1729
+ | `FALLOW_PR_COMMENT_LAYOUT` | Sticky PR/MR summary layout for `pr-comment-github` / `pr-comment-gitlab`: `default`, `compact`, `gate-only`, or `details`. |
1726
1730
  | `FALLOW_SCORE` | GitLab CI: set to `true` to compute health score in combined mode. Enables health delta header in MR comments. |
1727
1731
  | `FALLOW_TREND` | GitLab CI: set to `true` to compare current health metrics against saved snapshot. Implies `FALLOW_SCORE`. |
1728
1732
  | `FALLOW_EXTRA_ARGS` | GitLab CI: additional CLI flags passed through to fallow. |
@@ -1796,6 +1800,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1796
1800
  | `FALLOW_REVIEW` | `false` | Post inline code review comments on MR diff lines where issues were found |
1797
1801
  | `FALLOW_REVIEW_GUIDANCE` | `false` | Add collapsed "What to do" guidance blocks to inline review comments |
1798
1802
  | `FALLOW_SUMMARY_SCOPE` | `all` | Sticky summary scope: `all` keeps project-level findings outside the diff; `diff` applies the diff filter to those findings too |
1803
+ | `FALLOW_PR_COMMENT_LAYOUT` | `default` | Sticky summary layout: `default`, `compact`, `gate-only`, or `details` |
1799
1804
  | `FALLOW_SCORE` | `false` | Compute health score (0-100 with letter grade) in combined mode. Enables the health delta header in MR comments |
1800
1805
  | `FALLOW_TREND` | `false` | Compare current health metrics against saved snapshot. Implies `FALLOW_SCORE`. Shows per-metric deltas |
1801
1806
  | `FALLOW_EXTRA_ARGS` | - | Additional CLI flags passed through to fallow |
@@ -1815,7 +1820,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1815
1820
  {
1816
1821
  "kind": "dead-code",
1817
1822
  "schema_version": 7,
1818
- "version": "2.104.0",
1823
+ "version": "3.1.0",
1819
1824
  "elapsed_ms": 45,
1820
1825
  "total_issues": 12,
1821
1826
  "entry_points": {
@@ -1975,7 +1980,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1975
1980
  {
1976
1981
  "kind": "dupes",
1977
1982
  "schema_version": 7,
1978
- "version": "2.104.0",
1983
+ "version": "3.1.0",
1979
1984
  "elapsed_ms": 82,
1980
1985
  "total_clones": 15,
1981
1986
  "total_lines_duplicated": 230,
@@ -2019,11 +2024,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
2019
2024
  {
2020
2025
  "kind": "combined",
2021
2026
  "schema_version": 7,
2022
- "version": "2.104.0",
2027
+ "version": "3.1.0",
2023
2028
  "elapsed_ms": 159,
2024
2029
  "check": {
2025
2030
  "schema_version": 7,
2026
- "version": "2.104.0",
2031
+ "version": "3.1.0",
2027
2032
  "elapsed_ms": 45,
2028
2033
  "total_issues": 12,
2029
2034
  "unused_files": [],
@@ -486,7 +486,7 @@ The detector intentionally abstains when a Tailwind plugin or published CSS surf
486
486
 
487
487
  The same Tailwind v4 projects also get `css_analytics.token_consumers`, the reverse index: per `@theme` token, where it is consumed (a `consumer_count` plus a located `consumers[]` sample tagged `theme-var` / `css-var` / `utility` / `apply`), so you can read a token's blast radius before changing it. Treat `consumer_count` as a static lower bound: a computed class name such as `bg-${color}` is invisible to the scan, so a `0` here is the same "nothing fallow can see consumes this" population as `unused_theme_tokens`, not a deletion proof. `token_consumers` is descriptive context with no `actions[]`; drive any deletion off `unused_theme_tokens` and its verification command.
488
488
 
489
- `token_consumers` also covers CSS-in-JS token DEFINITIONS (StyleX `defineVars`, vanilla-extract `createTheme` / `createThemeContract` / `createGlobalTheme`), disambiguated by the consumer `kind`: a CSS-in-JS entry has `kind` `js-member`, `token` is the binding-qualified dotted access path (`vars.color.primary`), and `namespace` is the defining binding (`vars`). The cross-file scan resolves only relative imports, so a token consumed through a path alias (`@/tokens`) or a bare-package import is not counted (a sharper lower bound), and unlike Tailwind there is no corroborating dead-token finding, so a CSS-in-JS `consumer_count` of `0` is a weaker signal. Gated on a declared CSS-in-JS library (`@stylexjs/stylex` / `@vanilla-extract/css`); Panda (`defineTokens` / `token('...')`) is a planned follow-on.
489
+ `token_consumers` also covers CSS-in-JS token DEFINITIONS (StyleX `defineVars`, vanilla-extract `createTheme` / `createThemeContract` / `createGlobalTheme`, and PandaCSS `defineTokens`), disambiguated by the consumer `kind`: StyleX and vanilla-extract entries use `kind` `js-member`, `token` is the binding-qualified dotted access path (`vars.color.primary`), and `namespace` is the defining binding (`vars`); PandaCSS entries use the defining binding plus token path (`tokens.colors.brand`) and `token(...)` consumers are tagged `js-call`. The cross-file scan uses fallow's shared import resolver, so relative imports, tsconfig `paths` aliases, and workspace package imports can resolve to the token definition. Dynamic import strings, unresolved aliases, generated package state, and computed token access still keep `consumer_count` a lower bound, and unlike Tailwind there is no corroborating dead-token finding, so a CSS-in-JS `consumer_count` of `0` is a weaker signal. Gated on a declared CSS-in-JS library (`@stylexjs/stylex`, `@vanilla-extract/css`, or `@pandacss/dev`).
490
490
 
491
491
  ## CSS Health Candidates Are Advisory
492
492