fallow 2.96.0 → 2.97.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 +10 -10
- package/schema.json +242 -2
- package/skills/fallow/SKILL.md +17 -23
- package/skills/fallow/references/cli-reference.md +23 -15
- package/skills/fallow/references/gotchas.md +12 -0
- package/types/output-contract.d.ts +3271 -1300
|
@@ -61,6 +61,13 @@ Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#
|
|
|
61
61
|
| `--private-type-leaks` | Opt-in API hygiene check (default `off`) for exported signatures that reference same-file private types. Storybook `*.stories.*` story files and framework routing convention files (Next.js App + Pages Router, Gatsby, Remix v2, TanStack Router, Expo Router) are skipped to avoid noise. Enable via this flag or `private-type-leaks: "warn"` / `"error"` in [`rules`](#rules-configuration). |
|
|
62
62
|
| `--unused-enum-members` | Unused enum members |
|
|
63
63
|
| `--unused-class-members` | Unused class members |
|
|
64
|
+
| `--unused-store-members` | Unused Pinia store members |
|
|
65
|
+
| `--unprovided-injects` | inject() / getContext() reads a key that no provide() / setContext() supplies |
|
|
66
|
+
| `--unrendered-components` | A Vue / Svelte component is reachable through a barrel but rendered nowhere |
|
|
67
|
+
| `--unused-component-props` | A Vue defineProps prop or React component prop is referenced nowhere in its own component |
|
|
68
|
+
| `--unused-component-emits` | A Vue <script setup> defineEmits event is emitted nowhere in its own component |
|
|
69
|
+
| `--unused-server-actions` | A Next.js Server Action exported from a "use server" file is referenced by no code in the project |
|
|
70
|
+
| `--unused-load-data-keys` | A SvelteKit load() return-object key is read by no consumer |
|
|
64
71
|
| `--unresolved-imports` | Unresolved imports |
|
|
65
72
|
| `--unlisted-deps` | Unlisted dependencies |
|
|
66
73
|
| `--duplicate-exports` | Duplicate exports |
|
|
@@ -146,8 +153,8 @@ By default, `fallow dupes` skips generated framework output matching `**/.next/*
|
|
|
146
153
|
| `--threshold` | `string` | - | Fail if duplication exceeds this percentage |
|
|
147
154
|
| `--skip-local` | `bool` | `false` | Only report cross-directory duplicates |
|
|
148
155
|
| `--cross-language` | `bool` | `false` | Strip type annotations for TS↔JS matching |
|
|
149
|
-
| `--ignore-imports` | `bool` | `false` | Exclude
|
|
150
|
-
| `--no-ignore-imports` | `bool` | `false` | Count
|
|
156
|
+
| `--ignore-imports` | `bool` | `false` | Exclude module wiring from clone detection |
|
|
157
|
+
| `--no-ignore-imports` | `bool` | `false` | Count module wiring as clone candidates (opt out of the default exclusion) |
|
|
151
158
|
| `--top` | `string` | - | Show only the N most-duplicated clone groups (sorted by instance count desc, tiebreak: line count desc, then path/line). Summary stats reflect the full project. |
|
|
152
159
|
| `--trace` | `string` | - | Deep-dive clones. `FILE:LINE` traces all clones at a location; `dup:<id>` traces a clone group by the stable fingerprint shown in the listing and on `clone_groups[].fingerprint` in JSON. Fingerprints are usually `dup:<8hex>` and widen only on rare report collisions. Trace output adds an extract-function suggestion, estimated savings, and a best-effort proposed name per group |
|
|
153
160
|
|
|
@@ -384,6 +391,7 @@ Angular templates contribute synthetic `<template>` complexity findings whenever
|
|
|
384
391
|
| `--ownership` | `bool` | `false` | Attach ownership signals to hotspot entries: bus factor (Avelino truck factor), contributor count, top contributor with stale-days, recent contributors (top-3), `suggested_reviewers`, declared CODEOWNERS owner, `ownership_state`, ownership drift, unowned-hotspot detection. Human output gains a project-level summary line. JSON adds `low-bus-factor`, `unowned-hotspot`, `ownership-drift` action types. Test files get a `[test]` tag. Implies `--hotspots`. Requires git. |
|
|
385
392
|
| `--ownership-emails` | `raw\|handle\|anonymized\|hash` | - | Privacy mode for author emails. `handle` shows the local-part only (default, with GitHub noreply unwrap and deterministic same-handle disambiguation). `anonymized` emits stable `xxh3:` pseudonyms; `hash` remains accepted as the legacy spelling. `raw` shows full addresses. Use `anonymized` in regulated environments. Implies `--ownership`. Configure default via `health.ownership.emailMode`. |
|
|
386
393
|
| `--targets` | `bool` | `false` | Show only refactoring targets: ranked recommendations based on complexity, coupling, churn, and dead code signals. Categories: churn+complexity, circular dep, high impact, dead code, complexity, coupling. When no section flags are set, all sections are shown by default. Each target's JSON can include `direct_callers[]` (direct importers with the symbols they import) and `clone_siblings[]` (duplicate-code siblings with stable `dup:<8hex>` fingerprints for `fallow dupes --trace`); both omitted when empty. Human output adds `importers:` / `clones:` lines only when that evidence is present. |
|
|
394
|
+
| `--css` | `bool` | `false` | Add structural CSS analytics: specificity hotspots, !important density, over-complex selectors, deep nesting, and conservative cleanup candidates. Standard CSS is parsed structurally; preprocessor sources are scanned only where fallow can avoid expanding Sass/Less semantics. |
|
|
387
395
|
| `--effort` | `low\|medium\|high` | - | Filter refactoring targets by effort level. Implies `--targets`. |
|
|
388
396
|
| `--score` | `bool` | `false` | Show only the project health score (0-100) with letter grade (A/B/C/D/F). The score is included by default when no section flags are set. JSON includes `health_score` object with `score`, `grade`, and `penalties` breakdown. As of v2.55.0, plain `--score` skips the churn-backed hotspot penalty so it does not run a `git log` shell-out per invocation; pass `--hotspots` (or `--targets` with `--score`) to include the hotspot penalty. Snapshot (`--save-snapshot`) and trend (`--trend`) flows still trigger hotspot vital signs so saved data stays complete. |
|
|
389
397
|
| `--min-score` | `string` | - | Fail (exit 1) only when the health score is below this threshold. Implies `--score`. Authoritative CI quality gate: when set, complexity findings are demoted to informational and the exit code is driven solely by the score, so `--min-score 0` always exits 0. Composes with `--min-severity`. |
|
|
@@ -493,7 +501,7 @@ fallow health --format json --quiet --trend
|
|
|
493
501
|
{
|
|
494
502
|
"kind": "health",
|
|
495
503
|
"schema_version": 7,
|
|
496
|
-
"version": "2.
|
|
504
|
+
"version": "2.97.0",
|
|
497
505
|
"elapsed_ms": 32,
|
|
498
506
|
"summary": {
|
|
499
507
|
"files_analyzed": 482,
|
|
@@ -880,7 +888,7 @@ fallow audit \
|
|
|
880
888
|
{
|
|
881
889
|
"kind": "audit",
|
|
882
890
|
"schema_version": 7,
|
|
883
|
-
"version": "2.
|
|
891
|
+
"version": "2.97.0",
|
|
884
892
|
"command": "audit",
|
|
885
893
|
"verdict": "fail",
|
|
886
894
|
"changed_files_count": 12,
|
|
@@ -955,7 +963,7 @@ fallow flags --format json --quiet --workspace my-package
|
|
|
955
963
|
```json
|
|
956
964
|
{
|
|
957
965
|
"schema_version": 7,
|
|
958
|
-
"version": "2.
|
|
966
|
+
"version": "2.97.0",
|
|
959
967
|
"elapsed_ms": 116,
|
|
960
968
|
"feature_flags": [],
|
|
961
969
|
"total_flags": 0
|
|
@@ -1055,7 +1063,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1055
1063
|
{
|
|
1056
1064
|
"kind": "security",
|
|
1057
1065
|
"schema_version": "4",
|
|
1058
|
-
"version": "2.
|
|
1066
|
+
"version": "2.97.0",
|
|
1059
1067
|
"elapsed_ms": 42,
|
|
1060
1068
|
"config": {
|
|
1061
1069
|
"rules": {
|
|
@@ -1084,7 +1092,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1084
1092
|
{
|
|
1085
1093
|
"kind": "security",
|
|
1086
1094
|
"schema_version": "4",
|
|
1087
|
-
"version": "2.
|
|
1095
|
+
"version": "2.97.0",
|
|
1088
1096
|
"elapsed_ms": 42,
|
|
1089
1097
|
"config": {
|
|
1090
1098
|
"rules": {
|
|
@@ -1545,8 +1553,8 @@ Available on all commands:
|
|
|
1545
1553
|
| `--dupes-min-occurrences` | `string` | - | Override the minimum clone occurrences in combined mode (must be >= 2) |
|
|
1546
1554
|
| `--dupes-skip-local` | `bool` | `false` | Only report cross-directory duplicates in combined mode |
|
|
1547
1555
|
| `--dupes-cross-language` | `bool` | `false` | Enable cross-language duplicate detection in combined mode |
|
|
1548
|
-
| `--dupes-ignore-imports` | `bool` | `false` | Exclude
|
|
1549
|
-
| `--dupes-no-ignore-imports` | `bool` | `false` | Count
|
|
1556
|
+
| `--dupes-ignore-imports` | `bool` | `false` | Exclude module wiring from duplicate detection in combined mode |
|
|
1557
|
+
| `--dupes-no-ignore-imports` | `bool` | `false` | Count module wiring as clone candidates in combined mode (opt out of the default exclusion) |
|
|
1550
1558
|
| `--score` | `bool` | `false` | Compute health score (0-100 with letter grade) in combined mode. Enables the health delta header in PR comments. JSON includes `health_score` object with `score`, `grade`, and `penalties` breakdown |
|
|
1551
1559
|
| `--trend` | `bool` | `false` | Compare current health metrics against saved snapshot. Implies `--score`. Shows per-metric deltas with directional indicators. Requires at least one saved snapshot in `.fallow/snapshots/` |
|
|
1552
1560
|
| `--save-snapshot` | `string` | - | Save vital signs snapshot for trend tracking. Default path: `.fallow/snapshots/<timestamp>.json`. Forces file-scores + hotspot computation |
|
|
@@ -1574,7 +1582,7 @@ Available on all commands:
|
|
|
1574
1582
|
| `--dupes-min-occurrences` | `string` | - | Override the minimum clone occurrences in combined mode (must be >= 2) |
|
|
1575
1583
|
| `--dupes-skip-local` | `bool` | `false` | Only report cross-directory duplicates in combined mode |
|
|
1576
1584
|
| `--dupes-cross-language` | `bool` | `false` | Enable cross-language duplicate detection in combined mode |
|
|
1577
|
-
| `--dupes-ignore-imports` | `bool` | `false` | Exclude
|
|
1585
|
+
| `--dupes-ignore-imports` | `bool` | `false` | Exclude module wiring from duplicate detection in combined mode |
|
|
1578
1586
|
| `--score` | `bool` | `false` | Compute health score in combined mode |
|
|
1579
1587
|
| `--trend` | `bool` | `false` | Compare current health metrics against the most recent saved snapshot |
|
|
1580
1588
|
| `--save-snapshot` | `string` | - | Save a vital signs snapshot for trend tracking in combined mode. Provide a path or omit for the default `.fallow/snapshots/` location |
|
|
@@ -1701,7 +1709,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
|
|
|
1701
1709
|
{
|
|
1702
1710
|
"kind": "dead-code",
|
|
1703
1711
|
"schema_version": 7,
|
|
1704
|
-
"version": "2.
|
|
1712
|
+
"version": "2.97.0",
|
|
1705
1713
|
"elapsed_ms": 45,
|
|
1706
1714
|
"total_issues": 12,
|
|
1707
1715
|
"entry_points": {
|
|
@@ -1861,7 +1869,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
|
|
|
1861
1869
|
{
|
|
1862
1870
|
"kind": "dupes",
|
|
1863
1871
|
"schema_version": 7,
|
|
1864
|
-
"version": "2.
|
|
1872
|
+
"version": "2.97.0",
|
|
1865
1873
|
"elapsed_ms": 82,
|
|
1866
1874
|
"total_clones": 15,
|
|
1867
1875
|
"total_lines_duplicated": 230,
|
|
@@ -1905,11 +1913,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
|
|
|
1905
1913
|
{
|
|
1906
1914
|
"kind": "combined",
|
|
1907
1915
|
"schema_version": 7,
|
|
1908
|
-
"version": "2.
|
|
1916
|
+
"version": "2.97.0",
|
|
1909
1917
|
"elapsed_ms": 159,
|
|
1910
1918
|
"check": {
|
|
1911
1919
|
"schema_version": 7,
|
|
1912
|
-
"version": "2.
|
|
1920
|
+
"version": "2.97.0",
|
|
1913
1921
|
"elapsed_ms": 45,
|
|
1914
1922
|
"total_issues": 12,
|
|
1915
1923
|
"unused_files": [],
|
|
@@ -2131,4 +2139,4 @@ preset = "bulletproof"
|
|
|
2131
2139
|
|
|
2132
2140
|
### Valid Issue Type Tokens
|
|
2133
2141
|
|
|
2134
|
-
`unused-file`, `unused-export`, `unused-type`, `unused-dependency`, `unused-dev-dependency`, `unused-enum-member`, `unused-class-member`, `unresolved-import`, `unlisted-dependency`, `duplicate-export`, `circular-dependency`, `re-export-cycle`, `boundary-violation`, `policy-violation`, `unused-optional-dependency`, `type-only-dependency`, `test-only-dependency`, `code-duplication`
|
|
2142
|
+
`unused-file`, `unused-export`, `unused-type`, `unused-dependency`, `unused-dev-dependency`, `unused-enum-member`, `unused-class-member`, `unused-store-member`, `unresolved-import`, `unlisted-dependency`, `duplicate-export`, `circular-dependency`, `re-export-cycle`, `boundary-violation`, `policy-violation`, `unused-optional-dependency`, `type-only-dependency`, `test-only-dependency`, `code-duplication`
|
|
@@ -462,6 +462,18 @@ Fallow marks `src/fragments/user-fields.graphql` or `src/fragments/user-fields.g
|
|
|
462
462
|
|
|
463
463
|
---
|
|
464
464
|
|
|
465
|
+
## Tailwind v4 `@theme` Tokens Are Conservative Cleanup Candidates
|
|
466
|
+
|
|
467
|
+
When `fallow health --css` reports `css_analytics.unused_theme_tokens`, treat the rows as dead-design-token candidates, not as auto-fix instructions. A Tailwind v4 `@theme` token such as `--color-brand` is considered used when fallow sees a generated utility suffix such as `bg-brand` or `text-brand`, a `var(--color-brand)` read, an `@apply` utility, a Tailwind arbitrary value such as `rounded-[--radius-card]`, or another `@theme` token that references it.
|
|
468
|
+
|
|
469
|
+
The detector intentionally abstains when a Tailwind plugin or published CSS surface could consume tokens invisibly. Always run the row's `actions[].command` verification before deleting a token, and do not run `fallow fix` for these rows.
|
|
470
|
+
|
|
471
|
+
## CSS Health Candidates Are Advisory
|
|
472
|
+
|
|
473
|
+
`fallow health --css` also emits advisory cleanup and typo candidates in `css_analytics.unreferenced_css_classes` (a plain-CSS class defined but matched by no `class`/`className` in project markup), `css_analytics.unresolved_class_references` (the reverse: a markup class one edit away from a defined class, a likely typo), `css_analytics.unused_font_faces`, `css_analytics.undefined_keyframes`, and `css_analytics.font_size_unit_mix`. Treat them like review prompts, not confirmed defects. Run each row's `actions[].command` before changing CSS, because fonts, classes, animations, and type scales can be driven by inline styles, JavaScript, CMS templates, or preprocessor expansion that static analysis intentionally does not execute.
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
465
477
|
## Library Packages: Use `publicPackages` Instead of Visibility Tags
|
|
466
478
|
|
|
467
479
|
In monorepos, shared library packages have exported APIs consumed by external consumers not visible to fallow. Instead of annotating every export with `/** @public */` (or `@internal`, `@beta`, `@alpha`), use the `publicPackages` config to mark entire workspace packages as public libraries. Exports and exported enum/class members from these packages are excluded from unused API detection.
|