@webability/core 1.1.2 → 1.1.4

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.cts CHANGED
@@ -38,11 +38,25 @@ interface DetectedIssue {
38
38
  imageSrc?: string;
39
39
  /** Optional: outer HTML snippet (first 300 chars) for Claude context. */
40
40
  outerHtml?: string;
41
+ /**
42
+ * Detector-side signal that the finding is ambiguous and should land in
43
+ * `ScanResult.incomplete[]` (e.g. contrast against a gradient). The scanner
44
+ * propagates this to ScanIssue.confidence so the confidence classifier
45
+ * doesn't have to reverse-engineer the situation from HTML strings.
46
+ */
47
+ needsReview?: boolean;
48
+ /** Why this finding needs review — surfaced to MCP/SDK consumers. */
49
+ reviewReason?: string;
41
50
  }
42
51
  /** Every fix detector must implement this interface. */
43
52
  interface FixDetector {
44
53
  name: string;
45
54
  detect(page: PageLike): Promise<DetectedIssue[]>;
55
+ /** Per-page emission cap, when the detector has one. When a run returns
56
+ * >= cap findings the results are TRUNCATED (DOM-order biased) and the
57
+ * scan reports it via ScanResult.truncated — silent truncation reads as
58
+ * "covered everything" when it didn't (loop iter8 / honesty infra). */
59
+ cap?: number;
46
60
  }
