fallow 3.5.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,98 +2,60 @@
2
2
 
3
3
  **Codebase intelligence for TypeScript and JavaScript.**
4
4
 
5
- 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.
5
+ One binary finds unused code, circular dependencies, duplication, complexity hotspots, boundary violations, and design-system styling drift. An optional paid layer, Fallow Runtime, adds production execution evidence. No AI inside the analyzer, and no TypeScript compiler or Node.js runtime needed for static analysis: runs are deterministic, with typed output contracts and traceable explanations.
6
6
 
7
7
  [![CI](https://github.com/fallow-rs/fallow/actions/workflows/ci.yml/badge.svg)](https://github.com/fallow-rs/fallow/actions/workflows/ci.yml)
8
8
  [![npm](https://img.shields.io/npm/v/fallow.svg)](https://www.npmjs.com/package/fallow)
9
9
  [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/fallow-rs/fallow/blob/main/LICENSE)
10
10
 
11
- Fallow turns a frontend repository into a trusted quality report: health score, changed-code risk, hotspots, duplication, architecture issues, dependency hygiene, styling consistency, and cleanup opportunities.
12
-
13
- It helps you answer: what changed, what got riskier, what should be reviewed, what should be refactored, and what can be safely removed. No AI inside the analyzer. Fallow produces deterministic findings, typed output contracts, and traceable explanations that downstream tools can trust.
14
-
15
- Static analysis is open source. An optional runtime layer adds production execution evidence. Rust-native, sub-second, 123 framework plugins, no Node.js runtime dependency for analysis. fallow's edge is doing more in one pass: dead code, duplication, dependencies, complexity, architecture, styling consistency, and security candidates in a single tool. For head-to-head timings against [knip](https://knip.dev) and [jscpd](https://github.com/kucherenko/jscpd), see the [benchmarks](https://github.com/fallow-rs/fallow/tree/main/benchmarks): fallow is faster than knip on smaller projects, knip is faster on several larger repos, and jscpd's Rust rewrite is faster for raw duplication scanning.
16
-
17
- ## Installation
11
+ ## Install
18
12
 
19
13
  ```bash
20
- npm install --save-dev fallow # or: pnpm add -D fallow / yarn add -D fallow / bun add -d fallow
14
+ npm install --save-dev fallow # or: pnpm add -D fallow / yarn add -D fallow
21
15
  ```
22
16
 
23
- Installs the `fallow` CLI in your project, along with the `fallow-lsp` and `fallow-mcp` launchers that start the LSP and MCP servers from the same binary.
24
-
25
- The package also ships a version-matched Agent Skill under `skills/fallow`.
26
- For tools that need CLI and issue-surface metadata without spawning the binary,
27
- `fallow/capabilities.json` mirrors `fallow schema` for the installed version.
28
- TanStack Intent discovers it from `node_modules` automatically:
29
-
30
- ```bash
31
- npx @tanstack/intent list
32
- npx @tanstack/intent load fallow#fallow
33
- ```
34
-
35
- For one-off CLI use without project-local skill discovery, run `npx fallow`.
36
-
37
- Parsing fallow's JSON output in TypeScript? Import the typed shapes:
38
-
39
- ```ts
40
- import type { CheckOutput, FallowJsonOutput } from "fallow/types";
41
- ```
42
-
43
- The types are generated from the same schema as the VS Code extension and pin to the CLI version you install. See [docs.fallow.tools](https://docs.fallow.tools) for the full output contract.
17
+ This installs the `fallow` CLI plus the `fallow-lsp` and `fallow-mcp` launchers, so editor and agent integrations resolve the project-local binary instead of whatever happens to be on `PATH`. For one-off use, run `npx fallow` without installing. Other channels (cargo, Docker, prebuilt binaries) are covered in the [installation guide](https://docs.fallow.tools/installation).
44
18
 
45
19
  ## Quick start
46
20
 
47
21
  ```bash
48
- npx fallow audit # PR-style audit: verdict pass / warn / fail
49
- npx fallow audit --format json # Machine-readable audit (for CI and agents)
50
- npx fallow health --score # Quality score and grade
51
- npx fallow # Full codebase analysis: health + duplication + cleanup
52
- npx fallow dead-code # Cleanup-specific findings
22
+ npx fallow # Full pipeline: dead code + duplication + health
23
+ npx fallow audit # Gate only what a PR changed: verdict pass/warn/fail
24
+ npx fallow health --score # 0 to 100 health score with a letter grade
25
+ npx fallow dupes # Duplication; modes strict, mild (default), weak, semantic
53
26
  npx fallow fix --dry-run # Preview automatic cleanup
54
27
  ```
55
28
 
56
- ## What Fallow reports
57
-
58
- - **Quality score** -- compact health score with grade and trend delta when snapshot history is enabled
59
- - **PR risk** -- changed-code analysis with pass / warn / fail verdict and per-finding attribution
60
- - **Hotspots** -- functions, files, and packages combining complexity, churn, size, and coupling
61
- - **Duplication** -- clone families across four detection modes (strict, mild, weak, semantic)
62
- - **Design-system styling** -- CSS, Sass/Less, CSS Modules, Tailwind/shadcn/CVA, StyleX/PandaCSS, vanilla-extract, styled-components, and Emotion consistency signals
63
- - **Architecture** -- circular dependencies, boundary violations, re-export chains
64
- - **Dependency hygiene** -- unused, unlisted, unresolved, duplicate, and type-only deps; pnpm catalog and overrides
65
- - **Cleanup opportunities** -- unused files, exports, types, enum members, class members, stale suppressions
66
- - **Runtime intelligence (optional)** -- hot paths, cold code, runtime-weighted health, stale flags
29
+ ## Output and exit codes
67
30
 
68
- Cleanup opportunities are findings that look safe to review for removal because no graph evidence supports keeping them. Dead code is one category of cleanup, not the product identity.
31
+ Add `--format json --quiet` to any command for one typed JSON document on stdout. Exit code 1 means findings, not failure; 0 is clean (or an audit pass or warn verdict); 2 is a validation or runtime error, reported as a JSON error envelope rather than a stack trace.
69
32
 
70
- ## Code duplication
33
+ Parsing the output in TypeScript? Import the typed shapes, version-pinned to the CLI you install:
71
34
 
72
- ```bash
73
- fallow dupes # Default: mild mode
74
- fallow dupes --mode semantic # Catch clones with renamed variables
75
- fallow dupes --threshold 5 # Fail CI if duplication exceeds 5%
76
- fallow dupes --save-baseline # Save current duplication as baseline
35
+ ```ts
36
+ import type { CheckOutput, FallowJsonOutput } from "fallow/types";
77
37
  ```
78
38
 
79
- Four detection modes (strict, mild, weak, semantic), clone family grouping with refactoring suggestions, baseline tracking, and cross-language TS/JS matching.
39
+ Every issue carries an `actions[]` array with an `auto_fixable` flag, so scripts and agents know which findings they can hand to `fallow fix`. The full contract lives at [docs.fallow.tools](https://docs.fallow.tools).
80
40
 
81
- ## Built for agents
41
+ ## What fallow reports
82
42
 
83
- Fallow gives AI agents structured repo truth instead of forcing them to infer everything from grep. Agents call the CLI or the MCP server to answer:
43
+ - Unused files, exports, types, enum and class members, and dependencies
44
+ - Circular dependencies and re-export cycles
45
+ - Code duplication as clone families, across four detection modes
46
+ - Complexity hotspots and a 0 to 100 health score
47
+ - Architecture boundary violations, with zero-config presets
48
+ - Design-system styling drift for CSS and CSS-in-JS (Sass/Less, CSS Modules, Tailwind, styled-components, Emotion, and more)
49
+ - A changed-file PR gate with per-finding attribution (`fallow audit`)
50
+ - Optional runtime intelligence: hot paths, cold code, runtime-weighted health, stale flags (licensed Fallow Runtime; a single local coverage capture is free)
84
51
 
85
- - Who imports this symbol?
86
- - Why is this export considered used or unused?
87
- - What changed in this PR?
88
- - Which files are risky to touch?
89
- - What duplicate siblings exist?
90
- - What cleanup action is safest?
52
+ For head-to-head timings against [knip](https://knip.dev) and [jscpd](https://github.com/kucherenko/jscpd), see [BENCHMARKS.md](https://github.com/fallow-rs/fallow/blob/main/BENCHMARKS.md): fallow is faster than knip on smaller projects, knip is faster on several larger repos, and jscpd's Rust rewrite is faster at raw duplication scanning.
91
53
 
92
- Every issue in `--format json` carries a machine-actionable `actions` array with an `auto_fixable` flag so agents can self-correct.
54
+ ## Built for agents
93
55
 
94
- ### MCP server
56
+ Agents get structured repo truth instead of inferring everything from grep: who imports a symbol, why an export counts as used, what a PR changed, which cleanup action is safest.
95
57
 
96
- Agents that speak MCP can launch the bundled `fallow-mcp` server. Installed as a devDependency, the binary lives in `node_modules/.bin/` and is not on your `PATH`, so launch it through your package manager's runner:
58
+ The bundled `fallow-mcp` server lives in `node_modules/.bin/` when installed as a devDependency, so launch it through your package manager's runner:
97
59
 
98
60
  ```json
99
61
  {
@@ -106,15 +68,22 @@ Agents that speak MCP can launch the bundled `fallow-mcp` server. Installed as a
106
68
  }
107
69
  ```
108
70
 
109
- Swap `npx` for `pnpm exec` / `yarn` / `bunx` to match your package manager. If `fallow-mcp` is installed globally (on your `PATH`), `"command": "fallow-mcp"` works directly. See the [MCP integration guide](https://docs.fallow.tools/integrations/mcp).
71
+ Swap `npx` for `pnpm exec` or `yarn` to match your package manager; a globally installed `fallow-mcp` works as `"command": "fallow-mcp"` directly. See the [MCP integration guide](https://docs.fallow.tools/integrations/mcp).
72
+
73
+ The package also ships a version-matched agent skill under `skills/fallow`, and `fallow/capabilities.json` mirrors `fallow schema` for tools that need CLI and issue-surface metadata without spawning the binary. TanStack Intent discovers both from `node_modules`:
74
+
75
+ ```bash
76
+ npx @tanstack/intent list
77
+ npx @tanstack/intent load fallow#fallow
78
+ ```
110
79
 
111
80
  ## Framework support
112
81
 
113
- 123 built-in plugins covering Next.js, Nuxt, Remix, Qwik, SvelteKit, Gatsby, Astro, Angular, NestJS, AdonisJS, Ember, Expo Router, Vite, Webpack, Vitest, Jest, Playwright, Cypress, Storybook, ESLint, TypeScript, Tailwind, UnoCSS, Prisma, Drizzle, Convex, Turborepo, Hardhat, and many more. Auto-detected from your `package.json`.
82
+ Over 100 built-in framework plugins covering Next.js, Nuxt, Remix, Qwik, SvelteKit, Gatsby, Astro, Angular, NestJS, AdonisJS, Ember, Expo Router, Vite, Webpack, Vitest, Jest, Playwright, Cypress, Storybook, ESLint, TypeScript, Tailwind, UnoCSS, Prisma, Drizzle, Convex, Turborepo, Hardhat, and more. Entry points are auto-detected from `package.json`, so the first run needs no configuration.
114
83
 
115
84
  ## Configuration
116
85
 
117
- Create a config file in your project root, or run `fallow init`:
86
+ Works out of the box. To customize, let [`fallow recommend`](https://docs.fallow.tools/cli/recommend) propose a config from the detected stack (read-only; `--format json` returns the full decision set for agents), run `fallow init`, or create a config file in your project root:
118
87
 
119
88
  ```jsonc
120
89
  // .fallowrc.json
@@ -130,23 +99,13 @@ Create a config file in your project root, or run `fallow init`:
130
99
  }
131
100
  ```
132
101
 
133
- `$schema` gives editors autocomplete and validation and has no effect on
134
- analysis. As an npm package, `fallow` always ships a version-aligned schema at
135
- `./node_modules/fallow/schema.json`, which `fallow init` and
136
- `fallow recommend` point at by default: offline, no editor trust prompt. If
137
- you install fallow another way (cargo, homebrew, a bare binary) with no
138
- `node_modules/fallow` to point at, use the remote fallback instead:
139
- `https://raw.githubusercontent.com/fallow-rs/fallow/main/schema.json`. Some
140
- editors, including VS Code, refuse to load a remote schema URL until you
141
- explicitly trust the domain.
142
-
143
- Also supports TOML (`fallow init --toml` creates `fallow.toml`).
102
+ `$schema` gives editors autocomplete and validation and has no effect on analysis. The npm package ships a version-aligned schema at `./node_modules/fallow/schema.json`, so validation works offline with no editor trust prompt. TOML works too: `fallow init --toml` creates `fallow.toml`. Full reference: [configuration overview](https://docs.fallow.tools/configuration/overview).
144
103
 
145
104
  ## Documentation
146
105
 
147
- - [Full documentation](https://docs.fallow.tools)
106
+ - [docs.fallow.tools](https://docs.fallow.tools)
148
107
  - [GitHub repository](https://github.com/fallow-rs/fallow)
149
- - [Plugin Authoring Guide](https://github.com/fallow-rs/fallow/blob/main/docs/plugin-authoring.md)
108
+ - [Plugin authoring guide](https://github.com/fallow-rs/fallow/blob/main/docs/plugin-authoring.md)
150
109
 
151
110
  ## License
152
111
 
package/capabilities.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "manifest_version": "1",
5
5
  "description": "Codebase analyzer for TypeScript/JavaScript: unused code, circular dependencies, code duplication, complexity hotspots, and architecture boundary violations",
6
6
  "global_flags": [
@@ -311,7 +311,7 @@
311
311
  "name": "--save-regression-baseline",
312
312
  "type": "string",
313
313
  "required": false,
314
- "description": "Save the current issue counts as a regression baseline"
314
+ "description": "Save the current issue counts as a regression baseline. Omit PATH to update regression.baseline in the discovered fallow config, or create .fallowrc.json when none exists. Provide PATH to write a standalone file"
315
315
  },
316
316
  {
317
317
  "name": "--only",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
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": {
@@ -84,16 +84,16 @@
84
84
  "detect-libc": "2.1.2"
85
85
  },
86
86
  "devDependencies": {
87
- "@tanstack/intent": "0.3.2"
87
+ "@tanstack/intent": "0.3.5"
88
88
  },
89
89
  "optionalDependencies": {
90
- "@fallow-cli/darwin-arm64": "3.5.0",
91
- "@fallow-cli/darwin-x64": "3.5.0",
92
- "@fallow-cli/linux-x64-gnu": "3.5.0",
93
- "@fallow-cli/linux-arm64-gnu": "3.5.0",
94
- "@fallow-cli/linux-x64-musl": "3.5.0",
95
- "@fallow-cli/linux-arm64-musl": "3.5.0",
96
- "@fallow-cli/win32-arm64-msvc": "3.5.0",
97
- "@fallow-cli/win32-x64-msvc": "3.5.0"
90
+ "@fallow-cli/darwin-arm64": "3.5.1",
91
+ "@fallow-cli/darwin-x64": "3.5.1",
92
+ "@fallow-cli/linux-x64-gnu": "3.5.1",
93
+ "@fallow-cli/linux-arm64-gnu": "3.5.1",
94
+ "@fallow-cli/linux-x64-musl": "3.5.1",
95
+ "@fallow-cli/linux-arm64-musl": "3.5.1",
96
+ "@fallow-cli/win32-arm64-msvc": "3.5.1",
97
+ "@fallow-cli/win32-x64-msvc": "3.5.1"
98
98
  }
99
99
  }
@@ -1,10 +1,61 @@
1
1
  const test = require("node:test");
2
2
  const assert = require("node:assert/strict");
3
+ const fs = require("node:fs");
3
4
  const os = require("node:os");
4
5
  const { spawnSync } = require("node:child_process");
5
6
  const path = require("node:path");
6
7
 
7
8
  const RUN_BINARY = path.join(__dirname, "run-binary.js");
9
+ const BIN_DIR = path.join(__dirname, "..", "bin");
10
+
11
+ function currentPlatformPackage() {
12
+ const { getPlatformPackage } = require("./platform-package");
13
+ if (process.platform !== "linux") {
14
+ return getPlatformPackage(process.platform, process.arch);
15
+ }
16
+ let libcFamily;
17
+ try {
18
+ libcFamily = require("detect-libc").familySync();
19
+ } catch {
20
+ libcFamily = undefined;
21
+ }
22
+ return getPlatformPackage(process.platform, process.arch, libcFamily);
23
+ }
24
+
25
+ function runLauncher(t, launcher, args) {
26
+ const work = fs.mkdtempSync(path.join(os.tmpdir(), "fallow-launcher-"));
27
+ t.after(() => fs.rmSync(work, { recursive: true, force: true }));
28
+
29
+ const pkg = currentPlatformPackage();
30
+ assert.ok(pkg, "the test host must map to a supported platform package");
31
+ const pkgDir = path.join(work, "node_modules", ...pkg.split("/"));
32
+ fs.mkdirSync(pkgDir, { recursive: true });
33
+ fs.writeFileSync(
34
+ path.join(pkgDir, "package.json"),
35
+ JSON.stringify({ name: pkg, version: "3.5.0" }),
36
+ );
37
+
38
+ const binary = path.join(pkgDir, "fallow");
39
+ fs.writeFileSync(
40
+ binary,
41
+ "#!/usr/bin/env node\n" +
42
+ 'require("node:fs").writeFileSync(process.env.FALLOW_TEST_ARGS, JSON.stringify(process.argv.slice(2)));\n',
43
+ );
44
+ fs.chmodSync(binary, 0o755);
45
+
46
+ const argsFile = path.join(work, "args.json");
47
+ const result = spawnSync(process.execPath, [path.join(BIN_DIR, launcher), ...args], {
48
+ encoding: "utf8",
49
+ env: {
50
+ ...process.env,
51
+ NODE_PATH: path.join(work, "node_modules"),
52
+ FALLOW_SKIP_BINARY_VERIFY: "1",
53
+ FALLOW_TEST_ARGS: argsFile,
54
+ },
55
+ });
56
+ assert.equal(result.status, 0, result.stderr);
57
+ return JSON.parse(fs.readFileSync(argsFile, "utf8"));
58
+ }
8
59
 
9
60
  // Run a child that installs guardBrokenStdout, then emits a synthetic stdout
10
61
  // 'error' with the given code. Node delivers a broken-pipe failure as exactly
@@ -91,3 +142,23 @@ test("exitCodeForChildFailure preserves status codes and maps signal deaths", ()
91
142
  assert.equal(exitCodeForChildFailure({ status: null, signal: undefined }), 1);
92
143
  assert.equal(exitCodeForChildFailure({ status: null, signal: "NOT_A_SIGNAL" }), 1);
93
144
  });
145
+
146
+ test(
147
+ "fallow-lsp executes the multicall binary with the lsp-server subcommand",
148
+ { skip: process.platform === "win32" },
149
+ (t) => {
150
+ assert.deepEqual(runLauncher(t, "fallow-lsp", ["--stdio"]), ["lsp-server", "--stdio"]);
151
+ },
152
+ );
153
+
154
+ test(
155
+ "fallow-mcp executes the multicall binary with the mcp-server subcommand",
156
+ { skip: process.platform === "win32" },
157
+ (t) => {
158
+ assert.deepEqual(runLauncher(t, "fallow-mcp", ["--transport", "stdio"]), [
159
+ "mcp-server",
160
+ "--transport",
161
+ "stdio",
162
+ ]);
163
+ },
164
+ );
@@ -48,7 +48,7 @@ cargo install fallow-cli # build from source
48
48
  1. **Always use `--format json --quiet 2>/dev/null`** for machine-readable output. The `2>/dev/null` discards stderr so progress messages and threshold warnings don't corrupt the JSON on stdout. Never use `2>&1`
49
49
  2. **Always append `|| true`** to every fallow command. Exit code 1 means "issues found" (normal), not a runtime error. Without `|| true`, the Bash tool treats exit 1 as failure and cancels parallel commands. Only exit code 2 is a real error (invalid config, parse failure)
50
50
  3. **Use `--explain`** to include a `_meta` object in JSON output with metric definitions, ranges, and interpretation hints. In human format, `--explain` prints a `Description:` line under each section header.
51
- 4. **Use the root `kind` field** to identify typed JSON envelopes (`dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, etc.). `--legacy-envelope` exists only for one-cycle compatibility with older consumers.
51
+ 4. **Use the root `kind` field** to identify typed JSON envelopes (`dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, etc.).
52
52
  5. **Use issue type filters** (`--unused-exports`, `--unused-files`, etc.) to limit output scope
53
53
  6. **Always `--dry-run` before `fix`**, then `fix --yes` to apply
54
54
  7. **All output paths are relative** to the project root
@@ -350,15 +350,17 @@ Adds a per-decision-point `contributions[]` array to every complexity finding (e
350
350
  ### Gate CI on regressions (baselines)
351
351
  ```bash
352
352
  # 1. Save the current issue counts as a regression baseline
353
- fallow dead-code --format json --quiet --save-regression-baseline .fallow/baseline.json
353
+ fallow dead-code --format json --quiet --save-regression-baseline
354
354
  # 2. In CI: fail only if issues increase beyond tolerance
355
- fallow dead-code --format json --quiet --regression-baseline .fallow/baseline.json --fail-on-regression --tolerance 0
355
+ fallow dead-code --format json --quiet --fail-on-regression --tolerance 0
356
356
  # Identity-based baseline (fail only on NEW findings, not raw counts)
357
357
  fallow dead-code --format json --quiet --save-baseline .fallow/snapshot.json
358
358
  fallow dead-code --format json --quiet --baseline .fallow/snapshot.json
359
359
  ```
360
360
 
361
- `--save-regression-baseline` / `--regression-baseline` / `--fail-on-regression` / `--tolerance` are count-based gates; `--save-baseline` / `--baseline` are identity-based (track finding identity, fail on new). All six are global flags, so they also work on `health` and `dupes`. `audit` rejects the global baseline flags and uses `--dead-code-baseline` / `--health-baseline` / `--dupes-baseline` instead.
361
+ `--save-regression-baseline` / `--regression-baseline` / `--fail-on-regression` / `--tolerance` are count-based gates for `dead-code` and bare combined mode. `--save-baseline` / `--baseline` are identity-based (track finding identity, fail on new). `audit` rejects the global baseline flags and uses `--dead-code-baseline` / `--health-baseline` / `--dupes-baseline` instead.
362
+
363
+ With no path, `--save-regression-baseline` updates `regression.baseline` in the discovered fallow config, or creates `.fallowrc.json` when none exists. Pass a path only when a standalone baseline file is preferred.
362
364
 
363
365
  ### Explain an issue type without running analysis
364
366
  ```bash
@@ -130,8 +130,9 @@ fallow dead-code --format json --quiet --trace src/utils.ts:myFunction
130
130
  fallow dead-code --format json --quiet --save-baseline fallow-baselines/dead-code.json
131
131
  fallow dead-code --format json --quiet --baseline fallow-baselines/dead-code.json --fail-on-issues
132
132
 
133
- # Regression detection: save baseline on main, compare on PRs
133
+ # Regression detection: update regression.baseline in the discovered config
134
134
  fallow dead-code --format json --quiet --save-regression-baseline
135
+ # Then compare on PRs
135
136
  fallow dead-code --format json --quiet --fail-on-regression --tolerance 2%
136
137
 
137
138
  # Scope to specific files (e.g., lint-staged)
@@ -509,7 +510,7 @@ fallow health --format json --quiet --trend
509
510
  {
510
511
  "kind": "health",
511
512
  "schema_version": 7,
512
- "version": "3.5.0",
513
+ "version": "3.5.1",
513
514
  "elapsed_ms": 32,
514
515
  "summary": {
515
516
  "files_analyzed": 482,
@@ -907,7 +908,7 @@ fallow audit \
907
908
  {
908
909
  "kind": "audit",
909
910
  "schema_version": 7,
910
- "version": "3.5.0",
911
+ "version": "3.5.1",
911
912
  "command": "audit",
912
913
  "verdict": "fail",
913
914
  "changed_files_count": 12,
@@ -982,7 +983,7 @@ fallow flags --format json --quiet --workspace my-package
982
983
  ```json
983
984
  {
984
985
  "schema_version": 7,
985
- "version": "3.5.0",
986
+ "version": "3.5.1",
986
987
  "elapsed_ms": 116,
987
988
  "feature_flags": [],
988
989
  "total_flags": 0
@@ -1083,7 +1084,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1083
1084
  {
1084
1085
  "kind": "security",
1085
1086
  "schema_version": "4",
1086
- "version": "3.5.0",
1087
+ "version": "3.5.1",
1087
1088
  "elapsed_ms": 42,
1088
1089
  "config": {
1089
1090
  "rules": {
@@ -1112,7 +1113,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1112
1113
  {
1113
1114
  "kind": "security",
1114
1115
  "schema_version": "4",
1115
- "version": "3.5.0",
1116
+ "version": "3.5.1",
1116
1117
  "elapsed_ms": 42,
1117
1118
  "config": {
1118
1119
  "rules": {
@@ -1667,8 +1668,8 @@ Available on all commands:
1667
1668
  | `--report-path-prefix` | `string` | - | Prefix prepended to every path in the CI-facing formats (`github-annotations`, `github-summary`, `codeclimate`, `review-github`, `review-gitlab`). CI platforms address files by repository-root-relative path, so when the analyzed project lives in a subdirectory (e.g. `packages/app/`), paths need that offset. fallow detects the offset via the git toplevel automatically; this flag overrides the detection. Pass an empty string to disable rebasing and emit paths relative to `--root` |
1668
1669
  | `--fail-on-regression` | `bool` | `false` | Fail if issue count increased beyond tolerance vs a regression baseline |
1669
1670
  | `--tolerance` | `string` | `0` | Allowed increase: `"2%"` (percentage) or `"5"` (absolute). Default: `"0"` |
1670
- | `--regression-baseline` | `string` | - | Path to regression baseline file (default: `.fallow/regression-baseline.json`) |
1671
- | `--save-regression-baseline` | `string` | - | Save current issue counts as a regression baseline |
1671
+ | `--regression-baseline` | `string` | - | Path to a standalone regression baseline file. Without it, fallow uses `regression.baseline` from the config |
1672
+ | `--save-regression-baseline` | `string` | - | Save current issue counts. With no path, update `regression.baseline` in the discovered fallow config or create `.fallowrc.json`; with a path, write a standalone baseline file |
1672
1673
  | `--only` | `dead-code\|dupes\|health` | - | Run only specific analyses (e.g., `--only dead-code,dupes`). Values: `dead-code` (alias: `check`), `dupes`, `health` |
1673
1674
  | `--skip` | `dead-code\|dupes\|health` | - | Skip specific analyses (e.g., `--skip health`). Values: `dead-code` (alias: `check`), `dupes`, `health` |
1674
1675
  | `--dupes-mode` | `strict\|mild\|weak\|semantic` | - | Override duplication detection mode in combined mode |
@@ -1836,7 +1837,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1836
1837
  {
1837
1838
  "kind": "dead-code",
1838
1839
  "schema_version": 7,
1839
- "version": "3.5.0",
1840
+ "version": "3.5.1",
1840
1841
  "elapsed_ms": 45,
1841
1842
  "total_issues": 12,
1842
1843
  "entry_points": {
@@ -1996,7 +1997,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1996
1997
  {
1997
1998
  "kind": "dupes",
1998
1999
  "schema_version": 7,
1999
- "version": "3.5.0",
2000
+ "version": "3.5.1",
2000
2001
  "elapsed_ms": 82,
2001
2002
  "total_clones": 15,
2002
2003
  "total_lines_duplicated": 230,
@@ -2040,11 +2041,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
2040
2041
  {
2041
2042
  "kind": "combined",
2042
2043
  "schema_version": 7,
2043
- "version": "3.5.0",
2044
+ "version": "3.5.1",
2044
2045
  "elapsed_ms": 159,
2045
2046
  "check": {
2046
2047
  "schema_version": 7,
2047
- "version": "3.5.0",
2048
+ "version": "3.5.1",
2048
2049
  "elapsed_ms": 45,
2049
2050
  "total_issues": 12,
2050
2051
  "unused_files": [],
@@ -7,9 +7,9 @@
7
7
  * `npm/fallow/types/output-contract.d.ts` (published as `fallow/types`).
8
8
  *
9
9
  * To change a shape:
10
- * 1. Edit the Rust struct in `crates/types/src/results.rs` (or the
11
- * duplicates crate at `crates/core/src/duplicates/types.rs`). The Rust
12
- * side is the runtime source of truth for the JSON output.
10
+ * 1. Find the Rust owner through `derived_definition_names()` and its
11
+ * imports in `crates/cli/src/bin/schema_emit.rs`, then edit that type.
12
+ * Rust is the runtime source of truth for the JSON output.
13
13
  * 2. Regenerate `docs/output-schema.json` with
14
14
  * `cargo run -p fallow-cli --features schema-emit --bin fallow-schema-emit`.
15
15
  * The schema-emit drift tests compare the committed schema against the