fallow 2.103.0 → 3.0.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.
@@ -2,7 +2,7 @@
2
2
  * AUTOGENERATED FILE. DO NOT EDIT.
3
3
  *
4
4
  * Generated from `docs/output-schema.json` by
5
- * `editors/vscode/scripts/codegen-types.mjs`. The same file is written to
5
+ * `editors/vscode/scripts/codegen-contracts.mjs`. The same file is written to
6
6
  * `editors/vscode/src/generated/output-contract.d.ts` (extension internal) and
7
7
  * `npm/fallow/types/output-contract.d.ts` (published as `fallow/types`).
8
8
  *
@@ -10,22 +10,21 @@
10
10
  * 1. Edit the Rust struct in `crates/types/src/results.rs` (or the
11
11
  * duplicates crate at `crates/core/src/duplicates/types.rs`). The Rust
12
12
  * side is the runtime source of truth for the JSON output.
13
- * 2. Update `docs/output-schema.json` to match. The schema is
14
- * hand-maintained against the Rust structs; the drift-guard test in
15
- * `crates/cli/src/report/json.rs` enforces only a subset of the
16
- * contract (the `HealthFindingAction` enum). Field-level drift between
17
- * Rust and the schema is currently caught by code review.
18
- * 3. Run `pnpm --filter fallow-vscode codegen:types` from anywhere.
19
- * 4. Commit both regenerated files alongside the schema edit.
13
+ * 2. Regenerate `docs/output-schema.json` with
14
+ * `cargo run -p fallow-cli --features schema-emit --bin fallow-schema-emit`.
15
+ * The schema-emit drift tests compare the committed schema against the
16
+ * Rust-derived definitions.
17
+ * 3. Run `pnpm --filter fallow-vscode codegen:contracts` from anywhere.
18
+ * 4. Commit the regenerated schema and generated contract files together.
20
19
  *
21
- * CI runs `pnpm --filter fallow-vscode check:codegen` which fails when
20
+ * CI runs `pnpm --filter fallow-vscode check:contracts` which fails when
22
21
  * either committed file disagrees with what regen would produce.
23
22
  */
24
23
  /* eslint-disable */
25
24
 
26
25
 
27
26
  /**
28
- * Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator (for example `dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, `explain`, `inspect_target`, `impact`, `security`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `review-envelope`, and `review-reconcile`). Consumers should branch on `kind` instead of probing for unique field presence. `--legacy-envelope` removes only the document-root `kind` for one compatibility cycle. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array.
27
+ * Schemas for the JSON output of fallow commands. Object-shaped envelopes covered by the `FallowOutput` contract carry a top-level `kind` discriminator (for example `dead-code`, `dead-code-grouped`, `health`, `dupes`, `combined`, `audit`, `explain`, `inspect_target`, `impact`, `security`, `coverage-setup`, `coverage-analyze`, `list-boundaries`, `review-envelope`, and `review-reconcile`). Consumers should branch on `kind` instead of probing for unique field presence. `CodeClimateOutput` is a bare JSON array (per the Code Climate / GitLab Code Quality spec) and stays a sibling root branch discriminated by checking whether the document root is an array.
29
28
  */
30
29
  export type FallowJsonOutput = (FallowOutput | CodeClimateOutput)
31
30
  /**
@@ -34,11 +33,9 @@ export type FallowJsonOutput = (FallowOutput | CodeClimateOutput)
34
33
  * schema derived from this enum drives the document-root `oneOf` in
35
34
  * `docs/output-schema.json`.
36
35
  *
37
- * The default wire shape now carries a top-level `kind` discriminator so
38
- * agents and schema-validating clients can select the variant in O(1) instead
39
- * of probing for unique field presence. `--legacy-envelope` is a one-cycle
40
- * compatibility flag that removes only this document-root `kind` field from
41
- * CLI JSON output; nested report objects are not rewritten.
36
+ * The wire shape carries a top-level `kind` discriminator so agents and
37
+ * schema-validating clients can select the variant in O(1) instead of probing
38
+ * for unique field presence.
42
39
  *
43
40
  * One envelope is intentionally NOT in this enum:
44
41
  * - `CodeClimateOutput` serializes as a bare JSON array
@@ -254,7 +251,7 @@ export type ReExportCycleKind = ("multi-node" | "self-loop")
254
251
  /**
255
252
  * Which rule-pack rule kind produced a [`PolicyViolation`].
256
253
  */
257
- export type PolicyRuleKind = ("banned-call" | "banned-import" | "banned-effect")
254
+ export type PolicyRuleKind = ("banned-call" | "banned-import" | "banned-effect" | "banned-export")
258
255
  /**
259
256
  * Effective severity of a single [`PolicyViolation`]. Per-rule `severity`
260
257
  * overrides the `rules."policy-violation"` master; `off` rules emit nothing,
@@ -596,11 +593,41 @@ export type FrameworkHealthDetectorStatus = ("active" | "disabled_by_config" | "
596
593
  /**
597
594
  * Discriminant for [`CssCandidateAction::kind`].
598
595
  */
