fallow 3.32.0 → 3.33.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/capabilities.json +155 -17
- package/package.json +10 -10
- package/schema.json +5 -0
- package/scripts/lazy-verify.js +14 -2
- package/scripts/lazy-verify.test.js +6 -4
- package/scripts/run-binary.js +7 -1
- package/scripts/run-binary.test.js +71 -12
- package/skills/fallow/SKILL.md +7 -3
- package/skills/fallow/references/cli-reference.md +82 -16
- package/skills/fallow/references/gotchas.md +1 -1
- package/skills/fallow/references/mcp.md +2 -1
- package/skills/fallow/references/node-bindings.md +1 -1
- package/skills/fallow/references/patterns.md +6 -3
- package/skills/fallow-setup/references/ci-gate.md +1 -1
- package/types/output-contract.d.ts +1021 -32
|
@@ -8,6 +8,7 @@ Complete command and flag specifications for all fallow CLI commands.
|
|
|
8
8
|
|
|
9
9
|
- [Commands](#commands)
|
|
10
10
|
- [`dead-code`: Dead Code Analysis](#dead-code-dead-code-analysis)
|
|
11
|
+
- [`architecture`: Cycles, Boundaries and Policy Rules](#architecture-cycles-boundaries-and-policy-rules)
|
|
11
12
|
- [`dupes`: Duplication Detection](#dupes-duplication-detection)
|
|
12
13
|
- [`fix`: Auto-Remove Unused Code](#fix-auto-remove-unused-code)
|
|
13
14
|
- [`list`: Project Introspection](#list-project-introspection)
|
|
@@ -47,6 +48,7 @@ Every fallow command with its purpose and key flags. The table is regenerated fr
|
|
|
47
48
|
|---|---|---|
|
|
48
49
|
| `fallow` | Run full codebase analysis: cleanup + duplication + health (default) | `--only`, `--skip`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--ci`, `--fail-on-issues`, `--group-by`, `--summary`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline`, `--score`, `--trend`, `--save-snapshot`, `--include-entry-exports` |
|
|
49
50
|
| `dead-code` | Dead code analysis (`check` is an alias) | `--unused-exports`, `--changed-since`, `--changed-workspaces`, `--production`, `--file`, `--include-entry-exports`, `--stale-suppressions`, `--ci`, `--group-by`, `--summary`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline` |
|
|
51
|
+
| `architecture` | Check import cycles, boundaries and policy rules after editing | `--cycles`, `--boundaries`, `--policy`, `--file`, `--finding-id`, `path` |
|
|
50
52
|
| `watch` | Watch for changes and re-run analysis | `--no-clear` |
|
|
51
53
|
| `type-aware` | Inspect the optional TypeScript semantic companion | |
|
|
52
54
|
| `doctor` | Diagnose project readiness without analysis or mutation | |
|
|
@@ -77,6 +79,7 @@ Every fallow command with its purpose and key flags. The table is regenerated fr
|
|
|
77
79
|
| `explain` | Explain one issue type without running analysis | `<issue-type>`, `--format json` |
|
|
78
80
|
| `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` |
|
|
79
81
|
| `audit-cache` | Maintain reusable audit base-snapshot caches | |
|
|
82
|
+
| `baselines` | Maintain committed baselines: `baselines prune` removes the entries of fixed findings and never adds one | `prune --check`, `prune --dead-code-baseline`, `prune --health-baseline`, `prune --dupes-baseline` |
|
|
80
83
|
| `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` |
|
|
81
84
|
| `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` |
|
|
82
85
|
| `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` |
|
|
@@ -213,6 +216,56 @@ fallow dead-code --format json --quiet --include-entry-exports
|
|
|
213
216
|
|
|
214
217
|
---
|
|
215
218
|
|
|
219
|
+
## `architecture`: Cycles, Boundaries and Policy Rules
|
|
220
|
+
|
|
221
|
+
Reports circular dependencies, re-export cycles, package cycles, boundary violations (with boundary coverage and forbidden calls) and rule-pack policy violations. The command runs the `dead-code` analysis with these issue types selected. The JSON output has `kind: "architecture"` (with `--group-by`: `architecture-grouped`) and its own `schema_version`. The arrays, finding ids, actions, exit codes, gate outcomes and baselines are the same as on `dead-code`. A saved baseline keeps `kind: "dead-code"`. `fallow report --from` renders a saved architecture envelope in every format. The global scope and output flags (`--format`, `--changed-since`, `--workspace`, `--baseline`, `--save-baseline`) work as on `dead-code`.
|
|
222
|
+
|
|
223
|
+
`fallow dead-code` still reports these findings by default until the next major version. Its `--circular-deps`, `--re-export-cycles`, `--package-cycles`, `--boundary-violations` and `--policy-violations` flags are deprecated aliases. `fallow architecture` reports only part of the issue types, so `--fail-on-stale-baseline` does not gate on it, with any baseline. A baseline that `fallow architecture --save-baseline` writes lists only the architecture findings, and `fallow dead-code` warns when it reads such a baseline.
|
|
224
|
+
|
|
225
|
+
| Flag | Selects |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `--cycles` | Circular dependencies, re-export cycles and package cycles (`dead-code --circular-deps --re-export-cycles --package-cycles`) |
|
|
228
|
+
| `--boundaries` | Boundary violations, boundary coverage and forbidden calls (`dead-code --boundary-violations`) |
|
|
229
|
+
| `--policy` | Rule-pack policy violations (`dead-code --policy-violations`) |
|
|
230
|
+
| `--file <PATH>` | Only report findings in these files |
|
|
231
|
+
| `--finding-id <ID>` | Only report the findings with these ids |
|
|
232
|
+
|
|
233
|
+
Without a selection flag, the command reports every architecture issue type.
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{
|
|
237
|
+
"kind": "architecture",
|
|
238
|
+
"schema_version": 1,
|
|
239
|
+
"total_issues": 1,
|
|
240
|
+
"circular_dependencies": [
|
|
241
|
+
{ "files": ["src/a.ts", "src/b.ts"], "length": 2, "finding_id": "dc1:circular-dependency:...", "actions": [] }
|
|
242
|
+
],
|
|
243
|
+
"boundary_violations": [],
|
|
244
|
+
"policy_violations": []
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The MCP tool is `check_architecture` and the Node binding is `detectArchitecture`.
|
|
249
|
+
|
|
250
|
+
With `--group-by`, each group shows its findings under one "Architecture" heading.
|
|
251
|
+
|
|
252
|
+
Bare `fallow --only architecture` runs the `dead-code` analysis and reports only these findings in the `check` section. Bare `fallow --skip architecture` removes them from the `check` section. The health score, the duplication section and the file that `--save-baseline` writes stay the same as in a run without the value. The regression counts follow the narrowed section.
|
|
253
|
+
|
|
254
|
+
### Examples
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Before an edit: the rules that apply to the files
|
|
258
|
+
fallow guard src/ui/App.ts --format json --quiet
|
|
259
|
+
|
|
260
|
+
# After an edit: cycles, boundaries and policy rules
|
|
261
|
+
fallow architecture --format json --quiet
|
|
262
|
+
|
|
263
|
+
# Only import cycles on the changed files
|
|
264
|
+
fallow architecture --cycles --changed-since main --format json --quiet
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
216
269
|
## `dupes`: Duplication Detection
|
|
217
270
|
|
|
218
271
|
Finds code duplication and clones across the project.
|
|
@@ -467,7 +520,7 @@ Human output groups paths under "Shared with your team (commit these)" and "Loca
|
|
|
467
520
|
{
|
|
468
521
|
"kind": "agent-install",
|
|
469
522
|
"schema_version": 1,
|
|
470
|
-
"fallow_version": "3.
|
|
523
|
+
"fallow_version": "3.33.0",
|
|
471
524
|
"root": "/abs/path",
|
|
472
525
|
"mode": "install",
|
|
473
526
|
"dry_run": false,
|
|
@@ -677,7 +730,7 @@ fallow health --format json --quiet --trend
|
|
|
677
730
|
{
|
|
678
731
|
"kind": "health",
|
|
679
732
|
"schema_version": 7,
|
|
680
|
-
"version": "3.
|
|
733
|
+
"version": "3.33.0",
|
|
681
734
|
"elapsed_ms": 32,
|
|
682
735
|
"summary": {
|
|
683
736
|
"files_analyzed": 482,
|
|
@@ -1036,6 +1089,13 @@ Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#
|
|
|
1036
1089
|
|
|
1037
1090
|
With `--gate new-only`, inherited error-severity findings can be present in the JSON output while the verdict remains `pass`; check the `attribution` object and per-finding `introduced` booleans.
|
|
1038
1091
|
|
|
1092
|
+
A complexity finding matches its base finding by file path and function name. The line and the exceeded category do not affect the match, and a renamed file keeps its match. A complexity finding is introduced in these cases:
|
|
1093
|
+
|
|
1094
|
+
- No base finding matches it.
|
|
1095
|
+
- A metric that the head finding exceeds has a higher value than in the base finding.
|
|
1096
|
+
|
|
1097
|
+
An unchanged or decreased metric keeps the finding inherited, also when the exceeded category changes (for example from `both` to `cyclomatic`). When one file has more than one finding with the same function name, each base finding matches at most one head finding. Head findings with unchanged metric values match first. The other findings then match in line order.
|
|
1098
|
+
|
|
1039
1099
|
### JSON contract: which fields are severity-aware
|
|
1040
1100
|
|
|
1041
1101
|
| Field | Severity-aware? | What it counts |
|
|
@@ -1086,7 +1146,7 @@ fallow audit \
|
|
|
1086
1146
|
{
|
|
1087
1147
|
"kind": "audit",
|
|
1088
1148
|
"schema_version": 7,
|
|
1089
|
-
"version": "3.
|
|
1149
|
+
"version": "3.33.0",
|
|
1090
1150
|
"command": "audit",
|
|
1091
1151
|
"verdict": "fail",
|
|
1092
1152
|
"changed_files_count": 12,
|
|
@@ -1174,7 +1234,7 @@ fallow flags --format json --quiet --workspace my-package
|
|
|
1174
1234
|
```json
|
|
1175
1235
|
{
|
|
1176
1236
|
"schema_version": 7,
|
|
1177
|
-
"version": "3.
|
|
1237
|
+
"version": "3.33.0",
|
|
1178
1238
|
"elapsed_ms": 116,
|
|
1179
1239
|
"feature_flags": [],
|
|
1180
1240
|
"total_flags": 0
|
|
@@ -1275,7 +1335,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1275
1335
|
{
|
|
1276
1336
|
"kind": "security",
|
|
1277
1337
|
"schema_version": "4",
|
|
1278
|
-
"version": "3.
|
|
1338
|
+
"version": "3.33.0",
|
|
1279
1339
|
"elapsed_ms": 42,
|
|
1280
1340
|
"config": {
|
|
1281
1341
|
"rules": {
|
|
@@ -1304,7 +1364,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1304
1364
|
{
|
|
1305
1365
|
"kind": "security",
|
|
1306
1366
|
"schema_version": "4",
|
|
1307
|
-
"version": "3.
|
|
1367
|
+
"version": "3.33.0",
|
|
1308
1368
|
"elapsed_ms": 42,
|
|
1309
1369
|
"config": {
|
|
1310
1370
|
"rules": {
|
|
@@ -1438,6 +1498,11 @@ Each `--path` hop carries `type_only` and `dynamic`. A `dynamic` hop loads its t
|
|
|
1438
1498
|
<!-- generated:flags:trace:start -->
|
|
1439
1499
|
| Flag | Type | Default | Description |
|
|
1440
1500
|
|---|---|---|---|
|
|
1501
|
+
| `--dependency` | `string` | - | How the code uses each imported name of a package: file and call counts, one hop through project wrappers, and a count of each use that the trace cannot resolve |
|
|
1502
|
+
| `--specifier` | `string` | - | With `--dependency`, report only these imported names (repeatable or comma-separated). Turns on the site page |
|
|
1503
|
+
| `--sites` | `bool` | `false` | With `--dependency`, list the usage sites with file, line and column |
|
|
1504
|
+
| `--limit` | `string` | - | With `--dependency`, the largest number of sites on a page (1 to 500, default 50). Turns on the site page |
|
|
1505
|
+
| `--cursor` | `string` | - | With `--dependency`, the `next_cursor` of the previous page. Turns on the site page |
|
|
1441
1506
|
| `--path` | `string` | - | Shortest import path between two modules, as two file paths (e.g. `--path src/app.ts src/db.ts`). Mutually exclusive with the symbol target and the call-chain flags |
|
|
1442
1507
|
| `--eager-only` | `bool` | `false` | With `--path`, follow only static value imports, so the route explains why TO loads before FROM runs. `import()`, lazy globs, worker loads and `import type` do not qualify |
|
|
1443
1508
|
| `--callers` | `bool` | `false` | Walk UP to callers (modules that import the symbol). When neither `--callers` nor `--callees` is set, both directions are walked |
|
|
@@ -1817,7 +1882,7 @@ Uploads retry network failures, HTTP 429, and HTTP 502/503/504 up to three attem
|
|
|
1817
1882
|
| `--repo <NAME>` | string | `package.json` `repository.url`, then `git remote get-url origin` parsed to `owner/repo` | Repo identifier used in the source-map API path. Must match the beacon's `projectId` (and `upload-inventory`'s `--project-id`); pass `--repo <bare-name>` explicitly if the beacon reports a bare name. |
|
|
1818
1883
|
| `--git-sha <SHA>` | string | `$GITHUB_SHA` -> `$CI_COMMIT_SHA` -> `$COMMIT_SHA` -> `git rev-parse HEAD` | Commit SHA, 7-40 hex chars. |
|
|
1819
1884
|
| `--endpoint <URL>` | string | `$FALLOW_API_URL` or `https://api.fallow.cloud` | Override for staging / on-prem. |
|
|
1820
|
-
| `--strip-path <BOOL>` | bool | `true` | Upload basename-only `fileName` values. Use `--strip-path=false` when runtime coverage reports paths like `assets/app.js`. |
|
|
1885
|
+
| `--strip-path <BOOL>` | bool | `true` | Upload basename-only `fileName` values. Use `--strip-path=false` when runtime coverage reports paths like `assets/app.js`. Maps that share a basename are sent under their build-directory path, so no map replaces another. The command warns when a map's `sources` do not resolve to files in the repository (for example `sourceRoot: "/"` in `tsconfig.json`). |
|
|
1821
1886
|
| `--dry-run` | bool | `false` | Print what would upload; no API key or network call. |
|
|
1822
1887
|
| `--concurrency <N>` | integer | `4` | Parallel upload fanout. |
|
|
1823
1888
|
| `--fail-fast` | bool | `false` | Stop on the first upload failure. |
|
|
@@ -1922,8 +1987,8 @@ Available on all commands:
|
|
|
1922
1987
|
| `--tolerance` | `string` | `0` | Allowed increase: `"2%"` (percentage) or `"5"` (absolute). Default: `"0"` |
|
|
1923
1988
|
| `--regression-baseline` | `string` | - | Path to a standalone regression baseline file. Without it, fallow uses `regression.baseline` from the config |
|
|
1924
1989
|
| `--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 |
|
|
1925
|
-
| `--only` | `dead-code\|dupes\|health` | - | Run only specific analyses (e.g., `--only dead-code,dupes`). Values: `dead-code` (alias: `check`), `dupes`, `health` |
|
|
1926
|
-
| `--skip` | `dead-code\|dupes\|health` | - | Skip specific analyses (e.g., `--skip health`). Values: `dead-code` (alias: `check`), `dupes`, `health` |
|
|
1990
|
+
| `--only` | `dead-code\|dupes\|health\|architecture` | - | Run only specific analyses (e.g., `--only dead-code,dupes`). Values: `dead-code` (alias: `check`), `dupes`, `health`, `architecture`. `architecture` alone runs the dead-code analysis and reports only import cycles, boundary violations and policy violations |
|
|
1991
|
+
| `--skip` | `dead-code\|dupes\|health\|architecture` | - | Skip specific analyses (e.g., `--skip health`). Values: `dead-code` (alias: `check`), `dupes`, `health`, `architecture`. `architecture` alone removes import cycles, boundary violations and policy violations from the dead-code section |
|
|
1927
1992
|
| `--dupes-mode` | `strict\|mild\|weak\|semantic` | - | Override duplication detection mode in combined mode |
|
|
1928
1993
|
| `--dupes-near` | `bool` | `false` | Enable function-scoped near-miss clone detection in combined mode |
|
|
1929
1994
|
| `--dupes-threshold` | `string` | - | Override duplication threshold in combined mode |
|
|
@@ -1945,6 +2010,7 @@ Available on all commands:
|
|
|
1945
2010
|
| `--dupes-baseline` | `string` | - | Compare duplication clone groups against a saved baseline in combined mode (produced by `fallow dupes --save-baseline`) |
|
|
1946
2011
|
| `--health-baseline` | `string` | - | Compare health findings against a saved baseline in combined mode (produced by `fallow health --save-baseline`) |
|
|
1947
2012
|
| `--include-entry-exports` | `bool` | `false` | Report unused exports in entry files instead of auto-marking them as used |
|
|
2013
|
+
| `--show-cascade` | `bool` | `false` | Also report the unused exports, types, class members and enum members of unused files. By default the report hides them, because deleting the file removes them, and counts them in `cascade_hidden` |
|
|
1948
2014
|
| `--type-aware` | `bool` | `false` | Opt in to TypeScript semantic analysis for project-wide symbol evidence. This does not emit compiler diagnostics or typed lint findings |
|
|
1949
2015
|
| `--no-type-aware` | `bool` | `false` | Disable TypeScript semantic analysis even when `typeAware.enabled` or `FALLOW_TYPE_AWARE` opts in, keeping this run fully syntactic |
|
|
1950
2016
|
| `--type-aware-project` | `string` | - | TypeScript project config to use for type-aware analysis (repeatable) |
|
|
@@ -1965,8 +2031,8 @@ guarded edits.
|
|
|
1965
2031
|
<!-- generated:flags:fallow-combined:start -->
|
|
1966
2032
|
| Flag | Type | Default | Description |
|
|
1967
2033
|
|---|---|---|---|
|
|
1968
|
-
| `--only` | `dead-code\|dupes\|health` | - | Run only specific analyses when no subcommand is given |
|
|
1969
|
-
| `--skip` | `dead-code\|dupes\|health` | - | Skip specific analyses when no subcommand is given |
|
|
2034
|
+
| `--only` | `dead-code\|dupes\|health\|architecture` | - | Run only specific analyses when no subcommand is given |
|
|
2035
|
+
| `--skip` | `dead-code\|dupes\|health\|architecture` | - | Skip specific analyses when no subcommand is given |
|
|
1970
2036
|
| `--production` | `bool` | `false` | Production mode: exclude test/story/dev files, only start/build scripts, report type-only dependencies |
|
|
1971
2037
|
| `--no-production` | `bool` | `false` | Force production mode OFF for every analysis, overriding a project config's `production: true` (and `FALLOW_PRODUCTION`). Conflicts with `--production` |
|
|
1972
2038
|
| `--production-dead-code` | `bool` | `false` | Run dead-code analysis in production mode when using bare combined mode |
|
|
@@ -2113,7 +2179,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
|
|
|
2113
2179
|
{
|
|
2114
2180
|
"kind": "dead-code",
|
|
2115
2181
|
"schema_version": 7,
|
|
2116
|
-
"version": "3.
|
|
2182
|
+
"version": "3.33.0",
|
|
2117
2183
|
"elapsed_ms": 45,
|
|
2118
2184
|
"total_issues": 12,
|
|
2119
2185
|
"entry_points": {
|
|
@@ -2273,7 +2339,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
|
|
|
2273
2339
|
{
|
|
2274
2340
|
"kind": "dupes",
|
|
2275
2341
|
"schema_version": 7,
|
|
2276
|
-
"version": "3.
|
|
2342
|
+
"version": "3.33.0",
|
|
2277
2343
|
"elapsed_ms": 82,
|
|
2278
2344
|
"total_clones": 15,
|
|
2279
2345
|
"total_lines_duplicated": 230,
|
|
@@ -2317,11 +2383,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
|
|
|
2317
2383
|
{
|
|
2318
2384
|
"kind": "combined",
|
|
2319
2385
|
"schema_version": 7,
|
|
2320
|
-
"version": "3.
|
|
2386
|
+
"version": "3.33.0",
|
|
2321
2387
|
"elapsed_ms": 159,
|
|
2322
2388
|
"check": {
|
|
2323
2389
|
"schema_version": 7,
|
|
2324
|
-
"version": "3.
|
|
2390
|
+
"version": "3.33.0",
|
|
2325
2391
|
"elapsed_ms": 45,
|
|
2326
2392
|
"total_issues": 12,
|
|
2327
2393
|
"unused_files": [],
|
|
@@ -2356,7 +2422,7 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
|
|
|
2356
2422
|
}
|
|
2357
2423
|
```
|
|
2358
2424
|
|
|
2359
|
-
Use `--only` or `--skip` to control which analyses are included in the combined output. Use `--coverage` and `--coverage-root` to feed Istanbul coverage data to the embedded health analysis for exact CRAP scoring.
|
|
2425
|
+
Use `--only` or `--skip` to control which analyses are included in the combined output. The `architecture` value selects the import cycles, boundary violations and policy violations of the dead-code analysis: `--only architecture` reports only them, and `--skip architecture` removes them. Human output shows them in an "Architecture" category after the other dead-code categories, with and without `--quiet`, and also with `--group-by` and `--summary`. Use `--coverage` and `--coverage-root` to feed Istanbul coverage data to the embedded health analysis for exact CRAP scoring.
|
|
2360
2426
|
|
|
2361
2427
|
With `--score`, the combined output's `health` section includes a `health_score` object (same schema as `health --score`). With `--trend`, it includes a `health_trend` object comparing against the most recent saved snapshot. With `--save-snapshot`, a vital signs snapshot is persisted for future trend comparisons.
|
|
2362
2428
|
|
|
@@ -213,7 +213,7 @@ fallow dead-code --format json --quiet --save-baseline fallow-baselines/dead-cod
|
|
|
213
213
|
fallow dead-code --format json --quiet --baseline fallow-baselines/dead-code.json --fail-on-issues
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
Commit the baseline file to your repo.
|
|
216
|
+
Commit the baseline file to your repo. When a fix removes a finding, its entry stays in the file until you prune it. `fallow baselines prune` removes the entries that match no current finding and never adds an entry, so it is safe to run after each fix. It reads the paths in `audit.deadCodeBaseline`, `audit.healthBaseline` and `audit.dupesBaseline`.
|
|
217
217
|
|
|
218
218
|
---
|
|
219
219
|
|
|
@@ -14,6 +14,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
|
|
|
14
14
|
| `code_execute` | composition | free | - | `code`, `timeout_ms`, `max_output_bytes` | Bounded read-only Code Mode for composing multiple fallow analysis calls in one JavaScript snippet. The snippet receives `{ fallow, root }`, returns JSON-serializable data, and can call read-only helpers such as `fallow.projectInfo`, `fallow.audit`, `fallow.checkHealth`, and `fallow.run(tool, params)` for the same allowlist. `fallow.all(requests)` fans out independent calls in one go: pass `[{ tool, params }, ...]` and get back a positionally aligned array of `{ ok: true, value }` or `{ ok: false, error }`, so one failing element never hides the rest. Host calls are memoized for the duration of one snippet, so repeating the same tool with the same params (key order does not matter) is served from cache, spends no `max_host_calls` slot and no output budget, and is reported in `calls[]` with `cache_hit: true`; a call refused before dispatch (unknown tool, malformed params) spends no slot either, and `limits.max_rejected_host_calls` bounds how many of those the response records. Similar-code is excluded because Code Mode is capped at 30 seconds; use standalone `find_similar_code` and `inspect_similar_code`, which have dedicated 15-minute timeouts. Mutating fix tools are not exposed, and a host call that passes `save_baseline`, `save_regression_baseline` or `save_snapshot` is refused with the name of the standalone tool to call. The sandbox has no filesystem, network, imports, `process`, `require`, `Deno`, `Bun`, or shell access, and no dynamic code compilation: `eval`, `Function`, and the async and generator function constructors are removed, including the `constructor` route reachable through function prototypes. Params: `code`, optional `root`, `timeout_ms` (capped at 30000), and `max_output_bytes` (capped at 4000000). `max_output_bytes` bounds two separate things: the total fallow JSON host calls read, shared across a `fallow.all` fan-out rather than granted per element, and the serialized snippet result. An oversized result is refused with `ok:false`, `truncated:true`, `result_bytes`, and a short `result_preview` in place of the value, never returned whole, so return a projection rather than a whole report. |
|
|
15
15
|
| `analyze` | analysis | free | `fallow dead-code --format json --quiet` | `issue_types`, `production`, `workspace`, `baseline`, `group_by`, `file` | Full dead code analysis (unused files/exports/types/dependencies/members + circular dependencies + re-export cycles (barrel files that form a structural loop, silently breaking re-exports) + package cycles (workspace packages that import each other in a loop) + boundary violations + rule-pack policy violations (banned calls, imports, and catalogue-derived effects declared via the `rulePacks` config key) + stale suppressions). Private type leaks are an opt-in API hygiene check via `issue_types: ["private-type-leaks"]`. Deprecated exports that still have consumers are an opt-in migration sweep via `issue_types: ["deprecated-exports-in-use"]`. Set `boundary_violations: true` as a convenience alias for `issue_types: ["boundary-violations"]`. Set `group_by` to `"owner"`, `"directory"`, `"package"`, or `"section"` to partition results. The `section` mode reads GitLab CODEOWNERS `[Section]` headers and emits `owners` metadata per group |
|
|
16
16
|
| `check_changed` | analysis | free | `fallow dead-code --changed-since <ref> --format json --quiet` | `since`, `baseline`, `fail_on_regression` | Incremental analysis of files changed since a git ref |
|
|
17
|
+
| `check_architecture` | analysis | free | `fallow architecture --format json --quiet` | `cycles`, `boundaries`, `policy`, `baseline`, `group_by`, `file` | Architecture check: import cycles, boundary violations, and rule-pack policy violations in the `architecture` envelope, each with a stable finding_id |
|
|
17
18
|
| `security_candidates` | analysis | free | `fallow security --format json --quiet` | `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://fallow.tools/docs/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. |
|
|
18
19
|
| `find_similar_code` | analysis | free | `fallow similar-code --format json --quiet` | `threshold`, `min_lines`, `top`, `changed_since`, `paths` | Find unverified semantically similar function candidates with the exact pinned local model. Discovery is read-only and never authorizes or performs model setup. Scoped output materializes the exact admitted files once in `generation.scope.paths` as provenance. Ask the user to run `fallow similar-code setup --local` when setup is missing. Cold local inference has a dedicated 15-minute subprocess window. |
|
|
19
20
|
| `inspect_similar_code` | trace | free | `fallow similar-code inspect <candidate-id> --candidates <report.json> --format json --quiet` | `candidate_id`, `snapshot` | Inspect one exact unverified candidate without rerunning provider retrieval or global ranking. Pass `candidate_id` plus a bounded typed snapshot containing the unchanged discovery `schema_version`, `generation`, selected `candidate`, `completion`, and `diagnostics`. Current source is re-extracted and both endpoint hashes must still match, so stale source fails closed. Keep candidate worthiness, behavioral equivalence, and refactor safety as separate verdicts, and abstain when evidence is incomplete. |
|
|
@@ -49,7 +50,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
|
|
|
49
50
|
| `trace_import_path` | trace | free | `fallow trace --path <from> <to> --format json --quiet` | `from`, `to` | Trace the shortest import path between two modules, hop by hop |
|
|
50
51
|
| `trace_error` | trace | free | `fallow trace-error - --format json --quiet` | `trace` | Resolve a runtime stack trace's frames against the project graph |
|
|
51
52
|
| `impact_closure` | trace | free | `fallow dead-code --impact-closure <path> --format json --quiet` | `path` | Trace the transitive affected-but-not-in-diff set and coordination gaps for one file. Supports `root`, `config`, `production`, `workspace`, `no_cache`, and `threads`. Use as review-planning evidence for a file contract, not proof that affected files are wrong |
|
|
52
|
-
| `trace_dependency` | trace | free | `fallow dead-code --trace-dependency <package> --format json --quiet` | `package_name` | Trace where a dependency is imported (`fallow dead-code --trace-dependency PACKAGE --format json`). Required `package_name`. Returns importing files, type-only importers, total import count, `used_in_scripts` (true when invoked from package.json scripts or CI configs), and `is_used` (combined import + script signal; mirrors the unused-deps detector so build tools like `microbundle` or `vitest` are not falsely flagged as unused). Use before removing a dependency or moving between `dependencies` and `devDependencies` |
|
|
53
|
+
| `trace_dependency` | trace | free | `fallow dead-code --trace-dependency <package> --format json --quiet` | `package_name`, `specifiers`, `sites`, `limit`, `cursor` | Trace where a dependency is imported (`fallow dead-code --trace-dependency PACKAGE --format json`). Required `package_name`. Returns importing files, type-only importers, total import count, `used_in_scripts` (true when invoked from package.json scripts or CI configs), and `is_used` (combined import + script signal; mirrors the unused-deps detector so build tools like `microbundle` or `vitest` are not falsely flagged as unused). Use before removing a dependency or moving between `dependencies` and `devDependencies` |
|
|
53
54
|
| `trace_clone` | trace | free | `fallow dupes --trace <file:line> --format json --quiet` | `file`, `line`, `fingerprint`, `near`, `min_occurrences` | Deep-dive a duplicate-code clone group (`fallow dupes --trace <spec> --format json`). Address by exactly one of: `file` + `line` (a source location), or `fingerprint` (a `dup:<id>` from a prior `find_dupes` `clone_groups[].fingerprint`, usually `dup:<8hex>` and widened only on rare report collisions). Returns the matched clone instance plus every clone group containing it; each traced group carries its `fingerprint`, an extract-function `suggestion` with estimated savings, and a best-effort `suggested_name` (omitted when no confident name). Supports `mode`, `near`, `min_tokens`, `min_lines`, `min_occurrences`, `threshold`, `skip_local`, `ignore_symlinks`, `cross_language`, `ignore_imports`. Use the same `near` value as the originating `find_dupes` call. Use to consolidate duplication when you need exact sibling locations and a refactor target |
|
|
54
55
|
<!-- generated:mcp-tools:end -->
|
|
55
56
|
|
|
@@ -15,7 +15,7 @@ const similarCode = await detectSimilarCode({ root: process.cwd(), files: ['src/
|
|
|
15
15
|
const health = await computeHealth({ root: process.cwd(), score: true, ownershipEmails: 'handle' });
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
The async functions are `detectDeadCode`, `detectCircularDependencies`, `detectBoundaryViolations`, `detectDuplication`, `detectSimilarCode`, `detectFeatureFlags`, `computeComplexity`, and `computeHealth`. Each returns the same JSON envelope the CLI emits for `--format json`.
|
|
18
|
+
The async functions are `detectDeadCode`, `detectCircularDependencies`, `detectBoundaryViolations`, `detectArchitecture`, `detectDuplication`, `detectSimilarCode`, `detectFeatureFlags`, `computeComplexity`, and `computeHealth`. Each returns the same JSON envelope the CLI emits for `--format json`. `detectArchitecture` returns the `kind: "architecture"` envelope of `fallow architecture`; `detectCircularDependencies` and `detectBoundaryViolations` return the `dead-code` envelope.
|
|
19
19
|
|
|
20
20
|
`detectSimilarCode` returns a precisely typed `SimilarCodeReport` with generation provenance, embedding semantics, effective `generation.scope.paths`, completion, skips, cache accounting, diagnostics, and read-only candidate actions. Treat the materialized scope as provenance. Preserve the raw report when a candidate may be inspected later.
|
|
21
21
|
|
|
@@ -334,14 +334,16 @@ git commit -m "chore: add fallow baseline"
|
|
|
334
334
|
fallow dead-code --format json --quiet --baseline fallow-baselines/dead-code.json --fail-on-issues
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
-
### Step 4: Gradually fix and
|
|
337
|
+
### Step 4: Gradually fix and prune the baseline
|
|
338
338
|
|
|
339
|
-
As you fix existing issues,
|
|
339
|
+
As you fix existing issues, remove their entries from the baseline. Prune removes only the entries that match no current finding, so a new finding stays visible:
|
|
340
340
|
|
|
341
341
|
```bash
|
|
342
|
-
fallow
|
|
342
|
+
fallow baselines prune --dead-code-baseline fallow-baselines/dead-code.json --format json --quiet
|
|
343
343
|
```
|
|
344
344
|
|
|
345
|
+
With `audit.deadCodeBaseline`, `audit.healthBaseline` and `audit.dupesBaseline` in the config, `fallow baselines prune` prunes all three files in one run. Use `--save-baseline` only to record new findings on purpose. `fallow hooks install --target git --prune-baselines` runs the prune in the pre-commit hook and stages the pruned files.
|
|
346
|
+
|
|
345
347
|
### Duplication baseline
|
|
346
348
|
|
|
347
349
|
Same pattern works for duplication:
|
|
@@ -781,6 +783,7 @@ Prefer `fallow hooks install --target agent` to install this file. The script is
|
|
|
781
783
|
|
|
782
784
|
Behavior you can rely on:
|
|
783
785
|
- The handler walks up from the session directory to the nearest directory that holds `.claude/hooks/fallow-gate.sh` and runs the audit there, so a session in a package directory audits the install root. The walk stops at the first `.git` entry. When it finds no script, the handler runs the script under `$CLAUDE_PROJECT_DIR` from the session directory.
|
|
786
|
+
- The hook process can start in a directory that is not the session directory, for example in the main checkout when the session works in a nested git worktree. The script reads the session directory from the `cwd` field of the hook input and finds the audit root from it with the same walk. When the walk finds no script, for example with the user-scope script in `$HOME`, the audit root is the directory of the hook process when it is in the git work tree of the session. Else it is the git top level of the session directory, or the session directory outside a git repository. The audit root is never `$HOME`. The script compares physical paths, so a symlink does not change the walk. When the hook input has no usable `cwd`, the audit runs in the directory of the hook process.
|
|
784
787
|
- Runs only when the intercepted command is a `git commit` or `git push`, including invocations that pass git-level options before the subcommand (`git -c user.name=x commit`, `git --no-pager commit`, `git -C dir push`, `git --git-dir=/x push`); anything else exits 0. Set `FALLOW_GATE_DEBUG=1` to log skipped commands to stderr.
|
|
785
788
|
- Resolves `fallow` from PATH first, then `npx --no-install fallow` as a fallback. Skips with a stderr notice if neither is available or if `jq` is missing.
|
|
786
789
|
- Enforces a version floor via `FALLOW_GATE_MIN_VERSION`. The installed gate script holds the default floor (currently `2.85.0`). Fallow maintainers raise that default by hand; `fallow hooks install` does not set it to the installed version. Binaries below the floor are blocked with an upgrade hint. Set the env var to the empty string to disable the check.
|
|
@@ -58,4 +58,4 @@ fallow health --format json --quiet --save-baseline fallow-baselines/health.json
|
|
|
58
58
|
fallow dupes --format json --quiet --save-baseline fallow-baselines/dupes.json
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
Commit the baseline files. Pass each file to the matching command with `--baseline <path>`. `fallow audit` uses `--dead-code-baseline`, `--health-baseline`, and `--dupes-baseline` instead. `--fail-on-baseline-growth` makes a committed baseline shrink-only. Tell the user how many findings the baseline contains, and suggest that the team removes them by category.
|
|
61
|
+
Commit the baseline files. Pass each file to the matching command with `--baseline <path>`. `fallow audit` uses `--dead-code-baseline`, `--health-baseline`, and `--dupes-baseline` instead. `--fail-on-baseline-growth` makes a committed baseline shrink-only. After a fix, `fallow baselines prune` removes the entries that match no current finding, so `--fail-on-stale-baseline` stays green. Point `audit.deadCodeBaseline`, `audit.healthBaseline` and `audit.dupesBaseline` at the files so that one command prunes all three. Tell the user how many findings the baseline contains, and suggest that the team removes them by category.
|