@agentsean/analyzers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/dist/ai-crawlers.d.ts +19 -0
- package/dist/ai-crawlers.d.ts.map +1 -0
- package/dist/ai-crawlers.js +111 -0
- package/dist/ai-crawlers.js.map +1 -0
- package/dist/audit.d.ts +21 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +87 -0
- package/dist/audit.js.map +1 -0
- package/dist/catalogue-data.d.ts +4 -0
- package/dist/catalogue-data.d.ts.map +1 -0
- package/dist/catalogue-data.js +5103 -0
- package/dist/catalogue-data.js.map +1 -0
- package/dist/catalogue.d.ts +6 -0
- package/dist/catalogue.d.ts.map +1 -0
- package/dist/catalogue.js +25 -0
- package/dist/catalogue.js.map +1 -0
- package/dist/data/checks.json +5078 -0
- package/dist/data/lighthouse-13-insights.json +40 -0
- package/dist/data/schemaorg-vocab.json +89 -0
- package/dist/data/supported_types.json +71 -0
- package/dist/detectors/all.d.ts +30 -0
- package/dist/detectors/all.d.ts.map +1 -0
- package/dist/detectors/all.js +1619 -0
- package/dist/detectors/all.js.map +1 -0
- package/dist/detectors/canon.d.ts +2 -0
- package/dist/detectors/canon.d.ts.map +1 -0
- package/dist/detectors/canon.js +2 -0
- package/dist/detectors/canon.js.map +1 -0
- package/dist/detectors/conf.d.ts +2 -0
- package/dist/detectors/conf.d.ts.map +1 -0
- package/dist/detectors/conf.js +2 -0
- package/dist/detectors/conf.js.map +1 -0
- package/dist/detectors/crawl.d.ts +2 -0
- package/dist/detectors/crawl.d.ts.map +1 -0
- package/dist/detectors/crawl.js +2 -0
- package/dist/detectors/crawl.js.map +1 -0
- package/dist/detectors/cwv.d.ts +2 -0
- package/dist/detectors/cwv.d.ts.map +1 -0
- package/dist/detectors/cwv.js +2 -0
- package/dist/detectors/cwv.js.map +1 -0
- package/dist/detectors/direct.d.ts +2 -0
- package/dist/detectors/direct.d.ts.map +1 -0
- package/dist/detectors/direct.js +2 -0
- package/dist/detectors/direct.js.map +1 -0
- package/dist/detectors/dup.d.ts +2 -0
- package/dist/detectors/dup.d.ts.map +1 -0
- package/dist/detectors/dup.js +2 -0
- package/dist/detectors/dup.js.map +1 -0
- package/dist/detectors/gap.d.ts +2 -0
- package/dist/detectors/gap.d.ts.map +1 -0
- package/dist/detectors/gap.js +2 -0
- package/dist/detectors/gap.js.map +1 -0
- package/dist/detectors/href.d.ts +2 -0
- package/dist/detectors/href.d.ts.map +1 -0
- package/dist/detectors/href.js +2 -0
- package/dist/detectors/href.js.map +1 -0
- package/dist/detectors/img.d.ts +2 -0
- package/dist/detectors/img.d.ts.map +1 -0
- package/dist/detectors/img.js +2 -0
- package/dist/detectors/img.js.map +1 -0
- package/dist/detectors/index.d.ts +27 -0
- package/dist/detectors/index.d.ts.map +1 -0
- package/dist/detectors/index.js +27 -0
- package/dist/detectors/index.js.map +1 -0
- package/dist/detectors/js.d.ts +2 -0
- package/dist/detectors/js.d.ts.map +1 -0
- package/dist/detectors/js.js +2 -0
- package/dist/detectors/js.js.map +1 -0
- package/dist/detectors/link.d.ts +2 -0
- package/dist/detectors/link.d.ts.map +1 -0
- package/dist/detectors/link.js +2 -0
- package/dist/detectors/link.js.map +1 -0
- package/dist/detectors/log.d.ts +2 -0
- package/dist/detectors/log.d.ts.map +1 -0
- package/dist/detectors/log.js +2 -0
- package/dist/detectors/log.js.map +1 -0
- package/dist/detectors/mig.d.ts +2 -0
- package/dist/detectors/mig.d.ts.map +1 -0
- package/dist/detectors/mig.js +2 -0
- package/dist/detectors/mig.js.map +1 -0
- package/dist/detectors/mob.d.ts +2 -0
- package/dist/detectors/mob.d.ts.map +1 -0
- package/dist/detectors/mob.js +2 -0
- package/dist/detectors/mob.js.map +1 -0
- package/dist/detectors/onp.d.ts +2 -0
- package/dist/detectors/onp.d.ts.map +1 -0
- package/dist/detectors/onp.js +2 -0
- package/dist/detectors/onp.js.map +1 -0
- package/dist/detectors/page.d.ts +2 -0
- package/dist/detectors/page.d.ts.map +1 -0
- package/dist/detectors/page.js +2 -0
- package/dist/detectors/page.js.map +1 -0
- package/dist/detectors/param.d.ts +2 -0
- package/dist/detectors/param.d.ts.map +1 -0
- package/dist/detectors/param.js +2 -0
- package/dist/detectors/param.js.map +1 -0
- package/dist/detectors/perf.d.ts +2 -0
- package/dist/detectors/perf.d.ts.map +1 -0
- package/dist/detectors/perf.js +2 -0
- package/dist/detectors/perf.js.map +1 -0
- package/dist/detectors/predicates.d.ts +22 -0
- package/dist/detectors/predicates.d.ts.map +1 -0
- package/dist/detectors/predicates.js +142 -0
- package/dist/detectors/predicates.js.map +1 -0
- package/dist/detectors/resp.d.ts +2 -0
- package/dist/detectors/resp.d.ts.map +1 -0
- package/dist/detectors/resp.js +2 -0
- package/dist/detectors/resp.js.map +1 -0
- package/dist/detectors/robots.d.ts +2 -0
- package/dist/detectors/robots.d.ts.map +1 -0
- package/dist/detectors/robots.js +2 -0
- package/dist/detectors/robots.js.map +1 -0
- package/dist/detectors/sd.d.ts +2 -0
- package/dist/detectors/sd.d.ts.map +1 -0
- package/dist/detectors/sd.js +2 -0
- package/dist/detectors/sd.js.map +1 -0
- package/dist/detectors/sec.d.ts +2 -0
- package/dist/detectors/sec.d.ts.map +1 -0
- package/dist/detectors/sec.js +2 -0
- package/dist/detectors/sec.js.map +1 -0
- package/dist/detectors/smap.d.ts +2 -0
- package/dist/detectors/smap.d.ts.map +1 -0
- package/dist/detectors/smap.js +2 -0
- package/dist/detectors/smap.js.map +1 -0
- package/dist/detectors/soft404.d.ts +2 -0
- package/dist/detectors/soft404.d.ts.map +1 -0
- package/dist/detectors/soft404.js +2 -0
- package/dist/detectors/soft404.js.map +1 -0
- package/dist/detectors/thin.d.ts +2 -0
- package/dist/detectors/thin.d.ts.map +1 -0
- package/dist/detectors/thin.js +2 -0
- package/dist/detectors/thin.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/openseo-seed.d.ts +16 -0
- package/dist/openseo-seed.d.ts.map +1 -0
- package/dist/openseo-seed.js +157 -0
- package/dist/openseo-seed.js.map +1 -0
- package/dist/priority.d.ts +8 -0
- package/dist/priority.d.ts.map +1 -0
- package/dist/priority.js +53 -0
- package/dist/priority.js.map +1 -0
- package/dist/schemaorg.d.ts +28 -0
- package/dist/schemaorg.d.ts.map +1 -0
- package/dist/schemaorg.js +198 -0
- package/dist/schemaorg.js.map +1 -0
- package/dist/score.d.ts +10 -0
- package/dist/score.d.ts.map +1 -0
- package/dist/score.js +177 -0
- package/dist/score.js.map +1 -0
- package/dist/types.d.ts +109 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"param.js","sourceRoot":"","sources":["../../src/detectors/param.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../../src/detectors/perf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perf.js","sourceRoot":"","sources":["../../src/detectors/perf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CrawledPage } from "@agentsean/crawler";
|
|
2
|
+
import type { AuditContext, FindingDraft } from "../types.js";
|
|
3
|
+
export declare function hit(ruleId: string, urls: string[], evidence: unknown, confidence?: number): FindingDraft | null;
|
|
4
|
+
export declare function push(out: FindingDraft[], ruleId: string, urls: string[], evidence: unknown, confidence?: number): void;
|
|
5
|
+
export declare function htmlPages(ctx: AuditContext): CrawledPage[];
|
|
6
|
+
export declare function internalPages(ctx: AuditContext): CrawledPage[];
|
|
7
|
+
export declare function byUrl(ctx: AuditContext): Map<string, CrawledPage>;
|
|
8
|
+
export declare function statusOf(p: CrawledPage): number | null;
|
|
9
|
+
export declare function inRange(n: number | null, a: number, b: number): boolean;
|
|
10
|
+
export declare function hops(p: CrawledPage): number;
|
|
11
|
+
export declare function noindexOf(p: CrawledPage): boolean;
|
|
12
|
+
export declare function nofollowOf(p: CrawledPage): boolean;
|
|
13
|
+
export declare function canonicalTarget(p: CrawledPage): string | null;
|
|
14
|
+
export declare function absCanonical(p: CrawledPage): string | null;
|
|
15
|
+
export declare function selfCanonical(p: CrawledPage): boolean;
|
|
16
|
+
export declare function stripSlash(url: string): string;
|
|
17
|
+
export declare function isIndexable(p: CrawledPage): boolean;
|
|
18
|
+
export declare function hasReq(ctx: AuditContext, req: string): boolean;
|
|
19
|
+
export declare function robotsTokens(p: CrawledPage): string[];
|
|
20
|
+
export declare function gini(values: number[]): number;
|
|
21
|
+
export declare function originPath(url: string): string;
|
|
22
|
+
//# sourceMappingURL=predicates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../../src/detectors/predicates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,wBAAgB,GAAG,CACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,OAAO,EACjB,UAAU,SAAI,GACb,YAAY,GAAG,IAAI,CAerB;AAED,wBAAgB,IAAI,CAClB,GAAG,EAAE,YAAY,EAAE,EACnB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,EACd,QAAQ,EAAE,OAAO,EACjB,UAAU,SAAI,GACb,IAAI,CAGN;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,EAAE,CAE1D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,EAAE,CAE9D;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAOjE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAEtD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAE3C;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAKjD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAKlD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAI7D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CAQ1D;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAIrD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAQnD;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAO9D;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAMrD;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAS7C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9C"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { getCheck } from "../catalogue.js";
|
|
2
|
+
export function hit(ruleId, urls, evidence, confidence = 1) {
|
|
3
|
+
if (urls.length === 0)
|
|
4
|
+
return null;
|
|
5
|
+
const check = getCheck(ruleId);
|
|
6
|
+
if (!check)
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
ruleId,
|
|
10
|
+
severity: check.severity,
|
|
11
|
+
autonomyTier: check.autonomyTier,
|
|
12
|
+
title: check.name,
|
|
13
|
+
explanation: check.explanation,
|
|
14
|
+
fixTemplate: check.fixTemplate,
|
|
15
|
+
urls: [...new Set(urls)],
|
|
16
|
+
evidence,
|
|
17
|
+
confidence,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function push(out, ruleId, urls, evidence, confidence = 1) {
|
|
21
|
+
const f = hit(ruleId, urls, evidence, confidence);
|
|
22
|
+
if (f)
|
|
23
|
+
out.push(f);
|
|
24
|
+
}
|
|
25
|
+
export function htmlPages(ctx) {
|
|
26
|
+
return ctx.crawl.pages.filter((p) => p.extract !== null);
|
|
27
|
+
}
|
|
28
|
+
export function internalPages(ctx) {
|
|
29
|
+
return ctx.crawl.pages.filter((p) => p.isInternal);
|
|
30
|
+
}
|
|
31
|
+
export function byUrl(ctx) {
|
|
32
|
+
const m = new Map();
|
|
33
|
+
for (const p of ctx.crawl.pages) {
|
|
34
|
+
m.set(p.url, p);
|
|
35
|
+
m.set(p.finalUrl, p);
|
|
36
|
+
}
|
|
37
|
+
return m;
|
|
38
|
+
}
|
|
39
|
+
export function statusOf(p) {
|
|
40
|
+
return p.statusCode;
|
|
41
|
+
}
|
|
42
|
+
export function inRange(n, a, b) {
|
|
43
|
+
return n !== null && n >= a && n <= b;
|
|
44
|
+
}
|
|
45
|
+
export function hops(p) {
|
|
46
|
+
return Math.max(0, p.redirectChain.length - 1);
|
|
47
|
+
}
|
|
48
|
+
export function noindexOf(p) {
|
|
49
|
+
const parts = [...(p.extract?.robotsMeta ?? []), p.extract?.xRobotsTag ?? ""]
|
|
50
|
+
.join(",")
|
|
51
|
+
.toLowerCase();
|
|
52
|
+
return /\bnoindex\b|\bnone\b/.test(parts);
|
|
53
|
+
}
|
|
54
|
+
export function nofollowOf(p) {
|
|
55
|
+
const parts = [...(p.extract?.robotsMeta ?? []), p.extract?.xRobotsTag ?? ""]
|
|
56
|
+
.join(",")
|
|
57
|
+
.toLowerCase();
|
|
58
|
+
return /\bnofollow\b|\bnone\b/.test(parts);
|
|
59
|
+
}
|
|
60
|
+
export function canonicalTarget(p) {
|
|
61
|
+
const html = p.extract?.canonicalHtml[0];
|
|
62
|
+
const header = p.extract?.canonicalHeader[0];
|
|
63
|
+
return html || header || null;
|
|
64
|
+
}
|
|
65
|
+
export function absCanonical(p) {
|
|
66
|
+
const c = canonicalTarget(p);
|
|
67
|
+
if (!c)
|
|
68
|
+
return null;
|
|
69
|
+
try {
|
|
70
|
+
return new URL(c, p.finalUrl).href;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return c;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function selfCanonical(p) {
|
|
77
|
+
const c = absCanonical(p);
|
|
78
|
+
if (!c)
|
|
79
|
+
return false;
|
|
80
|
+
return stripSlash(c) === stripSlash(p.finalUrl);
|
|
81
|
+
}
|
|
82
|
+
export function stripSlash(url) {
|
|
83
|
+
try {
|
|
84
|
+
const u = new URL(url);
|
|
85
|
+
u.hash = "";
|
|
86
|
+
if (u.pathname.endsWith("/") && u.pathname !== "/")
|
|
87
|
+
u.pathname = u.pathname.slice(0, -1);
|
|
88
|
+
return u.href;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return url;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export function isIndexable(p) {
|
|
95
|
+
return (p.isInternal &&
|
|
96
|
+
p.statusCode === 200 &&
|
|
97
|
+
p.robotsAllowed &&
|
|
98
|
+
!noindexOf(p) &&
|
|
99
|
+
(selfCanonical(p) || !canonicalTarget(p)));
|
|
100
|
+
}
|
|
101
|
+
export function hasReq(ctx, req) {
|
|
102
|
+
if (req === "gsc")
|
|
103
|
+
return Boolean(ctx.gsc);
|
|
104
|
+
if (req === "crux")
|
|
105
|
+
return Boolean(ctx.crux);
|
|
106
|
+
if (req === "logs")
|
|
107
|
+
return Boolean(ctx.logs);
|
|
108
|
+
if (req === "migration")
|
|
109
|
+
return Boolean(ctx.migration);
|
|
110
|
+
if (req === "lighthouse")
|
|
111
|
+
return Boolean(ctx.lighthouse);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
export function robotsTokens(p) {
|
|
115
|
+
return [...(p.extract?.robotsMeta ?? []), p.extract?.xRobotsTag ?? ""]
|
|
116
|
+
.join(",")
|
|
117
|
+
.toLowerCase()
|
|
118
|
+
.split(/[\s,]+/)
|
|
119
|
+
.filter(Boolean);
|
|
120
|
+
}
|
|
121
|
+
export function gini(values) {
|
|
122
|
+
if (values.length === 0)
|
|
123
|
+
return 0;
|
|
124
|
+
const sorted = values.toSorted((a, b) => a - b);
|
|
125
|
+
const n = sorted.length;
|
|
126
|
+
const sum = sorted.reduce((s, v) => s + v, 0);
|
|
127
|
+
if (sum === 0)
|
|
128
|
+
return 0;
|
|
129
|
+
let acc = 0;
|
|
130
|
+
for (let i = 0; i < n; i++)
|
|
131
|
+
acc += (2 * (i + 1) - n - 1) * (sorted[i] ?? 0);
|
|
132
|
+
return acc / (n * sum);
|
|
133
|
+
}
|
|
134
|
+
export function originPath(url) {
|
|
135
|
+
try {
|
|
136
|
+
return new URL(url).pathname;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return url;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=predicates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.js","sourceRoot":"","sources":["../../src/detectors/predicates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resp.d.ts","sourceRoot":"","sources":["../../src/detectors/resp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resp.js","sourceRoot":"","sources":["../../src/detectors/resp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/detectors/robots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"robots.js","sourceRoot":"","sources":["../../src/detectors/robots.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sd.d.ts","sourceRoot":"","sources":["../../src/detectors/sd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sd.js","sourceRoot":"","sources":["../../src/detectors/sd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sec.d.ts","sourceRoot":"","sources":["../../src/detectors/sec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sec.js","sourceRoot":"","sources":["../../src/detectors/sec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smap.d.ts","sourceRoot":"","sources":["../../src/detectors/smap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smap.js","sourceRoot":"","sources":["../../src/detectors/smap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft404.d.ts","sourceRoot":"","sources":["../../src/detectors/soft404.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft404.js","sourceRoot":"","sources":["../../src/detectors/soft404.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thin.d.ts","sourceRoot":"","sources":["../../src/detectors/thin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thin.js","sourceRoot":"","sources":["../../src/detectors/thin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { CHECKS, getCheck, checksByCategory, categories } from "./catalogue.js";
|
|
2
|
+
export { analyzeCrawl, buildReport, findingFingerprint, flattenForDb, catalogueSize, } from "./audit.js";
|
|
3
|
+
export { computeSiteScore, SITE_SCORE_VERSION, SITE_SCORE_FORMULA } from "./score.js";
|
|
4
|
+
export { prioritize, PRIORITY_FORMULA, PRIORITY_VERSION } from "./priority.js";
|
|
5
|
+
export { validateJsonLdBlocks, googleSupportedTypes, schemaVocab, } from "./schemaorg.js";
|
|
6
|
+
export { detectAll, detectorFor, FAMILY_DETECTORS } from "./detectors/index.js";
|
|
7
|
+
export { OPENSEO_SEED_TO_CHECK, OPENSEO_COPY } from "./openseo-seed.js";
|
|
8
|
+
export { AI_CRAWLERS, TRAINING_TOKENS, CITATION_TOKENS, analyzeAiRobots, type AiCrawler, type CrawlerClass, } from "./ai-crawlers.js";
|
|
9
|
+
export type { CheckDefinition, FindingDraft, PrioritizedFinding, AuditReport, AuditContext, SiteScore, Severity, AutonomyTier, } from "./types.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EACL,WAAW,EACX,eAAe,EACf,eAAe,EACf,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,YAAY,GACb,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { CHECKS, getCheck, checksByCategory, categories } from "./catalogue.js";
|
|
2
|
+
export { analyzeCrawl, buildReport, findingFingerprint, flattenForDb, catalogueSize, } from "./audit.js";
|
|
3
|
+
export { computeSiteScore, SITE_SCORE_VERSION, SITE_SCORE_FORMULA } from "./score.js";
|
|
4
|
+
export { prioritize, PRIORITY_FORMULA, PRIORITY_VERSION } from "./priority.js";
|
|
5
|
+
export { validateJsonLdBlocks, googleSupportedTypes, schemaVocab, } from "./schemaorg.js";
|
|
6
|
+
export { detectAll, detectorFor, FAMILY_DETECTORS } from "./detectors/index.js";
|
|
7
|
+
export { OPENSEO_SEED_TO_CHECK, OPENSEO_COPY } from "./openseo-seed.js";
|
|
8
|
+
export { AI_CRAWLERS, TRAINING_TOKENS, CITATION_TOKENS, analyzeAiRobots, } from "./ai-crawlers.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EACL,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EACL,WAAW,EACX,eAAe,EACf,eAAe,EACf,eAAe,GAGhB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapted from OpenSEO `src/shared/audit-issues.ts` (MIT).
|
|
3
|
+
* Copyright (c) 2026 Ben Senescu and contributors.
|
|
4
|
+
*
|
|
5
|
+
* Descriptor shape kept: severity, title, explanation, howToFix.
|
|
6
|
+
* IDs remapped onto Agent Sean's check catalogue (research/01-technical-seo.md).
|
|
7
|
+
* User-facing copy is adapted; this is not a fork of OpenSEO.
|
|
8
|
+
*/
|
|
9
|
+
export type OpenSeoDescriptor = {
|
|
10
|
+
title: string;
|
|
11
|
+
explanation: string;
|
|
12
|
+
howToFix: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const OPENSEO_SEED_TO_CHECK: Record<string, string>;
|
|
15
|
+
export declare const OPENSEO_COPY: Record<string, OpenSeoDescriptor>;
|
|
16
|
+
//# sourceMappingURL=openseo-seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openseo-seed.d.ts","sourceRoot":"","sources":["../src/openseo-seed.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4BxD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CA4J1D,CAAC"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export const OPENSEO_SEED_TO_CHECK = {
|
|
2
|
+
"blocked-page": "RESP.4XX_INTERNAL",
|
|
3
|
+
"server-error": "RESP.5XX_INTERNAL",
|
|
4
|
+
"broken-internal-link": "LINK.BROKEN_INTERNAL",
|
|
5
|
+
"missing-title": "ONP.TITLE_MISSING",
|
|
6
|
+
"broken-page": "RESP.4XX_INTERNAL",
|
|
7
|
+
"duplicate-title": "ONP.TITLE_DUPLICATE",
|
|
8
|
+
"duplicate-meta-description": "ONP.META_DESC_DUPLICATE",
|
|
9
|
+
"duplicate-content": "DUP.EXACT_BODY",
|
|
10
|
+
"missing-meta-description": "ONP.META_DESC_MISSING",
|
|
11
|
+
"missing-h1": "ONP.H1_MISSING",
|
|
12
|
+
"multiple-h1": "ONP.H1_MULTIPLE",
|
|
13
|
+
"redirect-chain": "RESP.REDIRECT_CHAIN",
|
|
14
|
+
"redirect-loop": "RESP.REDIRECT_LOOP",
|
|
15
|
+
"canonical-conflict": "CANON.HTML_HEADER_MISMATCH",
|
|
16
|
+
"thin-content": "THIN.LOW_WORDCOUNT",
|
|
17
|
+
"images-missing-alt": "IMG.MISSING_ALT_ATTR",
|
|
18
|
+
"orphan-page": "CRAWL.ORPHAN",
|
|
19
|
+
"no-outgoing-links": "LINK.NO_OUTLINKS",
|
|
20
|
+
"title-too-long": "ONP.TITLE_TOO_LONG",
|
|
21
|
+
"title-too-short": "ONP.TITLE_TOO_SHORT",
|
|
22
|
+
"meta-description-too-long": "ONP.META_DESC_TOO_LONG",
|
|
23
|
+
"meta-description-too-short": "ONP.META_DESC_TOO_SHORT",
|
|
24
|
+
"heading-order-skip": "ONP.H_NON_SEQUENTIAL",
|
|
25
|
+
"slow-response": "RESP.SLOW_TTFB",
|
|
26
|
+
"noindex-page": "DIRECT.NOINDEX_UNEXPECTED",
|
|
27
|
+
"canonicalized-page": "CANON.CANONICALISED",
|
|
28
|
+
"deep-page": "CRAWL.DEPTH_GT_5",
|
|
29
|
+
};
|
|
30
|
+
export const OPENSEO_COPY = {
|
|
31
|
+
"RESP.5XX_INTERNAL": {
|
|
32
|
+
title: "Server error (5xx)",
|
|
33
|
+
explanation: "The page returned a 5xx server error. Search engines that repeatedly see server errors will crawl the site less and may drop the page from the index.",
|
|
34
|
+
howToFix: "Check the server logs for this URL and fix the underlying error. If the page is gone, return a 404/410 or redirect it to a relevant page instead of erroring.",
|
|
35
|
+
},
|
|
36
|
+
"LINK.BROKEN_INTERNAL": {
|
|
37
|
+
title: "Broken internal link",
|
|
38
|
+
explanation: "This page links to an internal URL that returns an error status (4xx/5xx). Broken links waste crawl budget, leak link equity, and frustrate users.",
|
|
39
|
+
howToFix: "Update the link to point at the correct live URL, or remove it. If the target was moved, prefer linking directly to the new URL rather than relying on a redirect.",
|
|
40
|
+
},
|
|
41
|
+
"ONP.TITLE_MISSING": {
|
|
42
|
+
title: "Missing title tag",
|
|
43
|
+
explanation: "The page has no <title>. The title is the strongest on-page relevance signal and the headline shown in search results; without it search engines generate one themselves, usually badly.",
|
|
44
|
+
howToFix: "Add a unique, descriptive <title> of roughly 50–60 characters that includes the page's primary topic.",
|
|
45
|
+
},
|
|
46
|
+
"RESP.4XX_INTERNAL": {
|
|
47
|
+
title: "Page returns an error (4xx)",
|
|
48
|
+
explanation: "This crawled URL returned a client error (e.g. 404). If it is referenced from your sitemap or other pages, crawlers keep wasting requests on it.",
|
|
49
|
+
howToFix: "If the page should exist, restore it. If it is intentionally gone, remove it from the sitemap and internal links, and consider a 301 redirect to the closest live page.",
|
|
50
|
+
},
|
|
51
|
+
"ONP.TITLE_DUPLICATE": {
|
|
52
|
+
title: "Duplicate title",
|
|
53
|
+
explanation: "Multiple pages share the same title tag. Search engines use titles to differentiate pages; duplicates make pages compete with each other.",
|
|
54
|
+
howToFix: "Write a unique title for each page describing its specific content.",
|
|
55
|
+
},
|
|
56
|
+
"ONP.META_DESC_DUPLICATE": {
|
|
57
|
+
title: "Duplicate meta description",
|
|
58
|
+
explanation: "Multiple pages share the same meta description, so search results show identical snippets.",
|
|
59
|
+
howToFix: "Write a unique meta description per page.",
|
|
60
|
+
},
|
|
61
|
+
"DUP.EXACT_BODY": {
|
|
62
|
+
title: "Duplicate page content",
|
|
63
|
+
explanation: "Two or more URLs serve byte-identical visible text. Search engines pick one version to index and ignore the rest.",
|
|
64
|
+
howToFix: "Consolidate duplicates: pick the canonical URL, add rel=canonical from the others, and 301-redirect duplicate URLs where possible.",
|
|
65
|
+
},
|
|
66
|
+
"ONP.META_DESC_MISSING": {
|
|
67
|
+
title: "Missing meta description",
|
|
68
|
+
explanation: "The page has no meta description. Search engines will assemble a snippet from page text.",
|
|
69
|
+
howToFix: "Add a meta description of roughly 70–160 characters that summarizes the page.",
|
|
70
|
+
},
|
|
71
|
+
"ONP.H1_MISSING": {
|
|
72
|
+
title: "Missing H1 heading",
|
|
73
|
+
explanation: "The page has no H1. The H1 tells users and search engines what the page is about.",
|
|
74
|
+
howToFix: "Add a single H1 that states the page's main topic.",
|
|
75
|
+
},
|
|
76
|
+
"ONP.H1_MULTIPLE": {
|
|
77
|
+
title: "Multiple H1 headings",
|
|
78
|
+
explanation: "The page has more than one H1, which dilutes the main-topic signal.",
|
|
79
|
+
howToFix: "Keep one H1 for the page's main heading and demote the others.",
|
|
80
|
+
},
|
|
81
|
+
"RESP.REDIRECT_CHAIN": {
|
|
82
|
+
title: "Redirect chain",
|
|
83
|
+
explanation: "Reaching the final page requires two or more consecutive redirects. Each hop adds latency and burns crawl budget.",
|
|
84
|
+
howToFix: "Point the first URL (and any internal links) directly at the final destination so there is at most one redirect.",
|
|
85
|
+
},
|
|
86
|
+
"RESP.REDIRECT_LOOP": {
|
|
87
|
+
title: "Redirect loop",
|
|
88
|
+
explanation: "This redirect eventually points back to itself, so the URL never resolves.",
|
|
89
|
+
howToFix: "Trace the redirect rules for this URL and break the cycle.",
|
|
90
|
+
},
|
|
91
|
+
"CANON.HTML_HEADER_MISMATCH": {
|
|
92
|
+
title: "Conflicting canonical signals",
|
|
93
|
+
explanation: "The page declares different canonical URLs in its HTML rel=canonical and its HTTP Link header.",
|
|
94
|
+
howToFix: "Pick one canonical URL and declare it in exactly one place.",
|
|
95
|
+
},
|
|
96
|
+
"THIN.LOW_WORDCOUNT": {
|
|
97
|
+
title: "Thin content",
|
|
98
|
+
explanation: "The page has very little visible text. Thin pages rarely rank and can drag down sitewide quality assessments.",
|
|
99
|
+
howToFix: "Expand the page with genuinely useful content, noindex it, or consolidate it into a stronger page.",
|
|
100
|
+
},
|
|
101
|
+
"IMG.MISSING_ALT_ATTR": {
|
|
102
|
+
title: "Images missing alt text",
|
|
103
|
+
explanation: "One or more images on the page lack alt attributes. Alt text is an accessibility requirement and the main way search engines understand images.",
|
|
104
|
+
howToFix: 'Add descriptive alt text to meaningful images; use an empty alt (alt="") only for purely decorative ones.',
|
|
105
|
+
},
|
|
106
|
+
"CRAWL.ORPHAN": {
|
|
107
|
+
title: "Orphan page",
|
|
108
|
+
explanation: "No crawled page links to this URL — it was only discoverable via the sitemap.",
|
|
109
|
+
howToFix: "Link to this page from relevant pages, or remove it from the sitemap.",
|
|
110
|
+
},
|
|
111
|
+
"LINK.NO_OUTLINKS": {
|
|
112
|
+
title: "Page has no outgoing links",
|
|
113
|
+
explanation: "The page contains no internal links — a dead end. Link equity that flows into it stops there.",
|
|
114
|
+
howToFix: "Add links to related pages, the parent category, or the homepage.",
|
|
115
|
+
},
|
|
116
|
+
"ONP.TITLE_TOO_LONG": {
|
|
117
|
+
title: "Title too long",
|
|
118
|
+
explanation: "The title exceeds ~60 characters, so search results will truncate it.",
|
|
119
|
+
howToFix: "Shorten the title to roughly 50–60 characters.",
|
|
120
|
+
},
|
|
121
|
+
"ONP.TITLE_TOO_SHORT": {
|
|
122
|
+
title: "Title too short",
|
|
123
|
+
explanation: "The title is under ~30 characters, which is usually too generic.",
|
|
124
|
+
howToFix: "Expand the title into a descriptive phrase (roughly 30–60 characters).",
|
|
125
|
+
},
|
|
126
|
+
"ONP.META_DESC_TOO_LONG": {
|
|
127
|
+
title: "Meta description too long",
|
|
128
|
+
explanation: "The meta description exceeds ~155 characters and will be truncated.",
|
|
129
|
+
howToFix: "Trim the description to roughly 70–155 characters.",
|
|
130
|
+
},
|
|
131
|
+
"ONP.META_DESC_TOO_SHORT": {
|
|
132
|
+
title: "Meta description too short",
|
|
133
|
+
explanation: "The meta description is under ~70 characters.",
|
|
134
|
+
howToFix: "Expand the description to roughly 70–155 characters.",
|
|
135
|
+
},
|
|
136
|
+
"ONP.H_NON_SEQUENTIAL": {
|
|
137
|
+
title: "Heading levels skip",
|
|
138
|
+
explanation: "The heading hierarchy skips levels (e.g. an H4 directly after an H2).",
|
|
139
|
+
howToFix: "Adjust heading levels so they descend one step at a time.",
|
|
140
|
+
},
|
|
141
|
+
"RESP.SLOW_TTFB": {
|
|
142
|
+
title: "Slow server response",
|
|
143
|
+
explanation: "The HTML response took over 600 ms. Slow TTFB drags down every downstream performance metric.",
|
|
144
|
+
howToFix: "Investigate server time and caching for this route.",
|
|
145
|
+
},
|
|
146
|
+
"CANON.CANONICALISED": {
|
|
147
|
+
title: "Canonicalized to another URL",
|
|
148
|
+
explanation: "The page declares a different URL as its canonical, telling search engines to index that URL instead.",
|
|
149
|
+
howToFix: "If this page should rank on its own, set its canonical to itself.",
|
|
150
|
+
},
|
|
151
|
+
"CRAWL.DEPTH_GT_5": {
|
|
152
|
+
title: "Page is deep in the site structure",
|
|
153
|
+
explanation: "The page is 5+ clicks from the homepage. Deep pages get crawled less often.",
|
|
154
|
+
howToFix: "Add links from higher-level pages to flatten the path to this page.",
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=openseo-seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openseo-seed.js","sourceRoot":"","sources":["../src/openseo-seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FindingDraft, PrioritizedFinding } from "./types.js";
|
|
2
|
+
export declare const PRIORITY_VERSION = "pr-1.0.0";
|
|
3
|
+
export declare const PRIORITY_FORMULA = "priority = severity \u00D7 coverage \u00D7 indexability \u00D7 traffic \u00D7 confidence \u00F7 effort";
|
|
4
|
+
export declare function prioritize(findings: FindingDraft[], totalUrls: number, opts?: {
|
|
5
|
+
gscClicksByUrl?: Record<string, number> | undefined;
|
|
6
|
+
indexableUrls?: Set<string> | undefined;
|
|
7
|
+
}): PrioritizedFinding[];
|
|
8
|
+
//# sourceMappingURL=priority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority.d.ts","sourceRoot":"","sources":["../src/priority.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEnE,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAE3C,eAAO,MAAM,gBAAgB,2GACoD,CAAC;AAiBlF,wBAAgB,UAAU,CACxB,QAAQ,EAAE,YAAY,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IACL,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACpD,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;CACzC,GACA,kBAAkB,EAAE,CAgCtB"}
|
package/dist/priority.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getCheck } from "./catalogue.js";
|
|
2
|
+
export const PRIORITY_VERSION = "pr-1.0.0";
|
|
3
|
+
export const PRIORITY_FORMULA = "priority = severity × coverage × indexability × traffic × confidence ÷ effort";
|
|
4
|
+
const SEVERITY_WEIGHT = {
|
|
5
|
+
critical: 100,
|
|
6
|
+
high: 40,
|
|
7
|
+
medium: 12,
|
|
8
|
+
low: 4,
|
|
9
|
+
insight: 1,
|
|
10
|
+
};
|
|
11
|
+
function effortFactor(tier) {
|
|
12
|
+
if (tier === "T1" || tier === "T0")
|
|
13
|
+
return 1.0;
|
|
14
|
+
if (tier === "T2")
|
|
15
|
+
return 1.3;
|
|
16
|
+
if (tier === "T3")
|
|
17
|
+
return 2.5;
|
|
18
|
+
return 5.0;
|
|
19
|
+
}
|
|
20
|
+
export function prioritize(findings, totalUrls, opts) {
|
|
21
|
+
const n = Math.max(1, totalUrls);
|
|
22
|
+
return findings
|
|
23
|
+
.map((f) => {
|
|
24
|
+
const check = getCheck(f.ruleId);
|
|
25
|
+
const severity = SEVERITY_WEIGHT[f.severity] ?? 12;
|
|
26
|
+
const affected = Math.max(1, f.urls.length);
|
|
27
|
+
const coverage = 0.2 + 0.8 * Math.min(1, affected / Math.max(25, 0.05 * n));
|
|
28
|
+
let indexableAffected = affected;
|
|
29
|
+
if (opts?.indexableUrls) {
|
|
30
|
+
indexableAffected = f.urls.filter((u) => opts.indexableUrls.has(u)).length;
|
|
31
|
+
}
|
|
32
|
+
const indexability = 0.15 + 0.85 * (indexableAffected / affected);
|
|
33
|
+
let clicks = 0;
|
|
34
|
+
if (opts?.gscClicksByUrl) {
|
|
35
|
+
for (const u of f.urls)
|
|
36
|
+
clicks += opts.gscClicksByUrl[u] ?? 0;
|
|
37
|
+
}
|
|
38
|
+
const traffic = Math.min(4, 1 + Math.log10(1 + clicks));
|
|
39
|
+
const confidence = f.confidence;
|
|
40
|
+
const effort = effortFactor(check?.autonomyTier ?? f.autonomyTier);
|
|
41
|
+
const priority = (severity * coverage * indexability * traffic * confidence) / effort;
|
|
42
|
+
return {
|
|
43
|
+
...f,
|
|
44
|
+
priority,
|
|
45
|
+
coverage,
|
|
46
|
+
indexability,
|
|
47
|
+
traffic,
|
|
48
|
+
effort,
|
|
49
|
+
};
|
|
50
|
+
})
|
|
51
|
+
.toSorted((a, b) => b.priority - a.priority);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=priority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority.js","sourceRoot":"","sources":["../src/priority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE3C,MAAM,CAAC,MAAM,gBAAgB,GAC3B,+EAA+E,CAAC;AAElF,MAAM,eAAe,GAA2B;IAC9C,QAAQ,EAAE,GAAG;IACb,IAAI,EAAE,EAAE;IACR,MAAM,EAAE,EAAE;IACV,GAAG,EAAE,CAAC;IACN,OAAO,EAAE,CAAC;CACX,CAAC;AAEF,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC/C,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC9B,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,QAAwB,EACxB,SAAiB,EACjB,IAGC;IAED,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACjC,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,iBAAiB,GAAG,QAAQ,CAAC;QACjC,IAAI,IAAI,EAAE,aAAa,EAAE,CAAC;YACxB,iBAAiB,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9E,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,CAAC,iBAAiB,GAAG,QAAQ,CAAC,CAAC;QAClE,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI;gBAAE,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;QAChC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC;QACnE,MAAM,QAAQ,GACZ,CAAC,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC,GAAG,MAAM,CAAC;QACvE,OAAO;YACL,GAAG,CAAC;YACJ,QAAQ;YACR,QAAQ;YACR,YAAY;YACZ,OAAO;YACP,MAAM;SACP,CAAC;IACJ,CAAC,CAAC;SACD,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC"}
|