599
- export type CssCandidateActionType = ("verify-unused" | "verify-undefined" | "consolidate" | "replace-with-token" | "standardize")
596
+ export type CssCandidateActionType = ("verify-unused" | "verify-undefined" | "consolidate" | "replace-with-token" | "standardize" | "simplify-selector")
600
597
  /**
601
598
  * Discriminant for [`UnusedAtRule::kind`].
602
599
  */
603
600
  export type UnusedAtRuleKind = ("property-registration" | "layer")
601
+ /**
602
+ * The surface through which a design token is consumed. The `theme-var` /
603
+ * `css-var` / `utility` / `apply` kinds are Tailwind v4 `@theme` consumption; the
604
+ * `js-member` / `js-call` kinds are CSS-in-JS consumption (member access on an
605
+ * imported StyleX/vanilla-extract token binding, or a PandaCSS `token('...')`
606
+ * call). The kind is the disjoint origin signal that distinguishes a Tailwind
607
+ * token entry from a CSS-in-JS token entry in the shared `token_consumers` list.
608
+ */
609
+ export type ConsumerKind = ("theme-var" | "css-var" | "utility" | "apply" | "js-member" | "js-call")
610
+ /**
611
+ * Trust level for a [`StylingHealth`] grade. TWO variants (not the three-tier
612
+ * `high`/`medium`/`low` of [`crate::Confidence`] / `FeatureFlagConfidence`) ON
613
+ * PURPOSE: styling confidence is binary (the grade is either reliable for the
614
+ * analyzed surface or it is not), not three distinct evidence tiers, so a
615
+ * never-emitted `Medium` would be dead surface. Serializes lowercase (`"high"` /
616
+ * `"low"`), matching the sibling confidence enums' vocabulary.
617
+ */
618
+ export type StylingHealthConfidence = ("high" | "low")
619
+ /**
620
+ * Effective configured severity for a styling finding.
621
+ */
622
+ export type StylingFindingSeverity = ("warn" | "error")
623
+ /**
624
+ * Confidence hint for a [`StylingFinding`].
625
+ */
626
+ export type StylingFindingConfidence = ("high" | "low")
627
+ /**
628
+ * Agent handling hint for a [`StylingFinding`].
629
+ */
630
+ export type StylingAgentDisposition = ("fix-confidently" | "verify-first")
604
631
  export type InspectTargetDescriptor = ({
605
632
  file: string
606
633
  type: "file"
@@ -788,12 +815,14 @@ export type RiskClass = ("low" | "medium" | "high")
788
815
  */
789
816
  export type ReviewEffort = ("glance" | "review" | "deep_dive")
790
817
  /**
791
- * The focus label for a review unit. EXACTLY two variants: `Skip` is NOT
792
- * representable, so the type system is the guarantee that free mode never emits
793
- * a `skip` label (safe explicit-skip is paid, runtime-backed only). Mirrors
794
- * the decision surface's "cut category not representable" structural posture.
818
+ * The focus label for a review unit. `Skip` is the SAFE explicit-skip label and
819
+ * is runtime-backed ONLY: it is producible solely on the paid runtime path
820
+ * and solely for a unit runtime-proves cold with zero risk signals. Free mode
821
+ * (no runtime evidence) emits only `ReviewHere` / `NotPrioritized`, never `Skip`
822
+ * (the build-focus-map labeller cannot reach the `Skip` arm without runtime
823
+ * input), so the free-tier "rank but never skip" stance holds by construction.
795
824
  */
796
- export type FocusLabel = ("review-here" | "not-prioritized")
825
+ export type FocusLabel = ("review-here" | "not-prioritized" | "skip")
797
826
  /**
798
827
  * A per-unit confidence flag. The EXACT panel-decided strings: a dynamically-
799
828
  * wired or re-export-heavy unit carries one so its static-reachability signal is
@@ -2488,7 +2517,8 @@ kind: PolicyRuleKind
2488
2517
  /**
2489
2518
  * What matched: the written callee path for `banned-call` (e.g.
2490
2519
  * `cp.exec`), the raw import specifier for `banned-import` (e.g.
2491
- * `moment/locale/nl`), or `<effect>: <callee>` for `banned-effect`.
2520
+ * `moment/locale/nl`), `<effect>: <callee>` for `banned-effect`, or the
2521
+ * exported name for `banned-export`.
2492
2522
  */
2493
2523
  matched: string
2494
2524
  severity: PolicyViolationSeverity
@@ -4017,6 +4047,23 @@ framework_health?: (FrameworkHealthDiagnostics | null)
4017
4047
  * over-complex selectors, deep nesting). Present only with `--css`.
4018
4048
  */
4019
4049
  css_analytics?: (CssAnalyticsReport | null)
4050
+ /**
4051
+ * Styling-health score and letter grade: a SECOND health axis derived from
4052
+ * the CSS analytics (the design-system axis), orthogonal to the JS/TS code
4053
+ * `health_score`. Present only with `--css` (the same condition as
4054
+ * `css_analytics`), so a plain `fallow health` run is byte-unchanged. The
4055
+ * code score is never affected by this field.
4056
+ */
4057
+ styling_health?: (StylingHealth | null)
4058
+ /**
4059
+ * Advisory STYLING FINDINGS: the graduation of the descriptive css
4060
+ * candidates into first-class, severity-aware, suppressible findings
4061
+ * surfaced in `fallow audit`. Verdict-neutral by default (the rule defaults
4062
+ * to `warn`); the styling domain's OWN findings collection, not the dead-code
4063
+ * `AnalysisResults`. Present only with `--css`; empty is skipped so a plain
4064
+ * run is byte-unchanged.
4065
+ */
4066
+ styling_findings?: StylingFinding[]
4020
4067
  }
