fallow 2.104.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "2.104.0",
3
+ "version": "3.0.0",
4
4
  "description": "Deterministic codebase intelligence for TypeScript and JavaScript. Quality, risk, architecture, dependencies, duplication, and safe cleanup evidence for humans, CI, and agents. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, zero-config framework support.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -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.0.0",
91
+ "@fallow-cli/darwin-x64": "3.0.0",
92
+ "@fallow-cli/linux-x64-gnu": "3.0.0",
93
+ "@fallow-cli/linux-arm64-gnu": "3.0.0",
94
+ "@fallow-cli/linux-x64-musl": "3.0.0",
95
+ "@fallow-cli/linux-arm64-musl": "3.0.0",
96
+ "@fallow-cli/win32-arm64-msvc": "3.0.0",
97
+ "@fallow-cli/win32-x64-msvc": "3.0.0"
94
98
  }
95
99
  }
package/schema.json CHANGED
@@ -167,6 +167,11 @@
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",
@@ -1099,6 +1104,31 @@
1099
1104
  "$ref": "#/$defs/Severity",
1100
1105
  "default": "off"
1101
1106
  },
1107
+ "css-token-drift": {
1108
+ "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.",
1109
+ "$ref": "#/$defs/Severity",
1110
+ "default": "warn"
1111
+ },
1112
+ "css-duplicate-block": {
1113
+ "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.",
1114
+ "$ref": "#/$defs/Severity",
1115
+ "default": "warn"
1116
+ },
1117
+ "css-selector-complexity": {
1118
+ "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.",
1119
+ "$ref": "#/$defs/Severity",
1120
+ "default": "warn"
1121
+ },
1122
+ "css-dead-surface": {
1123
+ "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.",
1124
+ "$ref": "#/$defs/Severity",
1125
+ "default": "warn"
1126
+ },
1127
+ "css-broken-reference": {
1128
+ "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.",
1129
+ "$ref": "#/$defs/Severity",
1130
+ "default": "warn"
1131
+ },
1102
1132
  "unresolved-imports": {
1103
1133
  "$ref": "#/$defs/Severity",
1104
1134
  "default": "error"
@@ -1852,6 +1882,56 @@
1852
1882
  }
1853
1883
  ]
1854
1884
  },
