Repository navigation
v2.68.0 - Typed PR/MR feedback layer + jsonc migration output
Highlights
Typed PR / MR feedback layer. The bash + jq layer that posted sticky PR comments and inline reviews is replaced with four typed Rust output formats (pr-comment-github, pr-comment-gitlab, review-github, review-gitlab) and a new fallow ci reconcile-review subcommand for stale-thread resolution. Combined-mode comments now render one sticky comment with collapsible <details> sections per category, truncated sections foreshadow the cap in the header (Duplication (160, showing 50)), and inline reviews ship with code-suggestion blocks for unused exports, class members, enum members, plus a text hint for unused files. SARIF gains partialFingerprints under both tools.fallow.fingerprint/v1 and primaryLocationLineHash/v1 so GitHub Code Scanning deduplicates fallow alerts across pushes; CodeClimate gains a deterministic fingerprint (required by GitLab Code Quality). Eleven new typed inputs: / variables: (comment-id, diff-filter, max-comments, api-retries, api-retry-delay, ...) make every wrapper knob discoverable in the GitHub Marketplace UI and the GitLab template. --workspace web,admin hashes the sorted list to a stable 6-hex marker suffix so parallel monorepo jobs do not race each other's sticky body. Twelve review-pad jq files retire; comment.sh and review.sh shrink to typed-format wrappers with paginated comment-list lookups, structured-error envelope guards, rate-limit + transient-5xx retry, and bot-authorship gating. (#315)
fallow migrate writes .fallowrc.jsonc for JSONC sources. Migrating a .jsonc source now produces .fallowrc.jsonc (matching the source extension) so editors auto-detect JSON-with-comments syntax and JSON validators stop flagging the // comments fallow has always emitted. New --jsonc flag forces the JSONC output path explicitly; mutually exclusive with --toml. Closes #313.
Fixes
-
vi.mock('./target', factory)credits the target file instead of surfacing a phantom__mocks__/targetasunresolved-import. Two bugs fell out of one: vitest only consults the__mocks__/<file>sibling when no factory is provided, but the auto-mock heuristic synthesized it for everyvi.mockcall. The visitor now records the target file as side-effect reachability, and only synthesizes__mocks__/<file>when no factory is provided. Detects arrow factories, function-expression factories, and nested parenthesized variants. BumpsCACHE_VERSION. Thanks @filipw01. Closes #311. -
Cross-package namespace-object aliases stay credited through multi-hop named-re-export barrels. When a package layers 1 to 3 named-re-export barrels between its public entry and the alias-defining file, consumers landing at any intermediate barrel were missed and
API.bar.<member>access targets were reported asunused-export. The Phase 2b matcher now does a forward BFS over re-export edges starting from(alias_file, via_export_name)to enumerate every reachable(barrel_file, exported_name_at_barrel)pair. Thanks @filipw01. Closes #310. -
Angular
@if (member(); as alias)no longer flags the conditioned member as unused. The Angular template scanner previously passed the entire parenthesized content to oxc as a single expression; the;insidevoid (...)failed to parse, so neither the call nor the alias was extracted. The scanner now splits the alias clause off the condition before parsing. Thanks @OmerGronich. Closes #308. -
Plugin-scoped hidden directories are traversed by every discovery consumer. The first cut wired
discovery_hidden_dir_scopesinto the analyze pipeline, so dead-code saw.client/.server/ equivalent plugin-contributed directories correctly, butlist,dupes,health,flags,coverage, and the rest re-walked with the default hidden-dir allowlist and skipped them. Coverage is now uniform across the toolchain. Thanks @jadengis. Closes #309. -
Turborepo
_generators/config.tsis detected as a generator config and credited. The plugin previously only looked at the canonicalturbo.jsonlocation; per-package<package>/_generators/config.tsfiles (Turborepo Custom Generator pattern) surfaced asunused-file. Thanks @filipw01. #312. -
Jest plugin follows the
projectsfield across all three real-world shapes (string globs,package.json#jestkeys, and inlineProjectConfigobjects). A rootjest.config.jsthat delegates discovery viaprojects: ['<rootDir>/packages/*']previously left fallow blind to every child config. The plugin now expands each entry against the filesystem (with<rootDir>substitution and glob support), recurses with cycle protection, and merges onlyreferenced_dependenciesandsetup_filesback into the parent so per-packagetestMatchstays scoped. -
.fallowrc.jsoncis consistently documented across every user-facing surface (the MCPconfigparam doc,fallow --configflag help, GitHub Action and GitLab CI input descriptions, the VS Code first-run page,AGENTS.md, the fallow-docs configuration / init pages, and the bundled npmcli-reference.md). Detection has worked since v2.57.0; only the docs drifted. Thanks @pdeveltere. Closes #313. -
PR / MR comment polish. Complexity dropdown header pluralizes singular finding (
(1 function above threshold)instead of(1 functions ...)), the status bar pluralizescode issue / clone group / health finding, and inline review-comment URLs keep the full path when display is shortened (the previous version 404'd on monorepo paths longer than 3 segments).
Test plan
The release was validated with the standard pre-flight (cargo check --workspace, cargo clippy -p fallow-cli -p fallow-mcp -- -D warnings, cargo test -p fallow-cli -p fallow-mcp, cargo fmt --check, typos ., bash action/tests/run.sh, bash ci/tests/run.sh).
Full Changelog: v2.67.0...v2.68.0