4021
4068
  /**
4022
4069
  * Wire envelope for a single complexity finding.
@@ -5826,6 +5873,19 @@ undefined_keyframes?: UndefinedKeyframes[]
5826
5873
  * descending.
5827
5874
  */
5828
5875
  duplicate_declaration_blocks?: CssDuplicateBlock[]
5876
+ /**
5877
+ * CVA / shadcn variant class strings that repeat the same normalized class
5878
+ * block in several variant values. Kept separate from CSS declaration-block
5879
+ * duplication because the source is JS config, not parsed CSS rules.
5880
+ */
5881
+ cva_duplicate_variant_blocks?: CvaDuplicateVariantBlock[]
5882
+ /**
5883
+ * CVA / shadcn variant class strings that hardcode a Tailwind arbitrary
5884
+ * value even though an existing token has the same or nearest comparable
5885
+ * value. Advisory: variants often encode product semantics, so agents
5886
+ * should verify intent before replacing.
5887
+ */
5888
+ cva_variant_token_drifts?: CvaVariantTokenDrift[]
5829
5889
  /**
5830
5890
  * Tailwind arbitrary-value utilities (`w-[13px]`, `bg-[#abc]`) found in
5831
5891
  * markup, which hardcode a one-off value instead of a configured scale
@@ -5834,6 +5894,13 @@ duplicate_declaration_blocks?: CssDuplicateBlock[]
5834
5894
  * value is sometimes the right call.
5835
5895
  */
5836
5896
  tailwind_arbitrary_values?: TailwindArbitraryValue[]
5897
+ /**
5898
+ * Located raw CSS declaration values that bypass token surfaces (`var()`,
5899
+ * `token()`, `theme()`) on scale-sensitive axes such as color, font-size,
5900
+ * line-height, radius, and shadow. Conservative candidates: a raw value can
5901
+ * be intentional, but introduced raw values are useful audit feedback.
5902
+ */
5903
+ raw_style_values?: RawStyleValue[]
5837
5904
  /**
5838
5905
  * Unused CSS at-rule entities: an `@property` registered but never read via
5839
5906
  * `var()` in any stylesheet, or an `@layer` declared but never populated by
@@ -5882,6 +5949,24 @@ unused_font_faces?: UnusedFontFace[]
5882
5949
  * downstream repo. Sorted by `(path, line, token)`.
5883
5950
  */
5884
5951
  unused_theme_tokens?: UnusedThemeToken[]
5952
+ /**
5953
+ * Tailwind v4 theme tokens whose comparable values are close to another
5954
+ * token in the same theme dictionary. These are opt-in `--css-deep`
5955
+ * candidates because they need whole-project token context.
5956
+ */
5957
+ near_duplicate_theme_tokens?: NearDuplicateThemeToken[]
5958
+ /**
5959
+ * A location-aware reverse index of Tailwind v4 `@theme` token consumers:
5960
+ * per token, where it is consumed (`var()` reads, `@apply` bodies, generated
5961
+ * utility classes) and through which surface, plus the full `consumer_count`
5962
+ * (a static lower bound) and the defining site. Built from the same gated
5963
+ * candidate set as `unused_theme_tokens` (v4 + non-plugin + non-published +
5964
+ * whole-scope), so a token with `consumer_count: 0` is the same "nothing
5965
+ * consumes this" signal. Sorted by token; empty when the project is not
5966
+ * Tailwind v4 or a plugin / published-library / partial-scope run gated the
5967
+ * scan out.
5968
+ */
5969
+ token_consumers?: TokenConsumers[]
5885
5970
  /**
5886
5971
  * The project authors `font-size` values in several units (`px`, `rem`,
5887
5972
  * `em`, `%`), with a per-unit distinct-value count: a type-scale
@@ -6068,11 +6153,16 @@ nesting_depth: number
6068
6153
  /**
6069
6154
  * Project-wide CSS analytics aggregates across every analyzed stylesheet
6070
6155
  * (including stylesheets with no notable rule, which are not listed
6071
- * individually).
6156
+ * individually in `files`).
6072
6157
  */
