@forkpoint/agent-lighthouse-core 0.2.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/LICENSE +674 -0
- package/dist/index.d.mts +713 -0
- package/dist/index.d.ts +713 -0
- package/dist/index.js +22510 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +22413 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,713 @@
|
|
|
1
|
+
import { CheerioAPI } from 'cheerio';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
interface FetchOptions {
|
|
5
|
+
url: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
followRedirects?: boolean;
|
|
8
|
+
acceptHeader?: string;
|
|
9
|
+
method?: 'GET' | 'POST' | 'OPTIONS' | 'HEAD';
|
|
10
|
+
body?: string;
|
|
11
|
+
contentType?: string;
|
|
12
|
+
/** External abort (e.g. the per-scan deadline). Combined with the per-request timeout. */
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
interface FetchResult {
|
|
16
|
+
url: string;
|
|
17
|
+
finalUrl: string;
|
|
18
|
+
status: number;
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
body: string;
|
|
21
|
+
ttfbMs: number;
|
|
22
|
+
totalMs: number;
|
|
23
|
+
contentType: string;
|
|
24
|
+
contentLength: number;
|
|
25
|
+
error?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validates that a URL is safe to fetch (http/https scheme, non-private IP).
|
|
29
|
+
* Use before fetching any URL extracted from scanned site content.
|
|
30
|
+
*/
|
|
31
|
+
declare function isSafeUrl(url: string): Promise<boolean>;
|
|
32
|
+
declare function createFetcher(): {
|
|
33
|
+
fetch: (options: FetchOptions) => Promise<FetchResult>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
interface WafProtection {
|
|
37
|
+
isBlocked: boolean;
|
|
38
|
+
provider?: 'akamai' | 'cloudflare' | 'datadome' | 'perimeterx' | 'imperva' | 'kasada' | 'aws-waf' | 'generic-waf' | 'connection-drop';
|
|
39
|
+
name: string;
|
|
40
|
+
reason: string;
|
|
41
|
+
statusCode?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Analyzes fetch results (homepage, root files, extra pages) to determine
|
|
45
|
+
* if the target website is behind a bot protection wall or WAF that drops
|
|
46
|
+
* or challenges automated AI agents.
|
|
47
|
+
*/
|
|
48
|
+
declare function detectWafProtection(targetUrl: string, homepageResult: FetchResult | null, rootFiles: Record<string, FetchResult>, scannedPagesCount: number): WafProtection | null;
|
|
49
|
+
|
|
50
|
+
type PageType = 'homepage' | 'category' | 'product' | 'content';
|
|
51
|
+
declare const PAGE_TYPE_LABELS: Record<PageType, string>;
|
|
52
|
+
/**
|
|
53
|
+
* A user-supplied page to scan with an explicit type.
|
|
54
|
+
*/
|
|
55
|
+
interface PageOverride {
|
|
56
|
+
url: string;
|
|
57
|
+
pageType: PageType;
|
|
58
|
+
}
|
|
59
|
+
/** Per-field presence in a product page's structured data. */
|
|
60
|
+
type FieldStatus = 'found' | 'partial' | 'missing';
|
|
61
|
+
/**
|
|
62
|
+
* Field-level verification of a product page, read directly from its structured
|
|
63
|
+
* data (JSON-LD + Microdata + RDFa).
|
|
64
|
+
*/
|
|
65
|
+
interface ProductFieldVerification {
|
|
66
|
+
sku: FieldStatus;
|
|
67
|
+
gtin: FieldStatus;
|
|
68
|
+
brand: FieldStatus;
|
|
69
|
+
category: FieldStatus;
|
|
70
|
+
availability: FieldStatus;
|
|
71
|
+
priceCurrency: FieldStatus;
|
|
72
|
+
stockLevel: FieldStatus;
|
|
73
|
+
reviewCount: FieldStatus;
|
|
74
|
+
sourceUrl?: string;
|
|
75
|
+
}
|
|
76
|
+
type FixEffort = 'trivial' | 'easy' | 'moderate' | 'complex';
|
|
77
|
+
interface AuditGuidance {
|
|
78
|
+
/** Customer-facing explanation of business impact when this audit fails */
|
|
79
|
+
impact: string;
|
|
80
|
+
/** Actionable, concise instructions to fix the issue */
|
|
81
|
+
fix: string;
|
|
82
|
+
/** Canonical code snippet showing the correct implementation */
|
|
83
|
+
code?: string;
|
|
84
|
+
/** Estimated effort to implement the fix */
|
|
85
|
+
effort: FixEffort;
|
|
86
|
+
/** Link to external documentation or spec */
|
|
87
|
+
docsUrl?: string;
|
|
88
|
+
/** Tags for filtering/grouping in the report UI */
|
|
89
|
+
tags?: string[];
|
|
90
|
+
}
|
|
91
|
+
type ScoreDisplayMode = 'binary' | 'ternary' | 'informative';
|
|
92
|
+
interface AuditMeta {
|
|
93
|
+
id: string;
|
|
94
|
+
category: string;
|
|
95
|
+
title: string;
|
|
96
|
+
failureTitle: string;
|
|
97
|
+
description: string;
|
|
98
|
+
scoreDisplayMode: ScoreDisplayMode;
|
|
99
|
+
weight: number;
|
|
100
|
+
applicablePageTypes?: PageType[];
|
|
101
|
+
defaultPriority: CheckPriority;
|
|
102
|
+
guidance?: AuditGuidance;
|
|
103
|
+
}
|
|
104
|
+
interface AuditResult {
|
|
105
|
+
status: CheckStatus;
|
|
106
|
+
score: number;
|
|
107
|
+
displayValue?: string;
|
|
108
|
+
explanation?: string;
|
|
109
|
+
expected?: string;
|
|
110
|
+
found?: string;
|
|
111
|
+
message?: string;
|
|
112
|
+
details?: {
|
|
113
|
+
expected?: string;
|
|
114
|
+
found?: string;
|
|
115
|
+
code?: string;
|
|
116
|
+
[key: string]: unknown;
|
|
117
|
+
};
|
|
118
|
+
pageUrl?: string;
|
|
119
|
+
priority?: CheckPriority;
|
|
120
|
+
}
|
|
121
|
+
type CheckStatus = 'pass' | 'warn' | 'fail' | 'na';
|
|
122
|
+
type CheckPriority = 'critical' | 'high' | 'medium' | 'low';
|
|
123
|
+
interface CheckRecommendation {
|
|
124
|
+
priority: CheckPriority;
|
|
125
|
+
description: string;
|
|
126
|
+
code?: string;
|
|
127
|
+
docsUrl?: string;
|
|
128
|
+
}
|
|
129
|
+
interface CheckResult {
|
|
130
|
+
id: string;
|
|
131
|
+
category: string;
|
|
132
|
+
title: string;
|
|
133
|
+
description: string;
|
|
134
|
+
status: CheckStatus;
|
|
135
|
+
score: number;
|
|
136
|
+
scoreDisplayMode: ScoreDisplayMode;
|
|
137
|
+
displayValue?: string;
|
|
138
|
+
explanation?: string;
|
|
139
|
+
pageUrl?: string;
|
|
140
|
+
priority: CheckPriority;
|
|
141
|
+
impact: string;
|
|
142
|
+
fix: string;
|
|
143
|
+
details?: {
|
|
144
|
+
expected?: string;
|
|
145
|
+
found?: string;
|
|
146
|
+
code?: string;
|
|
147
|
+
docsUrl?: string;
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
};
|
|
150
|
+
tags?: string[];
|
|
151
|
+
}
|
|
152
|
+
interface CategoryResult {
|
|
153
|
+
id: string;
|
|
154
|
+
name: string;
|
|
155
|
+
weight: number;
|
|
156
|
+
score: number;
|
|
157
|
+
checks: CheckResult[];
|
|
158
|
+
passCount: number;
|
|
159
|
+
warnCount: number;
|
|
160
|
+
failCount: number;
|
|
161
|
+
}
|
|
162
|
+
type ScoreTier = 'agent-ready' | 'partially-ready' | 'needs-work' | 'not-ready';
|
|
163
|
+
interface ScanReport {
|
|
164
|
+
scanId: string;
|
|
165
|
+
url: string;
|
|
166
|
+
domain: string;
|
|
167
|
+
overallScore: number;
|
|
168
|
+
scoreTier: ScoreTier;
|
|
169
|
+
summary?: string;
|
|
170
|
+
categories: CategoryResult[];
|
|
171
|
+
topPasses: CheckResult[];
|
|
172
|
+
topFails: CheckResult[];
|
|
173
|
+
categoryScores?: Record<string, number>;
|
|
174
|
+
checkResults?: CheckResult[];
|
|
175
|
+
recommendations: CheckRecommendation[];
|
|
176
|
+
pagesScanned: Array<{
|
|
177
|
+
url: string;
|
|
178
|
+
pageType: PageType;
|
|
179
|
+
}>;
|
|
180
|
+
pagesData?: Array<{
|
|
181
|
+
url: string;
|
|
182
|
+
pageType: PageType;
|
|
183
|
+
}>;
|
|
184
|
+
scannedAt: string;
|
|
185
|
+
createdAt?: string;
|
|
186
|
+
durationMs: number;
|
|
187
|
+
previousScore?: number;
|
|
188
|
+
scoreDelta?: number;
|
|
189
|
+
readinessScore?: number;
|
|
190
|
+
readinessVitals?: ReadinessVitals;
|
|
191
|
+
productFields?: ProductFieldVerification;
|
|
192
|
+
wafProtection?: WafProtection;
|
|
193
|
+
}
|
|
194
|
+
interface ReadinessVitals {
|
|
195
|
+
commerce: number;
|
|
196
|
+
content: number;
|
|
197
|
+
botAccessibility: number;
|
|
198
|
+
technical: number;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
type ProgressCallback = (pct: number, phase: string) => void | Promise<void>;
|
|
202
|
+
declare function runScan(url: string, onProgress?: ProgressCallback, pageOverrides?: PageOverride[] | null, signal?: AbortSignal): Promise<ScanReport>;
|
|
203
|
+
|
|
204
|
+
interface A11yNodeFinding {
|
|
205
|
+
target: string;
|
|
206
|
+
summary: string;
|
|
207
|
+
}
|
|
208
|
+
type A11yStatus = 'pass' | 'fail' | 'incomplete' | 'inapplicable';
|
|
209
|
+
interface A11yRuleResult {
|
|
210
|
+
status: A11yStatus;
|
|
211
|
+
nodes: A11yNodeFinding[];
|
|
212
|
+
}
|
|
213
|
+
/** ruleId → result for a single page. */
|
|
214
|
+
type A11yPageResult = Record<string, A11yRuleResult>;
|
|
215
|
+
|
|
216
|
+
interface PageContext {
|
|
217
|
+
url: string;
|
|
218
|
+
pageType: PageType;
|
|
219
|
+
fetchResult: FetchResult;
|
|
220
|
+
$: CheerioAPI;
|
|
221
|
+
/** Parsed JSON-LD blocks only (used by JSON-LD-specific audits). */
|
|
222
|
+
jsonLd: object[];
|
|
223
|
+
/**
|
|
224
|
+
* Union of all structured data: JSON-LD + Microdata + RDFa, normalized to
|
|
225
|
+
* schema.org-shaped objects. Product/commerce audits read this so they detect
|
|
226
|
+
* data regardless of the markup format. Optional for backward compatibility;
|
|
227
|
+
* audits fall back to `jsonLd` when absent.
|
|
228
|
+
*/
|
|
229
|
+
structuredData?: object[];
|
|
230
|
+
meta: Record<string, string>;
|
|
231
|
+
headLinks: Array<{
|
|
232
|
+
rel: string;
|
|
233
|
+
type: string;
|
|
234
|
+
href: string;
|
|
235
|
+
title: string;
|
|
236
|
+
}>;
|
|
237
|
+
/**
|
|
238
|
+
* Accessibility rule results for this page (ruleId → status + offending
|
|
239
|
+
* nodes), populated by the orchestrator. Consumed by the accessibility
|
|
240
|
+
* audits. Absent if the a11y run failed or was skipped.
|
|
241
|
+
*/
|
|
242
|
+
a11yResults?: A11yPageResult;
|
|
243
|
+
}
|
|
244
|
+
interface CheckContext {
|
|
245
|
+
rootFiles: Record<string, FetchResult>;
|
|
246
|
+
pages: PageContext[];
|
|
247
|
+
domain: string;
|
|
248
|
+
baseUrl: string;
|
|
249
|
+
fetch: (options: FetchOptions) => Promise<FetchResult>;
|
|
250
|
+
wafProtection?: WafProtection;
|
|
251
|
+
}
|
|
252
|
+
type CheckFn = (ctx: CheckContext) => CheckResult | Promise<CheckResult>;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Base class for all audits. Follows the Lighthouse pattern:
|
|
256
|
+
* each audit is a class with a static `meta` descriptor and
|
|
257
|
+
* an `audit()` method that receives the scan context.
|
|
258
|
+
*/
|
|
259
|
+
declare abstract class Audit {
|
|
260
|
+
static meta: AuditMeta;
|
|
261
|
+
private static readonly PRIORITY_MAP;
|
|
262
|
+
/** Validate an audit result against the schema. */
|
|
263
|
+
protected validate(result: AuditResult): AuditResult;
|
|
264
|
+
/** Run the audit and return a result. */
|
|
265
|
+
abstract audit(ctx: CheckContext): AuditResult | Promise<AuditResult>;
|
|
266
|
+
/** Create a passing result. */
|
|
267
|
+
protected pass(message: string, expected: string, found: string, pageUrl?: string): AuditResult;
|
|
268
|
+
/**
|
|
269
|
+
* Create a not-applicable result. Use when the audit's precondition is
|
|
270
|
+
* absent (e.g. a quality check on a feature the site doesn't implement at
|
|
271
|
+
* all). Excluded from score aggregation so it neither inflates nor deflates
|
|
272
|
+
* the category score — unlike a vacuous `pass()`, which rewards absence.
|
|
273
|
+
*/
|
|
274
|
+
protected notApplicable(message: string, expected: string, found: string, pageUrl?: string): AuditResult;
|
|
275
|
+
/** Create a warning result. */
|
|
276
|
+
protected warn(message: string, expected: string, found: string, recommendationOrPriority?: {
|
|
277
|
+
priority: CheckPriority;
|
|
278
|
+
[key: string]: unknown;
|
|
279
|
+
} | string, pageUrl?: string): AuditResult;
|
|
280
|
+
/** Create a failing result. */
|
|
281
|
+
protected fail(message: string, expected: string, found: string, recommendationOrPriority?: {
|
|
282
|
+
priority: CheckPriority;
|
|
283
|
+
[key: string]: unknown;
|
|
284
|
+
} | string, pageUrl?: string): AuditResult;
|
|
285
|
+
/** Merge static meta with the runtime result to produce a CheckResult. */
|
|
286
|
+
toCheckResult(rawResult: AuditResult): CheckResult;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
interface CategoryConfig {
|
|
290
|
+
id: string;
|
|
291
|
+
name: string;
|
|
292
|
+
/** Weight in the overall score (all weights should sum to 1.0). */
|
|
293
|
+
weight: number;
|
|
294
|
+
}
|
|
295
|
+
interface AuditRegistration {
|
|
296
|
+
/** Construct an audit instance. */
|
|
297
|
+
create: () => Audit;
|
|
298
|
+
/** The audit's static meta (copied here for fast access without instantiation). */
|
|
299
|
+
meta: AuditMeta;
|
|
300
|
+
}
|
|
301
|
+
interface ScanConfig {
|
|
302
|
+
categories: CategoryConfig[];
|
|
303
|
+
/** categoryId → list of audit registrations */
|
|
304
|
+
audits: Record<string, AuditRegistration[]>;
|
|
305
|
+
}
|
|
306
|
+
declare const defaultConfig: ScanConfig;
|
|
307
|
+
|
|
308
|
+
interface AuditRunResult {
|
|
309
|
+
checks: CheckResult[];
|
|
310
|
+
categories: CategoryResult[];
|
|
311
|
+
overallScore: number;
|
|
312
|
+
}
|
|
313
|
+
type ProgressFn = (completed: number, total: number) => void;
|
|
314
|
+
/**
|
|
315
|
+
* Execute all audits registered in the config against the scan context.
|
|
316
|
+
* Returns check results grouped into categories with weighted scores.
|
|
317
|
+
*/
|
|
318
|
+
declare function runAudits(ctx: CheckContext, config: ScanConfig, onProgress?: ProgressFn): Promise<AuditRunResult>;
|
|
319
|
+
|
|
320
|
+
declare function parseHtml(html: string): CheerioAPI;
|
|
321
|
+
declare function extractJsonLd($: CheerioAPI): object[];
|
|
322
|
+
/**
|
|
323
|
+
* Flatten parsed JSON-LD into a flat list of schema.org nodes.
|
|
324
|
+
*
|
|
325
|
+
* Real-world JSON-LD nests the interesting types arbitrarily: a top-level
|
|
326
|
+
* `[{...}]` array (common on Shopify), an `@graph` container, and properties
|
|
327
|
+
* like `Product.aggregateRating`, `ProductGroup.hasVariant[].aggregateRating`,
|
|
328
|
+
* `mainEntity`, `itemReviewed`, `offers`. The previous per-audit flatteners
|
|
329
|
+
* only descended into `@graph`, so anything array-wrapped or nested was
|
|
330
|
+
* invisible — producing false "schema not found" verdicts. This walks every
|
|
331
|
+
* object and array value so type/property lookups see the whole graph.
|
|
332
|
+
*/
|
|
333
|
+
declare function flattenJsonLd(blocks: object[]): object[];
|
|
334
|
+
/**
|
|
335
|
+
* Extract links from Markdown-ish text (llms.txt, READMEs).
|
|
336
|
+
*
|
|
337
|
+
* Real llms.txt files use many shapes the old line-anchored
|
|
338
|
+
* `^-\s*\[label\](url)` regex missed entirely: inline links inside prose,
|
|
339
|
+
* bare-URL bullets (`- **Privacy**: https://…`), `*`/`+`/numbered bullets, and
|
|
340
|
+
* indented/nested items. Returns `{ url, label, description }`, trimming the
|
|
341
|
+
* trailing punctuation/markup (backticks, brackets, periods) that otherwise
|
|
342
|
+
* corrupts the URL.
|
|
343
|
+
*/
|
|
344
|
+
declare function extractMarkdownLinks(body: string): Array<{
|
|
345
|
+
url: string;
|
|
346
|
+
label: string;
|
|
347
|
+
description: string;
|
|
348
|
+
}>;
|
|
349
|
+
declare function extractMetaTags($: CheerioAPI): Record<string, string>;
|
|
350
|
+
interface HeadLink {
|
|
351
|
+
rel: string;
|
|
352
|
+
type: string;
|
|
353
|
+
href: string;
|
|
354
|
+
title: string;
|
|
355
|
+
}
|
|
356
|
+
declare function extractHeadLinks($: CheerioAPI): HeadLink[];
|
|
357
|
+
declare function extractHeadings($: CheerioAPI): Array<{
|
|
358
|
+
level: number;
|
|
359
|
+
text: string;
|
|
360
|
+
}>;
|
|
361
|
+
declare function getMainContentText($: CheerioAPI): string;
|
|
362
|
+
declare function getWordCount($: CheerioAPI): number;
|
|
363
|
+
declare function extractImages($: CheerioAPI): Array<{
|
|
364
|
+
src: string;
|
|
365
|
+
alt: string;
|
|
366
|
+
hasAlt: boolean;
|
|
367
|
+
width?: string;
|
|
368
|
+
height?: string;
|
|
369
|
+
loading?: string;
|
|
370
|
+
role?: string;
|
|
371
|
+
}>;
|
|
372
|
+
declare function extractForms($: CheerioAPI): Array<{
|
|
373
|
+
action: string;
|
|
374
|
+
method: string;
|
|
375
|
+
inputs: Array<{
|
|
376
|
+
name: string;
|
|
377
|
+
type: string;
|
|
378
|
+
label?: string;
|
|
379
|
+
required: boolean;
|
|
380
|
+
}>;
|
|
381
|
+
}>;
|
|
382
|
+
declare function extractInternalLinks($: CheerioAPI, domain: string): string[];
|
|
383
|
+
declare function extractNavLinks($: CheerioAPI): string[];
|
|
384
|
+
declare function extractScripts($: CheerioAPI): Array<{
|
|
385
|
+
src?: string;
|
|
386
|
+
async: boolean;
|
|
387
|
+
defer: boolean;
|
|
388
|
+
type?: string;
|
|
389
|
+
isModule: boolean;
|
|
390
|
+
noModule: boolean;
|
|
391
|
+
inline: boolean;
|
|
392
|
+
}>;
|
|
393
|
+
declare function extractStylesheetUrls($: CheerioAPI): string[];
|
|
394
|
+
/**
|
|
395
|
+
* Detect whether a page is a Homepage, Category Page, Product Details Page,
|
|
396
|
+
* or Content Page based on URL patterns, JSON-LD schemas, meta tags, and
|
|
397
|
+
* HTML signals typical of ecommerce websites.
|
|
398
|
+
*/
|
|
399
|
+
declare function detectPageType(url: string, $: CheerioAPI, jsonLd: object[], meta: Record<string, string>, isFirstPage: boolean): PageType;
|
|
400
|
+
|
|
401
|
+
declare const DEFAULT_SCAN_LIMIT = 5;
|
|
402
|
+
declare const MAX_PAGES_PER_SCAN = 6;
|
|
403
|
+
declare const REQUEST_TIMEOUT_MS = 10000;
|
|
404
|
+
declare const SCAN_TIMEOUT_MS = 60000;
|
|
405
|
+
declare const MAX_RESPONSE_BODY_BYTES: number;
|
|
406
|
+
declare const MAX_CONCURRENT_REQUESTS = 10;
|
|
407
|
+
declare const SCANNER_USER_AGENT = "AgentLighthouse/1.0 (+https://github.com/ForkPoint/agent-lighthouse)";
|
|
408
|
+
declare const TAG_SKIPPED_PAGE_TYPE = "skipped:page-type";
|
|
409
|
+
declare const TAG_SCAN_ERROR = "scan-error";
|
|
410
|
+
declare const CATEGORY_WEIGHTS: Record<string, number>;
|
|
411
|
+
declare const CATEGORY_NAMES: Record<string, string>;
|
|
412
|
+
declare const READINESS_WEIGHTS: {
|
|
413
|
+
readonly commerce: 0.4;
|
|
414
|
+
readonly content: 0.25;
|
|
415
|
+
readonly botAccessibility: 0.2;
|
|
416
|
+
readonly technical: 0.15;
|
|
417
|
+
};
|
|
418
|
+
declare function getScoreTier(score: number): ScoreTier;
|
|
419
|
+
declare const SCORE_TIER_LABELS: Record<ScoreTier, string>;
|
|
420
|
+
declare function getTierLabel(tier: string | null): string;
|
|
421
|
+
declare function getTierColor(tier: string | null): string;
|
|
422
|
+
|
|
423
|
+
declare function calculateCategoryScore(checks: CheckResult[]): number;
|
|
424
|
+
declare function buildCategoryResult(id: string, checks: CheckResult[]): CategoryResult;
|
|
425
|
+
declare function calculateOverallScore(categories: CategoryResult[]): number;
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Read product fields straight from the scanned product page(s)' structured
|
|
429
|
+
* data. Looks only at pages typed `product` (the user-supplied product page in
|
|
430
|
+
* full-report mode), mirroring how a search engine parses that page.
|
|
431
|
+
*/
|
|
432
|
+
declare function extractProductFieldVerification(pages: PageContext[]): ProductFieldVerification;
|
|
433
|
+
|
|
434
|
+
declare const CheckStatusSchema: z.ZodEnum<["pass", "warn", "fail", "na"]>;
|
|
435
|
+
declare const CheckPrioritySchema: z.ZodEnum<["critical", "high", "medium", "low"]>;
|
|
436
|
+
declare const AuditResultSchema: z.ZodObject<{
|
|
437
|
+
status: z.ZodEnum<["pass", "warn", "fail", "na"]>;
|
|
438
|
+
score: z.ZodNumber;
|
|
439
|
+
displayValue: z.ZodOptional<z.ZodString>;
|
|
440
|
+
explanation: z.ZodOptional<z.ZodString>;
|
|
441
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
442
|
+
found: z.ZodOptional<z.ZodString>;
|
|
443
|
+
message: z.ZodOptional<z.ZodString>;
|
|
444
|
+
details: z.ZodOptional<z.ZodObject<{
|
|
445
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
446
|
+
found: z.ZodOptional<z.ZodString>;
|
|
447
|
+
code: z.ZodOptional<z.ZodString>;
|
|
448
|
+
}, "strip", z.ZodTypeAny, {
|
|
449
|
+
code?: string | undefined;
|
|
450
|
+
found?: string | undefined;
|
|
451
|
+
expected?: string | undefined;
|
|
452
|
+
}, {
|
|
453
|
+
code?: string | undefined;
|
|
454
|
+
found?: string | undefined;
|
|
455
|
+
expected?: string | undefined;
|
|
456
|
+
}>>;
|
|
457
|
+
pageUrl: z.ZodUnion<[z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodString]>, z.ZodString]>;
|
|
458
|
+
priority: z.ZodOptional<z.ZodEnum<["critical", "high", "medium", "low"]>>;
|
|
459
|
+
code: z.ZodOptional<z.ZodString>;
|
|
460
|
+
}, "strip", z.ZodTypeAny, {
|
|
461
|
+
status: "warn" | "pass" | "fail" | "na";
|
|
462
|
+
score: number;
|
|
463
|
+
code?: string | undefined;
|
|
464
|
+
found?: string | undefined;
|
|
465
|
+
expected?: string | undefined;
|
|
466
|
+
details?: {
|
|
467
|
+
code?: string | undefined;
|
|
468
|
+
found?: string | undefined;
|
|
469
|
+
expected?: string | undefined;
|
|
470
|
+
} | undefined;
|
|
471
|
+
message?: string | undefined;
|
|
472
|
+
displayValue?: string | undefined;
|
|
473
|
+
explanation?: string | undefined;
|
|
474
|
+
pageUrl?: string | undefined;
|
|
475
|
+
priority?: "critical" | "high" | "medium" | "low" | undefined;
|
|
476
|
+
}, {
|
|
477
|
+
status: "warn" | "pass" | "fail" | "na";
|
|
478
|
+
score: number;
|
|
479
|
+
code?: string | undefined;
|
|
480
|
+
found?: string | undefined;
|
|
481
|
+
expected?: string | undefined;
|
|
482
|
+
details?: {
|
|
483
|
+
code?: string | undefined;
|
|
484
|
+
found?: string | undefined;
|
|
485
|
+
expected?: string | undefined;
|
|
486
|
+
} | undefined;
|
|
487
|
+
message?: string | undefined;
|
|
488
|
+
displayValue?: string | undefined;
|
|
489
|
+
explanation?: string | undefined;
|
|
490
|
+
pageUrl?: string | undefined;
|
|
491
|
+
priority?: "critical" | "high" | "medium" | "low" | undefined;
|
|
492
|
+
}>;
|
|
493
|
+
declare const FixEffortSchema: z.ZodEnum<["trivial", "easy", "moderate", "complex"]>;
|
|
494
|
+
declare const AuditGuidanceSchema: z.ZodObject<{
|
|
495
|
+
impact: z.ZodString;
|
|
496
|
+
fix: z.ZodString;
|
|
497
|
+
code: z.ZodOptional<z.ZodString>;
|
|
498
|
+
effort: z.ZodEnum<["trivial", "easy", "moderate", "complex"]>;
|
|
499
|
+
docsUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodString]>;
|
|
500
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
501
|
+
}, "strip", z.ZodTypeAny, {
|
|
502
|
+
impact: string;
|
|
503
|
+
fix: string;
|
|
504
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
505
|
+
code?: string | undefined;
|
|
506
|
+
docsUrl?: string | undefined;
|
|
507
|
+
tags?: string[] | undefined;
|
|
508
|
+
}, {
|
|
509
|
+
impact: string;
|
|
510
|
+
fix: string;
|
|
511
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
512
|
+
code?: string | undefined;
|
|
513
|
+
docsUrl?: string | undefined;
|
|
514
|
+
tags?: string[] | undefined;
|
|
515
|
+
}>;
|
|
516
|
+
declare const ScoreDisplayModeSchema: z.ZodEnum<["binary", "ternary", "informative"]>;
|
|
517
|
+
declare const AuditMetaSchema: z.ZodObject<{
|
|
518
|
+
id: z.ZodString;
|
|
519
|
+
category: z.ZodString;
|
|
520
|
+
title: z.ZodString;
|
|
521
|
+
failureTitle: z.ZodString;
|
|
522
|
+
description: z.ZodString;
|
|
523
|
+
scoreDisplayMode: z.ZodEnum<["binary", "ternary", "informative"]>;
|
|
524
|
+
weight: z.ZodNumber;
|
|
525
|
+
applicablePageTypes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
526
|
+
defaultPriority: z.ZodEnum<["critical", "high", "medium", "low"]>;
|
|
527
|
+
guidance: z.ZodOptional<z.ZodObject<{
|
|
528
|
+
impact: z.ZodString;
|
|
529
|
+
fix: z.ZodString;
|
|
530
|
+
code: z.ZodOptional<z.ZodString>;
|
|
531
|
+
effort: z.ZodEnum<["trivial", "easy", "moderate", "complex"]>;
|
|
532
|
+
docsUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodString]>;
|
|
533
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
534
|
+
}, "strip", z.ZodTypeAny, {
|
|
535
|
+
impact: string;
|
|
536
|
+
fix: string;
|
|
537
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
538
|
+
code?: string | undefined;
|
|
539
|
+
docsUrl?: string | undefined;
|
|
540
|
+
tags?: string[] | undefined;
|
|
541
|
+
}, {
|
|
542
|
+
impact: string;
|
|
543
|
+
fix: string;
|
|
544
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
545
|
+
code?: string | undefined;
|
|
546
|
+
docsUrl?: string | undefined;
|
|
547
|
+
tags?: string[] | undefined;
|
|
548
|
+
}>>;
|
|
549
|
+
}, "strip", z.ZodTypeAny, {
|
|
550
|
+
category: string;
|
|
551
|
+
title: string;
|
|
552
|
+
id: string;
|
|
553
|
+
failureTitle: string;
|
|
554
|
+
description: string;
|
|
555
|
+
scoreDisplayMode: "binary" | "ternary" | "informative";
|
|
556
|
+
weight: number;
|
|
557
|
+
defaultPriority: "critical" | "high" | "medium" | "low";
|
|
558
|
+
applicablePageTypes?: string[] | undefined;
|
|
559
|
+
guidance?: {
|
|
560
|
+
impact: string;
|
|
561
|
+
fix: string;
|
|
562
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
563
|
+
code?: string | undefined;
|
|
564
|
+
docsUrl?: string | undefined;
|
|
565
|
+
tags?: string[] | undefined;
|
|
566
|
+
} | undefined;
|
|
567
|
+
}, {
|
|
568
|
+
category: string;
|
|
569
|
+
title: string;
|
|
570
|
+
id: string;
|
|
571
|
+
failureTitle: string;
|
|
572
|
+
description: string;
|
|
573
|
+
scoreDisplayMode: "binary" | "ternary" | "informative";
|
|
574
|
+
weight: number;
|
|
575
|
+
defaultPriority: "critical" | "high" | "medium" | "low";
|
|
576
|
+
applicablePageTypes?: string[] | undefined;
|
|
577
|
+
guidance?: {
|
|
578
|
+
impact: string;
|
|
579
|
+
fix: string;
|
|
580
|
+
effort: "trivial" | "easy" | "moderate" | "complex";
|
|
581
|
+
code?: string | undefined;
|
|
582
|
+
docsUrl?: string | undefined;
|
|
583
|
+
tags?: string[] | undefined;
|
|
584
|
+
} | undefined;
|
|
585
|
+
}>;
|
|
586
|
+
declare const CheckResultSchema: z.ZodObject<{
|
|
587
|
+
id: z.ZodString;
|
|
588
|
+
category: z.ZodString;
|
|
589
|
+
title: z.ZodString;
|
|
590
|
+
description: z.ZodString;
|
|
591
|
+
status: z.ZodEnum<["pass", "warn", "fail", "na"]>;
|
|
592
|
+
score: z.ZodNumber;
|
|
593
|
+
scoreDisplayMode: z.ZodEnum<["binary", "ternary", "informative"]>;
|
|
594
|
+
displayValue: z.ZodOptional<z.ZodString>;
|
|
595
|
+
explanation: z.ZodOptional<z.ZodString>;
|
|
596
|
+
pageUrl: z.ZodUnion<[z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodString]>, z.ZodString]>;
|
|
597
|
+
priority: z.ZodEnum<["critical", "high", "medium", "low"]>;
|
|
598
|
+
impact: z.ZodString;
|
|
599
|
+
fix: z.ZodString;
|
|
600
|
+
details: z.ZodOptional<z.ZodObject<{
|
|
601
|
+
expected: z.ZodOptional<z.ZodString>;
|
|
602
|
+
found: z.ZodOptional<z.ZodString>;
|
|
603
|
+
code: z.ZodOptional<z.ZodString>;
|
|
604
|
+
docsUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodString]>;
|
|
605
|
+
}, "strip", z.ZodTypeAny, {
|
|
606
|
+
code?: string | undefined;
|
|
607
|
+
found?: string | undefined;
|
|
608
|
+
expected?: string | undefined;
|
|
609
|
+
docsUrl?: string | undefined;
|
|
610
|
+
}, {
|
|
611
|
+
code?: string | undefined;
|
|
612
|
+
found?: string | undefined;
|
|
613
|
+
expected?: string | undefined;
|
|
614
|
+
docsUrl?: string | undefined;
|
|
615
|
+
}>>;
|
|
616
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
617
|
+
}, "strip", z.ZodTypeAny, {
|
|
618
|
+
status: "warn" | "pass" | "fail" | "na";
|
|
619
|
+
category: string;
|
|
620
|
+
title: string;
|
|
621
|
+
id: string;
|
|
622
|
+
score: number;
|
|
623
|
+
priority: "critical" | "high" | "medium" | "low";
|
|
624
|
+
impact: string;
|
|
625
|
+
fix: string;
|
|
626
|
+
description: string;
|
|
627
|
+
scoreDisplayMode: "binary" | "ternary" | "informative";
|
|
628
|
+
details?: {
|
|
629
|
+
code?: string | undefined;
|
|
630
|
+
found?: string | undefined;
|
|
631
|
+
expected?: string | undefined;
|
|
632
|
+
docsUrl?: string | undefined;
|
|
633
|
+
} | undefined;
|
|
634
|
+
displayValue?: string | undefined;
|
|
635
|
+
explanation?: string | undefined;
|
|
636
|
+
pageUrl?: string | undefined;
|
|
637
|
+
tags?: string[] | undefined;
|
|
638
|
+
}, {
|
|
639
|
+
status: "warn" | "pass" | "fail" | "na";
|
|
640
|
+
category: string;
|
|
641
|
+
title: string;
|
|
642
|
+
id: string;
|
|
643
|
+
score: number;
|
|
644
|
+
priority: "critical" | "high" | "medium" | "low";
|
|
645
|
+
impact: string;
|
|
646
|
+
fix: string;
|
|
647
|
+
description: string;
|
|
648
|
+
scoreDisplayMode: "binary" | "ternary" | "informative";
|
|
649
|
+
details?: {
|
|
650
|
+
code?: string | undefined;
|
|
651
|
+
found?: string | undefined;
|
|
652
|
+
expected?: string | undefined;
|
|
653
|
+
docsUrl?: string | undefined;
|
|
654
|
+
} | undefined;
|
|
655
|
+
displayValue?: string | undefined;
|
|
656
|
+
explanation?: string | undefined;
|
|
657
|
+
pageUrl?: string | undefined;
|
|
658
|
+
tags?: string[] | undefined;
|
|
659
|
+
}>;
|
|
660
|
+
|
|
661
|
+
declare function normalizeUrl(input: string): string;
|
|
662
|
+
declare function joinUrl(base: string, path: string): string;
|
|
663
|
+
declare function extractDomain(url: string): string;
|
|
664
|
+
declare function isPrivateIp(ip: string): boolean;
|
|
665
|
+
|
|
666
|
+
type PresetName = 'ecommerce' | 'saas' | 'content' | 'quick' | 'full';
|
|
667
|
+
interface PresetOptions {
|
|
668
|
+
name: PresetName;
|
|
669
|
+
description: string;
|
|
670
|
+
categoryFilter?: string[];
|
|
671
|
+
customWeights?: Record<string, number>;
|
|
672
|
+
maxPages?: number;
|
|
673
|
+
}
|
|
674
|
+
declare const PRESETS: Record<PresetName, PresetOptions>;
|
|
675
|
+
declare function getPreset(name?: string | null): PresetOptions;
|
|
676
|
+
|
|
677
|
+
interface AgentLighthouseConfig {
|
|
678
|
+
/** Target URL (if not supplied via CLI) */
|
|
679
|
+
url?: string;
|
|
680
|
+
/** Audit preset profile */
|
|
681
|
+
preset?: PresetName;
|
|
682
|
+
/** Categories to execute (default: all) */
|
|
683
|
+
categories?: string[];
|
|
684
|
+
/** Minimum score threshold (0-100) to fail CI */
|
|
685
|
+
minScore?: number;
|
|
686
|
+
/** Per-category minimum score assertions */
|
|
687
|
+
assertCategories?: Record<string, number>;
|
|
688
|
+
/** Output report formats (terminal, html, json, md) */
|
|
689
|
+
output?: Array<'terminal' | 'html' | 'json' | 'md'>;
|
|
690
|
+
/** Output directory for reports */
|
|
691
|
+
outputDir?: string;
|
|
692
|
+
/** Maximum number of pages to discover & scan */
|
|
693
|
+
maxPages?: number;
|
|
694
|
+
}
|
|
695
|
+
/** Helper function for type-safe configuration files */
|
|
696
|
+
declare function defineConfig(config: AgentLighthouseConfig): AgentLighthouseConfig;
|
|
697
|
+
/**
|
|
698
|
+
* Loads Agent Lighthouse configuration from a file.
|
|
699
|
+
*/
|
|
700
|
+
declare function loadConfigFile(customPath?: string): AgentLighthouseConfig;
|
|
701
|
+
|
|
702
|
+
type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
|
|
703
|
+
declare class Logger {
|
|
704
|
+
level: LogLevel;
|
|
705
|
+
private shouldLog;
|
|
706
|
+
debug(msg: string | Record<string, unknown>, ...args: unknown[]): void;
|
|
707
|
+
info(msg: string | Record<string, unknown>, ...args: unknown[]): void;
|
|
708
|
+
warn(msg: string | Record<string, unknown>, ...args: unknown[]): void;
|
|
709
|
+
error(msg: string | Record<string, unknown>, ...args: unknown[]): void;
|
|
710
|
+
}
|
|
711
|
+
declare const logger: Logger;
|
|
712
|
+
|
|
713
|
+
export { type AgentLighthouseConfig, Audit, type AuditGuidance, AuditGuidanceSchema, type AuditMeta, AuditMetaSchema, type AuditRegistration, type AuditResult, AuditResultSchema, type AuditRunResult, CATEGORY_NAMES, CATEGORY_WEIGHTS, type CategoryConfig, type CategoryResult, type CheckContext, type CheckFn, type CheckPriority, CheckPrioritySchema, type CheckRecommendation, type CheckResult, CheckResultSchema, type CheckStatus, CheckStatusSchema, DEFAULT_SCAN_LIMIT, type FetchOptions, type FetchResult, type FieldStatus, type FixEffort, FixEffortSchema, MAX_CONCURRENT_REQUESTS, MAX_PAGES_PER_SCAN, MAX_RESPONSE_BODY_BYTES, PAGE_TYPE_LABELS, PRESETS, type PageContext, type PageOverride, type PageType, type PresetName, type PresetOptions, type ProductFieldVerification, READINESS_WEIGHTS, REQUEST_TIMEOUT_MS, type ReadinessVitals, SCANNER_USER_AGENT, SCAN_TIMEOUT_MS, SCORE_TIER_LABELS, type ScanConfig, type ScanReport, type ScoreDisplayMode, ScoreDisplayModeSchema, type ScoreTier, TAG_SCAN_ERROR, TAG_SKIPPED_PAGE_TYPE, type WafProtection, buildCategoryResult, calculateCategoryScore, calculateOverallScore, createFetcher, defaultConfig, defineConfig, detectPageType, detectWafProtection, extractDomain, extractForms, extractHeadLinks, extractHeadings, extractImages, extractInternalLinks, extractJsonLd, extractMarkdownLinks, extractMetaTags, extractNavLinks, extractProductFieldVerification, extractScripts, extractStylesheetUrls, flattenJsonLd, getMainContentText, getPreset, getScoreTier, getTierColor, getTierLabel, getWordCount, isPrivateIp, isSafeUrl, joinUrl, loadConfigFile, logger, normalizeUrl, parseHtml, runAudits, runScan };
|