fallow 2.93.0 → 2.95.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.
@@ -0,0 +1,21 @@
1
+ # Node.js Bindings
2
+
3
+ When embedding fallow inside a Node.js process (editor extensions, long-running servers, custom tooling), prefer the NAPI bindings over spawning the CLI. Same analysis engine, same JSON envelopes, no subprocess or JSON parsing overhead.
4
+
5
+ ```bash
6
+ npm install @fallow-cli/fallow-node
7
+ ```
8
+
9
+ ```ts
10
+ import { detectDeadCode, detectDuplication, computeHealth } from '@fallow-cli/fallow-node';
11
+
12
+ const deadCode = await detectDeadCode({ root: process.cwd(), explain: true });
13
+ const dupes = await detectDuplication({ root: process.cwd(), mode: 'mild', minTokens: 30 });
14
+ const health = await computeHealth({ root: process.cwd(), score: true, ownershipEmails: 'handle' });
15
+ ```
16
+
17
+ Six async functions: `detectDeadCode`, `detectCircularDependencies`, `detectBoundaryViolations`, `detectDuplication`, `computeComplexity`, `computeHealth`. Each returns the same JSON envelope the CLI emits for `--format json`. Rejected promises throw a `FallowNodeError` with `message`, `exitCode`, and optional `code`, `help`, `context` fields that mirror the CLI's structured error surface.
18
+
19
+ Enum-like fields take lowercase CLI-style literals (`"mild"`, `"cyclomatic"`, `"handle"`, `"low"`). Write-path commands (`fix`, `init`, `hooks install`, `hooks uninstall`, `license activate`, `coverage setup`) are not exposed; use the CLI for those.
20
+
21
+ See <https://docs.fallow.tools/integrations/node-bindings> for the full field reference.
@@ -723,7 +723,7 @@ Use this when Claude Code is allowed to run Git commands in a repository that al
723
723
  The pattern is a local agent gate, not a Git hook. Claude Code intercepts its own `Bash` tool calls before execution. When Claude tries `git commit` or `git push`, the hook runs:
724
724
 
725
725
  ```bash
726
- fallow audit --format json --quiet --explain
726
+ fallow audit --format json --quiet --explain --gate-marker agent
727
727
  ```
728
728
 
729
729
  Behavior:
@@ -777,14 +777,14 @@ Prefer `fallow hooks install --target agent` to install this file. The script is
777
777
  Behavior you can rely on:
778
778
  - Runs only when the intercepted command matches `git commit` or `git push`; otherwise exits 0.
779
779
  - Resolves `fallow` from PATH first, then `npx --no-install fallow` as a fallback. Skips with a stderr notice if neither is available or if `jq` is missing.
780
- - Enforces a version floor via `FALLOW_GATE_MIN_VERSION` (default `2.46.0`). Binaries below the floor are blocked with an upgrade hint. Set the env var to the empty string to disable the check.
781
- - Runs `fallow audit --format json --quiet --explain` and, on verdict=`fail`, writes the full JSON envelope to stderr preceded by `fallow-gate: blocked by fallow <version> at <binary>` so the responsible binary is always identifiable.
780
+ - Enforces a version floor via `FALLOW_GATE_MIN_VERSION` (default `2.85.0`). Binaries below the floor are blocked with an upgrade hint. Set the env var to the empty string to disable the check.
781
+ - Runs `fallow audit --format json --quiet --explain --gate-marker agent` and, on verdict=`fail`, writes the full JSON envelope to stderr preceded by `fallow-gate: blocked by fallow <version> at <binary>` so the responsible binary is always identifiable. The gate marker lets local Impact record blocked-then-cleared agent gate events when Impact is enabled.
782
782
  - On runtime error (`{"error": true, ...}`) or unexpected non-zero exit, fails open with a one-line stderr notice; warn verdicts pass through silently.
783
783
 
784
784
  Codex fallback (add to repo root `AGENTS.md`):