6073
6158
  export interface CssAnalyticsSummary {
6074
6159
  /**
6075
- * Stylesheets analyzed (standard CSS only; SCSS is skipped).
6160
+ * Stylesheets analyzed: standard `.css` files, Vue/Svelte SFC `<style>`
6161
+ * blocks, and (dep-gated) CSS-in-JS, both the tagged-template form and the
6162
+ * object form (`style({...})` / `stylex.create({...})` / `css({...})`). SCSS
6163
+ * is skipped. Note: flat atomic object CSS-in-JS (StyleX/Panda) is counted
6164
+ * here and contributes to these aggregates, but has no notable rules, so its
6165
+ * files never appear in the per-file `files` list.
6076
6166
  */
6077
6167
  files_analyzed: number
6078
6168
  /**
@@ -6184,6 +6274,22 @@ tailwind_arbitrary_values: number
6184
6274
  * Total Tailwind arbitrary-value occurrences across markup.
6185
6275
  */
6186
6276
  tailwind_arbitrary_value_uses: number
6277
+ /**
6278
+ * Preprocessor stylesheets (`.scss`, `.sass`, `.less`) seen by the styling
6279
+ * scan. These are parsed textually for local candidates, not compiled.
6280
+ */
6281
+ preprocessor_stylesheets: number
6282
+ /**
6283
+ * True when project-wide class reachability was skipped because
6284
+ * preprocessor stylesheets outnumber plain CSS, making generated classes
6285
+ * invisible without a Sass/Less compiler.
6286
+ */
6287
+ preprocessor_reachability_abstained: boolean
6288
+ /**
6289
+ * Located raw CSS declaration values that bypass token surfaces on
6290
+ * scale-sensitive axes. Located in `raw_style_values`.
6291
+ */
6292
+ raw_style_values: number
6187
6293
  /**
6188
6294
  * `@property` registrations never referenced via `var()` in any stylesheet
6189
6295
  * (located in `unused_at_rules`). Cleanup candidates.
@@ -6219,6 +6325,12 @@ unused_font_faces: number
6219
6325
  * partial-scope run gated the scan out.
6220
6326
  */
6221
6327
  unused_theme_tokens: number
6328
+ /**
6329
+ * Tailwind v4 theme tokens whose comparable values are close to another
6330
+ * token in the same theme dictionary. Located in
6331
+ * `near_duplicate_theme_tokens`.
6332
+ */
6333
+ near_duplicate_theme_tokens: number
6222
6334
  /**
6223
6335
  * Number of distinct `font-size` units (`px` / `rem` / `em` / `%`) authored
6224
6336
  * across the codebase. Mixing units is a type-scale consistency smell,
@@ -6368,6 +6480,85 @@ path: string
6368
6480
  */
6369
6481
  line: number
6370
6482
  }
6483
+ /**
6484
+ * A duplicated CVA / shadcn variant class block.
6485
+ */
6486
+ export interface CvaDuplicateVariantBlock {
6487
+ /**
6488
+ * Normalized class block shared by several variant values.
6489
+ */
6490
+ value: string
6491
+ /**
6492
+ * Number of variant values with this class block.
6493
+ */
6494
+ occurrence_count: number
6495
+ /**
6496
+ * First locations of the duplicate values, sorted by path and line.
6497
+ */
6498
+ occurrences: CssBlockOccurrence[]
6499
+ /**
6500
+ * Read-only guidance step(s), so consumers can iterate `actions`
6501
+ * uniformly across every candidate type.
6502
+ */
6503
+ actions: CssCandidateAction[]
6504
+ }
6505
+ /**
6506
+ * A CVA / shadcn variant class value that can reuse an existing styling token.
6507
+ */
6508
+ export interface CvaVariantTokenDrift {
6509
+ /**
6510
+ * Tailwind arbitrary-value utility inside the variant class string.
6511
+ */
6512
+ class_token: string
6513
+ /**
6514
+ * Normalized value inside the arbitrary utility.
6515
+ */
6516
+ value: string
6517
+ /**
6518
+ * Full normalized variant class block containing the token.
6519
+ */
6520
+ variant_classes: string
6521
+ /**
6522
+ * Project-root-relative, forward-slash path to the variant definition.
6523
+ */
6524
+ path: string
6525
+ /**
6526
+ * 1-based line of the variant class string.
6527
+ */
6528
+ line: number
6529
+ nearest_token: NearestStylingToken
6530
+ /**
6531
+ * Read-only guidance step(s), so consumers can iterate `actions`
6532
+ * uniformly across every candidate type.
6533
+ */
6534
+ actions: CssCandidateAction[]
6535
+ }
6536
+ /**
6537
+ * A styling token candidate that can replace or explain a finding.
6538
+ */
6539
+ export interface NearestStylingToken {
6540
+ /**
6541
+ * Token name, e.g. `--color-brand`.
6542
+ */
6543
+ name: string
6544
+ /**
6545
+ * Normalized token value.
6546
+ */
6547
+ value: string
6548
+ /**
6549
+ * Project-root-relative, forward-slash definition path.
6550
+ */
6551
+ path: string
6552
+ /**
6553
+ * 1-based definition line.
6554
+ */
6555
+ line: number
6556
+ /**
6557
+ * Distance from the finding value. Lower is closer; units depend on the
6558
+ * comparable token namespace.
6559
+ */
6560
+ distance: number
6561
+ }
6371
6562
  /**
6372
6563
  * A distinct Tailwind arbitrary-value utility token used in markup, with its
6373
6564
  * total use count and first location (a design-token-bypass candidate).
@@ -6397,6 +6588,39 @@ line: number
6397
6588
  */