47
61
  /**
48
62
  * Browser-runtime detector signature.
@@ -72,6 +86,15 @@ interface SiteTheme {
72
86
  type IssueSource = 'webability' | 'axe-core' | 'deep-analysis';
73
87
  type IssueImpact = 'critical' | 'serious' | 'moderate' | 'minor';
74
88
  type WcagLevel = 'A' | 'AA' | 'AAA';
89
+ /**
90
+ * Confidence tier for a scan finding. Mirrors axe-core's three-tier output —
91
+ * `high` is a confirmed violation safe to act on; `needs_review` is ambiguous
92
+ * (e.g. text on a gradient background, mid-animation opacity, marketing imagery
93
+ * that may legitimately contain text). Consumers should never auto-apply fixes
94
+ * to `needs_review` findings — they belong in the `incomplete[]` bucket and
95
+ * require human judgment.
96
+ */
97
+ type IssueConfidence = 'high' | 'needs_review';
75
98
  interface ScanIssue {
76
99
  id: string;
77
100
  source: IssueSource;
@@ -82,6 +105,10 @@ interface ScanIssue {
82
105
  message: string;
83
106
  selector: string;
84
107
  html?: string;
108
+ /** When set, this issue is ambiguous and lives in `ScanResult.incomplete[]`. */
109
+ confidence?: IssueConfidence;
110
+ /** Why the classifier demoted this issue. Surfaced to MCP/SDK consumers. */
111
+ reviewReason?: string;
85
112
  fix?: {
86
113
  attribute: string;
87
114
  currentValue: string;
@@ -92,13 +119,37 @@ interface ScanIssue {
92
119
  interface ScanResult {
93
120
  url: string;
94
121
  timestamp: string;
122
+ /** High-confidence violations. Safe to surface as bugs. */
95
123
  issues: ScanIssue[];
124
+ /** Detectors that hit their per-page cap this run — their counts are lower
125
+ * bounds, not a census. Additive field; absent = nothing truncated. */
126
+ truncated?: Array<{
127
+ detector: string;
128
+ cap: number;
129
+ }>;
130
+ /**
131
+ * Non-fatal engine subsystem failures that silently disable a category of
132
+ * checks. Consumers MUST surface these to the user — a result with
133
+ * `engineWarnings` is NOT a full scan. Currently: `'color:kernel-injection-failed'`
134
+ * disables all contrast checks for the page. Absent = all subsystems healthy.
135
+ */
136
+ engineWarnings?: string[];
137
+ /** Engine (core package) version that produced this result — provenance */
138
+ engine?: string;
139
+ /**
140
+ * Findings the classifier or axe-core flagged as ambiguous. Show to the user
141
+ * for review — never auto-fix. Empty array (not omitted) when no incompletes,
142
+ * so consumers can rely on the field.
143
+ */
144
+ incomplete: ScanIssue[];
96
145
  summary: {
97
146
  total: number;
98
147
  critical: number;
99
148
  serious: number;
100
149
  moderate: number;
101
150
  minor: number;
151
+ /** Count of items in `incomplete[]`. */
152
+ incomplete: number;
102
153
  };
103
154
  axeResults?: unknown;
104
155
  }
@@ -129,11 +180,27 @@ interface ScanOptions {
129
180
  enableScreenshots?: boolean;
130
181
  /** Scan content inside iframes. Default: false. */
131
182
  includeIframes?: boolean;
183
+ /**
184
+ * Wait for entrance animations to finish before scanning (prevents false
185
+ * contrast failures on mid-fade text). `false` disables, a number sets the
186
+ * wait cap in ms. Default: enabled with a 4000ms cap.
187
+ */
188
+ settle?: boolean | number;
132
189
  }
133
190
 
134
191
  declare function scan(target: string | PageLike, options?: ScanOptions): Promise<ScanResult>;
135
192
 
136
- declare function runDetectors(page: PageLike): Promise<DetectedIssue[]>;
193
+ type TruncationEntry = {
194
+ detector: string;
195
+ cap: number;
196
+ };
197
+ /**
198
+ * `outTruncated` collects which detectors hit their per-page cap THIS call.
199
+ * `outWarnings` collects non-fatal engine subsystem failures (e.g. kernel
200
+ * injection blocked by CSP) that silently disable a category of checks.
201
+ * Both arrays are per-invocation (caller-owned), never module state.
202
+ */
203
+ declare function runDetectors(page: PageLike, outTruncated?: TruncationEntry[], outWarnings?: string[]): Promise<DetectedIssue[]>;
137
204
  declare function extractSiteTheme(page: PageLike): Promise<SiteTheme>;
138
205
 
139
206
  interface AxeViolation {
package/dist/index.d.ts CHANGED
@@ -38,11 +38,25 @@ interface DetectedIssue {
38
38
  imageSrc?: string;
39
39
  /** Optional: outer HTML snippet (first 300 chars) for Claude context. */
40
40
  outerHtml?: string;
41
+ /**
42
+ * Detector-side signal that the finding is ambiguous and should land in
43
+ * `ScanResult.incomplete[]` (e.g. contrast against a gradient). The scanner
44
+ * propagates this to ScanIssue.confidence so the confidence classifier
45
+ * doesn't have to reverse-engineer the situation from HTML strings.
46
+ */
47
+ needsReview?: boolean;
48
+ /** Why this finding needs review — surfaced to MCP/SDK consumers. */
49
+ reviewReason?: string;
41
50
  }
42
51
  /** Every fix detector must implement this interface. */
43
52
  interface FixDetector {
44
53
  name: string;
45
54
  detect(page: PageLike): Promise<DetectedIssue[]>;
55
+ /** Per-page emission cap, when the detector has one. When a run returns
56
+ * >= cap findings the results are TRUNCATED (DOM-order biased) and the
57
+ * scan reports it via ScanResult.truncated — silent truncation reads as
58
+ * "covered everything" when it didn't (loop iter8 / honesty infra). */
59
+ cap?: number;
46
60
  }
47
61
  /**
48
62
  * Browser-runtime detector signature.
@@ -72,6 +86,15 @@ interface SiteTheme {
72
86
  type IssueSource = 'webability' | 'axe-core' | 'deep-analysis';
73
87
  type IssueImpact = 'critical' | 'serious' | 'moderate' | 'minor';
74
88
  type WcagLevel = 'A' | 'AA' | 'AAA';
89
+ /**
90
+ * Confidence tier for a scan finding. Mirrors axe-core's three-tier output —
91
+ * `high` is a confirmed violation safe to act on; `needs_review` is ambiguous
92
+ * (e.g. text on a gradient background, mid-animation opacity, marketing imagery
93
+ * that may legitimately contain text). Consumers should never auto-apply fixes
94
+ * to `needs_review` findings — they belong in the `incomplete[]` bucket and
95
+ * require human judgment.
96
+ */
97
+ type IssueConfidence = 'high' | 'needs_review';
75
98
  interface ScanIssue {
76
99
  id: string;
77
100
  source: IssueSource;
@@ -82,6 +105,10 @@ interface ScanIssue {
82
105
  message: string;
83
106
  selector: string;
84
107
  html?: string;
108
+ /** When set, this issue is ambiguous and lives in `ScanResult.incomplete[]`. */
109
+ confidence?: IssueConfidence;
110
+ /** Why the classifier demoted this issue. Surfaced to MCP/SDK consumers. */
111
+ reviewReason?: string;
85
112
  fix?: {
86
113
  attribute: string;
87
114
  currentValue: string;
@@ -92,13 +119,37 @@ interface ScanIssue {
92
119
  interface ScanResult {
93
120
  url: string;
94
121
  timestamp: string;
122
+ /** High-confidence violations. Safe to surface as bugs. */
95
123
  issues: ScanIssue[];
124
+ /** Detectors that hit their per-page cap this run — their counts are lower
125
+ * bounds, not a census. Additive field; absent = nothing truncated. */
126
+ truncated?: Array<{
127
+ detector: string;
128
+ cap: number;
129
+ }>;
130
+ /**
131
+ * Non-fatal engine subsystem failures that silently disable a category of
132
+ * checks. Consumers MUST surface these to the user — a result with
133
+ * `engineWarnings` is NOT a full scan. Currently: `'color:kernel-injection-failed'`
134
+ * disables all contrast checks for the page. Absent = all subsystems healthy.
135
+ */
136
+ engineWarnings?: string[];
137
+ /** Engine (core package) version that produced this result — provenance */
138
+ engine?: string;
139
+ /**
140
+ * Findings the classifier or axe-core flagged as ambiguous. Show to the user
141
+ * for review — never auto-fix. Empty array (not omitted) when no incompletes,
142
+ * so consumers can rely on the field.
143
+ */
144
+ incomplete: ScanIssue[];
96
145
  summary: {
97
146
  total: number;
98
147
  critical: number;
99
148
  serious: number;
100
149
  moderate: number;
101
150
  minor: number;
151
+ /** Count of items in `incomplete[]`. */
152
+ incomplete: number;
102
153
  };
103
154
  axeResults?: unknown;
104
155
  }
@@ -129,11 +180,27 @@ interface ScanOptions {
129
180
  enableScreenshots?: boolean;
130
181
  /** Scan content inside iframes. Default: false. */
131
182
  includeIframes?: boolean;
183
+ /**
184
+ * Wait for entrance animations to finish before scanning (prevents false
185
+ * contrast failures on mid-fade text). `false` disables, a number sets the
186
+ * wait cap in ms. Default: enabled with a 4000ms cap.
187
+ */
188
+ settle?: boolean | number;
132
189
  }
133
190
 
134
191
  declare function scan(target: string | PageLike, options?: ScanOptions): Promise<ScanResult>;
135
192
 
136
- declare function runDetectors(page: PageLike): Promise<DetectedIssue[]>;
193
+ type TruncationEntry = {
194
+ detector: string;
195
+ cap: number;
196
+ };
197
+ /**
198
+ * `outTruncated` collects which detectors hit their per-page cap THIS call.
199
+ * `outWarnings` collects non-fatal engine subsystem failures (e.g. kernel
200
+ * injection blocked by CSP) that silently disable a category of checks.
201
+ * Both arrays are per-invocation (caller-owned), never module state.
202
+ */
203
+ declare function runDetectors(page: PageLike, outTruncated?: TruncationEntry[], outWarnings?: string[]): Promise<DetectedIssue[]>;
137
204
  declare function extractSiteTheme(page: PageLike): Promise<SiteTheme>;
138
205
 
139
206
  interface AxeViolation {