Skip to content

v2.68.0 - Typed PR/MR feedback layer + jsonc migration output

Choose a tag to compare

@BartWaardenburg BartWaardenburg released this 09 May 08:28
· 3855 commits to main since this release
v2.68.0
ffa223d

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__/target as unresolved-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 every vi.mock call. 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. Bumps CACHE_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 as unused-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 ; inside void (...) 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_scopes into the analyze pipeline, so dead-code saw .client / .server / equivalent plugin-contributed directories correctly, but list, 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.ts is detected as a generator config and credited. The plugin previously only looked at the canonical turbo.json location; per-package <package>/_generators/config.ts files (Turborepo Custom Generator pattern) surfaced as unused-file. Thanks @filipw01. #312.

  • Jest plugin follows the projects field across all three real-world shapes (string globs, package.json#jest keys, and inline ProjectConfig objects). A root jest.config.js that delegates discovery via projects: ['<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 only referenced_dependencies and setup_files back into the parent so per-package testMatch stays scoped.

  • .fallowrc.jsonc is consistently documented across every user-facing surface (the MCP config param doc, fallow --config flag 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 npm cli-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 pluralizes code 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