6398
6589
  actions: CssCandidateAction[]
6399
6590
  }
6591
+ /**
6592
+ * A located raw CSS declaration value on a scale-sensitive styling axis.
6593
+ */
6594
+ export interface RawStyleValue {
6595
+ /**
6596
+ * Value axis, e.g. `color`, `font-size`, `line-height`, `radius`, or `shadow`.
6597
+ */
6598
+ axis: string
6599
+ /**
6600
+ * CSS property where the raw value appears.
6601
+ */
6602
+ property: string
6603
+ /**
6604
+ * Rendered declaration value.
6605
+ */
6606
+ value: string
6607
+ /**
6608
+ * Project-root-relative, forward-slash path to the stylesheet.
6609
+ */
6610
+ path: string
6611
+ /**
6612
+ * 1-based line of the containing style rule.
6613
+ */
6614
+ line: number
6615
+ /**
6616
+ * Concrete token with the same or nearest comparable value, when resolved.
6617
+ */
6618
+ nearest_token?: (NearestStylingToken | null)
6619
+ /**
6620
+ * Read-only guidance step(s). Never auto-fixable.
6621
+ */
6622
+ actions: CssCandidateAction[]
6623
+ }
6400
6624
  /**
6401
6625
  * An unused CSS at-rule entity (an `@property` registration with no `var()`
6402
6626
  * reference, or an `@layer` declaration never populated), located by its first
@@ -6526,6 +6750,121 @@ line: number
6526
6750
  */
6527
6751
  actions: CssCandidateAction[]
6528
6752
  }
