fallow 3.31.0 → 3.32.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": "3.31.0",
3
+ "version": "3.32.0",
4
4
  "mcpName": "io.github.fallow-rs/fallow",
5
5
  "description": "Codebase intelligence for TypeScript and JavaScript: health, complexity, duplication, architecture, styling drift, and unused code from one graph. CLI, LSP, and MCP server. Zero config for over 100 frameworks.",
6
6
  "license": "MIT",
@@ -8,7 +8,7 @@
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/fallow-rs/fallow.git"
10
10
  },
11
- "homepage": "https://docs.fallow.tools",
11
+ "homepage": "https://fallow.tools/docs/",
12
12
  "funding": "https://github.com/sponsors/fallow-rs",
13
13
  "bugs": {
14
14
  "url": "https://github.com/fallow-rs/fallow/issues"
@@ -16,7 +16,7 @@
16
16
  "intent": {
17
17
  "version": 1,
18
18
  "repo": "fallow-rs/fallow",
19
- "docs": "https://docs.fallow.tools"
19
+ "docs": "https://fallow.tools/docs/"
20
20
  },
21
21
  "keywords": [
22
22
  "code-intelligence",
@@ -89,14 +89,14 @@
89
89
  "@tanstack/intent": "0.4.0"
90
90
  },
91
91
  "optionalDependencies": {
92
- "@fallow-cli/darwin-arm64": "3.31.0",
93
- "@fallow-cli/darwin-x64": "3.31.0",
94
- "@fallow-cli/linux-x64-gnu": "3.31.0",
95
- "@fallow-cli/linux-arm64-gnu": "3.31.0",
96
- "@fallow-cli/linux-x64-musl": "3.31.0",
97
- "@fallow-cli/linux-arm64-musl": "3.31.0",
98
- "@fallow-cli/win32-arm64-msvc": "3.31.0",
99
- "@fallow-cli/win32-x64-msvc": "3.31.0",
100
- "fallow-type-aware": "3.31.0"
92
+ "@fallow-cli/darwin-arm64": "3.32.0",
93
+ "@fallow-cli/darwin-x64": "3.32.0",
94
+ "@fallow-cli/linux-x64-gnu": "3.32.0",
95
+ "@fallow-cli/linux-arm64-gnu": "3.32.0",
96
+ "@fallow-cli/linux-x64-musl": "3.32.0",
97
+ "@fallow-cli/linux-arm64-musl": "3.32.0",
98
+ "@fallow-cli/win32-arm64-msvc": "3.32.0",
99
+ "@fallow-cli/win32-x64-msvc": "3.32.0",
100
+ "fallow-type-aware": "3.32.0"
101
101
  }
102
102
  }
package/schema.json CHANGED
@@ -136,7 +136,7 @@
136
136
  "default": []
137
137
  },
