@selfcure/analyzer 0.1.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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @selfcure/analyzer
2
+
3
+ > Testability scorer for **selfcure** — classifies interactive elements and computes a 0–100 score per component.
4
+
5
+ Takes `ComponentMeta[]` from [`@selfcure/crawler`](https://www.npmjs.com/package/@selfcure/crawler), builds a `selectorRanking` per element (`data-testid` → `id` → `aria-label` → `name` → CSS → XPath), detects **ambiguous locators** (when the best selector for an element also matches a sibling), and emits a testability score plus a dedup-aware suggested `data-testid`.
6
+
7
+ Internal library powering [`@selfcure/cli`](https://www.npmjs.com/package/@selfcure/cli) and [`@selfcure/mcp`](https://www.npmjs.com/package/@selfcure/mcp).
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @selfcure/analyzer
13
+ ```
14
+
15
+ ## Docs
16
+
17
+ Full documentation: https://github.com/ricardofrancocustodio/selfcure#readme
@@ -0,0 +1,550 @@
1
+ import { TestIdUsage, A11yFileEvidence, ComponentMeta } from '@selfcure/crawler';
2
+
3
+ type TagMaturityLevel = 0 | 1 | 2 | 3 | 4;
4
+ type TagMaturityLabel = 'unusable' | 'fragile' | 'usable' | 'stable' | 'governed';
5
+ declare const TML_LABELS: Record<TagMaturityLevel, TagMaturityLabel>;
6
+ type TagMaturityReasonCode = 'stable-testid' | 'missing-testid' | 'invalid-testid-name' | 'duplicate-testid' | 'deprecated-testid' | 'strong-role-name' | 'generic-accessible-name' | 'missing-accessible-name' | 'ambiguous-selector' | 'weak-css-selector' | 'runtime-not-observed' | 'runtime-unique' | 'missing-owner' | 'missing-intent';
7
+ interface TagMaturityReason {
8
+ code: TagMaturityReasonCode;
9
+ severity: 'info' | 'warning' | 'error';
10
+ message: string;
11
+ evidence?: string[];
12
+ }
13
+ type TagMaturityChangeType = 'add-testid' | 'rename-testid' | 'dedupe-testid' | 'add-accessible-name' | 'add-inventory-entry' | 'add-owner' | 'add-intent' | 'replace-selector' | 'confirm-runtime-state';
14
+ interface TagMaturityChange {
15
+ type: TagMaturityChangeType;
16
+ priority: 'low' | 'medium' | 'high';
17
+ description: string;
18
+ suggestedValue?: string;
19
+ /** True when selfcure can auto-patch this without user review */
20
+ patchAvailable?: boolean;
21
+ }
22
+ interface TagMaturityResult {
23
+ level: TagMaturityLevel;
24
+ label: TagMaturityLabel;
25
+ /** Mirrors the element's testabilityScore at assessment time */
26
+ score: number;
27
+ reasons: TagMaturityReason[];
28
+ requiredChanges: TagMaturityChange[];
29
+ /** 0–1 confidence in this assessment (lower when evidence is ambiguous) */
30
+ confidence: number;
31
+ }
32
+ interface TmlInventoryEntry {
33
+ hasOwner: boolean;
34
+ hasIntent: boolean;
35
+ hasRoute: boolean;
36
+ isDeprecated: boolean;
37
+ isDuplicate: boolean;
38
+ namingValid: boolean;
39
+ }
40
+ interface TagMaturityInput {
41
+ /** 0–100 testability score (after ambiguity penalties) */
42
+ testabilityScore: number;
43
+ /** True when the best selector matches multiple siblings in the same component */
44
+ ambiguous: boolean;
45
+ /** Best selector strategy (from selectorRanking[0].strategy) */
46
+ bestStrategy: 'data-testid' | 'id' | 'aria-label' | 'name' | 'css' | 'xpath';
47
+ /** Label for testid suggestion (label → id → aria-label) */
48
+ label?: string;
49
+ /** Element tag for suggestion building */
50
+ elementType: string;
51
+ /** Inventory metadata — only set when TestId Inventory Phase 3 is wired up */
52
+ inventory?: TmlInventoryEntry;
53
+ /** Runtime data — only set when agentic discovery Phase 7 is wired up */
54
+ runtime?: {
55
+ observed: boolean;
56
+ unique: boolean;
57
+ };
58
+ }
59
+
60
+ type InventoryElementStatus = 'active' | 'deprecated' | 'removed';
61
+ type InventoryElementStability = 'stable' | 'unstable' | 'dynamic';
62
+ interface InventoryElement {
63
+ testId: string;
64
+ component?: string;
65
+ elementType?: string;
66
+ intent?: string;
67
+ label?: string;
68
+ sourceFile?: string;
69
+ status: InventoryElementStatus;
70
+ stability: InventoryElementStability;
71
+ firstSeenAt?: string;
72
+ lastSeenAt?: string;
73
+ /** For dynamic IDs: pattern template, e.g. "users.table.row.{userId}.{action}-button" */
74
+ pattern?: string;
75
+ /** Owning team — overrides route-level owner when set */
76
+ owner?: string;
77
+ }
78
+ interface InventoryRoute {
79
+ path: string;
80
+ screen?: string;
81
+ owner?: string;
82
+ elements: InventoryElement[];
83
+ }
84
+ interface TestIdInventory {
85
+ version: string;
86
+ app: string;
87
+ generatedAt: string;
88
+ routes: InventoryRoute[];
89
+ }
90
+
91
+ type ParseResult = {
92
+ ok: true;
93
+ inventory: TestIdInventory;
94
+ } | {
95
+ ok: false;
96
+ errors: string[];
97
+ };
98
+ declare function parseInventory(raw: string): ParseResult;
99
+ declare function loadInventory(filePath: string): Promise<ParseResult>;
100
+ /**
101
+ * Return all testId strings from a parsed inventory in insertion order,
102
+ * deduplicating across routes.
103
+ */
104
+ declare function allTestIds(inventory: TestIdInventory): string[];
105
+
106
+ type AuditRuleId = 'duplicate-testid' | 'missing-inventory' | 'orphaned-inventory' | 'test-only-selector' | 'invalid-name' | 'generic-name' | 'missing-owner' | 'deprecated-used';
107
+ type IssueSeverity = 'error' | 'warning';
108
+ interface AuditIssue {
109
+ rule: AuditRuleId;
110
+ severity: IssueSeverity;
111
+ testId: string;
112
+ locations?: string[];
113
+ message?: string;
114
+ }
115
+ interface AuditSummary {
116
+ totalObserved: number;
117
+ duplicates: number;
118
+ missingInventory: number;
119
+ orphaned: number;
120
+ testOnlySelectors: number;
121
+ invalidNames: number;
122
+ }
123
+ interface AuditResult$1 {
124
+ summary: AuditSummary;
125
+ issues: AuditIssue[];
126
+ }
127
+ /**
128
+ * Audit a scanned set of usages against a governed inventory.
129
+ * Returns all detected issues plus a summary.
130
+ */
131
+ declare function audit(inventory: TestIdInventory, usages: TestIdUsage[]): AuditResult$1;
132
+
133
+ interface NamingViolation {
134
+ testId: string;
135
+ rule: 'invalid-name' | 'generic-name';
136
+ reason: string;
137
+ }
138
+ /**
139
+ * Validate a single testId against the naming convention.
140
+ * Returns null when the name is valid, or a violation descriptor when not.
141
+ */
142
+ declare function checkNaming(testId: string): NamingViolation | null;
143
+ /** Return true when the testId conforms to the naming convention. */
144
+ declare function isValidTestId(testId: string): boolean;
145
+
146
+ type WcagLevel = 'A' | 'AA' | 'AAA';
147
+ type A11ySeverity = 'info' | 'minor' | 'major' | 'critical';
148
+ type A11yCategory = 'perceivable' | 'operable' | 'understandable' | 'robust';
149
+ type A11ySource = 'static' | 'dynamic' | 'hybrid';
150
+ type FindingStatus = 'open' | 'resolved' | 'suppressed';
151
+ interface AccessibilityRule {
152
+ id: string;
153
+ wcag: string[];
154
+ level: WcagLevel;
155
+ category: A11yCategory;
156
+ severity: A11ySeverity;
157
+ source: A11ySource;
158
+ paid: boolean;
159
+ title: string;
160
+ description: string;
161
+ remediation: string;
162
+ }
163
+ interface AccessibilityFinding {
164
+ id: string;
165
+ ruleId: string;
166
+ wcag: string[];
167
+ level: WcagLevel;
168
+ severity: A11ySeverity;
169
+ status: FindingStatus;
170
+ route?: string;
171
+ component?: string;
172
+ sourceFile: string;
173
+ line: number;
174
+ column: number;
175
+ selector?: string;
176
+ testId?: string;
177
+ accessibleName?: string;
178
+ message: string;
179
+ remediation: string;
180
+ firstSeenAt: string;
181
+ lastSeenAt: string;
182
+ owner?: string;
183
+ }
184
+ interface FindingInventory {
185
+ version: string;
186
+ app: string;
187
+ standard: 'WCAG';
188
+ targetLevel: WcagLevel;
189
+ generatedAt: string;
190
+ findings: AccessibilityFinding[];
191
+ }
192
+ /** Requires a reason, owner, and expiration — suppressions without expiry are invalid in CI mode. */
193
+ interface FindingSuppression {
194
+ findingId: string;
195
+ reason: string;
196
+ owner: string;
197
+ expiresAt: string;
198
+ }
199
+
200
+ /** Severity levels in ascending order. */
201
+ declare const SEVERITY_ORDER: ReadonlyArray<A11ySeverity>;
202
+ /**
203
+ * WCAG level hierarchy: targeting AA means checking A + AA rules.
204
+ * Targeting AAA means checking all levels.
205
+ */
206
+ declare const LEVEL_HIERARCHY: Readonly<Record<WcagLevel, ReadonlyArray<WcagLevel>>>;
207
+ declare const accessibilityRules: ReadonlyArray<AccessibilityRule>;
208
+ declare function getRuleById(id: string): AccessibilityRule | undefined;
209
+ /** Return all rules applicable to the given WCAG target level (inclusive of lower levels). */
210
+ declare function getRulesByLevel(targetLevel: WcagLevel): AccessibilityRule[];
211
+ /** Return all rules at or above the given severity. */
212
+ declare function getRulesBySeverity(minSeverity: A11ySeverity): AccessibilityRule[];
213
+ interface RuleFilterOptions {
214
+ /** Include only rules applicable to this WCAG level and below. */
215
+ level?: WcagLevel;
216
+ /** Include only rules at or above this severity. */
217
+ minSeverity?: A11ySeverity;
218
+ /** Filter by paid status. */
219
+ paid?: boolean;
220
+ /** Filter by analysis source (static / dynamic / hybrid). */
221
+ source?: AccessibilityRule['source'];
222
+ /** Filter by WCAG principle category. */
223
+ category?: AccessibilityRule['category'];
224
+ }
225
+ declare function filterRules(opts?: RuleFilterOptions): AccessibilityRule[];
226
+
227
+ interface StaticAnalysisOptions {
228
+ /** WCAG target level — rules above this level are excluded. Default: 'AA'. */
229
+ level?: WcagLevel;
230
+ }
231
+ /**
232
+ * Run static accessibility analysis against JSX/TSX evidence extracted by the crawler.
233
+ * Returns findings sorted by file path then line number.
234
+ */
235
+ declare function runStaticAnalysis(evidenceList: A11yFileEvidence[], opts?: StaticAnalysisOptions): AccessibilityFinding[];
236
+
237
+ interface RuntimeElement {
238
+ tag: string;
239
+ role?: string;
240
+ /** Accessible name — aria-label or visible text */
241
+ name?: string;
242
+ /** Best selector available */
243
+ selector: string;
244
+ testId?: string;
245
+ /** Testability score 0–100 */
246
+ score: number;
247
+ }
248
+ interface RuntimeRouteEvidence {
249
+ url: string;
250
+ route: string;
251
+ status: 'reachable' | 'error' | 'timeout' | 'auth-required';
252
+ title?: string;
253
+ domSnapshotPath?: string;
254
+ accessibilityTreePath?: string;
255
+ screenshotPath?: string;
256
+ interactiveElements: RuntimeElement[];
257
+ consoleErrors: string[];
258
+ loadTimeMs: number;
259
+ }
260
+ interface RuntimeDiscoveryResult {
261
+ routes: RuntimeRouteEvidence[];
262
+ scannedRoutes: number;
263
+ reachable: number;
264
+ errored: number;
265
+ }
266
+ interface TestabilityFinding {
267
+ route: string;
268
+ url: string;
269
+ element: RuntimeElement;
270
+ score: number;
271
+ issues: string[];
272
+ }
273
+ interface RouteTestabilityResult {
274
+ route: string;
275
+ url: string;
276
+ status: RuntimeRouteEvidence['status'];
277
+ score: number;
278
+ totalElements: number;
279
+ flaggedCount: number;
280
+ findings: TestabilityFinding[];
281
+ }
282
+ interface TestabilityReport {
283
+ generatedAt: string;
284
+ minimumScore: number;
285
+ routes: RouteTestabilityResult[];
286
+ overall: {
287
+ score: number;
288
+ totalElements: number;
289
+ flaggedCount: number;
290
+ };
291
+ }
292
+ /**
293
+ * Compute a testability report from Playwright runtime discovery evidence.
294
+ * Only elements with score < minimumScore are reported as findings.
295
+ */
296
+ declare function buildTestabilityReport(result: RuntimeDiscoveryResult, minimumScore?: number): TestabilityReport;
297
+ /**
298
+ * Group findings by severity bucket for quick summary display.
299
+ */
300
+ declare function summarizeReport(report: TestabilityReport): {
301
+ critical: RouteTestabilityResult[];
302
+ warning: RouteTestabilityResult[];
303
+ healthy: RouteTestabilityResult[];
304
+ };
305
+
306
+ declare function deriveTestIdSuggestion(label: string | undefined, elementType: string): string;
307
+ /**
308
+ * Compute the Tag Maturity Level for a single interactive element.
309
+ *
310
+ * The function is pure — it does not read files or call external APIs.
311
+ * Inventory and runtime signals are optional; when absent the assessment
312
+ * is based entirely on static selector evidence.
313
+ */
314
+ declare function assessTagMaturity(input: TagMaturityInput): TagMaturityResult;
315
+
316
+ /** Build a set of testId values that appear more than once in the inventory. */
317
+ declare function buildDuplicateSet(inventory: TestIdInventory): Set<string>;
318
+ declare function isValidTmlNaming(testId: string): boolean;
319
+ /**
320
+ * Find inventory metadata for a given testId across all routes.
321
+ * Returns undefined when the testId is not registered.
322
+ */
323
+ declare function buildTmlInventoryEntry(testId: string, inventory: TestIdInventory, duplicateIds: Set<string>): TmlInventoryEntry | undefined;
324
+ interface EnrichableElement$1 {
325
+ testabilityScore: number;
326
+ ambiguous: boolean;
327
+ label?: string;
328
+ type: string;
329
+ selectors: {
330
+ dataTestId?: string;
331
+ };
332
+ selectorRanking: Array<{
333
+ strategy: string;
334
+ }>;
335
+ tml?: unknown;
336
+ }
337
+ /**
338
+ * Re-compute TML for all elements, enriching with inventory metadata.
339
+ * Mutates each element's `tml` field in place.
340
+ *
341
+ * Call this after `analyze()` when a TestId Inventory is available.
342
+ */
343
+ declare function enrichTmlWithInventory(results: Array<{
344
+ interactiveElements: EnrichableElement$1[];
345
+ }>, inventory: TestIdInventory): void;
346
+
347
+ interface RuntimeEl {
348
+ tag: string;
349
+ testId?: string;
350
+ name?: string;
351
+ selector: string;
352
+ }
353
+ interface RouteEvidence {
354
+ route: string;
355
+ status: string;
356
+ interactiveElements: RuntimeEl[];
357
+ }
358
+ interface RuntimeMap {
359
+ routes: RouteEvidence[];
360
+ }
361
+ interface EnrichableSelector {
362
+ dataTestId?: string;
363
+ ariaLabel?: string;
364
+ id?: string;
365
+ }
366
+ interface EnrichableElement {
367
+ testabilityScore: number;
368
+ ambiguous: boolean;
369
+ label?: string;
370
+ type: string;
371
+ selectors: EnrichableSelector;
372
+ selectorRanking: Array<{
373
+ strategy: string;
374
+ }>;
375
+ tml?: unknown;
376
+ }
377
+ /**
378
+ * Re-compute TML for all elements using Playwright runtime evidence from
379
+ * `selfcure discover --runtime`. Mutates each element's `tml` field in place.
380
+ *
381
+ * Pass the same `inventory` used in `enrichTmlWithInventory()` to preserve
382
+ * governance signals while adding runtime caps.
383
+ *
384
+ * Effects per element:
385
+ * - Observed + unique → confidence boost; static/inventory level preserved.
386
+ * - Observed + not unique → cap at TML 1 (locator ambiguous in live page).
387
+ * - Not observed → cap at TML 2 (element absent in rendered DOM).
388
+ */
389
+ declare function enrichTmlWithRuntime(results: Array<{
390
+ interactiveElements: EnrichableElement[];
391
+ }>, runtimeMap: RuntimeMap, inventory?: TestIdInventory): void;
392
+ declare function loadRuntimeMap(filePath: string): Promise<RuntimeMap>;
393
+
394
+ type FindingsParseResult = {
395
+ ok: true;
396
+ inventory: FindingInventory;
397
+ } | {
398
+ ok: false;
399
+ errors: string[];
400
+ };
401
+ declare function parseFindings(raw: string): FindingsParseResult;
402
+ declare function loadFindings(filePath: string): Promise<FindingsParseResult>;
403
+ declare function saveFindings(filePath: string, inventory: FindingInventory): Promise<void>;
404
+ declare function emptyInventory(opts: {
405
+ app: string;
406
+ targetLevel?: WcagLevel;
407
+ }): FindingInventory;
408
+ /**
409
+ * Merge findings from a new static scan into the existing inventory.
410
+ *
411
+ * Rules:
412
+ * - Suppressed findings are never touched.
413
+ * - Existing open/resolved findings that still appear → status 'open', lastSeenAt updated.
414
+ * - Existing open findings that no longer appear → status 'resolved'.
415
+ * - Previously resolved findings that reappear → status 'open', lastSeenAt updated.
416
+ * - New findings not in inventory → appended as 'open'.
417
+ *
418
+ * Match key: ruleId + sourceFile + line + column.
419
+ */
420
+ declare function mergeFindings(existing: FindingInventory, newFindings: AccessibilityFinding[]): FindingInventory;
421
+
422
+ type SeverityCounts = Record<A11ySeverity, number>;
423
+ interface AuditCounts {
424
+ open: number;
425
+ resolved: number;
426
+ suppressed: number;
427
+ bySeverity: SeverityCounts;
428
+ }
429
+ interface AuditResult {
430
+ /** All findings (open + resolved + suppressed) from the inventory. */
431
+ findings: AccessibilityFinding[];
432
+ counts: AuditCounts;
433
+ /**
434
+ * True when at least one open finding has severity >= failOn.
435
+ * Use this to decide the CI exit code.
436
+ */
437
+ wouldFailCI: boolean;
438
+ }
439
+ interface AuditOptions {
440
+ /**
441
+ * Minimum severity that triggers a CI failure.
442
+ * Findings below this threshold are reported but do not fail.
443
+ * Default: 'major'.
444
+ */
445
+ failOn?: A11ySeverity;
446
+ }
447
+ /**
448
+ * Audit a findings inventory: compute lifecycle counts and determine whether
449
+ * the build should fail in CI mode.
450
+ */
451
+ declare function runAudit(inventory: FindingInventory, opts?: AuditOptions): AuditResult;
452
+
453
+ /** One flagged element, normalised from a lint issue. */
454
+ interface IdePromptIssue {
455
+ /** Path to the source file containing the element. */
456
+ filePath: string;
457
+ /** Component the element belongs to, when known. */
458
+ componentName?: string;
459
+ /** Element kind: button / input / link / form / custom. */
460
+ elementType: string;
461
+ /** The element's current best selector (helps the agent locate it). */
462
+ selector?: string;
463
+ /** 1-based source line, when known. */
464
+ line?: number;
465
+ /**
466
+ * Why it was flagged:
467
+ * • 'ambiguous' — best selector also matches a sibling.
468
+ * • 'low-score' — no stable selector (testability below threshold).
469
+ */
470
+ kind: 'ambiguous' | 'low-score';
471
+ /** Human-readable reason when kind === 'ambiguous'. */
472
+ ambiguityReason?: string;
473
+ /** The data-testid selfcure suggests for this element. */
474
+ suggestedTestId: string;
475
+ }
476
+ interface IdePromptOptions {
477
+ /** Naming convention shown to the agent. Has a sensible default. */
478
+ convention?: string;
479
+ /** Relativise file paths against this directory (e.g. the project root). */
480
+ baseDir?: string;
481
+ }
482
+ /**
483
+ * Build a paste-ready prompt instructing an IDE AI agent (Copilot, Cursor,
484
+ * Claude Code, …) to add `data-testid` attributes to the flagged elements.
485
+ * Returns an empty string when there are no issues.
486
+ */
487
+ declare function buildIdePrompt(issues: IdePromptIssue[], opts?: IdePromptOptions): string;
488
+
489
+ type ElementType = 'button' | 'input' | 'link' | 'form' | 'custom';
490
+ type Complexity = 'low' | 'medium' | 'high';
491
+ interface SelectorCandidate {
492
+ strategy: 'data-testid' | 'id' | 'aria-label' | 'name' | 'css' | 'xpath';
493
+ /** Ready-to-use selector string */
494
+ value: string;
495
+ /** Stability score 0–100: higher = less likely to break on UI changes */
496
+ score: number;
497
+ /** How many elements within the same component match this selector value */
498
+ matchCount?: number;
499
+ /** How many elements across all analysed components match this selector value */
500
+ crossMatchCount?: number;
501
+ /** True when the selector matches more than one element in the same component */
502
+ ambiguous?: boolean;
503
+ }
504
+ interface ElementSelectors {
505
+ dataTestId?: string;
506
+ id?: string;
507
+ ariaLabel?: string;
508
+ name?: string;
509
+ /** Best CSS selector (may alias one of the above) */
510
+ cssSelector: string;
511
+ /** XPath expression */
512
+ xpath: string;
513
+ }
514
+ interface InteractiveElement {
515
+ type: ElementType;
516
+ /** Best selector — always equals selectorRanking[0].value */
517
+ selector: string;
518
+ label?: string;
519
+ /** e.g. ['click', 'fill', 'check'] */
520
+ actions: string[];
521
+ /** All available selectors for this element */
522
+ selectors: ElementSelectors;
523
+ /** Candidates sorted from most stable (index 0) to least stable */
524
+ selectorRanking: SelectorCandidate[];
525
+ /** Testability score for this element 0–100 */
526
+ testabilityScore: number;
527
+ /**
528
+ * True when the best available selector also matches another element in
529
+ * the same component — Playwright would resolve to multiple nodes.
530
+ */
531
+ ambiguous: boolean;
532
+ /** Human-readable explanation when {@link ambiguous} is true */
533
+ ambiguityReason?: string;
534
+ /** Tag Maturity Level assessment — populated by analyze() */
535
+ tml?: TagMaturityResult;
536
+ }
537
+ interface AnalysisResult {
538
+ component: ComponentMeta;
539
+ /** Testability score 0–100 — average of per-element testabilityScore values */
540
+ score: number;
541
+ interactiveElements: InteractiveElement[];
542
+ complexity: Complexity;
543
+ }
544
+ /**
545
+ * Analyse crawled components: classify their interactive elements, compute a
546
+ * testability score, and flag overall complexity.
547
+ */
548
+ declare function analyze(components: ComponentMeta[]): Promise<AnalysisResult[]>;
549
+
550
+ export { type AuditResult as A11yAuditResult, type A11yCategory, type A11ySeverity, type A11ySource, type AccessibilityFinding, type AccessibilityRule, type AnalysisResult, type AuditCounts, type AuditIssue, type AuditOptions, type AuditRuleId, type AuditSummary, type Complexity, type ElementSelectors, type ElementType, type FindingInventory, type FindingStatus, type FindingSuppression, type FindingsParseResult, type IdePromptIssue, type IdePromptOptions, type InteractiveElement, type InventoryElement, type InventoryElementStability, type InventoryElementStatus, type InventoryRoute, type IssueSeverity, LEVEL_HIERARCHY, type NamingViolation, type ParseResult, type RouteTestabilityResult, type RuleFilterOptions, type RuntimeMap, SEVERITY_ORDER, type SelectorCandidate, type SeverityCounts, type StaticAnalysisOptions, TML_LABELS, type TagMaturityChange, type TagMaturityInput, type TagMaturityLabel, type TagMaturityLevel, type TagMaturityReason, type TagMaturityReasonCode, type TagMaturityResult, type AuditResult$1 as TestIdAuditResult, type TestIdInventory, type TestabilityFinding, type TestabilityReport, type TmlInventoryEntry, type WcagLevel, accessibilityRules, allTestIds, analyze, assessTagMaturity, audit, buildDuplicateSet, buildIdePrompt, buildTestabilityReport, buildTmlInventoryEntry, checkNaming, analyze as default, deriveTestIdSuggestion, emptyInventory, enrichTmlWithInventory, enrichTmlWithRuntime, filterRules, getRuleById, getRulesByLevel, getRulesBySeverity, isValidTestId, isValidTmlNaming, loadFindings, loadInventory, loadRuntimeMap, mergeFindings, parseFindings, parseInventory, runAudit, runStaticAnalysis, saveFindings, summarizeReport };