6753
+ /**
6754
+ * A Tailwind v4 `@theme` token that appears to duplicate an existing token by
6755
+ * value. Emitted conservatively for comparable token namespaces, with the
6756
+ * nearest existing token named so an agent has a concrete reuse target.
6757
+ */
6758
+ export interface NearDuplicateThemeToken {
6759
+ /**
6760
+ * The full custom property as authored, including the `--` prefix.
6761
+ */
6762
+ token: string
6763
+ /**
6764
+ * The normalized authored token value.
6765
+ */
6766
+ value: string
6767
+ /**
6768
+ * Project-root-relative, forward-slash path to the token definition.
6769
+ */
6770
+ path: string
6771
+ /**
6772
+ * 1-based line of the token definition inside the `@theme` block.
6773
+ */
6774
+ line: number
6775
+ nearest_token: NearestStylingToken
6776
+ /**
6777
+ * Read-only guidance step(s) before replacing the token reference.
6778
+ */
6779
+ actions: CssCandidateAction[]
6780
+ }
6781
+ /**
6782
+ * A location-aware reverse index of where one design token is consumed, so an
6783
+ * agent editing the token can see its blast radius before changing or removing
6784
+ * it. Covers TWO token origins. The always-available discriminator is the `token`
6785
+ * SHAPE: a Tailwind token is the `--`-prefixed custom property (`--color-brand`),
6786
+ * a CSS-in-JS token is a dotted access path with no `--` prefix
6787
+ * (`vars.color.primary`). The per-consumer `kind` also discriminates origin, but
6788
+ * only when `consumer_count > 0` (a `consumer_count: 0` entry has an empty
6789
+ * `consumers` array and thus no `kind`), so branch on the `token` prefix for the
6790
+ * zero-consumer case. The two origins:
6791
+ *
6792
+ * - Tailwind v4 `@theme` tokens (kinds `theme-var` / `css-var` / `utility` /
6793
+ * `apply`), built from the same gated candidate set as `unused_theme_tokens`
6794
+ * (v4 + non-plugin + non-published + whole-scope), so a `consumer_count: 0`
6795
+ * corroborates the `unused_theme_tokens` "nothing consumes this" finding.
6796
+ * - CSS-in-JS tokens (kind `js-member` / `js-call`) from StyleX `defineVars`,
6797
+ * vanilla-extract `createTheme` family definitions, and PandaCSS `defineTokens`,
6798
+ * consumed via cross-module member access or PandaCSS `token('...')` calls. NOTE:
6799
+ * CSS-in-JS has NO corroborating dead-token finding (there is no
6800
+ * `unused_theme_tokens` analogue), so a CSS-in-JS `consumer_count: 0` is a weaker
6801
+ * signal than the Tailwind case (and the cross-file scan is relative-import or
6802
+ * generated-token-helper only, so alias / bare-package imports are not counted).
6803
+ *
6804
+ * This is DESCRIPTIVE context (a blast-radius lookup), not a finding, so it
6805
+ * deliberately carries no `actions` array (unlike the cleanup-candidate types in
6806
+ * this module). `consumer_count` is always a STATIC lower bound (a computed class
6807
+ * name like `bg-${color}`, or a CSS-in-JS access through an unresolved alias
6808
+ * import, is not counted).
6809
+ */
6810
+ export interface TokenConsumers {
6811
+ /**
6812
+ * The token identity. For a Tailwind `@theme` token this is the full custom
6813
+ * property as authored, INCLUDING the `--` prefix (`--color-brand`). For a
6814
+ * CSS-in-JS token (kind `js-member`) this is the binding-qualified dotted
6815
+ * access path, NO `--` prefix (`vars.color.primary`), matching how consumers
6816
+ * read it. The presence of the `--` prefix distinguishes the two origins.
6817
+ */
6818
+ token: string
6819
+ /**
6820
+ * For a Tailwind token, the v4 theme namespace (`color`, `radius`,
6821
+ * `font-weight`, ...). For a CSS-in-JS token (kind `js-member`), the defining
6822
+ * export BINDING the token set is accessed through (`vars`), which identifies
6823
+ * the token set, NOT a semantic group. (The field is thus overloaded by
6824
+ * origin; branch on `consumers[].kind` or the `token` shape.)
6825
+ */
6826
+ namespace: string
6827
+ /**
6828
+ * Project-root-relative, forward-slash path to the declaring stylesheet
6829
+ * (Tailwind) or the JS/TS token-definition file (CSS-in-JS).
6830
+ */
6831
+ definition_path: string
6832
+ /**
6833
+ * 1-based line of the token's definition (inside the `@theme` block for
6834
+ * Tailwind; the token key inside the `defineVars`/`createTheme` object for
6835
+ * CSS-in-JS).
6836
+ */
6837
+ definition_line: number
6838
+ /**
6839
+ * The FULL number of consumer locations found, a STATIC LOWER BOUND: a
6840
+ * computed class name (`bg-${color}`) or a value read outside CSS/markup the
6841
+ * scan never sees is not counted. This is the aggregate over every consumer,
6842
+ * computed BEFORE [`consumers`](Self::consumers) is capped to a sample.
6843
+ */
6844
+ consumer_count: number
6845
+ /**
6846
+ * A capped, deterministically-sorted sample of consumer locations (at most
6847
+ * [`TOKEN_CONSUMER_SAMPLE_CAP`]). The full count lives in
6848
+ * [`consumer_count`](Self::consumer_count); use this list to jump to
6849
+ * representative consumers, not to enumerate every one.
6850
+ */
6851
+ consumers: TokenConsumerLocation[]
6852
+ }
6853
+ /**
6854
+ * Where one Tailwind v4 `@theme` token is consumed, and through which surface.
6855
+ * One entry in a [`TokenConsumers::consumers`] sample.
6856
+ */
6857
+ export interface TokenConsumerLocation {
6858
+ /**
6859
+ * Project-root-relative, forward-slash path to the consuming file.
6860
+ */
6861
+ path: string
6862
+ /**
6863
+ * 1-based line of the consuming reference in that file.
6864
+ */
6865
+ line: number
6866
+ kind: ConsumerKind
6867
+ }
6529
6868
  /**
6530
6869
  * A design-token notation-consistency candidate: the distinct notations used
6531
6870
  * across the codebase for one value axis (today, length units on `font-size`),
@@ -6564,6 +6903,135 @@ notation: string
6564
6903
  */
6565
6904
  count: number
6566
6905
  }