138
138
  "duplicates": {
139
- "description": "Configures clone detection: `enabled` (default true), `mode` (`strict`, `mild` default, `weak`, `semantic`, from least to most identifier/literal blinding; `strict` and `mild` are equivalent under fallow's AST tokenizer, `weak` blinds string literals, `semantic` blinds all identifiers and literals for Type-2 renamed-variable detection), `near` (false, add bounded function-scoped near-miss detection), `minTokens` (50), `minLines` (5), `minOccurrences` (integer >= 2, deserialization fails below 2), `threshold` (max duplication percentage, 0 = no limit), `ignore` globs, `ignoredClones` (reviewed clone keys to hide until their content or occurrence count changes), `ignoreDefaults` (true, merge built-in generated-file ignores), `skipLocal` (only report cross-directory clones), `crossLanguage` (strip TS type annotations to match .ts against .js), `ignoreImports` (true, strip ES import/re-export/top-level require wiring from the token stream), and `normalization` (per-flag `ignoreIdentifiers`/`ignoreStringValues`/`ignoreNumericValues` overrides on top of `mode`). Raise `minOccurrences` to focus on widespread copy-paste, enable `near` for gapped structural clones, or set `mode` to `semantic` to catch renamed-variable exact clones.",
139
+ "description": "Configures clone detection: `enabled` (default true), `mode` (`strict`, `mild` default, `weak`, `semantic`, from least to most identifier/literal blinding; `strict` and `mild` are equivalent under fallow's AST tokenizer, `weak` blinds string literals, `semantic` blinds all identifiers and literals for Type-2 renamed-variable detection), `near` (false, add bounded function-scoped near-miss detection), `minTokens` (50), `minLines` (5), `minOccurrences` (integer >= 2, deserialization fails below 2), `threshold` (max duplication percentage, 0 = no limit), `ignore` globs, `ignoredClones` (reviewed clone keys to hide until their content or occurrence count changes), `ignoreDefaults` (true, merge built-in generated-file ignores), `skipLocal` (only report cross-directory clones), `ignoreSymlinks` (false, omit clone instances whose path is a symlink or lies under a symlinked directory), `crossLanguage` (strip TS type annotations to match .ts against .js), `ignoreImports` (true, strip ES import/re-export/top-level require wiring from the token stream), and `normalization` (per-flag `ignoreIdentifiers`/`ignoreStringValues`/`ignoreNumericValues` overrides on top of `mode`). Raise `minOccurrences` to focus on widespread copy-paste, enable `near` for gapped structural clones, or set `mode` to `semantic` to catch renamed-variable exact clones.",
140
140
  "$ref": "#/$defs/DuplicatesConfig",
141
141
  "default": {
142
142
  "enabled": true,
@@ -150,6 +150,7 @@
150
150
  "ignoredClones": [],
151
151
  "ignoreDefaults": true,
152
152
  "skipLocal": false,
153
+ "ignoreSymlinks": false,
153
154
  "crossLanguage": false,
154
155
  "ignoreImports": true,
155
156
  "normalization": {},
@@ -214,6 +215,7 @@
214
215
  "unprovided-injects": "warn",
215
216
  "unrendered-components": "warn",
216
217
  "unused-component-props": "warn",
218
+ "absent-component-props": "off",
217
219
  "unused-component-emits": "warn",
218
220
  "unused-component-inputs": "warn",
219
221
  "unused-component-outputs": "warn",
@@ -949,6 +951,11 @@
949
951
  "type": "boolean",
950
952
  "default": false
951
953
  },
954
+ "ignoreSymlinks": {
955
+ "description": "Omit clone instances whose file path is a symlink, or lies under a\nsymlinked directory, inside the project root.\n\nDefaults to `false`: symlinked instances stay in the report and carry\n`is_symlink: true` in JSON output. Set to `true` to report only\nduplication between real files. A clone group with fewer than two\nremaining instances is not reported. Symlinked files also leave the\ncorpus, so `stats` (files, lines, tokens and the duplication\npercentage that `threshold` checks) count only real files.",
956
+ "type": "boolean",
957
+ "default": false
958
+ },
952
959
  "crossLanguage": {
953
960
  "description": "Enable cross-language clone detection by stripping type annotations.\n\nWhen enabled, TypeScript type annotations (parameter types, return types,\ngenerics, interfaces, type aliases) are stripped from the token stream,\nallowing detection of clones between `.ts` and `.js` files.",
954
961
  "type": "boolean",
@@ -1388,6 +1395,11 @@
1388
1395
  "$ref": "#/$defs/Severity",
1389
1396
  "default": "warn"
1390
1397
  },
1398
+ "absent-component-props": {
1399
+ "description": "Used optional inputs absent from inspected callers. Requires manual review; off by default.",
1400
+ "$ref": "#/$defs/Severity",
1401
+ "default": "off"
1402
+ },
1391
1403
  "unused-component-emits": {
1392
1404
  "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.",
1393
1405
  "$ref": "#/$defs/Severity",
@@ -2230,6 +2242,17 @@
2230
2242
  }
2231
2243
  ]
2232
2244
  },
