Skip to content

v3.38.0: file-length limit, Fallow Cloud setup and login, lean JSON for agents

Choose a tag to compare

@BartWaardenburg BartWaardenburg released this 30 Oct 19:47
· 295 commits to main since this release
Immutable release. Only release title and notes can be modified.
v3.38.0
3d63c43

Features

  • fallow health can report files that are too long. Set health.maxFileLines or pass --max-file-lines <N>. Fallow then reports each file with more physical lines than the limit, blank and comment lines included. The default is 0, so the check is off. The new complexity-file-lines rule (default error) decides if a long file fails the run. SARIF and CodeClimate use the rule id fallow/long-file. thresholdOverrides[].maxFileLines sets a different limit for some files. In fallow audit, an existing long file stays inherited until it grows by 5 lines or more. Set the limit in an old project to stop further growth. The MCP check_health and Code Mode combined tools and the Node bindings accept the limit. The GitHub Action has a max-file-lines input, the GitLab template has FALLOW_MAX_FILE_LINES, and the VS Code Health view shows long files. (#3977)

  • fallow coverage setup --cloud plans a Fallow Cloud setup in one command. Fallow Cloud joins runtime coverage to the static inventory only when every step uses the same commit SHA. The plan gives beacon snippets that read the SHA from an environment variable, such as VERCEL_GIT_COMMIT_SHA or VITE_FALLOW_COMMIT_SHA. It also gives GitHub Actions steps in cloud.ci.steps: a full-history checkout, the inventory upload, the source-map uploads and the deployment registration for $GITHUB_SHA. The plan names the key variables and never a key value. It writes no file. --json adds a cloud object. --wait polls Fallow Cloud until every step is done. It exits 0 on success, 1 on a timeout and 2 on an authentication, key scope or input error. (#3976)

  • fallow cloud login stores a read-only Fallow Cloud key without copy and paste. The command shows a code and a URL. After an organization owner approves the code, fallow stores the key in the OS keychain. With no keychain, fallow stores it in ~/.config/fallow/credentials with mode 0600. fallow cloud logout removes the key. Commands that read production data, and the MCP cloud tools, search for a key in this order: --api-key, $FALLOW_API_KEY, the keychain, the credentials file. Upload commands still read only --api-key and $FALLOW_API_KEY, because the stored key is read-only. (#4000)

  • fallow inspect --file <path> --cloud shows production data for each function in a file. For each function you get its state in the deployment, its state over the period, calls, error groups, CPU milliseconds per hour and never-run branch ranges. Fallow pairs each local function with its deployed function by stable id, then by its name and position among functions with the same name. A missing key, a plan limit or an unreachable cloud prints a status in the cloud section, and the run does not fail. The new --format compact prints about 1 KB of plain text per file, which an editor hook can add to the context as it is. (#4000)

  • --lean makes the JSON report smaller for agent context. Use it with --format json on fallow dead-code, fallow health or the bare fallow run. The lean report omits empty arrays and dead-code summary counts that are zero. The lean report keeps one workspace diagnostic per kind and the first 10 rows of the hotspots, file_scores and large_functions tables. <table>_omitted gives the number of rows left out. --full-tables keeps every row. The root field profile: "lean" marks a lean report. Runs without --lean do not change. (#4007, #3992)

  • fallow mutation --kill-matrix lists tests that may be redundant. This opt-in mode runs every covering test of each mutant, so the run can take longer. It reports a test when other tests also kill every mutant that the test kills. Review each reported test before you remove it. (#3997)

  • Source-map uploads record where each generated line starts. fallow coverage upload-source-maps adds x_fallow_line_starts to each map. Fallow Cloud uses this field to find the function behind a browser Long Animation Frame in a chunk with more than one line. This also works for an anonymous function. A missing or unreadable script gives no field. (#3990, #3991)

  • Inventory and source-map uploads accept a Vercel deployment binding. Pass --vercel-deployment-id, or let fallow read VERCEL_DEPLOYMENT_ID during a Vercel build. Fallow Cloud checks the deployment against the upload SHA. (#4008)

Changed

  • fallow similar-code computes vectors about 2.7x faster on Apple silicon. The macOS builds of the fallow-similar-code companion now use Apple's Accelerate framework. On an Apple M5, 200 functions took 14.8 s instead of 40.7 s. This release has no measurement for Intel Macs. Linux and Windows builds do not change. The largest change in cosine similarity over 19,900 function pairs was 0.000001. (#3995, #3993)

  • The mutation and mutation-inspect JSON output moves to schema version "2". The mutation journal and the result cache also use a new format. See the upgrade notes. (#3997)

  • fallow flags gives medium confidence to generic SDK names in a file without a flag import. The names are isOn, isOff, useConfig, variation, getVariant and hasFeature. A product call such as getVariant('oak-30x40') was a high confidence flag before. A file that imports a flag SDK or a flag module keeps high, and so does a name in flags.sdkPatterns. (#3982)

  • --explain lists only the rules of the reported findings. _meta.rules in dead-code, architecture and combined JSON now holds only the rule codes with a finding in the run. A run without findings has no rules key. fallow explain <rule> still gives the text of any rule. (#4007, #3992)

  • The fallow skill says that covered_by_test can be false. Fallow Cloud reports false when a test or CI run tracked a function and never called it. An edit to a hot function with false is high risk, the same as null. (#3979)

Bug fixes

  • Inventory function names now match the names from the coverage instrumenter. Before, some functions got a different name in the inventory than in the runtime coverage, so Fallow Cloud did not join them. fallow coverage upload-inventory now follows the rules of oxc-coverage-instrument and Function.prototype.name:

    • A function assigned with = takes the variable name: startLoad = () => {} gives startLoad.
    • A function with its own name keeps it: const f = function g() {} gives g.
    • Only a direct argument of a call takes the callee name: foo([() => 1]) now gives (anonymous_N).
    • A default value takes its binding name: function Button({ onClick = () => {} }) gives onClick.

    The stable id of a renamed function changes. (#3965)

  • Fallow no longer reports a member suppression that only --production needs as stale in a normal run. Production mode excludes test files, so a member that only a test reads is unused in production mode. Fallow now keeps the fallow-ignore-next-line comment out of stale-suppression for enum, class and Pinia store members. The comment stays stale when a production file reads the member. Thanks @Smrtnyk for the report. (#3962, #3970, #3975)

  • fallow dead-code credits a member called on the return type of a method that a class calls through this. For this.current()?.onDown?.() with private current(): Tool | undefined, fallow now credits Tool.onDown. This also works for #-private methods and private getters. Thanks @Smrtnyk for the report. (#3960, #3971)

  • fallow dead-code no longer reports the default export of a local Oxlint jsPlugins entry as unused when the entry names a directory or omits the extension. Fallow now resolves the entry to the file that Oxlint loads, through the main field, an index file or a known extension. Thanks @Smrtnyk for the report. (#3961, #3968)

  • Fallow no longer reports unused exports in alias replacement files that the resolver never reaches. With includeEntryExports, fallow reported these exports as unused. Fallow now credits them for these alias keys:

    • a relative path in a Vitest alias, such as { find: "./clock.js", replacement: "./test/stubs/clock.ts" };
    • an installed package name in a Vitest, Vite or webpack alias, including a webpack exact-match key such as pkg$;
    • a relative path in a Vite mode config, such as vite.config.prod.ts, or in a webpack alias.

    A key for a package that is not installed, and a path alias such as @lib, keep precise export tracking. Thanks @Smrtnyk for the report. (#3963, #3969, #3974, #3978)

  • A Vite alias with a regular expression find now resolves. Fallow reads three anchored shapes: a literal such as /^node:module$/, a prefix with one capture such as /^@\/(.*)$/ with a /$1 replacement, and a prefix that ends with a slash. Other regular expression shapes still give no alias. Thanks @VariableVince for the report. (#3317, #3983)

  • Fallow reads a config that a function builds from local bindings. For a webpack config such as (env) => { const common = {...}; return [{ ...common, entry }]; }, fallow reported the entries as unused files. Fallow now reads local const and let bindings with a literal value, object spreads and returned arrays, without running the config code. For webpack and rspack, it reads up to 64 configs of an exported array. Fallow does not read a binding that the config can change. The new config reading applies to every plugin that reads a JavaScript or TypeScript config. (#3981, #3987)

  • Package script arguments no longer make every file in a glob an entry point. In node tool.js src/**/*.js, node runs only tool.js, so the glob is data. The same rule applies to tsx, ts-node, bun, deno run, nodemon and shells. An unknown program expands no glob but keeps its literal file arguments. Test runners, bundlers and compilers keep their file arguments as entry points. The rules also apply to shell helpers, CI steps and Dockerfile commands. Thanks @waldoluisribeiro for the report. (#3967, #3986)

  • fallow audit --base keeps an unchanged styling finding inherited after a line shift. Before, a line added above a CSS rule marked its css-* finding as introduced. The audit now matches a styling finding by its code, sub-kind, file and value, not by its line. Thanks @cheetahbyte for the report. (#3956, #3972)

  • --type-aware accepts the tsrs and TypeScript versions that a project already installs. The experimental tsrs backend now accepts any tsrs from 0.18.0 up to but not including 1.0.0, and the default backend accepts any TypeScript 7 release. Before, a newer tsrs made fallow use only syntactic analysis. fallow type-aware status shows the resolved version. Guarded fixes still need typescript@7.0.2. Thanks @Smrtnyk for the report. (#3998, #4005)

  • An import such as country-flag-icons or ./ThemeToggle no longer confirms a flag file. One path segment must now name a flag vendor or flags, for example @/lib/flags or ./featureFlags. In a file without a flag import, a call to a project function with a generic SDK name, such as a local isEnabled, is no longer a flag. (#3982)

  • Mutation testing instruments temporary Node source copies. A byte-identical copy of one planned source loads the instrumented code of that source. A copy that matches more than one planned source makes the run incomplete. (#3950, #3994)

  • Type-aware symbol impact follows compiler-resolved imports and re-exports. For an explicit .js import of a TypeScript source, the impact report now lists the transitive affected files, the targeted tests and the shortest provenance paths. (#4009)

  • CLI JSON errors tell you how to recover. Invalid arguments, invalid roots and a missing fix confirmation give a stable code and a help field with the next step. Skipped fixes also give help, and an invalid --lean combination gives a JSON error. Exit statuses do not change. (#4010)

  • Agent gates work without jq. Generated gates use a native fallow JSON reader when they find one. Older installations keep the jq fallback. A large blocking report keeps the blocking exit code when fallow cuts the displayed findings. fallow agent status lists the reader launchers without running project code. The fallow skill now runs agent onboarding through fallow agent install. (#4011)

  • Inventory uploads omit churn from a shallow Git history. This applies to fresh and cached uploads. (#4008)

  • Cloud analysis treats managed partial captures as positive execution evidence. Human and Markdown reports then omit the application coverage percentage and the cold-code conclusions. (#4008)

  • The fallow skill documents the audit styling fields and the file-length flag. styling_findings, css_analytics and styling_health are in the complexity block of the fallow audit JSON. The fallow health flags now list --max-file-lines. (#3984, #3988)

Upgrade notes

  • The VS Code extension 3.38.0 is not on the Visual Studio Marketplace or Open VSX. Install it from the fallow-vscode-*.vsix file for your platform on this release page, or wait for the next release, which publishes it to both marketplaces.

  • The mutation and mutation-inspect JSON output uses schema version "2". Update any script that checks the schema version. --resume refuses a journal from an older release. Fallow runs each cached mutant again one time. (#3997)

  • Run fallow similar-code setup --local one time after the update. The embedding semantics version changes from v1 to v2, so every vector cache clears one time. Setup reuses the verified model files and downloads nothing. (#3995)

  • Some inventory functions get a new name and a new stable id. The stable id changes because the name is one of its inputs. (#3965)

  • fallow coverage analyze gives review_required to one more function shape. A never-called function with its own name that starts on the line after its export now gets review_required, not safe_to_delete. (#3965)

  • The first fallow audit and fallow flags runs after the update take longer. The audit computes a new base snapshot, and fallow flags parses all files again.

Full Changelog: v3.37.0...v3.38.0