6906
+ /**
6907
+ * Project-level styling-health score: a SECOND health axis computed purely from
6908
+ * the structural CSS analytics (`CssAnalyticsReport`), orthogonal to the JS/TS
6909
+ * code-health [`HealthScore`]. Surfaced only alongside the `--css` analytics, so
6910
+ * a plain `fallow health` run is byte-unchanged. The code score and grade stay
6911
+ * untouched: styling health is additive, never folded into the code score.
6912
+ *
6913
+ * Like [`HealthScore`], the score starts at 100 and subtracts capped per-category
6914
+ * penalties; the grade reuses the shared [`letter_grade`] thresholds verbatim
6915
+ * (A>=85, B>=70, C>=55, D>=40, F<40), so the two axes are read on one scale.
6916
+ */
6917
+ export interface StylingHealth {
6918
+ formula_version: number
6919
+ score: number
6920
+ grade: string
6921
+ penalties: StylingHealthPenalties
6922
+ confidence: StylingHealthConfidence
6923
+ /**
6924
+ * Human-readable reason the grade is low-confidence: either the declaration
6925
+ * and stylesheet counts a thin grade was computed from, or that structure is
6926
+ * not assessable for compile-time-atomic CSS-in-JS. `None` when confidence is
6927
+ * `High`. Prose, not a stable machine field: gate on `confidence`, not on
6928
+ * this string.
6929
+ */
6930
+ confidence_reason?: (string | null)
6931
+ }
6932
+ /**
6933
+ * Per-category penalty breakdown for the styling-health score. Each field is the
6934
+ * number of points subtracted from a starting 100 for one CSS signal family,
6935
+ * already capped at its category ceiling. A `0.0` field means "the signal was
6936
+ * evaluated and clean"; the whole struct is only ever built when CSS analytics
6937
+ * were produced, so there is no "missing pipeline" ambiguity to model with
6938
+ * `Option` here (the parent `StylingHealth` is itself `Option` on the report).
6939
+ */
6940
+ export interface StylingHealthPenalties {
6941
+ /**
6942
+ * Copy-paste declaration blocks (`duplicate_declaration_blocks`), scaled by
6943
+ * total removable declarations. Capped at 20pt.
6944
+ */
6945
+ duplication: number
6946
+ /**
6947
+ * Dead styling surface, two independently-normalized terms summed and capped
6948
+ * at 20pt: (a) unused `@theme` tokens as a share of the total `@theme` token
6949
+ * population (size-independent, so a declaration-sparse Tailwind project is
6950
+ * not penalized for a few dead tokens); plus (b) the other dead entities
6951
+ * (unreferenced classes, unused `@property`/`@layer` at-rules, dead
6952
+ * `@font-face` families) as a share of `total_declarations`.
6953
+ */
6954
+ dead_surface: number
6955
+ /**
6956
+ * Broken references: markup classes one edit from a defined class
6957
+ * (`unresolved_class_references`) and animations referencing a `@keyframes`
6958
+ * defined nowhere (`undefined_keyframes`). Capped at 15pt.
6959
+ */
6960
+ broken_references: number
6961
+ /**
6962
+ * Design-token erosion: mixed `font-size` units (`font_size_unit_mix`),
6963
+ * Tailwind arbitrary-value bypasses (`tailwind_arbitrary_values`), and
6964
+ * distinct HARDCODED `box-shadow`/`border-radius`/`line-height` values above
6965
+ * per-axis baselines (the v3 value-sprawl drift sub-term; `var(--*)`-
6966
+ * referenced values are not counted). Capped at 10pt.
6967
+ */
6968
+ token_erosion: number
6969
+ /**
6970
+ * Structural smells from the summary aggregates: `!important` density and
6971
+ * deep style-rule nesting. Capped at 10pt.
6972
+ */
6973
+ structural: number
6974
+ }
6975
+ /**
6976
+ * One advisory STYLING FINDING: the graduation of a descriptive css candidate
6977
+ * into a first-class, severity-aware, suppressible finding surfaced in
6978
+ * `fallow audit`. The styling domain's OWN finding type (not borrowed into the
6979
+ * dead-code `AnalysisResults`, and not glued in the CLI). `code` is the kebab
6980
+ * IssueKind code (e.g. `css-token-drift`), so severity / inline suppression /
6981
+ * SARIF / MCP all resolve via the shared `issue_meta` contract through
6982
+ * `IssueKind::parse(code)`. One `Vec<StylingFinding>` carries every styling
6983
+ * family; the `code` discriminates.
6984
+ */
6985
+ export interface StylingFinding {
6986
+ /**
6987
+ * The kebab IssueKind code, e.g. `css-token-drift`.
6988
+ */
6989
+ code: string
6990
+ /**
6991
+ * The specific sub-kind within the family, e.g. `tailwind-arbitrary-value`.
6992
+ */
6993
+ sub_kind: string
6994
+ /**
6995
+ * Workspace-relative path of the finding.
6996
+ */
6997
+ path: string
6998
+ /**
6999
+ * 1-based line of the finding.
7000
+ */
7001
+ line: number
7002
+ /**
7003
+ * The offending literal value, e.g. `w-[13px]`.
7004
+ */
7005
+ value: string
7006
+ effective_severity: StylingFindingSeverity
7007
+ /**
7008
+ * Optional static lower-bound blast radius. For a dead design token this is
7009
+ * `0`; for other styling findings it is omitted.
7010
+ */
7011
+ blast_radius?: (number | null)
7012
+ /**
7013
+ * Confidence hint for agents and review UIs. Structural findings are high,
7014
+ * reachability findings are low because dynamic consumers may exist.
7015
+ */
7016
+ confidence?: (StylingFindingConfidence | null)
7017
+ /**
7018
+ * Suggested handling posture for agents. This is advisory data, fallow
7019
+ * still never applies styling changes automatically.
7020
+ */
7021
+ agent_disposition?: (StylingAgentDisposition | null)
7022
+ /**
7023
+ * Concrete reuse target for token-drift findings, when one can be resolved.
7024
+ */
7025
+ nearest_token?: (NearestStylingToken | null)
7026
+ /**
7027
+ * One concise machine-readable edit hint for agent consumers.
7028
+ */
7029
+ fix_hint?: (string | null)
7030
+ /**
7031
+ * Suggested next steps (verify / suppress; never an auto-fix).
7032
+ */
7033
+ actions: CssCandidateAction[]
7034
+ }
6567
7035
  /**
6568
7036
  * Envelope emitted by `fallow explain <issue-type> --format json`.
6569
7037
  *
@@ -6991,6 +7459,23 @@ framework_health?: (FrameworkHealthDiagnostics | null)
6991
7459
  * over-complex selectors, deep nesting). Present only with `--css`.
6992
7460
  */