2245
+ "absent-component-props": {
2246
+ "description": "Optional override for absent optional component inputs.",
2247
+ "anyOf": [
2248
+ {
2249
+ "$ref": "#/$defs/Severity"
2250
+ },
2251
+ {
2252
+ "type": "null"
2253
+ }
2254
+ ]
2255
+ },
2233
2256
  "unused-component-emits": {
2234
2257
  "description": "Optional override for [`RulesConfig::unused_component_emits`].",
2235
2258
  "anyOf": [
@@ -2737,6 +2760,13 @@
2737
2760
  "description": "Saved per-issue-type counts written by `--save-baseline` and compared by\n`--fail-on-regression`. Every count defaults to `0` when its key is missing,\nso hand-trimmed baselines stay loadable.",
2738
2761
  "type": "object",
2739
2762
  "properties": {
2763
+ "absentComponentProps": {
2764
+ "description": "Baseline count of optional component prop review candidates.",
2765
+ "type": "integer",
2766
+ "format": "uint",
2767
+ "minimum": 0,
2768
+ "default": 0
2769
+ },
2740
2770
  "analysisIdentity": {
2741
2771
  "description": "Compatibility identity for the analysis that produced these counts.\nMissing values in existing configs are treated as syntactic.",
2742
2772
  "$ref": "#/$defs/SemanticAnalysisIdentity",
@@ -6,7 +6,7 @@ license: MIT
6
6
 
7
7
  # Fallow: codebase intelligence for TypeScript and JavaScript
8
8
 
9
- 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 and cold-path deletion confidence, with a single local capture available by default and continuous/cloud runtime monitoring available as an optional mode. Broad framework plugin coverage, zero configuration, sub-second static analysis.
9
+ Fallow analyzes code and styles for changed-code risk, cleanup opportunities, circular dependencies, duplication, complexity hotspots, architecture boundary violations, design-system styling drift, feature flags, and opt-in security candidates. Runtime coverage merges production execution data into the same `fallow health` report for hot-path review and cold-path deletion confidence. A single local capture is available by default. Continuous or cloud runtime monitoring is optional.
10
10
 
11
11
  ## When to Use
12
12
  - Find cleanup opportunities: unused files, exports, types, members, dependencies, or feature flags that guard unused exports.
@@ -58,7 +58,23 @@ cargo install fallow-cli # build from source
58
58
  15. **Check production runtime data before an edit or a delete, when Fallow Cloud is connected**. Prefer the scoped reads over the full `get_cloud_runtime_context` pull. Before an edit, run `fallow coverage review-packet --repo <owner/repo>` (MCP `get_cloud_review_packet`) for the changed files and read `hit_count`, `covered_by_test`, and the callers when present. Before a delete, require `period_tracking_state: "never_called"`, not only `tracking_state`, and read `evidence_window.observed_hours`: few observed hours or a low-traffic surface mean "not visited", not "dead". After a deploy, run `fallow coverage deployment-changes --repo <owner/repo>` (MCP `get_cloud_deployment_changes`) and, when `comparable` is `false`, report `reason` and claim no change. Open files by `repo_path`, not `file_path`. Production data is context, never a gate. Details: [references/mcp.md](references/mcp.md#scoped-cloud-reads).
59
59
 
60
60
  ## Onboarding And Insight
61
- Offer setup only after a human-requested analysis shows findings and all signals match: `fallow config --path` exits 3, not CI, not a pipeline format, `fallow impact --format json --quiet` has `onboarding_declined: false`, and no offer happened this session. Ask after showing value. Choices: guard commits and PRs, baseline the existing backlog and clean by category, add AGENTS.md guidance, or keep as-is. On decline, run `fallow init --decline --quiet` and stay silent for this project. Mutate only after consent. For guards, inspect `fallow hooks status --format json --quiet`, then use `fallow hooks install --target agent` and `fallow hooks install --target git`; for large backlogs, pair the gate with `--save-baseline` / new-only guidance. Offer `fallow impact enable` as local-only value tracking, never as telemetry; also offer it once on already-configured projects when `fallow impact status --format json` has `enabled: false` and `explicit_decision: false`, and record a no with `fallow impact disable --quiet`. Surface value on clear events: if the agent gate blocked a commit or push and a later retry succeeded, mention what was contained; when `next_steps` carries id `impact-report`, run its command and relay the non-zero numbers to the user in one line. On request, summarize non-zero Impact counts. Ask about telemetry only after such a win, only if `fallow telemetry status --format json` has `explicit_decision: false`, and never run `fallow telemetry enable`.
61
+ Offer setup after showing the findings from a human-requested analysis, only when all these conditions hold:
62
+
63
+ - `fallow config --path` exits 3.
64
+ - The run is outside CI and does not use a pipeline format.
65
+ - `fallow impact --format json --quiet` has `onboarding_declined: false`.
66
+ - No offer happened this session.
67
+
68
+ Offer these choices: guard commits and PRs, baseline the existing backlog and clean by category, add AGENTS.md guidance, or keep as-is. Mutate only after consent. On decline, run `fallow init --decline --quiet` and stay silent for this project.
69
+
70
+ For guards, inspect `fallow hooks status --format json --quiet`, then use `fallow hooks install --target agent` and `fallow hooks install --target git`. For large backlogs, pair the gate with `--save-baseline` and new-only guidance.
71
+
72
+ Offer `fallow impact enable` for local value tracking. Impact is separate from telemetry. Also offer it once on an already-configured project when `fallow impact status --format json` has `enabled: false` and `explicit_decision: false`. Record a decline with `fallow impact disable --quiet`.
73
+
74
+ Report value when there is evidence. If the agent gate blocked a commit or push and a later retry succeeded, describe the issues that caused the block. When `next_steps` has id `impact-report`, run its command and report the non-zero numbers in one line. On request, summarize non-zero Impact counts.
75
+
76
+ Ask about telemetry only after one of these events, and only if `fallow telemetry status --format json` has `explicit_decision: false`. Never run `fallow telemetry enable`.
77
+
62
78
  ## Task Cheat Sheet
63
79
  Route by intent before reaching for the big analysis commands. Same matrix as `fallow schema` (`task_matrix`) and the generated AGENTS.md section.
64
80
 
@@ -90,7 +106,9 @@ Full command catalogue, one row per command: **[references/cli-reference.md](ref
90
106
 
91
107
  ## Issue Types
92
108
 
93
- Dead-code filter flags are one per issue type (`--unused-exports`, `--unused-types`, `--unused-deps`, `--circular-deps`, and so on). Passing one or more narrows `fallow dead-code` to those types; passing none reports every type. Every type suppresses the same way: `// fallow-ignore-next-line <issue-type>` above the finding, or `// fallow-ignore-file <issue-type>` at the top of the file; the bare form without a type suppresses all of them.
109
+ Dead-code filter flags select issue categories (`--unused-exports`, `--unused-types`, `--unused-deps`, `--circular-deps`, and so on). Some flags select related types together; `--unused-deps` covers several dependency types. Passing one or more narrows `fallow dead-code` to those categories. Passing none applies no issue-type filter.
110
+
111
+ For suppressible findings, use the placement listed in the issue catalogue: `// fallow-ignore-next-line <issue-type>` above the finding, or `// fallow-ignore-file <issue-type>` at the top of the file. Some types support only file-level suppression; others have no suppression comment. A bare supported form without a type suppresses all matching findings at that placement.
94
112
 
95
113
  `fallow explain <issue-type>` describes one type without running analysis, and the MCP server serves the same catalogue as the `fallow://issue-types` resource.
96
114
 
@@ -100,7 +118,7 @@ Full catalogue, one row per type: **[references/issue-types.md](references/issue
100
118
 
101
119
  Fallow ships an MCP server (`fallow-mcp`) that exposes these same analyses as agent tools. When the server is connected, its tools are already in your context with typed params and structured JSON returns, and each maps to a CLI fallback command. Prefer them when you want JSON without shelling out, or `code_execute` (Code Mode) to compose several read-only analyses in one sandboxed snippet (no single-call CLI equivalent). Otherwise use the CLI.
102
120
 
103
- The server also serves read-only reference resources (no subprocess, no analysis run, cacheable by URI; your client reads them through its own resource tool): `fallow://tools`, `fallow://issue-types`, `fallow://explain/{issue_type}`, `fallow://task-matrix`, and the config, plugin, and rule-pack JSON Schemas. Every payload is JSON and carries `fallow_version`.
121
+ The server also serves read-only reference resources (no subprocess, no analysis run, cacheable by URI; your client reads them through its own resource tool): `fallow://tools`, `fallow://issue-types`, `fallow://explain/{issue_type}`, `fallow://task-matrix`, and the config, plugin, and rule-pack JSON Schemas. Every resource payload is JSON. Each content item carries the server version in `_meta.fallow_version`.
104
122
 
105
123
  Full tool catalogue, resource catalogue, key params, runtime source-map confidence tiers, shared timeouts, and the `next_steps` dispatch mapping: **[references/mcp.md](references/mcp.md)**.
106
124
 
@@ -113,6 +131,8 @@ Full tool catalogue, resource catalogue, key params, runtime source-map confiden
113
131
  - [Similar Code](references/similar-code.md): snapshot-stable discovery, inspection, and verdict workflow
114
132
  - [Node Bindings](references/node-bindings.md): embed the analysis engine in a Node.js process via NAPI
115
133
 
134
+ To set up or modernize the code-quality tooling of a repository (package install, config, agent wiring, CI gate), use the `fallow-setup` skill.
135
+
116
136
  ## Common Workflows
117
137
 
118
138
  ### Audit a project for cleanup opportunities
@@ -240,7 +260,7 @@ fallow health --format json --quiet --group-by owner --score --ownership --save-
240
260
  fallow health --format json --quiet --group-by owner --score --workspace 'packages/*'
241
261
  ```
242
262
 
243
- `--group-by owner` partitions every metric by CODEOWNERS team (last-match-wins, GitHub semantics) with a directory-cached native resolver, so there is no need to parse CODEOWNERS or aggregate per owner yourself. With `--score`, each `groups[]` entry carries a first-class `health_score` (`{ score, grade, penalties: { dead_files, complexity, p90_complexity, maintainability, unused_deps, circular_deps, unit_size, coupling, duplication } }`) alongside its own `vital_signs` and per-file `file_scores[]` (`complexity_density`, `maintainability_index`). Human output renders a `● Per-owner health` table (`score / grade / files / hot`). `--save-snapshot` records a point-in-time entry that `--trend` reads later. This one command replaces a hand-rolled CODEOWNERS-resolution + per-owner-aggregation + scoring script end to end.
263
+ `--group-by owner` partitions every metric by CODEOWNERS team (last-match-wins, GitHub semantics) with a native resolver, so there is no need to parse CODEOWNERS or aggregate per owner yourself. With `--score`, each `groups[]` entry carries a first-class `health_score` (`{ score, grade, penalties: { dead_files, complexity, p90_complexity, maintainability, unused_deps, circular_deps, unit_size, coupling, duplication } }`) alongside its own `vital_signs` and per-file `file_scores[]` (`complexity_density`, `maintainability_index`). Human output renders a `● Per-owner health` table (`score / grade / files / hot`). `--save-snapshot` records a point-in-time entry that `--trend` reads later. This one command replaces a hand-rolled CODEOWNERS-resolution + per-owner-aggregation + scoring script end to end.
244
264
 
245
265
  Caveat for root-only path aliases: in monorepos where TypeScript path aliases (e.g. `@myorg/*`) are declared only in a root `tsconfig.base.json` that the per-package `tsconfig.json` files do not extend, imports through those aliases do not resolve, so dead-code signals (unused files/exports, and the `dead_files` penalty in the per-owner `health_score`) carry false positives. The complexity, maintainability, coupling, hotspot, and ownership signals are computed per file from the AST and git history and stay accurate regardless. Prefer `health` (not `dead-code`) for per-team quality tracking there.
246
266
 
@@ -375,11 +395,11 @@ export const deprecatedHelper = () => {};
375
395
  ## Key Gotchas
376
396
 
377
397
  - **`fix --yes` is required** in non-TTY (agent) environments. Without it, `fix` exits with code 2
378
- - **Zero config by default.** Built-in framework plugins auto-detect, including Wuchale config, Contentlayer content roots, tap and tsd test entry points. Read `fallow schema.plugins` for the current registry and don't create config unless customization is needed
379
- - **Syntactic analysis only.** No TypeScript compiler, so fully dynamic `import(variable)` is not resolved
398
+ - **Zero config by default.** Built-in framework plugins auto-detect, including Wuchale config, Contentlayer content roots, Kibana `kibana.jsonc` plugin entries, tap and tsd test entry points. Read `fallow schema.plugins` for the current registry and don't create config unless customization is needed
399
+ - **Default analysis is syntactic.** Fully dynamic `import(variable)` is not resolved. Optional `--type-aware` analysis adds TypeScript checker evidence
380
400
  - **Function overloads are deduplicated.** TypeScript function overload signatures are merged into a single export (not reported as separate unused exports)
381
- - **Re-export chains are resolved.** Exports through barrel files are tracked, not falsely flagged
382
- - **`--changed-since` is additive.** Only new issues in changed files, not all issues in the project
401
+ - **Re-export chains are resolved.** Fallow tracks exports through barrel files. Trace reported exports before removal when consumers may be outside static analysis
402
+ - **`--changed-since` scopes findings to changed files.** Existing findings in those files can remain, and dead-code dependency findings remain project-wide. Use `fallow audit --gate new-only` to distinguish introduced findings from inherited ones
383
403
 
384
404
  For the full list with examples, see [references/gotchas.md](references/gotchas.md).
385
405