fallow-rs/Fallow - Codebase Intelligence

Deterministic codebase intelligence for TypeScript/JavaScript in CI: quality, PR risk, hotspots, duplication, architecture.

View on GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Activelast commit Jul 10, 2026
License
MIT

Pinned Snippet

workflow.ymlSHA-pinned
uses: fallow-rs/fallow@c9326d9395c0b46f4077290473060b3e950b6e8c # v3.3.0

tags can be moved; commit SHAs can't. why a SHA?

namedescriptionrequireddefault
commandCommand to run: dead-code (unused code), dupes (code duplication), health (complexity), audit (changed-file quality gate), security (security candidates), fix (auto-remove unused code). Default runs all analyses. Legacy alias: check = dead-code.no""
rootProject root directoryno.
configPath to config file (.fallowrc.json, .fallowrc.jsonc, fallow.toml, or .fallow.toml)no
formatOutput format (human, json, sarif, compact, markdown, codeclimate, pr-comment-github, pr-comment-gitlab, review-github, review-gitlab, badge)nosarif
sarifUpload SARIF to GitHub Code Scanning. Available on public repos (free) and private or internal repos with GitHub Advanced Security. Requires permissions: security-events: write.nofalse
productionProduction mode: exclude test/dev files, only analyze start/build scriptsnofalse
production-dead-codeCombined mode only: run dead-code analysis in production modenofalse
production-healthCombined mode only: run health analysis in production modenofalse
production-dupesCombined mode only: run duplication analysis in production modenofalse
fail-on-issuesExit with code 1 if issues are foundnotrue
changed-sinceOnly report issues in files changed since this git ref (requires fetch-depth: 0)no
auto-changed-sinceAutomatically scope analysis to changed files in PR context using the base SHA (requires fetch-depth: 0). Ignored when changed-since is explicitly set.notrue
baselinePath to baseline file for comparisonno
save-baselineSave current results as a baseline fileno
versionFallow version override. When omitted, the action uses the project package.json fallow dependency spec if present, otherwise latest. Pin a current fallow version so Ed25519 + SHA-256 binary verification can run.no""
argsAdditional arguments to pass to fallow (space-separated)no""
artifacts-dirDirectory for generated action artifacts such as fallow-results.json, fallow-results.sarif, fallow-stderr.log, and fallow-analysis-args.sh. Relative to the workflow workspace.no.
commentPost results as a PR comment and Fallow Check Run (requires pull-requests: write for the comment and checks: write for the check)nofalse
github-tokenGitHub token for PR comments and SARIF uploadno${{ github.token }}
branded-tokenPost PR comments and reviews as the Fallow app (branded) when the workflow grants `permissions: id-token: write`. Set to false to always post with github-token. Falls back to github-token automatically when id-token is unavailable.notrue
broker-urlBase URL of the Fallow token broker used to mint the branded app token. Defaults to Fallow Cloud.nohttps://api.fallow.cloud
annotationsEmit findings as inline PR annotations via workflow commands (no Advanced Security required). On fallow >= 3.4.2 the action renders these natively via `fallow report --format github-annotations`; older binaries fall back to the bundled jq renderers, and version: latest users flip to the native path silently. The step log line "fallow: annotations rendered via native github-annotations" (or "via jq fallback") tells you which renderer ran.notrue
review-commentsPost findings as inline PR review comments with rich markdown formatting (code blocks, tables, links, suggestions). Creates a single review per run. Automatically disables plain-text annotations when enabled.nofalse
review-guidanceAppend collapsed "What to do" guidance blocks to inline review comments. Requires review-comments: true.nofalse
max-annotationsMaximum number of inline annotations to emit (default: 50). On the native path the action applies this cap to the rendered stream (GitHub itself displays at most 10 annotations per type per step).no50
max-commentsMaximum number of inline review comments + items in the sticky details table (default: 50). Mirrors max-annotations for the typed pr-comment / review formats.no50
comment-layoutSticky PR comment layout: default, compact, gate-only, or details. Use gate-only when a native Check Run is the primary PR surface.nodefault
comment-idSticky-comment marker id, embedded in the HTML comment that identifies fallow's comment for upsert. Defaults to 'fallow-results', auto-suffixed with the workspace name when running scoped to a single workspace package.no""
summary-scopeSticky PR summary comment scope: 'all' (default, include project-level dependency/catalog/override findings even when their anchor line is outside the diff) or 'diff' (apply the diff filter to those findings too). Does not affect inline review comments. If the diff file is unavailable, fallow reports all findings.noall
diff-filterDiff-aware finding filter: 'added' (default, only findings on PR-added lines), 'diff_context' (added lines plus surrounding context), 'file' (any file touched by the PR), 'nofilter' (every finding).noadded
diff-filePath to a unified-diff file. When set (directly OR derived by the analyze step from `gh pr diff` / `git diff --unified=0`), fallow narrows source-anchored findings to lines inside an added hunk; project-level findings (unused deps, catalog entries, dependency overrides) bypass the analysis filter. Sticky summary comments can opt into filtering project-level findings too with `summary-scope: diff`; inline review comments stay line-scoped. Also drives line-level scoping of the runtime-coverage `hot-path-touched` verdict. When both `diff-file` and `changed-since` are set, the diff filter wins for line-level filtering and `changed-since` still scopes file discovery; fallow logs a one-line stderr note. The analyze step propagates the resolved path via $GITHUB_ENV so the comment / review steps reuse the same file.no""
api-retriesMaximum HTTP retry attempts for fallow ci reconcile-review and the bash gh-api wrappers. Defaults to 3.no3
api-retry-delayFloor delay in seconds between rate-limited retries. Server-supplied Retry-After overrides this when present. Defaults to 2.no2
dupes-modeDetection mode for dupes command (strict, mild, weak, semantic)nomild
min-tokensMinimum token count for a clone (dupes command)no
min-linesMinimum line count for a clone (dupes command)no
thresholdFail if duplication exceeds this percentage (dupes command, 0 = no limit)no
skip-localOnly report cross-directory duplicates (dupes command)nofalse
cross-languageStrip TypeScript type annotations for TS<->JS clone matching (dupes command)nofalse
ignore-importsExclude import declarations from clone detection (dupes command)nofalse
workspaceScope output to one or more workspaces. Supports exact package names, globs matched against name and workspace path (apps/*, @scope/*), and !-prefixed negations. Comma-separated values ('web,admin') or a single pattern.no
changed-workspacesGit-derived monorepo scoping: scope output to workspaces containing any file changed since REF (e.g., 'origin/main'). Auto-derives the workspace set from git diff so CI jobs don't maintain a hand-written list. Requires git history (fetch-depth: 0). Mutually exclusive with 'workspace'. A missing ref or non-git directory is a hard error (exit 2) rather than silent full-scope fallback.no
max-cyclomaticMaximum cyclomatic complexity threshold (health command, default: 20)no
max-cognitiveMaximum cognitive complexity threshold (health command, default: 15)no
max-crapMaximum CRAP score threshold (health and audit commands, default: 30.0). Functions meeting or exceeding this score are reported alongside complexity findings. Pair with coverage data for accurate per-function scoring.no
coveragePath to Istanbul coverage-final.json data for accurate CRAP scoring (health, audit, and bare command).no
runtime-coveragePath to paid runtime coverage input for the health command: a V8 coverage directory, V8 JSON file, or Istanbul coverage-final.jsonno
coverage-rootRebase Istanbul file paths before matching coverage or runtime coverage input (health and audit commands)no
min-invocations-hotHot-path threshold for runtime coverage findings (health command, default: 100)no
min-observation-volumeMinimum observation volume required for high-confidence runtime coverage verdicts (health command)no
low-traffic-thresholdFraction of total trace volume below which an invoked function is classified as low_traffic instead of active (health command)no
topShow only the N worst offenders (health and dupes commands)no
sortSort order for health results: cyclomatic (default), cognitive, lines, or severity (health command)no
file-scoresCompute per-file maintainability index (health command)nofalse
hotspotsIdentify files that are both complex and frequently changing (health command)nofalse
targetsShow ranked refactoring recommendations (health command)nofalse
complexityShow only complexity findings section (health command)nofalse
sinceGit history window for hotspot analysis: durations (6m, 90d, 1y) or ISO dates (health command)no
min-commitsMinimum commits for a file to appear in hotspot ranking (health command, default: 3)no
scoreCompute health score (0-100 with letter grade). Enables the health delta header in PR comments. Works with health and bare command (all analyses).nofalse
min-severityOnly fail for findings at or above this severity (moderate, high, critical). Use "critical" to only fail on critical complexity findings.no
save-snapshotSave vital signs snapshot to .fallow/snapshots/ for trend tracking. Use actions/cache to persist across runs. Provide a path or leave empty for default. Works with health and bare command.no
trendCompare current metrics against the most recent saved snapshot and show per-metric deltas. Requires a previous snapshot from save-snapshot. Works with health and bare command.no
issue-typesComma-separated issue types to report (dead-code command). Valid: unused-files, unused-exports, unused-types, unused-deps, unused-enum-members, unused-class-members, unresolved-imports, unlisted-deps, duplicate-exports, circular-depsno
include-entry-exportsReport unused exports in entry files instead of auto-marking them as used. Catches framework export typos. Applied to dead-code analysis; also configurable persistently via includeEntryExports in your fallow config.nofalse
gateAudit verdict gate: new-only (default) fails only introduced findings, all fails on every finding in changed files.no
security-gateSecurity regression gate: new fails on candidates introduced on changed lines, newly-reachable fails on existing candidates that became reachable from entry points.no
dead-code-baselinePath to a dead-code baseline for the audit command.no
health-baselinePath to a health baseline for the audit command.no
dupes-baselinePath to a duplication baseline for the audit command.no
fail-on-regressionExit with code 1 if issue counts regressed compared to baseline (dead-code command)nofalse
toleranceAllowed regression tolerance before failing (e.g. "2%" or "5") (dead-code command)no0
regression-baselinePath to regression baseline file for comparison (dead-code command)no
save-regression-baselineSave current results as a regression baseline file (dead-code command)no
dry-runPreview changes without modifying files (fix command, default: true for CI safety)notrue
no-cacheDisable incremental parse cache (force full re-parse of all files)nofalse
threadsNumber of parser threads (default: available CPU cores)no
onlyRun only these analyses when no command is specified (comma-separated: dead-code,dupes,health)no
skipSkip these analyses when no command is specified (comma-separated: dead-code,dupes,health)no
namedescription
resultsPath to JSON results file
sarifPath to SARIF results file
issuesNumber of issues (dead-code), clone groups (dupes), security candidates (security), introduced findings counted by the audit verdict (audit), or fixes proposed/applied (fix). Audit count is gate-aware: with `gate: new-only` (default) it sums attribution.*_introduced; with `gate: all` it sums summary.* totals. Security count is gate-aware when `security-gate` is set. For audit, prefer `outputs.verdict` for severity-aware gating.
verdictAudit verdict (pass/warn/fail). Empty when command is not audit. The threshold step gates on this for audit so warn-tier findings do not fail CI.
gateAudit gate (new-only/all) or security gate (new/newly-reachable) that was applied. Empty when no gate ran.
changed-files-unavailabletrue when the analyze step could not enumerate PR-changed files (transient GitHub API failure, expired token, missing permissions); false on the happy path. Always emitted, regardless of whether changed-since was requested. Gate on this in downstream workflow steps to detect when analysis ran unscoped vs scoped.
post-skipped-reasonReason the Post review comments step skipped posting (pagination_failure / none). Set to pagination_failure only when the inline-review POST was actually aborted to avoid duplicate threads (multi-comment dedup lookup failed). Empty when the Post review comments step did not run.
dedup-lookup-failedtrue when a dedup lookup failed on the Post PR comment or Post review comments step. Distinct from post-skipped-reason: the summary-only paths post a fresh comment anyway (potential duplicate) when their lookup fails, while the multi-comment review path aborts. Gate on this to detect either degraded state. Resolves to "true" if EITHER step reported a failure, "false" otherwise.