1885
+ "css-token-drift": {
1886
+ "anyOf": [
1887
+ {
1888
+ "$ref": "#/$defs/Severity"
1889
+ },
1890
+ {
1891
+ "type": "null"
1892
+ }
1893
+ ]
1894
+ },
1895
+ "css-duplicate-block": {
1896
+ "anyOf": [
1897
+ {
1898
+ "$ref": "#/$defs/Severity"
1899
+ },
1900
+ {
1901
+ "type": "null"
1902
+ }
1903
+ ]
1904
+ },
1905
+ "css-selector-complexity": {
1906
+ "anyOf": [
1907
+ {
1908
+ "$ref": "#/$defs/Severity"
1909
+ },
1910
+ {
1911
+ "type": "null"
1912
+ }
1913
+ ]
1914
+ },
1915
+ "css-dead-surface": {
1916
+ "anyOf": [
1917
+ {
1918
+ "$ref": "#/$defs/Severity"
1919
+ },
1920
+ {
1921
+ "type": "null"
1922
+ }
1923
+ ]
1924
+ },
1925
+ "css-broken-reference": {
1926
+ "anyOf": [
1927
+ {
1928
+ "$ref": "#/$defs/Severity"
1929
+ },
1930
+ {
1931
+ "type": "null"
1932
+ }
1933
+ ]
1934
+ },
1855
1935
  "unresolved-imports": {
1856
1936
  "anyOf": [
1857
1937
  {
@@ -2250,6 +2330,18 @@
2250
2330
  "gate": {
2251
2331
  "$ref": "#/$defs/AuditGate"
2252
2332
  },
2333
+ "css": {
2334
+ "type": [
2335
+ "boolean",
2336
+ "null"
2337
+ ]
2338
+ },
2339
+ "cssDeep": {
2340
+ "type": [
2341
+ "boolean",
2342
+ "null"
2343
+ ]
2344
+ },
2253
2345
  "deadCodeBaseline": {
2254
2346
  "type": [
2255
2347
  "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 JavaScript, TypeScript, and styling. Static analysis 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 JavaScript, TypeScript, and styling
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 JavaScript, TypeScript, and styling. The static layer 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` |
@@ -152,7 +148,7 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
152
148
  | `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
149
  | `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
150
  | `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 |
151
+ | `missing-suppression-reason` | `--stale-suppressions` | - | - | Suppression comment omits a required reason |
156
152
  | `unused-catalog-entry` | `--unused-catalog-entries` | yes | - | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
157
153
  | `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
154
  | `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 +176,11 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
180
176
  | `high-complexity` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function exceeds both complexity thresholds |
181
177
  | `high-crap-score` | `--complexity` | - | `// fallow-ignore-next-line complexity` | Function has a high CRAP score (complexity combined with low coverage) |
182
178
  | `refactoring-target` | `--targets` | - | - | File identified as a high-priority refactoring candidate |
179
+ | `css-token-drift` | - | - | `// fallow-ignore-next-line css-token-drift` | CSS or CSS-in-JS hardcoded styling value bypasses the design token system |
180
+ | `css-duplicate-block` | - | - | `// fallow-ignore-next-line css-duplicate-block` | CSS or CSS-in-JS declaration block is duplicated across rules |
181
+ | `css-selector-complexity` | - | - | `// fallow-ignore-next-line css-selector-complexity` | CSS selector, nesting, or important usage is structurally complex |
182
+ | `css-dead-surface` | - | - | `// fallow-ignore-next-line css-dead-surface` | CSS or CSS-in-JS surface appears unused |
183
+ | `css-broken-reference` | - | - | `// fallow-ignore-next-line css-broken-reference` | CSS or CSS-in-JS reference resolves to no stylesheet definition |
183
184
  | `untested-file` | `--coverage-gaps` | - | `// fallow-ignore-file coverage-gaps` | Runtime-reachable file has no test dependency path |
184
185
  | `untested-export` | `--coverage-gaps` | - | `// fallow-ignore-file coverage-gaps` | Runtime-reachable export has no test dependency path |
185
186
  | `code-duplication` | - | - | `// fallow-ignore-next-line code-duplication` | Duplicated code block; Reported by fallow dupes (and bare fallow / fallow audit) |
@@ -203,15 +204,16 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
203
204
  | `check_changed` | analysis | free | `since`, `baseline`, `fail_on_regression` | Incremental analysis of files changed since a git ref |
204
205
  | `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
206
  | `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. |
207
+ | `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
208
  | `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 |
209
+ | `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
210
  | `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
211
  | `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
212
  | `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
213
  | `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
214
  | `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. |
215
+ | `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 |
216
+ | `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
217
  | `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
218
  | `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
219
  | `fix_preview` | fix | free | `no_create_config` | Dry-run auto-fix preview |
@@ -244,9 +246,6 @@ All JSON responses include structured `actions` arrays on every finding (dead co
244
246
 
245
247
  `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
248
 
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
249
  ## References
251
250
  - [CLI Reference](references/cli-reference.md): complete command and flag specifications, plus configuration field details
252
251
  - [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.0.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.0.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.0.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.0.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.0.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.0.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.0.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.0.0",
2023
2028
  "elapsed_ms": 159,
2024
2029
  "check": {
2025
2030
  "schema_version": 7,
2026
- "version": "2.104.0",
2031
+ "version": "3.0.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
 
@@ -242,9 +242,10 @@ fallow:
242
242
  variables:
243
243
  FALLOW_COMMENT: "true"
244
244
  FALLOW_SUMMARY_SCOPE: "diff"
245
+ FALLOW_PR_COMMENT_LAYOUT: "gate-only"
245
246
  ```
246
247
 
247
- Posts a summary comment on the MR with issue counts and findings. In MR pipelines, `--changed-since` is auto-detected from `$CI_MERGE_REQUEST_TARGET_BRANCH_NAME`, so only issues from changed files are reported. `FALLOW_SUMMARY_SCOPE: "diff"` also hides project-level dependency/catalog/override findings whose anchor line is outside the diff. Requires `GITLAB_TOKEN` CI/CD variable (project access token with `api` scope); `CI_JOB_TOKEN` is read-only for MR notes in the official GitLab API.
248
+ Posts a summary comment on the MR with issue counts and findings. In MR pipelines, `--changed-since` is auto-detected from `$CI_MERGE_REQUEST_TARGET_BRANCH_NAME`, so only issues from changed files are reported. `FALLOW_SUMMARY_SCOPE: "diff"` also hides project-level dependency/catalog/override findings whose anchor line is outside the diff. `FALLOW_PR_COMMENT_LAYOUT: "gate-only"` keeps the sticky comment compact when GitLab Code Quality is the primary review surface. Requires `GITLAB_TOKEN` CI/CD variable (project access token with `api` scope); `CI_JOB_TOKEN` is read-only for MR notes in the official GitLab API.
248
249
 
249
250
  ### GitLab CI: With Inline Code Review Comments
250
251
 
@@ -272,12 +273,13 @@ fallow:
272
273
  variables:
273
274
  FALLOW_COMMENT: "true"
274
275
  FALLOW_SUMMARY_SCOPE: "diff"
276
+ FALLOW_PR_COMMENT_LAYOUT: "gate-only"
275
277
  FALLOW_REVIEW: "true"
276
278
  FALLOW_REVIEW_GUIDANCE: "true"
277
279
  FALLOW_FAIL_ON_ISSUES: "true"
278
280
  ```
279
281
 
280
- Posts both a summary comment and inline review comments on the MR. `FALLOW_SUMMARY_SCOPE: "diff"` only affects the sticky summary; inline review comments remain anchored to diff lines. The template auto-detects the package manager (npm/pnpm/yarn) from lockfiles, so review comments show the correct commands for the project (e.g., `pnpm remove` instead of `npm uninstall`).
282
+ Posts both a summary comment and inline review comments on the MR. `FALLOW_SUMMARY_SCOPE: "diff"` and `FALLOW_PR_COMMENT_LAYOUT` only affect the sticky summary; inline review comments remain anchored to diff lines. The template auto-detects the package manager (npm/pnpm/yarn) from lockfiles, so review comments show the correct commands for the project (e.g., `pnpm remove` instead of `npm uninstall`).
281
283
 
282
284
  ### GitLab CI: With Health Score and Trend
283
285