@drskillissue/ganko 0.2.82 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import ts from 'typescript';
2
- import { RuleOverrides, Logger, StringInterner } from '@drskillissue/ganko-shared';
2
+ import { RuleOverrides, Logger, StringInterner, WorkspaceLayout } from '@drskillissue/ganko-shared';
3
3
  import { Declaration, AtRule, Root, Rule } from 'postcss';
4
4
  export { RULES, RULES_BY_CATEGORY, RuleEntry, getRule } from './rules-manifest.js';
5
5
 
@@ -51,7 +51,7 @@ interface CommentEntry {
51
51
  }
52
52
 
53
53
  /** Emit callback type for pushing diagnostics */
54
- type Emit = (d: Diagnostic) => void;
54
+ type Emit$1 = (d: Diagnostic) => void;
55
55
  /**
56
56
  * A plugin provides a graph type and its rules.
57
57
  *
@@ -64,7 +64,7 @@ interface Plugin<K extends string> {
64
64
  readonly kind: K;
65
65
  readonly extensions: readonly string[];
66
66
  /** Analyze files and emit diagnostics via callback */
67
- analyze(files: readonly string[], emit: Emit, context?: {
67
+ analyze(files: readonly string[], emit: Emit$1, context?: {
68
68
  program: ts.Program;
69
69
  }): void;
70
70
  }
@@ -102,7 +102,7 @@ interface Runner {
102
102
  * @param overrides - Current rule override map
103
103
  * @returns Wrapped emit that suppresses/remaps per overrides
104
104
  */
105
- declare function createOverrideEmit(target: Emit, overrides: RuleOverrides): Emit;
105
+ declare function createOverrideEmit(target: Emit$1, overrides: RuleOverrides): Emit$1;
106
106
  /**
107
107
  * Create a runner from configuration.
108
108
  */
@@ -194,12 +194,12 @@ declare class TypeResolver {
194
194
  *
195
195
  * Returns null if the type is not reactive.
196
196
  */
197
- getReactiveKind(node: ts.Node): ReactiveKind | null;
197
+ getReactiveKind(node: ts.Node): ReactiveKind$1 | null;
198
198
  /**
199
199
  * Get both reactive kind AND type info in a single call.
200
200
  */
201
201
  getReactiveKindWithType(node: ts.Node): {
202
- kind: ReactiveKind | null;
202
+ kind: ReactiveKind$1 | null;
203
203
  type: TypeInfo | null;
204
204
  };
205
205
  /**
@@ -340,7 +340,7 @@ interface VariableEntity$1 {
340
340
  reads: ReadEntity[];
341
341
  type: TypeInfo | null;
342
342
  isReactive: boolean;
343
- reactiveKind: ReactiveKind | null;
343
+ reactiveKind: ReactiveKind$1 | null;
344
344
  isSignalLike: boolean;
345
345
  isMemoVariable: boolean;
346
346
  hasPropertyAssignment: boolean;
@@ -350,7 +350,7 @@ interface VariableEntity$1 {
350
350
  *
351
351
  * Different kinds have different behaviors and tracking rules.
352
352
  */
353
- type ReactiveKind = "signal" | "store" | "props" | "memo" | "derived" | "accessor" | "resource";
353
+ type ReactiveKind$1 = "signal" | "store" | "props" | "memo" | "derived" | "accessor" | "resource";
354
354
  /** Assignment operator type extracted from AssignmentExpression */
355
355
  type AssignmentOperator = ts.SyntaxKind;
356
356
  /**
@@ -977,7 +977,7 @@ interface ExportEntity {
977
977
  /** Whether this is the default export */
978
978
  readonly isDefault: boolean;
979
979
  /** Reactive kind if this exports a reactive value */
980
- readonly reactiveKind: ReactiveKind | null;
980
+ readonly reactiveKind: ReactiveKind$1 | null;
981
981
  /**
982
982
  * Signature string for change detection.
983
983
  * Used by workspace layer to detect export API changes.
@@ -1344,11 +1344,118 @@ interface OwnershipEdge {
1344
1344
  readonly child: ComputationEntity;
1345
1345
  }
1346
1346
 
1347
+ interface JSXAttributeWithElement$1 {
1348
+ readonly attr: JSXAttributeEntity;
1349
+ readonly element: JSXElementEntity;
1350
+ }
1351
+ interface JSXStaticClassIndex$1 {
1352
+ readonly hasDynamicClass: boolean;
1353
+ readonly tokens: readonly string[];
1354
+ }
1355
+ interface JSXStaticObjectKeyIndex$1 {
1356
+ readonly hasDynamic: boolean;
1357
+ readonly keys: readonly string[];
1358
+ }
1359
+ interface JSXObjectPropertyWithElement$1 {
1360
+ readonly property: ts.ObjectLiteralElementLike;
1361
+ readonly attr: JSXAttributeEntity;
1362
+ readonly element: JSXElementEntity;
1363
+ }
1364
+ interface SolidSyntaxTree {
1365
+ readonly kind: "solid";
1366
+ readonly filePath: string;
1367
+ readonly version: string;
1368
+ readonly sourceFile: ts.SourceFile;
1369
+ readonly comments: readonly CommentEntry[];
1370
+ readonly scopes: readonly ScopeEntity[];
1371
+ readonly variables: readonly VariableEntity$1[];
1372
+ readonly functions: readonly FunctionEntity[];
1373
+ readonly calls: readonly CallEntity[];
1374
+ readonly jsxElements: readonly JSXElementEntity[];
1375
+ readonly imports: readonly ImportEntity[];
1376
+ readonly exports: readonly ExportEntity[];
1377
+ readonly classes: readonly ClassEntity[];
1378
+ readonly properties: readonly PropertyEntity[];
1379
+ readonly propertyAssignments: readonly PropertyAssignmentEntity[];
1380
+ readonly conditionalSpreads: readonly ConditionalSpreadEntity[];
1381
+ readonly objectSpreads: readonly ObjectSpreadEntity[];
1382
+ readonly nonNullAssertions: readonly NonNullAssertionEntity[];
1383
+ readonly typeAssertions: readonly TypeAssertionEntity[];
1384
+ readonly typePredicates: readonly TypePredicateEntity[];
1385
+ readonly unsafeGenericAssertions: readonly UnsafeGenericAssertionEntity[];
1386
+ readonly unsafeTypeAnnotations: readonly UnsafeTypeAnnotationEntity[];
1387
+ readonly inlineImports: readonly InlineImportEntity[];
1388
+ readonly computations: readonly ComputationEntity[];
1389
+ readonly dependencyEdges: readonly DependencyEdge[];
1390
+ readonly ownershipEdges: readonly OwnershipEdge[];
1391
+ readonly variablesByName: ReadonlyMap<string, readonly VariableEntity$1[]>;
1392
+ readonly functionsByNode: ReadonlyMap<ts.Node, FunctionEntity>;
1393
+ readonly functionsByDeclarationNode: ReadonlyMap<ts.Node, FunctionEntity>;
1394
+ readonly functionsByName: ReadonlyMap<string, readonly FunctionEntity[]>;
1395
+ readonly callsByNode: ReadonlyMap<ts.CallExpression | ts.NewExpression, CallEntity>;
1396
+ readonly callsByPrimitive: ReadonlyMap<string, readonly CallEntity[]>;
1397
+ readonly callsByMethodName: ReadonlyMap<string, readonly CallEntity[]>;
1398
+ readonly callsByArgNode: ReadonlyMap<ts.Node, ArgumentEntity>;
1399
+ readonly jsxByNode: ReadonlyMap<ts.Node, JSXElementEntity>;
1400
+ readonly jsxByTag: ReadonlyMap<string, readonly JSXElementEntity[]>;
1401
+ readonly jsxAttributesByElementId: ReadonlyMap<number, ReadonlyMap<string, JSXAttributeEntity>>;
1402
+ readonly jsxAttrsByKind: ReadonlyMap<JSXAttributeKind, readonly JSXAttributeWithElement$1[]>;
1403
+ readonly jsxClassAttributes: readonly JSXAttributeWithElement$1[];
1404
+ readonly jsxClassListAttributes: readonly JSXAttributeWithElement$1[];
1405
+ readonly jsxStyleAttributes: readonly JSXAttributeWithElement$1[];
1406
+ readonly fillImageElements: readonly JSXElementEntity[];
1407
+ readonly staticClassTokensByElementId: ReadonlyMap<number, JSXStaticClassIndex$1>;
1408
+ readonly staticClassListKeysByElementId: ReadonlyMap<number, JSXStaticObjectKeyIndex$1>;
1409
+ readonly staticStyleKeysByElementId: ReadonlyMap<number, JSXStaticObjectKeyIndex$1>;
1410
+ readonly classListProperties: readonly JSXObjectPropertyWithElement$1[];
1411
+ readonly styleProperties: readonly JSXObjectPropertyWithElement$1[];
1412
+ readonly inlineStyleClassNames: ReadonlySet<string>;
1413
+ readonly importsBySource: ReadonlyMap<string, readonly ImportEntity[]>;
1414
+ readonly exportsByName: ReadonlyMap<string, ExportEntity>;
1415
+ readonly exportsByEntityId: ReadonlyMap<number, ExportEntity>;
1416
+ readonly classesByNode: ReadonlyMap<ts.ClassDeclaration | ts.ClassExpression, ClassEntity>;
1417
+ readonly classesByName: ReadonlyMap<string, readonly ClassEntity[]>;
1418
+ readonly unaryExpressionsByOperator: ReadonlyMap<ts.SyntaxKind, readonly ts.PrefixUnaryExpression[]>;
1419
+ readonly spreadElements: readonly (ts.SpreadElement | ts.SpreadAssignment)[];
1420
+ readonly newExpressionsByCallee: ReadonlyMap<string, readonly ts.NewExpression[]>;
1421
+ readonly deleteExpressions: readonly ts.DeleteExpression[];
1422
+ readonly identifiersByName: ReadonlyMap<string, readonly ts.Identifier[]>;
1423
+ readonly firstScope: ScopeEntity | null;
1424
+ readonly componentScopes: ReadonlyMap<ScopeEntity, {
1425
+ readonly scope: ScopeEntity;
1426
+ readonly name: string;
1427
+ }>;
1428
+ readonly componentFunctions: readonly FunctionEntity[];
1429
+ readonly functionsWithReactiveCaptures: readonly FunctionEntity[];
1430
+ readonly reactiveVariables: readonly VariableEntity$1[];
1431
+ readonly propsVariables: readonly VariableEntity$1[];
1432
+ readonly storeVariables: readonly VariableEntity$1[];
1433
+ readonly resourceVariables: readonly VariableEntity$1[];
1434
+ readonly variablesWithPropertyAssignment: readonly VariableEntity$1[];
1435
+ readonly computationByCallId: ReadonlyMap<number, ComputationEntity>;
1436
+ readonly typeResolver: TypeResolver;
1437
+ readonly fileEntity: FileEntity$1;
1438
+ readonly lineStartOffsets: readonly number[];
1439
+ readonly jsxContextCache: WeakMap<ts.Node, JSXContext | null>;
1440
+ readonly scopeForCache: WeakMap<ts.Node, ScopeEntity>;
1441
+ readonly onDepsCache: WeakMap<ts.Node, boolean>;
1442
+ readonly passthroughCache: WeakMap<ts.Node, boolean>;
1443
+ findExpressionAtOffset(offset: number): ts.Node | null;
1444
+ }
1445
+
1446
+ declare function analyzeInput(input: SolidInput, emit: Emit$1): void;
1447
+ declare function runSolidRules(tree: SolidSyntaxTree, sourceFile: ts.SourceFile, emit: Emit$1): void;
1448
+ declare const SolidPlugin: Plugin<"solid">;
1449
+
1450
+ declare function createSolidInput(filePath: string, program: ts.Program, logger?: Logger): SolidInput;
1451
+
1347
1452
  /**
1348
- * SolidGraph Implementation
1453
+ * SolidBuildContext — mutable accumulator for solid analysis phases.
1454
+ *
1455
+ * Replaces the SolidGraph class. Phases call add* methods to populate entities.
1456
+ * After all phases complete, the context is frozen into a SolidSyntaxTree.
1349
1457
  */
1350
1458
 
1351
- /** @internal */
1352
1459
  interface JSXAttributeWithElement {
1353
1460
  readonly attr: JSXAttributeEntity;
1354
1461
  readonly element: JSXElementEntity;
@@ -1366,32 +1473,16 @@ interface JSXObjectPropertyWithElement {
1366
1473
  readonly attr: JSXAttributeEntity;
1367
1474
  readonly element: JSXElementEntity;
1368
1475
  }
1369
- /**
1370
- * The Solid.js program graph implementation.
1371
- *
1372
- * Contains all entities extracted from a Solid.js source file:
1373
- * scopes, variables, functions, calls, JSX elements, imports, exports, etc.
1374
- *
1375
- */
1376
- declare class SolidGraph {
1476
+ interface SolidBuildContext {
1377
1477
  readonly kind: "solid";
1478
+ readonly filePath: string;
1479
+ readonly version: string;
1378
1480
  readonly file: string;
1379
- readonly logger: Logger;
1380
1481
  readonly sourceFile: ts.SourceFile;
1381
- readonly comments: readonly CommentEntry[];
1382
1482
  readonly typeResolver: TypeResolver;
1483
+ readonly logger: Logger;
1383
1484
  readonly fileEntity: FileEntity$1;
1384
- private _nextScopeId;
1385
- private _nextVariableId;
1386
- private _nextFunctionId;
1387
- private _nextCallId;
1388
- private _nextJsxId;
1389
- private _nextImportId;
1390
- private _nextExportId;
1391
- private _nextClassId;
1392
- private _nextPropertyId;
1393
- private _nextConditionalSpreadId;
1394
- private _nextMiscId;
1485
+ readonly comments: readonly CommentEntry[];
1395
1486
  readonly scopes: ScopeEntity[];
1396
1487
  readonly variables: VariableEntity$1[];
1397
1488
  readonly functions: FunctionEntity[];
@@ -1431,7 +1522,6 @@ declare class SolidGraph {
1431
1522
  readonly staticStyleKeysByElementId: Map<number, JSXStaticObjectKeyIndex>;
1432
1523
  readonly classListProperties: JSXObjectPropertyWithElement[];
1433
1524
  readonly styleProperties: JSXObjectPropertyWithElement[];
1434
- /** CSS class names defined in inline `<style>` elements within JSX (e.g., SVG icons with embedded CSS). */
1435
1525
  readonly inlineStyleClassNames: Set<string>;
1436
1526
  readonly importsBySource: Map<string, ImportEntity[]>;
1437
1527
  readonly exportsByName: Map<string, ExportEntity>;
@@ -1443,7 +1533,6 @@ declare class SolidGraph {
1443
1533
  readonly newExpressionsByCallee: Map<string, ts.NewExpression[]>;
1444
1534
  readonly deleteExpressions: ts.DeleteExpression[];
1445
1535
  readonly identifiersByName: Map<string, ts.Identifier[]>;
1446
- private _lineStartOffsets;
1447
1536
  firstScope: ScopeEntity | null;
1448
1537
  readonly componentScopes: Map<ScopeEntity, {
1449
1538
  scope: ScopeEntity;
@@ -1456,137 +1545,72 @@ declare class SolidGraph {
1456
1545
  storeVariables: VariableEntity$1[];
1457
1546
  resourceVariables: VariableEntity$1[];
1458
1547
  variablesWithPropertyAssignment: VariableEntity$1[];
1459
- /** Reactive computation nodes (effects, memos, computed, roots, resources). */
1460
1548
  computations: ComputationEntity[];
1461
- /** Computation lookup by CallEntity ID. */
1462
1549
  readonly computationByCallId: Map<number, ComputationEntity>;
1463
- /** Dependency edges: computation reads reactive source. */
1464
1550
  dependencyEdges: DependencyEdge[];
1465
- /** Ownership edges: parent owns child computation. */
1466
1551
  ownershipEdges: OwnershipEdge[];
1467
1552
  readonly jsxContextCache: WeakMap<ts.Node, JSXContext | null>;
1468
1553
  readonly scopeForCache: WeakMap<ts.Node, ScopeEntity>;
1469
1554
  readonly onDepsCache: WeakMap<ts.Node, boolean>;
1470
1555
  readonly passthroughCache: WeakMap<ts.Node, boolean>;
1471
- /**
1472
- * Creates a new SolidGraph instance.
1473
- *
1474
- * @param input - The graph input containing source code and parser services
1475
- */
1476
- constructor(input: SolidInput);
1477
- /** @internal Generate next scope ID */
1478
1556
  nextScopeId(): number;
1479
- /** @internal Generate next variable ID */
1480
1557
  nextVariableId(): number;
1481
- /** @internal Generate next function ID */
1482
1558
  nextFunctionId(): number;
1483
- /** @internal Generate next call ID */
1484
1559
  nextCallId(): number;
1485
- /** @internal Generate next JSX element ID */
1486
1560
  nextJsxId(): number;
1487
- /** @internal Generate next import ID */
1488
1561
  nextImportId(): number;
1489
- /** @internal Generate next export ID */
1490
1562
  nextExportId(): number;
1491
- /** @internal Generate next class ID */
1492
1563
  nextClassId(): number;
1493
- /** @internal Generate next property ID */
1494
1564
  nextPropertyId(): number;
1495
- /** @internal Generate next conditional spread ID */
1496
1565
  nextConditionalSpreadId(): number;
1497
- /** @internal Generate next misc entity ID */
1498
1566
  nextMiscId(): number;
1499
- /**
1500
- * @internal Add a scope entity to the graph. Called by scopesPhase.
1501
- */
1502
1567
  addScope(scope: ScopeEntity): void;
1503
- /**
1504
- * @internal Add a variable entity to the graph. Called by scopesPhase.
1505
- */
1506
1568
  addVariable(variable: VariableEntity$1): void;
1507
- /**
1508
- * @internal Add a function entity to the graph. Called by entitiesPhase.
1509
- */
1510
1569
  addFunction(fn: FunctionEntity): void;
1511
- /**
1512
- * @internal Add a call entity to the graph. Called by entitiesPhase.
1513
- */
1514
1570
  addCall(call: CallEntity): void;
1515
- /**
1516
- * @internal Add a JSX element entity to the graph. Called by entitiesPhase.
1517
- */
1518
1571
  addJSXElement(element: JSXElementEntity): void;
1519
- /**
1520
- * Extract CSS class names from inline `<style>` JSX elements.
1521
- *
1522
- * Handles patterns like `<style>{`.foo { ... }`}</style>` found in SVG icons.
1523
- * Scans template literal and literal string children for `.className` patterns.
1524
- */
1525
- private extractInlineStyleClassNames;
1526
- private indexObjectAttribute;
1527
- /**
1528
- * @internal Add an import entity to the graph. Called by entitiesPhase.
1529
- */
1530
1572
  addImport(imp: ImportEntity): void;
1531
- /**
1532
- * @internal Add an export entity to the graph. Called by exportsPhase.
1533
- */
1534
1573
  addExport(exp: ExportEntity): void;
1535
- /** @internal Add a class entity to the graph. Called by entitiesPhase. */
1536
1574
  addClass(cls: ClassEntity): void;
1537
- /** @internal Add a property entity to the graph. */
1538
1575
  addProperty(prop: PropertyEntity): void;
1539
- /** @internal Add a property assignment entity to the graph. */
1540
1576
  addPropertyAssignment(pa: PropertyAssignmentEntity): void;
1541
- /** @internal Add a conditional spread entity to the graph. */
1542
1577
  addConditionalSpread(spread: ConditionalSpreadEntity): void;
1543
- /** @internal Add an object spread entity to the graph. */
1544
1578
  addObjectSpread(spread: ObjectSpreadEntity): void;
1545
- /** @internal Add a non-null assertion entity to the graph. */
1546
1579
  addNonNullAssertion(assertion: NonNullAssertionEntity): void;
1547
- /** @internal Add a type assertion entity to the graph. */
1548
1580
  addTypeAssertion(assertion: TypeAssertionEntity): void;
1549
- /** @internal Add a type predicate entity to the graph. */
1550
1581
  addTypePredicate(predicate: TypePredicateEntity): void;
1551
- /** @internal Add an unsafe generic assertion entity to the graph. */
1552
1582
  addUnsafeGenericAssertion(assertion: UnsafeGenericAssertionEntity): void;
1553
- /** @internal Add an unsafe type annotation entity to the graph. */
1554
1583
  addUnsafeTypeAnnotation(annotation: UnsafeTypeAnnotationEntity): void;
1555
- /** @internal Add an inline import entity to the graph. */
1556
1584
  addInlineImport(imp: InlineImportEntity): void;
1557
- /** @internal Add a computation entity to the graph. Called by dependenciesPhase. */
1558
1585
  addComputation(computation: ComputationEntity): void;
1559
- /** @internal Add a dependency edge to the graph. Called by dependenciesPhase. */
1560
1586
  addDependencyEdge(edge: DependencyEdge): void;
1561
- /** @internal Add an ownership edge to the graph. Called by dependenciesPhase. */
1562
1587
  addOwnershipEdge(edge: OwnershipEdge): void;
1563
- /**
1564
- * @internal Build reactive variable indexes. Called by reactivityPhase.
1565
- */
1566
1588
  buildReactiveIndex(): void;
1567
- /** @internal */
1568
1589
  addUnaryExpression(node: ts.PrefixUnaryExpression): void;
1569
- /** @internal */
1570
1590
  addDeleteExpression(node: ts.DeleteExpression): void;
1571
- /** @internal */
1572
1591
  addSpreadElement(node: ts.SpreadElement | ts.SpreadAssignment): void;
1573
- /** @internal */
1574
1592
  addNewExpressionByCallee(name: string, node: ts.NewExpression): void;
1575
- /** @internal */
1576
1593
  addIdentifierReference(node: ts.Identifier): void;
1577
- /**
1578
- * Line start offsets for position queries. Computed lazily — CLI lint
1579
- * never accesses this, so zero cost during analysis.
1580
- */
1581
- get lineStartOffsets(): readonly number[];
1582
- /**
1583
- * Find the deepest expression at a character offset using the AST.
1584
- * O(log n) via TypeScript's getTokenAtPosition + parent walk.
1585
- * Zero pre-computation — no dense array, no per-node writes during analysis.
1586
- */
1594
+ readonly lineStartOffsets: readonly number[];
1587
1595
  findExpressionAtOffset(offset: number): ts.Node | null;
1588
1596
  }
1589
1597
 
1598
+ /**
1599
+ * Solid analysis entry point.
1600
+ *
1601
+ * Builds a SolidSyntaxTree from a SolidInput by running all analysis phases
1602
+ * against a mutable SolidBuildContext, then freezing the result.
1603
+ */
1604
+
1605
+ /**
1606
+ * Build a SolidSyntaxTree from input.
1607
+ *
1608
+ * 1. Creates mutable SolidBuildContext
1609
+ * 2. Runs all 9 analysis phases (scopes, entities, wiring, reactivity, etc.)
1610
+ * 3. Freezes context into readonly SolidSyntaxTree
1611
+ */
1612
+ declare function buildSolidSyntaxTree(input: SolidInput, version: string): SolidSyntaxTree;
1613
+
1590
1614
  /**
1591
1615
  * Validates whether a CSS class name is a known Tailwind utility.
1592
1616
  *
@@ -1619,10 +1643,74 @@ interface TailwindValidator {
1619
1643
  * - `@tailwindcss/node` is not installed (directly or transitively)
1620
1644
  * - The design system fails to load
1621
1645
  */
1622
- declare function resolveTailwindValidator(files: readonly {
1646
+ /**
1647
+ * Preparation result for Tailwind resolution.
1648
+ *
1649
+ * Contains the data needed by the WorkspaceEvaluator subprocess to load the
1650
+ * design system. The caller passes these fields to evaluateWorkspace().
1651
+ */
1652
+ interface TailwindEvalParams {
1653
+ readonly modulePath: string;
1654
+ readonly entryCss: string;
1655
+ readonly entryBase: string;
1656
+ }
1657
+ /**
1658
+ * Prepare Tailwind evaluation parameters from CSS files.
1659
+ *
1660
+ * Detects the Tailwind entry file and resolves the @tailwindcss/node module
1661
+ * path. Returns null if no entry is detected or the module is not installed.
1662
+ * Does NOT spawn a subprocess — the caller does that via WorkspaceEvaluator.
1663
+ *
1664
+ * @param files - CSS files with content
1665
+ * @param rootPath - Project root for module resolution
1666
+ * @param workspacePackagePaths - Workspace package paths for module resolution
1667
+ * @param logger - Logger
1668
+ * @returns Evaluation parameters, or null
1669
+ */
1670
+ declare function prepareTailwindEval(files: readonly {
1671
+ path: string;
1672
+ content: string;
1673
+ }[], rootPath: string, workspacePackagePaths: readonly string[], logger?: Logger): TailwindEvalParams | null;
1674
+ /**
1675
+ * A TailwindValidator with a preloadable batch cache for arbitrary value classes.
1676
+ *
1677
+ * The static validator handles known utility/variant combinations.
1678
+ * Arbitrary values (min-h-[60vh], max-w-[360px], [&_[data-slot]]:hidden, etc.)
1679
+ * are not in the static set. The caller collects all class names that will be
1680
+ * checked, sends them to candidatesToCss in one batch via the WorkspaceEvaluator,
1681
+ * and preloads the results before rule execution.
1682
+ */
1683
+ interface BatchableTailwindValidator extends TailwindValidator {
1684
+ preloadBatch(classNames: readonly string[], results: readonly boolean[]): void;
1685
+ }
1686
+ /**
1687
+ * Build a TailwindValidator from evaluation results with batch preloading.
1688
+ *
1689
+ * @param utilities - Utility class names from the design system
1690
+ * @param variants - Variant definitions from the design system
1691
+ * @param logger - Logger
1692
+ * @returns BatchableTailwindValidator
1693
+ */
1694
+ declare function buildTailwindValidatorFromEval(utilities: readonly string[], variants: readonly {
1695
+ name: string;
1696
+ values: string[];
1697
+ hasDash: boolean;
1698
+ isArbitrary: boolean;
1699
+ }[], logger?: Logger): BatchableTailwindValidator;
1700
+ /**
1701
+ * Resolve a TailwindValidator synchronously.
1702
+ *
1703
+ * Uses the default Bun subprocess evaluator unless a custom one is provided.
1704
+ *
1705
+ * @param files - CSS files with content
1706
+ * @param rootPath - Project root (optional, walks up to package.json if not provided)
1707
+ * @param workspacePackagePaths - Workspace package paths (optional)
1708
+ * @returns TailwindValidator, or null
1709
+ */
1710
+ declare function resolveTailwindValidatorSync(files: readonly {
1623
1711
  path: string;
1624
1712
  content: string;
1625
- }[], logger?: Logger): Promise<TailwindValidator | null>;
1713
+ }[], rootPath?: string, workspacePackagePaths?: readonly string[]): BatchableTailwindValidator | null;
1626
1714
 
1627
1715
  /**
1628
1716
  * CSSInput - Input type for building CSSGraph from CSS/SCSS source files.
@@ -1645,26 +1733,20 @@ interface CSSFile {
1645
1733
  * Input for building a CSSGraph from CSS/SCSS source files.
1646
1734
  */
1647
1735
  interface CSSInput {
1648
- /** Files to process */
1649
1736
  readonly files: readonly CSSFile[];
1650
- /** Optional build options */
1651
- readonly options?: CSSOptions;
1652
- /** Pre-resolved Tailwind validator for utility class validation */
1653
- readonly tailwind?: TailwindValidator;
1654
- /** Logger for diagnostic output from CSS rules */
1655
- readonly logger?: Logger;
1656
- /**
1657
- * CSS custom property names provided by external libraries at runtime.
1658
- *
1659
- * These are discovered by scanning dependency packages for CSS custom property
1660
- * definitions injected via JavaScript (e.g., inline style attributes in JSX).
1661
- * Properties in this set are registered in the CSS graph as globally-scoped
1662
- * definitions so the resolution engine treats them as defined.
1663
- *
1664
- * Use `scanDependencyCustomProperties()` from `./library-analysis` to populate this.
1665
- */
1666
- readonly externalCustomProperties?: ReadonlySet<string>;
1737
+ readonly options: CSSOptions;
1738
+ readonly tailwind: TailwindValidator | null;
1739
+ readonly logger: Logger;
1740
+ readonly externalCustomProperties: ReadonlySet<string> | null;
1741
+ }
1742
+ interface CSSInputBuilder {
1743
+ files: readonly CSSFile[];
1744
+ options: CSSOptions;
1745
+ tailwind: TailwindValidator | null;
1746
+ logger: Logger;
1747
+ externalCustomProperties: ReadonlySet<string> | null;
1667
1748
  }
1749
+ declare function createCSSInput(files: readonly CSSFile[]): CSSInputBuilder;
1668
1750
  /**
1669
1751
  * Options for CSS graph building.
1670
1752
  */
@@ -1697,6 +1779,8 @@ interface TokenPatternConfig {
1697
1779
  }[];
1698
1780
  }
1699
1781
 
1782
+ declare const CSSPlugin: Plugin<"css">;
1783
+
1700
1784
  /**
1701
1785
  * CSS Specificity Types
1702
1786
  */
@@ -2241,37 +2325,150 @@ interface CSSParseError {
2241
2325
  }
2242
2326
 
2243
2327
  /**
2244
- * CSSGraphImpl - CSS Program Graph Implementation
2328
+ * CSSWorkspaceView readonly interface for CSS rules and queries.
2245
2329
  *
2330
+ * Replaces CSSGraph as the type received by CSS rules and query functions.
2331
+ * Contains every read-only field and query method that rules/queries access.
2246
2332
  */
2247
2333
 
2248
- /**
2249
- * A declaration referencing a keyframe name that has no matching @keyframes.
2250
- */
2251
- interface UnresolvedAnimationRef {
2252
- readonly declaration: DeclarationEntity;
2253
- readonly name: string;
2254
- }
2255
- interface KeyframeLayoutMutation {
2256
- readonly property: string;
2257
- readonly values: readonly string[];
2334
+ interface CSSWorkspaceView {
2335
+ readonly options: CSSOptions;
2336
+ readonly interner: StringInterner;
2337
+ readonly logger: Logger;
2338
+ readonly tailwind: TailwindValidator | null;
2339
+ readonly hasScssFiles: boolean;
2340
+ readonly files: readonly FileEntity[];
2341
+ readonly rules: readonly RuleEntity[];
2342
+ readonly selectors: readonly SelectorEntity[];
2258
2343
  readonly declarations: readonly DeclarationEntity[];
2344
+ readonly variables: readonly VariableEntity[];
2345
+ readonly variableRefs: readonly VariableReferenceEntity[];
2346
+ readonly atRules: readonly AtRuleEntity[];
2347
+ readonly tokens: readonly ThemeTokenEntity[];
2348
+ readonly mixins: readonly MixinEntity[];
2349
+ readonly includes: readonly MixinIncludeEntity[];
2350
+ readonly functions: readonly SCSSFunctionEntity[];
2351
+ readonly functionCalls: readonly FunctionCallEntity[];
2352
+ readonly placeholders: readonly PlaceholderEntity[];
2353
+ readonly extends: readonly ExtendEntity[];
2354
+ readonly filesByPath: ReadonlyMap<string, FileEntity>;
2355
+ readonly variablesByName: ReadonlyMap<string, readonly VariableEntity[]>;
2356
+ readonly rulesBySelector: ReadonlyMap<string, readonly RuleEntity[]>;
2357
+ readonly mixinsByName: ReadonlyMap<string, MixinEntity>;
2358
+ readonly functionsByName: ReadonlyMap<string, SCSSFunctionEntity>;
2359
+ readonly placeholdersByName: ReadonlyMap<string, PlaceholderEntity>;
2360
+ readonly layerOrder: ReadonlyMap<string, number>;
2361
+ readonly declarationsByProperty: ReadonlyMap<string, readonly DeclarationEntity[]>;
2362
+ readonly atRulesByName: ReadonlyMap<string, readonly AtRuleEntity[]>;
2363
+ readonly atRulesByKind: ReadonlyMap<AtRuleKind, readonly AtRuleEntity[]>;
2364
+ readonly atRulesByNode: ReadonlyMap<AtRule, AtRuleEntity>;
2365
+ readonly rulesByNode: ReadonlyMap<Rule, RuleEntity>;
2366
+ readonly duplicateSelectors: ReadonlyMap<string, {
2367
+ readonly selector: string;
2368
+ readonly rules: readonly RuleEntity[];
2369
+ }>;
2370
+ readonly tokensByCategory: ReadonlyMap<TokenCategory, readonly ThemeTokenEntity[]>;
2371
+ readonly importantDeclarations: readonly DeclarationEntity[];
2372
+ readonly globalVariables: readonly VariableEntity[];
2373
+ readonly unusedVariables: readonly VariableEntity[];
2374
+ readonly scssVariables: readonly VariableEntity[];
2375
+ readonly cssCustomProperties: readonly VariableEntity[];
2376
+ readonly unresolvedRefs: readonly VariableReferenceEntity[];
2377
+ readonly mediaQueries: readonly AtRuleEntity[];
2378
+ readonly keyframes: readonly AtRuleEntity[];
2379
+ readonly layers: readonly AtRuleEntity[];
2380
+ readonly fontFaces: readonly AtRuleEntity[];
2381
+ readonly supportsRules: readonly AtRuleEntity[];
2382
+ readonly unusedKeyframes: readonly AtRuleEntity[];
2383
+ readonly unusedMixins: readonly MixinEntity[];
2384
+ readonly unresolvedMixinIncludes: readonly MixinIncludeEntity[];
2385
+ readonly unusedFunctions: readonly SCSSFunctionEntity[];
2386
+ readonly unusedPlaceholders: readonly PlaceholderEntity[];
2387
+ readonly unresolvedExtends: readonly ExtendEntity[];
2388
+ readonly parseErrors: readonly CSSParseError[];
2389
+ readonly failedFilePaths: readonly string[];
2390
+ readonly tokenCategories: readonly TokenCategory[];
2391
+ readonly selectorsByPseudoClass: ReadonlyMap<string, readonly SelectorEntity[]>;
2392
+ readonly idSelectors: readonly SelectorEntity[];
2393
+ readonly attributeSelectors: readonly SelectorEntity[];
2394
+ readonly universalSelectors: readonly SelectorEntity[];
2395
+ readonly classNameIndex: ReadonlyMap<string, readonly SelectorEntity[]>;
2396
+ readonly selectorsBySubjectTag: ReadonlyMap<string, readonly SelectorEntity[]>;
2397
+ readonly selectorsWithoutSubjectTag: readonly SelectorEntity[];
2398
+ readonly selectorsTargetingCheckbox: readonly SelectorEntity[];
2399
+ readonly selectorsTargetingTableCell: readonly SelectorEntity[];
2400
+ readonly knownKeyframeNames: ReadonlySet<string>;
2401
+ readonly unresolvedAnimationRefs: readonly UnresolvedAnimationRef[];
2402
+ readonly declaredContainerNames: ReadonlyMap<string, readonly DeclarationEntity[]>;
2403
+ readonly containerQueryNames: ReadonlyMap<string, readonly AtRuleEntity[]>;
2404
+ readonly unusedContainerNames: ReadonlyMap<string, readonly DeclarationEntity[]>;
2405
+ readonly unknownContainerQueries: readonly AtRuleEntity[];
2406
+ readonly multiDeclarationProperties: ReadonlyMap<string, readonly DeclarationEntity[]>;
2407
+ readonly keyframeDeclarations: readonly DeclarationEntity[];
2408
+ readonly layoutPropertiesByClassToken: ReadonlyMap<string, readonly string[]>;
2409
+ readonly keyframeLayoutMutationsByName: ReadonlyMap<string, readonly KeyframeLayoutMutation$1[]>;
2410
+ readonly fontFaceDescriptorsByFamily: ReadonlyMap<string, readonly FontFaceDescriptor[]>;
2411
+ readonly usedFontFamiliesByRule: ReadonlyMap<number, readonly string[]>;
2412
+ readonly usedFontFamilies: ReadonlySet<string>;
2413
+ readonly filesWithLayers: ReadonlySet<string>;
2414
+ readonly emptyRules: readonly RuleEntity[];
2415
+ readonly emptyKeyframes: readonly AtRuleEntity[];
2416
+ readonly overqualifiedSelectors: readonly SelectorEntity[];
2417
+ readonly deepNestedRules: readonly RuleEntity[];
2418
+ declarationsForProperties(...properties: string[]): readonly DeclarationEntity[];
2259
2419
  }
2260
- interface FontFaceDescriptor {
2261
- readonly fontFace: AtRuleEntity;
2262
- readonly family: string;
2263
- readonly displayDeclaration: DeclarationEntity | null;
2264
- readonly srcDeclaration: DeclarationEntity | null;
2265
- readonly display: string | null;
2266
- readonly src: string | null;
2267
- readonly hasWebFontSource: boolean;
2268
- readonly hasEffectiveMetricOverrides: boolean;
2269
- }
2270
- declare class CSSGraph {
2420
+
2421
+ interface CSSSyntaxTree {
2271
2422
  readonly kind: "css";
2423
+ readonly filePath: string;
2424
+ readonly version: string;
2425
+ readonly isScss: boolean;
2426
+ readonly file: FileEntity;
2427
+ readonly rules: readonly RuleEntity[];
2428
+ readonly selectors: readonly SelectorEntity[];
2429
+ readonly declarations: readonly DeclarationEntity[];
2430
+ readonly variables: readonly VariableEntity[];
2431
+ readonly variableRefs: readonly VariableReferenceEntity[];
2432
+ readonly atRules: readonly AtRuleEntity[];
2433
+ readonly tokens: readonly ThemeTokenEntity[];
2434
+ readonly mixins: readonly MixinEntity[];
2435
+ readonly includes: readonly MixinIncludeEntity[];
2436
+ readonly functions: readonly SCSSFunctionEntity[];
2437
+ readonly functionCalls: readonly FunctionCallEntity[];
2438
+ readonly placeholders: readonly PlaceholderEntity[];
2439
+ readonly extends: readonly ExtendEntity[];
2440
+ readonly parseErrors: readonly CSSParseError[];
2441
+ readonly unresolvedRefs: readonly VariableReferenceEntity[];
2442
+ readonly unresolvedMixinIncludes: readonly MixinIncludeEntity[];
2443
+ readonly unresolvedExtends: readonly ExtendEntity[];
2444
+ readonly rulesBySelector: ReadonlyMap<string, readonly RuleEntity[]>;
2445
+ readonly rulesByNode: ReadonlyMap<Rule, RuleEntity>;
2446
+ readonly variablesByName: ReadonlyMap<string, readonly VariableEntity[]>;
2447
+ readonly declarationsByProperty: ReadonlyMap<string, readonly DeclarationEntity[]>;
2448
+ readonly atRulesByName: ReadonlyMap<string, readonly AtRuleEntity[]>;
2449
+ readonly atRulesByKind: ReadonlyMap<AtRuleKind, readonly AtRuleEntity[]>;
2450
+ readonly atRulesByNode: ReadonlyMap<AtRule, AtRuleEntity>;
2451
+ readonly classNameIndex: ReadonlyMap<string, readonly SelectorEntity[]>;
2452
+ readonly selectorsBySubjectTag: ReadonlyMap<string, readonly SelectorEntity[]>;
2453
+ readonly selectorsByPseudoClass: ReadonlyMap<string, readonly SelectorEntity[]>;
2454
+ readonly selectorsWithoutSubjectTag: readonly SelectorEntity[];
2455
+ readonly filesByPath: ReadonlyMap<string, FileEntity>;
2456
+ readonly sourceOrderBase: number;
2457
+ }
2458
+
2459
+ /**
2460
+ * CSSBuildContext — mutable accumulator for CSS analysis phases.
2461
+ *
2462
+ * Replaces the CSSGraph class. Phases call add* methods to populate entities.
2463
+ * After all phases complete, buildDerivedIndexes() is called, then the context
2464
+ * is frozen into CSSSyntaxTree[] + CSSWorkspaceView.
2465
+ */
2466
+
2467
+ interface CSSBuildContext {
2272
2468
  readonly options: CSSOptions;
2273
2469
  readonly interner: StringInterner;
2274
2470
  readonly logger: Logger;
2471
+ readonly tailwind: TailwindValidator | null;
2275
2472
  sourceOrder: number;
2276
2473
  hasScssFiles: boolean;
2277
2474
  readonly files: FileEntity[];
@@ -2291,7 +2488,6 @@ declare class CSSGraph {
2291
2488
  readonly filesByPath: Map<string, FileEntity>;
2292
2489
  readonly variablesByName: Map<string, VariableEntity[]>;
2293
2490
  readonly rulesBySelector: Map<string, RuleEntity[]>;
2294
- /** @internal Dedup index keyed by file+parent+selector+media+layer for duplicate detection. */
2295
2491
  readonly _selectorDedupIndex: Map<string, RuleEntity[]>;
2296
2492
  readonly mixinsByName: Map<string, MixinEntity>;
2297
2493
  readonly functionsByName: Map<string, SCSSFunctionEntity>;
@@ -2327,27 +2523,7 @@ declare class CSSGraph {
2327
2523
  readonly parseErrors: CSSParseError[];
2328
2524
  readonly failedFilePaths: string[];
2329
2525
  readonly tokenCategories: TokenCategory[];
2330
- private _filesWithLayers;
2331
- get filesWithLayers(): ReadonlySet<string>;
2332
2526
  readonly selectorsByPseudoClass: Map<string, SelectorEntity[]>;
2333
- readonly knownKeyframeNames: Set<string>;
2334
- readonly unresolvedAnimationRefs: UnresolvedAnimationRef[];
2335
- readonly declaredContainerNames: Map<string, DeclarationEntity[]>;
2336
- readonly containerQueryNames: Map<string, AtRuleEntity[]>;
2337
- readonly unusedContainerNames: Map<string, DeclarationEntity[]>;
2338
- readonly unknownContainerQueries: AtRuleEntity[];
2339
- /** Properties with 2+ declarations, each value pre-sorted by sourceOrder. */
2340
- readonly multiDeclarationProperties: Map<string, readonly DeclarationEntity[]>;
2341
- /** Declarations whose parent rule is inside a @keyframes block. */
2342
- readonly keyframeDeclarations: DeclarationEntity[];
2343
- /** Rules with zero declarations, zero nested rules, and zero nested at-rules. */
2344
- private _emptyRules;
2345
- get emptyRules(): readonly RuleEntity[];
2346
- /** @keyframes at-rules with no effective keyframe declarations. */
2347
- private _emptyKeyframes;
2348
- get emptyKeyframes(): readonly AtRuleEntity[];
2349
- private _overqualifiedSelectors;
2350
- get overqualifiedSelectors(): readonly SelectorEntity[];
2351
2527
  readonly idSelectors: SelectorEntity[];
2352
2528
  readonly attributeSelectors: SelectorEntity[];
2353
2529
  readonly universalSelectors: SelectorEntity[];
@@ -2356,17 +2532,19 @@ declare class CSSGraph {
2356
2532
  readonly selectorsWithoutSubjectTag: SelectorEntity[];
2357
2533
  readonly selectorsTargetingCheckbox: SelectorEntity[];
2358
2534
  readonly selectorsTargetingTableCell: SelectorEntity[];
2535
+ readonly knownKeyframeNames: Set<string>;
2536
+ readonly unresolvedAnimationRefs: UnresolvedAnimationRef[];
2537
+ readonly declaredContainerNames: Map<string, DeclarationEntity[]>;
2538
+ readonly containerQueryNames: Map<string, AtRuleEntity[]>;
2539
+ readonly unusedContainerNames: Map<string, DeclarationEntity[]>;
2540
+ readonly unknownContainerQueries: AtRuleEntity[];
2541
+ readonly multiDeclarationProperties: Map<string, readonly DeclarationEntity[]>;
2542
+ readonly keyframeDeclarations: DeclarationEntity[];
2359
2543
  readonly layoutPropertiesByClassToken: Map<string, readonly string[]>;
2360
- readonly keyframeLayoutMutationsByName: Map<string, readonly KeyframeLayoutMutation[]>;
2544
+ readonly keyframeLayoutMutationsByName: Map<string, readonly KeyframeLayoutMutation$1[]>;
2361
2545
  readonly fontFaceDescriptorsByFamily: Map<string, readonly FontFaceDescriptor[]>;
2362
2546
  readonly usedFontFamiliesByRule: Map<number, readonly string[]>;
2363
2547
  readonly usedFontFamilies: Set<string>;
2364
- /** Tailwind validator for utility class lookup (null if not a Tailwind project). */
2365
- readonly tailwind: TailwindValidator | null;
2366
- private _deepNestedRules;
2367
- get deepNestedRules(): readonly RuleEntity[];
2368
- constructor(input: CSSInput);
2369
- intern(s: string): string;
2370
2548
  nextFileId(): number;
2371
2549
  nextRuleId(): number;
2372
2550
  nextSelectorId(): number;
@@ -2382,6 +2560,7 @@ declare class CSSGraph {
2382
2560
  nextPlaceholderId(): number;
2383
2561
  nextExtendId(): number;
2384
2562
  nextSourceOrder(): number;
2563
+ intern(s: string): string;
2385
2564
  addFile(file: FileEntity): void;
2386
2565
  addRule(rule: RuleEntity): void;
2387
2566
  addSelector(selector: SelectorEntity): void;
@@ -2400,197 +2579,647 @@ declare class CSSGraph {
2400
2579
  addFailedFile(path: string): void;
2401
2580
  registerRuleBySelector(selector: string, rule: RuleEntity): void;
2402
2581
  registerLayerOrder(name: string, order: number): void;
2403
- /**
2404
- * Retrieve declarations matching any of the given property names.
2405
- * Uses the pre-built declarationsByProperty index for O(k) lookups.
2406
- */
2407
2582
  declarationsForProperties(...properties: string[]): readonly DeclarationEntity[];
2408
- /**
2409
- * Build derived indexes that require all entities to be populated.
2410
- * Called after all phases complete.
2411
- */
2412
2583
  buildDerivedIndexes(): void;
2413
- private buildContainingMediaStacks;
2414
- private buildKeyframeIndexes;
2415
- private buildContainerNameIndexes;
2416
- /**
2417
- * Sort each declarationsByProperty list by sourceOrder and populate
2418
- * multiDeclarationProperties with only those having 2+ entries.
2419
- */
2420
- private buildMultiDeclarationProperties;
2421
- private buildLayoutPropertiesByClassToken;
2422
- private buildFontIndexes;
2423
2584
  buildUnusedIndexes(): void;
2585
+ readonly filesWithLayers: ReadonlySet<string>;
2586
+ readonly emptyRules: readonly RuleEntity[];
2587
+ readonly emptyKeyframes: readonly AtRuleEntity[];
2588
+ readonly overqualifiedSelectors: readonly SelectorEntity[];
2589
+ readonly deepNestedRules: readonly RuleEntity[];
2424
2590
  }
2425
2591
 
2426
- interface ReservoirSampler {
2427
- readonly buffer: number[];
2428
- count: number;
2429
- readonly capacity: number;
2430
- }
2431
- interface LayoutPerfStatsMutable {
2432
- elementsScanned: number;
2433
- selectorCandidatesChecked: number;
2434
- compiledSelectorCount: number;
2435
- selectorsRejectedUnsupported: number;
2436
- selectorsGuardedConditional: number;
2437
- ancestryChecks: number;
2438
- matchEdgesCreated: number;
2439
- casesScored: number;
2440
- casesCollected: number;
2441
- casesRejectedLowEvidence: number;
2442
- casesRejectedThreshold: number;
2443
- casesRejectedUndecidable: number;
2444
- casesRejectedIdentifiability: number;
2445
- undecidableInterval: number;
2446
- conditionalSignals: number;
2447
- totalSignals: number;
2448
- cohortUnimodalFalse: number;
2449
- factorCoverageSum: number;
2450
- factorCoverageCount: number;
2451
- posteriorWidths: ReservoirSampler;
2452
- uncertaintyEscalations: number;
2453
- signalSnapshotsBuilt: number;
2454
- signalSnapshotCacheHits: number;
2455
- measurementIndexHits: number;
2456
- contextsClassified: number;
2457
- diagnosticsEmitted: number;
2458
- selectorIndexMs: number;
2459
- selectorMatchMs: number;
2460
- cascadeBuildMs: number;
2461
- caseBuildMs: number;
2462
- scoringMs: number;
2463
- elapsedMs: number;
2592
+ interface UnresolvedAnimationRef {
2593
+ readonly declaration: DeclarationEntity;
2594
+ readonly name: string;
2464
2595
  }
2465
-
2466
- type LayoutAxisModel = "horizontal-tb" | "vertical-rl" | "vertical-lr";
2467
- type InlineDirectionModel = "ltr" | "rtl";
2468
- type AlignmentContextKind = "inline-formatting" | "table-cell" | "flex-cross-axis" | "grid-cross-axis" | "block-flow" | "positioned-offset";
2469
- type LayoutContextContainerKind = "table" | "flex" | "grid" | "inline" | "block";
2470
- declare const enum ContextCertainty {
2471
- Resolved = 0,
2472
- Conditional = 1,
2473
- Unknown = 2
2596
+ interface KeyframeLayoutMutation$1 {
2597
+ readonly property: string;
2598
+ readonly values: readonly string[];
2599
+ readonly declarations: readonly DeclarationEntity[];
2600
+ }
2601
+ interface FontFaceDescriptor {
2602
+ readonly fontFace: AtRuleEntity;
2603
+ readonly family: string;
2604
+ readonly displayDeclaration: DeclarationEntity | null;
2605
+ readonly srcDeclaration: DeclarationEntity | null;
2606
+ readonly display: string | null;
2607
+ readonly src: string | null;
2608
+ readonly hasWebFontSource: boolean;
2609
+ readonly hasEffectiveMetricOverrides: boolean;
2610
+ }
2611
+ interface CSSBuildResult {
2612
+ readonly trees: readonly CSSSyntaxTree[];
2613
+ readonly workspace: CSSWorkspaceView;
2474
2614
  }
2615
+ declare function buildCSSResult(input: CSSInput): CSSBuildResult;
2616
+
2617
+ /**
2618
+ * Library Analysis — Extracts CSS custom properties provided by installed dependencies.
2619
+ *
2620
+ * Scans dependency packages for CSS custom property definitions injected at runtime
2621
+ * via JavaScript (e.g., inline style attributes in JSX). This enables the resolution
2622
+ * engine to treat library-provided properties as defined rather than flagging them
2623
+ * as unresolved.
2624
+ *
2625
+ * Architecture:
2626
+ * 1. Receive dependency names from WorkspaceLayout (single source of truth)
2627
+ * 2. For each dependency, scan its dist/source files for CSS custom property patterns
2628
+ * 3. Return discovered properties as a synthetic CSS `:root` declaration block
2629
+ * 4. The caller feeds this into the normal CSS parsing pipeline as an additional file
2630
+ *
2631
+ * The scanner detects properties set via:
2632
+ * - JSX style object keys: `"--kb-accordion-content-height": value`
2633
+ * - style.setProperty calls: `style.setProperty("--kb-accordion-content-height", ...)`
2634
+ * - CSS-in-JS template literals with custom property definitions
2635
+ */
2636
+
2475
2637
  /**
2476
- * Whether the CSS formatting context consults baselines for vertical positioning.
2638
+ * Scan installed dependencies for CSS custom properties they inject at runtime.
2477
2639
  *
2478
- * - `"relevant"`: Baselines participate in alignment (e.g. flex `align-items: baseline`,
2479
- * table-cell `vertical-align: baseline`, inline formatting context).
2480
- * - `"irrelevant"`: The alignment model is purely geometric; baselines are never
2481
- * consulted (e.g. flex `align-items: center`, table-cell `vertical-align: middle`
2482
- * with uniform cohort agreement).
2640
+ * Receives dependency names from WorkspaceLayout instead of re-reading
2641
+ * package.json files. Uses layout.root for node_modules resolution.
2483
2642
  *
2484
- * Computed once at context construction for flex/grid (parent-level data suffices).
2485
- * For table-cell contexts, finalized after cohort aggregation when the cohort's
2486
- * vertical-align consensus is known.
2643
+ * @param layout - Workspace layout with pre-resolved dependency names
2644
+ * @returns Set of CSS custom property names (e.g., "--kb-accordion-content-height")
2645
+ */
2646
+ declare function scanDependencyCustomProperties(layout: WorkspaceLayout): ReadonlySet<string>;
2647
+
2648
+ /**
2649
+ * Accessibility Policy Templates
2487
2650
  *
2488
- * CSS spec references:
2489
- * - Flex: CSS Flexbox §8.3, §9.6 `center` aligns by margin box center, not baselines.
2490
- * - Grid: CSS Grid §10.6 — analogous to flex.
2491
- * - Table: CSS2 §17.5.3 — `middle` centers cell content geometrically.
2651
+ * Predefined bundles of sizing, spacing, and contrast constraints
2652
+ * derived from WCAG 2.2, Material Design 3, Apple HIG, and
2653
+ * W3C Low Vision Needs.
2492
2654
  */
2493
- type BaselineRelevance = "relevant" | "irrelevant";
2494
- interface LayoutContextEvidence {
2495
- readonly containerKind: LayoutContextContainerKind;
2496
- readonly containerKindCertainty: ContextCertainty;
2497
- readonly hasTableSemantics: boolean;
2498
- readonly hasPositionedOffset: boolean;
2499
- readonly positionedOffsetCertainty: ContextCertainty;
2500
- }
2501
- interface AlignmentContext {
2502
- readonly kind: AlignmentContextKind;
2503
- readonly certainty: ContextCertainty;
2504
- readonly parentSolidFile: string;
2505
- readonly parentElementId: number;
2506
- readonly parentElementKey: string;
2507
- readonly parentTag: string | null;
2508
- readonly axis: LayoutAxisModel;
2509
- readonly axisCertainty: ContextCertainty;
2510
- readonly inlineDirection: InlineDirectionModel;
2511
- readonly inlineDirectionCertainty: ContextCertainty;
2512
- readonly parentDisplay: string | null;
2513
- readonly parentAlignItems: string | null;
2514
- readonly parentPlaceItems: string | null;
2515
- readonly hasPositionedOffset: boolean;
2516
- /**
2517
- * Whether the layout container's cross axis aligns with the document's
2518
- * block axis. When `true`, vertical sibling offset differences represent
2519
- * genuine alignment issues. When `false`, the block axis is the container's
2520
- * main axis — vertical positioning is controlled by the layout algorithm
2521
- * (gap, justify-content), and offset evidence should be suppressed.
2522
- *
2523
- * For non-flex/grid contexts (block flow, inline formatting, table-cell),
2524
- * this is always `true`.
2525
- */
2526
- readonly crossAxisIsBlockAxis: boolean;
2527
- readonly crossAxisIsBlockAxisCertainty: ContextCertainty;
2528
- readonly baselineRelevance: BaselineRelevance;
2529
- readonly evidence: LayoutContextEvidence;
2530
- }
2531
2655
 
2532
- declare const layoutSignalNames: readonly ["line-height", "font-size", "width", "inline-size", "height", "block-size", "min-width", "min-block-size", "min-height", "max-width", "max-height", "aspect-ratio", "vertical-align", "display", "white-space", "object-fit", "overflow", "overflow-y", "overflow-anchor", "scrollbar-gutter", "scrollbar-width", "contain-intrinsic-size", "content-visibility", "align-items", "align-self", "justify-items", "place-items", "place-self", "flex-direction", "flex-basis", "grid-auto-flow", "appearance", "box-sizing", "padding-top", "padding-left", "padding-right", "padding-bottom", "border-top-width", "border-left-width", "border-right-width", "border-bottom-width", "position", "top", "bottom", "margin-top", "margin-bottom", "transform", "translate", "inset-block-start", "inset-block-end", "writing-mode", "direction", "contain"];
2533
- type LayoutSignalName = (typeof layoutSignalNames)[number];
2534
- declare const enum LayoutSignalSource {
2535
- Selector = 0,
2536
- InlineStyle = 1
2656
+ /** Set the active policy for all policy rules. Pass null to disable. */
2657
+ declare function setActivePolicy(name: string | null): void;
2658
+
2659
+ interface TailwindSymbolContribution {
2660
+ readonly classNames: ReadonlyMap<string, ClassNameSymbol>;
2537
2661
  }
2538
- declare const enum LayoutSignalGuard {
2539
- Unconditional = 0,
2662
+ interface TailwindParsedCandidate {
2663
+ readonly raw: string;
2664
+ readonly variants: readonly TailwindParsedVariant[];
2665
+ readonly utility: string;
2666
+ readonly value: TailwindCandidateValue | null;
2667
+ readonly modifier: TailwindCandidateModifier | null;
2668
+ readonly important: boolean;
2669
+ readonly negative: boolean;
2670
+ }
2671
+ interface TailwindParsedVariant {
2672
+ readonly name: string;
2673
+ readonly kind: "static" | "functional" | "compound" | "arbitrary";
2674
+ readonly value: string | null;
2675
+ readonly modifier: string | null;
2676
+ }
2677
+ interface TailwindCandidateValue {
2678
+ readonly kind: "named" | "arbitrary" | "fraction";
2679
+ readonly value: string;
2680
+ readonly dashedIdent: string | null;
2681
+ }
2682
+ interface TailwindCandidateModifier {
2683
+ readonly kind: "named" | "arbitrary";
2684
+ readonly value: string;
2685
+ }
2686
+ interface TailwindResolvedDeclaration {
2687
+ readonly property: string;
2688
+ readonly value: string;
2689
+ }
2690
+ type TailwindCandidateDiagnostic = {
2691
+ readonly kind: "unknown-utility";
2692
+ readonly utility: string;
2693
+ } | {
2694
+ readonly kind: "invalid-variant";
2695
+ readonly variant: string;
2696
+ } | {
2697
+ readonly kind: "theme-token-not-found";
2698
+ readonly token: string;
2699
+ } | {
2700
+ readonly kind: "invalid-arbitrary-value";
2701
+ readonly value: string;
2702
+ } | {
2703
+ readonly kind: "incompatible-compound-variant";
2704
+ readonly variant: string;
2705
+ readonly parent: string;
2706
+ };
2707
+ type TailwindCandidateResult = {
2708
+ readonly valid: true;
2709
+ readonly candidate: TailwindParsedCandidate;
2710
+ readonly symbol: ClassNameSymbol;
2711
+ } | {
2712
+ readonly valid: false;
2713
+ readonly diagnostics: readonly TailwindCandidateDiagnostic[];
2714
+ };
2715
+ interface TailwindResolution {
2716
+ readonly candidate: TailwindParsedCandidate;
2717
+ readonly css: string;
2718
+ readonly declarations: readonly TailwindResolvedDeclaration[];
2719
+ }
2720
+ interface TailwindVariantInfo {
2721
+ readonly name: string;
2722
+ readonly kind: "static" | "functional" | "compound" | "arbitrary";
2723
+ readonly values: readonly string[];
2724
+ readonly hasDash: boolean;
2725
+ readonly isArbitrary: boolean;
2726
+ readonly order: number;
2727
+ }
2728
+ interface TailwindDesignSystem {
2729
+ candidatesToCss(classes: string[]): (string | null)[];
2730
+ getClassList(): [string, {
2731
+ modifiers: string[];
2732
+ }][];
2733
+ getVariants(): {
2734
+ name: string;
2735
+ values: string[];
2736
+ hasDash: boolean;
2737
+ isArbitrary: boolean;
2738
+ }[];
2739
+ }
2740
+ interface TailwindProvider {
2741
+ readonly kind: "tailwind";
2742
+ readonly designSystem: TailwindDesignSystem;
2743
+ parseCandidate(candidate: string): TailwindCandidateResult;
2744
+ has(className: string): boolean;
2745
+ resolve(className: string): TailwindResolution | null;
2746
+ getUtilitySymbols(): TailwindSymbolContribution;
2747
+ getVariants(): readonly TailwindVariantInfo[];
2748
+ }
2749
+
2750
+ interface CSSClassNameSource {
2751
+ readonly kind: "css";
2752
+ readonly selectors: readonly SelectorEntity[];
2753
+ readonly filePaths: readonly string[];
2754
+ }
2755
+ interface TailwindClassNameSource {
2756
+ readonly kind: "tailwind";
2757
+ readonly candidate: TailwindParsedCandidate;
2758
+ readonly resolvedCSS: string | null;
2759
+ readonly declarations: readonly TailwindResolvedDeclaration[];
2760
+ readonly diagnostics: readonly TailwindCandidateDiagnostic[];
2761
+ }
2762
+ type ClassNameSource = CSSClassNameSource | TailwindClassNameSource;
2763
+ interface ClassNameSymbol {
2764
+ readonly symbolKind: "className";
2765
+ readonly name: string;
2766
+ readonly filePath: string | null;
2767
+ readonly source: ClassNameSource;
2768
+ }
2769
+
2770
+ /**
2771
+ * Selector symbol + compiled matcher.
2772
+ *
2773
+ * compileSelectorMatcher moved from cross-file/layout/selector-match.ts.
2774
+ */
2775
+
2776
+ interface CompoundPseudoConstraints {
2777
+ readonly firstChild: boolean;
2778
+ readonly lastChild: boolean;
2779
+ readonly onlyChild: boolean;
2780
+ readonly nthChild: NthPattern | null;
2781
+ readonly nthLastChild: NthPattern | null;
2782
+ readonly nthOfType: NthPattern | null;
2783
+ readonly nthLastOfType: NthPattern | null;
2784
+ readonly anyOfGroups: readonly (readonly CompiledSelectorCompound[])[];
2785
+ readonly noneOfGroups: readonly (readonly CompiledSelectorCompound[])[];
2786
+ }
2787
+ interface CompiledSelectorCompound {
2788
+ readonly tagName: string | null;
2789
+ readonly idValue: string | null;
2790
+ readonly classes: readonly string[];
2791
+ readonly attributes: readonly SelectorAttributeConstraint[];
2792
+ readonly pseudo: CompoundPseudoConstraints;
2793
+ }
2794
+ interface SelectorSubjectConstraintSummary {
2795
+ readonly idValue: string | null;
2796
+ readonly classes: readonly string[];
2797
+ readonly attributeNames: readonly string[];
2798
+ readonly hasStructuralPseudo: boolean;
2799
+ }
2800
+ interface SelectorFeatureRequirements {
2801
+ readonly needsClassTokens: boolean;
2802
+ readonly needsAttributes: boolean;
2803
+ }
2804
+ interface CompiledSelectorMatcher {
2805
+ readonly subjectTag: string | null;
2806
+ readonly subject: SelectorSubjectConstraintSummary;
2807
+ readonly requirements: SelectorFeatureRequirements;
2808
+ readonly compoundsRightToLeft: readonly CompiledSelectorCompound[];
2809
+ readonly combinatorsRightToLeft: readonly CombinatorType[];
2810
+ }
2811
+ interface SelectorSymbol {
2812
+ readonly symbolKind: "selector";
2813
+ readonly name: string;
2814
+ readonly filePath: string | null;
2815
+ readonly entity: SelectorEntity;
2816
+ readonly specificity: readonly [number, number, number];
2817
+ readonly dispatchKeys: readonly string[];
2818
+ readonly compiledMatcher: CompiledSelectorMatcher | null;
2819
+ }
2820
+
2821
+ interface DeclarationSymbol {
2822
+ readonly symbolKind: "declaration";
2823
+ readonly name: string;
2824
+ readonly filePath: string | null;
2825
+ readonly entity: DeclarationEntity;
2826
+ readonly sourceOrder: number;
2827
+ readonly layerOrder: number;
2828
+ }
2829
+
2830
+ interface CustomPropertySymbol {
2831
+ readonly symbolKind: "customProperty";
2832
+ readonly name: string;
2833
+ readonly filePath: string | null;
2834
+ readonly entity: VariableEntity;
2835
+ readonly isGlobal: boolean;
2836
+ readonly isScss: boolean;
2837
+ readonly references: readonly VariableReferenceEntity[];
2838
+ readonly resolvedValue: string | null;
2839
+ }
2840
+
2841
+ interface KeyframeLayoutMutation {
2842
+ readonly property: string;
2843
+ readonly values: readonly string[];
2844
+ readonly declarations: readonly DeclarationEntity[];
2845
+ }
2846
+ interface KeyframesSymbol {
2847
+ readonly symbolKind: "keyframes";
2848
+ readonly name: string;
2849
+ readonly filePath: string | null;
2850
+ readonly entity: AtRuleEntity;
2851
+ readonly layoutMutations: readonly KeyframeLayoutMutation[];
2852
+ }
2853
+
2854
+ interface FontFaceSymbol {
2855
+ readonly symbolKind: "fontFace";
2856
+ readonly name: string;
2857
+ readonly filePath: string | null;
2858
+ readonly entity: AtRuleEntity;
2859
+ readonly family: string;
2860
+ readonly display: string | null;
2861
+ readonly hasWebFontSource: boolean;
2862
+ readonly hasEffectiveMetricOverrides: boolean;
2863
+ }
2864
+
2865
+ interface LayerSymbol {
2866
+ readonly symbolKind: "layer";
2867
+ readonly name: string;
2868
+ readonly filePath: string | null;
2869
+ readonly entity: AtRuleEntity;
2870
+ readonly order: number;
2871
+ }
2872
+
2873
+ interface ContainerSymbol {
2874
+ readonly symbolKind: "container";
2875
+ readonly name: string;
2876
+ readonly filePath: string | null;
2877
+ readonly declarations: readonly DeclarationEntity[];
2878
+ readonly queries: readonly AtRuleEntity[];
2879
+ }
2880
+
2881
+ interface ThemeTokenSymbol {
2882
+ readonly symbolKind: "themeToken";
2883
+ readonly name: string;
2884
+ readonly filePath: string | null;
2885
+ readonly entity: ThemeTokenEntity;
2886
+ readonly category: string;
2887
+ }
2888
+
2889
+ interface ComponentHostSymbol {
2890
+ readonly symbolKind: "componentHost";
2891
+ readonly name: string;
2892
+ readonly filePath: string | null;
2893
+ readonly importSource: string;
2894
+ readonly exportName: string;
2895
+ readonly hostTag: string | null;
2896
+ readonly hostClassTokens: readonly string[];
2897
+ readonly hostAttributes: ReadonlyMap<string, string | null>;
2898
+ readonly resolvedFilePath: string;
2899
+ }
2900
+
2901
+ interface SymbolTable {
2902
+ readonly classNames: ReadonlyMap<string, ClassNameSymbol>;
2903
+ readonly selectors: ReadonlyMap<number, SelectorSymbol>;
2904
+ readonly customProperties: ReadonlyMap<string, CustomPropertySymbol>;
2905
+ readonly componentHosts: ReadonlyMap<string, ComponentHostSymbol>;
2906
+ readonly keyframes: ReadonlyMap<string, KeyframesSymbol>;
2907
+ readonly fontFaces: ReadonlyMap<string, readonly FontFaceSymbol[]>;
2908
+ readonly layers: ReadonlyMap<string, LayerSymbol>;
2909
+ readonly containers: ReadonlyMap<string, ContainerSymbol>;
2910
+ readonly themeTokens: ReadonlyMap<string, ThemeTokenSymbol>;
2911
+ readonly selectorsByDispatchKey: ReadonlyMap<string, readonly SelectorSymbol[]>;
2912
+ readonly selectorsBySubjectTag: ReadonlyMap<string, readonly SelectorSymbol[]>;
2913
+ readonly selectorsWithoutSubjectTag: readonly SelectorSymbol[];
2914
+ readonly declarationsByProperty: ReadonlyMap<string, readonly DeclarationSymbol[]>;
2915
+ declarationsForProperties(...properties: string[]): readonly DeclarationEntity[];
2916
+ readonly duplicateSelectors: ReadonlyMap<string, {
2917
+ readonly selector: string;
2918
+ readonly rules: readonly RuleEntity[];
2919
+ }>;
2920
+ readonly multiDeclarationProperties: ReadonlyMap<string, readonly DeclarationEntity[]>;
2921
+ readonly layoutPropertiesByClassToken: ReadonlyMap<string, readonly string[]>;
2922
+ readonly usedFontFamilies: ReadonlySet<string>;
2923
+ readonly usedFontFamiliesByRule: ReadonlyMap<number, readonly string[]>;
2924
+ readonly idSelectors: readonly SelectorEntity[];
2925
+ readonly attributeSelectors: readonly SelectorEntity[];
2926
+ readonly universalSelectors: readonly SelectorEntity[];
2927
+ readonly selectorsTargetingCheckbox: readonly SelectorEntity[];
2928
+ readonly selectorsTargetingTableCell: readonly SelectorEntity[];
2929
+ readonly importantDeclarations: readonly DeclarationEntity[];
2930
+ readonly emptyRules: readonly RuleEntity[];
2931
+ readonly emptyKeyframes: readonly AtRuleEntity[];
2932
+ readonly deepNestedRules: readonly RuleEntity[];
2933
+ readonly overqualifiedSelectors: readonly SelectorEntity[];
2934
+ readonly unresolvedAnimationRefs: readonly {
2935
+ readonly declaration: DeclarationEntity;
2936
+ readonly name: string;
2937
+ }[];
2938
+ readonly unknownContainerQueries: readonly AtRuleEntity[];
2939
+ readonly unusedContainerNames: ReadonlyMap<string, readonly DeclarationEntity[]>;
2940
+ readonly keyframeDeclarations: readonly DeclarationEntity[];
2941
+ readonly tokensByCategory: ReadonlyMap<string, readonly ThemeTokenEntity[]>;
2942
+ readonly mixinsByName: ReadonlyMap<string, MixinEntity>;
2943
+ readonly functionsByName: ReadonlyMap<string, SCSSFunctionEntity>;
2944
+ readonly placeholdersByName: ReadonlyMap<string, PlaceholderEntity>;
2945
+ readonly unusedVariables: readonly VariableEntity[];
2946
+ readonly unusedKeyframes: readonly AtRuleEntity[];
2947
+ readonly unusedMixins: readonly MixinEntity[];
2948
+ readonly unusedFunctions: readonly SCSSFunctionEntity[];
2949
+ readonly unusedPlaceholders: readonly PlaceholderEntity[];
2950
+ readonly tokenCategories: readonly string[];
2951
+ hasClassName(name: string): boolean;
2952
+ getClassName(name: string): ClassNameSymbol | null;
2953
+ getSelectorsByClassName(name: string): readonly SelectorSymbol[];
2954
+ getCustomProperty(name: string): CustomPropertySymbol | null;
2955
+ getKeyframes(name: string): KeyframesSymbol | null;
2956
+ getFontFaces(family: string): readonly FontFaceSymbol[];
2957
+ getLayerOrder(name: string): number;
2958
+ }
2959
+
2960
+ type DependencyEdgeKind = "js-import" | "css-import" | "css-at-import" | "colocated" | "global-side-effect";
2961
+ interface DependencyEdgeInfo {
2962
+ readonly target: string;
2963
+ readonly kind: DependencyEdgeKind;
2964
+ }
2965
+ interface ComponentImportEdge {
2966
+ readonly importerFile: string;
2967
+ readonly importedName: string;
2968
+ }
2969
+ interface DependencyGraph {
2970
+ getDirectDependencies(filePath: string): readonly DependencyEdgeInfo[];
2971
+ getReverseDependencies(filePath: string): readonly string[];
2972
+ getCSSScope(solidFilePath: string): readonly string[];
2973
+ getComponentImporters(solidFilePath: string): readonly ComponentImportEdge[];
2974
+ getTransitivelyAffected(filePath: string): readonly string[];
2975
+ isInCSSScope(solidFilePath: string, cssFilePath: string): boolean;
2976
+ }
2977
+
2978
+ /**
2979
+ * Scoped selector index type + construction (Phase 6 adds buildScopedSelectorIndex).
2980
+ */
2981
+
2982
+ interface ScopedSelectorIndex {
2983
+ readonly byDispatchKey: ReadonlyMap<string, readonly SelectorSymbol[]>;
2984
+ readonly byTagName: ReadonlyMap<string, readonly SelectorSymbol[]>;
2985
+ readonly requirements: {
2986
+ readonly needsClassTokens: boolean;
2987
+ readonly needsAttributes: boolean;
2988
+ };
2989
+ }
2990
+
2991
+ /**
2992
+ * Layout fact types + computation from signal snapshots.
2993
+ *
2994
+ * Moved from cross-file/layout/build.ts steps 6-7.
2995
+ */
2996
+
2997
+ type LayoutFactKind = "reservedSpace" | "scrollContainer" | "flowParticipation" | "containingBlock";
2998
+ interface LayoutFactMap {
2999
+ reservedSpace: ReservedSpaceFact;
3000
+ scrollContainer: ScrollContainerFact;
3001
+ flowParticipation: FlowParticipationFact;
3002
+ containingBlock: ContainingBlockFact;
3003
+ }
3004
+ interface ReservedSpaceFact {
3005
+ readonly hasReservedSpace: boolean;
3006
+ readonly reasons: readonly string[];
3007
+ readonly hasContainIntrinsicSize: boolean;
3008
+ readonly hasUsableAspectRatio: boolean;
3009
+ readonly hasDeclaredInlineDimension: boolean;
3010
+ readonly hasDeclaredBlockDimension: boolean;
3011
+ }
3012
+ interface ScrollContainerFact {
3013
+ readonly isScrollContainer: boolean;
3014
+ readonly axis: number;
3015
+ readonly overflow: string | null;
3016
+ readonly overflowY: string | null;
3017
+ readonly hasConditionalScroll: boolean;
3018
+ readonly hasUnconditionalScroll: boolean;
3019
+ }
3020
+ interface FlowParticipationFact {
3021
+ readonly inFlow: boolean;
3022
+ readonly position: string | null;
3023
+ readonly hasConditionalOutOfFlow: boolean;
3024
+ readonly hasUnconditionalOutOfFlow: boolean;
3025
+ }
3026
+ interface ContainingBlockFact {
3027
+ readonly nearestPositionedAncestorKey: string | null;
3028
+ readonly nearestPositionedAncestorHasReservedSpace: boolean;
3029
+ }
3030
+
3031
+ /**
3032
+ * Cascade binding types + lazy per-element cascade resolution.
3033
+ *
3034
+ * Moved from cross-file/layout/cascade-builder.ts + selector-match.ts matching.
3035
+ */
3036
+
3037
+ declare const enum SignalSource {
3038
+ Selector = 0,
3039
+ InlineStyle = 1
3040
+ }
3041
+ declare const enum SignalGuardKind {
3042
+ Unconditional = 0,
2540
3043
  Conditional = 1
2541
3044
  }
2542
- declare const enum LayoutSignalUnit {
2543
- Px = 0,
2544
- Unitless = 1,
2545
- Keyword = 2,
2546
- Unknown = 3
3045
+ type GuardConditionKind = "media" | "supports" | "container" | "dynamic-attribute";
3046
+ interface GuardConditionProvenance {
3047
+ readonly kind: GuardConditionKind;
3048
+ readonly query: string | null;
3049
+ readonly key: string;
3050
+ }
3051
+ type RuleGuard = {
3052
+ readonly kind: SignalGuardKind.Unconditional;
3053
+ readonly conditions: readonly GuardConditionProvenance[];
3054
+ readonly key: "always";
3055
+ } | {
3056
+ readonly kind: SignalGuardKind.Conditional;
3057
+ readonly conditions: readonly GuardConditionProvenance[];
3058
+ readonly key: string;
3059
+ };
3060
+ interface CascadedDeclaration {
3061
+ readonly value: string;
3062
+ readonly source: SignalSource;
3063
+ readonly guardProvenance: RuleGuard;
3064
+ }
3065
+ interface SelectorMatch {
3066
+ readonly selectorId: number;
3067
+ readonly specificityScore: number;
3068
+ readonly sourceOrder: number;
3069
+ readonly conditionalMatch: boolean;
2547
3070
  }
3071
+ interface ElementCascade {
3072
+ readonly elementId: number;
3073
+ readonly declarations: ReadonlyMap<string, CascadedDeclaration>;
3074
+ readonly edges: readonly SelectorMatch[];
3075
+ }
3076
+
3077
+ /**
3078
+ * Signal snapshot types + construction.
3079
+ *
3080
+ * Moved from cross-file/layout/signal-normalization.ts + signal-collection.ts.
3081
+ */
3082
+
3083
+ declare const layoutSignalNames: readonly ["line-height", "font-size", "width", "inline-size", "height", "block-size", "min-width", "min-block-size", "min-height", "max-width", "max-height", "aspect-ratio", "vertical-align", "display", "white-space", "object-fit", "overflow", "overflow-y", "overflow-anchor", "scrollbar-gutter", "scrollbar-width", "contain-intrinsic-size", "content-visibility", "align-items", "align-self", "justify-items", "place-items", "place-self", "flex-direction", "flex-basis", "grid-auto-flow", "appearance", "box-sizing", "padding-top", "padding-left", "padding-right", "padding-bottom", "border-top-width", "border-left-width", "border-right-width", "border-bottom-width", "position", "top", "bottom", "margin-top", "margin-bottom", "transform", "translate", "inset-block-start", "inset-block-end", "writing-mode", "direction", "contain"];
3084
+ type LayoutSignalName = (typeof layoutSignalNames)[number];
2548
3085
  declare const enum SignalValueKind {
2549
3086
  Known = 0,
2550
3087
  Unknown = 1
2551
3088
  }
3089
+ declare const enum SignalUnit {
3090
+ Px = 0,
3091
+ Unitless = 1,
3092
+ Keyword = 2,
3093
+ Unknown = 3
3094
+ }
2552
3095
  declare const enum SignalQuality {
2553
3096
  Exact = 0,
2554
3097
  Estimated = 1
2555
3098
  }
2556
- interface LayoutKnownSignalValue {
3099
+ interface KnownSignalValue {
2557
3100
  readonly kind: SignalValueKind.Known;
2558
3101
  readonly name: LayoutSignalName;
2559
3102
  readonly normalized: string;
2560
- readonly source: LayoutSignalSource;
2561
- readonly guard: LayoutRuleGuard;
2562
- readonly unit: LayoutSignalUnit;
3103
+ readonly source: SignalSource;
3104
+ readonly guard: RuleGuard;
3105
+ readonly unit: SignalUnit;
2563
3106
  readonly px: number | null;
2564
3107
  readonly quality: SignalQuality;
2565
3108
  }
2566
- interface LayoutUnknownSignalValue {
3109
+ interface UnknownSignalValue {
2567
3110
  readonly kind: SignalValueKind.Unknown;
2568
3111
  readonly name: LayoutSignalName;
2569
- readonly source: LayoutSignalSource | null;
2570
- readonly guard: LayoutRuleGuard;
3112
+ readonly source: SignalSource | null;
3113
+ readonly guard: RuleGuard;
2571
3114
  readonly reason: string;
2572
3115
  }
2573
- type LayoutSignalValue = LayoutKnownSignalValue | LayoutUnknownSignalValue;
2574
- declare const enum LayoutTextualContentState {
3116
+ type SignalValue = KnownSignalValue | UnknownSignalValue;
3117
+ interface SignalSnapshot {
3118
+ readonly elementId: number;
3119
+ readonly signals: ReadonlyMap<LayoutSignalName, SignalValue>;
3120
+ readonly knownSignalCount: number;
3121
+ readonly unknownSignalCount: number;
3122
+ readonly conditionalSignalCount: number;
3123
+ }
3124
+ declare const enum TextualContentState {
2575
3125
  Yes = 0,
2576
3126
  No = 1,
2577
3127
  Unknown = 2,
2578
3128
  DynamicText = 3
2579
3129
  }
2580
- interface LayoutSignalSnapshot {
2581
- readonly node: LayoutElementNode;
2582
- readonly signals: ReadonlyMap<LayoutSignalName, LayoutSignalValue>;
2583
- readonly knownSignalCount: number;
2584
- readonly unknownSignalCount: number;
2585
- readonly conditionalSignalCount: number;
2586
- }
2587
- interface AlignmentElementEvidence {
3130
+
3131
+ interface ElementNode {
3132
+ readonly key: string;
2588
3133
  readonly solidFile: string;
2589
- readonly elementKey: string;
2590
3134
  readonly elementId: number;
3135
+ readonly jsxEntity: JSXElementEntity;
2591
3136
  readonly tag: string | null;
2592
- readonly snapshot: LayoutSignalSnapshot;
3137
+ readonly tagName: string | null;
3138
+ readonly classTokens: readonly string[];
3139
+ readonly classTokenSet: ReadonlySet<string>;
3140
+ readonly inlineStyleKeys: readonly string[];
3141
+ readonly parentElementNode: ElementNode | null;
3142
+ readonly childElementNodes: readonly ElementNode[];
3143
+ readonly previousSiblingNode: ElementNode | null;
3144
+ readonly siblingIndex: number;
3145
+ readonly siblingCount: number;
3146
+ readonly siblingTypeIndex: number;
3147
+ readonly siblingTypeCount: number;
3148
+ readonly selectorDispatchKeys: readonly string[];
3149
+ readonly attributes: ReadonlyMap<string, string | null>;
3150
+ readonly inlineStyleValues: ReadonlyMap<string, string>;
3151
+ readonly textualContent: TextualContentState;
3152
+ readonly isControl: boolean;
3153
+ readonly isReplaced: boolean;
3154
+ }
3155
+
3156
+ interface ConditionalSignalDelta {
3157
+ readonly hasConditional: boolean;
3158
+ readonly hasDelta: boolean;
3159
+ readonly conditionalValues: readonly string[];
3160
+ readonly unconditionalValues: readonly string[];
3161
+ readonly hasConditionalScrollValue: boolean;
3162
+ readonly hasConditionalNonScrollValue: boolean;
3163
+ readonly hasUnconditionalScrollValue: boolean;
3164
+ readonly hasUnconditionalNonScrollValue: boolean;
3165
+ }
3166
+
3167
+ /**
3168
+ * Alignment model types + computation.
3169
+ *
3170
+ * Moved from cross-file/layout/context-classification.ts + cohort-index.ts +
3171
+ * measurement-node.ts + content-composition.ts + consistency-domain.ts +
3172
+ * offset.ts + signal-access helpers + util helpers.
3173
+ */
3174
+
3175
+ type AlignmentContextKind = "inline-formatting" | "table-cell" | "flex-cross-axis" | "grid-cross-axis" | "block-flow" | "positioned-offset";
3176
+ type LayoutAxisModel = "horizontal-tb" | "vertical-rl" | "vertical-lr";
3177
+ type InlineDirectionModel = "ltr" | "rtl";
3178
+ type LayoutContextContainerKind = "table" | "flex" | "grid" | "inline" | "block";
3179
+ declare const enum ContextCertainty {
3180
+ Resolved = 0,
3181
+ Conditional = 1,
3182
+ Unknown = 2
3183
+ }
3184
+ type BaselineRelevance = "relevant" | "irrelevant";
3185
+ interface LayoutContextEvidence {
3186
+ readonly containerKind: LayoutContextContainerKind;
3187
+ readonly containerKindCertainty: ContextCertainty;
3188
+ readonly hasTableSemantics: boolean;
3189
+ readonly hasPositionedOffset: boolean;
3190
+ readonly positionedOffsetCertainty: ContextCertainty;
3191
+ }
3192
+ interface AlignmentContext {
3193
+ readonly kind: AlignmentContextKind;
3194
+ readonly certainty: ContextCertainty;
3195
+ readonly parentSolidFile: string;
3196
+ readonly parentElementId: number;
3197
+ readonly parentElementKey: string;
3198
+ readonly parentTag: string | null;
3199
+ readonly axis: LayoutAxisModel;
3200
+ readonly axisCertainty: ContextCertainty;
3201
+ readonly inlineDirection: InlineDirectionModel;
3202
+ readonly inlineDirectionCertainty: ContextCertainty;
3203
+ readonly parentDisplay: string | null;
3204
+ readonly parentAlignItems: string | null;
3205
+ readonly parentPlaceItems: string | null;
3206
+ readonly hasPositionedOffset: boolean;
3207
+ readonly crossAxisIsBlockAxis: boolean;
3208
+ readonly crossAxisIsBlockAxisCertainty: ContextCertainty;
3209
+ readonly baselineRelevance: BaselineRelevance;
3210
+ readonly evidence: LayoutContextEvidence;
3211
+ }
3212
+ declare const enum EvidenceValueKind {
3213
+ Exact = 0,
3214
+ Interval = 1,
3215
+ Conditional = 2,
3216
+ Unknown = 3
3217
+ }
3218
+ interface EvidenceWitness<T> {
3219
+ readonly value: T | null;
3220
+ readonly kind: EvidenceValueKind;
2593
3221
  }
3222
+ type NumericEvidenceValue = EvidenceWitness<number>;
2594
3223
  declare const enum AlignmentTextContrast {
2595
3224
  Different = 0,
2596
3225
  Same = 1,
@@ -2625,19 +3254,37 @@ interface CohortIdentifiability {
2625
3254
  readonly ambiguous: boolean;
2626
3255
  readonly kind: EvidenceValueKind;
2627
3256
  }
2628
- interface AlignmentCohortProfile {
2629
- readonly medianDeclaredOffsetPx: number | null;
2630
- readonly declaredOffsetDispersionPx: number | null;
2631
- readonly medianEffectiveOffsetPx: number | null;
2632
- readonly effectiveOffsetDispersionPx: number | null;
2633
- readonly medianLineHeightPx: number | null;
2634
- readonly lineHeightDispersionPx: number | null;
2635
- readonly dominantClusterSize: number;
2636
- readonly dominantClusterShare: number;
2637
- readonly unimodal: boolean;
3257
+ declare const enum ContentCompositionClassification {
3258
+ TextOnly = 0,
3259
+ ReplacedOnly = 1,
3260
+ MixedUnmitigated = 2,
3261
+ MixedMitigated = 3,
3262
+ BlockSegmented = 4,
3263
+ Unknown = 5
2638
3264
  }
2639
- interface AlignmentCohortFactSummary {
2640
- readonly exact: number;
3265
+ type InlineReplacedKind = "intrinsic" | "container";
3266
+ interface ContentCompositionFingerprint {
3267
+ readonly hasTextContent: boolean;
3268
+ readonly hasInlineReplaced: boolean;
3269
+ readonly inlineReplacedKind: InlineReplacedKind | null;
3270
+ readonly hasHeightContributingDescendant: boolean;
3271
+ readonly wrappingContextMitigates: boolean;
3272
+ readonly hasVerticalAlignMitigation: boolean;
3273
+ readonly mixedContentDepth: number;
3274
+ readonly classification: ContentCompositionClassification;
3275
+ readonly analyzableChildCount: number;
3276
+ readonly totalChildCount: number;
3277
+ readonly hasOnlyBlockChildren: boolean;
3278
+ }
3279
+ interface AlignmentElementEvidence {
3280
+ readonly solidFile: string;
3281
+ readonly elementKey: string;
3282
+ readonly elementId: number;
3283
+ readonly tag: string | null;
3284
+ readonly snapshot: SignalSnapshot;
3285
+ }
3286
+ interface CohortFactSummary {
3287
+ readonly exact: number;
2641
3288
  readonly interval: number;
2642
3289
  readonly unknown: number;
2643
3290
  readonly conditional: number;
@@ -2647,214 +3294,57 @@ interface AlignmentCohortFactSummary {
2647
3294
  readonly unknownShare: number;
2648
3295
  readonly conditionalShare: number;
2649
3296
  }
2650
- interface HotEvidenceWitness<T> extends EvidenceWitness<T> {
2651
- readonly present: boolean;
2652
- }
2653
- type HotNumericSignalEvidence = HotEvidenceWitness<number>;
2654
- type HotNormalizedSignalEvidence = HotEvidenceWitness<string>;
2655
- interface LayoutSnapshotHotSignals {
2656
- readonly lineHeight: HotNumericSignalEvidence;
2657
- readonly verticalAlign: HotNormalizedSignalEvidence;
2658
- readonly alignSelf: HotNormalizedSignalEvidence;
2659
- readonly placeSelf: HotNormalizedSignalEvidence;
2660
- readonly flexDirection: HotNormalizedSignalEvidence;
2661
- readonly gridAutoFlow: HotNormalizedSignalEvidence;
2662
- readonly writingMode: HotNormalizedSignalEvidence;
2663
- readonly direction: HotNormalizedSignalEvidence;
2664
- readonly display: HotNormalizedSignalEvidence;
2665
- readonly alignItems: HotNormalizedSignalEvidence;
2666
- readonly placeItems: HotNormalizedSignalEvidence;
2667
- readonly position: HotNormalizedSignalEvidence;
2668
- readonly insetBlockStart: HotNumericSignalEvidence;
2669
- readonly insetBlockEnd: HotNumericSignalEvidence;
2670
- readonly transform: HotNumericSignalEvidence;
2671
- readonly translate: HotNumericSignalEvidence;
2672
- readonly top: HotNumericSignalEvidence;
2673
- readonly bottom: HotNumericSignalEvidence;
2674
- readonly marginTop: HotNumericSignalEvidence;
2675
- readonly marginBottom: HotNumericSignalEvidence;
2676
- }
2677
- interface LayoutCohortSubjectStats {
3297
+ interface EvidenceProvenance {
3298
+ readonly reason: string;
3299
+ readonly guardKey: string;
3300
+ readonly guards: readonly GuardConditionProvenance[];
3301
+ }
3302
+ interface CohortProfile {
3303
+ readonly medianDeclaredOffsetPx: number | null;
3304
+ readonly declaredOffsetDispersionPx: number | null;
3305
+ readonly medianEffectiveOffsetPx: number | null;
3306
+ readonly effectiveOffsetDispersionPx: number | null;
3307
+ readonly medianLineHeightPx: number | null;
3308
+ readonly lineHeightDispersionPx: number | null;
3309
+ readonly dominantClusterSize: number;
3310
+ readonly dominantClusterShare: number;
3311
+ readonly unimodal: boolean;
3312
+ }
3313
+ interface CohortSubjectStats {
2678
3314
  readonly element: AlignmentElementEvidence;
2679
3315
  readonly declaredOffset: NumericEvidenceValue;
2680
3316
  readonly effectiveOffset: NumericEvidenceValue;
2681
3317
  readonly lineHeight: NumericEvidenceValue;
2682
- readonly baselineProfile: AlignmentCohortProfile;
3318
+ readonly baselineProfile: CohortProfile;
2683
3319
  readonly signals: AlignmentCohortSignals;
2684
3320
  readonly identifiability: CohortIdentifiability;
2685
3321
  readonly contentComposition: ContentCompositionFingerprint;
2686
3322
  }
2687
- interface LayoutCohortStats {
2688
- readonly profile: AlignmentCohortProfile;
2689
- readonly snapshots: readonly LayoutSignalSnapshot[];
2690
- readonly factSummary: AlignmentCohortFactSummary;
3323
+ interface CohortStats {
3324
+ readonly profile: CohortProfile;
3325
+ readonly snapshots: readonly SignalSnapshot[];
3326
+ readonly factSummary: CohortFactSummary;
2691
3327
  readonly provenance: EvidenceProvenance;
2692
3328
  readonly conditionalSignalCount: number;
2693
3329
  readonly totalSignalCount: number;
2694
- readonly subjectsByElementKey: ReadonlyMap<string, LayoutCohortSubjectStats>;
2695
- /** Element keys excluded from cohort analysis (e.g. visually-hidden accessible elements). */
3330
+ readonly subjectsByElementKey: ReadonlyMap<string, CohortSubjectStats>;
2696
3331
  readonly excludedElementKeys: ReadonlySet<string>;
2697
3332
  }
2698
- declare const enum ContentCompositionClassification {
2699
- TextOnly = 0,
2700
- ReplacedOnly = 1,
2701
- MixedUnmitigated = 2,
2702
- MixedMitigated = 3,
2703
- BlockSegmented = 4,
2704
- Unknown = 5
2705
- }
3333
+
2706
3334
  /**
2707
- * Distinguishes intrinsically-replaced elements (img, svg, video, canvas) from
2708
- * inline-block/inline-flex containers. Their baseline rules differ: an img uses
2709
- * its bottom edge as the baseline, while an inline-block uses its last line of text.
3335
+ * Stateful analysis types + computation.
3336
+ *
3337
+ * Moved from cross-file/layout/stateful-rule-index.ts.
2710
3338
  */
2711
- type InlineReplacedKind = "intrinsic" | "container";
2712
- interface ContentCompositionFingerprint {
2713
- readonly hasTextContent: boolean;
2714
- readonly hasInlineReplaced: boolean;
2715
- readonly inlineReplacedKind: InlineReplacedKind | null;
2716
- readonly hasHeightContributingDescendant: boolean;
2717
- readonly wrappingContextMitigates: boolean;
2718
- readonly hasVerticalAlignMitigation: boolean;
2719
- readonly mixedContentDepth: number;
2720
- readonly classification: ContentCompositionClassification;
2721
- readonly analyzableChildCount: number;
2722
- readonly totalChildCount: number;
2723
- readonly hasOnlyBlockChildren: boolean;
2724
- }
2725
- declare const enum EvidenceValueKind {
2726
- Exact = 0,
2727
- Interval = 1,
2728
- Conditional = 2,
2729
- Unknown = 3
2730
- }
2731
- interface EvidenceWitness<T> {
2732
- readonly value: T | null;
2733
- readonly kind: EvidenceValueKind;
2734
- }
2735
- type NumericEvidenceValue = EvidenceWitness<number>;
2736
- interface EvidenceProvenance {
2737
- readonly reason: string;
2738
- readonly guardKey: string;
2739
- readonly guards: readonly LayoutGuardConditionProvenance[];
2740
- }
2741
-
2742
- type LayoutGuardConditionKind = "media" | "supports" | "container" | "dynamic-attribute";
2743
- interface LayoutGuardConditionProvenance {
2744
- readonly kind: LayoutGuardConditionKind;
2745
- readonly query: string | null;
2746
- readonly key: string;
2747
- }
2748
- type LayoutRuleGuard = {
2749
- readonly kind: LayoutSignalGuard.Unconditional;
2750
- readonly conditions: readonly LayoutGuardConditionProvenance[];
2751
- readonly key: "always";
2752
- } | {
2753
- readonly kind: LayoutSignalGuard.Conditional;
2754
- readonly conditions: readonly LayoutGuardConditionProvenance[];
2755
- readonly key: string;
2756
- };
2757
3339
 
2758
- interface LayoutCascadedDeclaration {
2759
- readonly value: string;
2760
- readonly source: LayoutSignalSource;
2761
- readonly guardProvenance: LayoutRuleGuard;
2762
- }
2763
- interface LayoutElementNode {
2764
- readonly key: string;
2765
- readonly solidFile: string;
2766
- readonly elementId: number;
2767
- readonly tag: string | null;
2768
- readonly tagName: string | null;
2769
- readonly classTokens: readonly string[];
2770
- readonly classTokenSet: ReadonlySet<string>;
2771
- readonly inlineStyleKeys: readonly string[];
2772
- readonly parentElementNode: LayoutElementNode | null;
2773
- readonly previousSiblingNode: LayoutElementNode | null;
2774
- readonly siblingIndex: number;
2775
- readonly siblingCount: number;
2776
- readonly siblingTypeIndex: number;
2777
- readonly siblingTypeCount: number;
2778
- readonly selectorDispatchKeys: readonly string[];
2779
- readonly attributes: ReadonlyMap<string, string | null>;
2780
- readonly inlineStyleValues: ReadonlyMap<string, string>;
2781
- readonly textualContent: LayoutTextualContentState;
2782
- readonly isControl: boolean;
2783
- readonly isReplaced: boolean;
2784
- }
2785
- interface LayoutStyleRuleNode {
2786
- readonly cssFile: string;
2787
- readonly ruleId: number;
2788
- readonly selectorId: number;
2789
- }
2790
- interface LayoutMatchEdge {
2791
- readonly selectorId: number;
2792
- readonly specificityScore: number;
2793
- readonly sourceOrder: number;
2794
- /** Whether the selector match is conditional due to dynamic attribute values. */
2795
- readonly conditionalMatch: boolean;
2796
- }
2797
- interface LayoutElementRef {
2798
- readonly solid: SolidGraph;
2799
- readonly element: JSXElementEntity;
2800
- }
2801
- type LayoutReservedSpaceReason = "height" | "block-size" | "min-height" | "min-block-size" | "contain-intrinsic-size" | "aspect-ratio+width" | "aspect-ratio+inline-size" | "aspect-ratio+min-width" | "aspect-ratio+min-block-size" | "aspect-ratio+min-height";
2802
- interface LayoutReservedSpaceFact {
2803
- readonly hasReservedSpace: boolean;
2804
- readonly reasons: readonly LayoutReservedSpaceReason[];
2805
- readonly hasContainIntrinsicSize: boolean;
2806
- readonly hasUsableAspectRatio: boolean;
2807
- readonly hasDeclaredInlineDimension: boolean;
2808
- readonly hasDeclaredBlockDimension: boolean;
2809
- }
2810
- declare const enum LayoutScrollAxis {
2811
- None = 0,
2812
- X = 1,
2813
- Y = 2,
2814
- Both = 3
2815
- }
2816
- interface LayoutScrollContainerFact {
2817
- readonly isScrollContainer: boolean;
2818
- readonly axis: LayoutScrollAxis;
2819
- readonly overflow: string | null;
2820
- readonly overflowY: string | null;
2821
- readonly hasConditionalScroll: boolean;
2822
- readonly hasUnconditionalScroll: boolean;
2823
- }
2824
- interface LayoutFlowParticipationFact {
2825
- readonly inFlow: boolean;
2826
- readonly position: string | null;
2827
- readonly hasConditionalOutOfFlow: boolean;
2828
- readonly hasUnconditionalOutOfFlow: boolean;
2829
- }
2830
- interface LayoutContainingBlockFact {
2831
- readonly nearestPositionedAncestorKey: string | null;
2832
- readonly nearestPositionedAncestorHasReservedSpace: boolean;
2833
- }
2834
- interface LayoutConditionalSignalDeltaFact {
2835
- readonly hasConditional: boolean;
2836
- readonly hasDelta: boolean;
2837
- readonly conditionalValues: readonly string[];
2838
- readonly unconditionalValues: readonly string[];
2839
- readonly hasConditionalScrollValue: boolean;
2840
- readonly hasConditionalNonScrollValue: boolean;
2841
- readonly hasUnconditionalScrollValue: boolean;
2842
- readonly hasUnconditionalNonScrollValue: boolean;
2843
- }
2844
- interface LayoutStatefulSelectorEntry {
3340
+ interface StatefulSelectorEntry {
2845
3341
  readonly raw: string;
2846
3342
  readonly isStateful: boolean;
2847
- /** Pseudo-classes from STATE_PSEUDO_SET that caused this selector to be classified as stateful. */
2848
3343
  readonly statePseudoClasses: readonly string[];
2849
- /**
2850
- * True when ALL state pseudo-classes are "direct" interaction (hover, focus, active, etc.),
2851
- * meaning state changes only from the user physically interacting with the element itself.
2852
- * False when any pseudo-class is "indirect" (checked, target) — state can change externally.
2853
- */
2854
3344
  readonly isDirectInteraction: boolean;
2855
3345
  readonly baseLookupKeys: readonly string[];
2856
3346
  }
2857
- interface LayoutNormalizedRuleDeclaration {
3347
+ interface NormalizedRuleDeclaration {
2858
3348
  readonly declarationId: number;
2859
3349
  readonly property: string;
2860
3350
  readonly normalizedValue: string;
@@ -2863,318 +3353,236 @@ interface LayoutNormalizedRuleDeclaration {
2863
3353
  readonly startColumn: number;
2864
3354
  readonly propertyLength: number;
2865
3355
  }
2866
- interface LayoutElementRecord {
2867
- readonly ref: LayoutElementRef | null;
2868
- readonly edges: readonly LayoutMatchEdge[];
2869
- readonly cascade: ReadonlyMap<string, LayoutCascadedDeclaration>;
2870
- readonly snapshot: LayoutSignalSnapshot;
2871
- readonly hotSignals: LayoutSnapshotHotSignals;
2872
- readonly reservedSpace: LayoutReservedSpaceFact;
2873
- readonly scrollContainer: LayoutScrollContainerFact;
2874
- readonly flowParticipation: LayoutFlowParticipationFact;
2875
- readonly containingBlock: LayoutContainingBlockFact;
2876
- readonly conditionalDelta: ReadonlyMap<LayoutSignalName, LayoutConditionalSignalDeltaFact> | null;
2877
- readonly baselineOffsets: ReadonlyMap<LayoutSignalName, readonly number[]> | null;
2878
- }
2879
- interface LayoutGraph {
2880
- readonly elements: readonly LayoutElementNode[];
2881
- readonly childrenByParentNode: ReadonlyMap<LayoutElementNode, readonly LayoutElementNode[]>;
2882
- readonly elementBySolidFileAndId: ReadonlyMap<string, ReadonlyMap<number, LayoutElementNode>>;
2883
- readonly elementRefsBySolidFileAndId: ReadonlyMap<string, ReadonlyMap<number, LayoutElementRef>>;
2884
- readonly elementsByTagName: ReadonlyMap<string, readonly LayoutElementNode[]>;
2885
- readonly measurementNodeByRootKey: ReadonlyMap<string, LayoutElementNode>;
2886
- readonly hostElementRefsByNode: ReadonlyMap<LayoutElementNode, LayoutElementRef>;
2887
- readonly styleRules: readonly LayoutStyleRuleNode[];
2888
- readonly applies: readonly LayoutMatchEdge[];
2889
- readonly cssScopeBySolidFile: ReadonlyMap<string, readonly string[]>;
2890
- readonly selectorCandidatesByNode: ReadonlyMap<LayoutElementNode, readonly number[]>;
2891
- readonly selectorsById: ReadonlyMap<number, SelectorEntity>;
2892
- readonly records: ReadonlyMap<LayoutElementNode, LayoutElementRecord>;
2893
- readonly cohortStatsByParentNode: ReadonlyMap<LayoutElementNode, LayoutCohortStats>;
2894
- readonly contextByParentNode: ReadonlyMap<LayoutElementNode, AlignmentContext>;
2895
- readonly elementsWithConditionalDeltaBySignal: ReadonlyMap<LayoutSignalName, readonly LayoutElementNode[]>;
2896
- readonly elementsWithConditionalOverflowDelta: readonly LayoutElementNode[];
2897
- readonly elementsWithConditionalOffsetDelta: readonly LayoutElementNode[];
2898
- readonly elementsByKnownSignalValue: ReadonlyMap<LayoutSignalName, ReadonlyMap<string, readonly LayoutElementNode[]>>;
2899
- readonly dynamicSlotCandidateElements: readonly LayoutElementNode[];
2900
- readonly scrollContainerElements: readonly LayoutElementNode[];
2901
- readonly statefulSelectorEntriesByRuleId: ReadonlyMap<number, readonly LayoutStatefulSelectorEntry[]>;
2902
- readonly statefulNormalizedDeclarationsByRuleId: ReadonlyMap<number, readonly LayoutNormalizedRuleDeclaration[]>;
2903
- readonly statefulBaseValueIndex: ReadonlyMap<string, ReadonlyMap<string, ReadonlySet<string>>>;
2904
- readonly perf: LayoutPerfStatsMutable;
2905
- }
2906
-
2907
- /**
2908
- * Versioned cache for SolidGraph, CSSGraph, and LayoutGraph instances.
2909
- *
2910
- * SolidGraphs are cached per file path with a version string.
2911
- * The CSSGraph is a single instance covering all CSS files,
2912
- * invalidated via a monotonic generation counter bumped by
2913
- * `invalidate()` or `invalidateAll()`.
2914
- */
2915
- declare class GraphCache {
2916
- private readonly log;
2917
- private readonly solids;
2918
- private readonly crossFileDiagnostics;
2919
- private crossFileResults;
2920
- private css;
2921
- private solidGeneration;
2922
- private cssGeneration;
2923
- private layout;
2924
- constructor(log?: Logger);
2925
- /**
2926
- * Check if a SolidGraph is cached and current for a file path.
2927
- *
2928
- * Allows callers to skip builder allocation when the cache is warm.
2929
- *
2930
- * @param path Absolute file path
2931
- * @param version Script version string from the TS project service
2932
- */
2933
- hasSolidGraph(path: string, version: string): boolean;
2934
- /**
2935
- * Store a pre-built SolidGraph in the cache.
2936
- *
2937
- * Used by the CLI lint command which builds graphs during single-file
2938
- * analysis and pre-populates the cache for cross-file reuse.
2939
- *
2940
- * @param path Absolute file path
2941
- * @param version Script version string from the TS project service
2942
- * @param graph Pre-built SolidGraph
2943
- */
2944
- setSolidGraph(path: string, version: string, graph: SolidGraph): void;
2945
- /**
2946
- * Get a cached SolidGraph without building on miss.
2947
- *
2948
- * Returns the cached graph if the version matches, null otherwise.
2949
- * Use when the caller has already confirmed the entry exists via
2950
- * `hasSolidGraph` and wants to avoid allocating a builder closure.
2951
- *
2952
- * @param path Absolute file path
2953
- * @param version Script version string from the TS project service
2954
- */
2955
- getCachedSolidGraph(path: string, version: string): SolidGraph | null;
2956
- /**
2957
- * Get or build a SolidGraph for a file path.
2958
- *
2959
- * Returns the cached graph if the version matches.
2960
- * Otherwise invokes the builder, caches the result, and returns it.
2961
- *
2962
- * @param path Absolute file path
2963
- * @param version Script version string from the TS project service
2964
- * @param build Builder function invoked on cache miss
2965
- */
2966
- getSolidGraph(path: string, version: string, build: () => SolidGraph): SolidGraph;
2967
- /**
2968
- * Get the cached CSSGraph, or rebuild it.
2969
- *
2970
- * Returns the cached graph if the generation matches the current
2971
- * CSS generation counter. Otherwise invokes the builder, caches
2972
- * the result at the current generation, and returns it.
2973
- *
2974
- * @param build Builder function invoked on cache miss
2975
- */
2976
- getCSSGraph(build: () => CSSGraph): CSSGraph;
2977
- /**
2978
- * Get or build a LayoutGraph for current Solid/CSS cache state.
2979
- *
2980
- * Returns cached LayoutGraph when both Solid signature (path+version)
2981
- * and CSS generation match. Otherwise invokes the builder.
2982
- *
2983
- * @param build Builder function invoked on cache miss
2984
- */
2985
- getLayoutGraph(build: () => LayoutGraph): LayoutGraph;
2986
- /**
2987
- * Invalidate cached graphs affected by a file change.
2988
- *
2989
- * Classifies the path and invalidates the appropriate cache:
2990
- * solid files evict their per-file SolidGraph, CSS files bump
2991
- * the CSSGraph generation counter.
2992
- *
2993
- * @param path Absolute file path that changed
2994
- */
2995
- invalidate(path: string): void;
2996
- /**
2997
- * Invalidate all cached graphs.
2998
- *
2999
- * Called on workspace-level events like config changes.
3000
- */
3001
- invalidateAll(): void;
3002
- /**
3003
- * Get all cached SolidGraphs.
3004
- *
3005
- * Returns a snapshot array of all currently-cached graphs.
3006
- * Used by cross-file analysis which needs all SolidGraphs.
3007
- */
3008
- getAllSolidGraphs(): readonly SolidGraph[];
3009
- /**
3010
- * Get the cached CSSGraph, or null if not cached.
3011
- */
3012
- getCachedCSSGraph(): CSSGraph | null;
3013
- /**
3014
- * Get the cached LayoutGraph, or null if not cached.
3015
- */
3016
- getCachedLayoutGraph(): LayoutGraph | null;
3017
- /**
3018
- * Get cached cross-file diagnostics for a file path.
3019
- *
3020
- * Returns the previous cross-file results so single-file-only
3021
- * re-analysis (during typing) can merge them without re-running
3022
- * cross-file rules.
3023
- *
3024
- * @param path Absolute file path
3025
- */
3026
- getCachedCrossFileDiagnostics(path: string): readonly Diagnostic[];
3027
- /**
3028
- * Store cross-file diagnostics for a file path.
3029
- *
3030
- * @param path Absolute file path
3031
- * @param diagnostics Cross-file diagnostics for this path
3032
- */
3033
- setCachedCrossFileDiagnostics(path: string, diagnostics: readonly Diagnostic[]): void;
3034
- /**
3035
- * Get workspace-level cross-file results if the underlying graphs haven't changed.
3036
- *
3037
- * Returns the full per-file map when the solid signature and CSS generation
3038
- * match, meaning no graphs were rebuilt since the last run. Returns null
3039
- * when results are stale and `runCrossFileRules` must re-execute.
3040
- */
3356
+
3357
+ interface CustomPropertyResolution {
3358
+ readonly resolved: boolean;
3359
+ readonly symbol: CustomPropertySymbol | null;
3360
+ readonly value: string | null;
3361
+ readonly unresolvedReferences: readonly VariableReferenceEntity[];
3362
+ }
3363
+ type ReactiveKind = "signal" | "props" | "store" | "resource" | "memo" | "derived";
3364
+ interface FileSemanticModel {
3365
+ readonly filePath: string;
3366
+ readonly compilation: StyleCompilation;
3367
+ readonly solidTree: SolidSyntaxTree;
3368
+ getElementNode(elementId: number): ElementNode | null;
3369
+ getElementNodes(): readonly ElementNode[];
3370
+ getElementCascade(elementId: number): ElementCascade;
3371
+ getMatchingSelectors(elementId: number): readonly SelectorMatch[];
3372
+ getComponentHost(importSource: string, exportName: string): ComponentHostSymbol | null;
3373
+ getElementsByTagName(tag: string): readonly ElementNode[];
3374
+ getLayoutFact<K extends LayoutFactKind>(elementId: number, factKind: K): LayoutFactMap[K];
3375
+ getSignalSnapshot(elementId: number): SignalSnapshot;
3376
+ getConditionalDelta(elementId: number): ReadonlyMap<string, ConditionalSignalDelta> | null;
3377
+ getBaselineOffsets(elementId: number): ReadonlyMap<LayoutSignalName, readonly number[]> | null;
3378
+ getClassNameInfo(name: string): ClassNameSymbol | null;
3379
+ getCustomPropertyResolution(name: string): CustomPropertyResolution;
3380
+ getSelectorOverrides(selectorId: number): readonly SelectorSymbol[];
3381
+ getScopedCSSFiles(): readonly string[];
3382
+ getScopedSelectors(): ScopedSelectorIndex;
3383
+ getImportChain(): readonly ImportEntity[];
3384
+ getReactiveKind(variable: VariableEntity$1): ReactiveKind | null;
3385
+ getDependencyEdges(computation: ComputationEntity): readonly DependencyEdge[];
3386
+ getAlignmentContext(parentElementId: number): AlignmentContext | null;
3387
+ getCohortStats(parentElementId: number): CohortStats | null;
3388
+ getElementsWithConditionalDelta(signal: string): readonly ElementNode[];
3389
+ getScrollContainerElements(): readonly ElementNode[];
3390
+ getDynamicSlotCandidates(): readonly ElementNode[];
3391
+ getElementsByKnownSignalValue(signal: LayoutSignalName, value: string): readonly ElementNode[];
3392
+ getStatefulSelectorEntries(ruleId: number): readonly StatefulSelectorEntry[];
3393
+ getStatefulNormalizedDeclarations(ruleId: number): readonly NormalizedRuleDeclaration[];
3394
+ getStatefulBaseValueIndex(): ReadonlyMap<string, ReadonlyMap<string, ReadonlySet<string>>>;
3395
+ }
3396
+
3397
+ interface TailwindConfigInput {
3398
+ readonly kind: "tailwind-config";
3399
+ readonly filePath: string;
3400
+ readonly version: string;
3401
+ readonly validator: TailwindValidator | null;
3402
+ }
3403
+ interface PackageManifestInput {
3404
+ readonly kind: "package-manifest";
3405
+ readonly filePath: string;
3406
+ readonly version: string;
3407
+ }
3408
+ interface TSConfigInput {
3409
+ readonly kind: "tsconfig";
3410
+ readonly filePath: string;
3411
+ readonly version: string;
3412
+ }
3413
+ interface StyleCompilation {
3414
+ readonly id: number;
3415
+ readonly solidTrees: ReadonlyMap<string, SolidSyntaxTree>;
3416
+ readonly cssTrees: ReadonlyMap<string, CSSSyntaxTree>;
3417
+ readonly tailwindConfig: TailwindConfigInput | null;
3418
+ readonly packageManifest: PackageManifestInput | null;
3419
+ readonly tsConfig: TSConfigInput | null;
3420
+ readonly symbolTable: SymbolTable;
3421
+ readonly dependencyGraph: DependencyGraph;
3422
+ withSolidTree(tree: SolidSyntaxTree): StyleCompilation;
3423
+ withCSSTrees(trees: readonly CSSSyntaxTree[]): StyleCompilation;
3424
+ withCSSTree(tree: CSSSyntaxTree): StyleCompilation;
3425
+ withoutFile(filePath: string): StyleCompilation;
3426
+ withTailwindConfig(config: TailwindConfigInput | null): StyleCompilation;
3427
+ withPackageManifest(manifest: PackageManifestInput | null): StyleCompilation;
3428
+ withTSConfig(config: TSConfigInput | null): StyleCompilation;
3429
+ withFile(filePath: string, tree: SolidSyntaxTree | CSSSyntaxTree): StyleCompilation;
3430
+ getSolidTree(filePath: string): SolidSyntaxTree | null;
3431
+ getCSSTree(filePath: string): CSSSyntaxTree | null;
3432
+ getSemanticModel(solidFilePath: string): FileSemanticModel;
3433
+ getSolidFilePaths(): readonly string[];
3434
+ getCSSFilePaths(): readonly string[];
3435
+ }
3436
+ declare function createStyleCompilation(): StyleCompilation;
3437
+ declare function createCompilationFromLegacy(solidTrees: readonly SolidSyntaxTree[], cssTrees: readonly CSSSyntaxTree[]): StyleCompilation;
3438
+
3439
+ type CSSSourceProviderKind = "plain-css" | "scss" | "tailwind";
3440
+ interface CSSSymbolContribution {
3441
+ readonly classNames: ReadonlyMap<string, CSSClassNameSource>;
3442
+ readonly selectors: readonly SelectorSymbol[];
3443
+ readonly declarations: readonly DeclarationSymbol[];
3444
+ readonly customProperties: readonly CustomPropertySymbol[];
3445
+ readonly keyframes: readonly KeyframesSymbol[];
3446
+ readonly fontFaces: readonly FontFaceSymbol[];
3447
+ readonly layers: readonly LayerSymbol[];
3448
+ readonly containers: readonly ContainerSymbol[];
3449
+ readonly themeTokens: readonly ThemeTokenSymbol[];
3450
+ }
3451
+ interface CSSSourceProvider {
3452
+ readonly kind: CSSSourceProviderKind;
3453
+ parse(filePath: string, content: string, sourceOrderBase: number): CSSSyntaxTree;
3454
+ extractSymbols(tree: CSSSyntaxTree): CSSSymbolContribution;
3455
+ }
3456
+
3457
+ type AdditionalInput = TailwindConfigInput | {
3458
+ readonly kind: "package-manifest";
3459
+ readonly filePath: string;
3460
+ readonly version: string;
3461
+ } | {
3462
+ readonly kind: "tsconfig";
3463
+ readonly filePath: string;
3464
+ readonly version: string;
3465
+ };
3466
+ interface CompilationTracker {
3467
+ readonly currentCompilation: StyleCompilation;
3468
+ readonly previousCompilation: StyleCompilation | null;
3469
+ applyChange(filePath: string, content: string, version: string): CompilationTracker;
3470
+ applyDeletion(filePath: string): CompilationTracker;
3471
+ applyInputChange(input: AdditionalInput): CompilationTracker;
3472
+ /**
3473
+ * Apply a batch of file changes in one dependency graph rebuild.
3474
+ * solidTrees: pre-built SolidSyntaxTrees keyed by canonical path.
3475
+ * CSS files are parsed internally via CSSSourceProvider.
3476
+ * Rebuilds the dependency graph ONCE after all mutations.
3477
+ */
3478
+ applyBatch(changes: readonly {
3479
+ path: string;
3480
+ content: string;
3481
+ version: string;
3482
+ }[], solidTrees: ReadonlyMap<string, SolidSyntaxTree>): CompilationTracker;
3483
+ getStaleFiles(): ReadonlySet<string>;
3484
+ getDirectlyChangedFiles(): ReadonlySet<string>;
3485
+ isSemanticModelValid(filePath: string): boolean;
3486
+ getCachedCrossFileDiagnostics(filePath: string): readonly Diagnostic[];
3487
+ setCachedCrossFileDiagnostics(filePath: string, diagnostics: readonly Diagnostic[]): void;
3041
3488
  getCachedCrossFileResults(): ReadonlyMap<string, readonly Diagnostic[]> | null;
3042
- /**
3043
- * Store workspace-level cross-file results bucketed by file.
3044
- *
3045
- * Called after `runCrossFileRules` completes. Captures the current
3046
- * solid signature and CSS generation so subsequent lookups are O(1)
3047
- * until a graph changes.
3048
- *
3049
- * @param allDiagnostics All cross-file diagnostics from the workspace run
3050
- */
3051
3489
  setCachedCrossFileResults(allDiagnostics: readonly Diagnostic[]): void;
3052
- /** Number of cached SolidGraphs. */
3053
- get solidCount(): number;
3054
- /** The logger instance used by this cache. */
3055
- get logger(): Logger;
3490
+ invalidateCrossFileResults(): void;
3491
+ }
3492
+ interface CompilationTrackerOptions {
3493
+ readonly cssProvider?: CSSSourceProvider;
3494
+ readonly scssProvider?: CSSSourceProvider;
3495
+ readonly tailwindProvider?: TailwindProvider;
3496
+ readonly logger?: Logger;
3497
+ }
3498
+ declare function createCompilationTracker(compilation: StyleCompilation, options?: CompilationTrackerOptions): CompilationTracker;
3499
+
3500
+ interface PlainCSSProvider extends CSSSourceProvider {
3501
+ readonly kind: "plain-css";
3502
+ }
3503
+ declare function createPlainCSSProvider(): PlainCSSProvider;
3504
+
3505
+ /**
3506
+ * AnalysisRule + typed action registry — replaces CrossRule + BaseRule<CrossRuleContext>.
3507
+ */
3508
+
3509
+ type Emit = (diagnostic: Diagnostic) => void;
3510
+ declare const enum ComputationTier {
3511
+ CSSSyntax = 0,
3512
+ CrossSyntax = 1,
3513
+ ElementResolution = 2,
3514
+ SelectiveLayoutFacts = 3,
3515
+ FullCascade = 4,
3516
+ AlignmentModel = 5
3517
+ }
3518
+ interface TierRequirement {
3519
+ readonly tier: ComputationTier;
3520
+ readonly factKinds?: readonly LayoutFactKind[];
3521
+ readonly signals?: readonly LayoutSignalName[];
3522
+ }
3523
+ type StyleSymbolKind = keyof StyleSymbolByKind;
3524
+ interface StyleSymbolByKind {
3525
+ className: ClassNameSymbol;
3526
+ selector: SelectorSymbol;
3527
+ declaration: DeclarationSymbol;
3528
+ customProperty: CustomPropertySymbol;
3529
+ componentHost: ComponentHostSymbol;
3530
+ keyframes: KeyframesSymbol;
3531
+ fontFace: FontFaceSymbol;
3532
+ layer: LayerSymbol;
3533
+ container: ContainerSymbol;
3534
+ themeToken: ThemeTokenSymbol;
3535
+ }
3536
+ interface AnalysisActionRegistry {
3537
+ registerCSSSyntaxAction(action: (tree: CSSSyntaxTree, symbolTable: SymbolTable, emit: Emit) => void): void;
3538
+ registerCrossSyntaxAction(action: (solidTree: SolidSyntaxTree, symbolTable: SymbolTable, emit: Emit) => void): void;
3539
+ registerCompilationAction(action: (compilation: StyleCompilation, symbolTable: SymbolTable, emit: Emit) => void): void;
3540
+ registerSymbolAction<K extends StyleSymbolKind>(kind: K, action: (symbol: StyleSymbolByKind[K], semanticModel: FileSemanticModel, emit: Emit) => void): void;
3541
+ registerElementAction(action: (element: ElementNode, semanticModel: FileSemanticModel, emit: Emit) => void): void;
3542
+ registerFactAction<K extends LayoutFactKind>(factKind: K, action: (element: ElementNode, fact: LayoutFactMap[K], semanticModel: FileSemanticModel, emit: Emit) => void): void;
3543
+ registerCascadeAction(action: (element: ElementNode, cascade: ElementCascade, snapshot: SignalSnapshot, semanticModel: FileSemanticModel, emit: Emit) => void): void;
3544
+ registerConditionalDeltaAction(action: (element: ElementNode, delta: ReadonlyMap<string, ConditionalSignalDelta>, semanticModel: FileSemanticModel, emit: Emit) => void): void;
3545
+ registerAlignmentAction(action: (parentElement: ElementNode, context: AlignmentContext, cohort: CohortStats, semanticModel: FileSemanticModel, emit: Emit) => void): void;
3546
+ }
3547
+ interface AnalysisRule {
3548
+ readonly id: string;
3549
+ readonly severity: "error" | "warn" | "off";
3550
+ readonly messages: Record<string, string>;
3551
+ readonly meta: {
3552
+ readonly description: string;
3553
+ readonly fixable: boolean;
3554
+ readonly category: string;
3555
+ };
3556
+ readonly requirement: TierRequirement;
3557
+ register(registry: AnalysisActionRegistry): void;
3056
3558
  }
3057
3559
 
3058
3560
  /**
3059
- * Build a SolidGraph from input.
3060
- *
3061
- * Exported for use by cross-file rules that need to build graphs
3062
- * without running all solid rules.
3063
- */
3064
- declare function buildSolidGraph(input: SolidInput): SolidGraph;
3065
- /**
3066
- * Analyze pre-parsed input and emit diagnostics.
3067
- *
3068
- * For use by ESLint integration and LSP where the caller
3069
- * has already parsed the file (e.g. ESLint provides SourceCode).
3070
- */
3071
- declare function analyzeInput(input: SolidInput, emit: Emit): void;
3072
- /**
3073
- * Run single-file Solid rules on a pre-built graph.
3074
- *
3075
- * Separates rule execution from graph construction so callers that
3076
- * cache graphs (e.g. CLI lint) can build once, run single-file rules,
3077
- * and reuse the same graph for cross-file analysis.
3078
- */
3079
- declare function runSolidRules(graph: SolidGraph, sourceFile: ts.SourceFile, emit: Emit): void;
3080
- /**
3081
- * The Solid.js plugin.
3082
- *
3083
- * Analyzes Solid.js files by building a SolidGraph and running all rules.
3084
- * Rules push diagnostics via the emit callback.
3085
- */
3086
- declare const SolidPlugin: Plugin<"solid">;
3087
-
3088
- declare function createSolidInput(filePath: string, program: ts.Program, logger?: Logger): SolidInput;
3089
-
3090
- /**
3091
- * Build a CSSGraph from input.
3092
- *
3093
- * When `externalCustomProperties` is present in the input, generates a synthetic
3094
- * CSS file declaring those properties in `:root` and includes it in the graph.
3095
- * This ensures library-provided custom properties resolve through the normal
3096
- * cascade and resolution pipeline.
3097
- *
3098
- * Exported for use by cross-file rules that need to build graphs
3099
- * without running all CSS rules.
3100
- */
3101
- declare function buildCSSGraph(input: CSSInput): CSSGraph;
3102
- /**
3103
- * The CSS plugin.
3104
- *
3105
- * Analyzes CSS/SCSS files by reading from disk, building a CSSGraph,
3106
- * and running all rules. Rules push diagnostics via the emit callback.
3107
- *
3108
- * @example
3109
- * ```ts
3110
- * import { createRunner, CSSPlugin } from "@drskillissue/ganko"
3111
- *
3112
- * const runner = createRunner({ plugins: [CSSPlugin] })
3113
- * const diagnostics = runner.run(["src/styles/app.css"])
3114
- * ```
3115
- */
3116
- declare const CSSPlugin: Plugin<"css">;
3117
-
3118
- /**
3119
- * Library Analysis — Extracts CSS custom properties provided by installed dependencies.
3120
- *
3121
- * Scans dependency packages for CSS custom property definitions injected at runtime
3122
- * via JavaScript (e.g., inline style attributes in JSX). This enables the resolution
3123
- * engine to treat library-provided properties as defined rather than flagging them
3124
- * as unresolved.
3125
- *
3126
- * Architecture:
3127
- * 1. Read project package.json files to discover direct dependencies
3128
- * 2. For each dependency, scan its dist/source files for CSS custom property patterns
3129
- * 3. Return discovered properties as a synthetic CSS `:root` declaration block
3130
- * 4. The caller feeds this into the normal CSS parsing pipeline as an additional file
3131
- *
3132
- * The scanner detects properties set via:
3133
- * - JSX style object keys: `"--kb-accordion-content-height": value`
3134
- * - style.setProperty calls: `style.setProperty("--kb-accordion-content-height", ...)`
3135
- * - CSS-in-JS template literals with custom property definitions
3136
- */
3137
- /**
3138
- * Scan installed dependencies for CSS custom properties they inject at runtime.
3139
- *
3140
- * Reads each direct dependency's package.json to find its dist directory,
3141
- * then scans JavaScript/JSX files for CSS custom property name patterns.
3142
- *
3143
- * @param projectRoot - Absolute path to the project root (containing package.json)
3144
- * @returns Set of CSS custom property names (e.g., "--kb-accordion-content-height")
3145
- */
3146
- declare function scanDependencyCustomProperties(projectRoot: string): ReadonlySet<string>;
3147
-
3148
- /**
3149
- * Accessibility Policy Templates
3561
+ * AnalysisDispatcher tiered rule execution framework.
3150
3562
  *
3151
- * Predefined bundles of sizing, spacing, and contrast constraints
3152
- * derived from WCAG 2.2, Material Design 3, Apple HIG, and
3153
- * W3C Low Vision Needs.
3563
+ * Like Roslyn's CompilationWithAnalyzers + AnalyzerDriver:
3564
+ * rules register typed subscriptions, the framework inspects subscriptions
3565
+ * to determine the maximum required tier, computes only that tier,
3566
+ * and dispatches to subscribers.
3154
3567
  */
3155
3568
 
3156
- /** Set the active policy for all policy rules. Pass null to disable. */
3157
- declare function setActivePolicy(name: string | null): void;
3158
-
3159
- declare function buildLayoutGraph(solids: readonly SolidGraph[], css: CSSGraph, logger?: Logger): LayoutGraph;
3160
-
3161
- interface CrossRuleContext {
3162
- readonly solids: readonly SolidGraph[];
3163
- readonly css: CSSGraph;
3164
- readonly layout: LayoutGraph;
3165
- readonly logger: Logger;
3569
+ interface AnalysisResult {
3570
+ readonly diagnostics: readonly Diagnostic[];
3571
+ readonly maxTierComputed: ComputationTier;
3572
+ }
3573
+ interface AnalysisDispatcher {
3574
+ register(rule: AnalysisRule): void;
3575
+ run(compilation: StyleCompilation): AnalysisResult;
3576
+ /**
3577
+ * Run only on a subset of affected files. Tier 0 CSS syntax actions
3578
+ * only fire for affected CSS files. Tier 1+ only fire for affected
3579
+ * solid files. Compilation-wide actions always run.
3580
+ * Used for incremental re-analysis after a file change.
3581
+ */
3582
+ runSubset(compilation: StyleCompilation, affectedFiles: ReadonlySet<string>): AnalysisResult;
3166
3583
  }
3584
+ declare function createAnalysisDispatcher(): AnalysisDispatcher;
3167
3585
 
3168
- /**
3169
- * Run cross-file rules against pre-built graphs.
3170
- *
3171
- * Separates rule execution from graph construction so that callers
3172
- * with cached graphs (e.g. LSP GraphCache) can skip redundant parsing.
3173
- *
3174
- * @param context Pre-built Solid, CSS, and layout graphs
3175
- * @param emit Diagnostic emitter
3176
- * @param log Optional logger for diagnostics
3177
- */
3178
- declare function runCrossFileRules(context: CrossRuleContext, emit: Emit, log?: Logger | undefined): void;
3586
+ declare const allRules: readonly AnalysisRule[];
3179
3587
 
3180
- export { CSSGraph, type CSSInput, CSSPlugin, type CommentEntry, type ComputationEntity, type DependencyEdge, type Diagnostic, type Fix, type FixOperation, GraphCache, type Plugin, type ReactiveKind, type ReadEntity, type Runner, SolidGraph, type SolidInput, SolidPlugin, type TailwindValidator, type VariableEntity$1 as VariableEntity, analyzeInput, buildCSSGraph, buildLayoutGraph, buildSolidGraph, createOverrideEmit, createRunner, createSolidInput, resolveTailwindValidator, runCrossFileRules, runSolidRules, scanDependencyCustomProperties, setActivePolicy };
3588
+ export { type AnalysisDispatcher, type BatchableTailwindValidator, type CSSBuildContext, type CSSBuildResult, type CSSInput, type CSSInputBuilder, CSSPlugin, type CSSSyntaxTree, type CSSWorkspaceView, type CommentEntry, type CompilationTracker, type CompilationTrackerOptions, type ComputationEntity, type DependencyEdge, type Diagnostic, type Fix, type FixOperation, type Plugin, type ReactiveKind$1 as ReactiveKind, type ReadEntity, type Runner, type SolidBuildContext, type SolidInput, SolidPlugin, type SolidSyntaxTree, type SolidSyntaxTree as SolidTree, type StyleCompilation, type TailwindEvalParams, type TailwindValidator, type VariableEntity$1 as VariableEntity, allRules, analyzeInput, buildCSSResult, buildSolidSyntaxTree, buildTailwindValidatorFromEval, createAnalysisDispatcher, createCSSInput, createCompilationFromLegacy, createCompilationTracker, createOverrideEmit, createPlainCSSProvider, createRunner, createSolidInput, createStyleCompilation, prepareTailwindEval, resolveTailwindValidatorSync, runSolidRules, scanDependencyCustomProperties, setActivePolicy };