6993
7461
  css_analytics?: (CssAnalyticsReport | null)
7462
+ /**
7463
+ * Styling-health score and letter grade: a SECOND health axis derived from
7464
+ * the CSS analytics (the design-system axis), orthogonal to the JS/TS code
7465
+ * `health_score`. Present only with `--css` (the same condition as
7466
+ * `css_analytics`), so a plain `fallow health` run is byte-unchanged. The
7467
+ * code score is never affected by this field.
7468
+ */
7469
+ styling_health?: (StylingHealth | null)
7470
+ /**
7471
+ * Advisory STYLING FINDINGS: the graduation of the descriptive css
7472
+ * candidates into first-class, severity-aware, suppressible findings
7473
+ * surfaced in `fallow audit`. Verdict-neutral by default (the rule defaults
7474
+ * to `warn`); the styling domain's OWN findings collection, not the dead-code
7475
+ * `AnalysisResults`. Present only with `--css`; empty is skipped so a plain
7476
+ * run is byte-unchanged.
7477
+ */
7478
+ styling_findings?: StylingFinding[]
6994
7479
  grouped_by?: (GroupByMode | null)
6995
7480
  groups?: (HealthGroup[] | null)
6996
7481
  _meta?: (Meta | null)
@@ -8778,10 +9263,11 @@ export interface FocusMap {
8778
9263
  */
8779
9264
  review_here: FocusUnit[]
8780
9265
  /**
8781
- * EVERY `not-prioritized` unit (the escape hatch). Always present and fully
9266
+ * EVERY de-prioritized unit (`not-prioritized`, plus runtime-backed `skip`
9267
+ * units on the paid path) -- the escape hatch. Always present and fully
8782
9268
  * enumerated so a reviewer can always "show me what you de-prioritized"; the
8783
9269
  * human brief collapses it by default and re-expands under
8784
- * `--show-deprioritized`.
9270
+ * `--show-deprioritized`. Nothing is ever hidden, including a `skip`.
8785
9271
  */
8786
9272
  deprioritized: FocusUnit[]
8787
9273
  }
@@ -8806,9 +9292,9 @@ reason: string
8806
9292
  confidence?: ConfidenceFlag[]
8807
9293
  }
8808
9294
  /**
8809
- * The composite attention score, with the four deterministic component
8810
- * sub-scores kept on the wire so the runtime seam can re-weight `total`
8811
- * without recomputing the signals.
9295
+ * The composite attention score, with the deterministic component sub-scores
9296
+ * kept on the wire so the runtime layer adds its weight without recomputing the
9297
+ * signals.
8812
9298
  */
8813
9299
  export interface FocusScore {
8814
9300
  /**
@@ -8829,7 +9315,16 @@ risk_zone: number
8829
9315
  */
8830
9316
  change_shape: number
8831
9317
  /**
8832
- * The summed total. The paid runtime layer multiplies a runtime hot/cold weight in here.
9318
+ * Runtime-weight component (paid): a hot path (runtime evidence of high
9319
+ * invocation) adds an invocation-bucketed weight so it amplifies the blast
9320
+ * and outranks an otherwise-equal cold unit. `0` in free mode (no runtime
9321
+ * input), so the free-tier total stays the four deterministic components and
9322
+ * is byte-identical to the no-runtime baseline.
9323
+ */
9324
+ runtime?: number
9325
+ /**
9326
+ * The summed total of every present component (the four deterministic ones
9327
+ * plus the runtime weight).
8833
9328
  */
8834
9329
  total: number
8835
9330
  }