785
785
 
786
786
  ```md
787
- Before any `git commit` or `git push`, run `fallow audit --format json --quiet --explain`. If the verdict is `fail`, fix the reported findings before retrying. Treat JSON runtime errors like `{ "error": true, ... }` as non-blocking.
787
+ Before any `git commit` or `git push`, run `fallow audit --format json --quiet --explain --gate-marker agent`. If the verdict is `fail`, fix the reported findings before retrying. Treat JSON runtime errors like `{ "error": true, ... }` as non-blocking.
788
788
  ```
789
789
 
790
790
  Keep `fallow audit` in CI alongside this local gate. The hook only runs for Claude Code, not for human pushes or other agents, so it is a reinforcement layer rather than a replacement for server-side enforcement.
@@ -390,6 +390,10 @@ export type ComplexityMetric = ("cyclomatic" | "cognitive")
390
390
  * to cyclomatic complexity and so produces no contribution.
391
391
  */
392
392
  export type ComplexityContributionKind = ("if" | "else" | "else-if" | "ternary" | "logical-and" | "logical-or" | "nullish-coalescing" | "logical-assignment" | "optional-chain" | "for" | "for-in" | "for-of" | "while" | "do-while" | "switch" | "case" | "catch" | "labeled-break" | "labeled-continue")
393
+ /**
394
+ * Source for a finding's effective thresholds.
395
+ */
396
+ export type ThresholdSource = "override"
393
397
  /**
394
398
  * Discriminant for [`HealthFindingAction::kind`]. Mirrors the action types
395
399
  * emitted by `build_health_finding_actions`. A single finding's `actions`
@@ -407,6 +411,10 @@ export type CoverageModel = ("static_binary" | "static_estimated" | "istanbul")
407
411
  * Whether CRAP findings in the report used one coverage-source kind or a mix.
408
412
  */
409
413
  export type CoverageSourceConsistency = ("uniform" | "mixed")
414
+ /**
415
+ * Lifecycle state for a configured threshold override.
416
+ */
417
+ export type ThresholdOverrideStatus = ("active" | "stale" | "no_match")
410
418
  /**
411
419
  * Discriminant for [`UntestedFileAction::kind`]. Mirrors the action types
412
420
  * emitted by `build_untested_file_actions`.
@@ -2080,8 +2088,8 @@ introduced?: (AuditIntroduced | null)
2080
2088
  }
2081
2089
  /**
2082
2090
  * Wire-shape envelope for a [`PolicyViolation`] finding. Carries actions for
2083
- * replacing the banned call or import, or suppressing it with the
2084
- * `policy-violation` token.
2091
+ * replacing the banned call or import, or suppressing it with a scoped
2092
+ * `policy-violation:<pack>/<rule-id>` token.
2085
2093
  */
2086
2094
  export interface PolicyViolationFinding {
2087
2095
  /**
@@ -2816,6 +2824,11 @@ export interface HealthReport {
2816
2824
  */
2817
2825
  findings: HealthFinding[]
2818
2826
  summary: HealthSummary
2827
+ /**
2828
+ * Configured threshold override states. Entries are emitted for active
2829
+ * exceptions, stale exceptions, and full-run no-match cleanup hints.
2830
+ */
2831
+ threshold_overrides?: ThresholdOverrideState[]
2819
2832
  /**
2820
2833
  * Project-wide vital signs (always computed from available data).
2821
2834
  */
@@ -2915,6 +2928,15 @@ component_rollup?: (ComponentRollup | null)
2915
2928
  * otherwise so default and CI output stay lean.
2916
2929
  */
2917
2930
  contributions?: ComplexityContribution[]
2931
+ /**
2932
+ * Resolved thresholds used for this finding when a config override changed
2933
+ * at least one ceiling. Omitted for findings using global thresholds.
2934
+ */
2935
+ effective_thresholds?: (HealthEffectiveThresholds | null)
2936
+ /**
2937
+ * Source of the effective thresholds. Omitted when thresholds are global.
2938
+ */
2939
+ threshold_source?: (ThresholdSource | null)
2918
2940
  /**
2919
2941
  * Machine-actionable fix and suppress hints.
2920
2942
  */
@@ -2964,6 +2986,14 @@ weight: number
2964
2986
  */
2965
2987
  nesting: number
2966
2988
  }
2989
+ /**
2990
+ * Resolved thresholds used to evaluate a health finding.
2991
+ */
2992
+ export interface HealthEffectiveThresholds {
2993
+ max_cyclomatic: number
2994
+ max_cognitive: number
2995
+ max_crap: number
2996
+ }
2967
2997
  /**
2968
2998
  * Suggested action attached to a [`ComplexityViolation`].
2969
2999
  *
@@ -3046,6 +3076,36 @@ severity_critical_count: number
3046
3076
  severity_high_count: number
3047
3077
  severity_moderate_count: number
3048
3078
  }
3079
+ /**
3080
+ * Report entry describing whether a threshold override is active, stale, or
3081
+ * no longer matching any analyzed file or function.
3082
+ */
3083
+ export interface ThresholdOverrideState {
3084
+ status: ThresholdOverrideStatus
3085
+ override_index: number
3086
+ path?: (string | null)
3087
+ function?: (string | null)
3088
+ configured_thresholds: HealthConfiguredThresholds
3089
+ effective_thresholds: HealthEffectiveThresholds
3090
+ metrics?: (ThresholdOverrideMetrics | null)
3091
+ reason?: (string | null)
3092
+ }
3093
+ /**
3094
+ * Threshold values configured by a single override entry.
3095
+ */
3096
+ export interface HealthConfiguredThresholds {
3097
+ max_cyclomatic?: (number | null)
3098
+ max_cognitive?: (number | null)
3099
+ max_crap?: (number | null)
3100
+ }
3101
+ /**
3102
+ * Current complexity metrics for a matched threshold override entry.
3103
+ */
3104
+ export interface ThresholdOverrideMetrics {
3105
+ cyclomatic: number
3106
+ cognitive: number
3107
+ crap?: (number | null)
3108
+ }
3049
3109
  /**
3050
3110
  * Project-wide vital signs , a fixed set of metrics for trend tracking.
3051
3111
  *
@@ -4609,6 +4669,11 @@ elapsed_ms: ElapsedMs
4609
4669
  */
4610
4670
  findings: HealthFinding[]
4611
4671
  summary: HealthSummary
4672
+ /**
4673
+ * Configured threshold override states. Entries are emitted for active
4674
+ * exceptions, stale exceptions, and full-run no-match cleanup hints.
4675
+ */
4676
+ threshold_overrides?: ThresholdOverrideState[]
4612
4677
  /**
4613
4678
  * Project-wide vital signs (always computed from available data).
4614
4679
  */
@@ -5205,6 +5270,18 @@ recent_resolved: ResolutionEvent[]
5205
5270
  * "resolution tracking starts from your next run" instead of a bare zero.
5206
5271
  */
5207
5272
  attribution_active: boolean
5273
+ /**
5274
+ * Whether the local agent onboarding prompt has been explicitly declined.
5275
+ * Stored under `.fallow/` so agents can avoid cross-session nags.
5276
+ */
5277
+ onboarding_declined: boolean
5278
+ /**
5279
+ * Whether the user ever made an explicit enable/disable decision for
5280
+ * Impact tracking. `enabled: false` with `explicit_decision: false` means
5281
+ * "never asked"; with `true` it means "asked and declined". Agents use
5282
+ * this to offer the impact opt-in exactly once per project.
5283
+ */
5284
+ explicit_decision: boolean
5208
5285
  }
5209
5286
  /**
5210
5287
  * Per-category issue counts captured at a recorded run.